On 05/29/2014 03:45 PM, Pádraig Brady wrote:
> 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.

This was incomplete as it didn't also update the "fstype",
so that the incorrect type was shown with df -T.
The attached should fix this.

cheers,
Pádraig.

>From 696595e5719e8a3ca0232fa9979c50028ce10052 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?P=C3=A1draig=20Brady?= <[email protected]>
Date: Tue, 17 Jun 2014 00:18:47 +0100
Subject: [PATCH] df: use all of the last device details provided

* src/df.c (filter_mount_list): Recent commit v8.22-108-g25a2c94
failed to copy file system type along with the updated device name.
Therefore simply replace the existing mount entry with the
current one with all the latest device details.  Note the name,
even if not shorter in this entry, will be replaced with a shorter
name in a subsequent mount entry.
* tests/df/skip-duplicates.sh: Add a test case.
---
 src/df.c                    |   15 +++------------
 tests/df/skip-duplicates.sh |   15 ++++++++-------
 2 files changed, 11 insertions(+), 19 deletions(-)

diff --git a/src/df.c b/src/df.c
index 747d138..10047ce 100644
--- a/src/df.c
+++ b/src/df.c
@@ -642,7 +642,9 @@ filter_mount_list (void)
               if ((strchr (me->me_devname, '/')
                    && ! strchr (devlist->me->me_devname, '/'))
                   || (strlen (devlist->me->me_mountdir)
-                      > strlen (me->me_mountdir)))
+                      > strlen (me->me_mountdir))
+                  /* or one overmounted on a different device.  */
+                  || ! STREQ (devlist->me->me_devname, me->me_devname))
                 {
                   /* Discard mount entry for existing device.  */
                   discard_me = devlist->me;
@@ -652,17 +654,6 @@ filter_mount_list (void)
                 {
                   /* 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 6fb6ff5..a620e73 100755
--- a/tests/df/skip-duplicates.sh
+++ b/tests/df/skip-duplicates.sh
@@ -54,8 +54,8 @@ struct mntent *getmntent (FILE *fp)
     {.mnt_fsname="fsname",  .mnt_dir="/",},
     {.mnt_fsname="/fsname", .mnt_dir="/."},
     {.mnt_fsname="/fsname", .mnt_dir="/"},
-    {.mnt_fsname="virtfs",  .mnt_dir="/NONROOT"},
-    {.mnt_fsname="virtfs2", .mnt_dir="/NONROOT"},
+    {.mnt_fsname="virtfs",  .mnt_dir="/NONROOT", .mnt_type="fstype1"},
+    {.mnt_fsname="virtfs2", .mnt_dir="/NONROOT", .mnt_type="fstype2"},
     {.mnt_fsname="netns",   .mnt_dir="net:[1234567]"},
   };
 
@@ -71,7 +71,8 @@ struct mntent *getmntent (FILE *fp)
 
   while (done++ <= 7)
     {
-      mntents[done-2].mnt_type = "-";
+      if (!mntents[done-2].mnt_type)
+        mntents[done-2].mnt_type = "-";
       if (STREQ (mntents[done-2].mnt_dir, "/NONROOT"))
         mntents[done-2].mnt_dir = nonroot_fs;
       return &mntents[done-2];
@@ -92,11 +93,11 @@ test -f x || skip_ "internal test failure: maybe LD_PRELOAD doesn't work?"
 # The fake mtab file should only contain entries
 # having the same device number; thus the output should
 # consist of a header and unique entries.
-LD_PRELOAD=./k.so df >out || fail=1
+LD_PRELOAD=./k.so df -T >out || fail=1
 test $(wc -l <out) -eq $(expr 1 + $unique_entries) || { fail=1; cat out; }
 
 # Ensure we fail when unable to stat invalid entries
-LD_PRELOAD=./k.so CU_TEST_DUPE_INVALID=1 df >out && fail=1
+LD_PRELOAD=./k.so CU_TEST_DUPE_INVALID=1 df -T >out && fail=1
 test $(wc -l <out) -eq $(expr 1 + $unique_entries) || { fail=1; cat out; }
 
 # df should also prefer "/fsname" over "fsname"
@@ -106,8 +107,8 @@ if test "$unique_entries" = 2; then
   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; }
+# df should use the last seen devname (mnt_fsname) and devtype (mnt_type)
+test $(grep -c 'virtfs2.*fstype2' <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