Blame SOURCES/libvirt-qemu_hotplug-eliminate-multiple-identical-qemuDomainDetachHost-Device-functions.patch

99cbc7
From 004c83f00eca921bded4786f24e962174dc71c05 Mon Sep 17 00:00:00 2001
99cbc7
Message-Id: <004c83f00eca921bded4786f24e962174dc71c05@dist-git>
99cbc7
From: Laine Stump <laine@laine.org>
99cbc7
Date: Thu, 11 Apr 2019 15:14:32 -0400
99cbc7
Subject: [PATCH] qemu_hotplug: eliminate multiple identical
99cbc7
 qemuDomainDetachHost*Device() functions
99cbc7
MIME-Version: 1.0
99cbc7
Content-Type: text/plain; charset=UTF-8
99cbc7
Content-Transfer-Encoding: 8bit
99cbc7
99cbc7
There are separate Detach functions for PCI, USB, SCSI, Vhost, and
99cbc7
Mediated hostdevs, but the functions are all 100% the same code,
99cbc7
except that the PCI function checks for the guest side of the device
99cbc7
being a PCI Multifunction device, while the other 4 check that the
99cbc7
device's alias != NULL.
99cbc7
99cbc7
The check for multifunction PCI devices should be done for *all*
99cbc7
devices that are connected to the PCI bus in the guest, not just PCI
99cbc7
hostdevs, and qemuIsMultiFunctionDevice() conveniently returns false
99cbc7
if the queried device doesn't connect with PCI, so it is safe to make
99cbc7
this check for all hostdev devices. (It also needs to be done for many
99cbc7
other device types, but that will be addressed in a future patch).
99cbc7
99cbc7
Likewise, since all hostdevs are detached by calling
99cbc7
qemuDomainDeleteDevice(), which requires the device's alias, checking
99cbc7
for a valid alias is a reasonable thing for PCI hostdevs too.
99cbc7
99cbc7
Signed-off-by: Laine Stump <laine@laine.org>
99cbc7
ACKed-by: Peter Krempa <pkrempa@redhat.com>
99cbc7
Reviewed-by: Ján Tomko <jtomko@redhat.com>
99cbc7
(cherry picked from commit 287415e219fa2e477ae011ece275ab15a4be1d73)
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-21-laine@redhat.com>
99cbc7
Acked-by: Michal Privoznik <mprivozn@redhat.com>
99cbc7
---
99cbc7
 src/qemu/qemu_hotplug.c | 134 +++++++++-------------------------------
99cbc7
 1 file changed, 29 insertions(+), 105 deletions(-)
99cbc7
99cbc7
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
99cbc7
index 2bfb5f8d54..b6fcaadd55 100644
99cbc7
--- a/src/qemu/qemu_hotplug.c
99cbc7
+++ b/src/qemu/qemu_hotplug.c
99cbc7
@@ -4947,96 +4947,6 @@ int qemuDomainDetachControllerDevice(virQEMUDriverPtr driver,
99cbc7
     return ret;
99cbc7
 }
99cbc7
 
