GNOME Bugzilla – Bug 532815
gio + inotify support for hardlinks
Last modified: 2012-12-19 13:23:01 UTC
Since the inotify code just watches directories, not the actual files themselves, it looks like it doesn't work with hardlinked files. On Fedora, the system-config-network tool hardlinks the device config files (ifcfg-eth0 for example) in 3 locations: /etc/sysconfig/networking/profiles/default/ifcfg-eth0 /etc/sysconfig/networking/devices/ifcfg-eth0 /etc/sysconfig/network-scripts/ifcfg-eth0 If a program uses g_file_monitor_file() on any one of those, changes to any of the other hardlinked locations will _NOT_ trigger the 'changed' signal of the GFileMonitor object.
Created attachment 110788 [details] gio testcase for monitoring a path Use like: gcc -g -O0 -o gio-testcase gio-testcase.c `pkg-config --libs --cflags glib-2.0 gio-2.0` -Wall ./gio-testcase /etc/sysconfig/network-scripts/ifcfg-eth0
Will work up a plain inotify testcase showing how hardlinks get detected; but I think you have to watch the _file_ itself, because then you're watching the file's inode (which of course is shared between all hardlinks) not the directories, and then you'll get change notifications. Unfortunately, it looks like the glib inotify code only watches directories even if given a path to a file, probably for scalability reasons.
Created attachment 110809 [details] inotify testcase for monitoring a hardlinked path Build with e.g.: gcc -g -O0 -o inotify-testcase inotify-testcase.c `pkg-config --libs --cflags glib-2.0 gobject-2.0` -Wall run with: ./inotify-testcase /etc/sysconfig/network-scripts/ifcfg-eth0 and edit another hardlink than the one you're monitoring. You'll get events.
Maybe gio can check the number of hardlinks to decide whether the file itself should be monitored? Need to make sure you get an event on hardlink bump from 1 to 2 though, to switch...
Well, wouldn't something need to poll the file then to get notifications when the hardlink number changes? In that case, wouldn't it just be easier to inotify watch the files themselves?
I talked to John McCutchan about this and he says to get notified of file deletion one has to monitor the parent directory. Now seems like we need to monitor both. If I was to do the monitor API from scratch I'd make it take a flag set of events one wants to get notified about, but that doesn't matter at this point..
Related bug 536172 is about file monitoring not working with symlinks.
Yeah, the code would need to monitor both directories and the files themselves.
Monitoring all files in a directory is a huge problem. First of all you have to actually readdir() all files which is a large blocking startup cost of the monitor, then there is a very heavy cost for each monitor, and there is a per-user limit of 8192 inotify watches. I don't think this cost is worth it for all users for the few cases where hardlinks matter. Maybe we could introduce a flag that switches on this behaviour instead?
An additional flag for GFileMonitorFlags like G_FILE_MONITOR_WATCH_HARDLINKS or something like that would probably be fine.
Created attachment 148090 [details] [review] [PATCH] Bug 532815 - gio + inotify support for hardlinks review, plz?
This is only supported (and possible) on the inotify backend, so i'd like to add some docs that explains that this is just a hint. Also, i don't really know the inotify code that much so i can't review it that much. It looks good, but please test it thoroughly.
my thorough testing triggered a bug in the kernel. i'm getting the kernel guys at UDS to look at it, but i'm basically blocked until they clean up the issue.
(In reply to comment #13) > my thorough testing triggered a bug in the kernel. i'm getting the kernel guys > at UDS to look at it, but i'm basically blocked until they clean up the issue. Ryan, did anything ever happen with that?
Just verified with the testcases that GIO is still broken here; glib 2.32.
Dan: did you try with this old patch applied? I'm sure the issue must be fixed in the kernel by now...
Created attachment 216947 [details] [review] gio + inotify support for hardlinks Add a new GFileMonitorFlag: G_FILE_MONITOR_WATCH_HARDLINKS. When set, changes made to the file via another hard link will be detected. Implement the new flag for the inotify backend.
rebased. The inotify parts seem to work, although I don't know what the bug in the kernel you mention before was. (dcbw's test case needs to be modified to include G_FILE_MONITOR_WATCH_HARDLINKS of course.) However, it's generating the GFile path incorrectly when you modify a link other than the link you're monitoring. Eg, if you're monitoring /tmp/foo, and you edit it via a hard link /tmp/bar, then it claims that "/tmp" was modified, not "/tmp/foo".
Created attachment 217532 [details] [review] Fix pathname on changes-via-hardlink
Created attachment 217533 [details] [review] don't emit double events for WATCH_HARDLINKS watches If we're watching both the file and the directory, don't emit events when the directory watch reports a file-level change, since the file watch will report it as well.
I think we should land this, as it seems pretty useful. However, the docs needs to be modified to say that this is a "best effort" thing and will not work on all notification backends.
ok. someone (desrt?) should figure out if the last two patches I attached (fixing the original patch) are right
OK, I squashed the patches, clarified the docs a bit, renamed the enum to ..._HARD_LINKS rather than ..._HARDLINKS, and pushed.