summaryrefslogtreecommitdiffstats
path: root/libmount/src/tab.c
diff options
context:
space:
mode:
authorKarel Zak2012-03-09 13:11:24 +0100
committerKarel Zak2012-03-09 13:11:24 +0100
commit7293e97a42586ba552497bf7c8ab21e15b114541 (patch)
treeac979c32ed0db7c8e9c3d0fcc077d0432b45216f /libmount/src/tab.c
parentlsblk: add --version switch (diff)
downloadkernel-qcow2-util-linux-7293e97a42586ba552497bf7c8ab21e15b114541.tar.gz
kernel-qcow2-util-linux-7293e97a42586ba552497bf7c8ab21e15b114541.tar.xz
kernel-qcow2-util-linux-7293e97a42586ba552497bf7c8ab21e15b114541.zip
libmount: fix "already mounted" detection on systems with mtab
For systems with regular mtab the fs->root should be ignored in "already mounted" heuristic. Reported-by: Matt Burgess <matthew@linuxfromscratch.org> Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'libmount/src/tab.c')
-rw-r--r--libmount/src/tab.c66
1 files changed, 49 insertions, 17 deletions
diff --git a/libmount/src/tab.c b/libmount/src/tab.c
index 54d58c880..f3ec57381 100644
--- a/libmount/src/tab.c
+++ b/libmount/src/tab.c
@@ -704,16 +704,18 @@ struct libmnt_fs *mnt_table_find_pair(struct libmnt_table *tb, const char *sourc
}
/*
- * @tb: /proc/self/mountinfo
- * @fs: filesystem
- * @mountflags: MS_BIND or 0
- * @fsroot: fs-root that will be probably used in the mountinfo file
+ * tb: /proc/self/mountinfo
+ * fs: filesystem
+ * mountflags: MS_BIND or 0
+ * fsroot: fs-root that will be probably used in the mountinfo file
* for @fs after mount(2)
*
* For btrfs subvolumes this function returns NULL, but @fsroot properly set.
*
* Returns: entry from @tb that will be used as a source for @fs if the @fs is
* bindmount.
+ *
+ * Don't export to library API!
*/
struct libmnt_fs *mnt_table_get_fs_root(struct libmnt_table *tb,
struct libmnt_fs *fs,
@@ -816,6 +818,20 @@ err:
return NULL;
}
+static int is_mountinfo(struct libmnt_table *tb)
+{
+ struct libmnt_fs *fs;
+
+ if (!tb)
+ return 0;
+
+ fs = list_first_entry(&tb->ents, struct libmnt_fs, ents);
+ if (fs && mnt_fs_is_kernel(fs) && mnt_fs_get_root(fs))
+ return 1;
+
+ return 0;
+}
+
/**
* mnt_table_is_mounted:
* @tb: /proc/self/mountinfo file
@@ -831,10 +847,9 @@ err:
int mnt_table_is_fs_mounted(struct libmnt_table *tb, struct libmnt_fs *fstab_fs)
{
char *root = NULL;
- struct libmnt_fs *src_fs;
- const char *src;
+ const char *src = NULL;
char *xsrc = NULL, *tgt;
- int flags = 0, rc = 0;
+ int rc = 0;
assert(tb);
assert(fstab_fs);
@@ -842,12 +857,21 @@ int mnt_table_is_fs_mounted(struct libmnt_table *tb, struct libmnt_fs *fstab_fs)
if (mnt_fs_is_swaparea(fstab_fs))
return 0;
- if (mnt_fs_get_option(fstab_fs, "bind", NULL, NULL) == 0)
- flags = MS_BIND;
+ if (is_mountinfo(tb)) {
+ /* @tb is mountinfo, so we can try to use fs-roots */
+ struct libmnt_fs *fs;
+ int flags = 0;
- src_fs = mnt_table_get_fs_root(tb, fstab_fs, flags, &root);
- if (src_fs)
- src = mnt_fs_get_srcpath(src_fs);
+ if (mnt_fs_get_option(fstab_fs, "bind", NULL, NULL) == 0)
+ flags = MS_BIND;
+
+ fs = mnt_table_get_fs_root(tb, fstab_fs, flags, &root);
+ if (fs)
+ src = mnt_fs_get_srcpath(fs);
+ }
+
+ if (src)
+ src = xsrc = mnt_resolve_spec(src, tb->cache);
else if (mnt_fs_is_pseudofs(fstab_fs))
src = mnt_fs_get_source(fstab_fs);
else
@@ -856,18 +880,26 @@ int mnt_table_is_fs_mounted(struct libmnt_table *tb, struct libmnt_fs *fstab_fs)
tgt = mnt_resolve_path(mnt_fs_get_target(fstab_fs), tb->cache);
- if (tgt && src && root) {
+ if (tgt && src) {
struct libmnt_iter itr;
struct libmnt_fs *fs;
mnt_reset_iter(&itr, MNT_ITER_FORWARD);
while(mnt_table_next_fs(tb, &itr, &fs) == 0) {
- const char *r = mnt_fs_get_root(fs);
- if (r && strcmp(r, root) == 0
- && mnt_fs_streq_srcpath(fs, src)
- && mnt_fs_streq_target(fs, tgt))
+ if (root) {
+ /* mountinfo: compare root, source and target */
+ const char *r = mnt_fs_get_root(fs);
+
+ if (r && strcmp(r, root) == 0 &&
+ mnt_fs_streq_srcpath(fs, src) &&
+ mnt_fs_streq_target(fs, tgt))
+ break;
+ }
+ /* mtab: compare source and target */
+ else if (mnt_fs_streq_srcpath(fs, src) &&
+ mnt_fs_streq_target(fs, tgt))
break;
}
if (fs)