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

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