]> err.no Git - util-linux/commitdiff
libmount: add mnt_tab_parse_mtab()
authorKarel Zak <kzak@redhat.com>
Wed, 14 Jul 2010 13:05:14 +0000 (15:05 +0200)
committerKarel Zak <kzak@redhat.com>
Mon, 3 Jan 2011 11:28:40 +0000 (12:28 +0100)
Signed-off-by: Karel Zak <kzak@redhat.com>
misc-utils/findmnt.c
shlibs/mount/src/fs.c
shlibs/mount/src/mount.h.in
shlibs/mount/src/mount.sym
shlibs/mount/src/mountP.h
shlibs/mount/src/tab.c
shlibs/mount/src/tab_parse.c
shlibs/mount/src/utils.c

index 76564f6b863f410de588c38d1e4b3b667fa667bc..7314bb6e37ae3e387de50060eafed7785d123fa0 100644 (file)
@@ -330,6 +330,8 @@ static mnt_tab *parse_tabfile(const char *path)
 
        if (!strcmp(path, _PATH_MNTTAB))
                rc = mnt_tab_parse_fstab(tb);
+       else if (!strcmp(path, _PATH_MOUNTED))
+               rc = mnt_tab_parse_mtab(tb);
        else
                rc = mnt_tab_parse_file(tb, path);
 
index 8e51fd73d3c9e1a94fb577b7a5d3ad35313e9342..0cd2eaa5b1bf71b9d07286eedcd2258efe468c53 100644 (file)
@@ -381,6 +381,7 @@ int mnt_fs_append_optstr(mnt_fs *fs, const char *optstr)
 
        if (!fs || !optstr)
                return -1;
+
        return mnt_optstr_append_option(&fs->optstr, optstr, NULL);
 }
 
index 402d8fc7644187fb7a40d59f5fcdd3f19c4c02b6..fcb4b4e5a79976b35f3bff05d06c58eb820c17f0 100644 (file)
@@ -271,6 +271,7 @@ extern mnt_tab *mnt_new_tab_from_file(const char *filename);
 extern int mnt_tab_parse_stream(mnt_tab *tb, FILE *f, const char *filename);
 extern int mnt_tab_parse_file(mnt_tab *tb, const char *filename);
 extern int mnt_tab_parse_fstab(mnt_tab *tb);
+extern int mnt_tab_parse_mtab(mnt_tab *tb);
 extern int mnt_tab_set_parser_errcb(mnt_tab *tb,
                 int (*cb)(mnt_tab *tb, const char *filename, int line, int flag));
 
index e5c1fcf96f4bbd4cce260a9352a0d5b2ac9fcc3f..14d9fbf4ef71d5ff0f74462efa925980d276a081 100644 (file)
@@ -126,6 +126,7 @@ global:
        mnt_tab_next_fs;
        mnt_tab_parse_file;
        mnt_tab_parse_fstab;
+       mnt_tab_parse_mtab;
        mnt_tab_parse_stream;
        mnt_tab_remove_fs;
        mnt_tab_set_cache;
index 04084e5d1f2846c83033305025ba7cc37cb3a734..1de13917f1a4d35aa6e06d39376e03977c5740d9 100644 (file)
@@ -50,6 +50,10 @@ extern int libmount_debug_mask;
 /* extension for files in the /etc/fstab.d directory */
 #define MNT_MNTTABDIR_EXT      ".fstab"
 
