740027
From e82cfd53cfd127e5877aefa5ea1d50bfe71d1788 Mon Sep 17 00:00:00 2001
740027
From: Fridolin Pokorny <fpokorny@redhat.com>
740027
Date: Wed, 27 Aug 2014 15:25:30 +0200
740027
Subject: [PATCH 1/9] mountlist: use /proc/self/mountinfo when available
740027
740027
Use libmount to propagate device IDs provided by Linux in
740027
/proc/self/mountinfo.  This will give more accurate output when
740027
using df in chroot'ed environments as the device IDs are not
740027
determined by stat() which may be inaccurate within the chroot.
740027
740027
* lib/mountlist.c (read_file_system_list): Use the libmount routines
740027
from util-linux to parse "/proc/self/mountinfo" or fall back to
740027
standard getmntent() processing.
740027
* m4/ls-mntd-fs.m4: Check for libmount only when 1-argument
740027
getmntent() is used, as is the case on GNU/Linux.
740027
* DEPENDENCIES: Mention the optional util-linux dependency.
740027
740027
Upstream-commit: 3ea43e02541ece750ffc6cd1dfe34195421b4ef3
740027
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
740027
---
740027
 lib/mountlist.c  | 82 ++++++++++++++++++++++++++++++++++++------------
740027
 m4/ls-mntd-fs.m4 | 15 ++++++++-
740027
 2 files changed, 76 insertions(+), 21 deletions(-)
740027
740027
diff --git a/lib/mountlist.c b/lib/mountlist.c
740027
index 17779f6..617fa88 100644
740027
--- a/lib/mountlist.c
740027
+++ b/lib/mountlist.c
740027
@@ -128,6 +128,12 @@
740027
 # include <sys/mntent.h>
740027
 #endif
740027
 
740027
+#ifdef MOUNTED_PROC_MOUNTINFO
740027
+/* Use /proc/self/mountinfo instead of /proc/self/mounts (/etc/mtab)
740027
+ * on Linux, if available */
740027
+# include <libmount/libmount.h>
740027
+#endif
740027
+
740027
 #ifndef HAVE_HASMNTOPT
740027
 # define hasmntopt(mnt, opt) ((char *) 0)
740027
 #endif
740027
@@ -430,32 +436,68 @@ read_file_system_list (bool need_fs_type)
740027
 
740027
 #ifdef MOUNTED_GETMNTENT1 /* GNU/Linux, 4.3BSD, SunOS, HP-UX, Dynix, Irix.  */
740027
   {
740027
-    struct mntent *mnt;
740027
-    char const *table = MOUNTED;
740027
-    FILE *fp;
740027
+#ifdef MOUNTED_PROC_MOUNTINFO
740027
+    struct libmnt_table *fstable = NULL;
740027
 
740027
-    fp = setmntent (table, "r");
740027
-    if (fp == NULL)
740027
-      return NULL;
740027
+    fstable = mnt_new_table_from_file ("/proc/self/mountinfo");
740027
 
740027
-    while ((mnt = getmntent (fp)))
740027
+    if (fstable != NULL)
740027
       {
740027
-        me = xmalloc (sizeof *me);
740027
-        me->me_devname = xstrdup (mnt->mnt_fsname);
740027
-        me->me_mountdir = xstrdup (mnt->mnt_dir);
740027
-        me->me_type = xstrdup (mnt->mnt_type);
740027
-        me->me_type_malloced = 1;
740027
-        me->me_dummy = ME_DUMMY (me->me_devname, me->me_type, mnt);
740027
-        me->me_remote = ME_REMOTE (me->me_devname, me->me_type);
740027
-        me->me_dev = dev_from_mount_options (mnt->mnt_opts);
740027
+        struct libmnt_fs *fs;
740027
+        struct libmnt_iter *iter;
740027
 
740027
-        /* Add to the linked list. */
740027
-        *mtail = me;
740027
-        mtail = &me->me_next;
740027
+        iter = mnt_new_iter (MNT_ITER_FORWARD);
740027
+
740027
+        while (iter && mnt_table_next_fs (fstable, iter, &fs) == 0)
740027
+          {
740027
+            me = xmalloc (sizeof *me);
740027
+
740027
+            me->me_devname = xstrdup (mnt_fs_get_source (fs));
740027
+            me->me_mountdir = xstrdup (mnt_fs_get_target (fs));
740027
+            me->me_type = xstrdup (mnt_fs_get_fstype (fs));
740027
+            me->me_type_malloced = 1;
740027
+            me->me_dev = mnt_fs_get_devno (fs);
740027
+            me->me_dummy = mnt_fs_is_pseudofs (fs);
740027
+            me->me_remote = mnt_fs_is_netfs (fs);
740027
+
740027
+            /* Add to the linked list. */
740027
+            *mtail = me;
740027
+            mtail = &me->me_next;
740027
+          }
740027
+
740027
+        mnt_free_iter (iter);
740027
+        mnt_free_table (fstable);
740027
       }
740027
+    else /* fallback to /proc/self/mounts (/etc/mtab) if anything failed */
740027
+#endif /* MOUNTED_PROC_MOUNTINFO */
740027
+      {
740027
+        FILE * fp;
740027
+        struct mntent *mnt;
740027
+        char const *table = MOUNTED;
740027
 
740027
-    if (endmntent (fp) == 0)
740027
-      goto free_then_fail;
740027
+        fp = setmntent (table, "r");
740027
+        if (fp == NULL)
740027
+          return NULL;
740027
+
740027
+        while ((mnt = getmntent (fp)))
740027
+          {
740027
+            me = xmalloc (sizeof *me);
740027
+            me->me_devname = xstrdup (mnt->mnt_fsname);
740027
+            me->me_mountdir = xstrdup (mnt->mnt_dir);
740027
+            me->me_type = xstrdup (mnt->mnt_type);
740027
+            me->me_type_malloced = 1;
740027
+            me->me_dummy = ME_DUMMY (me->me_devname, me->me_type, mnt);
740027
+            me->me_remote = ME_REMOTE (me->me_devname, me->me_type);
740027
+            me->me_dev = dev_from_mount_options (mnt->mnt_opts);
740027
+
740027
+            /* Add to the linked list. */
740027
+            *mtail = me;
740027
+            mtail = &me->me_next;
740027
+          }
740027
+
740027
+        if (endmntent (fp) == 0)
740027
+          goto free_then_fail;
740027
+      }
740027
   }
740027
 #endif /* MOUNTED_GETMNTENT1. */
