coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] df: use the last device name provided by the system


From: Pádraig Brady
Subject: [PATCH] df: use the last device name provided by the system
Date: Thu, 29 May 2014 15:45:21 +0100

The device name reported for a particular mount entry
may no longer be valid if the mount point was subsequently
mounted on a different device.  Therefore honor the order
of the mount list returned by the system and use the last
reported device name.

* src/df.c (filter_mount_list): When discarding the current
mount entry, ensure that a new device name is not also discarded.
* tests/df/skip-duplicates.sh: Add a test case.  Also fix
a false failure in the edge case of a system with only a
single file system.
---
 src/df.c                    |   22 +++++++++++++++++++---
 tests/df/skip-duplicates.sh |   13 +++++++++----
 2 files changed, 28 insertions(+), 7 deletions(-)

diff --git a/src/df.c b/src/df.c
index 01ecca6..82b0c5f 100644
--- a/src/df.c
+++ b/src/df.c
@@ -604,7 +604,7 @@ excluded_fstype (const char *fstype)
 }
 
 /* Filter mount list by skipping duplicate entries.
-   In the case of duplicities - based on to the device number - the mount entry
+   In the case of duplicities - based on the device number - the mount entry
    with a '/' in its me_devname (i.e. not pseudo name like tmpfs) wins.
    If both have a real devname (e.g. bind mounts), then that with the shorter
    me_mountdir wins.  */
@@ -638,17 +638,33 @@ filter_mount_list (void)
 
           if (devlist)
             {
-              discard_me = me;
-
               /* ...let the shorter mountdir win.  */
               if ((strchr (me->me_devname, '/')
                    && ! strchr (devlist->me->me_devname, '/'))
                   || (strlen (devlist->me->me_mountdir)
                       > strlen (me->me_mountdir)))
                 {
+                  /* Discard mount entry for existing device.  */
                   discard_me = devlist->me;
                   devlist->me = me;
                 }
+              else
+                {
+                  /* Discard mount entry currently being processed.  */
+                  discard_me = me;
+
+                  /* We might still want the devname from this mount entry as
+                     the dev_num might not correlate with st_dev if another
+                     device is subsequently overmounted at mountdir, so honor
+                     the order of the presented list and replace with the
+                     latest devname encountered.  */
+                  if (! STREQ (devlist->me->me_devname, me->me_devname))
+                    {
+                      free (devlist->me->me_devname);
+                      devlist->me->me_devname = xstrdup (me->me_devname);
+                    }
+                }
+
             }
         }
 
diff --git a/tests/df/skip-duplicates.sh b/tests/df/skip-duplicates.sh
index 44f7d4c..6fb6ff5 100755
--- a/tests/df/skip-duplicates.sh
+++ b/tests/df/skip-duplicates.sh
@@ -55,7 +55,7 @@ struct mntent *getmntent (FILE *fp)
     {.mnt_fsname="/fsname", .mnt_dir="/."},
     {.mnt_fsname="/fsname", .mnt_dir="/"},
     {.mnt_fsname="virtfs",  .mnt_dir="/NONROOT"},
-    {.mnt_fsname="virtfs",  .mnt_dir="/NONROOT"},
+    {.mnt_fsname="virtfs2", .mnt_dir="/NONROOT"},
     {.mnt_fsname="netns",   .mnt_dir="net:[1234567]"},
   };
 
@@ -100,9 +100,14 @@ LD_PRELOAD=./k.so CU_TEST_DUPE_INVALID=1 df >out && fail=1
 test $(wc -l <out) -eq $(expr 1 + $unique_entries) || { fail=1; cat out; }
 
 # df should also prefer "/fsname" over "fsname"
-test $(grep -c '/fsname' <out) -eq 1 || { fail=1; cat out; }
-# ... and "/fsname" with '/' as Mounted on over '/.'
-test $(grep -cF '/.' <out) -eq 0 || { fail=1; cat out; }
+if test "$unique_entries" = 2; then
+  test $(grep -c '/fsname' <out) -eq 1 || { fail=1; cat out; }
+  # ... and "/fsname" with '/' as Mounted on over '/.'
+  test $(grep -cF '/.' <out) -eq 0 || { fail=1; cat out; }
+fi
+
+# df should use the last seen devname (mnt_fsname)
+test $(grep -c 'virtfs2' <out) -eq 1 || { fail=1; cat out; }
 
 # Ensure that filtering duplicates does not affect -a processing.
 LD_PRELOAD=./k.so df -a >out || fail=1
-- 
1.7.7.6




reply via email to

[Prev in Thread] Current Thread [Next in Thread]