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