From be6904b92f51bb5579bec97934417fce00a0e5a0 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Tue, 15 Jan 2013 14:23:54 +0100 Subject: mount: support multiple MS_PROPAGATION flags in one mount(8) exec Signed-off-by: Karel Zak --- sys-utils/mount.c | 64 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 37 insertions(+), 27 deletions(-) (limited to 'sys-utils/mount.c') diff --git a/sys-utils/mount.c b/sys-utils/mount.c index fed96eb7b..0b57c92a0 100644 --- a/sys-utils/mount.c +++ b/sys-utils/mount.c @@ -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. 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); -- cgit v1.2.3-55-g7522