Subject: bug#28506: coreutils 8.28 test suite hangs on APFS filesystem

From: Pádraig Brady <[email-masked]>
Date: Wed, 20 Sep 2017 22:20:06 -0700

On 18/09/17 18:07, Jack Howarth wrote:
> On Mon, Sep 18, 2017 at 7:40 PM, Jim Meyering <[email-masked]> wrote:
> 
>> On Mon, Sep 18, 2017 at 4:26 PM, Jack Howarth
>> <[email-masked]> wrote:
>>> On Mon, Sep 18, 2017 at 5:08 PM, Jim Meyering <[email-masked]> wrote:
>> ...
>>>> Is there any chance your failing test was via a python2 framework? I'm
>>>> asking (on Pádraig's behalf) because there is a known problem whereby
>>>> SIGPIPE is mishandled in that case, and that might explain this
>>>> failure, since the data-generation phase relies on SIGPIPE killing
>>>> this test's "yes" command.
>>>
>>> I doubt it as the hang doesn't happen under 10.13 when run on a JHFS
>>> formatted volume.
>>
>> How did you run the tests?
>>
> 
> Actually, I forgot to mention that the coreutils test suite hang only
> occurred on the APFS volumes when the coreutils built against the gettext
> and libiconv from fink. A build outside of fink which didn't build against
> those packages didn't show the hang in the coreutils test suite. The fink
> gettext and libiconv packages that I am using are those from...
> 
> https://sourceforge.net/p/fink/package-submissions/4955/
> 
> and
> 
> https://sourceforge.net/p/fink/package-submissions/5004/
> 
> which are both patched for the format string strictness in High Sierra. I
> found that using --disable-nls in configuring coreutils was insufficient to
> suppress the test suite hang which I assume is due to the presence of...
> 
> #define HAVE_LIBINTL_H 1
> 
> in the generated ./lib/config.h
> 
> despite the presence of...
> 
> /* #undef HAVE_DCGETTEXT */
> /* #undef HAVE_GETTEXT */
> 
> when --disable-nls is used so it still could be a Unicode related change in
> APFS, no?
>       Jack

The libintl bit reminded me of https://lists.gnu.org/archive/html/bug-gnulib/2014-10/msg00014.html
I.E. on OSX enabling those libs creates implicit threads I think.
Perhaps that's messing with SIGPIPE handling and only the implicit
thread gets it, thus not killing the main yes(1) thread.
However the yes(1) is also protected with a timeout(1) call.
Perhaps timeout(1) is a silent noop. We should support OSX through DYLD_INSERT_LIBRARIES,
but perhaps there is something preventing that on your system?
But then would the timeout tests fail. Could you check the timeout tests with:

  make SUBDIRS=. TESTS=tests/misc/filter.sh check

In any case we should protect calls to timeout(1) to ensure it's supported.
The attached does that at least.

cheers,
Pádraig.
From c003741b9e39d354d94a786dc86e5b97b01e4680 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?P=C3=A1draig=20Brady?= <[email-masked]>
Date: Wed, 20 Sep 2017 22:15:04 -0700
Subject: [PATCH] tests: ensure the timeout command works if used

* init.cfg (require_timeout_): A new function.
* tests/*: Add require_timeout_ if timeout(1) is called.
* tests/split/filter.sh: Likewise. Also remove a duplicate clause,
and simply and use of timeout(1) by removing a subshell.
---
 init.cfg                                 |  8 +++++++-
 tests/cp/fiemap-extents.sh               |  1 +
 tests/cp/fiemap-perf.sh                  |  2 ++
 tests/cp/parent-perm-race.sh             |  2 ++
 tests/cp/sparse-to-pipe.sh               |  1 +
 tests/dd/no-allocate.sh                  |  2 ++
 tests/dd/skip-seek-past-dev.sh           |  1 +
 tests/dd/stats.sh                        |  1 +
 tests/df/no-mtab-status.sh               |  1 +
 tests/df/skip-rootfs.sh                  |  4 +++-
 tests/df/total-verify.sh                 |  3 ++-
 tests/du/move-dir-while-traversing.sh    |  2 +-
 tests/ls/infloop.sh                      |  2 ++
 tests/ls/readdir-mountpoint-inode.sh     |  2 ++
 tests/misc/head-write-error.sh           |  2 ++
 tests/misc/seq-epipe.sh                  |  2 ++
 tests/misc/seq-io-errors.sh              |  2 ++
 tests/misc/shred-remove.sh               |  1 +
 tests/misc/shuf.sh                       |  1 +
 tests/misc/sleep.sh                      |  1 +
 tests/misc/sort-NaN-infloop.sh           |  1 +
 tests/misc/sort-compress-hang.sh         |  1 +
 tests/misc/sort-exit-early.sh            |  1 +
 tests/misc/sync.sh                       |  2 ++
 tests/misc/tee.sh                        |  2 ++
 tests/misc/truncate-fifo.sh              |  1 +
 tests/misc/uniq-perf.sh                  |  1 +
 tests/rm/ext3-perf.sh                    |  1 +
 tests/rm/r-root.sh                       |  2 ++
 tests/split/filter.sh                    | 13 ++++---------
 tests/tail-2/follow-name.sh              |  2 ++
 tests/tail-2/follow-stdin.sh             |  2 ++
 tests/tail-2/inotify-dir-recreate.sh     |  2 ++
 tests/tail-2/inotify-only-regular.sh     |  2 ++
 tests/tail-2/inotify-race.sh             |  1 +
 tests/tail-2/inotify-race2.sh            |  1 +
 tests/tail-2/inotify-rotate-resources.sh |  2 ++
 tests/tail-2/inotify-rotate.sh           |  2 ++
 tests/tail-2/pid.sh                      |  1 +
 tests/tail-2/pipe-f.sh                   |  2 ++
 tests/tail-2/pipe-f2.sh                  |  2 +-
 tests/tail-2/retry.sh                    |  2 ++
 tests/tail-2/symlink.sh                  |  2 ++
 tests/tail-2/wait.sh                     |  2 ++
 44 files changed, 77 insertions(+), 14 deletions(-)

diff --git a/init.cfg b/init.cfg
index 71582e8..4896c9a 100644
--- a/init.cfg
+++ b/init.cfg
@@ -314,7 +314,13 @@ require_built_()
     esac
   done
 
-  test $skip_ = yes && skip_ "required program(s) not built"
+  test $skip_ = yes && skip_ 'required program(s) not built'
+  return 0
+}
+
+require_timeout_() {
+  require_built_ 'timeout' && timeout 0.001 sleep 10
+  test $? = 124 || skip_ 'timeout support required'
 }
 
 require_file_system_bytes_free_()
diff --git a/tests/cp/fiemap-extents.sh b/tests/cp/fiemap-extents.sh
index 5f235ed..c822bcd 100755
--- a/tests/cp/fiemap-extents.sh
+++ b/tests/cp/fiemap-extents.sh
@@ -19,6 +19,7 @@
 . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
 print_ver_ cp
 
+require_timeout_
 require_sparse_support_
 
 touch fiemap_chk || framework_failure_
diff --git a/tests/cp/fiemap-perf.sh b/tests/cp/fiemap-perf.sh
index e122537..74bee5c 100755
--- a/tests/cp/fiemap-perf.sh
+++ b/tests/cp/fiemap-perf.sh
@@ -19,6 +19,8 @@
 . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
 print_ver_ cp
 
+require_timeout_
+
 # Require a fiemap-enabled FS.
 touch fiemap_chk
 fiemap_capable_ fiemap_chk ||
diff --git a/tests/cp/parent-perm-race.sh b/tests/cp/parent-perm-race.sh
index 68fb721..3bdd721 100755
--- a/tests/cp/parent-perm-race.sh
+++ b/tests/cp/parent-perm-race.sh
@@ -19,6 +19,8 @@
 . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
 print_ver_ cp
 
+require_timeout_
+
 # cp -p gives ENOTSUP on NFS on Linux 2.6.9 at least
 require_local_dir_
 
diff --git a/tests/cp/sparse-to-pipe.sh b/tests/cp/sparse-to-pipe.sh
index 3f13b37..288f366 100755
--- a/tests/cp/sparse-to-pipe.sh
+++ b/tests/cp/sparse-to-pipe.sh
@@ -19,6 +19,7 @@
 . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
 print_ver_ cp
 
+require_timeout_
 require_sparse_support_
 
 # Terminate any background cp process
diff --git a/tests/dd/no-allocate.sh b/tests/dd/no-allocate.sh
index 43d6ecd..06ec6d6 100755
--- a/tests/dd/no-allocate.sh
+++ b/tests/dd/no-allocate.sh
@@ -19,6 +19,8 @@
 . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
 print_ver_ dd
 
+require_timeout_
+
 # Determine basic amount of memory needed.
 echo . > f || framework_failure_
 vm=$(get_min_ulimit_v_ timeout 10 dd if=f of=f2 status=none) \
diff --git a/tests/dd/skip-seek-past-dev.sh b/tests/dd/skip-seek-past-dev.sh
index f3cfb53..ebd1fae 100755
--- a/tests/dd/skip-seek-past-dev.sh
+++ b/tests/dd/skip-seek-past-dev.sh
@@ -19,6 +19,7 @@
 . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
 print_ver_ dd
 
+require_timeout_
 # need write access to local device
 # (even though we don't actually write anything)
 require_root_
diff --git a/tests/dd/stats.sh b/tests/dd/stats.sh
index 3e6fc14..d2bb4ac 100755
--- a/tests/dd/stats.sh
+++ b/tests/dd/stats.sh
@@ -19,6 +19,7 @@
 . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
 print_ver_ dd
 require_trap_signame_
+require_timeout_
 
 kill -l | grep 'INFO' && SIGINFO='INFO' || SIGINFO='USR1'
 
diff --git a/tests/df/no-mtab-status.sh b/tests/df/no-mtab-status.sh
index 319d58b..b6d53a2 100755
--- a/tests/df/no-mtab-status.sh
+++ b/tests/df/no-mtab-status.sh
@@ -20,6 +20,7 @@
 . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
 print_ver_ df
 require_gcc_shared_
+require_timeout_
 
 # Protect against inaccessible remote mounts etc.
 timeout 10 df || skip_ "df fails"
diff --git a/tests/df/skip-rootfs.sh b/tests/df/skip-rootfs.sh
index 425cbc8..82a9d2a 100755
--- a/tests/df/skip-rootfs.sh
+++ b/tests/df/skip-rootfs.sh
@@ -19,8 +19,10 @@
 . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
 print_ver_ df
 
+require_timeout_
+
 # Protect against inaccessible remote mounts etc.
-timeout 10 df || skip_ "df fails"
+timeout 10 df || skip_ 'df fails'
 
 # Verify that rootfs is in mtab (and shown when the -a option is specified).
 # Note this is the case when /proc/self/mountinfo is parsed
diff --git a/tests/df/total-verify.sh b/tests/df/total-verify.sh
index 5256e71..43a694a 100755
--- a/tests/df/total-verify.sh
+++ b/tests/df/total-verify.sh
@@ -19,9 +19,10 @@
 . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
 print_ver_ df
 require_perl_
+require_timeout_
 
 # Protect against inaccessible remote mounts etc.
-timeout 10 df || skip_ "df fails"
+timeout 10 df || skip_ 'df fails'
 
 cat <<\EOF > check-df || framework_failure_
 my ($total, $used, $avail) = (0, 0, 0);
diff --git a/tests/du/move-dir-while-traversing.sh b/tests/du/move-dir-while-traversing.sh
index 70fa22e..f03f77c 100755
--- a/tests/du/move-dir-while-traversing.sh
+++ b/tests/du/move-dir-while-traversing.sh
@@ -19,7 +19,7 @@
 . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
 print_ver_ du
 require_trap_signame_
-
+require_timeout_
 # We use a python-inotify script, so...
 python -m pyinotify -h > /dev/null \
   || skip_ 'python inotify package not installed'
diff --git a/tests/ls/infloop.sh b/tests/ls/infloop.sh
index 643f177..3fe7e7d 100755
--- a/tests/ls/infloop.sh
+++ b/tests/ls/infloop.sh
@@ -20,6 +20,8 @@
 . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
 print_ver_ ls
 
+require_timeout_
+
 mkdir loop || framework_failure_
 ln -s ../loop loop/sub || framework_failure_
 
diff --git a/tests/ls/readdir-mountpoint-inode.sh b/tests/ls/readdir-mountpoint-inode.sh
index b4ca9e4..08bdeed 100755
--- a/tests/ls/readdir-mountpoint-inode.sh
+++ b/tests/ls/readdir-mountpoint-inode.sh
@@ -19,6 +19,8 @@
 . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
 print_ver_ ls
 
+require_timeout_
+
 # We use --local here so as to not activate
 # potentially very many remote mounts.
 df --local --out=target | sed -n '/^\/./p' > mount_points
diff --git a/tests/misc/head-write-error.sh b/tests/misc/head-write-error.sh
index cba591a..7af2520 100755
--- a/tests/misc/head-write-error.sh
+++ b/tests/misc/head-write-error.sh
@@ -20,6 +20,8 @@
 . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
 print_ver_ head
 
+require_timeout_
+
 if ! test -w /dev/full || ! test -c /dev/full; then
   skip_ '/dev/full is required'
 fi
diff --git a/tests/misc/seq-epipe.sh b/tests/misc/seq-epipe.sh
index 43ff2c7..890cc1f 100755
--- a/tests/misc/seq-epipe.sh
+++ b/tests/misc/seq-epipe.sh
@@ -19,6 +19,8 @@
 . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
 print_ver_ seq
 
+require_timeout_
+
 (trap '' PIPE && yes | :) 2>&1 | grep -qF 'Broken pipe' ||
     skip_ 'trapping SIGPIPE is not supported'
 
diff --git a/tests/misc/seq-io-errors.sh b/tests/misc/seq-io-errors.sh
index fd6924e..410aaca 100755
--- a/tests/misc/seq-io-errors.sh
+++ b/tests/misc/seq-io-errors.sh
@@ -19,6 +19,8 @@
 . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
 print_ver_ seq
 
+require_timeout_
+
 if ! test -w /dev/full || ! test -c /dev/full; then
   skip_ '/dev/full is required'
 fi
diff --git a/tests/misc/shred-remove.sh b/tests/misc/shred-remove.sh
index 8720eaf..da9fc47 100755
--- a/tests/misc/shred-remove.sh
+++ b/tests/misc/shred-remove.sh
@@ -19,6 +19,7 @@
 . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
 print_ver_ shred
 skip_if_root_
+require_timeout_
 
 # The length of the basename is what matters.
 # In this case, shred-4.0l would try to rename the file 256^10 times
diff --git a/tests/misc/shuf.sh b/tests/misc/shuf.sh
index 66364d4..bef0575 100755
--- a/tests/misc/shuf.sh
+++ b/tests/misc/shuf.sh
@@ -19,6 +19,7 @@
 . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
 print_ver_ shuf
 getlimits_
+require_timeout_
 
 seq 100 > in || framework_failure_
 
diff --git a/tests/misc/sleep.sh b/tests/misc/sleep.sh
index 0397b7b..e8f57d7 100755
--- a/tests/misc/sleep.sh
+++ b/tests/misc/sleep.sh
@@ -19,6 +19,7 @@
 . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
 print_ver_ sleep
 getlimits_
+require_timeout_
 
 # invalid timeouts
 returns_ 1 timeout 10 sleep invalid || fail=1
diff --git a/tests/misc/sort-NaN-infloop.sh b/tests/misc/sort-NaN-infloop.sh
index e7e49a2..5e00dcb 100755
--- a/tests/misc/sort-NaN-infloop.sh
+++ b/tests/misc/sort-NaN-infloop.sh
@@ -18,6 +18,7 @@
 
 . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
 print_ver_ sort
+require_timeout_
 
 echo nan > F || framework_failure_
 printf 'nan\nnan\n' > exp || framework_failure_
diff --git a/tests/misc/sort-compress-hang.sh b/tests/misc/sort-compress-hang.sh
index e76409f..076788b 100755
--- a/tests/misc/sort-compress-hang.sh
+++ b/tests/misc/sort-compress-hang.sh
@@ -19,6 +19,7 @@
 . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
 print_ver_ sort
 very_expensive_
+require_timeout_
 
 cat <<EOF >compress || framework_failure_
 #!$SHELL
diff --git a/tests/misc/sort-exit-early.sh b/tests/misc/sort-exit-early.sh
index 2ce7c5b..8708ddb 100755
--- a/tests/misc/sort-exit-early.sh
+++ b/tests/misc/sort-exit-early.sh
@@ -19,6 +19,7 @@
 . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
 print_ver_ sort
 skip_if_root_
+require_timeout_
 
 SORT_FAILURE=2
 
diff --git a/tests/misc/sync.sh b/tests/misc/sync.sh
index bf1b4f1..4b4deab 100755
--- a/tests/misc/sync.sh
+++ b/tests/misc/sync.sh
@@ -19,6 +19,8 @@
 . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
 print_ver_ sync
 
+require_timeout_
+
 touch file
 
 # fdatasync+syncfs is nonsensical
diff --git a/tests/misc/tee.sh b/tests/misc/tee.sh
index 5998c5a..eb39e6b 100755
--- a/tests/misc/tee.sh
+++ b/tests/misc/tee.sh
@@ -19,6 +19,8 @@
 . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
 print_ver_ tee
 
+require_timeout_
+
 echo line >sample || framework_failure_
 
 # POSIX says: "Processing of at least 13 file operands shall be supported."
diff --git a/tests/misc/truncate-fifo.sh b/tests/misc/truncate-fifo.sh
index e84fa54..2fa6beb 100755
--- a/tests/misc/truncate-fifo.sh
+++ b/tests/misc/truncate-fifo.sh
@@ -18,6 +18,7 @@
 
 . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
 print_ver_ truncate
+require_timeout_
 
 mkfifo_or_skip_ fifo
 
diff --git a/tests/misc/uniq-perf.sh b/tests/misc/uniq-perf.sh
index 70ef28c..936f318 100755
--- a/tests/misc/uniq-perf.sh
+++ b/tests/misc/uniq-perf.sh
@@ -18,6 +18,7 @@
 
 . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
 print_ver_ uniq
+require_timeout_
 
 seq 100 > in || fail=1
 timeout 10 uniq -f 10000000000 in || fail=1
diff --git a/tests/rm/ext3-perf.sh b/tests/rm/ext3-perf.sh
index 0fe8efe..b2abecd 100755
--- a/tests/rm/ext3-perf.sh
+++ b/tests/rm/ext3-perf.sh
@@ -18,6 +18,7 @@
 
 . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
 print_ver_ rm
+require_timeout_
 
 very_expensive_
 
diff --git a/tests/rm/r-root.sh b/tests/rm/r-root.sh
index edc3542..7800809 100755
--- a/tests/rm/r-root.sh
+++ b/tests/rm/r-root.sh
@@ -19,6 +19,8 @@
 . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
 print_ver_ rm
 
+require_timeout_
+
 # POSIX mandates rm(1) to skip '/' arguments.  This test verifies this mandated
 # behavior as well as the --preserve-root and --no-preserve-root options.
 # Especially the latter case is a live fire exercise as rm(1) is supposed to
diff --git a/tests/split/filter.sh b/tests/split/filter.sh
index 96602bd..e8dcdc6 100755
--- a/tests/split/filter.sh
+++ b/tests/split/filter.sh
@@ -18,8 +18,9 @@
 
 . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
 print_ver_ split
+require_timeout_
 require_sparse_support_ # for 'truncate --size=$LARGE'
-xz --version || skip_ "xz (better than gzip/bzip2) required"
+xz --version || skip_ 'xz (better than gzip/bzip2) required'
 
 for total_n_lines in 5 3000 20000; do
   seq $total_n_lines > in || framework_failure_
@@ -60,8 +61,8 @@ for mode in '' 'r/'; do
   fi
   for N in 1 2; do
     rm -f x??.n || framework_failure_
-    timeout 10 sh -c \
-      "yes | split --filter='head -c1 >\$FILE.n' -n $mode$N $FILE" || fail=1
+    yes | timeout 10 split --filter='head -c1 >$FILE.n' -n $mode$N $FILE \
+      || fail=1
     # Also ensure we get appropriate output from each filter
     seq 1 $N | tr '0-9' 1 > stat.exp
     stat -c%s x??.n > stat.out || framework_failure_
@@ -75,10 +76,4 @@ for buf in 1000 1000000; do
     "yes | split --filter='head -c1 >/dev/null' -b $buf" || fail=1
 done
 
-# Ensure that "endless" input _is_ processed for unbounded number of filters
-for buf in 1000 1000000; do
-  returns_ 124 timeout .5 sh -c \
-    "yes | split --filter='head -c1 >/dev/null' -b $buf" || fail=1
-done
-
 Exit $fail
diff --git a/tests/tail-2/follow-name.sh b/tests/tail-2/follow-name.sh
index 01f0ff2..3b51be9 100755
--- a/tests/tail-2/follow-name.sh
+++ b/tests/tail-2/follow-name.sh
@@ -19,6 +19,8 @@
 . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
 print_ver_ tail
 
+require_timeout_
+
 cat <<\EOF > exp || framework_failure_
 tail: cannot open 'no-such' for reading: No such file or directory
 tail: no files remaining
diff --git a/tests/tail-2/follow-stdin.sh b/tests/tail-2/follow-stdin.sh
index 7df8350..a865d83 100755
--- a/tests/tail-2/follow-stdin.sh
+++ b/tests/tail-2/follow-stdin.sh
@@ -19,6 +19,8 @@
 . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
 print_ver_ tail
 
+require_timeout_
+
 #################
 # tail -f - would fail with the initial inotify implementation
 
diff --git a/tests/tail-2/inotify-dir-recreate.sh b/tests/tail-2/inotify-dir-recreate.sh
index 3c33153..6ee242f 100755
--- a/tests/tail-2/inotify-dir-recreate.sh
+++ b/tests/tail-2/inotify-dir-recreate.sh
@@ -21,6 +21,8 @@
 . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
 print_ver_ tail
 
+require_timeout_
+
 grep '^#define HAVE_INOTIFY 1' "$CONFIG_HEADER" >/dev/null && is_local_dir_ . \
   || skip_ 'inotify is not supported'
 
diff --git a/tests/tail-2/inotify-only-regular.sh b/tests/tail-2/inotify-only-regular.sh
index f48e36f..0363473 100755
--- a/tests/tail-2/inotify-only-regular.sh
+++ b/tests/tail-2/inotify-only-regular.sh
@@ -19,6 +19,8 @@
 . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
 print_ver_ tail
 
+require_timeout_
+
 grep '^#define HAVE_INOTIFY 1' "$CONFIG_HEADER" >/dev/null \
   || skip_ 'inotify support required'
 
diff --git a/tests/tail-2/inotify-race.sh b/tests/tail-2/inotify-race.sh
index 433a173..ad55f82 100755
--- a/tests/tail-2/inotify-race.sh
+++ b/tests/tail-2/inotify-race.sh
@@ -22,6 +22,7 @@
 
 . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
 print_ver_ tail sleep
+require_timeout_
 
 # Terminate any background gdb/tail process
 cleanup_() {
diff --git a/tests/tail-2/inotify-race2.sh b/tests/tail-2/inotify-race2.sh
index ffbf29f..e0fd716 100755
--- a/tests/tail-2/inotify-race2.sh
+++ b/tests/tail-2/inotify-race2.sh
@@ -21,6 +21,7 @@
 
 . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
 print_ver_ tail sleep
+require_timeout_
 
 # Terminate any background gdb/tail process
 cleanup_() {
diff --git a/tests/tail-2/inotify-rotate-resources.sh b/tests/tail-2/inotify-rotate-resources.sh
index 82d6713..a7b12fc 100755
--- a/tests/tail-2/inotify-rotate-resources.sh
+++ b/tests/tail-2/inotify-rotate-resources.sh
@@ -19,6 +19,8 @@
 . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
 print_ver_ tail
 
+require_timeout_
+
 # Inotify not used on remote file systems
 require_local_dir_
 
diff --git a/tests/tail-2/inotify-rotate.sh b/tests/tail-2/inotify-rotate.sh
index 4b4cff2..0fd58a4 100755
--- a/tests/tail-2/inotify-rotate.sh
+++ b/tests/tail-2/inotify-rotate.sh
@@ -19,6 +19,8 @@
 . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
 print_ver_ tail
 
+require_timeout_
+
 grep '^#define HAVE_INOTIFY 1' "$CONFIG_HEADER" >/dev/null \
   || expensive_
 
diff --git a/tests/tail-2/pid.sh b/tests/tail-2/pid.sh
index 7121d68..20856e2 100755
--- a/tests/tail-2/pid.sh
+++ b/tests/tail-2/pid.sh
@@ -18,6 +18,7 @@
 
 . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
 print_ver_ tail
+require_timeout_
 getlimits_
 
 touch empty here || framework_failure_
diff --git a/tests/tail-2/pipe-f.sh b/tests/tail-2/pipe-f.sh
index 759881c..134e4bf 100755
--- a/tests/tail-2/pipe-f.sh
+++ b/tests/tail-2/pipe-f.sh
@@ -19,6 +19,8 @@
 . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
 print_ver_ tail
 
+require_timeout_
+
 # Speedup the non inotify case
 fastpoll='-s.1 --max-unchanged-stats=1'
 
diff --git a/tests/tail-2/pipe-f2.sh b/tests/tail-2/pipe-f2.sh
index c7e429e..903ac1d 100755
--- a/tests/tail-2/pipe-f2.sh
+++ b/tests/tail-2/pipe-f2.sh
@@ -18,7 +18,7 @@
 
 . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
 print_ver_ tail
-
+require_timeout_
 mkfifo_or_skip_ fifo
 
 echo 1 > fifo &
diff --git a/tests/tail-2/retry.sh b/tests/tail-2/retry.sh
index abe0d67..79e8bda 100755
--- a/tests/tail-2/retry.sh
+++ b/tests/tail-2/retry.sh
@@ -19,6 +19,8 @@
 . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
 print_ver_ tail
 
+require_timeout_
+
 # Function to count number of lines from tail
 # while ignoring transient errors due to resource limits
 countlines_ ()
diff --git a/tests/tail-2/symlink.sh b/tests/tail-2/symlink.sh
index 1bbd577..fa34979 100755
--- a/tests/tail-2/symlink.sh
+++ b/tests/tail-2/symlink.sh
@@ -19,6 +19,8 @@
 . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
 print_ver_ tail
 
+require_timeout_
+
 # Function to count number of lines from tail
 # while ignoring transient errors due to resource limits
 countlines_ ()
diff --git a/tests/tail-2/wait.sh b/tests/tail-2/wait.sh
index c79fc66..b79de6f 100755
--- a/tests/tail-2/wait.sh
+++ b/tests/tail-2/wait.sh
@@ -20,6 +20,8 @@
 . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
 print_ver_ tail
 
+require_timeout_
+
 grep '^#define HAVE_INOTIFY 1' "$CONFIG_HEADER" >/dev/null \
   && HAVE_INOTIFY=1
 
-- 
2.9.3