[libvirt] [PATCH v2 10/12] qemu_hotplug: Allow asynchronous detach

Michal Privoznik mprivozn at redhat.com
Thu May 24 11:13:37 UTC 2018


The virDomainDetachDeviceAlias API is designed so that it only
sends detach request to qemu. It's user's responsibility to wait
for DEVICE_DELETED event, not libvirt's. Add @async flag to
qemuDomainDetach*Device() functions so that caller can chose if
detach is semi-synchronous (old virDomainDetachDeviceFlags()) or
fully asynchronous (new virDomainDetachDeviceFlags()).

Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
---
 src/qemu/qemu_driver.c  |  32 +++----
 src/qemu/qemu_hotplug.c | 231 ++++++++++++++++++++++++++++++++----------------
 src/qemu/qemu_hotplug.h |  33 ++++---
 tests/qemuhotplugtest.c |  13 +--
 4 files changed, 203 insertions(+), 106 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 2347e71cfb..81a9833b39 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -7726,14 +7726,15 @@ qemuDomainAttachDeviceLive(virDomainObjPtr vm,
 static int
 qemuDomainDetachDeviceControllerLive(virQEMUDriverPtr driver,
                                      virDomainObjPtr vm,
-                                     virDomainDeviceDefPtr dev)
+                                     virDomainDeviceDefPtr dev,
+                                     bool async)
 {
     virDomainControllerDefPtr cont = dev->data.controller;
     int ret = -1;
 
     switch (cont->type) {
     case VIR_DOMAIN_CONTROLLER_TYPE_SCSI:
-        ret = qemuDomainDetachControllerDevice(driver, vm, dev);
+        ret = qemuDomainDetachControllerDevice(driver, vm, dev, async);
         break;
     default :
         virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
@@ -7746,46 +7747,47 @@ qemuDomainDetachDeviceControllerLive(virQEMUDriverPtr driver,
 static int
 qemuDomainDetachDeviceLive(virDomainObjPtr vm,
                            virDomainDeviceDefPtr dev,
-                           virQEMUDriverPtr driver)
+                           virQEMUDriverPtr driver,
+                           bool async)
 {
     int ret = -1;
 
     switch ((virDomainDeviceType)dev->type) {
     case VIR_DOMAIN_DEVICE_DISK:
-        ret = qemuDomainDetachDeviceDiskLive(driver, vm, dev);
+        ret = qemuDomainDetachDeviceDiskLive(driver, vm, dev, async);
         break;
     case VIR_DOMAIN_DEVICE_CONTROLLER:
-        ret = qemuDomainDetachDeviceControllerLive(driver, vm, dev);
+        ret = qemuDomainDetachDeviceControllerLive(driver, vm, dev, async);
         break;
     case VIR_DOMAIN_DEVICE_LEASE:
         ret = qemuDomainDetachLease(driver, vm, dev->data.lease);
         break;
     case VIR_DOMAIN_DEVICE_NET:
-        ret = qemuDomainDetachNetDevice(driver, vm, dev);
+        ret = qemuDomainDetachNetDevice(driver, vm, dev, async);
         break;
     case VIR_DOMAIN_DEVICE_HOSTDEV:
-        ret = qemuDomainDetachHostDevice(driver, vm, dev);
+        ret = qemuDomainDetachHostDevice(driver, vm, dev, async);
         break;
     case VIR_DOMAIN_DEVICE_CHR:
-        ret = qemuDomainDetachChrDevice(driver, vm, dev->data.chr);
+        ret = qemuDomainDetachChrDevice(driver, vm, dev->data.chr, async);
         break;
     case VIR_DOMAIN_DEVICE_RNG:
-        ret = qemuDomainDetachRNGDevice(driver, vm, dev->data.rng);
+        ret = qemuDomainDetachRNGDevice(driver, vm, dev->data.rng, async);
         break;
     case VIR_DOMAIN_DEVICE_MEMORY:
-        ret = qemuDomainDetachMemoryDevice(driver, vm, dev->data.memory);
+        ret = qemuDomainDetachMemoryDevice(driver, vm, dev->data.memory, async);
         break;
     case VIR_DOMAIN_DEVICE_SHMEM:
-        ret = qemuDomainDetachShmemDevice(driver, vm, dev->data.shmem);
+        ret = qemuDomainDetachShmemDevice(driver, vm, dev->data.shmem, async);
         break;
     case VIR_DOMAIN_DEVICE_WATCHDOG:
-        ret = qemuDomainDetachWatchdog(driver, vm, dev->data.watchdog);
+        ret = qemuDomainDetachWatchdog(driver, vm, dev->data.watchdog, async);
         break;
     case VIR_DOMAIN_DEVICE_INPUT:
-        ret = qemuDomainDetachInputDevice(vm, dev->data.input);
+        ret = qemuDomainDetachInputDevice(vm, dev->data.input, async);
         break;
     case VIR_DOMAIN_DEVICE_REDIRDEV:
-        ret = qemuDomainDetachRedirdevDevice(driver, vm, dev->data.redirdev);
+        ret = qemuDomainDetachRedirdevDevice(driver, vm, dev->data.redirdev, async);
         break;
 
     case VIR_DOMAIN_DEVICE_FS:
@@ -8716,7 +8718,7 @@ qemuDomainDetachDeviceLiveAndConfig(virQEMUDriverPtr driver,
     }
 
     if (flags & VIR_DOMAIN_AFFECT_LIVE) {
-        if (qemuDomainDetachDeviceLive(vm, dev_copy, driver) < 0)
+        if (qemuDomainDetachDeviceLive(vm, dev_copy, driver, false) < 0)
             goto cleanup;
         /*
          * update domain status forcibly because the domain status may be
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index e84dc909b9..5b5c27b011 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -4740,7 +4740,8 @@ qemuDomainSignalDeviceRemoval(virDomainObjPtr vm,
 static int
 qemuDomainDetachVirtioDiskDevice(virQEMUDriverPtr driver,
                                  virDomainObjPtr vm,
-                                 virDomainDiskDefPtr detach)
+                                 virDomainDiskDefPtr detach,
+                                 bool async)
 {
     int ret = -1;
     qemuDomainObjPrivatePtr priv = vm->privateData;
@@ -4757,7 +4758,8 @@ qemuDomainDetachVirtioDiskDevice(virQEMUDriverPtr driver,
             goto cleanup;
     }
 
-    qemuDomainMarkDeviceForRemoval(vm, &detach->info);
+    if (!async)
+        qemuDomainMarkDeviceForRemoval(vm, &detach->info);
 
     qemuDomainObjEnterMonitor(driver, vm);
     if (qemuMonitorDelDevice(priv->mon, detach->info.alias) < 0) {
@@ -4769,18 +4771,24 @@ qemuDomainDetachVirtioDiskDevice(virQEMUDriverPtr driver,
     if (qemuDomainObjExitMonitor(driver, vm) < 0)
         goto cleanup;
 
-    if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
-        ret = qemuDomainRemoveDiskDevice(driver, vm, detach);
+    if (async) {
+        ret = 0;
+    } else {
+        if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
+            ret = qemuDomainRemoveDiskDevice(driver, vm, detach);
+    }
 
  cleanup:
-    qemuDomainResetDeviceRemoval(vm);
+    if (!async)
+        qemuDomainResetDeviceRemoval(vm);
     return ret;
 }
 
 static int
 qemuDomainDetachDiskDevice(virQEMUDriverPtr driver,
                            virDomainObjPtr vm,
-                           virDomainDiskDefPtr detach)
+                           virDomainDiskDefPtr detach,
+                           bool async)
 {
     int ret = -1;
     qemuDomainObjPrivatePtr priv = vm->privateData;
@@ -4788,7 +4796,8 @@ qemuDomainDetachDiskDevice(virQEMUDriverPtr driver,
     if (qemuDomainDiskBlockJobIsActive(detach))
         goto cleanup;
 
-    qemuDomainMarkDeviceForRemoval(vm, &detach->info);
+    if (!async)
+        qemuDomainMarkDeviceForRemoval(vm, &detach->info);
 
     qemuDomainObjEnterMonitor(driver, vm);
     if (qemuMonitorDelDevice(priv->mon, detach->info.alias) < 0) {
@@ -4800,11 +4809,16 @@ qemuDomainDetachDiskDevice(virQEMUDriverPtr driver,
     if (qemuDomainObjExitMonitor(driver, vm) < 0)
         goto cleanup;
 
-    if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
-        ret = qemuDomainRemoveDiskDevice(driver, vm, detach);
+    if (async) {
+        ret = 0;
+    } else {
+        if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
+            ret = qemuDomainRemoveDiskDevice(driver, vm, detach);
+    }
 
  cleanup:
-    qemuDomainResetDeviceRemoval(vm);
+    if (!async)
+        qemuDomainResetDeviceRemoval(vm);
     return ret;
 }
 
@@ -4824,7 +4838,8 @@ qemuFindDisk(virDomainDefPtr def, const char *dst)
 int
 qemuDomainDetachDeviceDiskLive(virQEMUDriverPtr driver,
                                virDomainObjPtr vm,
-                               virDomainDeviceDefPtr dev)
+                               virDomainDeviceDefPtr dev,
+                               bool async)
 {
     virDomainDiskDefPtr disk;
     int ret = -1;
@@ -4841,10 +4856,10 @@ qemuDomainDetachDeviceDiskLive(virQEMUDriverPtr driver,
     case VIR_DOMAIN_DISK_DEVICE_DISK:
     case VIR_DOMAIN_DISK_DEVICE_LUN:
         if (disk->bus == VIR_DOMAIN_DISK_BUS_VIRTIO)
-            ret = qemuDomainDetachVirtioDiskDevice(driver, vm, disk);
+            ret = qemuDomainDetachVirtioDiskDevice(driver, vm, disk, async);
         else if (disk->bus == VIR_DOMAIN_DISK_BUS_SCSI ||
                  disk->bus == VIR_DOMAIN_DISK_BUS_USB)
-            ret = qemuDomainDetachDiskDevice(driver, vm, disk);
+            ret = qemuDomainDetachDiskDevice(driver, vm, disk, async);
         else
             virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
                            _("This type of disk cannot be hot unplugged"));
@@ -4922,7 +4937,8 @@ static bool qemuDomainControllerIsBusy(virDomainObjPtr vm,
 
 int qemuDomainDetachControllerDevice(virQEMUDriverPtr driver,
                                      virDomainObjPtr vm,
-                                     virDomainDeviceDefPtr dev)
+                                     virDomainDeviceDefPtr dev,
+                                     bool async)
 {
     int idx, ret = -1;
     virDomainControllerDefPtr detach = NULL;
@@ -4974,7 +4990,8 @@ int qemuDomainDetachControllerDevice(virQEMUDriverPtr driver,
             goto cleanup;
     }
 
-    qemuDomainMarkDeviceForRemoval(vm, &detach->info);
+    if (!async)
+        qemuDomainMarkDeviceForRemoval(vm, &detach->info);
 
     qemuDomainObjEnterMonitor(driver, vm);
     if (qemuMonitorDelDevice(priv->mon, detach->info.alias)) {
@@ -4984,18 +5001,24 @@ int qemuDomainDetachControllerDevice(virQEMUDriverPtr driver,
     if (qemuDomainObjExitMonitor(driver, vm) < 0)
         goto cleanup;
 
-    if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
-        ret = qemuDomainRemoveControllerDevice(driver, vm, detach);
+    if (async) {
+        ret = 0;
+    } else {
+        if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
+            ret = qemuDomainRemoveControllerDevice(driver, vm, detach);
+    }
 
  cleanup:
-    qemuDomainResetDeviceRemoval(vm);
+    if (!async)
+        qemuDomainResetDeviceRemoval(vm);
     return ret;
 }
 
 static int
 qemuDomainDetachHostPCIDevice(virQEMUDriverPtr driver,
                               virDomainObjPtr vm,
-                              virDomainHostdevDefPtr detach)
+                              virDomainHostdevDefPtr detach,
+                              bool async)
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
     virDomainHostdevSubsysPCIPtr pcisrc = &detach->source.subsys.u.pci;
@@ -5009,7 +5032,8 @@ qemuDomainDetachHostPCIDevice(virQEMUDriverPtr driver,
         return -1;
     }
 
-    qemuDomainMarkDeviceForRemoval(vm, detach->info);
+    if (!async)
+        qemuDomainMarkDeviceForRemoval(vm, detach->info);
 
     qemuDomainObjEnterMonitor(driver, vm);
     ret = qemuMonitorDelDevice(priv->mon, detach->info->alias);
@@ -5022,7 +5046,8 @@ qemuDomainDetachHostPCIDevice(virQEMUDriverPtr driver,
 static int
 qemuDomainDetachHostUSBDevice(virQEMUDriverPtr driver,
                               virDomainObjPtr vm,
-                              virDomainHostdevDefPtr detach)
+                              virDomainHostdevDefPtr detach,
+                              bool async)
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
     int ret;
@@ -5033,7 +5058,8 @@ qemuDomainDetachHostUSBDevice(virQEMUDriverPtr driver,
         return -1;
     }
 
-    qemuDomainMarkDeviceForRemoval(vm, detach->info);
+    if (!async)
+        qemuDomainMarkDeviceForRemoval(vm, detach->info);
 
     qemuDomainObjEnterMonitor(driver, vm);
     ret = qemuMonitorDelDevice(priv->mon, detach->info->alias);
@@ -5046,7 +5072,8 @@ qemuDomainDetachHostUSBDevice(virQEMUDriverPtr driver,
 static int
 qemuDomainDetachHostSCSIDevice(virQEMUDriverPtr driver,
                                virDomainObjPtr vm,
-                               virDomainHostdevDefPtr detach)
+                               virDomainHostdevDefPtr detach,
+                               bool async)
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
     int ret = -1;
@@ -5057,7 +5084,8 @@ qemuDomainDetachHostSCSIDevice(virQEMUDriverPtr driver,
         return -1;
     }
 
-    qemuDomainMarkDeviceForRemoval(vm, detach->info);
+    if (!async)
+        qemuDomainMarkDeviceForRemoval(vm, detach->info);
 
     qemuDomainObjEnterMonitor(driver, vm);
     ret = qemuMonitorDelDevice(priv->mon, detach->info->alias);
@@ -5071,7 +5099,8 @@ qemuDomainDetachHostSCSIDevice(virQEMUDriverPtr driver,
 static int
 qemuDomainDetachSCSIVHostDevice(virQEMUDriverPtr driver,
                                 virDomainObjPtr vm,
-                                virDomainHostdevDefPtr detach)
+                                virDomainHostdevDefPtr detach,
+                                bool async)
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
     int ret = -1;
@@ -5082,7 +5111,8 @@ qemuDomainDetachSCSIVHostDevice(virQEMUDriverPtr driver,
         return -1;
     }
 
-    qemuDomainMarkDeviceForRemoval(vm, detach->info);
+    if (!async)
+        qemuDomainMarkDeviceForRemoval(vm, detach->info);
 
     qemuDomainObjEnterMonitor(driver, vm);
     ret = qemuMonitorDelDevice(priv->mon, detach->info->alias);
@@ -5097,7 +5127,8 @@ qemuDomainDetachSCSIVHostDevice(virQEMUDriverPtr driver,
 static int
 qemuDomainDetachMediatedDevice(virQEMUDriverPtr driver,
                                virDomainObjPtr vm,
-                               virDomainHostdevDefPtr detach)
+                               virDomainHostdevDefPtr detach,
+                               bool async)
 {
     int ret = -1;
     qemuDomainObjPrivatePtr priv = vm->privateData;
@@ -5108,7 +5139,8 @@ qemuDomainDetachMediatedDevice(virQEMUDriverPtr driver,
         return -1;
     }
 
-    qemuDomainMarkDeviceForRemoval(vm, detach->info);
+    if (!async)
+        qemuDomainMarkDeviceForRemoval(vm, detach->info);
 
     qemuDomainObjEnterMonitor(driver, vm);
     ret = qemuMonitorDelDevice(priv->mon, detach->info->alias);
@@ -5122,7 +5154,8 @@ qemuDomainDetachMediatedDevice(virQEMUDriverPtr driver,
 static int
 qemuDomainDetachThisHostDevice(virQEMUDriverPtr driver,
                                virDomainObjPtr vm,
-                               virDomainHostdevDefPtr detach)
+                               virDomainHostdevDefPtr detach,
+                               bool async)
 {
     int ret = -1;
 
@@ -5131,19 +5164,19 @@ qemuDomainDetachThisHostDevice(virQEMUDriverPtr driver,
 
     switch (detach->source.subsys.type) {
     case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
-        ret = qemuDomainDetachHostPCIDevice(driver, vm, detach);
+        ret = qemuDomainDetachHostPCIDevice(driver, vm, detach, async);
         break;
     case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
-        ret = qemuDomainDetachHostUSBDevice(driver, vm, detach);
+        ret = qemuDomainDetachHostUSBDevice(driver, vm, detach, async);
         break;
     case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI:
-        ret = qemuDomainDetachHostSCSIDevice(driver, vm, detach);
+        ret = qemuDomainDetachHostSCSIDevice(driver, vm, detach, async);
         break;
     case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST:
-        ret = qemuDomainDetachSCSIVHostDevice(driver, vm, detach);
+        ret = qemuDomainDetachSCSIVHostDevice(driver, vm, detach, async);
         break;
     case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV:
-        ret = qemuDomainDetachMediatedDevice(driver, vm, detach);
+        ret = qemuDomainDetachMediatedDevice(driver, vm, detach, async);
         break;
     default:
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
@@ -5155,11 +5188,13 @@ qemuDomainDetachThisHostDevice(virQEMUDriverPtr driver,
     if (ret < 0) {
         if (virDomainObjIsActive(vm))
             virDomainAuditHostdev(vm, detach, "detach", false);
-    } else if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1) {
+    } else if (!async &&
+               (ret = qemuDomainWaitForDeviceRemoval(vm)) == 1) {
         ret = qemuDomainRemoveHostDevice(driver, vm, detach);
     }
 
-    qemuDomainResetDeviceRemoval(vm);
+    if (!async)
+        qemuDomainResetDeviceRemoval(vm);
 
     return ret;
 }
@@ -5167,7 +5202,8 @@ qemuDomainDetachThisHostDevice(virQEMUDriverPtr driver,
 /* search for a hostdev matching dev and detach it */
 int qemuDomainDetachHostDevice(virQEMUDriverPtr driver,
                                virDomainObjPtr vm,
-                               virDomainDeviceDefPtr dev)
+                               virDomainDeviceDefPtr dev,
+                               bool async)
 {
     virDomainHostdevDefPtr hostdev = dev->data.hostdev;
     virDomainHostdevSubsysPtr subsys = &hostdev->source.subsys;
@@ -5242,16 +5278,17 @@ int qemuDomainDetachHostDevice(virQEMUDriverPtr driver,
      * function so that mac address / virtualport are reset
      */
     if (detach->parent.type == VIR_DOMAIN_DEVICE_NET)
-        return qemuDomainDetachNetDevice(driver, vm, &detach->parent);
+        return qemuDomainDetachNetDevice(driver, vm, &detach->parent, async);
     else
-        return qemuDomainDetachThisHostDevice(driver, vm, detach);
+        return qemuDomainDetachThisHostDevice(driver, vm, detach, async);
 }
 
 
 int
 qemuDomainDetachShmemDevice(virQEMUDriverPtr driver,
                             virDomainObjPtr vm,
-                            virDomainShmemDefPtr dev)
+                            virDomainShmemDefPtr dev,
+                            bool async)
 {
     int ret = -1;
     ssize_t idx = -1;
@@ -5282,7 +5319,8 @@ qemuDomainDetachShmemDevice(virQEMUDriverPtr driver,
         return -1;
     }
 
-    qemuDomainMarkDeviceForRemoval(vm, &shmem->info);
+    if (!async)
+        qemuDomainMarkDeviceForRemoval(vm, &shmem->info);
 
     qemuDomainObjEnterMonitor(driver, vm);
     if (qemuMonitorDelDevice(priv->mon, shmem->info.alias) < 0) {
@@ -5304,7 +5342,8 @@ qemuDomainDetachShmemDevice(virQEMUDriverPtr driver,
 int
 qemuDomainDetachWatchdog(virQEMUDriverPtr driver,
                          virDomainObjPtr vm,
-                         virDomainWatchdogDefPtr dev)
+                         virDomainWatchdogDefPtr dev,
+                         bool async)
 {
     int ret = -1;
     virDomainWatchdogDefPtr watchdog = vm->def->watchdog;
@@ -5336,7 +5375,8 @@ qemuDomainDetachWatchdog(virQEMUDriverPtr driver,
         return -1;
     }
 
-    qemuDomainMarkDeviceForRemoval(vm, &watchdog->info);
+    if (!async)
+        qemuDomainMarkDeviceForRemoval(vm, &watchdog->info);
 
     qemuDomainObjEnterMonitor(driver, vm);
     if (qemuMonitorDelDevice(priv->mon, watchdog->info.alias) < 0) {
@@ -5358,7 +5398,8 @@ qemuDomainDetachWatchdog(virQEMUDriverPtr driver,
 int
 qemuDomainDetachRedirdevDevice(virQEMUDriverPtr driver,
                                virDomainObjPtr vm,
-                               virDomainRedirdevDefPtr dev)
+                               virDomainRedirdevDefPtr dev,
+                               bool async)
 {
     int ret = -1;
     qemuDomainObjPrivatePtr priv = vm->privateData;
@@ -5379,7 +5420,8 @@ qemuDomainDetachRedirdevDevice(virQEMUDriverPtr driver,
         return -1;
     }
 
-    qemuDomainMarkDeviceForRemoval(vm, &tmpRedirdevDef->info);
+    if (!async)
+        qemuDomainMarkDeviceForRemoval(vm, &tmpRedirdevDef->info);
 
     qemuDomainObjEnterMonitor(driver, vm);
     if (qemuMonitorDelDevice(priv->mon, tmpRedirdevDef->info.alias) < 0) {
@@ -5389,11 +5431,16 @@ qemuDomainDetachRedirdevDevice(virQEMUDriverPtr driver,
     if (qemuDomainObjExitMonitor(driver, vm) < 0)
         goto cleanup;
 
-    if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
-        ret = qemuDomainRemoveRedirdevDevice(driver, vm, tmpRedirdevDef);
+    if (async) {
+        ret = 0;
+    } else {
+        if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
+            ret = qemuDomainRemoveRedirdevDevice(driver, vm, tmpRedirdevDef);
+    }
 
  cleanup:
-    qemuDomainResetDeviceRemoval(vm);
+    if (!async)
+        qemuDomainResetDeviceRemoval(vm);
     return ret;
 }
 
@@ -5401,7 +5448,8 @@ qemuDomainDetachRedirdevDevice(virQEMUDriverPtr driver,
 int
 qemuDomainDetachNetDevice(virQEMUDriverPtr driver,
                           virDomainObjPtr vm,
-                          virDomainDeviceDefPtr dev)
+                          virDomainDeviceDefPtr dev,
+                          bool async)
 {
     int detachidx, ret = -1;
     virDomainNetDefPtr detach = NULL;
@@ -5414,7 +5462,8 @@ qemuDomainDetachNetDevice(virQEMUDriverPtr driver,
 
     if (virDomainNetGetActualType(detach) == VIR_DOMAIN_NET_TYPE_HOSTDEV) {
         ret = qemuDomainDetachThisHostDevice(driver, vm,
-                                             virDomainNetGetActualHostdev(detach));
+                                             virDomainNetGetActualHostdev(detach),\
+                                             async);
         goto cleanup;
     }
 
@@ -5442,7 +5491,8 @@ qemuDomainDetachNetDevice(virQEMUDriverPtr driver,
      */
     ignore_value(qemuInterfaceStopDevice(detach));
 
-    qemuDomainMarkDeviceForRemoval(vm, &detach->info);
+    if (!async)
+        qemuDomainMarkDeviceForRemoval(vm, &detach->info);
 
     qemuDomainObjEnterMonitor(driver, vm);
     if (qemuMonitorDelDevice(priv->mon, detach->info.alias) < 0) {
@@ -5454,11 +5504,16 @@ qemuDomainDetachNetDevice(virQEMUDriverPtr driver,
     if (qemuDomainObjExitMonitor(driver, vm) < 0)
         goto cleanup;
 
-    if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
-        ret = qemuDomainRemoveNetDevice(driver, vm, detach);
+    if (async) {
+        ret = 0;
+    } else {
+        if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
+            ret = qemuDomainRemoveNetDevice(driver, vm, detach);
+    }
 
  cleanup:
-    qemuDomainResetDeviceRemoval(vm);
+    if (!async)
+        qemuDomainResetDeviceRemoval(vm);
     return ret;
 }
 
@@ -5585,7 +5640,8 @@ int qemuDomainDetachLease(virQEMUDriverPtr driver,
 
 int qemuDomainDetachChrDevice(virQEMUDriverPtr driver,
                               virDomainObjPtr vm,
-                              virDomainChrDefPtr chr)
+                              virDomainChrDefPtr chr,
+                              bool async)
 {
     int ret = -1;
     qemuDomainObjPrivatePtr priv = vm->privateData;
@@ -5609,7 +5665,8 @@ int qemuDomainDetachChrDevice(virQEMUDriverPtr driver,
     if (qemuBuildChrDeviceStr(&devstr, vmdef, chr, priv->qemuCaps) < 0)
         goto cleanup;
 
-    qemuDomainMarkDeviceForRemoval(vm, &tmpChr->info);
+    if (!async)
+        qemuDomainMarkDeviceForRemoval(vm, &tmpChr->info);
 
     qemuDomainObjEnterMonitor(driver, vm);
     if (devstr && qemuMonitorDelDevice(priv->mon, tmpChr->info.alias) < 0) {
@@ -5619,11 +5676,16 @@ int qemuDomainDetachChrDevice(virQEMUDriverPtr driver,
     if (qemuDomainObjExitMonitor(driver, vm) < 0)
         goto cleanup;
 
-    if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
-        ret = qemuDomainRemoveChrDevice(driver, vm, tmpChr);
+    if (async) {
+        ret = 0;
+    } else {
+        if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
+            ret = qemuDomainRemoveChrDevice(driver, vm, tmpChr);
+    }
 
  cleanup:
-    qemuDomainResetDeviceRemoval(vm);
+    if (!async)
+        qemuDomainResetDeviceRemoval(vm);
     VIR_FREE(devstr);
     return ret;
 }
@@ -5632,7 +5694,8 @@ int qemuDomainDetachChrDevice(virQEMUDriverPtr driver,
 int
 qemuDomainDetachRNGDevice(virQEMUDriverPtr driver,
                           virDomainObjPtr vm,
-                          virDomainRNGDefPtr rng)
+                          virDomainRNGDefPtr rng,
+                          bool async)
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
     ssize_t idx;
@@ -5656,18 +5719,24 @@ qemuDomainDetachRNGDevice(virQEMUDriverPtr driver,
         return -1;
     }
 
-    qemuDomainMarkDeviceForRemoval(vm, &tmpRNG->info);
+    if (!async)
+        qemuDomainMarkDeviceForRemoval(vm, &tmpRNG->info);
 
     qemuDomainObjEnterMonitor(driver, vm);
     rc = qemuMonitorDelDevice(priv->mon, tmpRNG->info.alias);
     if (qemuDomainObjExitMonitor(driver, vm) || rc < 0)
         goto cleanup;
 
-    if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
-        ret = qemuDomainRemoveRNGDevice(driver, vm, tmpRNG);
+    if (async) {
+        ret = 0;
+    } else {
+        if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
+            ret = qemuDomainRemoveRNGDevice(driver, vm, tmpRNG);
+    }
 
  cleanup:
-    qemuDomainResetDeviceRemoval(vm);
+    if (!async)
+        qemuDomainResetDeviceRemoval(vm);
     return ret;
 }
 
@@ -5675,7 +5744,8 @@ qemuDomainDetachRNGDevice(virQEMUDriverPtr driver,
 int
 qemuDomainDetachMemoryDevice(virQEMUDriverPtr driver,
                              virDomainObjPtr vm,
-                             virDomainMemoryDefPtr memdef)
+                             virDomainMemoryDefPtr memdef,
+                             bool async)
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
     virDomainMemoryDefPtr mem;
@@ -5701,18 +5771,24 @@ qemuDomainDetachMemoryDevice(virQEMUDriverPtr driver,
         return -1;
     }
 
-    qemuDomainMarkDeviceForRemoval(vm, &mem->info);
+    if (!async)
+        qemuDomainMarkDeviceForRemoval(vm, &mem->info);
 
     qemuDomainObjEnterMonitor(driver, vm);
     rc = qemuMonitorDelDevice(priv->mon, mem->info.alias);
     if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0)
         goto cleanup;
 
-    if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
-        ret = qemuDomainRemoveMemoryDevice(driver, vm, mem);
+    if (async) {
+        ret = 0;
+    } else {
+        if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
+            ret = qemuDomainRemoveMemoryDevice(driver, vm, mem);
+    }
 
  cleanup:
-    qemuDomainResetDeviceRemoval(vm);
+    if (!async)
+        qemuDomainResetDeviceRemoval(vm);
     return ret;
 }
 
@@ -6380,7 +6456,8 @@ qemuDomainSetVcpuInternal(virQEMUDriverPtr driver,
 
 int
 qemuDomainDetachInputDevice(virDomainObjPtr vm,
-                            virDomainInputDefPtr def)
+                            virDomainInputDefPtr def,
+                            bool async)
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
     virQEMUDriverPtr driver = priv->driver;
@@ -6410,7 +6487,8 @@ qemuDomainDetachInputDevice(virDomainObjPtr vm,
         break;
     }
 
-    qemuDomainMarkDeviceForRemoval(vm, &input->info);
+    if (!async)
+        qemuDomainMarkDeviceForRemoval(vm, &input->info);
 
     qemuDomainObjEnterMonitor(driver, vm);
     if (qemuMonitorDelDevice(priv->mon, input->info.alias)) {
@@ -6420,10 +6498,15 @@ qemuDomainDetachInputDevice(virDomainObjPtr vm,
     if (qemuDomainObjExitMonitor(driver, vm) < 0)
         goto cleanup;
 
-    if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
-        ret = qemuDomainRemoveInputDevice(vm, input);
+    if (async) {
+        ret = 0;
+    } else {
+        if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
+            ret = qemuDomainRemoveInputDevice(vm, input);
+    }
 
  cleanup:
-    qemuDomainResetDeviceRemoval(vm);
+    if (!async)
+        qemuDomainResetDeviceRemoval(vm);
     return ret;
 }
diff --git a/src/qemu/qemu_hotplug.h b/src/qemu/qemu_hotplug.h
index b2f5fa688b..751cbf61d4 100644
--- a/src/qemu/qemu_hotplug.h
+++ b/src/qemu/qemu_hotplug.h
@@ -87,7 +87,8 @@ int qemuDomainAttachMemory(virQEMUDriverPtr driver,
                            virDomainMemoryDefPtr mem);
 int qemuDomainDetachMemoryDevice(virQEMUDriverPtr driver,
                                  virDomainObjPtr vm,
-                                 virDomainMemoryDefPtr memdef);
+                                 virDomainMemoryDefPtr memdef,
+                                 bool async);
 int qemuDomainChangeGraphics(virQEMUDriverPtr driver,
                              virDomainObjPtr vm,
                              virDomainGraphicsDefPtr dev);
@@ -106,26 +107,33 @@ int qemuDomainChangeNetLinkState(virQEMUDriverPtr driver,
                                  int linkstate);
 int qemuDomainDetachDeviceDiskLive(virQEMUDriverPtr driver,
                                    virDomainObjPtr vm,
-                                   virDomainDeviceDefPtr dev);
+                                   virDomainDeviceDefPtr dev,
+                                   bool async);
 int qemuDomainDetachControllerDevice(virQEMUDriverPtr driver,
                                      virDomainObjPtr vm,
-                                     virDomainDeviceDefPtr dev);
+                                     virDomainDeviceDefPtr dev,
+                                     bool async);
 int qemuDomainDetachNetDevice(virQEMUDriverPtr driver,
                               virDomainObjPtr vm,
-                              virDomainDeviceDefPtr dev);
+                              virDomainDeviceDefPtr dev,
+                              bool async);
 int qemuDomainDetachHostDevice(virQEMUDriverPtr driver,
                                virDomainObjPtr vm,
-                               virDomainDeviceDefPtr dev);
+                               virDomainDeviceDefPtr dev,
+                               bool async);
 int qemuDomainDetachShmemDevice(virQEMUDriverPtr driver,
                                 virDomainObjPtr vm,
-                                virDomainShmemDefPtr dev);
+                                virDomainShmemDefPtr dev,
+                                bool async);
 int qemuDomainDetachWatchdog(virQEMUDriverPtr driver,
                              virDomainObjPtr vm,
-                             virDomainWatchdogDefPtr watchdog);
+                             virDomainWatchdogDefPtr watchdog,
+                             bool async);
 
 int qemuDomainDetachRedirdevDevice(virQEMUDriverPtr driver,
                                    virDomainObjPtr vm,
-                                   virDomainRedirdevDefPtr dev);
+                                   virDomainRedirdevDefPtr dev,
+                                   bool async);
 
 int qemuDomainAttachInputDevice(virQEMUDriverPtr driver,
                                 virDomainObjPtr vm,
@@ -142,13 +150,15 @@ int qemuDomainAttachChrDevice(virQEMUDriverPtr driver,
                               virDomainChrDefPtr chr);
 int qemuDomainDetachChrDevice(virQEMUDriverPtr driver,
                               virDomainObjPtr vm,
-                              virDomainChrDefPtr chr);
+                              virDomainChrDefPtr chr,
+                              bool async);
 int qemuDomainAttachRNGDevice(virQEMUDriverPtr driver,
                               virDomainObjPtr vm,
                               virDomainRNGDefPtr rng);
 int qemuDomainDetachRNGDevice(virQEMUDriverPtr driver,
                               virDomainObjPtr vm,
-                              virDomainRNGDefPtr rng);
+                              virDomainRNGDefPtr rng,
+                              bool async);
 
 void qemuDomainRemoveVcpuAlias(virQEMUDriverPtr driver,
                                virDomainObjPtr vm,
@@ -184,6 +194,7 @@ int qemuDomainSetVcpuInternal(virQEMUDriverPtr driver,
                               bool state);
 
 int qemuDomainDetachInputDevice(virDomainObjPtr vm,
-                                virDomainInputDefPtr def);
+                                virDomainInputDefPtr def,
+                                bool async);
 
 #endif /* __QEMU_HOTPLUG_H__ */
diff --git a/tests/qemuhotplugtest.c b/tests/qemuhotplugtest.c
index e93503812a..663e33ed00 100644
--- a/tests/qemuhotplugtest.c
+++ b/tests/qemuhotplugtest.c
@@ -142,22 +142,23 @@ testQemuHotplugAttach(virDomainObjPtr vm,
 
 static int
 testQemuHotplugDetach(virDomainObjPtr vm,
-                      virDomainDeviceDefPtr dev)
+                      virDomainDeviceDefPtr dev,
+                      bool async)
 {
     int ret = -1;
 
     switch (dev->type) {
     case VIR_DOMAIN_DEVICE_DISK:
-        ret = qemuDomainDetachDeviceDiskLive(&driver, vm, dev);
+        ret = qemuDomainDetachDeviceDiskLive(&driver, vm, dev, async);
         break;
     case VIR_DOMAIN_DEVICE_CHR:
-        ret = qemuDomainDetachChrDevice(&driver, vm, dev->data.chr);
+        ret = qemuDomainDetachChrDevice(&driver, vm, dev->data.chr, async);
         break;
     case VIR_DOMAIN_DEVICE_SHMEM:
-        ret = qemuDomainDetachShmemDevice(&driver, vm, dev->data.shmem);
+        ret = qemuDomainDetachShmemDevice(&driver, vm, dev->data.shmem, async);
         break;
     case VIR_DOMAIN_DEVICE_WATCHDOG:
-        ret = qemuDomainDetachWatchdog(&driver, vm, dev->data.watchdog);
+        ret = qemuDomainDetachWatchdog(&driver, vm, dev->data.watchdog, async);
         break;
     default:
         VIR_TEST_VERBOSE("device type '%s' cannot be detached\n",
@@ -322,7 +323,7 @@ testQemuHotplug(const void *data)
         break;
 
     case DETACH:
-        ret = testQemuHotplugDetach(vm, dev);
+        ret = testQemuHotplugDetach(vm, dev, false);
         if (ret == 0 || fail)
             ret = testQemuHotplugCheckResult(vm, domain_xml,
                                              domain_filename, fail);
-- 
2.16.1




More information about the libvir-list mailing list