On Mon, Jun 23, 2025 at 21:59:13 +0200, Peter Krempa wrote:
From: Peter Krempa <pkrempa(a)redhat.com>
Historically libvirt specified 'usb-storage' as driver for USB disks.
This though combined with '-blockdev' doesn't properly configure the
device to look like CDROM for <disk type='cdrom'>.
'usb-bot' acts like a controler and allows explicitly connecting a
-device to it.
In qemu the devices share implementation so they are effectively
identical and can be used interchangably. There is though a slight
difference in how the storage device itself (the SCSI bit) looks when
CDROM as they were not declared as cdrom before.
Looks like some words were dropped from the last sentence above.
As this is effectively a bugfix we'll be fixing the behaviour for
the
default configuration. The possibility to explicitly set the model is
added as a possibility for working around possible problems if they'd
appear.
Signed-off-by: Peter Krempa <pkrempa(a)redhat.com>
---
docs/formatdomain.rst | 23 +++++--
src/conf/domain_conf.c | 2 +
src/conf/domain_conf.h | 3 +
src/conf/schemas/domaincommon.rng | 2 +
src/qemu/qemu_domain_address.c | 2 +
.../disk-usb-device-model.x86_64-latest.args | 46 +++++++++++++
.../disk-usb-device-model.x86_64-latest.xml | 64 +++++++++++++++++++
.../qemuxmlconfdata/disk-usb-device-model.xml | 46 +++++++++++++
tests/qemuxmlconftest.c | 1 +
9 files changed, 185 insertions(+), 4 deletions(-)
create mode 100644 tests/qemuxmlconfdata/disk-usb-device-model.x86_64-latest.args
create mode 100644 tests/qemuxmlconfdata/disk-usb-device-model.x86_64-latest.xml
create mode 100644 tests/qemuxmlconfdata/disk-usb-device-model.xml
diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
index ae054a52b3..e4ebf061c7 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -2862,10 +2862,25 @@ paravirtualized driver is specified via the ``disk`` element.
``model``
Indicates the emulated device model of the disk. Typically this is
- indicated solely by the ``bus`` property but for ``bus`` "virtio" the
- model can be specified further with "virtio",
"virtio-transitional" or
- "virtio-non-transitional". See `virtio device models`_
- for more details. :since:`Since 5.2.0`
+ indicated solely by the ``bus`` property.
+
+ For ``bus`` "virtio" the model can be specified further with
"virtio",
+ "virtio-transitional" or "virtio-non-transitional". See
`virtio device
+ models`_ for more details. :since:`Since 5.2.0`
+
+ For ``bus`` "usb" the model can be specified further with
``usb-storage``
+ or ``usb-bot``. There is no difference between the two models for
+ ``<disk type='disk'``. However with ``usb-bot`` a device configured as
Missing > in the disk element.
+ ``<disk type='cdrom'>`` is properly exposed as a
cdrom device inside the
+ guest OS. Unfortunately this configuration is not ABI compatible and thus
+ it can't be interchanged.
This is not ABI compatible with usb-storage model, right? I suggest
being explicit about it.
+
+ The QEMU hypervisor driver will pick ``usb-bot`` for cold starts or
+ hotplug for cdrom devices to properly configure the devices. This is
+ not compatible for migration to older versions of libvirt and explicit
+ configuration needs to be used.
So are you saying starting an existing domain with usb cdrom after
upgrading libvirt will cause issues during migration to an older
libvirt? I don't think we can do this. We should rather pick usb-storage
(which is the case now as I understood from the description) unless
usb-bot is set explicitly in the XML.
+ :since:`Since 11.5.0`; relevant only for ``QEMU`` hypervisor.
+
``rawio``
Indicates whether the disk needs rawio capability. Valid settings are
"yes" or "no" (default is "no"). If any one disk in
a domain has
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 1a6c8afb1d..2882a7746b 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -1399,6 +1399,8 @@ VIR_ENUM_IMPL(virDomainDiskModel,
"virtio",
"virtio-transitional",
"virtio-non-transitional",
+ "usb-storage",
+ "usb-bot",
);
VIR_ENUM_IMPL(virDomainDiskMirrorState,
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 3d380073cf..73e8a2fb99 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -439,6 +439,9 @@ typedef enum {
VIR_DOMAIN_DISK_MODEL_VIRTIO_TRANSITIONAL,
VIR_DOMAIN_DISK_MODEL_VIRTIO_NON_TRANSITIONAL,
Extra empty line?
+ VIR_DOMAIN_DISK_MODEL_USB_STORAGE,
+ VIR_DOMAIN_DISK_MODEL_USB_BOT,
+
VIR_DOMAIN_DISK_MODEL_LAST
} virDomainDiskModel;
diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng
index b1fe51f519..a80005562a 100644
--- a/src/conf/schemas/domaincommon.rng
+++ b/src/conf/schemas/domaincommon.rng
@@ -1766,6 +1766,8 @@
<value>virtio</value>
<value>virtio-transitional</value>
<value>virtio-non-transitional</value>
+ <value>usb-storage</value>
+ <value>usb-bot</value>
</choice>
</attribute>
</optional>
diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c
index bb86cfa0c3..3a23f70d39 100644
--- a/src/qemu/qemu_domain_address.c
+++ b/src/qemu/qemu_domain_address.c
@@ -729,6 +729,8 @@ qemuDomainDeviceCalculatePCIConnectFlags(virDomainDeviceDef *dev,
case VIR_DOMAIN_DISK_MODEL_DEFAULT:
return virtioFlags;
case VIR_DOMAIN_DISK_MODEL_LAST:
+ case VIR_DOMAIN_DISK_MODEL_USB_STORAGE:
+ case VIR_DOMAIN_DISK_MODEL_USB_BOT:
break;
}
return 0;
diff --git a/tests/qemuxmlconfdata/disk-usb-device-model.x86_64-latest.args
b/tests/qemuxmlconfdata/disk-usb-device-model.x86_64-latest.args
new file mode 100644
index 0000000000..6d31319a49
--- /dev/null
+++ b/tests/qemuxmlconfdata/disk-usb-device-model.x86_64-latest.args
@@ -0,0 +1,46 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1 \
+USER=test \
+LOGNAME=test \
+XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.local/share \
+XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.cache \
+XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \
+/usr/bin/qemu-system-x86_64 \
+-name guest=QEMUGuest1,debug-threads=on \
+-S \
+-object
'{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}'
\
+-machine pc,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
+-accel tcg \
+-cpu qemu64 \
+-m size=219136k \
+-object
'{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}'
\
+-overcommit mem-lock=off \
+-smp 1,sockets=1,cores=1,threads=1 \
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
+-display none \
+-no-user-config \
+-nodefaults \
+-chardev socket,id=charmonitor,fd=1729,server=on,wait=off \
+-mon chardev=charmonitor,id=monitor,mode=control \
+-rtc base=utc \
+-no-shutdown \
+-boot strict=on \
+-device
'{"driver":"piix3-usb-uhci","id":"usb","bus":"pci.0","addr":"0x1.0x2"}'
\
+-device
'{"driver":"usb-hub","id":"hub0","bus":"usb.0","port":"1"}'
\
+-blockdev
'{"driver":"file","filename":"/tmp/img1","node-name":"libvirt-6-storage","read-only":false}'
\
+-device
'{"driver":"usb-storage","bus":"usb.0","port":"2","drive":"libvirt-6-storage","id":"usb-disk0","bootindex":1,"removable":false}'
\
+-blockdev
'{"driver":"file","filename":"/tmp/img2","node-name":"libvirt-5-storage","read-only":true}'
\
+-device
'{"driver":"usb-storage","bus":"usb.0","port":"1.1","drive":"libvirt-5-storage","id":"usb-disk1","removable":false}'
\
+-blockdev
'{"driver":"file","filename":"/tmp/img3","node-name":"libvirt-4-storage","read-only":false}'
\
+-device
'{"driver":"usb-storage","bus":"usb.0","port":"1.2","drive":"libvirt-4-storage","id":"usb-disk2","removable":false}'
\
+-blockdev
'{"driver":"file","filename":"/tmp/img4","node-name":"libvirt-3-storage","read-only":true}'
\
+-device
'{"driver":"usb-storage","bus":"usb.0","port":"1.3","drive":"libvirt-3-storage","id":"usb-disk3","removable":false}'
\
+-blockdev
'{"driver":"file","filename":"/tmp/img5","node-name":"libvirt-2-storage","read-only":false}'
\
+-device
'{"driver":"usb-storage","bus":"usb.0","port":"1.4","drive":"libvirt-2-storage","id":"usb-disk4","removable":false}'
\
+-blockdev
'{"driver":"file","filename":"/tmp/img6","node-name":"libvirt-1-storage","read-only":true}'
\
+-device
'{"driver":"usb-storage","bus":"usb.0","port":"1.5","drive":"libvirt-1-storage","id":"usb-disk5","removable":false}'
\
Well, this is strange. The XML uses both usb-storage and usb-bot, but
only usb-storage is present in *.args. This kind of makes sense since
the code for handling model is not wired up yet, but having the tests in
a commit that describes the new models and how libvirt handles them is
confusing.
Jirka