]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
vmspawn: change order of fields in --extra-drive=
authorZbigniew Jędrzejewski-Szmek <zbyszek@amutable.com>
Tue, 3 Mar 2026 15:32:29 +0000 (16:32 +0100)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 3 Mar 2026 22:05:32 +0000 (07:05 +0900)
Closes #40877. As requested, --extra-drive=path[:format] is changed
to --extra-drive=[format:]path, so that the parsing is less ambiguous.
(In the original request, it was requested that the empty format can be
used also, but that was dropped in the second version of the patch.)

NEWS
man/systemd-vmspawn.xml
src/vmspawn/vmspawn.c

diff --git a/NEWS b/NEWS
index 495f12eda80898ea8c3f8791452398c2b57503b7..82b30951d24e4b0ae6c99297dff4b80396cfd985 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -329,8 +329,8 @@ CHANGES WITH 260 in spe:
           the same switch in systemd-nspawn.
 
         * systemd-vmspawn gained a new switch --image-format= for selecting the
-          image format (i.e. support qcow2 in additin to raw) to boot
-          from. --extra-drive= now takes the image format as a colon separated
+          image format (i.e. support qcow2 in additin to raw) to boot from.
+          Also --extra-drive= now takes the image format as a colon separated
           parameter.
 
         Changes in systemd-nsresourced/systemd-mountfsd:
index 0b4fef2314a6dafb7caf60f9fad609e831be8ddf..136bd6534062b4c9fa48349f2e9b1ca9c2454b54 100644 (file)
         </varlistentry>
 
         <varlistentry>
-          <term><option>--extra-drive=<replaceable>PATH</replaceable>[:<replaceable>FORMAT</replaceable>]</option></term>
+          <term><option>--extra-drive=[<replaceable>FORMAT</replaceable>:]<replaceable>PATH</replaceable></option></term>
 
           <listitem><para>Takes a disk image or block device on the host and supplies it to the virtual
-          machine as another drive. Optionally, the image format can be specified by appending a colon and
-          the format (<literal>raw</literal> or <literal>qcow2</literal>). Defaults to <literal>raw</literal>.
-          Note that <literal>qcow2</literal> is only supported for regular files, not block devices.</para>
+          machine as another drive. Optionally, the image format can be specified by prefixing the path with
+          <literal>raw</literal> or <literal>qcow2</literal> and a colon. The format defaults to
+          <literal>raw</literal>. Note that <literal>qcow2</literal> is only supported for regular files, not
+          block devices.</para>
 
           <xi:include href="version-info.xml" xpointer="v256"/></listitem>
         </varlistentry>
index d68a621e060de6c56a2ca9192f6de34383be3dfb..fc647b15638fac9e73c4da7e809e6e9286585bab 100644 (file)
@@ -238,9 +238,9 @@ static int help(void) {
                "                           Mount a file or directory from the host into the VM\n"
                "     --bind-ro=SOURCE[:TARGET]\n"
                "                           Mount a file or directory, but read-only\n"
-               "     --extra-drive=PATH[:FORMAT]\n"
+               "     --extra-drive=[FORMAT:]PATH\n"
                "                           Adds an additional disk to the virtual machine\n"
-               "                           (format: raw, qcow2; default: raw)\n"
+               "                           (FORMAT: raw, qcow2; default: raw)\n"
                "     --bind-user=NAME       Bind user from host to virtual machine\n"
                "     --bind-user-shell=BOOL|PATH\n"
                "                            Configure the shell to use for --bind-user= users\n"
@@ -559,23 +559,26 @@ static int parse_argv(int argc, char *argv[]) {
                         break;
 
                 case ARG_EXTRA_DRIVE: {
-                        _cleanup_free_ char *buf = NULL, *drive_path = NULL;
                         ImageFormat format = IMAGE_FORMAT_RAW;
+                        const char *dp = optarg;
 
-                        const char *colon = strrchr(optarg, ':');
+                        const char *colon = strchr(dp, ':');
                         if (colon) {
-                                ImageFormat f = image_format_from_string(colon + 1);
+                                _cleanup_free_ char *fs = strndup(optarg, colon - optarg);
+                                if (!fs)
+                                        return log_oom();
+
+                                ImageFormat f = image_format_from_string(fs);
                                 if (f < 0)
-                                        log_debug_errno(f, "Failed to parse image format '%s', assuming it is a part of path, ignoring: %m", colon + 1);
+                                        log_debug_errno(f, "Cannot parse '%s' as an image format, assuming it is a part of path, ignoring.", fs);
                                 else {
                                         format = f;
-                                        buf = strndup(optarg, colon - optarg);
-                                        if (!buf)
-                                                return log_oom();
+                                        dp = colon + 1;
                                 }
                         }
 
-                        r = parse_path_argument(buf ?: optarg, /* suppress_root= */ false, &drive_path);
+                        _cleanup_free_ char *drive_path = NULL;
+                        r = parse_path_argument(dp, /* suppress_root= */ false, &drive_path);
                         if (r < 0)
                                 return r;