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

Daniel P. Berrange berrange at redhat.com
Mon Nov 1 14:29:06 UTC 2010


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 :|




More information about the libvir-list mailing list