>>> On 5/20/2016 at 06:32 PM, in message <573EE7C3.7000703@xxxxxxxxxx>, Joao Martins <joao.m.martins@xxxxxxxxxx> wrote: > On 05/19/2016 09:14 AM, Chunyan Liu wrote: > > Support hot attach/detach a USB host device to guest. > > Curretnly libxl only supports xen PV guest, and only > > supports specifying USB host device by 'bus number' > > and 'device number'. > > > > For example: > > usb.xml: > > <hostdev mode='subsystem' type='usb' managed='no'> > > <source> > > <address bus='1' device='3'/> > > </source> > > </hostdev> > > #xl attach-device dom usb.xml > > #xl detach-device dom usb.xml > > > > Signed-off-by: Chunyan Liu <cyliu@xxxxxxxx> > > --- > > Changes: > > * add LIBXL_HAVE_PVUSB check > > * fix Jim's comments > > > > src/libxl/libxl_driver.c | 136 > ++++++++++++++++++++++++++++++++++++++++++++++- > > 1 file changed, 135 insertions(+), 1 deletion(-) > > > > diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c > > index 960673f..a171efe 100644 > > --- a/src/libxl/libxl_driver.c > > +++ b/src/libxl/libxl_driver.c > > @@ -3028,6 +3028,56 @@ libxlDomainAttachHostPCIDevice(libxlDriverPrivatePtr > driver, > > return ret; > > } > > > > +#ifdef LIBXL_HAVE_PVUSB > > +static int > > +libxlDomainAttachHostUSBDevice(libxlDriverPrivatePtr driver, > > + virDomainObjPtr vm, > > + virDomainHostdevDefPtr hostdev) > > +{ > > + libxlDriverConfigPtr cfg = libxlDriverConfigGet(driver); > > + libxl_device_usbdev usbdev; > > + virHostdevManagerPtr hostdev_mgr = driver->hostdevMgr; > > + int ret = -1; > > + > > + libxl_device_usbdev_init(&usbdev); > > + > > + if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS || > > + hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) > > + goto cleanup; > > + > > + if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs + 1) < 0) > > + goto cleanup; > > + > > + if (virHostdevPrepareUSBDevices(hostdev_mgr, LIBXL_DRIVER_NAME, > > + vm->def->name, &hostdev, 1, 0) < 0) > > + goto cleanup; > > + > > + if (libxlMakeUSB(hostdev, &usbdev) < 0) > > + goto reattach; > > + > > + if (libxl_device_usbdev_add(cfg->ctx, vm->def->id, &usbdev, 0) < 0) { > > + virReportError(VIR_ERR_INTERNAL_ERROR, > > + _("libxenlight failed to attach usb device > Busnum:%3x, Devnum:%3x"), > > + hostdev->source.subsys.u.usb.bus, > > + hostdev->source.subsys.u.usb.device); > > + goto reattach; > > + } > > + > > + vm->def->hostdevs[vm->def->nhostdevs++] = hostdev; > > + ret = 0; > > + goto cleanup; > > + > > + reattach: > > + virHostdevReAttachUSBDevices(hostdev_mgr, LIBXL_DRIVER_NAME, > > + vm->def->name, &hostdev, 1); > > + > > + cleanup: > > + virObjectUnref(cfg); > > + libxl_device_usbdev_dispose(&usbdev); > > + return ret; > > +} > > +#endif > > + > > static int > > libxlDomainAttachHostDevice(libxlDriverPrivatePtr driver, > > virDomainObjPtr vm, > > @@ -3046,6 +3096,13 @@ libxlDomainAttachHostDevice(libxlDriverPrivatePtr > driver, > > return -1; > > break; > > > > +#ifdef LIBXL_HAVE_PVUSB > > + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: > > + if (libxlDomainAttachHostUSBDevice(driver, vm, hostdev) < 0) > > + return -1; > > + break; > > +#endif > > + > > default: > > virReportError(VIR_ERR_CONFIG_UNSUPPORTED, > > _("hostdev subsys type '%s' not supported"), > > @@ -3271,7 +3328,9 @@ libxlDomainAttachDeviceConfig(virDomainDefPtr vmdef, > virDomainDeviceDefPtr dev) > > case VIR_DOMAIN_DEVICE_HOSTDEV: > > hostdev = dev->data.hostdev; > > > > - if (hostdev->source.subsys.type != > VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) > > + if (hostdev->source.subsys.type != > > + (VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI || > > + VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB)) > Is this conditional correct when LIBXL_HAVE_PVUSB isn't there? No harm without LIBXL_HAVE_PVUSB, it can be handled. But if you want to use it to reboot the domain, the real hotplug into the system will be failed without LIBXL_HAVE_PVUSB. So, if our purpose is: any PVUSB function should be forbidden without LIBXL_HAVE_PVUSB, we need to add a check; otherwise, it's OK. How do you think? - Chunyan > > > return -1; > > > > if (virDomainHostdevFind(vmdef, hostdev, &found) >= 0) { > > @@ -3389,6 +3448,76 @@ libxlDomainDetachHostPCIDevice(libxlDriverPrivatePtr > driver, > > return ret; > > } > > > > +#ifdef LIBXL_HAVE_PVUSB > > +static int > > +libxlDomainDetachHostUSBDevice(libxlDriverPrivatePtr driver, > > + virDomainObjPtr vm, > > + virDomainHostdevDefPtr hostdev) > > +{ > > + libxlDriverConfigPtr cfg = libxlDriverConfigGet(driver); > > + virDomainHostdevSubsysPtr subsys = &hostdev->source.subsys; > > + virDomainHostdevSubsysUSBPtr usbsrc = &subsys->u.usb; > > + virHostdevManagerPtr hostdev_mgr = driver->hostdevMgr; > > + libxl_device_usbdev usbdev; > > + libxl_device_usbdev *usbdevs = NULL; > > + int num = 0; > > + virDomainHostdevDefPtr detach; > > + int idx; > > + size_t i; > > + bool found = false; > > + int ret = -1; > > + > > + libxl_device_usbdev_init(&usbdev); > > + > > + idx = virDomainHostdevFind(vm->def, hostdev, &detach); > > + if (idx < 0) { > > + virReportError(VIR_ERR_OPERATION_FAILED, > > + _("host USB device Busnum: %3x, Devnum: %3x not > found"), > > + usbsrc->bus, usbsrc->device); > > + goto cleanup; > > + } > > + > > + usbdevs = libxl_device_usbdev_list(cfg->ctx, vm->def->id, &num); > > + for (i = 0; i < num; i++) { > > + if (usbdevs[i].u.hostdev.hostbus == usbsrc->bus && > > + usbdevs[i].u.hostdev.hostaddr == usbsrc->device) { > > + libxl_device_usbdev_copy(cfg->ctx, &usbdev, &usbdevs[i]); > > + found = true; > > + break; > > + } > > + } > > + libxl_device_usbdev_list_free(usbdevs, num); > > + > > + if (!found) { > > + virReportError(VIR_ERR_OPERATION_FAILED, > > + _("host USB device Busnum: %3x, Devnum: %3x not > found"), > > + usbsrc->bus, usbsrc->device); > > + goto cleanup; > > + } > > + > > + if (libxl_device_usbdev_remove(cfg->ctx, vm->def->id, &usbdev, 0) < 0) { > > + virReportError(VIR_ERR_INTERNAL_ERROR, > > + _("libxenlight failed to detach USB device\ > > + Busnum: %3x, Devnum: %3x"), > > + usbsrc->bus, usbsrc->device); > > + goto cleanup; > > + } > > + > > + virDomainHostdevRemove(vm->def, idx); > > + > > + virHostdevReAttachUSBDevices(hostdev_mgr, LIBXL_DRIVER_NAME, > > + vm->def->name, &hostdev, 1); > > + > > + ret = 0; > > + > > + cleanup: > > + virDomainHostdevDefFree(detach); > > + virObjectUnref(cfg); > > + libxl_device_usbdev_dispose(&usbdev); > > + return ret; > > +} > > +#endif > > + > > static int > > libxlDomainDetachHostDevice(libxlDriverPrivatePtr driver, > > virDomainObjPtr vm, > > @@ -3407,6 +3536,11 @@ libxlDomainDetachHostDevice(libxlDriverPrivatePtr > driver, > > case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: > > return libxlDomainDetachHostPCIDevice(driver, vm, hostdev); > > > > +#ifdef LIBXL_HAVE_PVUSB > > + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: > > + return libxlDomainDetachHostUSBDevice(driver, vm, hostdev); > > +#endif > > + > > default: > > virReportError(VIR_ERR_INTERNAL_ERROR, > > _("unexpected hostdev type %d"), subsys->type); > > > > -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list