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

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