diff options
author | Pádraig Brady <P@draigBrady.com> | 2010-10-12 01:39:58 +0100 |
---|---|---|
committer | Pádraig Brady <P@draigBrady.com> | 2010-10-12 11:41:17 +0100 |
commit | 61b77891c2d9af299063850a0c4d1d721340cfff (patch) | |
tree | 53d70fd61a8c64ab6be607a0f9083ff6583f0886 /tests/tail-2 | |
parent | 9f4744534f1de87b9630dfbde91b9ebd9592d056 (diff) | |
download | coreutils-61b77891c2d9af299063850a0c4d1d721340cfff.tar.xz |
tail: fix checking of currently unavailable directories
* src/tail.c (tail_forever_inotify): Handle the case where
tail --follow=name with inotify, is not able to add a watch on
a specified directory. This may happen due to inotify resource
limits or if the directory is currently missing or inaccessible.
In all these cases, revert to polling which will try to reopen
the file later. Note inotify returns ENOSPC when it runs out
of resources, and instead we report a particular error message,
lest users think one of their file systems is full.
(main): Document another caveat with using inotify, where we
currently don't recheck directories recreated after the
initial watch is setup.
* tests/tail-2/F-vs-rename: Fix the endless loop triggered by
the above issue.
* tests/tail-2/inotify-hash-abuse: Likewise.
* tests/tail-2/wait: Don't fail in the resource exhaustion case.
* tests/tail-2/F-vs-missing: A new test for this failure mode
which was until now just triggered on older buggy linux kernels
which returned ENOSPC constantly from inotify_add_watch().
* NEWS: Mention the fix.
Diffstat (limited to 'tests/tail-2')
-rwxr-xr-x | tests/tail-2/F-vs-missing | 49 | ||||
-rwxr-xr-x | tests/tail-2/F-vs-rename | 35 | ||||
-rwxr-xr-x | tests/tail-2/inotify-hash-abuse | 27 | ||||
-rwxr-xr-x | tests/tail-2/wait | 2 |
4 files changed, 81 insertions, 32 deletions
diff --git a/tests/tail-2/F-vs-missing b/tests/tail-2/F-vs-missing new file mode 100755 index 000000000..8c1d01898 --- /dev/null +++ b/tests/tail-2/F-vs-missing @@ -0,0 +1,49 @@ +#!/bin/sh +# demonstrate that tail -F works for currently missing dirs +# Before coreutils-8.6, tail -F missing/file would not +# notice any subsequent availability of the missing/file. + +# Copyright (C) 2010 Free Software Foundation, Inc. + +# 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 Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +. "${srcdir=.}/init.sh"; path_prepend_ ../src +test "$VERBOSE" = yes && tail --version + +debug='---disable-inotify' +debug= +tail $debug -F -s.1 missing/file > out 2>&1 & pid=$! + +check_tail_output() +{ + local delay="$1" + grep "$tail_re" out > /dev/null || + { sleep $delay; return 1; } +} + +# Wait up to 6.3s for tail to start with diagnostic: +# tail: cannot open `missing/file' for reading: No such file or directory +tail_re='cannot open' retry_delay_ check_tail_output .1 7 || fail=1 + +mkdir missing || fail=1 +(cd missing && echo x > file) + +# Wait up to 6.3s for this to appear in the output: +# "tail: `...' has appeared; following end of new file" +tail_re='has appeared' retry_delay_ check_tail_output .1 7 || + { echo "$0: file: unexpected delay?"; cat out; fail=1; } + +kill -HUP $pid + +Exit $fail diff --git a/tests/tail-2/F-vs-rename b/tests/tail-2/F-vs-rename index 74db80137..98b36e745 100755 --- a/tests/tail-2/F-vs-rename +++ b/tests/tail-2/F-vs-rename @@ -18,39 +18,36 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. -if test "$VERBOSE" = yes; then - set -x - tail --version -fi - -. $srcdir/test-lib.sh +. "${srcdir=.}/init.sh"; path_prepend_ ../src +test "$VERBOSE" = yes && tail --version touch a b || framework_failure -debug='---disable-inotify -s .01' +debug='---disable-inotify' debug= -tail $debug -F a b > out 2>&1 & pid=$! +tail $debug -F -s.1 a b > out 2>&1 & pid=$! + +check_tail_output() +{ + local delay="$1" + grep "$tail_re" out > /dev/null || + { sleep $delay; return 1; } +} -# Wait until tail has started... +# Wait up to 6.3s for tail to start echo x > a -until grep '^x$' out >/dev/null 2>&1; do :; done +tail_re='^x$' retry_delay_ check_tail_output .1 7 || fail=1 mv a b || fail=1 -# Wait for the diagnostic: +# Wait 6.3s for this diagnostic: # tail: `a' has become inaccessible: No such file or directory -until grep inaccessible out >/dev/null 2>&1; do :; done +tail_re='inaccessible' retry_delay_ check_tail_output .1 7 || fail=1 echo x > a # Wait up to 6.3s for this to appear in the output: # "tail: `...' has appeared; following end of new file" -tail_f_vs_rename_1() -{ - local delay="$1" - grep 'has appeared;' out > /dev/null || - { sleep $delay; return 1; } -} -retry_delay_ tail_f_vs_rename_1 .1 7 || +tail_re='has appeared' retry_delay_ check_tail_output .1 7 || { echo "$0: a: unexpected delay?"; cat out; fail=1; } echo y >> b diff --git a/tests/tail-2/inotify-hash-abuse b/tests/tail-2/inotify-hash-abuse index 65a341211..d45668a69 100755 --- a/tests/tail-2/inotify-hash-abuse +++ b/tests/tail-2/inotify-hash-abuse @@ -16,30 +16,33 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. -if test "$VERBOSE" = yes; then - set -x - tail --version -fi - -. $srcdir/test-lib.sh +. "${srcdir=.}/init.sh"; path_prepend_ ../src +test "$VERBOSE" = yes && tail --version # 9 is a magic number, related to internal details of tail.c and hash.c n=9 seq $n | xargs touch || framework_failure -debug='---disable-inotify -s .01' +debug='---disable-inotify' debug= -tail $debug -qF $(seq $n) > out 2>&1 & pid=$! +tail $debug -s.1 -qF $(seq $n) > out 2>&1 & pid=$! + +check_tail_output() +{ + local delay="$1" + grep "$tail_re" out > /dev/null || + { sleep $delay; return 1; } +} -# Wait until tail has started... +# Wait up to 6.3s for tail to start echo x > $n -until grep '^x$' out >/dev/null 2>&1; do :; done +tail_re='^x$' retry_delay_ check_tail_output .1 7 || fail=1 mv 1 f || fail=1 -# Wait for this diagnostic: +# Wait 6.3s for this diagnostic: # tail: `1' has become inaccessible: No such file or directory -until grep inaccessible out >/dev/null 2>&1; do :; done +tail_re='inaccessible' retry_delay_ check_tail_output .1 7 || fail=1 # Trigger the bug. Before the fix, this would provoke the abort. echo a > 1 || fail=1 diff --git a/tests/tail-2/wait b/tests/tail-2/wait index 332cfcc09..a9636910e 100755 --- a/tests/tail-2/wait +++ b/tests/tail-2/wait @@ -53,7 +53,7 @@ for inotify in ---disable-inotify ''; do timeout 1 tail -s0.1 -F $inotify not_here test $? = 124 || fail=1 - grep -v 'tail: inotify cannot be used, reverting to polling:' tail.err > x + grep -Ev 'inotify (resources exhausted|cannot be used)' tail.err > x mv x tail.err test -s tail.err && fail=1 :>tail.err |