on 2012/12/01 04:26, Daniel P. Berrange wrote: > From: "Daniel P. Berrange" <berrange@xxxxxxxxxx> > > 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@xxxxxxxxxx> > --- > 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list