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>
This commit is contained in:
parent
5b7be9900a
commit
9ac77b8a78
|
@ -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.
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
/*
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue