From: Pádraig Brady
Date: Sun, 5 Apr 2015 17:21:38 +0000 (+0100) Subject: df: fix --local hanging with inaccessible remote mounts X-Git-Tag: v8.24~87 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1b1c40e1d6f8cf30b6c7c9d31bbddbc3d5cc72e6;p=thirdparty%2Fcoreutils.git df: fix --local hanging with inaccessible remote mounts * src/df.c (filter_mount_list): With -l, avoid stating remote mounts. * init.cfg: Avoid test hangs with inaccessible remote mounts. * tests/df/no-mtab-status.sh: Skip with inaccessible remote mounts. * tests/df/skip-rootfs.sh: Likewise. * tests/df/total-verify.sh: Likewise. * NEWS: Mention the bug fix. Reported at http://bugzilla.redhat.com/1199679 --- diff --git a/NEWS b/NEWS index 4b12e4629c..fc652f11a3 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,9 @@ GNU coreutils NEWS -*- outline -*- dd supports more robust SIGINFO/SIGUSR1 handling for outputting statistics. Previously those signals may have inadvertently terminated the process. + df --local no longer hangs with inaccessible remote mounts. + [bug introduced in coreutils-8.21] + du now silently ignores all directory cycles due to bind mounts. Previously it would issue a warning and exit with a failure status. [bug introduced in coreutils-8.1 and partially fixed in coreutils-8.23] diff --git a/init.cfg b/init.cfg index ada1dcee48..3beba5a9a1 100644 --- a/init.cfg +++ b/init.cfg @@ -79,7 +79,7 @@ is_local_dir_() require_mount_list_() { local mount_list_fail='cannot read table of mounted file systems' - df 2>&1 | grep -F "$mount_list_fail" >/dev/null && + df --local 2>&1 | grep -F "$mount_list_fail" >/dev/null && skip_ "$mount_list_fail" } diff --git a/src/df.c b/src/df.c index 38566811c6..9d4c027404 100644 --- a/src/df.c +++ b/src/df.c @@ -622,13 +622,16 @@ filter_mount_list (bool devices_only) struct devlist *devlist; struct mount_entry *discard_me = NULL; - /* TODO: On Linux we might avoid this stat() and another in get_dev() + /* Avoid stating remote file systems as that may hang. + TODO: On Linux we might avoid this stat() and another in get_dev() by using the device IDs available from /proc/self/mountinfo. read_file_system_list() could populate me_dev from those for efficiency and accuracy. */ - if (-1 == stat (me->me_mountdir, &buf)) + if ((me->me_remote && show_local_fs) + || -1 == stat (me->me_mountdir, &buf)) { - /* Stat failed - add ME to be able to complain about it later. */ + /* If remote, and showing just local, add ME for filtering later. + If stat failed; add ME to be able to complain about it later. */ buf.st_dev = me->me_dev; } else diff --git a/tests/df/no-mtab-status.sh b/tests/df/no-mtab-status.sh index 0c1bec8ef2..49d12558da 100755 --- a/tests/df/no-mtab-status.sh +++ b/tests/df/no-mtab-status.sh @@ -21,7 +21,8 @@ print_ver_ df require_gcc_shared_ -df || skip_ "df fails" +# Protect against inaccessible remote mounts etc. +timeout 10 df || skip_ "df fails" grep '^#define HAVE_MNTENT_H 1' $CONFIG_HEADER > /dev/null \ || skip_ "no mntent.h available to confirm the interface" diff --git a/tests/df/skip-rootfs.sh b/tests/df/skip-rootfs.sh index a3b68e9b26..43ba70b43a 100755 --- a/tests/df/skip-rootfs.sh +++ b/tests/df/skip-rootfs.sh @@ -19,7 +19,8 @@ . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src print_ver_ df -df || skip_ "df fails" +# Protect against inaccessible remote mounts etc. +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 86c6217ded..ba50b03c3d 100755 --- a/tests/df/total-verify.sh +++ b/tests/df/total-verify.sh @@ -20,7 +20,8 @@ print_ver_ df require_perl_ -df || skip_ "df fails" +# Protect against inaccessible remote mounts etc. +timeout 10 df || skip_ "df fails" cat <<\EOF > check-df || framework_failure_ my ($total, $used, $avail) = (0, 0, 0);