]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
vmspawn: add disk type selection for root and extra drives (#41301)
authorLennart Poettering <lennart@amutable.com>
Tue, 24 Mar 2026 20:48:00 +0000 (21:48 +0100)
committerGitHub <noreply@github.com>
Tue, 24 Mar 2026 20:48:00 +0000 (21:48 +0100)
  vmspawn previously hardcoded virtio-blk for all drives. This adds
  --image-disk-type= to select the root disk type (virtio-blk,
  virtio-scsi, or nvme) and allows per-drive overrides via a
  colon-separated prefix on --extra-drive=. The format and disk type
  prefixes can appear in any order since their value sets don't overlap.

  For virtio-scsi, a single shared controller is created with drives
  attached as scsi-hd devices. For nvme, each drive gets its own
controller. Both have serial number length limits (30 and 20 characters
  respectively), so long filenames are replaced with a truncated SHA-256
  hex digest.

1  2 
man/systemd-vmspawn.xml
shell-completion/bash/systemd-vmspawn
src/vmspawn/vmspawn-settings.c
src/vmspawn/vmspawn-settings.h
src/vmspawn/vmspawn.c

Simple merge
index 08e92e0a4b503d80583851e4b2fc500ef09b0f43,718cb300ce4043e2de5ea060057c5135594a0516..0e2e46a84c6b7f2b4989a2206001a35a566be926
@@@ -56,9 -57,11 +57,11 @@@ _systemd_vmspawn() 
      elif __contains_word "$prev" ${OPTS[SSH_KEY]}; then
          comps='dsa ecdsa ecdsa-sk ed25519 ed25519-sk rsa'
      elif __contains_word "$prev" ${OPTS[CONSOLE]}; then
 -        comps='interactive native gui'
 +        comps='interactive native gui read-only headless'
      elif __contains_word "$prev" ${OPTS[IMAGE_FORMAT]}; then
          comps='raw qcow2'
+     elif __contains_word "$prev" ${OPTS[IMAGE_DISK_TYPE]}; then
+         comps='virtio-blk virtio-scsi nvme'
      elif __contains_word "$prev" ${OPTS[ARG]}; then
          comps=''
      else
Simple merge
Simple merge
index d41a9203891a8c8c27edf330edfbed79b993a38d,72aa39e18a4e5e3a400b9f9f6f6d142573ec0878..91da71d669832f5bcaf9ddae893b96faf70cdb0e
@@@ -2644,11 -2730,37 +2737,37 @@@ static int run_virtual_machine(int kvm_
                  if (strv_extend(&cmdline, "-device") < 0)
                          return log_oom();
  
-                 if (strv_extendf(&cmdline, "virtio-blk-pci,drive=vmspawn_extra_%zu,serial=%s", i++, escaped_drive_fn) < 0)
-                         return log_oom();
+                 DiskType dt = drive->disk_type >= 0 ? drive->disk_type : arg_image_disk_type;
+                 switch (dt) {
+                 case DISK_TYPE_VIRTIO_BLK:
+                         if (strv_extendf(&cmdline, "virtio-blk-pci,drive=vmspawn_extra_%zu,serial=%s", i++, escaped_drive_fn) < 0)
+                                 return log_oom();
+                         break;
+                 case DISK_TYPE_VIRTIO_SCSI: {
+                         _cleanup_free_ char *serial = NULL;
+                         r = disk_serial(escaped_drive_fn, 30, &serial);
+                         if (r < 0)
+                                 return log_oom();
+                         if (strv_extendf(&cmdline, "scsi-hd,bus=vmspawn_scsi.0,drive=vmspawn_extra_%zu,serial=%s", i++, serial) < 0)
+                                 return log_oom();
+                         break;
+                 }
+                 case DISK_TYPE_NVME: {
+                         _cleanup_free_ char *serial = NULL;
+                         r = disk_serial(escaped_drive_fn, 20, &serial);
+                         if (r < 0)
+                                 return log_oom();
+                         if (strv_extendf(&cmdline, "nvme,drive=vmspawn_extra_%zu,serial=%s", i++, serial) < 0)
+                                 return log_oom();
+                         break;
+                 }
+                 default:
+                         assert_not_reached();
+                 }
          }
  
 -        if (arg_console_mode != CONSOLE_GUI) {
 +        if (!IN_SET(arg_console_mode, CONSOLE_GUI, CONSOLE_HEADLESS)) {
                  r = strv_prepend(&arg_kernel_cmdline_extra, "console=hvc0");
                  if (r < 0)
                          return log_oom();