99cbc7
From 14c62fbf0a1ed27ab12ba439afd0d2e7c55996f2 Mon Sep 17 00:00:00 2001
99cbc7
Message-Id: <14c62fbf0a1ed27ab12ba439afd0d2e7c55996f2@dist-git>
99cbc7
From: Laine Stump <laine@laine.org>
99cbc7
Date: Thu, 11 Apr 2019 15:14:47 -0400
99cbc7
Subject: [PATCH] qemu_hotplug: standardize the names/args/calling of
99cbc7
 qemuDomainDetach*()
99cbc7
99cbc7
Most of these functions will soon contain only some setup for
99cbc7
detaching the device, not the detach code proper (since that code is
99cbc7
identical for these devices). Their device specific functions are all
99cbc7
being renamed to qemuDomainDetachPrep*(), where * is the
99cbc7
name of that device's data member in the virDomainDeviceDef
99cbc7
object.
99cbc7
99cbc7
Since there will be other code in qemuDomainDetachDeviceLive() after
99cbc7
the calls to qemuDomainDetachPrep*() that could still fail, we no
99cbc7
longer directly set "ret" with the return code from
99cbc7
qemuDomainDetachPrep*() functions, but simply return -1 on
99cbc7
failure, and wait until the end of qemuDomainDetachDeviceLive() to set
99cbc7
ret = 0.
99cbc7
99cbc7
Along with the rename, qemuDomainDetachPrep*() functions are also
99cbc7
given similar arglists, including an arg called "match" that points to
99cbc7
the proto-object of the device we want to delete, and another arg
99cbc7
"detach" that is used to return a pointer to the actual object that
99cbc7
will be (for now *has been*) detached. To make sure these new args
99cbc7
aren't confused with existing local pointers that sometimes had the
99cbc7
same name (detach), the local pointer to the device is now named after
99cbc7
the device type ("controller", "disk", etc). These point to the same
99cbc7
place as (*detach)->data.blah, it's just easier on the eyes to have,
99cbc7
e.g., "disk->dst" rather than "(*detach)->data.disk-dst".
99cbc7
99cbc7
Signed-off-by: Laine Stump <laine@laine.org>
99cbc7
ACKed-by: Peter Krempa <pkrempa@redhat.com>
99cbc7
(cherry picked from commit b6a53bf9079bc9ef2dc3f8b85ff5c84da14b9a0a)
99cbc7
99cbc7
Partially-Resolves: https://bugzilla.redhat.com/1658198
99cbc7
Signed-off-by: Laine Stump <laine@redhat.com>
99cbc7
Signed-off-by: Laine Stump <laine@laine.org>
99cbc7
Message-Id: <20190411191453.24055-36-laine@redhat.com>
99cbc7
Acked-by: Michal Privoznik <mprivozn@redhat.com>
99cbc7
---
99cbc7
 src/qemu/qemu_hotplug.c | 316 +++++++++++++++++++++++-----------------
99cbc7
 1 file changed, 181 insertions(+), 135 deletions(-)
99cbc7
99cbc7
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
99cbc7
index 9c0ee1c6a5..693b8878b5 100644
99cbc7
--- a/src/qemu/qemu_hotplug.c
99cbc7
+++ b/src/qemu/qemu_hotplug.c
99cbc7
@@ -4838,21 +4838,22 @@ qemuFindDisk(virDomainDefPtr def, const char *dst)
99cbc7
 }
99cbc7
 
99cbc7
 static int
