[libvirt] [PATCH 2/3] qemu: Delete USB devices used by domain on stop

Jiri Denemark jdenemar at redhat.com
Wed Apr 4 12:25:55 UTC 2012


On Mon, Mar 26, 2012 at 17:40:00 +0200, Michal Privoznik wrote:
> To prevent assigning one USB device to two domains,
> we keep a list of assigned USB devices. On domain
> startup - qemuProcessStart() - we insert devices
> used by domain into the list but remove them only
> on detach-device. Devices are, however, released
> on qemuProcessReconnect() as well.
        ^^
     qemuProcessStop()
> ---
>  src/qemu/qemu_hostdev.c |   61 +++++++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 61 insertions(+), 0 deletions(-)
> 
> diff --git a/src/qemu/qemu_hostdev.c b/src/qemu/qemu_hostdev.c
> index d4d7461..6ce2421 100644
> --- a/src/qemu/qemu_hostdev.c
> +++ b/src/qemu/qemu_hostdev.c
> @@ -755,6 +755,64 @@ void qemuDomainReAttachHostdevDevices(struct qemud_driver *driver,
>      pciDeviceListFree(pcidevs);
>  }
>  
> +static void
> +qemuDomainReAttachHostUsbDevices(struct qemud_driver *driver,
> +                                 const char *name,
> +                                 virDomainHostdevDefPtr *hostdevs,
> +                                 int nhostdevs)
> +{
> +    int i;
> +
> +    for (i = 0; i < nhostdevs; i++) {
> +        virDomainHostdevDefPtr hostdev = hostdevs[i];
> +        usbDevice *usb, *tmp;
> +        const char *used_by = NULL;
> +
> +        if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
> +            continue;
> +        if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB)
> +            continue;
> +
> +        usb = usbGetDevice(hostdev->source.subsys.u.usb.bus,
> +                           hostdev->source.subsys.u.usb.device);
> +
> +        if (!usb) {
> +            VIR_WARN("Unable to reattach USB device %03d.%03d on domain %s",
> +                     hostdev->source.subsys.u.usb.bus,
> +                     hostdev->source.subsys.u.usb.device,
> +                     name);
> +            continue;
> +        }
> +
> +        /* Delete only those USB devices which belongs
> +         * to domain @name because qemuProcessStart() might
> +         * have failed because USB device is already taken.
> +         * Therefore we want to steal only those devices from
> +         * the list which were taken by @name */
> +
> +        tmp = usbDeviceListFind(driver->activeUsbHostdevs, usb);

This is the last usage of usb so I think it's better to call
usbFreeDevice(usb); here to avoid having to call it several times later.

> +        if (!tmp) {
> +            VIR_WARN("Unable to find device %03d.%03d "
> +                     "in list of active USB devices",
> +                     hostdev->source.subsys.u.usb.bus,
> +                     hostdev->source.subsys.u.usb.device);
> +            usbFreeDevice(usb);
Now, the above line may be removed.
> +            continue;
> +        }
> +
> +        used_by = usbDeviceGetUsedBy(tmp);
> +        if (STREQ_NULLABLE(used_by, name)) {
> +            VIR_DEBUG("Removing %03d.%03d dom=%s from activeUsbHostdevs",
> +                      hostdev->source.subsys.u.usb.bus,
> +                      hostdev->source.subsys.u.usb.device,
> +                      name);
> +
> +            usbDeviceListDel(driver->activeUsbHostdevs, tmp);
> +        }
> +
> +        usbFreeDevice(usb);
And this one as well.
> +    }
> +}
>  
>  void qemuDomainReAttachHostDevices(struct qemud_driver *driver,
>                                     virDomainDefPtr def)
> @@ -764,4 +822,7 @@ void qemuDomainReAttachHostDevices(struct qemud_driver *driver,
>  
>      qemuDomainReAttachHostdevDevices(driver, def->name, def->hostdevs,
>                                       def->nhostdevs);
> +
> +    qemuDomainReAttachHostUsbDevices(driver, def->name, def->hostdevs,
> +                                     def->nhostdevs);
>  }

ACK

Jirka




More information about the libvir-list mailing list