]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-mount: allow creating tmpfs
authorLuca Boccassi <bluca@debian.org>
Wed, 16 Aug 2023 01:00:47 +0000 (02:00 +0100)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Mon, 21 Aug 2023 09:45:15 +0000 (11:45 +0200)
Mount units can do it, but the command line tool cannot, as it needs a
valid 'what'. If --tmpfs/-T if passed, parse the argument as 'where'
and send a literal 'tmpfs' as the 'what' if not specified.

man/systemd-mount.xml
src/mount/mount-tool.c
test/units/testsuite-74.mount.sh

index e25d5c435e95a29166bb85692339870c39f68d47..890c950cd05a8f821e69f5772829f7b9c217aa39 100644 (file)
       <arg choice="plain"><replaceable>WHAT</replaceable></arg>
       <arg choice="opt"><replaceable>WHERE</replaceable></arg>
     </cmdsynopsis>
+    <cmdsynopsis>
+      <command>systemd-mount</command>
+      <arg choice="opt" rep="repeat"><replaceable>OPTIONS</replaceable></arg>
+      <arg choice="plain"><option>--tmpfs</option></arg>
+      <arg choice="opt"><replaceable>NAME</replaceable></arg>
+      <arg choice="plain"><replaceable>WHERE</replaceable></arg>
+    </cmdsynopsis>
     <cmdsynopsis>
       <command>systemd-mount</command>
       <arg choice="opt" rep="repeat"><replaceable>OPTIONS</replaceable></arg>
@@ -63,7 +70,9 @@
     whose name is generated from the file system label. In this mode the block device or image file must
     exist at the time of invocation of the command, so that it may be probed. If the device is found to be a
     removable block device (e.g. a USB stick), an automount point is created instead of a regular mount point
