Detecting foreign IN_MOVED_FROM renames with inotify

842 views Asked by At

Assume a C program which mirrors the changes in a watched directory to a mirror directory. You recursively watch all subdirectories and use a structure indexed on watch descriptors containing the pathnames of the watched directories to be able to reconstruct the full pathname of the file in case of an event. This is all you need to process all events but IN_MOVED_FROM and IN_MOVED_TO. In the case of these two, you, in addition to the aforementioned, seem to also need the following:

  • A structure indexed on cookies allowing you to store and retrieve the watch descriptor and the filename of a particular IN_MOVED_FROM event once a matching IN_MOVED_TO event appears.
  • A timestamp-ordered queue (redundant) containing cookies which have not yet been paired, so that they can be reinterpreted as IN_DELETE events and removed from both of the structures once an arbitrary period of time has passed.
  • A pathname/filename -> watch descriptor relation (redundant), which allows you to effectively find out the watch descriptor of a timeouted cookie in case the (re)moved filesystem object was a directory, which you now need to unwatch.

Quite some overhead for supporting rename operations. Is there really no other way to detect a foreign rename other than waiting for an unpaired cookie to time out? Given the fact that there appears to be a way of telling between a local and foreign rename in fsnotify, this seems as a rather odd design choice.

2

There are 2 answers

3
zeekvfu On BEST ANSWER

With inotify, you need to set an timeout to handle the mismatched/unpaired/foreign rename operation(eg. mv a file into or out of a watched directory), treat them as IN_CREATE or IN_DELETE events.
Once I worked on a project relating to file synchronization mechanism, faced with the same issue, and solved it the same way.

IMHO, the design of inotify API is somewhat disgusting. Take the rename operation as an example, inotify interpretes it as TWO seperates events. :-(

According to the link you give, Linux kernel does distinguish the local/foreign rename operation, and you can achieve this using the dnotify interface. But since dnotify was already obsoleted by inotify interface, I won't recommend this.

reference:
http://en.wikipedia.org/wiki/Dnotify

1
ismail On

I suggest either studying or just linking to libinotifytools library. It handles most if not all of the cases.