6d73e5dfdf
Signed-off-by: Karel Zak <kzak@redhat.com>
106 lines
3.5 KiB
Diff
106 lines
3.5 KiB
Diff
From 0cac8948216a298deaf5fd30837ed9cc80618f80 Mon Sep 17 00:00:00 2001
|
|
From: Karel Zak <kzak@redhat.com>
|
|
Date: Tue, 31 May 2011 18:02:29 +0200
|
|
Subject: [PATCH] mount: use libmount to detect already mounted bind mounts
|
|
|
|
It's pretty tricky to detect that a bind mount from fstab is already
|
|
mounted on system without /etc/mtab. Let's use functionality from
|
|
libmount.
|
|
|
|
Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=701176
|
|
Signed-off-by: Karel Zak <kzak@redhat.com>
|
|
---
|
|
mount/mount.c | 42 ++++++++++++++++++++++++++++++++++++++----
|
|
1 files changed, 38 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/mount/mount.c b/mount/mount.c
|
|
index 29963c2..3ba705f 100644
|
|
--- a/mount/mount.c
|
|
+++ b/mount/mount.c
|
|
@@ -212,7 +212,7 @@ static const char *opt_loopdev, *opt_vfstype, *opt_offset, *opt_sizelimit,
|
|
*opt_encryption, *opt_speed, *opt_comment, *opt_uhelper;
|
|
|
|
static int is_readonly(const char *node);
|
|
-static int mounted (const char *spec0, const char *node0);
|
|
+static int mounted (const char *spec0, const char *node0, struct mntentchn *fstab_mc);
|
|
static int check_special_mountprog(const char *spec, const char *node,
|
|
const char *type, int flags, char *extra_opts, int *status);
|
|
|
|
@@ -1562,7 +1562,7 @@ try_mount_one (const char *spec0, const char *node0, const char *types0,
|
|
/* The "mount -f" checks for for existing record in /etc/mtab (with
|
|
* regular non-fake mount this is usually done by kernel)
|
|
*/
|
|
- if (!(flags & MS_REMOUNT) && fake && mounted (spec, node))
|
|
+ if (!(flags & MS_REMOUNT) && fake && mounted (spec, node, NULL))
|
|
die(EX_USAGE, _("mount: according to mtab, "
|
|
"%s is already mounted on %s\n"),
|
|
spec, node);
|
|
@@ -2016,13 +2016,46 @@ mount_one (const char *spec, const char *node, const char *types,
|
|
return try_mount_one (spec, node, types, opts, freq, pass, 0);
|
|
}
|
|
|
|
+#ifdef HAVE_LIBMOUNT_MOUNT
|
|
+static struct libmnt_table *minfo; /* parsed mountinfo file */
|
|
+#endif
|
|
+
|
|
/* Check if an fsname/dir pair was already in the old mtab. */
|
|
static int
|
|
-mounted (const char *spec0, const char *node0) {
|
|
+mounted (const char *spec0, const char *node0, struct mntentchn *fstab_mc) {
|
|
struct mntentchn *mc, *mc0;
|
|
const char *spec, *node;
|
|
int ret = 0;
|
|
|
|
+#ifdef HAVE_LIBMOUNT_MOUNT
|
|
+ /*
|
|
+ * Use libmount to check for already mounted bind mounts on systems
|
|
+ * without mtab.
|
|
+ */
|
|
+ if (fstab_mc && fstab_mc->m.mnt_opts &&
|
|
+ mtab_is_a_symlink() && strstr(fstab_mc->m.mnt_opts, "bind")) {
|
|
+
|
|
+ struct libmnt_fs *fs = mnt_new_fs();
|
|
+ int rc = fs ? 0 : -1;
|
|
+
|
|
+ if (!rc)
|
|
+ rc = mnt_fs_set_fstype(fs, fstab_mc->m.mnt_type);
|
|
+ if (!rc)
|
|
+ rc = mnt_fs_set_source(fs, fstab_mc->m.mnt_fsname);
|
|
+ if (!rc)
|
|
+ rc = mnt_fs_set_target(fs, fstab_mc->m.mnt_dir);
|
|
+ if (!rc)
|
|
+ rc = mnt_fs_set_options(fs, fstab_mc->m.mnt_opts);
|
|
+ if (!rc && !minfo)
|
|
+ minfo = mnt_new_table_from_file("/proc/self/mountinfo");
|
|
+ if (!rc && minfo)
|
|
+ rc = mnt_table_is_fs_mounted(minfo, fs);
|
|
+
|
|
+ mnt_free_fs(fs);
|
|
+ if (rc == 1)
|
|
+ return 1;
|
|
+ }
|
|
+#endif
|
|
/* Handle possible UUID= and LABEL= in spec */
|
|
spec = spec_to_devname(spec0);
|
|
if (!spec)
|
|
@@ -2030,6 +2063,7 @@ mounted (const char *spec0, const char *node0) {
|
|
|
|
node = canonicalize(node0);
|
|
|
|
+
|
|
mc0 = mtab_head();
|
|
for (mc = mc0->nxt; mc && mc != mc0; mc = mc->nxt)
|
|
if (streq (spec, mc->m.mnt_fsname) &&
|
|
@@ -2050,7 +2084,7 @@ is_fstab_entry_mounted(struct mntentchn *mc, int verbose)
|
|
{
|
|
struct stat st;
|
|
|
|
- if (mounted(mc->m.mnt_fsname, mc->m.mnt_dir))
|
|
+ if (mounted(mc->m.mnt_fsname, mc->m.mnt_dir, mc))
|
|
goto yes;
|
|
|
|
/* extra care for loop devices */
|
|
--
|
|
1.7.5.2
|
|
|