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

Diego Elio Pettenò flameeyes at gmail.com
Fri Oct 29 22:25:30 UTC 2010


Add a new interface to hostusb.h to add an USB device abstraction to a
cgroup whitelist; then use it both when attaching a new USB device and when
adding it to the commandline so that the device can be accessed by the
QEmu-specific cgroup.
---
 src/libvirt_private.syms |    1 +
 src/qemu/qemu_driver.c   |   36 ++++++++++++++++++++++++++++++++++++
 src/util/hostusb.c       |    6 ++++++
 src/util/hostusb.h       |    4 +++-
 4 files changed, 46 insertions(+), 1 deletions(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index cf06256..0c6f308 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -707,6 +707,7 @@ virMutexUnlock;
 
 
 # usb.h
+usbAllowDeviceCgroup;
 usbDeviceFileIterate;
 usbDeviceGetBus;
 usbDeviceGetDevno;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 1eea3a9..acf319e 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -3505,6 +3505,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 = usbFindDevice(hostdev->source.subsys.u.usb.vendor,
+                                   hostdev->source.subsys.u.usb.product)) == NULL)
+            goto cleanup;
+
+          if (usbAllowDeviceCgroup(usb, cgroup) < 0)
+            goto cleanup;
+        }
     }
 
     if ((rc = qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_MEMORY))) {
@@ -8454,6 +8471,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 = usbFindDevice(hostdev->source.subsys.u.usb.vendor,
+                               hostdev->source.subsys.u.usb.product)) == NULL)
+        goto error;
+
+      if (usbAllowDeviceCgroup(usb, cgroup) < 0)
+        goto error;
+    }
+
     qemuDomainObjEnterMonitorWithDriver(driver, vm);
     if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE)
         ret = qemuMonitorAddDevice(priv->mon, devstr);
diff --git a/src/util/hostusb.c b/src/util/hostusb.c
index 2d6e414..2cbe1fb 100644
--- a/src/util/hostusb.c
+++ b/src/util/hostusb.c
@@ -225,3 +225,9 @@ int usbDeviceFileIterate(usbDevice *dev,
 {
     return (actor)(dev, dev->path, opaque);
 }
+
+int usbAllowDeviceCgroup(usbDevice *dev,
+                         virCgroupPtr group)
+{
+    return virCgroupAllowDevicePath(group, dev->path);
+}
diff --git a/src/util/hostusb.h b/src/util/hostusb.h
index f4a13ca..12269ad 100644
--- a/src/util/hostusb.h
+++ b/src/util/hostusb.h
@@ -23,6 +23,7 @@
 # define __VIR_USB_H__
 
 # include "internal.h"
+# include "cgroup.h"
 
 typedef struct _usbDevice usbDevice;
 
@@ -48,6 +49,7 @@ typedef int (*usbDeviceFileActor)(usbDevice *dev,
 int usbDeviceFileIterate(usbDevice *dev,
                          usbDeviceFileActor actor,
                          void *opaque);
-
+int usbAllowDeviceCgroup(usbDevice *dev,
+                         virCgroupPtr group);
 
 #endif /* __VIR_USB_H__ */
-- 
1.7.3.2




More information about the libvir-list mailing list