On 11/11/18 10:59 PM, Han Han wrote: > https://bugzilla.redhat.com/show_bug.cgi?id=1375423 > > Signed-off-by: Han Han <hhan@xxxxxxxxxx> > --- > src/qemu/qemu_driver.c | 5 ++- > src/qemu/qemu_hotplug.c | 81 ++++++++++++++++++++++++++++++++++++++++- > src/qemu/qemu_hotplug.h | 4 ++ > 3 files changed, 88 insertions(+), 2 deletions(-) > > diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c > index 774f6ac8b9..2813a00050 100644 > --- a/src/qemu/qemu_driver.c > +++ b/src/qemu/qemu_driver.c > @@ -7822,11 +7822,14 @@ qemuDomainDetachDeviceLive(virDomainObjPtr vm, > ret = qemuDomainDetachVsockDevice(vm, dev->data.vsock, async); > break; > > + case VIR_DOMAIN_DEVICE_HUB: > + ret = qemuDomainDetachHubDevice(vm, dev->data.hub, async); > + break; > + > case VIR_DOMAIN_DEVICE_FS: > case VIR_DOMAIN_DEVICE_SOUND: > case VIR_DOMAIN_DEVICE_VIDEO: > case VIR_DOMAIN_DEVICE_GRAPHICS: > - case VIR_DOMAIN_DEVICE_HUB: > case VIR_DOMAIN_DEVICE_SMARTCARD: > case VIR_DOMAIN_DEVICE_MEMBALLOON: > case VIR_DOMAIN_DEVICE_NVRAM: > diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c > index ca73456260..124703b7b2 100644 > --- a/src/qemu/qemu_hotplug.c > +++ b/src/qemu/qemu_hotplug.c > @@ -4965,6 +4965,32 @@ qemuDomainRemoveRedirdevDevice(virQEMUDriverPtr driver, > } > > > +static int > +qemuDomainRemoveHubDevice(virDomainObjPtr vm, > + virDomainHubDefPtr dev) > +{ > + qemuDomainObjPrivatePtr priv = vm->privateData; > + virQEMUDriverPtr driver = priv->driver; > + virObjectEventPtr event = NULL; > + size_t i; > + > + VIR_DEBUG("Removing hub device %s from domain %p %s", > + dev->info.alias, vm, vm->def->name); > + > + event = virDomainEventDeviceRemovedNewFromObj(vm, dev->info.alias); > + virObjectEventStateQueue(driver->domainEventState, event); > + for (i = 0; i < vm->def->nhubs; i++) { > + if (vm->def->hubs[i] == dev) > + break; > + } > + qemuDomainReleaseDeviceAddress(vm, &dev->info, NULL); > + > + virDomainHubDefFree(vm->def->hubs[i]); > + VIR_DELETE_ELEMENT(vm->def->hubs, i, vm->def->nhubs); > + return 0; > +} > + > + > int > qemuDomainRemoveDevice(virQEMUDriverPtr driver, > virDomainObjPtr vm, > @@ -5016,13 +5042,16 @@ qemuDomainRemoveDevice(virQEMUDriverPtr driver, > ret = qemuDomainRemoveVsockDevice(vm, dev->data.vsock); > break; > > + case VIR_DOMAIN_DEVICE_HUB: > + ret = qemuDomainRemoveHubDevice(vm, dev->data.hub); > + break; > + > case VIR_DOMAIN_DEVICE_NONE: > case VIR_DOMAIN_DEVICE_LEASE: > case VIR_DOMAIN_DEVICE_FS: > case VIR_DOMAIN_DEVICE_SOUND: > case VIR_DOMAIN_DEVICE_VIDEO: > case VIR_DOMAIN_DEVICE_GRAPHICS: > - case VIR_DOMAIN_DEVICE_HUB: > case VIR_DOMAIN_DEVICE_SMARTCARD: > case VIR_DOMAIN_DEVICE_MEMBALLOON: > case VIR_DOMAIN_DEVICE_NVRAM: > @@ -7019,3 +7048,53 @@ qemuDomainDetachVsockDevice(virDomainObjPtr vm, > qemuDomainResetDeviceRemoval(vm); > return ret; > } > + > + > +int > +qemuDomainDetachHubDevice(virDomainObjPtr vm, > + virDomainHubDefPtr def, > + bool async) > +{ > + qemuDomainObjPrivatePtr priv = vm->privateData; > + virQEMUDriverPtr driver = priv->driver; > + virDomainHubDefPtr detach; > + int ret = -1; > + int idx; > + > + if ((idx = virDomainHubDefFind(vm->def, def)) < 0) { > + virReportError(VIR_ERR_OPERATION_FAILED, "%s", > + _("matching hub device not found")); > + return -1; > + } > + > + detach = vm->def->hubs[idx]; > + if (qemuDomainHubIsBusy(vm, detach)) { > + virReportError(VIR_ERR_OPERATION_FAILED, "%s", > + _("device cannot be detached: device is busy")); > + goto cleanup; > + } This is where either the virDomainUSBDeviceDefForeach logic would need to be called in order to determine whether some other device was attached to this hub or some mechanism to get/search usbaddrs for this hub and determine if its "targetHub->portmap" was (virBitmapIsAllClear). More or less the antecedent to virDomainUSBAddressSetAddHub and potentially virDomainUSBAddressSetAddController. John > + > + if (!async) > + qemuDomainMarkDeviceForRemoval(vm, &detach->info); > + > + qemuDomainObjEnterMonitor(driver, vm); > + if (qemuMonitorDelDevice(priv->mon, detach->info.alias)) { > + ignore_value(qemuDomainObjExitMonitor(driver, vm)); > + goto cleanup; > + } > + > + if (qemuDomainObjExitMonitor(driver, vm) < 0) > + goto cleanup; > + > + if (async) { > + ret = 0; > + } else { > + if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1) > + ret = qemuDomainRemoveHubDevice(vm, detach); > + } > + > + cleanup: > + if (!async) > + qemuDomainResetDeviceRemoval(vm); > + return ret; > +} > diff --git a/src/qemu/qemu_hotplug.h b/src/qemu/qemu_hotplug.h > index 19b8950254..5c860c26ac 100644 > --- a/src/qemu/qemu_hotplug.h > +++ b/src/qemu/qemu_hotplug.h > @@ -204,4 +204,8 @@ int qemuDomainDetachInputDevice(virDomainObjPtr vm, > int qemuDomainDetachVsockDevice(virDomainObjPtr vm, > virDomainVsockDefPtr dev, > bool async); > + > +int qemuDomainDetachHubDevice(virDomainObjPtr vm, > + virDomainHubDefPtr def, > + bool async); > #endif /* __QEMU_HOTPLUG_H__ */ > -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list