rjeczalik / notify

File system event notification library on steroids.
MIT License
900 stars 128 forks source link

inotify event path may be incorrect if wd is not yet updated to its new path #221

Open ReallyLiri opened 1 year ago

ReallyLiri commented 1 year ago

I observed the following behavior in Ubuntu:

mkdir test_dir
# ...
mkdir new_dir
mv test_dir new_dir/

In practice we get the following hits (I added some dbg prints)

added watch on wd=13 ('/home/ubuntu/tmp/test_dir')
// ...
received_event notify.InCreate (0x40000100) ('/home/ubuntu/tmp/new_dir', i=0, wd=2, cookie=0, len=1)
received_event notify.InMovedFrom (0x40000040) ('/home/ubuntu/tmp/test_dir', i=0, wd=2, cookie=1536, len=2)
dispatching notify.Create on "/home/ubuntu/tmp/new_dir"
received_event notify.InMoveSelf (0x800) ('/home/ubuntu/tmp/test_dir', i=1, wd=13, cookie=0, len=2)
dispatching notify.Rename on "/home/ubuntu/tmp/test_dir"
added watch on wd=20 ('/home/ubuntu/tmp/new_dir')
dispatching notify.Rename on "/home/ubuntu/tmp/test_dir"
added watch on wd=13 ('/home/ubuntu/tmp/new_dir/test_dir')

The path of the InMoveSelf event is deduced to be the path from "before" the move, because the code doesn't know any better.

Once the recursive watch of the new dir (new_dir) is processed by the relevant goroutine, we get a new watch set to wd=13, which points to the correct path.

One possible solution would be to "finish" handling all of the Create event and its recursive implications before moving on, but that would require big changes to the code.

Note this scenario will only occur if the mkdir + mv are done using a script, therefore in a very short period.

I couldn't find any other way to get the "accurate" path of the InMoveSelf event. Considering its the "counterpart" of the InMovedFrom, we can tell that the path is not the "moved to" path, but I didn't find any alternative way to get the "current" path of a given wd.