>From 3ea12e28fb00e022516712acfdcc55527c342524 Mon Sep 17 00:00:00 2001 From: Fridolin Pokorny Date: Wed, 27 Aug 2014 15:25:30 +0200 Subject: [PATCH] mountlist: added /proc//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) diff --git a/ChangeLog b/ChangeLog index 9b3c85d..e312e0a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +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) + 2014-07-13 Pádraig Brady gettext: revert "update macros to version 0.19" diff --git a/DEPENDENCIES b/DEPENDENCIES index e19a37e..0d7691c 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//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..886c56d 100644 --- a/lib/mountlist.c +++ b/lib/mountlist.c @@ -128,6 +128,12 @@ # include #endif +#ifdef MOUNTED_PROC_MOUNTINFO +/* Use /proc//mountinfo instead of /proc/self/mounts (/etc/mtab) + * on Linux, if available */ +# include +#endif + #ifndef HAVE_HASMNTOPT # define hasmntopt(mnt, opt) ((char *) 0) #endif @@ -346,6 +352,17 @@ fstype_to_string (int t) } #endif /* MOUNTED_VMOUNT */ +#ifdef MOUNTED_PROC_MOUNTINFO +static const char * +mountinfo_path (void) { + static char filename[sizeof ("/proc//mountinfo") + 13]; /* 13 to hold a PID */ + + sprintf (filename, "/proc/%u/mountinfo", getpid ()); + + return filename; +} +#endif /* MOUNTED_PROC_MOUNTINFO */ + #if defined MOUNTED_GETMNTENT1 || defined MOUNTED_GETMNTENT2 @@ -429,32 +446,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 (mountinfo_path ()); - 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..0c7e1c4 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/PID/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//mountinfo on Linux.]) + LIBS="-lmount $LIBS" + fi fi fi -- 1.9.3