Blob Blame History Raw
From 8af5fddcda3fe76db25ea4172c7f21a9d19178a0 Mon Sep 17 00:00:00 2001
Message-Id: <8af5fddcda3fe76db25ea4172c7f21a9d19178a0.1386932210.git.jdenemar@redhat.com>
From: Cole Robinson <crobinso@redhat.com>
Date: Mon, 9 Dec 2013 20:12:43 +0100
Subject: [PATCH] qemu: hotplug: Only label hostdev after checking device
 conflicts

https://bugzilla.redhat.com/show_bug.cgi?id=1025108

Similar to what Jiri did for cgroup setup/teardown in 05e149f94, push
it all into the device handler functions so we can do the necessary prep
work before claiming the device.

This also fixes hotplugging USB devices by product/vendor (virt-manager's
default behavior):

https://bugzilla.redhat.com/show_bug.cgi?id=1016511
(cherry picked from commit ee414b5d6d1601bde8440a9de050c02447bbd3bf)

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
 src/qemu/qemu_hotplug.c | 42 ++++++++++++++++++++++++++++++++++--------
 1 file changed, 34 insertions(+), 8 deletions(-)

diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index a60c08d..f2b6dba 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1013,6 +1013,7 @@ int qemuDomainAttachHostPciDevice(virQEMUDriverPtr driver,
     char *configfd_name = NULL;
     bool releaseaddr = false;
     bool teardowncgroup = false;
+    bool teardownlabel = false;
     int backend = hostdev->source.subsys.u.pci.backend;
 
     if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs+1) < 0)
@@ -1053,6 +1054,11 @@ int qemuDomainAttachHostPciDevice(virQEMUDriverPtr driver,
         goto error;
     teardowncgroup = true;
 
+    if (virSecurityManagerSetHostdevLabel(driver->securityManager,
+                                          vm->def, hostdev, NULL) < 0)
+        goto error;
+    teardownlabel = true;
+
     if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
         if (qemuAssignDeviceHostdevAlias(vm->def, hostdev, -1) < 0)
             goto error;
@@ -1110,6 +1116,10 @@ int qemuDomainAttachHostPciDevice(virQEMUDriverPtr driver,
 error:
     if (teardowncgroup && qemuTeardownHostdevCgroup(vm, hostdev) < 0)
         VIR_WARN("Unable to remove host device cgroup ACL on hotplug fail");
+    if (teardownlabel &&
+        virSecurityManagerRestoreHostdevLabel(driver->securityManager,
+                                              vm->def, hostdev, NULL) < 0)
+        VIR_WARN("Unable to restore host device labelling on hotplug fail");
 
     if (releaseaddr)
         qemuDomainReleaseDeviceAddress(vm, hostdev->info, NULL);
@@ -1304,6 +1314,7 @@ int qemuDomainAttachHostUsbDevice(virQEMUDriverPtr driver,
     char *devstr = NULL;
     bool added = false;
     bool teardowncgroup = false;
+    bool teardownlabel = false;
     int ret = -1;
 
     if (qemuFindHostdevUSBDevice(hostdev, true, &usb) < 0)
@@ -1325,6 +1336,11 @@ int qemuDomainAttachHostUsbDevice(virQEMUDriverPtr driver,
         goto cleanup;
     teardowncgroup = true;
 
+    if (virSecurityManagerSetHostdevLabel(driver->securityManager,
+                                          vm->def, hostdev, NULL) < 0)
+        goto cleanup;
+    teardownlabel = true;
+
     if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
         if (qemuAssignDeviceHostdevAlias(vm->def, hostdev, -1) < 0)
             goto cleanup;
@@ -1351,10 +1367,14 @@ int qemuDomainAttachHostUsbDevice(virQEMUDriverPtr driver,
 
     ret = 0;
 cleanup:
-    if (ret < 0 &&
-        teardowncgroup &&
-        qemuTeardownHostdevCgroup(vm, hostdev) < 0)
-        VIR_WARN("Unable to remove host device cgroup ACL on hotplug fail");
+    if (ret < 0) {
+        if (teardowncgroup && qemuTeardownHostdevCgroup(vm, hostdev) < 0)
+            VIR_WARN("Unable to remove host device cgroup ACL on hotplug fail");
+        if (teardownlabel &&
+            virSecurityManagerRestoreHostdevLabel(driver->securityManager,
+                                                  vm->def, hostdev, NULL) < 0)
+            VIR_WARN("Unable to restore host device labelling on hotplug fail");
+    }
     if (added)
         virUSBDeviceListSteal(driver->activeUsbHostdevs, usb);
     virUSBDeviceFree(usb);
@@ -1373,6 +1393,7 @@ qemuDomainAttachHostScsiDevice(virQEMUDriverPtr driver,
     char *devstr = NULL;
     char *drvstr = NULL;
     bool teardowncgroup = false;
+    bool teardownlabel = false;
 
     if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DRIVE) ||
         !virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) ||
@@ -1397,6 +1418,11 @@ qemuDomainAttachHostScsiDevice(virQEMUDriverPtr driver,
         goto cleanup;
     teardowncgroup = true;
 
+    if (virSecurityManagerSetHostdevLabel(driver->securityManager,
+                                          vm->def, hostdev, NULL) < 0)
+        goto cleanup;
+    teardownlabel = true;
+
     if (qemuAssignDeviceHostdevAlias(vm->def, hostdev, -1) < 0)
         goto cleanup;
 
@@ -1438,6 +1464,10 @@ cleanup:
         qemuDomainReAttachHostScsiDevices(driver, vm->def->name, &hostdev, 1);
         if (teardowncgroup && qemuTeardownHostdevCgroup(vm, hostdev) < 0)
             VIR_WARN("Unable to remove host device cgroup ACL on hotplug fail");
+        if (teardownlabel &&
+            virSecurityManagerRestoreHostdevLabel(driver->securityManager,
+                                                  vm->def, hostdev, NULL) < 0)
+            VIR_WARN("Unable to restore host device labelling on hotplug fail");
     }
     VIR_FREE(drvstr);
     VIR_FREE(devstr);
@@ -1455,10 +1485,6 @@ int qemuDomainAttachHostDevice(virQEMUDriverPtr driver,
         return -1;
     }
 
-    if (virSecurityManagerSetHostdevLabel(driver->securityManager,
-                                          vm->def, hostdev, NULL) < 0)
-        return -1;
-
     switch (hostdev->source.subsys.type) {
     case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
         if (qemuDomainAttachHostPciDevice(driver, vm,
-- 
1.8.5.1