-    (i.e. the <option>--automount=</option> option is implied, see below).</para>
+    (i.e. the <option>--automount=</option> option is implied, see below). If the option <option>--tmpfs</option>
+    is specified, then the argument will be interpreted as the path where the new temporary file system will
+    be mounted on.</para>
 
     <para>If two arguments are specified, the first indicates the mount source (the
     <replaceable>WHAT</replaceable>) and the second indicates the path to mount it on (the
         information.</para></listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><option>-T</option></term>
+        <term><option>--tmpfs</option></term>
+
+        <listitem>
+          <para>Create and mount a new temporary file system on <replaceable>WHERE</replaceable>, with an
+          optional <replaceable>NAME</replaceable> that defaults to <literal>tmpfs</literal>.</para>
+        </listitem>
+      </varlistentry>
+
       <xi:include href="user-system-options.xml" xpointer="user" />
       <xi:include href="user-system-options.xml" xpointer="system" />
       <xi:include href="user-system-options.xml" xpointer="host" />
index 89bf7fd80d20751f97da19977d0bc1af19bb96d1..31abc0685dcd1df904c78f8331bdcd067b4d9d7b 100644 (file)
@@ -71,6 +71,7 @@ static uid_t arg_uid = UID_INVALID;
 static gid_t arg_gid = GID_INVALID;
 static bool arg_fsck = true;
 static bool arg_aggressive_gc = false;
+static bool arg_tmpfs = false;
 
 STATIC_DESTRUCTOR_REGISTER(arg_mount_what, freep);
 STATIC_DESTRUCTOR_REGISTER(arg_mount_where, freep);
@@ -80,6 +81,34 @@ STATIC_DESTRUCTOR_REGISTER(arg_description, freep);
 STATIC_DESTRUCTOR_REGISTER(arg_property, strv_freep);
 STATIC_DESTRUCTOR_REGISTER(arg_automount_property, strv_freep);
 
+static int parse_where(const char *input, char **ret_where) {
+        _cleanup_free_ char *where = NULL;
+        int r;
+
+        assert(input);
+        assert(ret_where);
+
+        if (arg_transport == BUS_TRANSPORT_LOCAL) {
+                r = chase(input, NULL, CHASE_NONEXISTENT, &where, NULL);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to make path %s absolute: %m", input);
+        } else {
+                where = strdup(input);
+                if (!where)
+                        return log_oom();
+
+                path_simplify(where);
+
+                if (!path_is_absolute(where))
+                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+                                               "Path must be absolute when operating remotely: %s",
+                                               where);
+        }
+
+        *ret_where = TAKE_PTR(where);
+        return 0;
+}
+
 static int help(void) {
         _cleanup_free_ char *link = NULL;
         int r;
@@ -89,6 +118,7 @@ static int help(void) {
                 return log_oom();
 
         printf("systemd-mount [OPTIONS...] WHAT [WHERE]\n"
+               "systemd-mount [OPTIONS...] --tmpfs [NAME] WHERE\n"
                "systemd-mount [OPTIONS...] --list\n"
                "%s [OPTIONS...] %sWHAT|WHERE...\n\n"
                "Establish a mount or auto-mount point transiently.\n\n"
@@ -118,6 +148,7 @@ static int help(void) {
                "     --list                       List mountable block devices\n"
                "  -u --umount                     Unmount mount points\n"
                "  -G --collect                    Unload unit after it stopped, even when failed\n"
+               "  -T --tmpfs                      Create a new tmpfs on the mount point\n"
                "\nSee the %s for details.\n",
                program_invocation_short_name,
                streq(program_invocation_short_name, "systemd-umount") ? "" : "--umount ",
@@ -177,6 +208,7 @@ static int parse_argv(int argc, char *argv[]) {
                 { "umount",             no_argument,       NULL, 'u'                    },
                 { "unmount",            no_argument,       NULL, 'u'                    },
                 { "collect",            no_argument,       NULL, 'G'                    },
+                { "tmpfs",              no_argument,       NULL, 'T'                    },
                 {},
         };
 
@@ -188,7 +220,7 @@ static int parse_argv(int argc, char *argv[]) {
         if (invoked_as(argv, "systemd-umount"))
                 arg_action = ACTION_UMOUNT;
 
-        while ((c = getopt_long(argc, argv, "hqH:M:t:o:p:AuGl", options, NULL)) >= 0)
+        while ((c = getopt_long(argc, argv, "hqH:M:t:o:p:AuGlT", options, NULL)) >= 0)
 
                 switch (c) {
 
@@ -327,6 +359,10 @@ static int parse_argv(int argc, char *argv[]) {
                         arg_aggressive_gc = true;
                         break;
 
+                case 'T':
+                        arg_tmpfs = true;
+                        break;
+
                 case '?':
                         return -EINVAL;
 
@@ -361,7 +397,8 @@ static int parse_argv(int argc, char *argv[]) {
                         for (i = optind; i < argc; i++)
                                 if (!path_is_absolute(argv[i]) )
                                         return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
-                                                               "Only absolute path is supported: %s", argv[i]);
+                                                               "Path must be absolute when operating remotely: %s",
+                                                               argv[i]);
                 }
         } else {
                 if (optind >= argc)
@@ -372,50 +409,59 @@ static int parse_argv(int argc, char *argv[]) {
                         return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
                                                "At most two arguments required.");
 
-                if (arg_mount_type && !fstype_is_blockdev_backed(arg_mount_type)) {
-                        arg_mount_what = strdup(argv[optind]);
-                        if (!arg_mount_what)
-                                return log_oom();
+                if (arg_tmpfs) {
+                        if (argc <= optind+1) {
+                                arg_mount_what = strdup("tmpfs");
+                                if (!arg_mount_what)
+                                        return log_oom();
 
-                } else if (arg_transport == BUS_TRANSPORT_LOCAL) {
-                        _cleanup_free_ char *u = NULL;
+                                r = parse_where(argv[optind], &arg_mount_where);
+                                if (r < 0)
+                                        return r;
+                        } else {
+                                arg_mount_what = strdup(argv[optind]);
+                                if (!arg_mount_what)
+                                        return log_oom();
+                        }
 
-                        u = fstab_node_to_udev_node(argv[optind]);
-                        if (!u)
+                        if (!strv_contains(arg_property, "Type=tmpfs") &&
+                            strv_extend(&arg_property, "Type=tmpfs") < 0)
                                 return log_oom();
-
-                        r = chase(u, NULL, 0, &arg_mount_what, NULL);
-                        if (r < 0)
-                                return log_error_errno(r, "Failed to make path %s absolute: %m", u);
                 } else {
-                        arg_mount_what = strdup(argv[optind]);
-                        if (!arg_mount_what)
-                                return log_oom();
+                        if (arg_mount_type && !fstype_is_blockdev_backed(arg_mount_type)) {
+                                arg_mount_what = strdup(argv[optind]);
+                                if (!arg_mount_what)
+                                        return log_oom();
 
-                        path_simplify(arg_mount_what);
+                        } else if (arg_transport == BUS_TRANSPORT_LOCAL) {
+                                _cleanup_free_ char *u = NULL;
 
-                        if (!path_is_absolute(arg_mount_what))
-                                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
-                                                       "Only absolute path is supported: %s", arg_mount_what);
-                }
+                                u = fstab_node_to_udev_node(argv[optind]);
+                                if (!u)
+                                        return log_oom();
 
-                if (argc > optind+1) {
-                        if (arg_transport == BUS_TRANSPORT_LOCAL) {
-                                r = chase(argv[optind+1], NULL, CHASE_NONEXISTENT, &arg_mount_where, NULL);
+                                r = chase(u, NULL, 0, &arg_mount_what, NULL);
                                 if (r < 0)
-                                        return log_error_errno(r, "Failed to make path %s absolute: %m", argv[optind+1]);
+                                        return log_error_errno(r, "Failed to make path %s absolute: %m", u);
                         } else {
-                                arg_mount_where = strdup(argv[optind+1]);
-                                if (!arg_mount_where)
+                                arg_mount_what = strdup(argv[optind]);
+                                if (!arg_mount_what)
                                         return log_oom();
 
-                                path_simplify(arg_mount_where);
+                                path_simplify(arg_mount_what);
 
-                                if (!path_is_absolute(arg_mount_where))
+                                if (!path_is_absolute(arg_mount_what))
                                         return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
-                                                               "Only absolute path is supported: %s", arg_mount_where);
+                                                               "Path must be absolute when operating remotely: %s",
+                                                               arg_mount_what);
                         }
-                } else
+                }
+
+                if (argc > optind+1) {
+                        r = parse_where(argv[optind+1], &arg_mount_where);
+                        if (r < 0)
+                                return r;
+                } else if (!arg_tmpfs)
                         arg_discover = true;
 
                 if (arg_discover && arg_transport != BUS_TRANSPORT_LOCAL)
index c4ecfdcadad5195a2d92b7f3db72a2e2d8ad47d4..41c5c8652a23bb40dd013d29cf08204b43783c24 100755 (executable)
@@ -140,3 +140,12 @@ systemctl status "$WORK_DIR/mnt"
 touch "$WORK_DIR/mnt/hello"
 [[ "$(stat -c "%U:%G" "$WORK_DIR/mnt/hello")" == "testuser:testuser" ]]
 systemd-umount LABEL=owner-vfat
+
+# tmpfs
+mkdir -p "$WORK_DIR/mnt/foo/bar"
+systemd-mount --tmpfs "$WORK_DIR/mnt/foo"
+test ! -d "$WORK_DIR/mnt/foo/bar"
+touch "$WORK_DIR/mnt/foo/baz"
+systemd-umount "$WORK_DIR/mnt/foo"
+test -d "$WORK_DIR/mnt/foo/bar"
+test ! -e "$WORK_DIR/mnt/foo/baz"