]> Savannah Git Hosting - gnulib.git/commitdiff
mountlist: use /proc/self/mountinfo when available
authorFridolin Pokorny <fpokorny@redhat.com>
Wed, 27 Aug 2014 13:25:30 +0000 (15:25 +0200)
committerPádraig Brady <P@draigBrady.com>
Tue, 9 Sep 2014 11:56:04 +0000 (12:56 +0100)
Use libmount to propagate device IDs provided by Linux in
/proc/self/mountinfo.  This will give more accurate output when
using df in chroot'ed environments as the device IDs are not
determined by stat() which may be inaccurate within the chroot.

* lib/mountlist.c (read_file_system_list): Use the libmount routines
from util-linux to parse "/proc/self/mountinfo" or fall back to
standard getmntent() processing.
* m4/ls-mntd-fs.m4: Check for libmount only when 1-argument
getmntent() is used, as is the case on GNU/Linux.
* DEPENDENCIES: Mention the optional util-linux dependency.

ChangeLog
DEPENDENCIES
lib/mountlist.c
m4/ls-mntd-fs.m4

index 48e0b17ab6acd196feda20f89eef1dce4f389d48..7b8202f206ee1361fa2298ac7d050e9bb1e180b2 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2014-09-09  Fridolin Pokorny  <fpokorny@redhat.com>
+
+       mountlist: use /proc/self/mountinfo when available
+       Use libmount to propagate device IDs provided by Linux in
+       /proc/self/mountinfo.  This will give more accurate output when
+       using df in chroot'ed environments as the device IDs are not
+       determined by stat() which may be inaccurate within the chroot.
+       * lib/mountlist.c (read_file_system_list): Use the libmount routines
+       from util-linux to parse "/proc/self/mountinfo" or fall back to
+       standard getmntent() processing.
+       * m4/ls-mntd-fs.m4: Check for libmount only when 1-argument
+       getmntent() is used, as is the case on GNU/Linux.
+
 2014-09-07  Eric Wong  <normalperson@yhbt.net>
 
        users.txt: add cmogstored
index e19a37e7a7a4ccdf22e5f7292a6beab880dacc0c..44f7ca04dfabc101656566571a475274abaed730 100644 (file)
@@ -162,3 +162,10 @@ at any time.
   + Download:
     http://ftp.gnu.org/gnu/libtool/
     ftp://ftp.gnu.org/gnu/libtool/
+
+* util-linux
+  + Optional.
+    Needed if you want to support /proc/self/mountinfo available on Linux.
+    This will give an ability to propagate device ID of a mounted file system.
+  + Download:
+    http://www.kernel.org/pub/linux/utils/util-linux/
index b3be011a1b3b6eb8ed75179d63152401fd48d1a6..84dc2c8cc0749697fb77769fd0813d989919bcd2 100644 (file)
 # include <sys/mntent.h>
 #endif
 
+#ifdef MOUNTED_PROC_MOUNTINFO
+/* Use /proc/self/mountinfo instead of /proc/self/mounts (/etc/mtab)
+ * on Linux, if available */
+# include <libmount/libmount.h>
+#endif
+
 #ifndef HAVE_HASMNTOPT
 # define hasmntopt(mnt, opt) ((char *) 0)
 #endif
