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@xxxxxxxxxx> --- 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