99cbc7
-static int
99cbc7
-qemuDomainDetachHostPCIDevice(virDomainObjPtr vm,
99cbc7
-                              virDomainHostdevDefPtr detach,
99cbc7
-                              bool async)
99cbc7
-{
99cbc7
-    virDomainHostdevSubsysPCIPtr pcisrc = &detach->source.subsys.u.pci;
99cbc7
-
99cbc7
-    if (qemuIsMultiFunctionDevice(vm->def, detach->info)) {
99cbc7
-        virReportError(VIR_ERR_OPERATION_FAILED,
99cbc7
-                       _("cannot hot unplug multifunction PCI device: %.4x:%.2x:%.2x.%.1x"),
99cbc7
-                       pcisrc->addr.domain, pcisrc->addr.bus,
99cbc7
-                       pcisrc->addr.slot, pcisrc->addr.function);
99cbc7
-        return -1;
99cbc7
-    }
99cbc7
-
99cbc7
-    if (!async)
99cbc7
-        qemuDomainMarkDeviceForRemoval(vm, detach->info);
99cbc7
-
99cbc7
-    return qemuDomainDeleteDevice(vm, detach->info->alias);
99cbc7
-}
99cbc7
-
99cbc7
-static int
99cbc7
-qemuDomainDetachHostUSBDevice(virDomainObjPtr vm,
99cbc7
-                              virDomainHostdevDefPtr detach,
99cbc7
-                              bool async)
99cbc7
-{
99cbc7
-    if (!detach->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
-
99cbc7
-    return qemuDomainDeleteDevice(vm, detach->info->alias);
99cbc7
-}
99cbc7
-
99cbc7
-static int
99cbc7
-qemuDomainDetachHostSCSIDevice(virDomainObjPtr vm,
99cbc7
-                               virDomainHostdevDefPtr detach,
99cbc7
-                               bool async)
99cbc7
-{
99cbc7
-    if (!detach->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
-
99cbc7
-    return qemuDomainDeleteDevice(vm, detach->info->alias);
99cbc7
-}
99cbc7
-
99cbc7
-static int
99cbc7
-qemuDomainDetachSCSIVHostDevice(virDomainObjPtr vm,
99cbc7
-                                virDomainHostdevDefPtr detach,
99cbc7
-                                bool async)
99cbc7
-{
99cbc7
-    if (!detach->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
-
99cbc7
-    return qemuDomainDeleteDevice(vm, detach->info->alias);
99cbc7
-}
99cbc7
-
99cbc7
-
99cbc7
-static int
99cbc7
-qemuDomainDetachMediatedDevice(virDomainObjPtr vm,
99cbc7
-                               virDomainHostdevDefPtr detach,
99cbc7
-                               bool async)
99cbc7
-{
99cbc7
-    if (!detach->info->alias) {
99cbc7
-        virReportError(VIR_ERR_OPERATION_FAILED, "%s",
99cbc7
-                       _("device cannot be detached without a device alias"));
99cbc7
-        return -1;
99cbc7
-    }
99cbc7
-
99cbc7
-    if (!async)
99cbc7
-        qemuDomainMarkDeviceForRemoval(vm, detach->info);
99cbc7
-
99cbc7
-    return qemuDomainDeleteDevice(vm, detach->info->alias);
99cbc7
-}
99cbc7
-
99cbc7
 
99cbc7
 static int
99cbc7
 qemuDomainDetachThisHostDevice(virQEMUDriverPtr driver,
99cbc7
@@ -5046,25 +4956,30 @@ qemuDomainDetachThisHostDevice(virQEMUDriverPtr driver,
99cbc7
 {
99cbc7
     int ret = -1;
99cbc7
 
99cbc7
-    if (qemuAssignDeviceHostdevAlias(vm->def, &detach->info->alias, -1) < 0)
99cbc7
+    if (qemuIsMultiFunctionDevice(vm->def, detach->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
         return -1;
99cbc7
+    }
99cbc7
+
99cbc7
+    if (!detach->info->alias) {
99cbc7
+        virReportError(VIR_ERR_OPERATION_FAILED,
99cbc7
+                       "%s", _("device cannot be detached without a device alias"));
99cbc7
+        return -1;
99cbc7
+    }
99cbc7
 
99cbc7
     switch (detach->source.subsys.type) {
99cbc7
     case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
99cbc7
-        ret = qemuDomainDetachHostPCIDevice(vm, detach, async);
99cbc7
-        break;
99cbc7
     case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
99cbc7
-        ret = qemuDomainDetachHostUSBDevice(vm, detach, async);
99cbc7
-        break;
99cbc7
     case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI:
99cbc7
-        ret = qemuDomainDetachHostSCSIDevice(vm, detach, async);
99cbc7
-        break;
99cbc7
     case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST:
99cbc7
-        ret = qemuDomainDetachSCSIVHostDevice(vm, detach, async);
99cbc7
-        break;
99cbc7
     case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV:
99cbc7
-        ret = qemuDomainDetachMediatedDevice(vm, detach, async);
99cbc7
-        break;
99cbc7
+       /* we support detach of all these types of hostdev */
99cbc7
+       break;
99cbc7
+
99cbc7
     default:
99cbc7
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
99cbc7
                        _("hot unplug is not supported for hostdev subsys type '%s'"),
99cbc7
@@ -5072,14 +4987,23 @@ qemuDomainDetachThisHostDevice(virQEMUDriverPtr driver,
99cbc7
         return -1;
99cbc7
     }
99cbc7
 
99cbc7
-    if (ret < 0) {
99cbc7
+    if (!async)
99cbc7
+        qemuDomainMarkDeviceForRemoval(vm, detach->info);
99cbc7
+
99cbc7
+    if (qemuDomainDeleteDevice(vm, detach->info->alias) < 0) {
99cbc7
         if (virDomainObjIsActive(vm))
99cbc7
             virDomainAuditHostdev(vm, detach, "detach", false);
99cbc7
-    } else if (!async &&
99cbc7
-               (ret = qemuDomainWaitForDeviceRemoval(vm)) == 1) {
99cbc7
-        ret = qemuDomainRemoveHostDevice(driver, vm, detach);
99cbc7
+        goto cleanup;
99cbc7
     }
99cbc7
 
99cbc7
+    if (async) {
99cbc7
+        ret = 0;
99cbc7
+    } else {
99cbc7
+        if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
99cbc7
+            ret = qemuDomainRemoveHostDevice(driver, vm, detach);
99cbc7
+    }
99cbc7
+
99cbc7
+ cleanup:
99cbc7
     if (!async)
99cbc7
         qemuDomainResetDeviceRemoval(vm);
99cbc7
 
99cbc7
-- 
99cbc7
2.21.0
99cbc7