[libvirt] [PATCH 1/2] qemu: add the USB devices to the cgroup whitelist

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

With this file in place, opening any source file in libvirt will set up Emacs for proper indentation. --- .dir-locals.el | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-) create mode 100644 .dir-locals.el diff --git a/.dir-locals.el b/.dir-locals.el new file mode 100644 index 0000000..7c483d2 --- /dev/null +++ b/.dir-locals.el @@ -0,0 +1,8 @@ +( + (c-mode . ( + (c-file-style . "K&R") + (indent-tabs-mode . nil) + (c-indent-level . 4) + (c-basic-offset . 4) + )) + ) -- 1.7.3.2

On Mon, Nov 01, 2010 at 12:03:17PM +0100, Diego Elio Pettenò wrote:
With this file in place, opening any source file in libvirt will set up Emacs for proper indentation. --- .dir-locals.el | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-) create mode 100644 .dir-locals.el
diff --git a/.dir-locals.el b/.dir-locals.el new file mode 100644 index 0000000..7c483d2 --- /dev/null +++ b/.dir-locals.el @@ -0,0 +1,8 @@ +( + (c-mode . ( + (c-file-style . "K&R") + (indent-tabs-mode . nil) + (c-indent-level . 4) + (c-basic-offset . 4) + )) + )
ACK Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://deltacloud.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

On Mon, Nov 01, 2010 at 12:03:16PM +0100, Diego Elio Pettenò wrote:
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);
ACK, looks fine now. Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://deltacloud.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

On 11/01/2010 08:29 AM, Daniel P. Berrange wrote:
On Mon, Nov 01, 2010 at 12:03:16PM +0100, Diego Elio Pettenò wrote:
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(-)
ACK, looks fine now.
Pushed, as well as the emace directive file. -- Eric Blake eblake@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org
participants (3)
-
Daniel P. Berrange
-
Diego Elio Pettenò
-
Eric Blake