[libvirt] [PATCH 10/23] Add support for USB host device passthrough with LXC

Gao feng gaofeng at cn.fujitsu.com
Tue Dec 11 03:48:05 UTC 2012


on 2012/12/01 04:26, Daniel P. Berrange wrote:
> From: "Daniel P. Berrange" <berrange at redhat.com>
> 
> This adds support for host device passthrough with the
> LXC driver. Since there is only a single kernel image,
> it doesn't make sense to pass through PCI devices, but
> USB devices are fine. For the latter we merely need to
> make the /dev/bus/usb/NNN/MMM character device exist
> in the container's /dev
> 
> Signed-off-by: Daniel P. Berrange <berrange at redhat.com>
> ---
>  src/Makefile.am         |   1 +
>  src/lxc/lxc_cgroup.c    |  64 ++++++++
>  src/lxc/lxc_cgroup.h    |  12 ++
>  src/lxc/lxc_conf.h      |   3 +
>  src/lxc/lxc_container.c | 124 ++++++++++++++-
>  src/lxc/lxc_driver.c    |   6 +
>  src/lxc/lxc_hostdev.c   | 390 ++++++++++++++++++++++++++++++++++++++++++++++++
>  src/lxc/lxc_hostdev.h   |  43 ++++++
>  src/lxc/lxc_process.c   |  11 ++
>  9 files changed, 653 insertions(+), 1 deletion(-)
>  create mode 100644 src/lxc/lxc_hostdev.c
>  create mode 100644 src/lxc/lxc_hostdev.h
> 
> diff --git a/src/Makefile.am b/src/Makefile.am
> index 627dbb5..c3459a5 100644
> --- a/src/Makefile.am
> +++ b/src/Makefile.am
> @@ -411,6 +411,7 @@ LXC_DRIVER_SOURCES =						\
>  		lxc/lxc_container.c lxc/lxc_container.h		\
>  		lxc/lxc_cgroup.c lxc/lxc_cgroup.h		\
>  		lxc/lxc_domain.c lxc/lxc_domain.h		\
> +		lxc/lxc_hostdev.c lxc/lxc_hostdev.h		\
>  		lxc/lxc_monitor.c lxc/lxc_monitor.h		\
>  		lxc/lxc_process.c lxc/lxc_process.h		\
>  		lxc/lxc_fuse.c lxc/lxc_fuse.h			\
> diff --git a/src/lxc/lxc_cgroup.c b/src/lxc/lxc_cgroup.c
> index 0636869..14c840a 100644
> --- a/src/lxc/lxc_cgroup.c
> +++ b/src/lxc/lxc_cgroup.c
> @@ -291,6 +291,49 @@ struct _virLXCCgroupDevicePolicy {
>  };
>  
>  
> +int
> +virLXCSetupHostUsbDeviceCgroup(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,
> +                                  VIR_CGROUP_DEVICE_RW);
> +    if (rc < 0) {

Maybe it's better to give some warning message when rc == 1,it
means the path is not a device.

> +        virReportSystemError(-rc,
> +                             _("Unable to allow device %s"),
> +                             path);
> +        return -1;
> +    }
> +
> +    return 0;
> +}
> +
> +
> +int
> +virLXCTeardownHostUsbDeviceCgroup(usbDevice *dev ATTRIBUTE_UNUSED,
> +                                  const char *path,
> +                                  void *opaque)
> +{
> +    virCgroupPtr cgroup = opaque;
> +    int rc;
> +
> +    VIR_DEBUG("Process path '%s' for USB device", path);
> +    rc = virCgroupDenyDevicePath(cgroup, path,
> +                                 VIR_CGROUP_DEVICE_RW);
> +    if (rc < 0) {
> +        virReportSystemError(-rc,
> +                             _("Unable to deny device %s"),
> +                             path);
> +        return -1;
> +    }
> +
> +    return 0;
> +}
> +
>

[...]

>  
>  
> +static int lxcContainerSetupHostdevSubsysUSB(virDomainDefPtr vmDef ATTRIBUTE_UNUSED,
> +                                             virDomainHostdevDefPtr def ATTRIBUTE_UNUSED,
> +                                             const char *dstprefix ATTRIBUTE_UNUSED,
> +                                             virSecurityManagerPtr securityDriver ATTRIBUTE_UNUSED)

ATTRIBUTE_UNUSED should be removed.

> +{
> +    int ret = -1;
> +    char *src = NULL;
> +    char *dstdir = NULL;
> +    char *dstfile = NULL;
> +    struct stat sb;
> +    mode_t mode;
> +

[...]

> +
> +int
> +virLXCPrepareHostdevUSBDevices(virLXCDriverPtr driver,
> +                               const char *name,
> +                               usbDeviceList *list)
> +{
> +    size_t i, j;
> +    unsigned int count;
> +    usbDevice *tmp;
> +
> +    count = usbDeviceListCount(list);
> +
> +    for (i = 0; i < count; i++) {
> +        usbDevice *usb = usbDeviceListGet(list, i);
> +        if ((tmp = usbDeviceListFind(driver->activeUsbHostdevs, usb))) {
> +            const char *other_name = usbDeviceGetUsedBy(tmp);
> +
> +            if (other_name)
> +                virReportError(VIR_ERR_OPERATION_INVALID,
> +                               _("USB device %s is in use by domain %s"),
> +                               usbDeviceGetName(tmp), other_name);
> +            else
> +                virReportError(VIR_ERR_OPERATION_INVALID,
> +                               _("USB device %s is already in use"),
> +                               usbDeviceGetName(tmp));
> +            goto error;
> +        }
> +
> +        usbDeviceSetUsedBy(usb, name);
> +        VIR_DEBUG("Adding %03d.%03d dom=%s to activeUsbHostdevs",
> +                  usbDeviceGetBus(usb), usbDeviceGetDevno(usb), name);
> +        /*
> +         * The caller is responsible to steal these usb devices
> +         * from the usbDeviceList that passed in on success,
> +         * perform rollback on failure.
> +         */
> +        if (usbDeviceListAdd(driver->activeUsbHostdevs, usb) < 0)
> +            goto error;
> +    }
> +    return 0;
> +
> +error:
> +    for (j = 0; j < i; j++) {
> +        tmp = usbDeviceListGet(list, i);

j?

> +        usbDeviceListSteal(driver->activeUsbHostdevs, tmp);
> +    }
> +    return -1;
> +}

this patch looks good to me.
ACK




More information about the libvir-list mailing list