directory notifications lost after fork?
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.
How to reproduce (tested with 2.4.17):
gcc -o dnoticebug dnoticebug.c
dnoticebug & # run in background
cat dnoticebug.c >/dev/null # "notified" should now be printed
cat dnoticebug.c >/dev/null # nothing is printed this time
If you comment out the line with fork below, "notified" *will* be printed every time you cat dnoticebug.c.
I'm not subscribed to the list so I'd appreciate if you CCed me. (Otherwise I'd have to use the archives :) Thanks.
Oskar Liljeblad ([email protected])
===
#define _GNU_SOURCE
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
static void handler(int sig, siginfo_t *si, void *data)
{
printf("notified\n");
}int main(void)
{
struct sigaction act;
int fd;
act.sa_sigaction = handler;
sigemptyset(&act.sa_mask);
act.sa_flags = SA_SIGINFO;
sigaction(SIGRTMIN, &act, NULL);
fd = open(".", O_RDONLY);
fcntl(fd, F_SETSIG, SIGRTMIN);
fcntl(fd, F_NOTIFY, DN_ACCESS|DN_MULTISHOT);
while (1) {
pause();
if (fork() <= 0) exit(0);
wait(NULL);
}
}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
Quoted 59 lines · Oskar Liljeblad
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_SETSIGfcntl no longer is delivered when notified.How to reproduce (tested with 2.4.17):
gcc -o dnoticebugdnoticebug.c
dnoticebug & # run in background
catdnoticebug.c>/dev/null # "notified" should now be printed
catdnoticebug.c>/dev/null # nothing is printed this timeIf you comment out the line with fork below, "notified" *will* be printed every time you cat
dnoticebug.c.I'm not subscribed to the list so I'd appreciate if you CCed me. (Otherwise I'd have to use the archives :) Thanks.
Oskar Liljeblad ([email protected])
===
#define
_GNU_SOURCE
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>static void
handler(int sig, siginfo_t *si, void *data){ printf("notified\n"); }int main(void)
{ struct sigaction act; int fd; act.sa_sigaction = handler; sigemptyset(&act.sa_mask); act.sa_flags = SA_SIGINFO; sigaction(SIGRTMIN, &act, NULL); fd = open(".", O_RDONLY); fcntl(fd, F_SETSIG, SIGRTMIN); fcntl(fd, F_NOTIFY, DN_ACCESS|DN_MULTISHOT); while (1) { pause(); if (fork() <= 0) exit(0); wait(NULL); } }-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Quoted 4 lines · usel
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). [..]
FWIW, as long as you keep the child alive after fork the notifications are not lost. Also the same effect when you keep the parent(s) alive and decide to receive notification in the newly created process instead.
Oskar Liljeblad ([email protected])
Quoted 10 lines · Oskar Liljeblad
Quoted 4 lines · usel
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). [..]
FWIW, as long as you keep the child alive after fork the notifications are not lost. Also the same effect when you keep the parent(s) alive and decide to receive notification in the newly created process instead.
What process are the notifications sent, in this case? IMHO, only the parent can catch them, as fcntl called in the parent only.
Anyway, strange effect.
Quoted 7 lines
Oskar Liljeblad ([email protected])
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Quoted 13 lines · Oskar Liljeblad
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_SETSIGfcntl no longer is delivered when notified.How to reproduce (tested with 2.4.17):
gcc -o dnoticebugdnoticebug.c
dnoticebug & # run in background
catdnoticebug.c>/dev/null # "notified" should now be printed
catdnoticebug.c>/dev/null # nothing is printed this time
Quoted 5 lines
If you comment out the line with fork below, "notified" *will* be printed every time you cat
dnoticebug.c.I'm not subscribed to the list so I'd appreciate if you CCed me. (Otherwise I'd have to use the archives :) Thanks.
this should fix your problem:
ftp://ftp.us.kernel.org/pub/linux/kernel/people/andrea/kernels/v2.4/2.4.19pre2aa2/00_dnotify-fl_owner-1
Andrea
Hi Andrea,
Quoted 9 lines · On Mon, 11 Mar 2002 11:26:52 +0100 Andrea Arcangeli <[email protected]> wrote:
Quoted 6 lines · Oskar Liljeblad
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_SETSIGfcntl no longer is delivered when notified.
Quoted 5 lines
this should fix your problem:
ftp://ftp.us.kernel.org/pub/linux/kernel/people/andrea/kernels/v2.4/2.4.19pre2aa2/00_dnotify-fl_owner-1Andrea
Can you see any reason we should not use hte patch below instead?
Signature · 44 lines
Cheers, Stephen Rothwell [email protected] http://www.canb.auug.org.au/~sfr/ diff -ruN 2.4.19-pre3/fs/dnotify.c 2.4.19-pre3-notify/fs/dnotify.c --- 2.4.19-pre3/fs/dnotify.c Wed Nov 8 18:27:57 2000 +++ 2.4.19-pre3-notify/fs/dnotify.c Tue Mar 12 12:02:15 2002 @@ -1,7 +1,7 @@ /* * Directory notifications for Linux. * - * Copyright (C) 2000 Stephen Rothwell + * Copyright (C) 2000,2001,2002 Stephen Rothwell * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -59,7 +59,7 @@ write_lock(&dn_lock); prev = &inode->i_dnotify; for (odn = *prev; odn != NULL; prev = &odn->dn_next, odn = *prev) - if (odn->dn_filp == filp) + if ((odn->dn_owner == current->files) && (odn->dn_filp == filp)) break; if (odn != NULL) { if (turning_off) { @@ -82,6 +82,7 @@ dn->dn_mask = arg; dn->dn_fd = fd; dn->dn_filp = filp; + dn->dn_owner = current->files; inode->i_dnotify_mask |= arg & ~DN_MULTISHOT; dn->dn_next = inode->i_dnotify; inode->i_dnotify = dn; diff -ruN 2.4.19-pre3/include/linux/dnotify.h 2.4.19-pre3-notify/include/linux/dnotify.h --- 2.4.19-pre3/include/linux/dnotify.h Wed Mar 6 16:08:12 2002 +++ 2.4.19-pre3-notify/include/linux/dnotify.h Tue Mar 12 11:23:07 2002 @@ -11,6 +11,7 @@ see linux/fcntl.h */ int dn_fd; struct file * dn_filp; + fl_owner_t dn_owner; }; #define DNOTIFY_MAGIC 0x444E4F54
Quoted 12 lines · Stephen Rothwell
Hi Andrea,
Quoted 9 lines · On Mon, 11 Mar 2002 11:26:52 +0100 Andrea Arcangeli <[email protected]> wrote:
Quoted 6 lines · Oskar Liljeblad
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_SETSIGfcntl no longer is delivered when notified.
Quoted 7 lines
Quoted 5 lines
this should fix your problem:
ftp://ftp.us.kernel.org/pub/linux/kernel/people/andrea/kernels/v2.4/2.4.19pre2aa2/00_dnotify-fl_owner-1Andrea
Can you see any reason we should not use hte patch below instead?
If somebody overrides the dnotify on the same file, he should become the new owner, that's not handled in the below patch.
Secondly I prefer to return -EPERM to userspace if somebody tries to drop a dnotify that it doesn't own, it gives more information back to userspace.
On the same lines I would prefer that also a "turning_off" that fails to find the file in the i_dnotify list , would return an error to be strictier, but I didn't changed this bit of course.
Andrea
Hi Adrea,
Quoted 3 lines · On Tue, 12 Mar 2002 02:20:46 +0100 Andrea Arcangeli <[email protected]> wrote:
If somebody overrides the dnotify on the same file, he should become the new owner, that's not handled in the below patch.
My contention is that if some process (not in the same thread group as the process that originally set up the directory notifier) tries to set up a directory notifier on the same file descriptor (i.e. they are a child of the original process), then they should get their own notifier. The parent can remove their notifier if they want to.
Notice that multiple processes can have notifiers enabled for the same directory (even with a different set of flags).
My patch makes directory notifiers per thread group instead of per process tree (which they are now).
Quoted 3 lines
Secondly I prefer to return
-EPERMto userspace if somebody tries to drop a dnotify that it doesn't own, it gives more information back to userspace.
This would be equivalent to returning -EPERM if you tried to remove a lock on a file when you didn't set it ...
Signature · 2 lines
Cheers, Stephen Rothwell [email protected] http://www.canb.auug.org.au/~sfr/
Quoted 2 lines · Stephen Rothwell
My patch makes directory notifiers per thread group instead of per process tree (which they are now).
I overlooked that in your patch you changed the index for the lookup, so yes, that looks a better fix.
Quoted 2 lines
This would be equivalent to returning
-EPERMif you tried to remove a lock on a file when you didn't set it ...
Lock are standard and we cannot change such API, but for a fairly new API I'd prefer strict stuff. Anyways now -EPERM would be wrong and the need of the errorback is also lower because there's no risk of collisions anymore, now different current->files will be able to get different notifiers, so if something it should be a -ENOENT, it's not a matter of permissions/ownership anymore.
Andrea
Quoted 5 lines · Alex Riesen
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.
I don't yet, but I am planning to use them for an ultra-high-performance dynamic web server and make-like tool.
The idea is that a dynamic page's cache validity (or the validity of a subrequest) may depend on a large number of stat() results.
Dnotify can be used, as I understand it, to avoid having to actually do the stat() calls on each request.
In this way, cached dynamic pages can be served as quickly as static pages, right down to using the minimum set of system calls.
At the same time, dynamic pages are served perfectly _as if_ they are recalculated every time from their prerequisite files, including: script code (Perl, PHP etc.), included files, templates, images, database files. So with things like setting the width and height of each IMG tag from scanning the image files, and complex templates such as navigation bars that you currently remake by hand using "make" -- these things immediately update as you modify the site's source files.
It makes a pretty nice document editing environment too -- save file from Emacs, immediately view formatted file in web browser :-)
I can do this at the moment, but with a number of stat() calls on each request. With dnotify I think I can eliminate those but I haven't got that far yet.
If dnotify is too buggy as stands then for this project I'd very much like it to be fixed. Loss of notifications after fork() sounds like a rather serious bug :-/
cheers,
-- Jamie