mount: support multiple MS_PROPAGATION flags in one mount(8) exec
Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
parent
6498ece0e7
commit
be6904b92f
|
@ -458,14 +458,11 @@ of that mount such that mounts and umounts within any of the mirrors propagate
|
|||
to the other mirror. A slave mount receives propagation from its master, but
|
||||
any not vice-versa. A private mount carries no propagation abilities. A
|
||||
unbindable mount is a private mount which cannot be cloned through a bind
|
||||
operation. Detailed semantics is documented in Documentation/filesystems/sharedsubtree.txt
|
||||
operation. Detailed semantics is documented in
|
||||
.B Documentation/filesystems/sharedsubtree.txt
|
||||
file in the kernel source tree.
|
||||
|
||||
Note that Linux kernel does not allow to change more propagation flags by one
|
||||
.BR mount (2)
|
||||
syscall and the flags cannot be mixed with another mount options. It means that
|
||||
more --make-* options cannot be used together or with another mount options.
|
||||
|
||||
Supported operations:
|
||||
.RS
|
||||
.nf
|
||||
.BI "mount --make-shared " mountpoint
|
||||
|
@ -486,6 +483,41 @@ mounts under a given mountpoint.
|
|||
.BI "mount --make-runbindable " mountpoint
|
||||
.fi
|
||||
.RE
|
||||
|
||||
.BR mount (8)
|
||||
.B does not read
|
||||
.BR fstab (5)
|
||||
when --make-* operation is requested. All necessary information has to be
|
||||
specified on command line.
|
||||
|
||||
Note that Linux kernel does not allow to change more propagation flags by one
|
||||
.BR mount (2)
|
||||
syscall and the flags cannot be mixed with another mount options.
|
||||
|
||||
Since util-linux 2.23 mount command allows to use more propagation flags
|
||||
together and with another mount operations. This feature is EXPERIMENTAL. In
|
||||
this case the propagation flags are applied by additional mount(2) syscalls
|
||||
after previous successful mount operation. Note that this use case is not
|
||||
atomic. The propagation flags is possible to specified in
|
||||
.BR fstab (5)
|
||||
as mount options
|
||||
(private,slave,shared,unbindable,rprivate,rslave,rshared,runbindable).
|
||||
|
||||
For example
|
||||
.RS
|
||||
.nf
|
||||
.BI "mount --make-private --make-unbindable /dev/sda1 /A"
|
||||
.fi
|
||||
.RE
|
||||
|
||||
is the same as
|
||||
.RS
|
||||
.nf
|
||||
.BI "mount /dev/sda1 /A"
|
||||
.BI "mount --make-private /A"
|
||||
.BI "mount --make-unbindable /A"
|
||||
.fi
|
||||
.RE
|
||||
.RE
|
||||
|
||||
.SH COMMAND LINE OPTIONS
|
||||
|
|
|
@ -335,11 +335,14 @@ static int mk_exit_code(struct libmnt_context *cxt, int rc)
|
|||
const char *src = mnt_context_get_source(cxt);
|
||||
|
||||
try_readonly:
|
||||
if (mnt_context_helper_executed(cxt))
|
||||
if (mnt_context_helper_executed(cxt)) {
|
||||
/*
|
||||
* /sbin/mount.<type> called, return status
|
||||
*/
|
||||
if (rc == -MNT_ERR_APPLYFLAGS)
|
||||
warnx(_("WARNING: failed to apply propagation flags"));
|
||||
return mnt_context_get_helper_status(cxt);
|
||||
}
|
||||
|
||||
if (rc == 0 && mnt_context_get_status(cxt) == 1) {
|
||||
/*
|
||||
|
@ -497,7 +500,7 @@ try_readonly:
|
|||
case EINVAL:
|
||||
if (mflags & MS_REMOUNT)
|
||||
warnx(_("%s not mounted or bad option"), tgt);
|
||||
else if (mflags & MS_PROPAGATION)
|
||||
else if (rc == -MNT_ERR_APPLYFLAGS)
|
||||
warnx(_("%s is not mountpoint or bad option"), tgt);
|
||||
else
|
||||
warnx(_("wrong fs type, bad option, bad superblock on %s,\n"
|
||||
|
@ -635,6 +638,12 @@ static void sanitize_paths(struct libmnt_context *cxt)
|
|||
}
|
||||
}
|
||||
|
||||
static void append_option(struct libmnt_context *cxt, const char *opt)
|
||||
{
|
||||
if (mnt_context_append_options(cxt, opt))
|
||||
err(MOUNT_EX_SYSERR, _("failed to append option '%s'"), opt);
|
||||
}
|
||||
|
||||
static void __attribute__((__noreturn__)) usage(FILE *out)
|
||||
{
|
||||
fputs(USAGE_HEADER, out);
|
||||
|
@ -718,6 +727,7 @@ int main(int argc, char **argv)
|
|||
char *srcbuf = NULL;
|
||||
char *types = NULL;
|
||||
unsigned long oper = 0;
|
||||
int propa = 0;
|
||||
|
||||
enum {
|
||||
MOUNT_OPT_SHARED = CHAR_MAX + 1,
|
||||
|
@ -771,12 +781,7 @@ int main(int argc, char **argv)
|
|||
};
|
||||
|
||||
static const ul_excl_t excl[] = { /* rows and cols in in ASCII order */
|
||||
{ 'B','M','R', /* bind,move,rbind */
|
||||
MOUNT_OPT_SHARED, MOUNT_OPT_SLAVE,
|
||||
MOUNT_OPT_PRIVATE, MOUNT_OPT_UNBINDABLE,
|
||||
MOUNT_OPT_RSHARED, MOUNT_OPT_RSLAVE,
|
||||
MOUNT_OPT_RPRIVATE, MOUNT_OPT_RUNBINDABLE },
|
||||
|
||||
{ 'B','M','R' }, /* bind,move,rbind */
|
||||
{ 'L','U', MOUNT_OPT_SOURCE }, /* label,uuid,source */
|
||||
{ 0 }
|
||||
};
|
||||
|
@ -830,8 +835,7 @@ int main(int argc, char **argv)
|
|||
mnt_context_disable_mtab(cxt, TRUE);
|
||||
break;
|
||||
case 'r':
|
||||
if (mnt_context_append_options(cxt, "ro"))
|
||||
err(MOUNT_EX_SYSERR, _("failed to append options"));
|
||||
append_option(cxt, "ro");
|
||||
readwrite = 0;
|
||||
break;
|
||||
case 'v':
|
||||
|
@ -841,13 +845,11 @@ int main(int argc, char **argv)
|
|||
print_version();
|
||||
break;
|
||||
case 'w':
|
||||
if (mnt_context_append_options(cxt, "rw"))
|
||||
err(MOUNT_EX_SYSERR, _("failed to append options"));
|
||||
append_option(cxt, "rw");
|
||||
readwrite = 1;
|
||||
break;
|
||||
case 'o':
|
||||
if (mnt_context_append_options(cxt, optarg))
|
||||
err(MOUNT_EX_SYSERR, _("failed to append options"));
|
||||
append_option(cxt, optarg);
|
||||
break;
|
||||
case 'O':
|
||||
if (mnt_context_set_options_pattern(cxt, optarg))
|
||||
|
@ -890,28 +892,36 @@ int main(int argc, char **argv)
|
|||
oper |= (MS_BIND | MS_REC);
|
||||
break;
|
||||
case MOUNT_OPT_SHARED:
|
||||
oper |= MS_SHARED;
|
||||
append_option(cxt, "shared");
|
||||
propa = 1;
|
||||
break;
|
||||
case MOUNT_OPT_SLAVE:
|
||||
oper |= MS_SLAVE;
|
||||
append_option(cxt, "slave");
|
||||
propa = 1;
|
||||
break;
|
||||
case MOUNT_OPT_PRIVATE:
|
||||
oper |= MS_PRIVATE;
|
||||
append_option(cxt, "private");
|
||||
propa = 1;
|
||||
break;
|
||||
case MOUNT_OPT_UNBINDABLE:
|
||||
oper |= MS_UNBINDABLE;
|
||||
append_option(cxt, "unbindable");
|
||||
propa = 1;
|
||||
break;
|
||||
case MOUNT_OPT_RSHARED:
|
||||
oper |= (MS_SHARED | MS_REC);
|
||||
append_option(cxt, "rshared");
|
||||
propa = 1;
|
||||
break;
|
||||
case MOUNT_OPT_RSLAVE:
|
||||
oper |= (MS_SLAVE | MS_REC);
|
||||
append_option(cxt, "rslave");
|
||||
propa = 1;
|
||||
break;
|
||||
case MOUNT_OPT_RPRIVATE:
|
||||
oper |= (MS_PRIVATE | MS_REC);
|
||||
append_option(cxt, "rprivate");
|
||||
propa = 1;
|
||||
break;
|
||||
case MOUNT_OPT_RUNBINDABLE:
|
||||
oper |= (MS_UNBINDABLE | MS_REC);
|
||||
append_option(cxt, "runbindable");
|
||||
propa = 1;
|
||||
break;
|
||||
case MOUNT_OPT_TARGET:
|
||||
mnt_context_disable_swapmatch(cxt, 1);
|
||||
|
@ -944,7 +954,7 @@ int main(int argc, char **argv)
|
|||
!mnt_context_get_target(cxt) &&
|
||||
!argc &&
|
||||
!all) {
|
||||
if (oper)
|
||||
if (oper || mnt_context_get_options(cxt))
|
||||
usage(stderr);
|
||||
print_all(cxt, types, show_labels);
|
||||
goto done;
|
||||
|
@ -1010,13 +1020,13 @@ int main(int argc, char **argv)
|
|||
if (mnt_context_is_restricted(cxt))
|
||||
sanitize_paths(cxt);
|
||||
|
||||
if (oper) {
|
||||
/* MS_PROPAGATION operations, let's set the mount flags */
|
||||
if (oper)
|
||||
/* BIND/MOVE operations, let's set the mount flags */
|
||||
mnt_context_set_mflags(cxt, oper);
|
||||
|
||||
/* For -make* or --bind is fstab unnecessary */
|
||||
if (oper || propa)
|
||||
/* For --make-* or --bind is fstab unnecessary */
|
||||
mnt_context_set_optsmode(cxt, MNT_OMODE_NOTAB);
|
||||
}
|
||||
|
||||
rc = mnt_context_mount(cxt);
|
||||
rc = mk_exit_code(cxt, rc);
|
||||
|
|
Loading…
Reference in New Issue