summaryrefslogtreecommitdiffstats
path: root/shlibs/mount/src/tab_parse.c
diff options
context:
space:
mode:
authorKarel Zak2010-07-14 15:05:14 +0200
committerKarel Zak2011-01-03 12:28:40 +0100
commit0532ba1d8f875d97c3938bc8bd32e7e536f8d08f (patch)
tree71116b30652fdfec30ad0d624ef5f4e368e0b03a /shlibs/mount/src/tab_parse.c
parentlibmount: add mnt_split_optstr() (diff)
downloadkernel-qcow2-util-linux-0532ba1d8f875d97c3938bc8bd32e7e536f8d08f.tar.gz
kernel-qcow2-util-linux-0532ba1d8f875d97c3938bc8bd32e7e536f8d08f.tar.xz
kernel-qcow2-util-linux-0532ba1d8f875d97c3938bc8bd32e7e536f8d08f.zip
libmount: add mnt_tab_parse_mtab()
Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'shlibs/mount/src/tab_parse.c')
-rw-r--r--shlibs/mount/src/tab_parse.c90
1 files changed, 90 insertions, 0 deletions
diff --git a/shlibs/mount/src/tab_parse.c b/shlibs/mount/src/tab_parse.c
index 06bb64862..dc3486d53 100644
--- a/shlibs/mount/src/tab_parse.c
+++ b/shlibs/mount/src/tab_parse.c
@@ -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;
+}