summaryrefslogtreecommitdiffstats
path: root/libmount
diff options
context:
space:
mode:
authorKarel Zak2015-08-17 11:54:26 +0200
committerKarel Zak2015-08-17 11:54:26 +0200
commit9ac77b8a78452eab0612523d27fee52159f5016a (patch)
tree1027d32d1c3b2065fc4efe5f15105c283a34f7f9 /libmount
parentdocs: add lsblk vs. btrfs to TODO (diff)
downloadkernel-qcow2-util-linux-9ac77b8a78452eab0612523d27fee52159f5016a.tar.gz
kernel-qcow2-util-linux-9ac77b8a78452eab0612523d27fee52159f5016a.tar.xz
kernel-qcow2-util-linux-9ac77b8a78452eab0612523d27fee52159f5016a.zip
libmount: add support for "bind,ro"
Now it's necessary t use two mount(8) calls to create a read-only mount: mount /foo /bar -o bind mount /bar -o remount,ro,bind This patch allows to specify "bind,ro" and the remount is done automatically by libmount by additional mount(2) syscall. It's not atomic of course. Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'libmount')
-rw-r--r--libmount/src/context_mount.c48
1 files changed, 47 insertions, 1 deletions
diff --git a/libmount/src/context_mount.c b/libmount/src/context_mount.c
index 63cba216b..9dadadf8e 100644
--- a/libmount/src/context_mount.c
+++ b/libmount/src/context_mount.c
@@ -63,6 +63,10 @@ static int mnt_context_append_additional_mount(struct libmnt_context *cxt,
return 0;
}
+/*
+ * add additional mount(2) syscall requests when necessary to set propagation flags
+ * after regular mount(2).
+ */
static int init_propagation(struct libmnt_context *cxt)
{
char *name;
@@ -102,6 +106,41 @@ static int init_propagation(struct libmnt_context *cxt)
return 0;
}
+/*
+ * add additional mount(2) syscall request to implement "ro,bind", the first regular
+ * mount(2) is the "bind" operation, the second is "remount,ro,bind" call.
+ *
+ * Note that we don't remove "ro" from the first syscall (kernel silently
+ * ignores this flags for bind operation) -- maybe one day kernel will support
+ * read-only binds in one step and then all will be done by the firts mount(2) and the
+ * second remount will be noop...
+ */
+static int init_robind(struct libmnt_context *cxt)
+{
+ struct libmnt_addmount *ad;
+ int rc;
+
+ assert(cxt);
+ assert(cxt->mountflags & MS_BIND);
+ assert(cxt->mountflags & MS_RDONLY);
+ assert(!(cxt->mountflags & MS_REMOUNT));
+
+ DBG(CXT, ul_debugobj(cxt, "mount: initialize additional ro,bind mount"));
+
+ ad = mnt_new_addmount();
+ if (!ad)
+ return -ENOMEM;
+
+ ad->mountflags = MS_REMOUNT | MS_BIND | MS_RDONLY;
+ if (cxt->mountflags & MS_REC)
+ ad->mountflags |= MS_REC;
+ rc = mnt_context_append_additional_mount(cxt, ad);
+ if (rc)
+ return rc;
+
+ return 0;
+}
+
#if defined(HAVE_LIBSELINUX) || defined(HAVE_SMACK)
struct libmnt_optname {
const char *name;
@@ -214,6 +253,13 @@ static int fix_optstr(struct libmnt_context *cxt)
if (rc)
return rc;
}
+ if ((cxt->mountflags & MS_BIND)
+ && (cxt->mountflags & MS_RDONLY)
+ && !(cxt->mountflags & MS_REMOUNT)) {
+ rc = init_robind(cxt);
+ if (rc)
+ return rc;
+ }
next = fs->fs_optstr;
@@ -731,7 +777,7 @@ static int do_mount(struct libmnt_context *cxt, const char *try_type)
-cxt->syscall_status));
return -cxt->syscall_status;
}
- DBG(CXT, ul_debugobj(cxt, "mount(2) success"));
+ DBG(CXT, ul_debugobj(cxt, " success"));
cxt->syscall_status = 0;
/*