Use inotify to detect external IN_MOVED_FROM renaming
Suppose a C program mirrors changes in the monitoring directory to the mirror directory. You recursively observe all subdirectories and use the watch directory that contains pathnames
in a structure indexed on the watch descriptors
so that the full pathname of the file can be reconstructed when an event occurs. That’s all you need to handle all events, but IN_MOVED_FROM
and IN_MOVED_TO
. In both cases, it seems that you need the following in addition to the above:
- The structure of indexing on
cookies
allows you to store and retrievewatch descriptor
andfilename
for a specificIN_MOVED_FROM
once an event eventthat matches IN_MOVED_TO
appears. - A
timestamp
– Ordered queues (redundant) contain cookies that have not been paired so that they can be reinterpreted asIN_DELETE
events and removed from both structures after any period of time has elapsed. - A
pathname/filename
-> watch descriptor relationship (redundancy), which allows you to effectively find out if thewatch descriptor
timed out cookie
if the (re)moved file system object is a directory and you now need to unmonitor.
The overhead of supporting rename operations is considerable. Is there really no other way to detect foreign renames other than waiting for unpaired cookies to time out? Given that there is appears to be a way of telling between a local and foreign rename fsnotify, which seems like a rather strange design choice.
Solution
With iNotify
, you need to set a timeout to handle mismatched/unpaired/external rename operations (for example, mv
files in and out of the watch directory), treating them as IN_CREATE
or IN_DELETE
events.
Once I did a project related to the file synchronization mechanism, I encountered the same problem, and I used the same method to solve it.
IMHO, the design of the inotify
API is somewhat disgusting. Take the rename operation as an example, which inotify
interprets as two separate events. 🙁
According to link you give, the Linux kernel does distinguish between local/external rename operations, and you can use dnotify
Interface to do this. But since dnotify
has been eliminated by the inotify
interface, I don’t recommend this.