[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