Make sure that the QEmu process within the cgroup can access the device
file for the USB device that has to be connected to the virtual domain.
---
src/qemu/qemu_driver.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 55 insertions(+), 0 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index a7cce6a..0612e69 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -3434,6 +3434,25 @@ static int qemuSetupChardevCgroup(virDomainDefPtr def,
}
+static int qemuSetupHostUsbDeviceCgroup(usbDevice *dev ATTRIBUTE_UNUSED,
+ const char *path,
+ void *opaque)
+{
+ virCgroupPtr cgroup = opaque;
+ int rc;
+
+ VIR_DEBUG("Process path '%s' for USB device", path);
+ rc = virCgroupAllowDevicePath(cgroup, path);
+ if (rc != 0) {
+ virReportSystemError(-rc,
+ _("Unable to allow device %s"),
+ path);
+ return -1;
+ }
+
+ return 0;
+}
+
static int qemuSetupCgroup(struct qemud_driver *driver,
virDomainObjPtr vm)
{
@@ -3507,6 +3526,23 @@ static int qemuSetupCgroup(struct qemud_driver *driver,
qemuSetupChardevCgroup,
cgroup) < 0)
goto cleanup;
+
+ for (i = 0; i < vm->def->nhostdevs; i++) {
+ virDomainHostdevDefPtr hostdev = vm->def->hostdevs[i];
+ usbDevice *usb;
+
+ if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
+ continue;
+ if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB)
+ continue;
+
+ if ((usb = usbGetDevice(hostdev->source.subsys.u.usb.bus,
+ hostdev->source.subsys.u.usb.device)) == NULL)
+ goto cleanup;
+
+ if (usbDeviceFileIterate(usb, qemuSetupHostUsbDeviceCgroup, cgroup) < 0 )
+ goto cleanup;
+ }
}
if ((rc = qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_MEMORY))) {
@@ -8511,6 +8547,25 @@ static int qemudDomainAttachHostUsbDevice(struct qemud_driver
*driver,
goto error;
}
+ if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_DEVICES)) {
+ virCgroupPtr cgroup = NULL;
+ usbDevice *usb;
+
+ if (virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0)
!=0 ) {
+ qemuReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Unable to find cgroup for %s\n"),
+ vm->def->name);
+ goto error;
+ }
+
+ if ((usb = usbGetDevice(hostdev->source.subsys.u.usb.bus,
+ hostdev->source.subsys.u.usb.device)) == NULL)
+ goto error;
+
+ if (usbDeviceFileIterate(usb, qemuSetupHostUsbDeviceCgroup, cgroup) < 0 )
+ goto error;
+ }
+
qemuDomainObjEnterMonitorWithDriver(driver, vm);
if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE)
ret = qemuMonitorAddDevice(priv->mon, devstr);
--
1.7.3.2