[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