summaryrefslogtreecommitdiffstats
path: root/sys-utils/mount.c
diff options
context:
space:
mode:
authorKarel Zak2012-07-17 22:02:35 +0200
committerKarel Zak2012-07-17 22:02:35 +0200
commitaedeaa40d1cf5eb687a575b322a09a9a48ced623 (patch)
treeb7dba13be34a5afaa13486f524e11fcaaabea1f6 /sys-utils/mount.c
parentlibmount: allow to disable swap between source and target (diff)
downloadkernel-qcow2-util-linux-aedeaa40d1cf5eb687a575b322a09a9a48ced623.tar.gz
kernel-qcow2-util-linux-aedeaa40d1cf5eb687a575b322a09a9a48ced623.tar.xz
kernel-qcow2-util-linux-aedeaa40d1cf5eb687a575b322a09a9a48ced623.zip
mount: (new) add --source and --target
In some cases (for example if only one mount argument is given) may be mount request ambivalent: # mount /foo and fstab: /dev/sda5 /foo rw 0 0 /foo /bar bind 0 0 the new options allows to be more explicit # mount --target /foo (mounts /dev/sda5) # mount --source /foo (binds /foo to /bar) It's possible to use the options together # mount --source /dev/sda2 --target /home Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'sys-utils/mount.c')
-rw-r--r--sys-utils/mount.c98
1 files changed, 73 insertions, 25 deletions
diff --git a/sys-utils/mount.c b/sys-utils/mount.c
index 9116e8081..461569f2b 100644
--- a/sys-utils/mount.c
+++ b/sys-utils/mount.c
@@ -355,8 +355,19 @@ try_readonly:
warnx(_("%s is already mounted"), src);
return MOUNT_EX_USAGE;
case -MNT_ERR_NOFSTAB:
- warnx(_("can't find %s in %s"), src ? src : tgt,
+ if (mnt_context_is_swapmatch(cxt)) {
+ warnx(_("can't find %s in %s"),
+ src ? src : tgt,
mnt_get_fstab_path());
+ return MOUNT_EX_USAGE;
+ }
+ /* source/target explicitly defined */
+ if (tgt)
+ warnx(_("can't find mountpoint %s in %s"),
+ tgt, mnt_get_fstab_path());
+ else
+ warnx(_("can't find mount source %s in %s"),
+ src, mnt_get_fstab_path());
return MOUNT_EX_USAGE;
case -MNT_ERR_NOFSTYPE:
if (restricted)
@@ -595,7 +606,7 @@ static void __attribute__((__noreturn__)) usage(FILE *out)
fprintf(out, _(
" %1$s [-lhV]\n"
" %1$s -a [options]\n"
- " %1$s [options] <source> | <directory>\n"
+ " %1$s [options] [--source] <source> | [--target] <directory>\n"
" %1$s [options] <source> <directory>\n"
" %1$s <operation> <mountpoint> [<target>]\n"),
program_invocation_short_name);
@@ -619,6 +630,9 @@ static void __attribute__((__noreturn__)) usage(FILE *out)
" -r, --read-only mount the filesystem read-only (same as -o ro)\n"
" -t, --types <list> limit the set of filesystem types\n"));
fprintf(out, _(
+ " --source <src> explicitly specifies source (path, label, uuid)\n"
+ " --target <target> explicitly specifies mountpoint\n"));
+ fprintf(out, _(
" -v, --verbose say what is being done\n"
" -V, --version display version information and exit\n"
" -w, --read-write mount the filesystem read-write (default)\n"));
@@ -667,7 +681,7 @@ int main(int argc, char **argv)
int c, rc = MOUNT_EX_SUCCESS, all = 0, show_labels = 0;
struct libmnt_context *cxt;
struct libmnt_table *fstab = NULL;
- char *source = NULL, *srcbuf = NULL;
+ char *srcbuf = NULL;
char *types = NULL;
unsigned long oper = 0;
@@ -679,7 +693,9 @@ int main(int argc, char **argv)
MOUNT_OPT_RSHARED,
MOUNT_OPT_RSLAVE,
MOUNT_OPT_RPRIVATE,
- MOUNT_OPT_RUNBINDABLE
+ MOUNT_OPT_RUNBINDABLE,
+ MOUNT_OPT_TARGET,
+ MOUNT_OPT_SOURCE
};
enum {
@@ -692,9 +708,12 @@ int main(int argc, char **argv)
EXCL_MAKE_RSHARED,
EXCL_MAKE_RSLAVE,
EXCL_MAKE_RPRIVATE,
- EXCL_MAKE_RUNBINDABLE
+ EXCL_MAKE_RUNBINDABLE,
+ EXCL_SOURCE,
+ EXCL_UUID,
+ EXCL_LABEL
};
- int excl_any = EXCL_NONE;
+ int excl_any = EXCL_NONE, excl_src = EXCL_NONE;
static const struct option longopts[] = {
{ "all", 0, 0, 'a' },
@@ -729,6 +748,8 @@ int main(int argc, char **argv)
{ "no-canonicalize", 0, 0, 'c' },
{ "internal-only", 0, 0, 'i' },
{ "show-labels", 0, 0, 'l' },
+ { "target", 1, 0, MOUNT_OPT_TARGET },
+ { "source", 1, 0, MOUNT_OPT_SOURCE },
{ NULL, 0, 0, 0 }
};
@@ -749,7 +770,10 @@ int main(int argc, char **argv)
longopts, NULL)) != -1) {
/* only few options are allowed for non-root users */
- if (mnt_context_is_restricted(cxt) && !strchr("hlLUVvpris", c))
+ if (mnt_context_is_restricted(cxt) &&
+ !strchr("hlLUVvpris", c) &&
+ c != MOUNT_OPT_TARGET &&
+ c != MOUNT_OPT_SOURCE)
exit_non_root(option_to_longopt(c, longopts));
switch(c) {
@@ -803,13 +827,18 @@ int main(int argc, char **argv)
_("invalid passphrase file descriptor"));
break;
case 'L':
+ exclusive_option(&excl_src, EXCL_LABEL, _("-L, -U and --source"));
+ xasprintf(&srcbuf, "LABEL=\"%s\"", optarg);
+ mnt_context_disable_swapmatch(cxt, 1);
+ mnt_context_set_source(cxt, srcbuf);
+ free(srcbuf);
+ break;
case 'U':
- if (source)
- errx(MOUNT_EX_USAGE, _("only one <source> may be specified"));
- if (xasprintf(&srcbuf, "%s=\"%s\"",
- c == 'L' ? "LABEL" : "UUID", optarg) <= 0)
- err(MOUNT_EX_SYSERR, _("failed to allocate source buffer"));
- source = srcbuf;
+ exclusive_option(&excl_src, EXCL_UUID, _("-L, -U and --source"));
+ xasprintf(&srcbuf, "UUID=\"%s\"", optarg);
+ mnt_context_disable_swapmatch(cxt, 1);
+ mnt_context_set_source(cxt, srcbuf);
+ free(srcbuf);
break;
case 'l':
show_labels = 1;
@@ -865,6 +894,15 @@ int main(int argc, char **argv)
exclusive_option(&excl_any, EXCL_MAKE_RUNBINDABLE, EXCL_ERROR);
oper |= (MS_UNBINDABLE | MS_REC);
break;
+ case MOUNT_OPT_TARGET:
+ mnt_context_disable_swapmatch(cxt, 1);
+ mnt_context_set_target(cxt, optarg);
+ break;
+ case MOUNT_OPT_SOURCE:
+ exclusive_option(&excl_src, EXCL_SOURCE, _("-L, -U and --source"));
+ mnt_context_disable_swapmatch(cxt, 1);
+ mnt_context_set_source(cxt, optarg);
+ break;
default:
usage(stderr);
break;
@@ -874,14 +912,17 @@ int main(int argc, char **argv)
argc -= optind;
argv += optind;
- if (!source && !argc && !all) {
+ if (!mnt_context_get_source(cxt) &&
+ !mnt_context_get_target(cxt) &&
+ !argc &&
+ !all) {
if (oper)
usage(stderr);
print_all(cxt, types, show_labels);
goto done;
}
- if (oper && (types || all || source))
+ if (oper && (types || all || mnt_context_get_source(cxt)))
usage(stderr);
if (types && (all || strchr(types, ',') ||
@@ -899,25 +940,31 @@ int main(int argc, char **argv)
rc = mount_all(cxt);
goto done;
- } else if (argc == 0 && source) {
+ } else if (argc == 0 && (mnt_context_get_source(cxt) ||
+ mnt_context_get_target(cxt))) {
/*
- * B) mount -L|-U
+ * B) mount -L|-U|--source|--target
*/
- mnt_context_set_source(cxt, source);
+ if (mnt_context_is_restricted(cxt) &&
+ mnt_context_get_source(cxt) &&
+ mnt_context_get_target(cxt))
+ exit_non_root(NULL);
} else if (argc == 1) {
/*
- * C) mount [-L|-U] <target>
+ * C) mount [-L|-U|--source] <target>
* mount <source|target>
+ *
+ * non-root may specify source *or* target, but not both
*/
- if (source) {
- if (mnt_context_is_restricted(cxt))
- exit_non_root(NULL);
- mnt_context_set_source(cxt, source);
- }
+ if (mnt_context_is_restricted(cxt) &&
+ mnt_context_get_source(cxt))
+ exit_non_root(NULL);
+
mnt_context_set_target(cxt, argv[0]);
- } else if (argc == 2 && !source) {
+ } else if (argc == 2 && !mnt_context_get_source(cxt)
+ && !mnt_context_get_target(cxt)) {
/*
* D) mount <source> <target>
*/
@@ -925,6 +972,7 @@ int main(int argc, char **argv)
exit_non_root(NULL);
mnt_context_set_source(cxt, argv[0]);
mnt_context_set_target(cxt, argv[1]);
+
} else
usage(stderr);