[libvirt] [PATCH v3 09/10] qemu: Implement usb hub device hotunplug

Han Han hhan at redhat.com
Mon Nov 12 03:59:24 UTC 2018


https://bugzilla.redhat.com/show_bug.cgi?id=1375423

Signed-off-by: Han Han <hhan at 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




More information about the libvir-list mailing list