diff options
author | Karel Zak | 2015-08-17 11:54:26 +0200 |
---|---|---|
committer | Karel Zak | 2015-08-17 11:54:26 +0200 |
commit | 9ac77b8a78452eab0612523d27fee52159f5016a (patch) | |
tree | 1027d32d1c3b2065fc4efe5f15105c283a34f7f9 /libmount | |
parent | docs: add lsblk vs. btrfs to TODO (diff) | |
download | kernel-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.c | 48 |
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; /* |