On Mon, Jun 23, 2025 at 21:59:13 +0200, Peter Krempa wrote:
> From: Peter Krempa <pkre...@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 <pkre...@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

Reply via email to