Skip to contentSkip to conversation

directory notifications lost after fork?

DISCUSSION Malte Starostik 3 participants 4 messages Mar 12, 2002

lore
Share & tools
lore
#0 lore raw

(Manually quoted from the archive)

Quoted 6 lines

Just a "me too".
I have tried also to use the default (SIGIO) by setting owner pid (just in case). It is all the same.
Does someone use the notifications, btw?
The whole thing seems somewhat untested.
-alex

We used to use them in the KDE libraries. However, we decided to disable it for now due to this problem since it's not theoretical, it hits quite often in konqueror and especially kdesktop as both spawn child processes. On a side note, dnotify is pretty weak compared to FAM with imon
(http://oss.sgi.com/projects/fam/) IMHO:
Imagine a file manager that has a view on a large directory like /usr/bin. Now a file in that directory is added / removed / changed. With dnotify, the filemanager will have to rescan the whole directory as a reaction to the signal, to find out which file has changed. OTOH, with FAM, it gets a precise event that tells "file `somebinary' has been added" or similar.
I don't have much of a clue about the kernel, so please excuse my ignorance, but the imon patch seems pretty unintrusive to me and enables more fine-grained file change notifications than dnotify. Also, FAM can monitor NFS-mounted directories with almost no network overhead when it's also running on the server.

Quoted 7 lines · Oskar Liljeblad
Quoted 6 lines

The code snipper demonstrates what I consider a bug in the dnotify facilities in the kernel. After a fork, all registered notifications are lost in the process where they originally where registered (the parent process). "lost" here means that the signal specified with F_SETSIG fcntl no longer is delivered when notified.

Regards,
-Malte

PS: I'm not subscribed, please CC me on answers; I'll also watch the archive.

Signature · 2 lines
Malte Starostik
PGP: 1024D/D2F3C787 [C138 2121 FAF3 410A 1C2A  27CD 5431 7745 D2F3 C787]
#1 lore raw
Quoted 6 lines · Malte Starostik

Imagine a file manager that has a view on a large directory like /usr/bin. Now a file in that directory is added / removed / changed. With dnotify, the filemanager will have to rescan the whole directory as a reaction to the signal, to find out which file has changed. OTOH, with FAM, it gets a precise event that tells "file `somebinary' has been added" or similar.

It would indeed be very cool if dnotify could say which inode has been updated. The problem I have with FAM is that notifications aren't immediate, which makes it useless for my fast dynamic web server application. For that, notifications have to be strong enough to support the rule "if I have not received a dnotify _now_, then my cached stat() result is valid for files in that directory _now_".

Quoted 5 lines

I don't have much of a clue about the kernel, so please excuse my ignorance, but the imon patch seems pretty unintrusive to me and enables more fine-grained file change notifications than dnotify. Also, FAM can monitor NFS-mounted directories with almost no network overhead when it's also running on the server.

Ah, thanks, I didn't know about imon.

The imon API is nice -- I could use that and more efficiently than dnotify. (I can't use FAM because of notification delays, but the imon device is just right).

Unfortunately the implementation is rather intrusive. As it says, it implies a performance hit on every file operation on all files, if any file is being monitored. So I can see it being disabled on high performance servers, which is where I need it.

A fusion of imon and dnotify would be good:

- absolute minimum impact on file operations: a small inline check, per inode not globally, as dnotify does now.

- imon-style hash table used for inodes that aren't in core, so you can monitor a large number of files individually without pulling their inodes into core. When inodes are brought into core then the hash table entries are moved to the in core inode, and vice versa.

(Not sure about the reliability of hashing on inode numbers, though -- some filesystems don't provide reliable inode numbers).

- dnotify-style lists of monitoring requests attached to in core inodes.

- per-process monitoring sets, as dnotify does.

- imon-style precision notification of individual files, including reliably monitoring files which are hard linked in different directories.

- dnotify causes files to notify their parent directory (yes it's ambiguous with hard links). In a per-file scheme, one possible flag on a file's inode would be "notify my parent directory". I see no reason not to extend that to "I am a directory. If I receive a notification from a child, notify _my_ parent directory", for those occasions when you'd like to monitor a whole directory hierarchy without having to do the equivalent slow disk accesses of "find -print" on it first.

- guarantee that the event will be sent to the monitoring process immediately after the operation which triggers the event, and before the operation releases inode semaphore, if it has it -- so that monitoring processes can depend on "if I haven't received a notification then my stat() cache is still valid".

Some ideas. I would really like this to be usable with my idea for a fast dynamic web server, which is also a "make" server, so I'm willing to put some work in here.

Feedback appreciated,
-- Jamie

#2 lore raw
In reply to Malte Starostik
Quoted 2 lines · Jamie Lokier

- dnotify causes files to notify their parent directory (yes it's ambiguous with hard links).

That's a bitch, isn't it? The only way I can think of to deal with it is via a hardlink reverse map, and there are lots of worms in that can, including where you store it, how much it costs to maintain it, how persistent it should be and how to make it perfectly non-racy.

Signature · 1 line
Daniel
#3 lore raw
In reply to Malte Starostik
Quoted 8 lines · Daniel Phillips
Quoted 2 lines · Jamie Lokier

- dnotify causes files to notify their parent directory (yes it's ambiguous with hard links).

That's a bitch, isn't it? The only way I can think of to deal with it is via a hardlink reverse map, and there are lots of worms in that can, including where you store it, how much it costs to maintain it, how persistent it should be and how to make it perfectly non-racy.

For dnotify purposes this may be solvable without a full reverse map. Suppose that we have per-inode notifiers as I suggested, and as the imon patch implements. Of course, multiple listeners can attach to an inode's notifier chain -- this is needed to support multiple processes listening.

Then you can implement dnotify by attaching the parent directory as a listener to each of its child inodes. (It's a bit heavy to set up, though).

Now, when an inode is modifed we don't guarantee to notify all the parent directories... but we do guarantee to notify all the ones which are actually listening at the moment. So it's a partial reverse map. I expect Al Viro would have something to say about dcache races at this point.

For recursive parent notification, such as monitoring "/usr" to learn about changes anywhere underneath "/usr", the above is perhaps impractical. We're right back to having to do "find -print" equivalent disk activity. Or reverse maps in the filesystem. Ugh.

In practice I'd just give up trying to cache stat() results of hard linked files, unless I knew I'd found all the paths to those files. Just don't use hard links ;-)

cheers,
-- Jamie