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