diff --git a/SOURCES/0084-libmount-add-support-for-bind-ro.patch b/SOURCES/0084-libmount-add-support-for-bind-ro.patch new file mode 100644 index 00000000..0de55564 --- /dev/null +++ b/SOURCES/0084-libmount-add-support-for-bind-ro.patch @@ -0,0 +1,159 @@ +From 2218dc0d130bb72809e2d8b26a36402bf6293727 Mon Sep 17 00:00:00 2001 +From: Karel Zak +Date: Mon, 17 Aug 2015 11:54:26 +0200 +Subject: [PATCH 84/86] libmount: add support for "bind,ro" + +Now it's necessary to 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. + +Addresses: http://bugzilla.redhat.com/show_bug.cgi?id=1281839 +Signed-off-by: Karel Zak +--- + libmount/src/context_mount.c | 46 ++++++++++++++++++++++++++++++++++++++++++++ + sys-utils/mount.8 | 37 ++++++++++++++++++----------------- + 2 files changed, 65 insertions(+), 18 deletions(-) + +diff --git a/libmount/src/context_mount.c b/libmount/src/context_mount.c +index d6691eb..4df2646 100644 +--- a/libmount/src/context_mount.c ++++ b/libmount/src/context_mount.c +@@ -62,6 +62,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) + } + + /* ++ * 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, mnt_debug_h(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; ++} ++ ++/* + * this has to be called after mnt_context_evaluate_permissions() + */ + static int fix_optstr(struct libmnt_context *cxt) +@@ -174,6 +213,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; + +diff --git a/sys-utils/mount.8 b/sys-utils/mount.8 +index 3648870..49cb281 100644 +--- a/sys-utils/mount.8 ++++ b/sys-utils/mount.8 +@@ -388,25 +388,25 @@ or shortoption + .\" available since Linux 2.4.11. + + Note that the filesystem mount options will remain the same as those +-on the original mount point, and cannot be changed by passing the -o +-option along with --bind/--rbind. The mount options can be +-changed by a separate remount command, for example: ++on the original mount point. ++ ++.BR mount(8) ++since v2.27 (backported to RHEL7.3) allow to change the options by passing the ++.B \-o ++option along with ++.BR \-\-bind ++for example: + + .RS + .br +-.B mount --bind +-.I olddir newdir +-.br +-.B mount -o remount,ro +-.I newdir ++.B mount \-\-bind,ro foo foo + .RE + +-Note that behavior of the remount operation depends on the /etc/mtab file. The +-first command stores the 'bind' flag to the /etc/mtab file and the second +-command reads the flag from the file. If you have a system without the +-/etc/mtab file or if you explicitly define source and target for the remount +-command (then mount(8) does not read /etc/mtab), then you have to use bind flag +-(or option) for the remount command too. For example: ++This feature is not supported by Linux kernel and it is implemented in userspace ++by additional remount mount(2) syscall. This solution is not atomic. ++ ++The alternative (classic) way to create a read-only bind mount is to use remount ++operation, for example: + + .RS + .br +@@ -417,14 +417,15 @@ command (then mount(8) does not read /etc/mtab), then you have to use bind flag + .I olddir newdir + .RE + +-Note that +-.I remount,ro,bind +-will create a read-only mountpoint (VFS entry), but the original filesystem suberblock +-will be still writable, it means that the ++Note that read-only bind will create a read-only mountpoint (VFS entry), but the ++original filesystem superblock will still be writable, meaning that the + .I olddir + will be writable, but the + .I newdir + will be read-only. ++ ++It's impossible to change mount options recursively ++(for example with \fB -o rbind,ro\fR). + .RE + + .B The move operation. +-- +2.7.4