diff --git a/src/qemu/qemu_hostdev.c b/src/qemu/qemu_hostdev.c index d4d746162c2ae27c142a9fdca8dbbdf038823190..a8890ebfa7cd7b54c0f7f4d018d97ab94e223e2a 100644 --- a/src/qemu/qemu_hostdev.c +++ b/src/qemu/qemu_hostdev.c @@ -755,6 +755,63 @@ 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); + usbFreeDevice(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); + 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); + } + } +} void qemuDomainReAttachHostDevices(struct qemud_driver *driver, virDomainDefPtr def) @@ -764,4 +821,7 @@ void qemuDomainReAttachHostDevices(struct qemud_driver *driver, qemuDomainReAttachHostdevDevices(driver, def->name, def->hostdevs, def->nhostdevs); + + qemuDomainReAttachHostUsbDevices(driver, def->name, def->hostdevs, + def->nhostdevs); }