Hmm, okay. In earlier testing, I must have had a bug because I wasn't seeing filenames for FAN_MOVE or FAN_DELETE. But, my code is more robust now, and when I switch it to those events I do see filenames -- but not paths. Looks like I can do the open_by_handle_at trick on the fd in the main FAN_MOVED_FROM, FAN_MOVED_TO and FAN_DELETE event and that'll give me the directory path and then I can combine it with the file name in the info structure? Are FAN_MOVED_FROM and FAN_MOVED_TO guaranteed to be emitted atomically, or is there a possibility they could be split up by other events? If so, could there be multiple overlapping FAN_MOVED_FROM/FAN_MOVED_TO pairs under the right circumstances?? One other thing I'm seeing is that in enumerating the mount table in order to mark things, I find multiple entries with the same fsid. These seem to be cases where an item _inside another mount_ has been used as the device for a mount. One example is /boot/grub, which is mounted from /boot/efi/grub, where /boot/efi is itself mounted from a physical device. When enumerating the mounts, both of these return the same fsid from fstatfs. There is at least one other with such a collision, though it does not appear in fstab. Both the root filesystem / and a filesystem mounted at /var/snap/firefox/common/host-unspell return the same fsid. Does this mean that there is simply a category of event that cannot be guaranteed to return the correct path, because the only identifying information, the fsid, isn't guaranteed to be unique? Or is there a way to resolve this? Thanks, Jonathan Gilbert On Mon, May 20, 2024 at 10:58 PM Amir Goldstein <amir73il@xxxxxxxxx> wrote: > > On Tue, May 21, 2024 at 4:04 AM Jonathan Gilbert <logic@xxxxxxxxxx> wrote: > > > > Hello :-) > > > > I want to use fanotify to construct a best-effort log of changes to > > the filesystem over time. It would be super useful if events like > > FAN_MOVE_SELF and FAN_DELETE_SELF could report the path that the file > > _was_ at just prior to the event. Reporting an FID value is of limited > > use, because even if it still exists, looking up the name (e.g. by > > open_by_handle_at, the way fatrace does) will only reveal the new name > > after a FAN_MOVE_SELF -- and after a FAN_DELETE_SELF, the file no > > longer has any path! > > > > I understand that in terms of a strictly accurate reconstruction of > > changes over time, fanotify events are of limited use, because they > > aren't guaranteed to be ordered and from what I have read it seems it > > is possible for some changes to "slip through" from time to time. But, > > this is not a problem for my use case. > > > > I have no idea what things are available where in the kernel code that > > generates these events, but in the course of writing the code that > > reads the event data that gets sent to an fanotify fd, I was thinking > > that the simplest way to achieve this would be for FAN_MOVE_SELF and > > FAN_DELETE_SELF events to have associated info structures with paths > > in them. FAN_DELETE_SELF could provide an info structure with the path > > that just got unlinked, and FAN_MOVE_SELF could provide two info > > structures, one for the old path and one for the new. > > > > Of course, it is possible that this information isn't currently > > available at the spot where the events are being generated! > > This statement is correct for FAN_DELETE_SELF. > > > > > But, this would be immensely useful to my use case. Any possibility? > > > > FAN_DELETE emitted for every unlink() has the unlinked file name - > a file can have many names (i.e. hardlinks) will almost always come > before the final FAN_DELETE_SELF, which is emitted only when st_nlink > drops to zero.and last file reference is closed. > > I say almost always, because moving over a file, can also unlink it, > so either FAN_DELETE or FAN_RENAME should be observed > before FAN_DELETE_SELF and those should be enough for your > purpose. > > FAN_MOVE_SELF could in theory have info about source and target > file names, same as FAN_RENAME because it is being generated > within the exact same fsnotify_move() hook, but that's the reason > that FAN_RENAME is enough for your purpose. > > FAN_MOVE_SELF intentionally does not carry this information > so that watchers of FAN_MOVE_SELF could get all the move events > merged and get a single move event with the FID after a series of > many renames. > > Thanks, > Amir.