740027
 
740027
diff --git a/m4/ls-mntd-fs.m4 b/m4/ls-mntd-fs.m4
740027
index fb116c8..bc5ed82 100644
740027
--- a/m4/ls-mntd-fs.m4
740027
+++ b/m4/ls-mntd-fs.m4
740027
@@ -1,4 +1,4 @@
740027
-# serial 30
740027
+# serial 31
740027
 # How to list mounted file systems.
740027
 
740027
 # Copyright (C) 1998-2004, 2006, 2009-2013 Free Software Foundation, Inc.
740027
@@ -168,6 +168,19 @@ if test $ac_cv_func_getmntent = yes; then
740027
         [Define if there is a function named getmntent for reading the list of
740027
          mounted file systems, and that function takes two arguments.  (SVR4)])
740027
       AC_CHECK_FUNCS([hasmntopt])
740027
+
740027
+      # Check for libmount to support /proc/self/mountinfo on Linux
740027
+      AC_CACHE_VAL([ac_cv_lib_libmount_mnt_table_parse_stream],
740027
+        [AC_CHECK_LIB([mount], [mnt_new_table_from_file],
740027
+          ac_cv_lib_mount_mnt_table_parse_stream=yes,
740027
+          ac_cv_lib_mount_mnt_table_parse_stream=no)])
740027
+      if test $ac_cv_lib_mount_mnt_table_parse_stream = yes; then
740027
+         AC_DEFINE([MOUNTED_PROC_MOUNTINFO], [1],
740027
+           [Define if want to use /proc/self/mountinfo on Linux.])
740027
+         LIBS="-lmount $LIBS"
740027
+      elif test -f /proc/self/mountinfo; then
740027
+         AC_MSG_WARN([/proc/self/mountinfo present but libmount is missing.])
740027
+      fi
740027
     fi
740027
   fi
740027
 
740027
-- 
740027
2.17.2
740027
740027
740027
From 7e5e39933b60761dbd5ad1b0e2d8c075d72ef322 Mon Sep 17 00:00:00 2001
740027
From: =?UTF-8?q?P=C3=A1draig=20Brady?= <P@draigBrady.com>
740027
Date: Thu, 30 Oct 2014 04:08:50 +0000
740027
Subject: [PATCH 2/9] mountlist: don't use libmount to decide on dummy/remote
740027
740027
* lib/mountlist.c (read_file_system_list): Don't use the libmount
740027
routines to determine whether a file system is dummy or remote,
740027
as they're not currently compatible.  For example the remoteness
740027
is determined on file system type (for which the list seems incomplete),
740027
rather than simply checking for a ':' in the device name.
740027
Also libmount currently determines that 'tmpfs' is a dummy file system
740027
even though it has associated storage.
740027
740027
Upstream-commit: 2768ceb7994506e2cfba88be3b6bd13ef5440a90
740027
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
740027
---
740027
 lib/mountlist.c | 19 +++++++++++++------
740027
 1 file changed, 13 insertions(+), 6 deletions(-)
740027
740027
diff --git a/lib/mountlist.c b/lib/mountlist.c
740027
index 617fa88..b01846c 100644
740027
--- a/lib/mountlist.c
740027
+++ b/lib/mountlist.c
740027
@@ -182,10 +182,9 @@
740027
    we grant an exception to any with "bind" in its list of mount options.
740027
    I.e., those are *not* dummy entries.  */
740027
 #ifdef MOUNTED_GETMNTENT1
740027
-# define ME_DUMMY(Fs_name, Fs_type, Fs_ent)	\
740027
+# define ME_DUMMY(Fs_name, Fs_type, Bind)	\
740027
   (ME_DUMMY_0 (Fs_name, Fs_type)		\
740027
-   || (strcmp (Fs_type, "none") == 0		\
740027
-       && !hasmntopt (Fs_ent, "bind")))
740027
+   || (strcmp (Fs_type, "none") == 0 && !Bind))
740027
 #else
740027
 # define ME_DUMMY(Fs_name, Fs_type)		\
740027
   (ME_DUMMY_0 (Fs_name, Fs_type) || strcmp (Fs_type, "none") == 0)
740027
@@ -457,8 +456,14 @@ read_file_system_list (bool need_fs_type)
740027
             me->me_type = xstrdup (mnt_fs_get_fstype (fs));
740027
             me->me_type_malloced = 1;
740027
             me->me_dev = mnt_fs_get_devno (fs);
740027
-            me->me_dummy = mnt_fs_is_pseudofs (fs);
740027
-            me->me_remote = mnt_fs_is_netfs (fs);
740027
+            /* Note we don't use mnt_fs_is_pseudofs() or mnt_fs_is_netfs() here
740027
+               as libmount's classification is non-compatible currently.
740027
+               Also we pass "false" for the "Bind" option as that's only
740027
+               significant when the Fs_type is "none" which will not be
740027
+               the case when parsing "/proc/self/mountinfo", and only
740027
+               applies for static /etc/mtab files.  */
740027
+            me->me_dummy = ME_DUMMY (me->me_devname, me->me_type, false);
740027
+            me->me_remote = ME_REMOTE (me->me_devname, me->me_type);
740027
 
740027
             /* Add to the linked list. */
740027
             *mtail = me;
740027
@@ -481,12 +486,14 @@ read_file_system_list (bool need_fs_type)
740027
 
740027
         while ((mnt = getmntent (fp)))
