From mboxrd@z Thu Jan 1 00:00:00 1970 From: ludo@gnu.org (Ludovic =?UTF-8?Q?Court=C3=A8s?=) Subject: bug#21460: Race condition in tests/tail-2/assert.sh Date: Fri, 11 Sep 2015 22:55:01 +0200 Message-ID: <87a8ssad7e.fsf@gnu.org> References: <87wpvw2ad8.fsf@gnu.org> <55F30CEC.7060102@cs.ucla.edu> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Return-path: Sender: "Debbugs-submit" Resent-Message-ID: In-Reply-To: <55F30CEC.7060102@cs.ucla.edu> (Paul Eggert's message of "Fri, 11 Sep 2015 10:18:36 -0700") List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-coreutils-bounces+gcgcb-bug-coreutils-616=gmane.org@gnu.org Sender: bug-coreutils-bounces+gcgcb-bug-coreutils-616=gmane.org@gnu.org To: Paul Eggert Cc: 21460@debbugs.gnu.org, bug-guix@gnu.org List-Id: bug-guix.gnu.org --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Paul Eggert skribis: > Ludovic Court=C3=A8s wrote: >> I think the problem happens when =E2=80=98tail=E2=80=99 opens =E2=80=98f= oo=E2=80=99 right in between of >> the two notifications: =E2=80=98foo=E2=80=99 is still there, and so =E2= =80=98tail=E2=80=99 doesn=E2=80=99t >> report anything. >> >> Does that make sense? > > Yes, though if the link count is indeed zero, I'm surprised that > 'tail' can open the file -- that sounds like a bug in the kernel. Attached is a reproducer; just run it in a loop for a couple of seconds: --8<---------------cut here---------------start------------->8--- $ while ./a.out ; do : ; done funny, errno =3D Success, nlink =3D 0 Aborted (core dumped) --8<---------------cut here---------------end--------------->8--- I=E2=80=99m not sure if that=E2=80=99s a kernel bug. Strictly speaking, in= otify works as expected: we get a notification for nlink--, which doesn=E2=80=99t mean = the file has vanished. The conclusion for =E2=80=98tail=E2=80=99 would be to wait for the IN_DELET= E_SELF event before considering the file to be gone. WDYT? (That =E2=80=98inotify_rm_watch=E2=80=99 returns EINVAL *is* a bug IMO, but= not worrisome.) Thanks, Ludo=E2=80=99. --=-=-= Content-Type: text/plain Content-Disposition: inline; filename=inotify.c Content-Description: the inotify race #define _GNU_SOURCE 1 #include #include #include #include #include #include #include #include #include int main () { int file = creat ("foo", S_IRUSR | S_IWUSR); assert_perror (errno); close (file); int notifications = inotify_init (); assert_perror (errno); int watch = inotify_add_watch (notifications, "foo", IN_MODIFY | IN_ATTRIB | IN_DELETE_SELF | IN_MOVE_SELF); assert_perror (errno); if (fork () == 0) { unlink ("foo"); assert_perror (errno); exit (EXIT_SUCCESS); } struct inotify_event event; ssize_t count = read (notifications, &event, sizeof event); assert (count == sizeof event); assert (event.mask == IN_ATTRIB); struct stat st; stat ("foo", &st); if (errno != ENOENT) { printf ("funny, errno = %m, nlink = %li\n", st.st_nlink); abort (); } count = read (notifications, &event, sizeof event); assert (count == sizeof event); assert (event.mask == IN_DELETE_SELF); /* Bug #2: this returns EINVAL for no good reason. */ /* inotify_rm_watch (notifications, watch); */ /* assert_perror (errno); */ return EXIT_SUCCESS; } --=-=-=--