mirror of
git://git.sv.gnu.org/coreutils.git
synced 2026-03-05 20:43:51 +02:00
* 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.
85 lines
2.1 KiB
Bash
Executable File
85 lines
2.1 KiB
Bash
Executable File
#!/bin/sh
|
|
# Make sure that `tail -f' returns immediately if a file doesn't exist
|
|
# while `tail -F' waits for it to appear.
|
|
|
|
# Copyright (C) 2003, 2006-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/>.
|
|
|
|
if test "$VERBOSE" = yes; then
|
|
set -x
|
|
tail --version
|
|
fi
|
|
|
|
. $srcdir/test-lib.sh
|
|
|
|
touch here || framework_failure
|
|
{ touch unreadable && chmod a-r unreadable; } || framework_failure
|
|
|
|
|
|
for inotify in ---disable-inotify ''; do
|
|
timeout 10 tail -s0.1 -f $inotify not_here
|
|
test $? = 124 && fail=1
|
|
|
|
if test ! -r unreadable; then # can't test this when root
|
|
timeout 10 tail -s0.1 -f $inotify unreadable
|
|
test $? = 124 && fail=1
|
|
fi
|
|
|
|
timeout 1 tail -s0.1 -f $inotify here 2>tail.err
|
|
test $? = 124 || fail=1
|
|
|
|
# `tail -F' must wait in any case.
|
|
|
|
timeout 1 tail -s0.1 -F $inotify here 2>>tail.err
|
|
test $? = 124 || fail=1
|
|
|
|
if test ! -r unreadable; then # can't test this when root
|
|
timeout 1 tail -s0.1 -F $inotify unreadable
|
|
test $? = 124 || fail=1
|
|
fi
|
|
|
|
timeout 1 tail -s0.1 -F $inotify not_here
|
|
test $? = 124 || fail=1
|
|
|
|
grep -Ev 'inotify (resources exhausted|cannot be used)' tail.err > x
|
|
mv x tail.err
|
|
test -s tail.err && fail=1
|
|
:>tail.err
|
|
|
|
tail_F()
|
|
{
|
|
local delay="$1"
|
|
|
|
touch k || framework_failure
|
|
tail -s.1 --max-unchanged-stats=2 -F $inotify k > tail.out &
|
|
pid=$!
|
|
sleep $delay
|
|
mv k l
|
|
sleep $delay
|
|
touch k
|
|
mv k l
|
|
sleep $delay
|
|
echo NO >> l
|
|
sleep $delay
|
|
kill $pid
|
|
rm -f k l
|
|
|
|
test ! -s tail.out
|
|
}
|
|
retry_delay_ tail_F .1 4 || fail=1
|
|
done
|
|
|
|
Exit $fail
|