On 12/18/2013 05:39 PM, Eric Blake wrote:
> On 12/18/2013 09:46 AM, Jeff Kirkpatrick wrote:
>> However, I don't see explicit reasons for the non-zero exit code. If you
>> want to ask for the reason, you may write an emailto coreutils@gnu.org."
>>
>> Can anyone elaborate on why the decision to use a non-zero exit code?
> 
> Because POSIX requires a non-zero exit code any time an error message is
> output, including when a directory is skipped due to a directory loop.
> 
> http://pubs.opengroup.org/onlinepubs/9699919799/utilities/du.html

We suppress the cycle warning when following symlinks
as it's not an error in that case.
Similarly we should suppress the cycle warning for bind mounts
as it's not an error in that case either.
Hence I propose the attached to avoid the exit failure in this case.

I'm not considering other tools that emit_cycle_warning() yet,
as they're less likely to be used in such cases.

thanks,
Pádraig.
>From 6c69b9f4639ac291db82eefb4aab25de36869672 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?P=C3=A1draig=20Brady?= <p...@draigbrady.com>
Date: Thu, 19 Jun 2014 12:11:00 +0100
Subject: [PATCH] du: ignore directory cycles due to bind mounts

* src/du.c (process_file): Treat cycles due to bind mounts
like cycles due to following symlinks.
* tests/du/bind-mount-dir-cycle.sh: Adjust accordingly.
* NEWS: Mention the change in behavior.
Reported at http://bugzilla.redhat.com/836557
---
 NEWS                             |    3 +++
 src/du.c                         |   12 ++++--------
 tests/du/bind-mount-dir-cycle.sh |    5 ++---
 3 files changed, 9 insertions(+), 11 deletions(-)

diff --git a/NEWS b/NEWS
index 77286f8..d3c2368 100644
--- a/NEWS
+++ b/NEWS
@@ -48,6 +48,9 @@ GNU coreutils NEWS                                    -*- outline -*-
   display the correct device name for directories mounted multiple times.
   [These bugs were present in "the beginning".]
 
+  du now silently ignores directory cycles introduced with bind mounts.
+  Previously it would issue a warning and exit with a failure status.
+
   head --bytes=-N and --lines=-N now handles devices more
   consistently, not ignoring data from virtual devices like /dev/zero,
   or on BSD systems data from tty devices.
diff --git a/src/du.c b/src/du.c
index e4509fd..0966326 100644
--- a/src/du.c
+++ b/src/du.c
@@ -514,15 +514,11 @@ process_file (FTS *fts, FTSENT *ent)
           break;
 
         case FTS_DC:
-          if (cycle_warning_required (fts, ent))
+          /* If not following symlinks and not a (bind) mount point.  */
+          if (cycle_warning_required (fts, ent)
+              && ! di_set_lookup (di_mnt, sb->st_dev, sb->st_ino))
             {
-              /* If this is a mount point, then diagnose it and avoid
-                 the cycle.  */
-              if (di_set_lookup (di_mnt, sb->st_dev, sb->st_ino))
-                error (0, 0, _("mount point %s already traversed"),
-                       quote (file));
-              else
-                emit_cycle_warning (file);
+              emit_cycle_warning (file);
               return false;
             }
           return true;
diff --git a/tests/du/bind-mount-dir-cycle.sh b/tests/du/bind-mount-dir-cycle.sh
index 4fef345..ac6bf2e 100755
--- a/tests/du/bind-mount-dir-cycle.sh
+++ b/tests/du/bind-mount-dir-cycle.sh
@@ -27,12 +27,11 @@ mount --bind a a/b \
   || skip_ "This test requires mount with a working --bind option."
 
 echo a > exp || framework_failure_
-echo "du: mount point 'a/b' already traversed" > exp-err || framework_failure_
 
-du a > out 2> err && fail=1
+du a > out 2> err || fail=1
 sed 's/^[0-9][0-9]*	//' out > k && mv k out
 
-compare exp-err err || fail=1
+compare /dev/null err || fail=1
 compare exp out || fail=1
 
 Exit $fail
-- 
1.7.7.6

Reply via email to