https://bugzilla.redhat.com/show_bug.cgi?id=1375423
Signed-off-by: Han Han <hhan(a)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;
+ }
+
+ 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__ */
--
2.19.1