|
|
c401cc |
From 4d8f410cd601aa1ff3e3eb7c4787cfa3b50c932f Mon Sep 17 00:00:00 2001
|
|
|
c401cc |
Message-Id: <4d8f410cd601aa1ff3e3eb7c4787cfa3b50c932f.1385135432.git.jdenemar@redhat.com>
|
|
|
c401cc |
From: Jiri Denemark <jdenemar@redhat.com>
|
|
|
c401cc |
Date: Fri, 15 Nov 2013 15:46:39 +0100
|
|
|
c401cc |
Subject: [PATCH] qemu: Call qemuSetupHostdevCGroup later during hotplug
|
|
|
c401cc |
|
|
|
c401cc |
https://bugzilla.redhat.com/show_bug.cgi?id=1025108
|
|
|
c401cc |
|
|
|
c401cc |
So far qemuSetupHostdevCGroup was called very early during hotplug, even
|
|
|
c401cc |
before we knew the device we were about to hotplug was actually
|
|
|
c401cc |
available. By calling the function later, we make sure QEMU won't be
|
|
|
c401cc |
allowed to access devices used by other domains.
|
|
|
c401cc |
|
|
|
c401cc |
Another important effect of this change is that hopluging USB devices
|
|
|
c401cc |
specified by vendor and product (but not by their USB address) works
|
|
|
c401cc |
again. This was broken since v1.0.5-171-g7d763ac, when the call to
|
|
|
c401cc |
qemuFindHostdevUSBDevice was moved after the call to
|
|
|
c401cc |
qemuSetupHostdevCGroup, which then used an uninitialized USB address.
|
|
|
c401cc |
|
|
|
c401cc |
(cherry picked from commit 05e149f94cbd34e4c3d4e9c7f6871e13cfe03d8c)
|
|
|
c401cc |
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
|
|
|
c401cc |
---
|
|
|
c401cc |
src/qemu/qemu_hotplug.c | 36 +++++++++++++++++++++++++++---------
|
|
|
c401cc |
1 file changed, 27 insertions(+), 9 deletions(-)
|
|
|
c401cc |
|
|
|
c401cc |
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
|
|
|
c401cc |
index 4b9cc07..a60c08d 100644
|
|
|
c401cc |
--- a/src/qemu/qemu_hotplug.c
|
|
|
c401cc |
+++ b/src/qemu/qemu_hotplug.c
|
|
|
c401cc |
@@ -1012,6 +1012,7 @@ int qemuDomainAttachHostPciDevice(virQEMUDriverPtr driver,
|
|
|
c401cc |
int configfd = -1;
|
|
|
c401cc |
char *configfd_name = NULL;
|
|
|
c401cc |
bool releaseaddr = false;
|
|
|
c401cc |
+ bool teardowncgroup = false;
|
|
|
c401cc |
int backend = hostdev->source.subsys.u.pci.backend;
|
|
|
c401cc |
|
|
|
c401cc |
if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs+1) < 0)
|
|
|
c401cc |
@@ -1048,6 +1049,10 @@ int qemuDomainAttachHostPciDevice(virQEMUDriverPtr driver,
|
|
|
c401cc |
break;
|
|
|
c401cc |
}
|
|
|
c401cc |
|
|
|
c401cc |
+ if (qemuSetupHostdevCGroup(vm, hostdev) < 0)
|
|
|
c401cc |
+ goto error;
|
|
|
c401cc |
+ teardowncgroup = true;
|
|
|
c401cc |
+
|
|
|
c401cc |
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
|
|
|
c401cc |
if (qemuAssignDeviceHostdevAlias(vm->def, hostdev, -1) < 0)
|
|
|
c401cc |
goto error;
|
|
|
c401cc |
@@ -1103,6 +1108,9 @@ int qemuDomainAttachHostPciDevice(virQEMUDriverPtr driver,
|
|
|
c401cc |
return 0;
|
|
|
c401cc |
|
|
|
c401cc |
error:
|
|
|
c401cc |
+ if (teardowncgroup && qemuTeardownHostdevCgroup(vm, hostdev) < 0)
|
|
|
c401cc |
+ VIR_WARN("Unable to remove host device cgroup ACL on hotplug fail");
|
|
|
c401cc |
+
|
|
|
c401cc |
if (releaseaddr)
|
|
|
c401cc |
qemuDomainReleaseDeviceAddress(vm, hostdev->info, NULL);
|
|
|
c401cc |
|
|
|
c401cc |
@@ -1295,6 +1303,7 @@ int qemuDomainAttachHostUsbDevice(virQEMUDriverPtr driver,
|
|
|
c401cc |
virUSBDevicePtr usb = NULL;
|
|
|
c401cc |
char *devstr = NULL;
|
|
|
c401cc |
bool added = false;
|
|
|
c401cc |
+ bool teardowncgroup = false;
|
|
|
c401cc |
int ret = -1;
|
|
|
c401cc |
|
|
|
c401cc |
if (qemuFindHostdevUSBDevice(hostdev, true, &usb) < 0)
|
|
|
c401cc |
@@ -1312,6 +1321,10 @@ int qemuDomainAttachHostUsbDevice(virQEMUDriverPtr driver,
|
|
|
c401cc |
added = true;
|
|
|
c401cc |
virUSBDeviceListSteal(list, usb);
|
|
|
c401cc |
|
|
|
c401cc |
+ if (qemuSetupHostdevCGroup(vm, hostdev) < 0)
|
|
|
c401cc |
+ goto cleanup;
|
|
|
c401cc |
+ teardowncgroup = true;
|
|
|
c401cc |
+
|
|
|
c401cc |
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
|
|
|
c401cc |
if (qemuAssignDeviceHostdevAlias(vm->def, hostdev, -1) < 0)
|
|
|
c401cc |
goto cleanup;
|
|
|
c401cc |
@@ -1338,6 +1351,10 @@ int qemuDomainAttachHostUsbDevice(virQEMUDriverPtr driver,
|
|
|
c401cc |
|
|
|
c401cc |
ret = 0;
|
|
|
c401cc |
cleanup:
|
|
|
c401cc |
+ if (ret < 0 &&
|
|
|
c401cc |
+ teardowncgroup &&
|
|
|
c401cc |
+ qemuTeardownHostdevCgroup(vm, hostdev) < 0)
|
|
|
c401cc |
+ VIR_WARN("Unable to remove host device cgroup ACL on hotplug fail");
|
|
|
c401cc |
if (added)
|
|
|
c401cc |
virUSBDeviceListSteal(driver->activeUsbHostdevs, usb);
|
|
|
c401cc |
virUSBDeviceFree(usb);
|
|
|
c401cc |
@@ -1355,6 +1372,7 @@ qemuDomainAttachHostScsiDevice(virQEMUDriverPtr driver,
|
|
|
c401cc |
qemuDomainObjPrivatePtr priv = vm->privateData;
|
|
|
c401cc |
char *devstr = NULL;
|
|
|
c401cc |
char *drvstr = NULL;
|
|
|
c401cc |
+ bool teardowncgroup = false;
|
|
|
c401cc |
|
|
|
c401cc |
if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DRIVE) ||
|
|
|
c401cc |
!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) ||
|
|
|
c401cc |
@@ -1375,6 +1393,10 @@ qemuDomainAttachHostScsiDevice(virQEMUDriverPtr driver,
|
|
|
c401cc |
return -1;
|
|
|
c401cc |
}
|
|
|
c401cc |
|
|
|
c401cc |
+ if (qemuSetupHostdevCGroup(vm, hostdev) < 0)
|
|
|
c401cc |
+ goto cleanup;
|
|
|
c401cc |
+ teardowncgroup = true;
|
|
|
c401cc |
+
|
|
|
c401cc |
if (qemuAssignDeviceHostdevAlias(vm->def, hostdev, -1) < 0)
|
|
|
c401cc |
goto cleanup;
|
|
|
c401cc |
|
|
|
c401cc |
@@ -1412,8 +1434,11 @@ qemuDomainAttachHostScsiDevice(virQEMUDriverPtr driver,
|
|
|
c401cc |
|
|
|
c401cc |
ret = 0;
|
|
|
c401cc |
cleanup:
|
|
|
c401cc |
- if (ret < 0)
|
|
|
c401cc |
+ if (ret < 0) {
|
|
|
c401cc |
qemuDomainReAttachHostScsiDevices(driver, vm->def->name, &hostdev, 1);
|
|
|
c401cc |
+ if (teardowncgroup && qemuTeardownHostdevCgroup(vm, hostdev) < 0)
|
|
|
c401cc |
+ VIR_WARN("Unable to remove host device cgroup ACL on hotplug fail");
|
|
|
c401cc |
+ }
|
|
|
c401cc |
VIR_FREE(drvstr);
|
|
|
c401cc |
VIR_FREE(devstr);
|
|
|
c401cc |
return ret;
|
|
|
c401cc |
@@ -1430,12 +1455,9 @@ int qemuDomainAttachHostDevice(virQEMUDriverPtr driver,
|
|
|
c401cc |
return -1;
|
|
|
c401cc |
}
|
|
|
c401cc |
|
|
|
c401cc |
- if (qemuSetupHostdevCGroup(vm, hostdev) < 0)
|
|
|
c401cc |
- return -1;
|
|
|
c401cc |
-
|
|
|
c401cc |
if (virSecurityManagerSetHostdevLabel(driver->securityManager,
|
|
|
c401cc |
vm->def, hostdev, NULL) < 0)
|
|
|
c401cc |
- goto cleanup;
|
|
|
c401cc |
+ return -1;
|
|
|
c401cc |
|
|
|
c401cc |
switch (hostdev->source.subsys.type) {
|
|
|
c401cc |
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
|
|
|
c401cc |
@@ -1469,10 +1491,6 @@ error:
|
|
|
c401cc |
if (virSecurityManagerRestoreHostdevLabel(driver->securityManager,
|
|
|
c401cc |
vm->def, hostdev, NULL) < 0)
|
|
|
c401cc |
VIR_WARN("Unable to restore host device labelling on hotplug fail");
|
|
|
c401cc |
-
|
|
|
c401cc |
-cleanup:
|
|
|
c401cc |
- if (qemuTeardownHostdevCgroup(vm, hostdev) < 0)
|
|
|
c401cc |
- VIR_WARN("Unable to remove host device cgroup ACL on hotplug fail");
|
|
|
c401cc |
return -1;
|
|
|
c401cc |
}
|
|
|
c401cc |
|
|
|
c401cc |
--
|
|
|
c401cc |
1.8.4.4
|
|
|
c401cc |
|