99cbc7
-qemuDomainDetachDeviceDiskLive(virQEMUDriverPtr driver,
99cbc7
-                               virDomainObjPtr vm,
99cbc7
-                               virDomainDeviceDefPtr dev,
99cbc7
-                               bool async)
99cbc7
+qemuDomainDetachPrepDisk(virQEMUDriverPtr driver,
99cbc7
+                         virDomainObjPtr vm,
99cbc7
+                         virDomainDiskDefPtr match,
99cbc7
+                         virDomainDiskDefPtr *detach,
99cbc7
+                         bool async)
99cbc7
 {
99cbc7
     virDomainDiskDefPtr disk;
99cbc7
     int idx;
99cbc7
     int ret = -1;
99cbc7
 
99cbc7
-    if ((idx = qemuFindDisk(vm->def, dev->data.disk->dst)) < 0) {
99cbc7
+    if ((idx = qemuFindDisk(vm->def, match->dst)) < 0) {
99cbc7
         virReportError(VIR_ERR_OPERATION_FAILED,
99cbc7
-                       _("disk %s not found"), dev->data.disk->dst);
99cbc7
+                       _("disk %s not found"), match->dst);
99cbc7
         return -1;
99cbc7
     }
99cbc7
-    disk = vm->def->disks[idx];
99cbc7
+    *detach = disk = vm->def->disks[idx];
99cbc7
 
99cbc7
     switch ((virDomainDiskDevice) disk->device) {
99cbc7
     case VIR_DOMAIN_DISK_DEVICE_DISK:
99cbc7
@@ -4989,57 +4990,55 @@ static bool qemuDomainControllerIsBusy(virDomainObjPtr vm,
99cbc7
 }
99cbc7
 
99cbc7
 static int
99cbc7
-qemuDomainDetachControllerDevice(virQEMUDriverPtr driver,
99cbc7
-                                 virDomainObjPtr vm,
99cbc7
-                                 virDomainDeviceDefPtr dev,
99cbc7
-                                 bool async)
99cbc7
+qemuDomainDetachPrepController(virQEMUDriverPtr driver,
99cbc7
+                               virDomainObjPtr vm,
99cbc7
+                               virDomainControllerDefPtr match,
99cbc7
+                               virDomainControllerDefPtr *detach,
99cbc7
+                               bool async)
99cbc7
 {
99cbc7
     int idx, ret = -1;
99cbc7
-    virDomainControllerDefPtr detach = NULL;
99cbc7
+    virDomainControllerDefPtr controller = NULL;
99cbc7
 
99cbc7
-    if (dev->data.controller->type != VIR_DOMAIN_CONTROLLER_TYPE_SCSI) {
99cbc7
+    if (match->type != VIR_DOMAIN_CONTROLLER_TYPE_SCSI) {
99cbc7
         virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
99cbc7
                        _("'%s' controller cannot be hot unplugged."),
99cbc7
-                       virDomainControllerTypeToString(dev->data.controller->type));
99cbc7
+                       virDomainControllerTypeToString(match->type));
99cbc7
         return -1;
99cbc7
     }
99cbc7
 
99cbc7
-    if ((idx = virDomainControllerFind(vm->def,
99cbc7
-                                       dev->data.controller->type,
99cbc7
-                                       dev->data.controller->idx)) < 0) {
99cbc7
+    if ((idx = virDomainControllerFind(vm->def, match->type, match->idx)) < 0) {
99cbc7
         virReportError(VIR_ERR_DEVICE_MISSING,
99cbc7
                        _("controller %s:%d not found"),
99cbc7
-                       virDomainControllerTypeToString(dev->data.controller->type),
99cbc7
-                       dev->data.controller->idx);
99cbc7
+                       virDomainControllerTypeToString(match->type),
99cbc7
+                       match->idx);
99cbc7
         goto cleanup;
99cbc7
     }
99cbc7
 
99cbc7
-    detach = vm->def->controllers[idx];
99cbc7
+    *detach = controller = vm->def->controllers[idx];
99cbc7
 
99cbc7
-    if (qemuIsMultiFunctionDevice(vm->def, &detach->info)) {
99cbc7
+    if (qemuIsMultiFunctionDevice(vm->def, &controller->info)) {
99cbc7
         virReportError(VIR_ERR_OPERATION_FAILED,
99cbc7
-                       _("cannot hot unplug multifunction PCI device: %s"),
99cbc7
-                       dev->data.disk->dst);
99cbc7
+                       "%s", _("cannot hot unplug multifunction PCI device"));
99cbc7
         goto cleanup;
99cbc7
     }
99cbc7
 
99cbc7
-    if (qemuDomainControllerIsBusy(vm, detach)) {
99cbc7
+    if (qemuDomainControllerIsBusy(vm, controller)) {
99cbc7
         virReportError(VIR_ERR_OPERATION_FAILED, "%s",
99cbc7
                        _("device cannot be detached: device is busy"));
99cbc7
         goto cleanup;
99cbc7
     }
99cbc7
 
99cbc7
     if (!async)
99cbc7
-        qemuDomainMarkDeviceForRemoval(vm, &detach->info);
99cbc7
+        qemuDomainMarkDeviceForRemoval(vm, &controller->info);
99cbc7
 
99cbc7
-    if (qemuDomainDeleteDevice(vm, detach->info.alias) < 0)
99cbc7
+    if (qemuDomainDeleteDevice(vm, controller->info.alias) < 0)
99cbc7
         goto cleanup;
99cbc7
 
99cbc7
     if (async) {
99cbc7
         ret = 0;
99cbc7
     } else {
99cbc7
         if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
99cbc7
-            ret = qemuDomainRemoveControllerDevice(driver, vm, detach);
99cbc7
+            ret = qemuDomainRemoveControllerDevice(driver, vm, controller);
99cbc7
     }
99cbc7
 
99cbc7
  cleanup:
99cbc7
@@ -5051,29 +5050,30 @@ qemuDomainDetachControllerDevice(virQEMUDriverPtr driver,
99cbc7
 
99cbc7
 /* search for a hostdev matching dev and detach it */
99cbc7
 static int
99cbc7
-qemuDomainDetachHostDevice(virQEMUDriverPtr driver,
99cbc7
-                           virDomainObjPtr vm,
99cbc7
-                           virDomainDeviceDefPtr dev,
99cbc7
-                           bool async)
99cbc7
+qemuDomainDetachPrepHostdev(virQEMUDriverPtr driver,
99cbc7
+                            virDomainObjPtr vm,
99cbc7
+                            virDomainHostdevDefPtr match,
99cbc7
+                            virDomainHostdevDefPtr *detach,
99cbc7
+                            bool async)
99cbc7
 {
99cbc7
-    virDomainHostdevDefPtr hostdev = dev->data.hostdev;
99cbc7
-    virDomainHostdevSubsysPtr subsys = &hostdev->source.subsys;
99cbc7
+    virDomainHostdevSubsysPtr subsys = &match->source.subsys;
99cbc7
     virDomainHostdevSubsysUSBPtr usbsrc = &subsys->u.usb;
99cbc7
     virDomainHostdevSubsysPCIPtr pcisrc = &subsys->u.pci;
99cbc7
     virDomainHostdevSubsysSCSIPtr scsisrc = &subsys->u.scsi;
99cbc7
     virDomainHostdevSubsysMediatedDevPtr mdevsrc = &subsys->u.mdev;
99cbc7
-    virDomainHostdevDefPtr detach = NULL;
99cbc7
+    virDomainHostdevDefPtr hostdev = NULL;
99cbc7
     int idx;
99cbc7
     int ret = -1;
99cbc7
 
99cbc7
-    if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) {
99cbc7
+    if (match->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) {
99cbc7
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
99cbc7
                        _("hot unplug is not supported for hostdev mode '%s'"),
99cbc7
-                       virDomainHostdevModeTypeToString(hostdev->mode));
99cbc7
+                       virDomainHostdevModeTypeToString(match->mode));
99cbc7
         return -1;
99cbc7
     }
99cbc7
 
99cbc7
-    idx = virDomainHostdevFind(vm->def, hostdev, &detach);
99cbc7
+    idx = virDomainHostdevFind(vm->def, match, &hostdev);
99cbc7
+    *detach = hostdev;
99cbc7
 
99cbc7
     if (idx < 0) {
99cbc7
         switch (subsys->type) {
99cbc7
@@ -5126,27 +5126,27 @@ qemuDomainDetachHostDevice(virQEMUDriverPtr driver,
99cbc7
         return -1;
99cbc7
     }
99cbc7
 
99cbc7
-    if (qemuIsMultiFunctionDevice(vm->def, detach->info)) {
99cbc7
+    if (qemuIsMultiFunctionDevice(vm->def, hostdev->info)) {
99cbc7
         virReportError(VIR_ERR_OPERATION_FAILED,
99cbc7
                        _("cannot hot unplug multifunction PCI device with guest address: "
99cbc7
                          "%.4x:%.2x:%.2x.%.1x"),
99cbc7
-                       detach->info->addr.pci.domain, detach->info->addr.pci.bus,
99cbc7
-                       detach->info->addr.pci.slot, detach->info->addr.pci.function);
99cbc7
+                       hostdev->info->addr.pci.domain, hostdev->info->addr.pci.bus,
99cbc7
+                       hostdev->info->addr.pci.slot, hostdev->info->addr.pci.function);
99cbc7
         return -1;
99cbc7
     }
99cbc7
 
99cbc7
-    if (!detach->info->alias) {
99cbc7
+    if (!hostdev->info->alias) {
99cbc7
         virReportError(VIR_ERR_OPERATION_FAILED,
99cbc7
                        "%s", _("device cannot be detached without a device alias"));
99cbc7
         return -1;
99cbc7
     }
99cbc7
 
99cbc7
     if (!async)
99cbc7
-        qemuDomainMarkDeviceForRemoval(vm, detach->info);
99cbc7
+        qemuDomainMarkDeviceForRemoval(vm, hostdev->info);
99cbc7
 
99cbc7
-    if (qemuDomainDeleteDevice(vm, detach->info->alias) < 0) {
99cbc7
+    if (qemuDomainDeleteDevice(vm, hostdev->info->alias) < 0) {
99cbc7
         if (virDomainObjIsActive(vm))
99cbc7
-            virDomainAuditHostdev(vm, detach, "detach", false);
99cbc7
+            virDomainAuditHostdev(vm, hostdev, "detach", false);
99cbc7
         goto cleanup;
99cbc7
     }
99cbc7
 
99cbc7
@@ -5154,7 +5154,7 @@ qemuDomainDetachHostDevice(virQEMUDriverPtr driver,
99cbc7
         ret = 0;
99cbc7
     } else {
99cbc7
         if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
99cbc7
-            ret = qemuDomainRemoveHostDevice(driver, vm, detach);
99cbc7
+            ret = qemuDomainRemoveHostDevice(driver, vm, hostdev);
99cbc7
     }
99cbc7
 
99cbc7
  cleanup:
99cbc7
@@ -5167,24 +5167,25 @@ qemuDomainDetachHostDevice(virQEMUDriverPtr driver,
99cbc7
 
99cbc7
 
99cbc7
 static int
99cbc7
-qemuDomainDetachShmemDevice(virQEMUDriverPtr driver,
99cbc7
-                            virDomainObjPtr vm,
99cbc7
-                            virDomainShmemDefPtr dev,
99cbc7
-                            bool async)
99cbc7
+qemuDomainDetachPrepShmem(virQEMUDriverPtr driver,
99cbc7
+                          virDomainObjPtr vm,
99cbc7
+                          virDomainShmemDefPtr match,
99cbc7
+                          virDomainShmemDefPtr *detach,
99cbc7
+                          bool async)
99cbc7
 {
99cbc7
     int ret = -1;
99cbc7
     ssize_t idx = -1;
99cbc7
     virDomainShmemDefPtr shmem = NULL;
99cbc7
 
99cbc7
-    if ((idx = virDomainShmemDefFind(vm->def, dev)) < 0) {
99cbc7
+    if ((idx = virDomainShmemDefFind(vm->def, match)) < 0) {
99cbc7
         virReportError(VIR_ERR_DEVICE_MISSING,
99cbc7
                        _("model '%s' shmem device not present "
99cbc7
                          "in domain configuration"),
99cbc7
-                       virDomainShmemModelTypeToString(dev->model));
99cbc7
+                       virDomainShmemModelTypeToString(match->model));
99cbc7
         return -1;
99cbc7
     }
99cbc7
 
99cbc7
-    shmem = vm->def->shmems[idx];
99cbc7
+    *detach = shmem = vm->def->shmems[idx];
99cbc7
 
99cbc7
     switch ((virDomainShmemModel)shmem->model) {
99cbc7
     case VIR_DOMAIN_SHMEM_MODEL_IVSHMEM_PLAIN:
99cbc7
@@ -5221,13 +5222,16 @@ qemuDomainDetachShmemDevice(virQEMUDriverPtr driver,
99cbc7
 
99cbc7
 
99cbc7
 static int
99cbc7
-qemuDomainDetachWatchdog(virQEMUDriverPtr driver,
99cbc7
-                         virDomainObjPtr vm,
99cbc7
-                         virDomainWatchdogDefPtr dev,
99cbc7
-                         bool async)
99cbc7
+qemuDomainDetachPrepWatchdog(virQEMUDriverPtr driver,
99cbc7
+                             virDomainObjPtr vm,
99cbc7
+                             virDomainWatchdogDefPtr match,
99cbc7
+                             virDomainWatchdogDefPtr *detach,
99cbc7
+                             bool async)
99cbc7
 {
99cbc7
     int ret = -1;
99cbc7
-    virDomainWatchdogDefPtr watchdog = vm->def->watchdog;
99cbc7
+    virDomainWatchdogDefPtr watchdog;
99cbc7
+
99cbc7
+    *detach = watchdog = vm->def->watchdog;
99cbc7
 
99cbc7
     if (!watchdog) {
99cbc7
         virReportError(VIR_ERR_DEVICE_MISSING, "%s",
99cbc7
@@ -5238,9 +5242,9 @@ qemuDomainDetachWatchdog(virQEMUDriverPtr driver,
99cbc7
     /* While domains can have up to one watchdog, the one supplied by the user
99cbc7
      * doesn't necessarily match the one domain has. Refuse to detach in such
99cbc7
      * case. */
99cbc7
-    if (!(watchdog->model == dev->model &&
99cbc7
-          watchdog->action == dev->action &&
99cbc7
-          virDomainDeviceInfoAddressIsEqual(&dev->info, &watchdog->info))) {
99cbc7
+    if (!(watchdog->model == match->model &&
99cbc7
+          watchdog->action == match->action &&
99cbc7
+          virDomainDeviceInfoAddressIsEqual(&match->info, &watchdog->info))) {
99cbc7
         virReportError(VIR_ERR_DEVICE_MISSING,
99cbc7
                        _("model '%s' watchdog device not present "
99cbc7
                          "in domain configuration"),
99cbc7
@@ -5276,40 +5280,41 @@ qemuDomainDetachWatchdog(virQEMUDriverPtr driver,
99cbc7
 
99cbc7
 
99cbc7
 static int
99cbc7
-qemuDomainDetachRedirdevDevice(virQEMUDriverPtr driver,
99cbc7
-                               virDomainObjPtr vm,
99cbc7
-                               virDomainRedirdevDefPtr dev,
99cbc7
-                               bool async)
99cbc7
+qemuDomainDetachPrepRedirdev(virQEMUDriverPtr driver,
99cbc7
+                             virDomainObjPtr vm,
99cbc7
+                             virDomainRedirdevDefPtr match,
99cbc7
+                             virDomainRedirdevDefPtr *detach,
99cbc7
+                             bool async)
99cbc7
 {
99cbc7
     int ret = -1;
99cbc7
-    virDomainRedirdevDefPtr tmpRedirdevDef;
99cbc7
+    virDomainRedirdevDefPtr redirdev;
99cbc7
     ssize_t idx;
99cbc7
 
99cbc7
-    if ((idx = virDomainRedirdevDefFind(vm->def, dev)) < 0) {
99cbc7
+    if ((idx = virDomainRedirdevDefFind(vm->def, match)) < 0) {
99cbc7
         virReportError(VIR_ERR_OPERATION_INVALID, "%s",
99cbc7
                        _("no matching redirdev was not found"));
99cbc7
         return -1;
99cbc7
     }
99cbc7
 
99cbc7
-    tmpRedirdevDef = vm->def->redirdevs[idx];
99cbc7
+    *detach = redirdev = vm->def->redirdevs[idx];
99cbc7
 
99cbc7
-    if (!tmpRedirdevDef->info.alias) {
99cbc7
+    if (!redirdev->info.alias) {
99cbc7
         virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
99cbc7
                        _("alias not set for redirdev device"));
99cbc7
         return -1;
99cbc7
     }
99cbc7
 
99cbc7
     if (!async)
99cbc7
-        qemuDomainMarkDeviceForRemoval(vm, &tmpRedirdevDef->info);
99cbc7
+        qemuDomainMarkDeviceForRemoval(vm, &redirdev->info);
99cbc7
 
99cbc7
-    if (qemuDomainDeleteDevice(vm, tmpRedirdevDef->info.alias) < 0)
99cbc7
+    if (qemuDomainDeleteDevice(vm, redirdev->info.alias) < 0)
99cbc7
         goto cleanup;
99cbc7
 
99cbc7
     if (async) {
99cbc7
         ret = 0;
99cbc7
     } else {
99cbc7
         if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
99cbc7
-            ret = qemuDomainRemoveRedirdevDevice(driver, vm, tmpRedirdevDef);
99cbc7
+            ret = qemuDomainRemoveRedirdevDevice(driver, vm, redirdev);
99cbc7
     }
99cbc7
 
99cbc7
  cleanup:
99cbc7
@@ -5320,53 +5325,54 @@ qemuDomainDetachRedirdevDevice(virQEMUDriverPtr driver,
99cbc7
 
99cbc7
 
99cbc7
 static int
99cbc7
-qemuDomainDetachNetDevice(virQEMUDriverPtr driver,
99cbc7
-                          virDomainObjPtr vm,
99cbc7
-                          virDomainDeviceDefPtr dev,
99cbc7
-                          bool async)
99cbc7
+qemuDomainDetachPrepNet(virQEMUDriverPtr driver,
99cbc7
+                        virDomainObjPtr vm,
99cbc7
+                        virDomainNetDefPtr match,
99cbc7
+                        virDomainNetDefPtr *detach,
99cbc7
+                        bool async)
99cbc7
 {
99cbc7
     int detachidx, ret = -1;
99cbc7
-    virDomainNetDefPtr detach = NULL;
99cbc7
+    virDomainNetDefPtr net = NULL;
99cbc7
 
99cbc7
-    if ((detachidx = virDomainNetFindIdx(vm->def, dev->data.net)) < 0)
99cbc7
+    if ((detachidx = virDomainNetFindIdx(vm->def, match)) < 0)
99cbc7
         goto cleanup;
99cbc7
 
99cbc7
-    detach = vm->def->nets[detachidx];
99cbc7
+    *detach = net = vm->def->nets[detachidx];
99cbc7
 
99cbc7
-    if (qemuIsMultiFunctionDevice(vm->def, &detach->info)) {
99cbc7
+    if (qemuIsMultiFunctionDevice(vm->def, &net->info)) {
99cbc7
         virReportError(VIR_ERR_OPERATION_FAILED,
99cbc7
                        _("cannot hot unplug multifunction PCI device: %s"),
99cbc7
-                       detach->ifname);
99cbc7
+                       net->ifname);
99cbc7
         goto cleanup;
99cbc7
     }
99cbc7
 
99cbc7
-    if (!detach->info.alias) {
99cbc7
-        if (qemuAssignDeviceNetAlias(vm->def, detach, -1) < 0)
99cbc7
+    if (!net->info.alias) {
99cbc7
+        if (qemuAssignDeviceNetAlias(vm->def, net, -1) < 0)
99cbc7
             goto cleanup;
99cbc7
     }
99cbc7
 
99cbc7
-    if (virDomainNetGetActualBandwidth(detach) &&
99cbc7
-        virNetDevSupportBandwidth(virDomainNetGetActualType(detach)) &&
99cbc7
-        virNetDevBandwidthClear(detach->ifname) < 0)
99cbc7
+    if (virDomainNetGetActualBandwidth(net) &&
99cbc7
+        virNetDevSupportBandwidth(virDomainNetGetActualType(net)) &&
99cbc7
+        virNetDevBandwidthClear(net->ifname) < 0)
99cbc7
         VIR_WARN("cannot clear bandwidth setting for device : %s",
99cbc7
-                 detach->ifname);
99cbc7
+                 net->ifname);
99cbc7
 
99cbc7
     /* deactivate the tap/macvtap device on the host, which could also
99cbc7
      * affect the parent device (e.g. macvtap passthrough mode sets
99cbc7
      * the parent device offline)
99cbc7
      */
99cbc7
-    ignore_value(qemuInterfaceStopDevice(detach));
99cbc7
+    ignore_value(qemuInterfaceStopDevice(net));
99cbc7
 
99cbc7
     if (!async)
99cbc7
-        qemuDomainMarkDeviceForRemoval(vm, &detach->info);
99cbc7
+        qemuDomainMarkDeviceForRemoval(vm, &net->info);
99cbc7
 
99cbc7
-    if (qemuDomainDeleteDevice(vm, detach->info.alias) < 0) {
99cbc7
+    if (qemuDomainDeleteDevice(vm, net->info.alias) < 0) {
99cbc7
         if (virDomainObjIsActive(vm)) {
99cbc7
             /* the audit message has a different format for hostdev network devices */
99cbc7
-            if (virDomainNetGetActualType(detach) == VIR_DOMAIN_NET_TYPE_HOSTDEV)
99cbc7
-                virDomainAuditHostdev(vm, virDomainNetGetActualHostdev(detach), "detach", false);
99cbc7
+            if (virDomainNetGetActualType(net) == VIR_DOMAIN_NET_TYPE_HOSTDEV)
99cbc7
+                virDomainAuditHostdev(vm, virDomainNetGetActualHostdev(net), "detach", false);
99cbc7
             else
99cbc7
-                virDomainAuditNet(vm, detach, NULL, "detach", false);
99cbc7
+                virDomainAuditNet(vm, net, NULL, "detach", false);
99cbc7
         }
99cbc7
         goto cleanup;
99cbc7
     }
99cbc7
@@ -5375,7 +5381,7 @@ qemuDomainDetachNetDevice(virQEMUDriverPtr driver,
99cbc7
         ret = 0;
99cbc7
     } else {
99cbc7
         if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
99cbc7
-            ret = qemuDomainRemoveNetDevice(driver, vm, detach);
99cbc7
+            ret = qemuDomainRemoveNetDevice(driver, vm, net);
99cbc7
     }
99cbc7
 
99cbc7
  cleanup:
99cbc7
@@ -5444,42 +5450,43 @@ qemuDomainDetachChrDevice(virQEMUDriverPtr driver,
99cbc7
 
99cbc7
 
99cbc7
 static int
99cbc7
-qemuDomainDetachRNGDevice(virQEMUDriverPtr driver,
99cbc7
-                          virDomainObjPtr vm,
99cbc7
-                          virDomainRNGDefPtr rng,
99cbc7
-                          bool async)
99cbc7
+qemuDomainDetachPrepRNG(virQEMUDriverPtr driver,
99cbc7
+                        virDomainObjPtr vm,
99cbc7
+                        virDomainRNGDefPtr match,
99cbc7
+                        virDomainRNGDefPtr *detach,
99cbc7
+                        bool async)
99cbc7
 {
99cbc7
     ssize_t idx;
99cbc7
-    virDomainRNGDefPtr tmpRNG;
99cbc7
+    virDomainRNGDefPtr rng;
99cbc7
     int ret = -1;
99cbc7
 
99cbc7
-    if ((idx = virDomainRNGFind(vm->def, rng)) < 0) {
99cbc7
+    if ((idx = virDomainRNGFind(vm->def, match)) < 0) {
99cbc7
         virReportError(VIR_ERR_DEVICE_MISSING,
99cbc7
                        _("model '%s' RNG device not present "
99cbc7
                          "in domain configuration"),
99cbc7
-                       virDomainRNGBackendTypeToString(rng->model));
99cbc7
+                       virDomainRNGBackendTypeToString(match->model));
99cbc7
         return -1;
99cbc7
     }
99cbc7
 
99cbc7
-    tmpRNG = vm->def->rngs[idx];
99cbc7
+    *detach = rng = vm->def->rngs[idx];
99cbc7
 
99cbc7
-    if (!tmpRNG->info.alias) {
99cbc7
+    if (!rng->info.alias) {
99cbc7
         virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
99cbc7
                        _("alias not set for RNG device"));
99cbc7
         return -1;
99cbc7
     }
99cbc7
 
99cbc7
     if (!async)
99cbc7
-        qemuDomainMarkDeviceForRemoval(vm, &tmpRNG->info);
99cbc7
+        qemuDomainMarkDeviceForRemoval(vm, &rng->info);
99cbc7
 
99cbc7
-    if (qemuDomainDeleteDevice(vm, tmpRNG->info.alias) < 0)
99cbc7
+    if (qemuDomainDeleteDevice(vm, rng->info.alias) < 0)
99cbc7
         goto cleanup;
99cbc7
 
99cbc7
     if (async) {
99cbc7
         ret = 0;
99cbc7
     } else {
99cbc7
         if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
99cbc7
-            ret = qemuDomainRemoveRNGDevice(driver, vm, tmpRNG);
99cbc7
+            ret = qemuDomainRemoveRNGDevice(driver, vm, rng);
99cbc7
     }
99cbc7
 
99cbc7
  cleanup:
99cbc7
@@ -5490,26 +5497,27 @@ qemuDomainDetachRNGDevice(virQEMUDriverPtr driver,
99cbc7
 
99cbc7
 
99cbc7
 static int
99cbc7
-qemuDomainDetachMemoryDevice(virQEMUDriverPtr driver,
99cbc7
-                             virDomainObjPtr vm,
99cbc7
-                             virDomainMemoryDefPtr memdef,
99cbc7
-                             bool async)
99cbc7
+qemuDomainDetachPrepMemory(virQEMUDriverPtr driver,
99cbc7
+                           virDomainObjPtr vm,
99cbc7
+                           virDomainMemoryDefPtr match,
99cbc7
+                           virDomainMemoryDefPtr *detach,
99cbc7
+                           bool async)
99cbc7
 {
99cbc7
     virDomainMemoryDefPtr mem;
99cbc7
     int idx;
99cbc7
     int ret = -1;
99cbc7
 
99cbc7
-    qemuDomainMemoryDeviceAlignSize(vm->def, memdef);
99cbc7
+    qemuDomainMemoryDeviceAlignSize(vm->def, match);
99cbc7
 
99cbc7
-    if ((idx = virDomainMemoryFindByDef(vm->def, memdef)) < 0) {
99cbc7
+    if ((idx = virDomainMemoryFindByDef(vm->def, match)) < 0) {
99cbc7
         virReportError(VIR_ERR_DEVICE_MISSING,
99cbc7
                        _("model '%s' memory device not present "
99cbc7
                          "in the domain configuration"),
99cbc7
-                       virDomainMemoryModelTypeToString(memdef->model));
99cbc7
+                       virDomainMemoryModelTypeToString(match->model));
99cbc7
         return -1;
99cbc7
     }
99cbc7
 
99cbc7
-    mem = vm->def->mems[idx];
99cbc7
+    *detach = mem = vm->def->mems[idx];
99cbc7
 
99cbc7
     if (!mem->info.alias) {
99cbc7
         virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
99cbc7
@@ -5538,20 +5546,21 @@ qemuDomainDetachMemoryDevice(virQEMUDriverPtr driver,
99cbc7
 
99cbc7
 
99cbc7
 static int
99cbc7
-qemuDomainDetachInputDevice(virDomainObjPtr vm,
99cbc7
-                            virDomainInputDefPtr def,
99cbc7
-                            bool async)
99cbc7
+qemuDomainDetachPrepInput(virDomainObjPtr vm,
99cbc7
+                          virDomainInputDefPtr match,
99cbc7
+                          virDomainInputDefPtr *detach,
99cbc7
+                          bool async)
99cbc7
 {
99cbc7
     virDomainInputDefPtr input;
99cbc7
     int ret = -1;
99cbc7
     int idx;
99cbc7
 
99cbc7
-    if ((idx = virDomainInputDefFind(vm->def, def)) < 0) {
99cbc7
+    if ((idx = virDomainInputDefFind(vm->def, match)) < 0) {
99cbc7
         virReportError(VIR_ERR_OPERATION_FAILED, "%s",
99cbc7
                        _("matching input device not found"));
99cbc7
         return -1;
99cbc7
     }
99cbc7
-    input = vm->def->inputs[idx];
99cbc7
+    *detach = input = vm->def->inputs[idx];
99cbc7
 
99cbc7
     switch ((virDomainInputBus) input->bus) {
99cbc7
     case VIR_DOMAIN_INPUT_BUS_PS2:
99cbc7
@@ -5589,16 +5598,18 @@ qemuDomainDetachInputDevice(virDomainObjPtr vm,
99cbc7
 
99cbc7
 
99cbc7
 static int
99cbc7
-qemuDomainDetachVsockDevice(virDomainObjPtr vm,
99cbc7
-                            virDomainVsockDefPtr dev,
99cbc7
-                            bool async)
99cbc7
+qemuDomainDetachPrepVsock(virDomainObjPtr vm,
99cbc7
+                          virDomainVsockDefPtr match,
99cbc7
+                          virDomainVsockDefPtr *detach,
99cbc7
+                          bool async)
99cbc7
 {
99cbc7
-    virDomainVsockDefPtr vsock = vm->def->vsock;
99cbc7
+    virDomainVsockDefPtr vsock;
99cbc7
     int ret = -1;
99cbc7
 
99cbc7
 
99cbc7
+    *detach = vsock = vm->def->vsock;
99cbc7
     if (!vsock ||
99cbc7
-        !virDomainVsockDefEquals(dev, vsock)) {
99cbc7
+        !virDomainVsockDefEquals(match, vsock)) {
99cbc7
         virReportError(VIR_ERR_OPERATION_FAILED, "%s",
99cbc7
                        _("matching vsock device not found"));
99cbc7
         return -1;
99cbc7
@@ -5654,6 +5665,7 @@ qemuDomainDetachDeviceLive(virDomainObjPtr vm,
99cbc7
                            virQEMUDriverPtr driver,
99cbc7
                            bool async)
99cbc7
 {
99cbc7
+    virDomainDeviceDef detach = { .type = match->type };
99cbc7
     int ret = -1;
99cbc7
 
99cbc7
     switch ((virDomainDeviceType)match->type) {
99cbc7
@@ -5676,38 +5688,70 @@ qemuDomainDetachDeviceLive(virDomainObjPtr vm,
99cbc7
          * assure it is okay to detach the device.
99cbc7
          */
99cbc7
     case VIR_DOMAIN_DEVICE_DISK:
99cbc7
-        ret = qemuDomainDetachDeviceDiskLive(driver, vm, match, async);
99cbc7
+        if (qemuDomainDetachPrepDisk(driver, vm, match->data.disk,
99cbc7
+                                     &detach.data.disk, async) < 0) {
99cbc7
+            return -1;
99cbc7
+        }
99cbc7
         break;
99cbc7
     case VIR_DOMAIN_DEVICE_CONTROLLER:
99cbc7
-        ret = qemuDomainDetachControllerDevice(driver, vm, match, async);
99cbc7
+        if (qemuDomainDetachPrepController(driver, vm, match->data.controller,
99cbc7
+                                           &detach.data.controller, async) < 0) {
99cbc7
+            return -1;
99cbc7
+        }
99cbc7
         break;
99cbc7
     case VIR_DOMAIN_DEVICE_NET:
99cbc7
-        ret = qemuDomainDetachNetDevice(driver, vm, match, async);
99cbc7
+        if (qemuDomainDetachPrepNet(driver, vm, match->data.net,
99cbc7
+                                    &detach.data.net, async) < 0) {
99cbc7
+            return -1;
99cbc7
+        }
99cbc7
         break;
99cbc7
     case VIR_DOMAIN_DEVICE_HOSTDEV:
99cbc7
-        ret = qemuDomainDetachHostDevice(driver, vm, match, async);
99cbc7
+        if (qemuDomainDetachPrepHostdev(driver, vm, match->data.hostdev,
99cbc7
+                                        &detach.data.hostdev, async) < 0) {
99cbc7
+            return -1;
99cbc7
+        }
99cbc7
         break;
99cbc7
     case VIR_DOMAIN_DEVICE_RNG:
99cbc7
-        ret = qemuDomainDetachRNGDevice(driver, vm, match->data.rng, async);
99cbc7
+        if (qemuDomainDetachPrepRNG(driver, vm, match->data.rng,
99cbc7
+                                    &detach.data.rng, async) < 0) {
99cbc7
+            return -1;
99cbc7
+        }
99cbc7
         break;
99cbc7
     case VIR_DOMAIN_DEVICE_MEMORY:
99cbc7
-        ret = qemuDomainDetachMemoryDevice(driver, vm, match->data.memory, async);
99cbc7
+        if (qemuDomainDetachPrepMemory(driver, vm, match->data.memory,
99cbc7
+                                       &detach.data.memory, async) < 0) {
99cbc7
+            return -1;
99cbc7
+        }
99cbc7
         break;
99cbc7
     case VIR_DOMAIN_DEVICE_SHMEM:
99cbc7
-        ret = qemuDomainDetachShmemDevice(driver, vm, match->data.shmem, async);
99cbc7
+        if (qemuDomainDetachPrepShmem(driver, vm, match->data.shmem,
99cbc7
+                                      &detach.data.shmem, async) < 0) {
99cbc7
+            return -1;
99cbc7
+        }
99cbc7
         break;
99cbc7
     case VIR_DOMAIN_DEVICE_WATCHDOG:
99cbc7
-        ret = qemuDomainDetachWatchdog(driver, vm, match->data.watchdog, async);
99cbc7
+        if (qemuDomainDetachPrepWatchdog(driver, vm, match->data.watchdog,
99cbc7
+                                         &detach.data.watchdog, async) < 0) {
99cbc7
+            return -1;
99cbc7
+        }
99cbc7
         break;
99cbc7
     case VIR_DOMAIN_DEVICE_INPUT:
99cbc7
-        ret = qemuDomainDetachInputDevice(vm, match->data.input, async);
99cbc7
+        if (qemuDomainDetachPrepInput(vm, match->data.input,
99cbc7
+                                      &detach.data.input, async) < 0) {
99cbc7
+            return -1;
99cbc7
+        }
99cbc7
         break;
99cbc7
     case VIR_DOMAIN_DEVICE_REDIRDEV:
99cbc7
-        ret = qemuDomainDetachRedirdevDevice(driver, vm, match->data.redirdev, async);
99cbc7
+        if (qemuDomainDetachPrepRedirdev(driver, vm, match->data.redirdev,
99cbc7
+                                         &detach.data.redirdev, async) < 0) {
99cbc7
+            return -1;
99cbc7
+        }
99cbc7
         break;
99cbc7
-
99cbc7
     case VIR_DOMAIN_DEVICE_VSOCK:
99cbc7
-        ret = qemuDomainDetachVsockDevice(vm, match->data.vsock, async);
99cbc7
+        if (qemuDomainDetachPrepVsock(vm, match->data.vsock,
99cbc7
+                                      &detach.data.vsock, async) < 0) {
99cbc7
+            return -1;
99cbc7
+        }
99cbc7
         break;
99cbc7
 
99cbc7
     case VIR_DOMAIN_DEVICE_FS:
99cbc7
@@ -5729,6 +5773,8 @@ qemuDomainDetachDeviceLive(virDomainObjPtr vm,
99cbc7
         return -1;
99cbc7
     }
99cbc7
 
99cbc7
+    ret = 0;
99cbc7
+
99cbc7
     return ret;
99cbc7
 }
99cbc7
 
99cbc7
-- 
99cbc7
2.21.0
99cbc7