On Mon, Jun 23, 2025 at 21:59:18 +0200, Peter Krempa wrote:
> From: Akihiko Odaki <akihiko.od...@daynix.com>
> 
> usb-storage is a compound device that automatically creates a USB mass
> storage device and a SCSI device as its backend. Unfortunately it lacks
> some configuration options that are usually present with a SCSI device,
> and cannot represent CD-ROM in particular.
> 
> Replace usb-storage with usb-bot, which can be combined with a manually
> created SCSI device. libvirt will configure the SCSI device in a way
> identical with how QEMU does for usb-storage except that now it respects
> a configuration option to represent CD-ROM.
> 
> Resolves: https://gitlab.com/libvirt/libvirt/-/issues/368
> Signed-off-by: Akihiko Odaki <akihiko.od...@daynix.com>
> Signed-off-by: Peter Krempa <pkre...@redhat.com>
> ---
>  src/qemu/qemu_alias.c                         | 20 ++++-
>  src/qemu/qemu_capabilities.c                  |  3 +-
>  src/qemu/qemu_command.c                       | 86 ++++++++++++++++---
>  src/qemu/qemu_command.h                       |  5 ++
>  src/qemu/qemu_hotplug.c                       | 18 ++++
>  src/qemu/qemu_validate.c                      | 38 ++++++--
>  tests/qemuhotplugtest.c                       |  4 +-
>  ...om-usb-empty.x86_64-latest.abi-update.args |  3 +-
>  .../disk-usb-device-model.x86_64-latest.args  |  6 +-
>  ...k-usb-device.x86_64-latest.abi-update.args | 12 ++-
>  10 files changed, 167 insertions(+), 28 deletions(-)
...
> diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
> index e1ed8181e3..4f6a3d3414 100644
> --- a/src/qemu/qemu_hotplug.c
> +++ b/src/qemu/qemu_hotplug.c
...
> @@ -811,6 +820,12 @@ qemuDomainAttachDiskGeneric(virDomainObj *vm,
>          }
>      }
> 
> +    if (rc == 0) {
> +        if (disk->bus == VIR_DOMAIN_DISK_BUS_USB &&
> +            disk->model == VIR_DOMAIN_DISK_MODEL_USB_BOT)
> +            rc = qemuMonitorSetUSBDiskAttached(priv->mon, disk->info.alias);
> +    }

Why not just

    if (rc == 0 &&
        disk->bus == ... &&
        disk->model == ...)

> +
>      qemuDomainObjExitMonitor(vm);
> 
>      if (rc < 0)
> @@ -822,6 +837,9 @@ qemuDomainAttachDiskGeneric(virDomainObj *vm,
>      if (qemuDomainObjEnterMonitorAsync(vm, asyncJob) < 0)
>          return -1;
> 
> +    if (busAdded)
> +        ignore_value(qemuMonitorDelDevice(priv->mon, disk->info.alias));
> +
>      if (extensionDeviceAttached)
>          ignore_value(qemuDomainDetachExtensionDevice(priv->mon, 
> &disk->info));
> 
> diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
> index 7e0e4db516..4b8d4fc692 100644
> --- a/src/qemu/qemu_validate.c
> +++ b/src/qemu/qemu_validate.c
> @@ -3183,16 +3183,40 @@ qemuValidateDomainDeviceDefDiskFrontend(const 
> virDomainDiskDef *disk,
>          break;
> 
>      case VIR_DOMAIN_DISK_BUS_USB:
> -        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_USB_STORAGE)) {
> -            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
> -                           _("This QEMU doesn't support '-device 
> usb-storage'"));
> +        switch (disk->model) {
> +        case VIR_DOMAIN_DISK_MODEL_DEFAULT:
> +            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> +                           _("USB disk model was not selected by selection 
> code"));

This should only be possible if neither usb-storage nor usb-bot is
supported by QEMU, shouldn't it? In that case, shouldn't the selection
code itself report the error and actually be explicit about the failure?

>              return -1;
> -        }
> 
> -        if (disk->model == VIR_DOMAIN_DISK_MODEL_USB_STORAGE &&
> -            virStorageSourceIsEmpty(disk->src)) {
> +        case VIR_DOMAIN_DISK_MODEL_USB_STORAGE:
> +            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_USB_STORAGE)) {
> +                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
> +                               _("This QEMU doesn't support '-device 
> usb-storage'"));
> +                return -1;
> +            }
> +
> +            if (virStorageSourceIsEmpty(disk->src)) {
> +                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
> +                               _("'usb' disk must not be empty"));
> +                return -1;
> +            }
> +            break;
> +
> +        case VIR_DOMAIN_DISK_MODEL_USB_BOT:
> +            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_USB_BOT)) {
> +                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
> +                               _("This QEMU doesn't support '-device 
> usb-bot'"));
> +                return -1;
> +            }
> +            break;
> +
> +        case VIR_DOMAIN_DISK_MODEL_VIRTIO_TRANSITIONAL:
> +        case VIR_DOMAIN_DISK_MODEL_VIRTIO:
> +        case VIR_DOMAIN_DISK_MODEL_VIRTIO_NON_TRANSITIONAL:
> +        case VIR_DOMAIN_DISK_MODEL_LAST:
>              virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
> -                           _("'usb' disk must not be empty"));
> +                           _("USB disk supports only models: 'usb-storage', 
> 'usb-bot''"));

s/''/'/
And the error message looks weird to me, how about
s/models/the following models/ ?

>              return -1;
>          }
>
...

Reviewed-by: Jiri Denemark <jdene...@redhat.com>

Reply via email to