>From de0b7dba227f654380137c8843287f4ad32e8dc6 Mon Sep 17 00:00:00 2001 From: Fridolin Pokorny Date: Wed, 27 Aug 2014 15:25:30 +0200 Subject: [PATCH] mountlist: added /proc/self/mountinfo support * mountlist: add support for libmount from util-linux * m4/ls-mntd-fs.m4: check for libmount only when 1-argument getmntent() is used (possible Linux) By using libmount it is possible to propagate device ID provided by Linux in /proc/self/mountinfo. This will give more accurate output when using df in chroot'ed environments. Device IDs are not determined by stat() call using mountpoint, so it is not possible to make a collision when same names are used (e.g. /home/ and CHROOT-ROOT/home/). --- ChangeLog | 13 +++++++++ DEPENDENCIES | 8 ++++++ lib/mountlist.c | 81 ++++++++++++++++++++++++++++++++++++++++++-------------- m4/ls-mntd-fs.m4 | 13 ++++++++- 4 files changed, 94 insertions(+), 21 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9b3c85d..2ab46ce 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2014-08-27 Fridolin Pokorny + + mountlist: add support for libmount from util-linux + m4/ls-mntd-fs.m4: check for libmount only when 1-argument getmntent() + is used (possible Linux) + By using libmount it is possible to propagate device ID provided by + Linux in /proc/self/mountinfo. This will give more accurate output + when using df in chroot'ed environments. Device IDs are not + determined by stat() call using mountpoint, so it is not possible to + make a collision when same names are used (e.g. /home/ and + CHROOT-ROOT/home/). + + 2014-07-13 Pádraig Brady gettext: revert "update macros to version 0.19" diff --git a/DEPENDENCIES b/DEPENDENCIES index e19a37e..c54db82 100644 --- a/DEPENDENCIES +++ b/DEPENDENCIES @@ -162,3 +162,11 @@ 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 b3be011..5195d56 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,67 @@ 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 (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_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 563ed71..c89e0c9 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,17 @@ 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" + fi fi fi -- 1.9.3