+/* library private paths */
+#define MNT_PATH_RUNDIR                "/var/run/mount"
+#define MNT_PATH_MOUNTINFO     MNT_PATH_RUNDIR "/mountinfo"
+
 #ifdef TEST_PROGRAM
 struct mtest {
        const char      *name;
@@ -64,6 +68,7 @@ extern int mnt_run_test(struct mtest *tests, int argc, char *argv[]);
 /* utils.c */
 extern char *mnt_getenv_safe(const char *arg);
 extern char *mnt_get_username(const uid_t uid);
+extern int mnt_has_regular_mtab(void);
 
 /*
  * Generic iterator
@@ -206,6 +211,4 @@ extern int mnt_optent_assign_map(mnt_optent *op,
 extern int __mnt_fs_set_source(mnt_fs *fs, char *source);
 extern int __mnt_fs_set_fstype(mnt_fs *fs, char *fstype);
 
-
-
 #endif /* _LIBMOUNT_PRIVATE_H */
index 45e52e1b6f4c6506819fba8cdc18555bf8c9ed0b..939e8c8767e8abe031f06f808f92cc237b9108d6 100644 (file)
@@ -332,6 +332,8 @@ int mnt_tab_next_fs(mnt_tab *tb, mnt_iter *itr, mnt_fs **fs)
        if (!tb || !itr || !fs)
                return -1;
        rc = 1;
+       *fs = NULL;
+
        if (!itr->head)
                MNT_ITER_INIT(itr, &tb->ents);
        if (itr->p != itr->head) {
index 06bb6486267bd2aa741729b67e9c91004cd03a48..dc3486d53fec47853485234ea937bd812e89261d 100644 (file)
@@ -602,3 +602,93 @@ done:
 
        return num > 0 ? 0 : -1;
 }
+
+/*
+ * This function uses @uf to found corresponding record in @tb, then the record
+ * from @tb is updated (userspace specific mount options are added).
+ *
+ * Note that @uf must contain userspace specific mount options only!
+ *
+ * Returns: modified filesystem (from @tb) or NULL.
+ */
+static mnt_fs *mnt_tab_merge_userspace_fs(mnt_tab *tb, mnt_fs *uf)
+{
+       mnt_fs *fs;
+       mnt_iter itr;
+       const char *optstr, *src, *target, *root;
+
+       assert(tb);
+       assert(uf);
+       if (!tb || !uf)
+               return NULL;
+
+       src = mnt_fs_get_srcpath(uf);
+       target = mnt_fs_get_target(uf);
+       optstr = mnt_fs_get_vfs_optstr(uf);
+       root = mnt_fs_get_root(uf);
+
+       if (!src || !target || !optstr || !root)
+               return NULL;
+
+       mnt_reset_iter(&itr, MNT_ITER_BACKWARD);
+
+       while(mnt_tab_next_fs(tb, &itr, &fs) == 0) {
+               const char *s = mnt_fs_get_srcpath(fs),
+                          *t = mnt_fs_get_target(fs),
+                          *r = mnt_fs_get_root(fs);
+
+               if (s && t && r && !strcmp(t, target) &&
+                   !strcmp(s, src) && !strcmp(r, root))
+                       break;
+       }
+
+       if (fs)
+               mnt_fs_append_optstr(fs, optstr);
+       return fs;
+}
+
+/**
+ * mnt_tab_parse_mtab:
+ * @tb: table
+ *
+ * This function parses /etc/mtab or {/proc/self,/var/run/mount}/mountinfo or
+ * /proc/mounts. Note that the /var/run/mount/mountinfo file is optional and
+ * contains userspace specific mount options only.
+ *
+ * See also mnt_tab_set_parser_errcb().
+ *
+ * Returns: 0 on success or -1 in case of error.
+ */
+int mnt_tab_parse_mtab(mnt_tab *tb)
+{
+       int rc;
+       mnt_tab *u_tb;
+       mnt_fs *u_fs;
+       mnt_iter itr;
+
+       if (mnt_has_regular_mtab()) {
+               rc = mnt_tab_parse_file(tb, _PATH_MOUNTED);
+               if (!rc)
+                       return 0;               /* system with regular mtab */
+       }
+
+       /* read kernel information from /proc/self/mountinfo */
+       rc = mnt_tab_parse_file(tb, _PATH_PROC_MOUNTINFO);
+       if (rc)
+               /* hmm, old kernel? ...try /proc/mounts */
+               return mnt_tab_parse_file(tb, _PATH_PROC_MOUNTS);
+
+       /* try to read userspace specific information from /var/run/mount */
+       u_tb = mnt_new_tab_from_file(MNT_PATH_MOUNTINFO);
+       if (!u_tb)
+               return 0;       /* private mountinfo does not exist */
+
+       mnt_reset_iter(&itr, MNT_ITER_BACKWARD);
+
+       /*  merge userspace options into mountinfo from kernel */
+       while(mnt_tab_next_fs(u_tb, &itr, &u_fs) == 0)
+               mnt_tab_merge_userspace_fs(tb, u_fs);
+
+       mnt_free_tab(u_tb);
+       return 0;
+}
index a1ab50c08381f01a52fd05ee077085c22e6b837a..9bdd62adee9296ecce58fdf5211558ea2dda7ef6 100644 (file)
@@ -28,6 +28,7 @@
 #include <fcntl.h>
 #include <pwd.h>
 
+#include "pathnames.h"
 #include "mountP.h"
 
 char *mnt_getenv_safe(const char *arg)
@@ -249,6 +250,18 @@ char *mnt_get_username(const uid_t uid)
        return username;
 }
 
+/*
+ * Returns 1 if /etc/mtab is a reqular file.
+ */
+int mnt_has_regular_mtab(void)
+{
+       struct stat st;
+
+       if (lstat(_PATH_MOUNTED, &st) == 0 && S_ISREG(st.st_mode))
+               return 1;
+       return 0;
+}
+
 #ifdef TEST_PROGRAM
 int test_match_fstype(struct mtest *ts, int argc, char *argv[])
 {