From: Fridolin Pokorny Date: Wed, 27 Aug 2014 13:25:30 +0000 (+0200) Subject: mountlist: use /proc/self/mountinfo when available X-Git-Tag: v1.0~7302 X-Git-Url: https://gitweb.git.savannah.gnu.org/gitweb/?a=commitdiff_plain;h=3ea43e02541ece750ffc6cd1dfe34195421b4ef3;p=gnulib.git 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. * DEPENDENCIES: Mention the optional util-linux dependency. --- diff --git a/ChangeLog b/ChangeLog index 48e0b17ab6..7b8202f206 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2014-09-09 Fridolin Pokorny + + 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 users.txt: add cmogstored diff --git a/DEPENDENCIES b/DEPENDENCIES index e19a37e7a7..44f7ca04df 100644 --- a/DEPENDENCIES +++ b/DEPENDENCIES @@ -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/ diff --git a/lib/mountlist.c b/lib/mountlist.c index b3be011a1b..84dc2c8cc0 100644 --- a/lib/mountlist.c +++ b/lib/mountlist.c @@ -128,6 +128,12 @@ # include #endif +#ifdef MOUNTED_PROC_MOUNTINFO +/* Use /proc/self/mountinfo instead of /proc/self/mounts (/etc/mtab) + * on Linux, if available */ +# include +#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. */ diff --git a/m4/ls-mntd-fs.m4 b/m4/ls-mntd-fs.m4 index 563ed71cbe..9e46ccccaa 100644 --- a/m4/ls-mntd-fs.m4 +++ b/m4/ls-mntd-fs.m4 @@ -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