On 11/11/18 10:59 PM, Han Han wrote:
> https://bugzilla.redhat.com/show_bug.cgi?id=1375423
>
> Signed-off-by: Han Han <h...@redhat.com>
> ---
> 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@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list