File 05e149f9-call-qemuSetupHostdevCGroup-later.patch of Package libvirt.4601
commit 05e149f94cbd34e4c3d4e9c7f6871e13cfe03d8c
Author: Jiri Denemark <jdenemar@redhat.com>
Date: Thu Nov 14 12:02:40 2013 +0100
qemu: Call qemuSetupHostdevCGroup later during hotplug
https://bugzilla.redhat.com/show_bug.cgi?id=1025108
So far qemuSetupHostdevCGroup was called very early during hotplug, even
before we knew the device we were about to hotplug was actually
available. By calling the function later, we make sure QEMU won't be
allowed to access devices used by other domains.
Another important effect of this change is that hopluging USB devices
specified by vendor and product (but not by their USB address) works
again. This was broken since v1.0.5-171-g7d763ac, when the call to
qemuFindHostdevUSBDevice was moved after the call to
qemuSetupHostdevCGroup, which then used an uninitialized USB address.
Index: libvirt-1.1.2/src/qemu/qemu_hotplug.c
===================================================================
--- libvirt-1.1.2.orig/src/qemu/qemu_hotplug.c
+++ libvirt-1.1.2/src/qemu/qemu_hotplug.c
@@ -1134,6 +1134,7 @@ int qemuDomainAttachHostPciDevice(virQEM
int configfd = -1;
char *configfd_name = NULL;
bool releaseaddr = false;
+ bool teardowncgroup = false;
if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs + 1) < 0)
return -1;
@@ -1164,6 +1165,10 @@ int qemuDomainAttachHostPciDevice(virQEM
vm->def->hostdevs[vm->def->nhostdevs--] = NULL;
}
+ if (qemuSetupHostdevCGroup(vm, hostdev) < 0)
+ goto error;
+ teardowncgroup = true;
+
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
if (qemuAssignDeviceHostdevAlias(vm->def, hostdev, -1) < 0)
goto error;
@@ -1220,6 +1225,9 @@ int qemuDomainAttachHostPciDevice(virQEM
return 0;
error:
+ if (teardowncgroup && qemuTeardownHostdevCgroup(vm, hostdev) < 0)
+ VIR_WARN("Unable to remove host device cgroup ACL on hotplug fail");
+
if (releaseaddr)
qemuDomainReleaseDeviceAddress(vm, hostdev->info, NULL);
@@ -1412,6 +1420,7 @@ int qemuDomainAttachHostUsbDevice(virQEM
virUSBDevicePtr usb = NULL;
char *devstr = NULL;
bool added = false;
+ bool teardowncgroup = false;
int ret = -1;
if (qemuFindHostdevUSBDevice(hostdev, true, &usb) < 0)
@@ -1429,6 +1438,10 @@ int qemuDomainAttachHostUsbDevice(virQEM
added = true;
virUSBDeviceListSteal(list, usb);
+ if (qemuSetupHostdevCGroup(vm, hostdev) < 0)
+ goto cleanup;
+ teardowncgroup = true;
+
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
if (qemuAssignDeviceHostdevAlias(vm->def, hostdev, -1) < 0)
goto cleanup;
@@ -1455,6 +1468,10 @@ int qemuDomainAttachHostUsbDevice(virQEM
ret = 0;
cleanup:
+ if (ret < 0 &&
+ teardowncgroup &&
+ qemuTeardownHostdevCgroup(vm, hostdev) < 0)
+ VIR_WARN("Unable to remove host device cgroup ACL on hotplug fail");
if (added)
virUSBDeviceListSteal(driver->activeUsbHostdevs, usb);
virUSBDeviceFree(usb);
@@ -1472,6 +1489,7 @@ qemuDomainAttachHostScsiDevice(virQEMUDr
qemuDomainObjPrivatePtr priv = vm->privateData;
char *devstr = NULL;
char *drvstr = NULL;
+ bool teardowncgroup = false;
if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DRIVE) ||
!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) ||
@@ -1492,6 +1510,10 @@ qemuDomainAttachHostScsiDevice(virQEMUDr
return -1;
}
+ if (qemuSetupHostdevCGroup(vm, hostdev) < 0)
+ goto cleanup;
+ teardowncgroup = true;
+
if (qemuAssignDeviceHostdevAlias(vm->def, hostdev, -1) < 0)
goto cleanup;
@@ -1529,8 +1551,11 @@ qemuDomainAttachHostScsiDevice(virQEMUDr
ret = 0;
cleanup:
- if (ret < 0)
+ if (ret < 0) {
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");
+ }
VIR_FREE(drvstr);
VIR_FREE(devstr);
return ret;
@@ -1547,12 +1572,9 @@ int qemuDomainAttachHostDevice(virQEMUDr
return -1;
}
- if (qemuSetupHostdevCGroup(vm, hostdev) < 0)
- return -1;
-
if (virSecurityManagerSetHostdevLabel(driver->securityManager,
vm->def, hostdev, NULL) < 0)
- goto cleanup;
+ return -1;
switch (hostdev->source.subsys.type) {
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
@@ -1586,10 +1608,6 @@ error:
if (virSecurityManagerRestoreHostdevLabel(driver->securityManager,
vm->def, hostdev, NULL) < 0)
VIR_WARN("Unable to restore host device labelling on hotplug fail");
-
-cleanup:
- if (qemuTeardownHostdevCgroup(vm, hostdev) < 0)
- VIR_WARN("Unable to remove host device cgroup ACL on hotplug fail");
return -1;
}