Blame SOURCES/libvirt-qemu-prevent-attempts-to-detach-a-device-on-a-controller-with-hotplug-off.patch

a41c76
From 176ca1e59775810524a2375927725fbe419d9e5c Mon Sep 17 00:00:00 2001
a41c76
Message-Id: <176ca1e59775810524a2375927725fbe419d9e5c@dist-git>
a41c76
From: Laine Stump <laine@redhat.com>
a41c76
Date: Mon, 18 May 2020 14:53:04 -0400
a41c76
Subject: [PATCH] qemu: prevent attempts to detach a device on a controller
a41c76
 with hotplug='off'
a41c76
a41c76
Although the original patches to support controllers with
a41c76
hotplug='off' were checking during hotplug/attach requests that the
a41c76
device was being plugged into a PCI controller that didn't have
a41c76
hotplug disabled, but I forgot to do the same for device detach (the
a41c76
main impetus for adding the feature was to prevent unplugs originating
a41c76
from within the guest, so it slipped my mind). So although the guest
a41c76
OS was ultimately unable to honor the unplug request, libvirt could
a41c76
still be used to make such a request, and since device attach/detach
a41c76
are asynchronous operations, the caller to libvirt would receive a
a41c76
success status back (the device would stubbornly/correctly remain in
a41c76
the domain status XML however)
a41c76
a41c76
This patch remedies that, by looking at the controller for the device
a41c76
in the detach request, and immediately failing the operation if that
a41c76
controller has hotplug=off.
a41c76
a41c76
Signed-off-by: Laine Stump <laine@redhat.com>
a41c76
Reviewed-by: Erik Skultety <eskultet@redhat.com>
a41c76
(cherry picked from commit c0e04c2e62957fe872b5bc3d89d5b1d95f10450c)
a41c76
a41c76
https://bugzilla.redhat.com/1802592
a41c76
Signed-off-by: Laine Stump <laine@redhat.com>
a41c76
Message-Id: <20200518185304.188810-1-laine@redhat.com>
a41c76
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
a41c76
---
a41c76
 src/qemu/qemu_hotplug.c | 30 ++++++++++++++++++++++++++++++
a41c76
 1 file changed, 30 insertions(+)
a41c76
a41c76
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
a41c76
index 3ccc01f0b7..29e1a41f9d 100644
a41c76
--- a/src/qemu/qemu_hotplug.c
a41c76
+++ b/src/qemu/qemu_hotplug.c
a41c76
@@ -5846,6 +5846,36 @@ qemuDomainDetachDeviceLive(virDomainObjPtr vm,
a41c76
         return -1;
a41c76
     }
a41c76
 
a41c76
+    if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
a41c76
+
a41c76
+        virDomainControllerDefPtr controller;
a41c76
+        int controllerIdx = virDomainControllerFind(vm->def,
a41c76
+                                                    VIR_DOMAIN_CONTROLLER_TYPE_PCI,
a41c76
+                                                    info->addr.pci.bus);
a41c76
+        if (controllerIdx < 0) {
a41c76
+            virReportError(VIR_ERR_OPERATION_FAILED,
a41c76
+                           _("cannot hot unplug %s device with PCI guest address: "
a41c76
+                             VIR_PCI_DEVICE_ADDRESS_FMT
a41c76
+                             " - controller not found"),
a41c76
+                           virDomainDeviceTypeToString(detach.type),
a41c76
+                           info->addr.pci.domain, info->addr.pci.bus,
a41c76
+                           info->addr.pci.slot, info->addr.pci.function);
a41c76
+            return -1;
a41c76
+        }
a41c76
+
a41c76
+        controller = vm->def->controllers[controllerIdx];
a41c76
+        if (controller->opts.pciopts.hotplug == VIR_TRISTATE_SWITCH_OFF) {
a41c76
+            virReportError(VIR_ERR_OPERATION_FAILED,
a41c76
+                           _("cannot hot unplug %s device with PCI guest address: "
a41c76
+                             VIR_PCI_DEVICE_ADDRESS_FMT
a41c76
+                             " - not allowed by controller"),
a41c76
+                           virDomainDeviceTypeToString(detach.type),
a41c76
+                           info->addr.pci.domain, info->addr.pci.bus,
a41c76
+                           info->addr.pci.slot, info->addr.pci.function);
a41c76
+            return -1;
a41c76
+        }
a41c76
+    }
a41c76
+
a41c76
     /*
a41c76
      * Issue the qemu monitor command to delete the device (based on
a41c76
      * its alias), and optionally wait a short time in case the
a41c76
-- 
a41c76
2.26.2
a41c76