|
|
a0f4b9 |
From 9f7fe1b83fcc508dc3e05815d03dbbb752a1cfba Mon Sep 17 00:00:00 2001
|
|
|
a0f4b9 |
From: Karel Zak <kzak@redhat.com>
|
|
|
a0f4b9 |
Date: Fri, 1 Jun 2018 12:16:19 +0200
|
|
|
a0f4b9 |
Subject: [PATCH 63/63] libmount: improve MS_REC usage
|
|
|
a0f4b9 |
|
|
|
a0f4b9 |
libmount allows to split one library (mount(8)) call to multiple mount(2)
|
|
|
a0f4b9 |
syscalls, for example
|
|
|
a0f4b9 |
|
|
|
a0f4b9 |
--rbind --make-rslave
|
|
|
a0f4b9 |
|
|
|
a0f4b9 |
in this case we have to be careful with MS_REC because the flag is
|
|
|
a0f4b9 |
applied to multiple operations.
|
|
|
a0f4b9 |
|
|
|
a0f4b9 |
# strace -e mount mount --rbind --make-rslave /mnt/A /mnt/B
|
|
|
a0f4b9 |
|
|
|
a0f4b9 |
Old version:
|
|
|
a0f4b9 |
|
|
|
a0f4b9 |
mount("/mnt/A", "/mnt/B", 0x13ecac0, MS_MGC_VAL|MS_BIND, NULL) = 0
|
|
|
a0f4b9 |
mount("none", "/mnt/B", NULL, MS_REC|MS_SLAVE, NULL) = 0
|
|
|
a0f4b9 |
|
|
|
a0f4b9 |
Fixed version:
|
|
|
a0f4b9 |
|
|
|
a0f4b9 |
mount("/mnt/A", "/mnt/B", 0x1f22ac0, MS_MGC_VAL|MS_BIND|MS_REC, NULL) = 0
|
|
|
a0f4b9 |
mount("none", "/mnt/B", NULL, MS_REC|MS_SLAVE, NULL) = 0
|
|
|
a0f4b9 |
|
|
|
a0f4b9 |
Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=1946921
|
|
|
a0f4b9 |
Upstream: http://github.com/karelzak/util-linux/commit/816773b475900909d42c2c8282a6ac50252cac22
|
|
|
a0f4b9 |
Signed-off-by: Karel Zak <kzak@redhat.com>
|
|
|
a0f4b9 |
---
|
|
|
a0f4b9 |
libmount/src/context.c | 5 +++++
|
|
|
a0f4b9 |
libmount/src/context_mount.c | 25 ++++++++++++++++++++++---
|
|
|
a0f4b9 |
libmount/src/optstr.c | 9 ++++++---
|
|
|
a0f4b9 |
3 files changed, 33 insertions(+), 6 deletions(-)
|
|
|
a0f4b9 |
|
|
|
a0f4b9 |
diff --git a/libmount/src/context.c b/libmount/src/context.c
|
|
|
a0f4b9 |
index e7f1ee934..8e00b75a9 100644
|
|
|
a0f4b9 |
--- a/libmount/src/context.c
|
|
|
a0f4b9 |
+++ b/libmount/src/context.c
|
|
|
a0f4b9 |
@@ -1375,6 +1375,11 @@ struct libmnt_lock *mnt_context_get_lock(struct libmnt_context *cxt)
|
|
|
a0f4b9 |
*
|
|
|
a0f4b9 |
* both of these calls have the same effect.
|
|
|
a0f4b9 |
*
|
|
|
a0f4b9 |
+ * Be careful if you want to use MS_REC flag -- in this case the bit is applied
|
|
|
a0f4b9 |
+ * to all bind/slave/etc. options. If you want to mix more propadation flags
|
|
|
a0f4b9 |
+ * and/or bind, move operations than it's better to specify mount options by
|
|
|
a0f4b9 |
+ * strings.
|
|
|
a0f4b9 |
+ *
|
|
|
a0f4b9 |
* Returns: 0 on success, negative number in case of error.
|
|
|
a0f4b9 |
*/
|
|
|
a0f4b9 |
int mnt_context_set_mflags(struct libmnt_context *cxt, unsigned long flags)
|
|
|
a0f4b9 |
diff --git a/libmount/src/context_mount.c b/libmount/src/context_mount.c
|
|
|
a0f4b9 |
index b88e60507..a8e84127c 100644
|
|
|
a0f4b9 |
--- a/libmount/src/context_mount.c
|
|
|
a0f4b9 |
+++ b/libmount/src/context_mount.c
|
|
|
a0f4b9 |
@@ -73,6 +73,7 @@ static int init_propagation(struct libmnt_context *cxt)
|
|
|
a0f4b9 |
char *opts = (char *) mnt_fs_get_vfs_options(cxt->fs);
|
|
|
a0f4b9 |
size_t namesz;
|
|
|
a0f4b9 |
struct libmnt_optmap const *maps[1];
|
|
|
a0f4b9 |
+ int rec_count = 0;
|
|
|
a0f4b9 |
|
|
|
a0f4b9 |
if (!opts)
|
|
|
a0f4b9 |
return 0;
|
|
|
a0f4b9 |
@@ -86,9 +87,19 @@ static int init_propagation(struct libmnt_context *cxt)
|
|
|
a0f4b9 |
struct libmnt_addmount *ad;
|
|
|
a0f4b9 |
int rc;
|
|
|
a0f4b9 |
|
|
|
a0f4b9 |
- if (!mnt_optmap_get_entry(maps, 1, name, namesz, &ent)
|
|
|
a0f4b9 |
- || !ent
|
|
|
a0f4b9 |
- || !(ent->id & MS_PROPAGATION))
|
|
|
a0f4b9 |
+ if (!mnt_optmap_get_entry(maps, 1, name, namesz, &ent) || !ent)
|
|
|
a0f4b9 |
+ continue;
|
|
|
a0f4b9 |
+
|
|
|
a0f4b9 |
+ DBG(CXT, ul_debugobj(cxt, " checking %s", ent->name));
|
|
|
a0f4b9 |
+
|
|
|
a0f4b9 |
+ /* Note that MS_REC may be used for more flags, so we have to keep
|
|
|
a0f4b9 |
+ * track about number of recursive options to keep the MS_REC in the
|
|
|
a0f4b9 |
+ * mountflags if necessary.
|
|
|
a0f4b9 |
+ */
|
|
|
a0f4b9 |
+ if (ent->id & MS_REC)
|
|
|
a0f4b9 |
+ rec_count++;
|
|
|
a0f4b9 |
+
|
|
|
a0f4b9 |
+ if (!(ent->id & MS_PROPAGATION))
|
|
|
a0f4b9 |
continue;
|
|
|
a0f4b9 |
|
|
|
a0f4b9 |
ad = mnt_new_addmount();
|
|
|
a0f4b9 |
@@ -96,13 +107,21 @@ static int init_propagation(struct libmnt_context *cxt)
|
|
|
a0f4b9 |
return -ENOMEM;
|
|
|
a0f4b9 |
|
|
|
a0f4b9 |
ad->mountflags = ent->id;
|
|
|
a0f4b9 |
+ DBG(CXT, ul_debugobj(cxt, " adding extra mount(2) call for %s", ent->name));
|
|
|
a0f4b9 |
rc = mnt_context_append_additional_mount(cxt, ad);
|
|
|
a0f4b9 |
if (rc)
|
|
|
a0f4b9 |
return rc;
|
|
|
a0f4b9 |
|
|
|
a0f4b9 |
+ DBG(CXT, ul_debugobj(cxt, " removing %s from primary mount(2) call", ent->name));
|
|
|
a0f4b9 |
cxt->mountflags &= ~ent->id;
|
|
|
a0f4b9 |
+
|
|
|
a0f4b9 |
+ if (ent->id & MS_REC)
|
|
|
a0f4b9 |
+ rec_count--;
|
|
|
a0f4b9 |
}
|
|
|
a0f4b9 |
|
|
|
a0f4b9 |
+ if (rec_count)
|
|
|
a0f4b9 |
+ cxt->mountflags |= MS_REC;
|
|
|
a0f4b9 |
+
|
|
|
a0f4b9 |
return 0;
|
|
|
a0f4b9 |
}
|
|
|
a0f4b9 |
|
|
|
a0f4b9 |
diff --git a/libmount/src/optstr.c b/libmount/src/optstr.c
|
|
|
a0f4b9 |
index 8248f0dee..cc077ffd9 100644
|
|
|
a0f4b9 |
--- a/libmount/src/optstr.c
|
|
|
a0f4b9 |
+++ b/libmount/src/optstr.c
|
|
|
a0f4b9 |
@@ -800,14 +800,17 @@ int mnt_optstr_apply_flags(char **optstr, unsigned long flags,
|
|
|
a0f4b9 |
if (rc)
|
|
|
a0f4b9 |
goto err;
|
|
|
a0f4b9 |
}
|
|
|
a0f4b9 |
- if (!(ent->mask & MNT_INVERT))
|
|
|
a0f4b9 |
+ if (!(ent->mask & MNT_INVERT)) {
|
|
|
a0f4b9 |
fl &= ~ent->id;
|
|
|
a0f4b9 |
+ if (ent->id & MS_REC)
|
|
|
a0f4b9 |
+ fl |= MS_REC;
|
|
|
a0f4b9 |
+ }
|
|
|
a0f4b9 |
}
|
|
|
a0f4b9 |
}
|
|
|
a0f4b9 |
}
|
|
|
a0f4b9 |
|
|
|
a0f4b9 |
- /* add missing options */
|
|
|
a0f4b9 |
- if (fl) {
|
|
|
a0f4b9 |
+ /* add missing options (but ignore fl if contains MS_REC only) */
|
|
|
a0f4b9 |
+ if (fl && fl != MS_REC) {
|
|
|
a0f4b9 |
const struct libmnt_optmap *ent;
|
|
|
a0f4b9 |
char *p;
|
|
|
a0f4b9 |
|
|
|
a0f4b9 |
--
|
|
|
a0f4b9 |
2.31.1
|
|
|
a0f4b9 |
|