bug-coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: tail aborts while following by name if using inotify


From: Jim Meyering
Subject: Re: tail aborts while following by name if using inotify
Date: Mon, 28 Dec 2009 14:10:18 +0100

Rob Wortman wrote:
> I have noticed a behavioral quirk in versions of tail which use inotify.
> When following a file by name (using tail -F or tail --follow=name),
> tail will abort when a file returns after being renamed. I see that this
> bug was addressed in coreutils-8.1, but I still find the behavior in
> coreutils-8.2.
>
> The most illustrative way that I've found to demonstrate what I see is
> as follows:
>
> $ touch file; tail -F file & echo $! > pid
> [1] 26527
> $ while [[ "$( ps ho comm "$(<pid)" )" == tail ]]; do mv file file1; touch 
> file; done
> tail: `file' has become inaccessible: No such file or directory
> tail: `file' has appeared;  following end of new file
> <repeat previous 2 lines 7 more times>
> tail: `file' has become inaccessible: No such file or directory
> [1]+  Aborted                 (core dumped) tail -F file
>
> The backtrace from the core dump:
> #0  0x00007ff6ed4f5ec5 in raise () from /lib/libc.so.6
> #1  0x00007ff6ed4f73c1 in abort () from /lib/libc.so.6
> #2  0x000000000040685e in hash_insert ()
> #3  0x0000000000403532 in tail_forever_inotify ()
> #4  0x0000000000404b9d in main ()
>
> In the while loop at the end of tail_forever_inotify, if hash_insert
> does not abort, recheck is called immediately after, which will print
> the "following end of new file" message. So, I can tell how many times
> hash_insert succeeds. This is significant because in the above example,
> hash_insert always succeeds 8 times and fails on the 9th.
>
> The number of successes is inversely proportional to the number of files
> that tail is watching. If tail is watching 9 or more files, it succeeds
> 0 times, and aborts the first time a moved file returns. This example
> requires no loops:
>
> $ touch file{1..9}; tail -qF file* &
> [1] 16341
> $ mv file1 wombat
> tail: `file1' has become inaccessible: No such file or directory
> $ touch file1
> $ ls
> core  file1  file2  file3  file4  file5  file6  file7  file8  file9  wombat
> [1]+  Aborted                 (core dumped) tail -qF file*
>
> I have also noticed that tail does not exhibit this behavior when a
> watched file is removed and recreated, or when one is moved and moved
> back: I can only reproduce this by moving a file and recreating it.

Thanks for the detailed report!
I've figured out what's going on, but don't have a fix yet.

The trouble is that tail is violating the contract with the hash module
by changing a key value (the File_spec.wd member) in an element in the
hash table.  When insertion requires a rehash (because the new entry
is not in the table), hash_insert aborts when the new entry is not in
the rehashed table.  Obviously, if it's not in the pre-rehash table,
it must not be in the post-rehash one.  But since tail.c changes a key
behind the hash module's back, it gets what it deserves ;-)

This will be fixed for the upcoming coreutils-8.3 release.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]