@@ -429,32 +435,68 @@ read_file_system_list (bool need_fs_type)
 
 #ifdef MOUNTED_GETMNTENT1 /* GNU/Linux, 4.3BSD, SunOS, HP-UX, Dynix, Irix.  */
   {
-    struct mntent *mnt;
-    char const *table = MOUNTED;
-    FILE *fp;
+#ifdef MOUNTED_PROC_MOUNTINFO
+    struct libmnt_table *fstable = NULL;
 
-    fp = setmntent (table, "r");
-    if (fp == NULL)
-      return NULL;
+    fstable = mnt_new_table_from_file ("/proc/self/mountinfo");
 
-    while ((mnt = getmntent (fp)))
+    if (fstable != NULL)
       {
-        me = xmalloc (sizeof *me);
-        me->me_devname = xstrdup (mnt->mnt_fsname);
-        me->me_mountdir = xstrdup (mnt->mnt_dir);
-        me->me_type = xstrdup (mnt->mnt_type);
-        me->me_type_malloced = 1;
-        me->me_dummy = ME_DUMMY (me->me_devname, me->me_type, mnt);
-        me->me_remote = ME_REMOTE (me->me_devname, me->me_type);
-        me->me_dev = dev_from_mount_options (mnt->mnt_opts);
+        struct libmnt_fs *fs;
+        struct libmnt_iter *iter;
 
-        /* Add to the linked list. */
-        *mtail = me;
-        mtail = &me->me_next;
+        iter = mnt_new_iter (MNT_ITER_FORWARD);
+
+        while (iter && mnt_table_next_fs (fstable, iter, &fs) == 0)
+          {
+            me = xmalloc (sizeof *me);
+
+            me->me_devname = xstrdup (mnt_fs_get_source (fs));
+            me->me_mountdir = xstrdup (mnt_fs_get_target (fs));
+            me->me_type = xstrdup (mnt_fs_get_fstype (fs));
+            me->me_type_malloced = 1;
+            me->me_dev = mnt_fs_get_devno (fs);
+            me->me_dummy = mnt_fs_is_pseudofs (fs);
+            me->me_remote = mnt_fs_is_netfs (fs);
+
+            /* Add to the linked list. */
+            *mtail = me;
+            mtail = &me->me_next;
+          }
+
+        mnt_free_iter (iter);
+        mnt_free_table (fstable);
       }
+    else /* fallback to /proc/self/mounts (/etc/mtab) if anything failed */
+#endif /* MOUNTED_PROC_MOUNTINFO */
+      {
+        FILE * fp;
+        struct mntent *mnt;
+        char const *table = MOUNTED;
 
-    if (endmntent (fp) == 0)
-      goto free_then_fail;
+        fp = setmntent (table, "r");
+        if (fp == NULL)
+          return NULL;
+
+        while ((mnt = getmntent (fp)))
+          {
+            me = xmalloc (sizeof *me);
+            me->me_devname = xstrdup (mnt->mnt_fsname);
+            me->me_mountdir = xstrdup (mnt->mnt_dir);
+            me->me_type = xstrdup (mnt->mnt_type);
+            me->me_type_malloced = 1;
+            me->me_dummy = ME_DUMMY (me->me_devname, me->me_type, mnt);
+            me->me_remote = ME_REMOTE (me->me_devname, me->me_type);
+            me->me_dev = dev_from_mount_options (mnt->mnt_opts);
+
+            /* Add to the linked list. */
+            *mtail = me;
+            mtail = &me->me_next;
+          }
+
+        if (endmntent (fp) == 0)
+          goto free_then_fail;
+      }
   }
 #endif /* MOUNTED_GETMNTENT1. */
 
index 563ed71cbe201ee0f4cc3042484847e8b917bb53..9e46ccccaa39831fff2ae804795eb45e44e5ea3f 100644 (file)
@@ -1,4 +1,4 @@
-# serial 30
+# serial 31
 # How to list mounted file systems.
 
 # Copyright (C) 1998-2004, 2006, 2009-2014 Free Software Foundation, Inc.
@@ -152,6 +152,19 @@ if test $ac_cv_func_getmntent = yes; then
          of mounted file systems, and that function takes a single argument.
          (4.3BSD, SunOS, HP-UX, Dynix, Irix)])
       AC_CHECK_FUNCS([hasmntopt])
+
+      # Check for libmount to support /proc/self/mountinfo on Linux
+      AC_CACHE_VAL([ac_cv_lib_libmount_mnt_table_parse_stream],
+        [AC_CHECK_LIB([mount], [mnt_new_table_from_file],
+          ac_cv_lib_mount_mnt_table_parse_stream=yes,
+          ac_cv_lib_mount_mnt_table_parse_stream=no)])
+      if test $ac_cv_lib_mount_mnt_table_parse_stream = yes; then
+         AC_DEFINE([MOUNTED_PROC_MOUNTINFO], [1],
+           [Define if want to use /proc/self/mountinfo on Linux.])
+         LIBS="-lmount $LIBS"
+      elif test -f /proc/self/mountinfo; then
+         AC_MSG_WARN([/proc/self/mountinfo present but libmount is missing.])
+      fi
     fi
   fi