]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
mount: (new) add --source and --target
authorKarel Zak <kzak@redhat.com>
Tue, 17 Jul 2012 20:02:35 +0000 (22:02 +0200)
committerKarel Zak <kzak@redhat.com>
Tue, 17 Jul 2012 20:02:35 +0000 (22:02 +0200)
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>
sys-utils/mount.8
sys-utils/mount.c

index 3ddd3f15539c628877d91c7b4e83a2bc3e0b98a3..c8b6f41c8670182530079d72e22f484d7d5df5d8 100644 (file)
@@ -99,7 +99,19 @@ If only directory or device is given, for example:
 
 .RE
 then mount looks for a mountpoint and if not found then for a device in the
-/etc/fstab file.
+/etc/fstab file. It's possible to use
+.B --target 
+or
+.B --source
+options to avoid ambivalent interpretation of the given argument. For example
+.RS
+
+.br
+.BI "mount --target /mountpoint"
+.br
+
+.RE
+
 
 .B The listing and help.
 .RS
@@ -557,6 +569,10 @@ Tolerate sloppy mount options rather than failing. This will ignore
 mount options not supported by a filesystem type. Not all filesystems
 support this option. This option exists for support of the Linux
 autofs\-based automounter.
+.IP "\fB\-\-source \fIsrc\fP"
+If only one argument for the mount command is given then the argument might be
+interpreted as target (mountpoint) or source (device). This option allows to
+explicitly define that the argument is mount source.
 .IP "\fB\-r, \-\-read\-only\fP"
 Mount the filesystem read-only. A synonym is
 .BR "\-o ro" .
@@ -733,6 +749,10 @@ mounts all filesystems except those of type
 and
 .IR ext .
 .RE
+.IP "\fB\-\-target \fIdir\fP"
+If only one argument for the mount command is given then the argument might be
+interpreted as target (mountpoint) or source (device). This option allows to
+explicitly define that the argument is mount target.
 .IP "\fB\-O, \-\-test-opts \fIopts\fP"
 Used in conjunction with
 .BR \-a ,
index 9116e808156f5ed7e5d8fae6ee25e93f2921201f..461569f2bb2ac57d86be51d932d34e283fb782ba 100644 (file)
@@ -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);