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. --- 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); + 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); + 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); + } +} 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); } -- 1.7.8.5 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list