render / rpms / libvirt

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