740027
           {
740027
+            bool bind = hasmntopt (mnt, "bind");
740027
+
740027
             me = xmalloc (sizeof *me);
740027
             me->me_devname = xstrdup (mnt->mnt_fsname);
740027
             me->me_mountdir = xstrdup (mnt->mnt_dir);
740027
             me->me_type = xstrdup (mnt->mnt_type);
740027
             me->me_type_malloced = 1;
740027
-            me->me_dummy = ME_DUMMY (me->me_devname, me->me_type, mnt);
740027
+            me->me_dummy = ME_DUMMY (me->me_devname, me->me_type, bind);
740027
             me->me_remote = ME_REMOTE (me->me_devname, me->me_type);
740027
             me->me_dev = dev_from_mount_options (mnt->mnt_opts);
740027
 
740027
-- 
740027
2.17.2
740027
740027
740027
From e51d88d267c5222ed2bd852bc4701dfe87d8360a Mon Sep 17 00:00:00 2001
740027
From: =?UTF-8?q?P=C3=A1draig=20Brady?= <P@draigBrady.com>
740027
Date: Thu, 2 Apr 2015 04:18:02 +0100
740027
Subject: [PATCH 3/9] mountlist: remove dependency on libmount
740027
740027
* lib/mountlist.c (read_file_system_list): Parse /proc/self/mountinfo
740027
directly, rather than depending on libmount, which has many
740027
dependencies due to its dependence on libselinux, as detailed at:
740027
http://lists.gnu.org/archive/html/bug-gnulib/2015-01/msg00063.html
740027
Note we restrict this to __linux__ as that's probably where this
740027
interface will remain.  If ever porting, it would be best
740027
to first pull the makedev() wrapper from coreutils to a gnulib module.
740027
Note also we don't add a getline dependency to the mountlist module,
740027
as all Linux versions are sufficient.
740027
740027
Upstream-commit: 3fb6e360363744462ce15c381f0b116c6fc4ce82
740027
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
740027
---
740027
 lib/mountlist.c  | 128 ++++++++++++++++++++++++++++++++++++-----------
740027
 m4/ls-mntd-fs.m4 |  17 +------
740027
 2 files changed, 102 insertions(+), 43 deletions(-)
740027
740027
diff --git a/lib/mountlist.c b/lib/mountlist.c
740027
index b01846c..2dbb245 100644
740027
--- a/lib/mountlist.c
740027
+++ b/lib/mountlist.c
740027
@@ -58,6 +58,7 @@
740027
 
740027
 #ifdef MOUNTED_GETMNTENT1       /* 4.3BSD, SunOS, HP-UX, Dynix, Irix.  */
740027
 # include <mntent.h>
740027
+# include <sys/types.h>
740027
 # if !defined MOUNTED
740027
 #  if defined _PATH_MOUNTED     /* GNU libc  */
740027
 #   define MOUNTED _PATH_MOUNTED
740027
@@ -128,12 +129,6 @@
740027
 # include <sys/mntent.h>
740027
 #endif
740027
 
740027
-#ifdef MOUNTED_PROC_MOUNTINFO
740027
-/* Use /proc/self/mountinfo instead of /proc/self/mounts (/etc/mtab)
740027
- * on Linux, if available */
740027
-# include <libmount/libmount.h>
740027
-#endif
740027
-
740027
 #ifndef HAVE_HASMNTOPT
740027
 # define hasmntopt(mnt, opt) ((char *) 0)
740027
 #endif
740027
@@ -389,6 +384,34 @@ dev_from_mount_options (char const *mount_options)
740027
 
740027
 #endif
740027
 
740027
+#if defined MOUNTED_GETMNTENT1 && defined __linux__
740027
+
740027
+/* Unescape the paths in mount tables.
740027
+   STR is updated in place.  */
740027
+
740027
+static void
740027
+unescape_tab (char *str)
740027
+{
740027
+  size_t i, j = 0;
740027
+  size_t len = strlen (str) + 1;
740027
+  for (i = 0; i < len; i++)
740027
+    {
740027
+      if (str[i] == '\\' && (i + 4 < len)
740027
+          && str[i + 1] >= '0' && str[i + 1] <= '3'
740027
+          && str[i + 2] >= '0' && str[i + 2] <= '7'
740027
+          && str[i + 3] >= '0' && str[i + 3] <= '7')
740027
+        {
740027
+          str[j++] = (str[i + 1] - '0') * 64 +
740027
+                     (str[i + 2] - '0') * 8 +
740027
+                     (str[i + 3] - '0');
740027
+          i += 3;
740027
+        }
740027
+      else
740027
+        str[j++] = str[i];
740027
+    }
740027
+}
740027
+#endif
740027
+
740027
 /* Return a list of the currently mounted file systems, or NULL on error.
740027
    Add each entry to the tail of the list so that they stay in order.
740027
    If NEED_FS_TYPE is true, ensure that the file system type fields in
740027
@@ -435,30 +458,70 @@ read_file_system_list (bool need_fs_type)
740027
 
740027
 #ifdef MOUNTED_GETMNTENT1 /* GNU/Linux, 4.3BSD, SunOS, HP-UX, Dynix, Irix.  */
740027
   {
740027
-#ifdef MOUNTED_PROC_MOUNTINFO
740027
-    struct libmnt_table *fstable = NULL;
740027
-
740027
-    fstable = mnt_new_table_from_file ("/proc/self/mountinfo");
740027
+    FILE *fp;
740027
 
740027
-    if (fstable != NULL)
740027
+#ifdef __linux__
740027
+    /* Try parsing mountinfo first, as that make device IDs available.
740027
+       Note we could use libmount routines to simplify this parsing a little
740027
+       (and that code is in previous versions of this function), however
740027
+       libmount depends on libselinux which pulls in many dependencies.  */
740027
+    char const *mountinfo = "/proc/self/mountinfo";
740027
+    fp = fopen (mountinfo, "r");
740027
+    if (fp != NULL)
740027
       {
740027
-        struct libmnt_fs *fs;
740027
-        struct libmnt_iter *iter;
740027
+        char *line = NULL;
740027
+        size_t buf_size = 0;
740027
 
740027
-        iter = mnt_new_iter (MNT_ITER_FORWARD);
740027
-
740027
-        while (iter && mnt_table_next_fs (fstable, iter, &fs) == 0)
740027
+        while (getline (&line, &buf_size, fp) != -1)
740027
           {
740027
+            unsigned int devmaj, devmin;
740027
+            int target_s, target_e, type_s, type_e, source_s, source_e;
740027
+            char test;
740027
+            char *dash;
740027
+            int rc;
740027
+
740027
+            rc = sscanf(line, "%*u "        /* id - discarded  */
740027
+                              "%*u "        /* parent - discarded */
740027
+                              "%u:%u "      /* dev major:minor  */
740027
+                              "%*s "        /* mountroot - discarded  */
740027
+                              "%n%*s%n"     /* target, start and end  */
740027
+                              "%c",         /* more data...  */
740027
+                              &devmaj, &devmin,
740027
+                              &target_s, &target_e,
740027
+                              &test);
740027
+            if (rc != 3 && rc != 5)  /* 5 if %n included in count.  */
740027
+              continue;
740027
+
740027
+            /* skip optional fields, terminated by " - "  */
740027
+            dash = strstr (line + target_e, " - ");
740027
+            if (! dash)
740027
+              continue;
740027
+
740027
+            rc = sscanf(dash, " - "
740027
+                              "%n%*s%n "    /* FS type, start and end  */
740027
+                              "%n%*s%n "    /* source, start and end  */
740027
+                              "%c",         /* more data...  */
740027
+                              &type_s, &type_e,
740027
+                              &source_s, &source_e,
740027
+                              &test);
740027
+            if (rc != 1 && rc != 5)  /* 5 if %n included in count.  */
740027
+              continue;
740027
+
740027
+            /* manipulate the sub-strings in place.  */
740027
+            line[target_e] = '\0';
740027
+            dash[type_e] = '\0';
740027
+            dash[source_e] = '\0';
740027
+            unescape_tab (dash + source_s);
740027
+            unescape_tab (line + target_s);
740027
+
740027
             me = xmalloc (sizeof *me);
740027
 
740027
-            me->me_devname = xstrdup (mnt_fs_get_source (fs));
740027
-            me->me_mountdir = xstrdup (mnt_fs_get_target (fs));
740027
-            me->me_type = xstrdup (mnt_fs_get_fstype (fs));
740027
+            me->me_devname = xstrdup (dash + source_s);
740027
+            me->me_mountdir = xstrdup (line + target_s);
740027
+            me->me_type = xstrdup (dash + type_s);
740027
             me->me_type_malloced = 1;
740027
-            me->me_dev = mnt_fs_get_devno (fs);
740027
-            /* Note we don't use mnt_fs_is_pseudofs() or mnt_fs_is_netfs() here
740027
-               as libmount's classification is non-compatible currently.
740027
-               Also we pass "false" for the "Bind" option as that's only
740027
+            me->me_dev = makedev (devmaj, devmin);
740027
+            /* we pass "false" for the "Bind" option as that's only
740027
                significant when the Fs_type is "none" which will not be
740027
                the case when parsing "/proc/self/mountinfo", and only
740027
                applies for static /etc/mtab files.  */
740027
@@ -470,13 +533,22 @@ read_file_system_list (bool need_fs_type)
740027
             mtail = &me->me_next;
740027
           }
740027
 
740027
-        mnt_free_iter (iter);
740027
-        mnt_free_table (fstable);
740027
+        free (line);
740027
+
740027
+        if (ferror (fp))
740027
+          {
740027
+            int saved_errno = errno;
740027
+            fclose (fp);
740027
+            errno = saved_errno;
740027
+            goto free_then_fail;
740027
+          }
740027
+
740027
+        if (fclose (fp) == EOF)
740027
+          goto free_then_fail;
740027
       }
740027
-    else /* fallback to /proc/self/mounts (/etc/mtab) if anything failed */
740027
-#endif /* MOUNTED_PROC_MOUNTINFO */
740027
+    else /* fallback to /proc/self/mounts (/etc/mtab).  */
740027
+#endif /* __linux __ */
740027
       {
740027
-        FILE * fp;
740027
         struct mntent *mnt;
740027
         char const *table = MOUNTED;
740027
 
740027
diff --git a/m4/ls-mntd-fs.m4 b/m4/ls-mntd-fs.m4
740027
index bc5ed82..412fbfc 100644
740027
--- a/m4/ls-mntd-fs.m4
740027
+++ b/m4/ls-mntd-fs.m4
740027
@@ -1,4 +1,4 @@
740027
-# serial 31
740027
+# serial 32
740027
 # How to list mounted file systems.
740027
 
740027
 # Copyright (C) 1998-2004, 2006, 2009-2013 Free Software Foundation, Inc.
740027
@@ -120,7 +120,7 @@ if test $ac_cv_func_getmntent = yes; then
740027
   # Determine whether it's the one-argument variant or the two-argument one.
740027
 
740027
   if test -z "$ac_list_mounted_fs"; then
740027
-    # 4.3BSD, SunOS, HP-UX, Dynix, Irix
740027
+    # GNU/Linux, 4.3BSD, SunOS, HP-UX, Dynix, Irix
740027
     AC_MSG_CHECKING([for one-argument getmntent function])
740027
     AC_CACHE_VAL([fu_cv_sys_mounted_getmntent1],
740027
                  [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
740027
@@ -168,19 +168,6 @@ if test $ac_cv_func_getmntent = yes; then
740027
         [Define if there is a function named getmntent for reading the list of
740027
          mounted file systems, and that function takes two arguments.  (SVR4)])
740027
       AC_CHECK_FUNCS([hasmntopt])
740027
-
740027
-      # Check for libmount to support /proc/self/mountinfo on Linux
740027
-      AC_CACHE_VAL([ac_cv_lib_libmount_mnt_table_parse_stream],
740027
-        [AC_CHECK_LIB([mount], [mnt_new_table_from_file],
740027
-          ac_cv_lib_mount_mnt_table_parse_stream=yes,
740027
-          ac_cv_lib_mount_mnt_table_parse_stream=no)])
740027
-      if test $ac_cv_lib_mount_mnt_table_parse_stream = yes; then
740027
-         AC_DEFINE([MOUNTED_PROC_MOUNTINFO], [1],
740027
-           [Define if want to use /proc/self/mountinfo on Linux.])
740027
-         LIBS="-lmount $LIBS"
740027
-      elif test -f /proc/self/mountinfo; then
740027
-         AC_MSG_WARN([/proc/self/mountinfo present but libmount is missing.])
740027
-      fi
740027
     fi
740027
   fi
740027
 
740027
-- 
740027
2.17.2
740027
740027
740027
From a6a7c39b36699fdbbb57679f2f71fc3ae08e8ba2 Mon Sep 17 00:00:00 2001
740027
From: Dave Chiluk <chiluk@canonical.com>
740027
Date: Mon, 31 Aug 2015 16:07:58 -0500
740027
Subject: [PATCH 4/9] mountlist: add me_mntroot field on Linux machines
740027
740027
* lib/mountlist.c (read_file_system_list): Populate me_mntroot in
740027
mount_entry so Linux machines based on /proc/self/mountinfo can
740027
distinguish between bind mounts and original mounts.  In reality bind
740027
mounts aren't treated differently than mountroot=/ mounts by the
740027
kernel, but the user often wants these bind mounts distinguished.
740027
* lib/mountlist.h (struct mount_entry): Add me_mntroot element.
740027
More details at https://pad.lv/1432871
740027
740027
Upstream-commit: c6148bca89e9465fd6ba3a10d273ec4cb58c2dbe
740027
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
740027
---
740027
 lib/mountlist.c | 25 ++++++++++++++++++++++---
740027
 lib/mountlist.h |  2 ++
740027
 2 files changed, 24 insertions(+), 3 deletions(-)
740027
740027
diff --git a/lib/mountlist.c b/lib/mountlist.c
740027
index 2dbb245..f4d285a 100644
740027
--- a/lib/mountlist.c
740027
+++ b/lib/mountlist.c
740027
@@ -444,6 +444,7 @@ read_file_system_list (bool need_fs_type)
740027
         me = xmalloc (sizeof *me);
740027
         me->me_devname = xstrdup (mnt->mnt_fsname);
740027
         me->me_mountdir = xstrdup (mnt->mnt_dir);
740027
+        me->me_mntroot = NULL;
740027
         me->me_type = xstrdup (mnt->mnt_type);
740027
         me->me_type_malloced = 1;
740027
         me->me_dummy = ME_DUMMY (me->me_devname, me->me_type);
740027
@@ -475,7 +476,8 @@ read_file_system_list (bool need_fs_type)
740027
         while (getline (&line, &buf_size, fp) != -1)
740027
           {
740027
             unsigned int devmaj, devmin;
740027
-            int target_s, target_e, type_s, type_e, source_s, source_e;
740027
+            int target_s, target_e, type_s, type_e;
740027
+            int source_s, source_e, mntroot_s, mntroot_e;
740027
             char test;
740027
             char *dash;
740027
             int rc;
740027
@@ -483,13 +485,15 @@ read_file_system_list (bool need_fs_type)
740027
             rc = sscanf(line, "%*u "        /* id - discarded  */
740027
                               "%*u "        /* parent - discarded */
740027
                               "%u:%u "      /* dev major:minor  */
740027
-                              "%*s "        /* mountroot - discarded  */
740027
+                              "%n%*s%n "    /* mountroot */
740027
                               "%n%*s%n"     /* target, start and end  */
740027
                               "%c",         /* more data...  */
740027
                               &devmaj, &devmin,
740027
+                              &mntroot_s, &mntroot_e,
740027
                               &target_s, &target_e,
740027
                               &test);
740027
-            if (rc != 3 && rc != 5)  /* 5 if %n included in count.  */
740027
+
740027
+            if (rc != 3 && rc != 7)  /* 7 if %n included in count.  */
740027
               continue;
740027
 
740027
             /* skip optional fields, terminated by " - "  */
740027
@@ -508,16 +512,19 @@ read_file_system_list (bool need_fs_type)
740027
               continue;
740027
 
740027
             /* manipulate the sub-strings in place.  */
740027
+            line[mntroot_e] = '\0';
740027
             line[target_e] = '\0';
740027
             dash[type_e] = '\0';
740027
             dash[source_e] = '\0';
740027
             unescape_tab (dash + source_s);
740027
             unescape_tab (line + target_s);
740027
+            unescape_tab (line + mntroot_s);
740027
 
740027
             me = xmalloc (sizeof *me);
740027
 
740027
             me->me_devname = xstrdup (dash + source_s);
740027
             me->me_mountdir = xstrdup (line + target_s);
740027
+            me->me_mntroot = xstrdup (line + mntroot_s);
740027
             me->me_type = xstrdup (dash + type_s);
740027
             me->me_type_malloced = 1;
740027
             me->me_dev = makedev (devmaj, devmin);
740027
@@ -563,6 +570,7 @@ read_file_system_list (bool need_fs_type)
740027
             me = xmalloc (sizeof *me);
740027
             me->me_devname = xstrdup (mnt->mnt_fsname);
740027
             me->me_mountdir = xstrdup (mnt->mnt_dir);
740027
+            me->me_mntroot = NULL;
740027
             me->me_type = xstrdup (mnt->mnt_type);
740027
             me->me_type_malloced = 1;
740027
             me->me_dummy = ME_DUMMY (me->me_devname, me->me_type, bind);
740027
@@ -595,6 +603,7 @@ read_file_system_list (bool need_fs_type)
740027
         me = xmalloc (sizeof *me);
740027
         me->me_devname = xstrdup (fsp->f_mntfromname);
740027
         me->me_mountdir = xstrdup (fsp->f_mntonname);
740027
+        me->me_mntroot = NULL;
740027
         me->me_type = fs_type;
740027
         me->me_type_malloced = 0;
740027
         me->me_dummy = ME_DUMMY (me->me_devname, me->me_type);
740027
@@ -621,6 +630,7 @@ read_file_system_list (bool need_fs_type)
740027
         me = xmalloc (sizeof *me);
740027
         me->me_devname = xstrdup (fsp->f_mntfromname);
740027
         me->me_mountdir = xstrdup (fsp->f_mntonname);
740027
+        me->me_mntroot = NULL;
740027
         me->me_type = xstrdup (fsp->f_fstypename);
740027
         me->me_type_malloced = 1;
740027
         me->me_dummy = ME_DUMMY (me->me_devname, me->me_type);
740027
@@ -647,6 +657,7 @@ read_file_system_list (bool need_fs_type)
740027
         me = xmalloc (sizeof *me);
740027
         me->me_devname = xstrdup (fsd.fd_req.devname);
740027
         me->me_mountdir = xstrdup (fsd.fd_req.path);
740027
+        me->me_mntroot = NULL;
740027
         me->me_type = gt_names[fsd.fd_req.fstype];
740027
         me->me_type_malloced = 0;
740027
         me->me_dummy = ME_DUMMY (me->me_devname, me->me_type);
740027
@@ -745,6 +756,7 @@ read_file_system_list (bool need_fs_type)
740027
           me->me_devname = xstrdup (fi.device_name[0] != '\0'
740027
                                     ? fi.device_name : fi.fsh_name);
740027
           me->me_mountdir = xstrdup (re != NULL ? re->name : fi.fsh_name);
740027
+          me->me_mntroot = NULL;
740027
           me->me_type = xstrdup (fi.fsh_name);
740027
           me->me_type_malloced = 1;
740027
           me->me_dev = fi.dev;
740027
@@ -794,6 +806,7 @@ read_file_system_list (bool need_fs_type)
740027
         me = xmalloc (sizeof *me);
740027
         me->me_devname = xstrdup (stats[counter].f_mntfromname);
740027
         me->me_mountdir = xstrdup (stats[counter].f_mntonname);
740027
+        me->me_mntroot = NULL;
740027
         me->me_type = xstrdup (FS_TYPE (stats[counter]));
740027
         me->me_type_malloced = 1;
740027
         me->me_dummy = ME_DUMMY (me->me_devname, me->me_type);
740027
@@ -830,6 +843,7 @@ read_file_system_list (bool need_fs_type)
740027
         strcpy (me->me_devname + 5, mnt.mt_dev);
740027
 # endif
740027
         me->me_mountdir = xstrdup (mnt.mt_filsys);
740027
+        me->me_mntroot = NULL;
740027
         me->me_dev = (dev_t) -1;        /* Magic; means not known yet. */
740027
         me->me_type = "";
740027
         me->me_type_malloced = 0;
740027
@@ -877,6 +891,7 @@ read_file_system_list (bool need_fs_type)
740027
         me = xmalloc (sizeof *me);
740027
         me->me_devname = xstrdup ((*ent)->mt_resource);
740027
         me->me_mountdir = xstrdup ((*ent)->mt_directory);
740027
+        me->me_mntroot = NULL;
740027
         me->me_type = xstrdup ((*ent)->mt_fstype);
740027
         me->me_type_malloced = 1;
740027
         me->me_dummy = ME_DUMMY (me->me_devname, me->me_type);
740027
@@ -939,6 +954,7 @@ read_file_system_list (bool need_fs_type)
740027
             me = xmalloc (sizeof *me);
740027
             me->me_devname = xstrdup (mnt.mnt_special);
740027
             me->me_mountdir = xstrdup (mnt.mnt_mountp);
740027
+            me->me_mntroot = NULL;
740027
             me->me_type = xstrdup (mnt.mnt_fstype);
740027
             me->me_type_malloced = 1;
740027
             me->me_dummy = MNT_IGNORE (&mnt) != 0;
740027
@@ -1015,6 +1031,7 @@ read_file_system_list (bool need_fs_type)
740027
                                       vmp->vmt_data[VMT_OBJECT].vmt_off);
740027
           }
740027
         me->me_mountdir = xstrdup (thisent + vmp->vmt_data[VMT_STUB].vmt_off);
740027
+        me->me_mntroot = NULL;
740027
         me->me_type = xstrdup (fstype_to_string (vmp->vmt_gfstype));
740027
         me->me_type_malloced = 1;
740027
         options = thisent + vmp->vmt_data[VMT_ARGS].vmt_off;
740027
@@ -1058,6 +1075,7 @@ read_file_system_list (bool need_fs_type)
740027
             me = xmalloc (sizeof *me);
740027
             me->me_devname = xstrdup (dev.f_mntfromname);
740027
             me->me_mountdir = xstrdup (dev.f_mntonname);
740027
+            me->me_mntroot = NULL;
740027
             me->me_type = xstrdup (dev.f_fstypename);
740027
             me->me_type_malloced = 1;
740027
             me->me_dummy = ME_DUMMY (me->me_devname, me->me_type);
740027
@@ -1100,6 +1118,7 @@ void free_mount_entry (struct mount_entry *me)
740027
 {
740027
   free (me->me_devname);
740027
   free (me->me_mountdir);
740027
+  free (me->me_mntroot);
740027
   if (me->me_type_malloced)
740027
     free (me->me_type);
740027
   free (me);
740027
diff --git a/lib/mountlist.h b/lib/mountlist.h
740027
index 55877e2..1872b2b 100644
740027
--- a/lib/mountlist.h
740027
+++ b/lib/mountlist.h
740027
@@ -27,6 +27,8 @@ struct mount_entry
740027
 {
740027
   char *me_devname;             /* Device node name, including "/dev/". */
740027
   char *me_mountdir;            /* Mount point directory name. */
740027
+  char *me_mntroot;             /* Directory on filesystem of device used */
740027
+                                /* as root for the (bind) mount. */
740027
   char *me_type;                /* "nfs", "4.2", etc. */
740027
   dev_t me_dev;                 /* Device number of me_mountdir. */
740027
   unsigned int me_dummy : 1;    /* Nonzero for dummy file systems. */
740027
-- 
740027
2.17.2
740027
740027
740027
From 6b301e5f89d4555e33b267e3ea5a709a4b584038 Mon Sep 17 00:00:00 2001
740027
From: Andrew Borodin <aborodin@vmail.ru>
740027
Date: Sun, 27 Sep 2015 11:41:17 +0300
740027
Subject: [PATCH 5/9] mountlist: clean up of variable duplication
740027
740027
* lib/mountlist.c (read_file_system_list) [MOUNTED_LISTMNTENT]:
740027
the 'me' variable is already declared above.  Remove it here.
740027
740027
Upstream-commit: 1eda6d17e93fa496368f82cac6317b8045cc9373
740027
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
740027
---
740027
 lib/mountlist.c | 1 -
740027
 1 file changed, 1 deletion(-)
740027
740027
diff --git a/lib/mountlist.c b/lib/mountlist.c
740027
index f4d285a..6f66996 100644
740027
--- a/lib/mountlist.c
740027
+++ b/lib/mountlist.c
740027
@@ -429,7 +429,6 @@ read_file_system_list (bool need_fs_type)
740027
   {
740027
     struct tabmntent *mntlist, *p;
740027
     struct mntent *mnt;
740027
-    struct mount_entry *me;
740027
 
740027
     /* the third and fourth arguments could be used to filter mounts,
740027
        but Crays doesn't seem to have any mounts that we want to
740027
-- 
740027
2.17.2
740027
740027
740027
From b2063df8d13fc279f3fa38d1315e3ff3f66c70e5 Mon Sep 17 00:00:00 2001
740027
From: Eric Blake <eblake@redhat.com>
740027
Date: Wed, 14 Sep 2016 19:21:42 -0500
740027
Subject: [PATCH 6/9] mountlist: include sysmacros.h for glibc
740027
740027
On Fedora rawhide (glibc 2.25), './gnulib-tool --test mountlist'
740027
reports:
740027
../../gllib/mountlist.c: In function 'read_file_system_list':
740027
../../gllib/mountlist.c:534:13: warning: '__makedev_from_sys_types' is deprecated:
740027
  In the GNU C Library, `makedev' is defined by <sys/sysmacros.h>.
740027
  For historical compatibility, it is currently defined by
740027
  <sys/types.h> as well, but we plan to remove this soon.
740027
  To use `makedev', include <sys/sysmacros.h> directly.
740027
  If you did not intend to use a system-defined macro `makedev',
740027
  you should #undef it after including <sys/types.h>.
740027
  [-Wdeprecated-declarations]
740027
             me->me_dev = makedev (devmaj, devmin);
740027
             ^~
740027
In file included from /usr/include/features.h:397:0,
740027
                 from /usr/include/sys/types.h:25,
740027
                 from ./sys/types.h:28,
740027
                 from ../../gllib/mountlist.h:23,
740027
                 from ../../gllib/mountlist.c:20:
740027
/usr/include/sys/sysmacros.h:89:1: note: declared here
740027
 __SYSMACROS_DEFINE_MAKEDEV (__SYSMACROS_FST_IMPL_TEMPL)
740027
 ^
740027
740027
Fix it by including the right headers.  We also need a fix to
740027
autoconf's AC_HEADER_MAJOR, but that's a separate patch.
740027
740027
* m4/mountlist.m4 (gl_PREREQ_MOUTLIST_EXTRA): Include
740027
AC_HEADER_MAJOR.
740027
* lib/mountlist.c (includes): Use correct headers.
740027
740027
Signed-off-by: Eric Blake <eblake@redhat.com>
740027
740027
Upstream-commit: 4da63c5881f60f71999a943612da9112232b9161
740027
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
740027
---
740027
 lib/mountlist.c | 6 ++++++
740027
 m4/mountlist.m4 | 3 ++-
740027
 2 files changed, 8 insertions(+), 1 deletion(-)
740027
740027
diff --git a/lib/mountlist.c b/lib/mountlist.c
740027
index 6f66996..40338ac 100644
740027
--- a/lib/mountlist.c
740027
+++ b/lib/mountlist.c
740027
@@ -37,6 +37,12 @@
740027
 # include <sys/param.h>
740027
 #endif
740027
 
740027
+#if MAJOR_IN_MKDEV
740027
+# include <sys/mkdev.h>
740027
+#elif MAJOR_IN_SYSMACROS
740027
+# include <sys/sysmacros.h>
740027
+#endif
740027
+
740027
 #if defined MOUNTED_GETFSSTAT   /* OSF_1 and Darwin1.3.x */
740027
 # if HAVE_SYS_UCRED_H
740027
 #  include <grp.h> /* needed on OSF V4.0 for definition of NGROUPS,
740027
diff --git a/m4/mountlist.m4 b/m4/mountlist.m4
740027
index cd137c9..2f47ce2 100644
740027
--- a/m4/mountlist.m4
740027
+++ b/m4/mountlist.m4
740027
@@ -1,4 +1,4 @@
740027
-# serial 11
740027
+# serial 12
740027
 dnl Copyright (C) 2002-2006, 2009-2013 Free Software Foundation, Inc.
740027
 dnl This file is free software; the Free Software Foundation
740027
 dnl gives unlimited permission to copy and/or distribute it,
740027
@@ -15,5 +15,6 @@ AC_DEFUN([gl_PREREQ_MOUNTLIST_EXTRA],
740027
 [
740027
   dnl Note gl_LIST_MOUNTED_FILE_SYSTEMS checks for mntent.h, not sys/mntent.h.
740027
   AC_CHECK_HEADERS([sys/mntent.h])
740027
+  AC_HEADER_MAJOR()dnl for use of makedev ()
740027
   gl_FSTYPENAME
740027
 ])
740027
-- 
740027
2.17.2
740027
740027
740027
From 472ef28870dce7ca7505fa2ca477040da347a567 Mon Sep 17 00:00:00 2001
740027
From: =?UTF-8?q?P=C3=A1draig=20Brady?= <P@draigBrady.com>
740027
Date: Thu, 2 Apr 2015 05:34:07 +0100
740027
Subject: [PATCH 7/9] df: fix use of uninitialized variable reported by
740027
 valgrind
740027
740027
 Conditional jump or move depends on uninitialised value(s)
740027
    at 0x40380C: get_field_values (df.c:840)
740027
    by 0x403E16: get_dev (df.c:994)
740027
    by 0x404D65: get_all_entries (df.c:1364)
740027
    by 0x405926: main (df.c:1714)
740027
740027
* src/df.c (get_dev): Initialize the fsu.fsu_bavail_top_bit_set
740027
member, when adding placeholder entries.
740027
(main): Avoid a "definitely lost" memory leak warning from valgrind,
740027
reported by Bernhard Voelker.
740027
740027
Upstream-commit: bf180f8f5a53eb82054e85e26dcd1ea7c43dbdfe
740027
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
740027
---
740027
 src/df.c | 4 ++++
740027
 1 file changed, 4 insertions(+)
740027
740027
diff --git a/src/df.c b/src/df.c
740027
index ce11b50..5ffd0a5 100644
740027
--- a/src/df.c
740027
+++ b/src/df.c
740027
@@ -935,6 +935,7 @@ get_dev (char const *disk, char const *mount_point, char const* file,
740027
             return;
740027
 
740027
           fstype = "-";
740027
+          fsu.fsu_bavail_top_bit_set = false;
740027
           fsu.fsu_blocksize = fsu.fsu_blocks = fsu.fsu_bfree =
740027
           fsu.fsu_bavail = fsu.fsu_files = fsu.fsu_ffree = UINTMAX_MAX;
740027
         }
740027
@@ -959,6 +960,7 @@ get_dev (char const *disk, char const *mount_point, char const* file,
740027
               && (! dev_me->me_remote || ! me_remote))
740027
             {
740027
               fstype = "-";
740027
+              fsu.fsu_bavail_top_bit_set = false;
740027
               fsu.fsu_blocksize = fsu.fsu_blocks = fsu.fsu_bfree =
740027
               fsu.fsu_bavail = fsu.fsu_files = fsu.fsu_ffree = UINTMAX_MAX;
740027
             }
740027
@@ -1736,6 +1738,8 @@ main (int argc, char **argv)
740027
       for (i = optind; i < argc; ++i)
740027
         if (argv[i])
740027
           get_entry (argv[i], &stats[i - optind]);
740027
+
740027
+      IF_LINT (free (stats));
740027
     }
740027
   else
740027
     get_all_entries ();
740027
-- 
740027
2.17.2
740027
740027
740027
From fc6104cc9d8d2908b3225b035def82d3a95bdfd0 Mon Sep 17 00:00:00 2001
740027
From: =?UTF-8?q?P=C3=A1draig=20Brady?= <P@draigBrady.com>
740027
Date: Sun, 5 Apr 2015 18:21:38 +0100
740027
Subject: [PATCH 8/9] df: fix --local hanging with inaccessible remote mounts
740027
740027
* src/df.c (filter_mount_list): With -l, avoid stating remote mounts.
740027
* init.cfg: Avoid test hangs with inaccessible remote mounts.
740027
* tests/df/no-mtab-status.sh: Skip with inaccessible remote mounts.
740027
* tests/df/skip-rootfs.sh: Likewise.
740027
* tests/df/total-verify.sh: Likewise.
740027
* NEWS: Mention the bug fix.
740027
Reported at http://bugzilla.redhat.com/1199679
740027
740027
Upstream-commit: 1b1c40e1d6f8cf30b6c7c9d31bbddbc3d5cc72e6
740027
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
740027
---
740027
 init.cfg                   | 2 +-
740027
 tests/df/no-mtab-status.sh | 3 ++-
740027
 tests/df/skip-rootfs.sh    | 3 ++-
740027
 tests/df/total-verify.sh   | 3 ++-
740027
 4 files changed, 7 insertions(+), 4 deletions(-)
740027
740027
diff --git a/init.cfg b/init.cfg
740027
index 3364a73..d5a80bb 100644
740027
--- a/init.cfg
740027
+++ b/init.cfg
740027
@@ -79,7 +79,7 @@ is_local_dir_()
740027
 require_mount_list_()
740027
 {
740027
   local mount_list_fail='cannot read table of mounted file systems'
740027
-  df 2>&1 | grep -F "$mount_list_fail" >/dev/null &&
740027
+  df --local 2>&1 | grep -F "$mount_list_fail" >/dev/null &&
740027
     skip_ "$mount_list_fail"
740027
 }
740027
 
740027
diff --git a/tests/df/no-mtab-status.sh b/tests/df/no-mtab-status.sh
740027
index 2e6b61b..9b6b9d3 100755
740027
--- a/tests/df/no-mtab-status.sh
740027
+++ b/tests/df/no-mtab-status.sh
740027
@@ -21,7 +21,8 @@
740027
 print_ver_ df
740027
 require_gcc_shared_
740027
 
740027
-df || skip_ "df fails"
740027
+# Protect against inaccessible remote mounts etc.
740027
+timeout 10 df || skip_ "df fails"
740027
 
740027
 # Simulate "mtab" failure.
740027
 cat > k.c <<'EOF' || framework_failure_
740027
diff --git a/tests/df/skip-rootfs.sh b/tests/df/skip-rootfs.sh
740027
index 9c5d0a9..b79751e 100755
740027
--- a/tests/df/skip-rootfs.sh
740027
+++ b/tests/df/skip-rootfs.sh
740027
@@ -19,7 +19,8 @@
740027
 . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
740027
 print_ver_ df
740027
 
740027
-df || skip_ "df fails"
740027
+# Protect against inaccessible remote mounts etc.
740027
+timeout 10 df || skip_ "df fails"
740027
 
740027
 # Verify that rootfs is in mtab (and shown when the -a option is specified).
740027
 df -a >out || fail=1
740027
diff --git a/tests/df/total-verify.sh b/tests/df/total-verify.sh
740027
index a045ccf..f05a91e 100755
740027
--- a/tests/df/total-verify.sh
740027
+++ b/tests/df/total-verify.sh
740027
@@ -20,7 +20,8 @@
740027
 print_ver_ df
740027
 require_perl_
740027
 
740027
-df || skip_ "df fails"
740027
+# Protect against inaccessible remote mounts etc.
740027
+timeout 10 df || skip_ "df fails"
740027
 
740027
 cat <<\EOF > check-df || framework_failure_
740027
 my ($total, $used, $avail) = (0, 0, 0);
740027
-- 
740027
2.17.2
740027
740027
740027
From 9a52ebdc70071076a1b7263b64b118972d203778 Mon Sep 17 00:00:00 2001
740027
From: Dave Chiluk <chiluk@canonical.com>
740027
Date: Mon, 21 Sep 2015 15:04:11 -0500
740027
Subject: [PATCH 9/9] df: prioritize mounts nearer the device root
740027
740027
In the presence of bind mounts of a device, the 4th "mount root" field
740027
from /proc/self/mountinfo is now considered, so as to prefer mount
740027
points closer to the root of the device.  Note on older systems with
740027
an /etc/mtab file, the source device was listed as the originating
740027
directory, and so this was not an issue.
740027
Details at http://pad.lv/1432871
740027
740027
* src/df.c (filter_mount_list): When deduplicating mount entries,
740027
only prefer sources nearer or at the root of the device, when the
740027
target is nearer the root of the device.
740027
* NEWS: Mention the change in behavior.
740027
740027
Upstream-commit: 3babaf83875ceac896c8dd3a64248e955dfecef9
740027
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
740027
---
740027
 src/df.c | 12 +++++++++---
740027
 1 file changed, 9 insertions(+), 3 deletions(-)
740027
740027
diff --git a/src/df.c b/src/df.c
740027
index 5ffd0a5..c50aa80 100644
740027
--- a/src/df.c
740027
+++ b/src/df.c
740027
@@ -649,6 +649,13 @@ filter_mount_list (bool devices_only)
740027
 
740027
           if (devlist)
740027
             {
740027
+              bool target_nearer_root = strlen (devlist->me->me_mountdir)
740027
+                                        > strlen (me->me_mountdir);
740027
+              /* With bind mounts, prefer items nearer the root of the source */
740027
+              bool source_below_root = devlist->me->me_mntroot != NULL
740027
+                                       && me->me_mntroot != NULL
740027
+                                       && (strlen (devlist->me->me_mntroot)
740027
+                                           < strlen (me->me_mntroot));
740027
               if (! print_grand_total && me->me_remote && devlist->me->me_remote
740027
                   && ! STREQ (devlist->me->me_devname, me->me_devname))
740027
                 {
740027
@@ -660,9 +667,8 @@ filter_mount_list (bool devices_only)
740027
               else if ((strchr (me->me_devname, '/')
740027
                        /* let "real" devices with '/' in the name win.  */
740027
                         && ! strchr (devlist->me->me_devname, '/'))
740027
-                       /* let a shorter mountdir win.  */
740027
-                       || (strlen (devlist->me->me_mountdir)
740027
-                           > strlen (me->me_mountdir))
740027
+                       /* let points towards the root of the device win.  */
740027
+                       || (target_nearer_root && ! source_below_root)
740027
                        /* let an entry overmounted on a new device win...  */
740027
                        || (! STREQ (devlist->me->me_devname, me->me_devname)
740027
                            /* ... but only when matching an existing mnt point,
740027
-- 
740027
2.17.2
740027