]> xenbits.xensource.com Git - libvirt.git/commitdiff
qemu: Add support for hot unplugging redirdev device
authorChen Hanxiao <chenhanxiao@gmail.com>
Fri, 5 Jan 2018 02:47:47 +0000 (10:47 +0800)
committerJohn Ferlan <jferlan@redhat.com>
Mon, 8 Jan 2018 16:49:26 +0000 (11:49 -0500)
Commit id '162efa1a' added support hotplug a redirdev, but
did not add the hot unplug. This patch will add that support
to allow usage of the detach-device --live on the device.

Reviewed-by: John Ferlan <jferlan@redhat.com>
Signed-off-by: Chen Hanxiao <chenhanxiao@gmail.com>
src/qemu/qemu_driver.c
src/qemu/qemu_hotplug.c
src/qemu/qemu_hotplug.h

index 4eb8521c47611e97614aa2ebe9a073834bb7eff5..a203c9297ab6750cb374a4aeefda36c3688dd7dd 100644 (file)
@@ -7799,6 +7799,9 @@ qemuDomainDetachDeviceLive(virDomainObjPtr vm,
     case VIR_DOMAIN_DEVICE_INPUT:
         ret = qemuDomainDetachInputDevice(vm, dev->data.input);
         break;
+    case VIR_DOMAIN_DEVICE_REDIRDEV:
+        ret = qemuDomainDetachRedirdevDevice(driver, vm, dev->data.redirdev);
+        break;
 
     case VIR_DOMAIN_DEVICE_FS:
     case VIR_DOMAIN_DEVICE_SOUND:
@@ -7808,7 +7811,6 @@ qemuDomainDetachDeviceLive(virDomainObjPtr vm,
     case VIR_DOMAIN_DEVICE_SMARTCARD:
     case VIR_DOMAIN_DEVICE_MEMBALLOON:
     case VIR_DOMAIN_DEVICE_NVRAM:
-    case VIR_DOMAIN_DEVICE_REDIRDEV:
     case VIR_DOMAIN_DEVICE_NONE:
     case VIR_DOMAIN_DEVICE_TPM:
     case VIR_DOMAIN_DEVICE_PANIC:
index 385be80f2f4cddb2fe29ab5d69e7405a312b53ce..6dc16a1054aff68d8a9c61b28b435f0ed44d500e 100644 (file)
@@ -4399,6 +4399,53 @@ qemuDomainRemoveInputDevice(virDomainObjPtr vm,
 }
 
 
+static int
+qemuDomainRemoveRedirdevDevice(virQEMUDriverPtr driver,
+                               virDomainObjPtr vm,
+                               virDomainRedirdevDefPtr dev)
+{
+    qemuDomainObjPrivatePtr priv = vm->privateData;
+    virObjectEventPtr event;
+    char *charAlias = NULL;
+    ssize_t idx;
+    int ret = -1;
+
+    VIR_DEBUG("Removing redirdev device %s from domain %p %s",
+              dev->info.alias, vm, vm->def->name);
+
+    if (!(charAlias = qemuAliasChardevFromDevAlias(dev->info.alias)))
+        goto cleanup;
+
+    qemuDomainObjEnterMonitor(driver, vm);
+    /* DeviceDel from Detach may remove chardev,
+     * so we cannot rely on return status to delete TLS chardevs.
+     */
+    ignore_value(qemuMonitorDetachCharDev(priv->mon, charAlias));
+
+    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+        goto cleanup;
+
+    if (qemuDomainDelChardevTLSObjects(driver, vm, dev->source, charAlias) < 0)
+        goto cleanup;
+
+    virDomainAuditRedirdev(vm, dev, "detach", true);
+
+    event = virDomainEventDeviceRemovedNewFromObj(vm, dev->info.alias);
+    qemuDomainEventQueue(driver, event);
+
+    if ((idx = virDomainRedirdevDefFind(vm->def, dev)) >= 0)
+        virDomainRedirdevDefRemove(vm->def, idx);
+    qemuDomainReleaseDeviceAddress(vm, &dev->info, NULL);
+    virDomainRedirdevDefFree(dev);
+
+    ret = 0;
+
+ cleanup:
+    VIR_FREE(charAlias);
+    return ret;
+}
+
+
 int
 qemuDomainRemoveDevice(virQEMUDriverPtr driver,
                        virDomainObjPtr vm,
@@ -4438,6 +4485,10 @@ qemuDomainRemoveDevice(virQEMUDriverPtr driver,
         ret = qemuDomainRemoveInputDevice(vm, dev->data.input);
         break;
 
+    case VIR_DOMAIN_DEVICE_REDIRDEV:
+        ret = qemuDomainRemoveRedirdevDevice(driver, vm, dev->data.redirdev);
+        break;
+
     case VIR_DOMAIN_DEVICE_NONE:
     case VIR_DOMAIN_DEVICE_LEASE:
     case VIR_DOMAIN_DEVICE_FS:
@@ -4446,7 +4497,6 @@ qemuDomainRemoveDevice(virQEMUDriverPtr driver,
     case VIR_DOMAIN_DEVICE_WATCHDOG:
     case VIR_DOMAIN_DEVICE_GRAPHICS:
     case VIR_DOMAIN_DEVICE_HUB:
-    case VIR_DOMAIN_DEVICE_REDIRDEV:
     case VIR_DOMAIN_DEVICE_SMARTCARD:
     case VIR_DOMAIN_DEVICE_MEMBALLOON:
     case VIR_DOMAIN_DEVICE_NVRAM:
@@ -5139,6 +5189,49 @@ qemuDomainDetachWatchdog(virQEMUDriverPtr driver,
 }
 
 
+int
+qemuDomainDetachRedirdevDevice(virQEMUDriverPtr driver,
+                               virDomainObjPtr vm,
+                               virDomainRedirdevDefPtr dev)
+{
+    int ret = -1;
+    qemuDomainObjPrivatePtr priv = vm->privateData;
+    virDomainRedirdevDefPtr tmpRedirdevDef;
+    ssize_t idx;
+
+    if ((idx = virDomainRedirdevDefFind(vm->def, dev)) < 0) {
+        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+                       _("no matching redirdev was not found"));
+        return -1;
+    }
+
+    tmpRedirdevDef = vm->def->redirdevs[idx];
+
+    if (!tmpRedirdevDef->info.alias) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("alias not set for redirdev device"));
+        return -1;
+    }
+
+    qemuDomainMarkDeviceForRemoval(vm, &tmpRedirdevDef->info);
+
+    qemuDomainObjEnterMonitor(driver, vm);
+    if (qemuMonitorDelDevice(priv->mon, tmpRedirdevDef->info.alias) < 0) {
+        ignore_value(qemuDomainObjExitMonitor(driver, vm));
+        goto cleanup;
+    }
+    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+        goto cleanup;
+
+    if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
+        ret = qemuDomainRemoveRedirdevDevice(driver, vm, tmpRedirdevDef);
+
+ cleanup:
+    qemuDomainResetDeviceRemoval(vm);
+    return ret;
+}
+
+
 int
 qemuDomainDetachNetDevice(virQEMUDriverPtr driver,
                           virDomainObjPtr vm,
index 3e0d618e0a38cdd04787ef8e772b1f8c7f2cc623..9a0c057f197829a74adf92590134c6aa414335ef 100644 (file)
@@ -126,6 +126,10 @@ int qemuDomainDetachWatchdog(virQEMUDriverPtr driver,
                              virDomainObjPtr vm,
                              virDomainWatchdogDefPtr watchdog);
 
+int qemuDomainDetachRedirdevDevice(virQEMUDriverPtr driver,
+                                   virDomainObjPtr vm,
+                                   virDomainRedirdevDefPtr dev);
+
 int qemuDomainAttachInputDevice(virQEMUDriverPtr driver,
                                 virDomainObjPtr vm,
                                 virDomainInputDefPtr input);