[PATCH 1/1] QEMU: support USB cdrom devices

Jan-Marek Glogowski glogow at fbihome.de
Sun Sep 6 14:36:15 UTC 2020


If a USB cdrom is configured, the media type is silently ignored,
when generating the QEMU command, so libvirt actually generates
USB disks. The main problem is, that -blockdev mechanism relies
on the device type to handle the media type, like ide-cd and
ide-hd. But there is just usb-storage.

As a result the Windows 10 Arm64 installer won't find the virtio
ISO or even its own install media. You can actually turn them into
USB sticks, by setting them removable, so they show up in the
installer, but then it doesn't expect joliet or UDF filesystems,
so can't access these either.

So this generates the old driver+device commandline arguments in
the case of USB cdrom devices to make the installer happy.

Signed-off-by: Jan-Marek Glogowski <glogow at fbihome.de>
---
 src/qemu/qemu_command.c                       | 21 ++++++++++++++++++-
 src/qemu/qemu_command.h                       |  1 +
 src/qemu/qemu_domain.c                        |  2 +-
 .../disk-cdrom-bus-other.x86_64-latest.args   | 12 +++++------
 4 files changed, 28 insertions(+), 8 deletions(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index bd98b0a97c..f98af612de 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -1121,6 +1121,22 @@ qemuDiskBusIsSD(int bus)
 }
 
 
+/**
+ * qemuDiskIsUSBCD
+ * @disk: the disk
+ *
+ * Returns true, if the disk is an USB cdrom, which can't be currently
+ * represented by using -blockdev entries (other frontends have extra
+ * '-hd' and '-cd' devices to distinguish the media).
+ */
+bool
+qemuDiskIsUSBCD(virDomainDiskDefPtr disk)
+{
+    return ((virDomainDiskBus)disk->bus) == VIR_DOMAIN_DISK_BUS_USB
+           && disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM;
+}
+
+
 /**
  * qemuDiskSourceNeedsProps:
  * @src: disk source
@@ -1425,6 +1441,9 @@ qemuBuildDriveStr(virDomainDiskDefPtr disk,
     if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_STORAGE_WERROR))
         qemuBuildDiskFrontendAttributeErrorPolicy(disk, &opt);
 
+    if (qemuDiskIsUSBCD(disk))
+        virBufferAddLit(&opt, ",media=cdrom");
+
     if (disk->src->readonly)
         virBufferAddLit(&opt, ",readonly=on");
 
@@ -2075,7 +2094,7 @@ qemuBuildDiskSourceCommandLine(virCommandPtr cmd,
     size_t i;
 
     if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_BLOCKDEV) &&
-        !qemuDiskBusIsSD(disk->bus)) {
+        !qemuDiskBusIsSD(disk->bus) && !qemuDiskIsUSBCD(disk)) {
         if (virStorageSourceIsEmpty(disk->src))
             return 0;
 
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
index 89d99b111f..54093b388e 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -110,6 +110,7 @@ char *qemuBuildNicDevStr(virDomainDefPtr def,
 
 char *qemuDeviceDriveHostAlias(virDomainDiskDefPtr disk);
 bool qemuDiskBusIsSD(int bus);
+bool qemuDiskIsUSBCD(virDomainDiskDefPtr disk);
 
 qemuBlockStorageSourceAttachDataPtr
 qemuBuildStorageSourceAttachPrepareDrive(virDomainDiskDefPtr disk,
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index b1884b6c84..27d8bd6cc2 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -7282,7 +7282,7 @@ qemuDomainDiskGetBackendAlias(virDomainDiskDefPtr disk,
     *backendAlias = NULL;
 
     if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_BLOCKDEV) ||
-        qemuDiskBusIsSD(disk->bus)) {
+        qemuDiskBusIsSD(disk->bus) || qemuDiskIsUSBCD(disk)) {
         if (!(*backendAlias = qemuAliasDiskDriveFromDisk(disk)))
             return -1;
 
diff --git a/tests/qemuxml2argvdata/disk-cdrom-bus-other.x86_64-latest.args b/tests/qemuxml2argvdata/disk-cdrom-bus-other.x86_64-latest.args
index be091f150f..64e6fe1f42 100644
--- a/tests/qemuxml2argvdata/disk-cdrom-bus-other.x86_64-latest.args
+++ b/tests/qemuxml2argvdata/disk-cdrom-bus-other.x86_64-latest.args
@@ -28,13 +28,13 @@ file=/tmp/lib/domain--1-QEMUGuest1/master-key.aes \
 -no-acpi \
 -boot strict=on \
 -device piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 \
--blockdev '{"driver":"file","filename":"/root/boot.iso",\
-"node-name":"libvirt-2-storage","auto-read-only":true,"discard":"unmap"}' \
--blockdev '{"node-name":"libvirt-2-format","read-only":true,"driver":"raw",\
-"file":"libvirt-2-storage"}' \
--device usb-storage,bus=usb.0,port=1,drive=libvirt-2-format,id=usb-disk0,\
+-drive file=/root/boot.iso,format=raw,if=none,id=drive-usb-disk0,media=cdrom,\
+readonly=on \
+-device usb-storage,bus=usb.0,port=1,drive=drive-usb-disk0,id=usb-disk0,\
+removable=off \
+-drive if=none,id=drive-usb-disk1,media=cdrom,readonly=on \
+-device usb-storage,bus=usb.0,port=2,drive=drive-usb-disk1,id=usb-disk1,\
 removable=off \
--device usb-storage,bus=usb.0,port=2,id=usb-disk1,removable=off \
 -sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,\
 resourcecontrol=deny \
 -msg timestamp=on
-- 
2.20.1




More information about the libvir-list mailing list