diff options
-rw-r--r-- | Documentation/releases/v2.27-ReleaseNotes | 4 | ||||
-rw-r--r-- | libmount/src/context_mount.c | 48 | ||||
-rw-r--r-- | sys-utils/mount.8 | 35 |
3 files changed, 67 insertions, 20 deletions
diff --git a/Documentation/releases/v2.27-ReleaseNotes b/Documentation/releases/v2.27-ReleaseNotes index 44793220c..d537f7ef6 100644 --- a/Documentation/releases/v2.27-ReleaseNotes +++ b/Documentation/releases/v2.27-ReleaseNotes @@ -9,6 +9,10 @@ new default unifies unshare behavior and makes it independent of distribution default. The unshare supports persistent namespaces too (no process has to run to keep namespace in existence). +The command mount(8) supports read-only binds in one step by the options +"bind,ro" (command line or fstab). This feature is implemented by additional +remount mount(2) syscall and it is not atomic. + The commands fdisk and sfdisk can be compiled with GNU readline support to improve their line-editing functionality. 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; /* diff --git a/sys-utils/mount.8 b/sys-utils/mount.8 index b43958654..8c0fd83d8 100644 --- a/sys-utils/mount.8 +++ b/sys-utils/mount.8 @@ -362,28 +362,25 @@ a second place by using: .RE Note that the filesystem mount options will remain the same as those -on the original mount point, and cannot be changed by passing the +on the original mount point. + +.BR mount(8) +since v2.27 allow to change the options by passing the .B \-o option along with -.BR \-\-bind / \-\-rbind . -The mount options can be -changed by a separate remount command, for example: +.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 the behavior of the remount operation depends on the /etc/mtab file. -The first command stores the 'bind' flag in 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 \fBmount\fR(8) does not read /etc/mtab), then you have to use -the 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 @@ -394,14 +391,14 @@ the bind flag (or option) for the remount command too. For example: .I olddir newdir .RE -Note that -.B remount,ro,bind -will create a read-only mountpoint (VFS entry), but the original filesystem -superblock will still be writable, meaning 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 b \fB -o rbind,ro\fR). .RE .B The move operation. |