[libvirt] [PATCH V2 0/4] libxl: support pvusb

This patch series is to support pvusb in libxl driver. --- Changes in v2: * add LIBXL_HAVE_PVUSB check * add convertion of domxml USB config to/from xl.cfg * address other comments Chunyan Liu (4): libxl: support creating guest with USB hostdev libxl: support hotplug USB host device Add convertion domxml USB config to/from xl.cfg xlconfigtest: add test on USB convertion src/libxl/libxl_conf.c | 74 ++++++++++++++++++++ src/libxl/libxl_conf.h | 5 ++ src/libxl/libxl_domain.c | 16 ++++- src/libxl/libxl_driver.c | 144 +++++++++++++++++++++++++++++++++++++- src/xenconfig/xen_xl.c | 151 ++++++++++++++++++++++++++++++++++++++++ tests/xlconfigdata/test-usb.cfg | 13 ++++ tests/xlconfigdata/test-usb.xml | 35 ++++++++++ tests/xlconfigtest.c | 1 + 8 files changed, 435 insertions(+), 4 deletions(-) create mode 100644 tests/xlconfigdata/test-usb.cfg create mode 100644 tests/xlconfigdata/test-usb.xml -- 2.1.4

Support creating guest with USB host device in config file. Currently libxl only supports xen PV guest, and only supports specifying USB host device by 'bus number' and 'device number', for example: <hostdev mode='subsystem' type='usb' managed='no'> <source> <address bus='1' device='3'/> </source> </hostdev> Signed-off-by: Chunyan Liu <cyliu@suse.com> --- Changes: * add LIBXL_HAVE_PVUSB check * address Jim's comments src/libxl/libxl_conf.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++ src/libxl/libxl_conf.h | 5 ++++ src/libxl/libxl_domain.c | 16 +++++++++-- src/libxl/libxl_driver.c | 8 +++++- 4 files changed, 100 insertions(+), 3 deletions(-) diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c index c399f5c..c6c76c4 100644 --- a/src/libxl/libxl_conf.c +++ b/src/libxl/libxl_conf.c @@ -1861,6 +1861,75 @@ int libxlDriverConfigLoadFile(libxlDriverConfigPtr cfg, } +#ifdef LIBXL_HAVE_PVUSB +int +libxlMakeUSB(virDomainHostdevDefPtr hostdev, libxl_device_usbdev *usbdev) +{ + virDomainHostdevSubsysUSBPtr usbsrc = &hostdev->source.subsys.u.usb; + + if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) + return -1; + if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) + return -1; + + if (usbsrc->bus <= 0 || usbsrc->device <= 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("libxenlight supports only USB device " + "specified by busnum:devnum")); + return -1; + } + + usbdev->u.hostdev.hostbus = usbsrc->bus; + usbdev->u.hostdev.hostaddr = usbsrc->device; + + return 0; +} + +static int +libxlMakeUSBList(virDomainDefPtr def, libxl_domain_config *d_config) +{ + virDomainHostdevDefPtr *l_hostdevs = def->hostdevs; + size_t nhostdevs = def->nhostdevs; + size_t nusbdevs = 0; + libxl_device_usbdev *x_usbdevs; + size_t i, j; + + if (nhostdevs == 0) + return 0; + + if (VIR_ALLOC_N(x_usbdevs, nhostdevs) < 0) + return -1; + + for (i = 0, j = 0; i < nhostdevs; i++) { + if (l_hostdevs[i]->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) + continue; + if (l_hostdevs[i]->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) + continue; + + libxl_device_usbdev_init(&x_usbdevs[j]); + + if (libxlMakeUSB(l_hostdevs[i], &x_usbdevs[j]) < 0) + goto error; + + nusbdevs++; + j++; + } + + VIR_SHRINK_N(x_usbdevs, nhostdevs, nhostdevs - nusbdevs); + d_config->usbdevs = x_usbdevs; + d_config->num_usbdevs = nusbdevs; + + return 0; + + error: + for (i = 0; i < nusbdevs; i++) + libxl_device_usbdev_dispose(&x_usbdevs[i]); + + VIR_FREE(x_usbdevs); + return -1; +} +#endif + int libxlMakePCI(virDomainHostdevDefPtr hostdev, libxl_device_pci *pcidev) { @@ -2092,6 +2161,11 @@ libxlBuildDomainConfig(virPortAllocatorPtr graphicsports, if (libxlMakePCIList(def, d_config) < 0) return -1; +#ifdef LIBXL_HAVE_PVUSB + if (libxlMakeUSBList(def, d_config) < 0) + return -1; +#endif + /* * Now that any potential VFBs are defined, update the build info with * the data of the primary display. Some day libxl might implicitely do diff --git a/src/libxl/libxl_conf.h b/src/libxl/libxl_conf.h index c5b9429..df318f4 100644 --- a/src/libxl/libxl_conf.h +++ b/src/libxl/libxl_conf.h @@ -196,6 +196,11 @@ libxlMakeVfb(virPortAllocatorPtr graphicsports, int libxlMakePCI(virDomainHostdevDefPtr hostdev, libxl_device_pci *pcidev); +#ifdef LIBXL_HAVE_PVUSB +int +libxlMakeUSB(virDomainHostdevDefPtr hostdev, libxl_device_usbdev *usbdev); +#endif + virDomainXMLOptionPtr libxlCreateXMLConf(void); diff --git a/src/libxl/libxl_domain.c b/src/libxl/libxl_domain.c index 5fa1bd9..3dda34d 100644 --- a/src/libxl/libxl_domain.c +++ b/src/libxl/libxl_domain.c @@ -726,9 +726,15 @@ libxlDomainCleanup(libxlDriverPrivatePtr driver, int vnc_port; char *file; virHostdevManagerPtr hostdev_mgr = driver->hostdevMgr; + unsigned int hostdev_flags; + + hostdev_flags = VIR_HOSTDEV_SP_PCI; +#ifdef LIBXL_HAVE_PVUSB + hostdev_flags |= VIR_HOSTDEV_SP_USB; +#endif virHostdevReAttachDomainDevices(hostdev_mgr, LIBXL_DRIVER_NAME, - vm->def, VIR_HOSTDEV_SP_PCI, NULL); + vm->def, hostdev_flags, NULL); VIR_FREE(priv->lockState); if (virDomainLockProcessPause(driver->lockManager, vm, &priv->lockState) < 0) @@ -1038,6 +1044,12 @@ libxlDomainStart(libxlDriverPrivatePtr driver, virHostdevManagerPtr hostdev_mgr = driver->hostdevMgr; libxl_asyncprogress_how aop_console_how; libxl_domain_restore_params params; + unsigned int hostdev_flags; + + hostdev_flags = VIR_HOSTDEV_SP_PCI; +#ifdef LIBXL_HAVE_PVUSB + hostdev_flags |= VIR_HOSTDEV_SP_USB; +#endif libxl_domain_config_init(&d_config); @@ -1114,7 +1126,7 @@ libxlDomainStart(libxlDriverPrivatePtr driver, goto cleanup_dom; if (virHostdevPrepareDomainDevices(hostdev_mgr, LIBXL_DRIVER_NAME, - vm->def, VIR_HOSTDEV_SP_PCI) < 0) + vm->def, hostdev_flags) < 0) goto cleanup_dom; /* Unlock virDomainObj while creating the domain */ diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c index 2c19ddb..960673f 100644 --- a/src/libxl/libxl_driver.c +++ b/src/libxl/libxl_driver.c @@ -352,6 +352,12 @@ libxlReconnectDomain(virDomainObjPtr vm, int len; uint8_t *data = NULL; virHostdevManagerPtr hostdev_mgr = driver->hostdevMgr; + unsigned int hostdev_flags; + + hostdev_flags = VIR_HOSTDEV_SP_PCI; +#ifdef LIBXL_HAVE_PVUSB + hostdev_flags |= VIR_HOSTDEV_SP_USB; +#endif virObjectLock(vm); @@ -379,7 +385,7 @@ libxlReconnectDomain(virDomainObjPtr vm, /* Update hostdev state */ if (virHostdevUpdateActiveDomainDevices(hostdev_mgr, LIBXL_DRIVER_NAME, - vm->def, VIR_HOSTDEV_SP_PCI) < 0) + vm->def, hostdev_flags) < 0) goto out; if (virAtomicIntInc(&driver->nactive) == 1 && driver->inhibitCallback) -- 2.1.4

On 05/19/2016 09:14 AM, Chunyan Liu wrote:
Support creating guest with USB host device in config file. Currently libxl only supports xen PV guest, and only supports specifying USB host device by 'bus number' and 'device number', for example: <hostdev mode='subsystem' type='usb' managed='no'> <source> <address bus='1' device='3'/> </source> </hostdev>
Signed-off-by: Chunyan Liu <cyliu@suse.com> There was only a nitpick that I spotted but other than that looks good to me:
Reviewed-by: Joao Martins <joao.m.martins@oracle.com>
--- Changes: * add LIBXL_HAVE_PVUSB check * address Jim's comments
src/libxl/libxl_conf.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++ src/libxl/libxl_conf.h | 5 ++++ src/libxl/libxl_domain.c | 16 +++++++++-- src/libxl/libxl_driver.c | 8 +++++- 4 files changed, 100 insertions(+), 3 deletions(-)
diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c index c399f5c..c6c76c4 100644 --- a/src/libxl/libxl_conf.c +++ b/src/libxl/libxl_conf.c @@ -1861,6 +1861,75 @@ int libxlDriverConfigLoadFile(libxlDriverConfigPtr cfg,
}
+#ifdef LIBXL_HAVE_PVUSB +int +libxlMakeUSB(virDomainHostdevDefPtr hostdev, libxl_device_usbdev *usbdev) +{ + virDomainHostdevSubsysUSBPtr usbsrc = &hostdev->source.subsys.u.usb; + + if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) + return -1; + if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) + return -1; + + if (usbsrc->bus <= 0 || usbsrc->device <= 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("libxenlight supports only USB device " + "specified by busnum:devnum")); + return -1; + } + + usbdev->u.hostdev.hostbus = usbsrc->bus; + usbdev->u.hostdev.hostaddr = usbsrc->device; + + return 0; +} + +static int +libxlMakeUSBList(virDomainDefPtr def, libxl_domain_config *d_config) +{ + virDomainHostdevDefPtr *l_hostdevs = def->hostdevs; + size_t nhostdevs = def->nhostdevs; + size_t nusbdevs = 0; + libxl_device_usbdev *x_usbdevs; + size_t i, j; + + if (nhostdevs == 0) + return 0; + + if (VIR_ALLOC_N(x_usbdevs, nhostdevs) < 0) + return -1; + + for (i = 0, j = 0; i < nhostdevs; i++) { + if (l_hostdevs[i]->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) + continue; + if (l_hostdevs[i]->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) + continue; + + libxl_device_usbdev_init(&x_usbdevs[j]); + + if (libxlMakeUSB(l_hostdevs[i], &x_usbdevs[j]) < 0) + goto error; + + nusbdevs++; + j++; + } + + VIR_SHRINK_N(x_usbdevs, nhostdevs, nhostdevs - nusbdevs); + d_config->usbdevs = x_usbdevs; + d_config->num_usbdevs = nusbdevs; + + return 0; + + error: + for (i = 0; i < nusbdevs; i++) + libxl_device_usbdev_dispose(&x_usbdevs[i]); + + VIR_FREE(x_usbdevs); + return -1; +} +#endif + int libxlMakePCI(virDomainHostdevDefPtr hostdev, libxl_device_pci *pcidev) { @@ -2092,6 +2161,11 @@ libxlBuildDomainConfig(virPortAllocatorPtr graphicsports, if (libxlMakePCIList(def, d_config) < 0) return -1;
+#ifdef LIBXL_HAVE_PVUSB + if (libxlMakeUSBList(def, d_config) < 0) + return -1; +#endif + /* * Now that any potential VFBs are defined, update the build info with * the data of the primary display. Some day libxl might implicitely do diff --git a/src/libxl/libxl_conf.h b/src/libxl/libxl_conf.h index c5b9429..df318f4 100644 --- a/src/libxl/libxl_conf.h +++ b/src/libxl/libxl_conf.h @@ -196,6 +196,11 @@ libxlMakeVfb(virPortAllocatorPtr graphicsports, int libxlMakePCI(virDomainHostdevDefPtr hostdev, libxl_device_pci *pcidev);
+#ifdef LIBXL_HAVE_PVUSB +int +libxlMakeUSB(virDomainHostdevDefPtr hostdev, libxl_device_usbdev *usbdev); +#endif + The #ifdef and #endif aren't indented properly. In this case the code style requires it to be "# ifdef" and "# endif" otherwise make syntax-check will fail.
virDomainXMLOptionPtr libxlCreateXMLConf(void);
diff --git a/src/libxl/libxl_domain.c b/src/libxl/libxl_domain.c index 5fa1bd9..3dda34d 100644 --- a/src/libxl/libxl_domain.c +++ b/src/libxl/libxl_domain.c @@ -726,9 +726,15 @@ libxlDomainCleanup(libxlDriverPrivatePtr driver, int vnc_port; char *file; virHostdevManagerPtr hostdev_mgr = driver->hostdevMgr; + unsigned int hostdev_flags; + + hostdev_flags = VIR_HOSTDEV_SP_PCI; +#ifdef LIBXL_HAVE_PVUSB + hostdev_flags |= VIR_HOSTDEV_SP_USB; +#endif Just one suggestion: this chunk (and the ones after) could probably be made simpler by having hostdev_flags initialized beforehand with VIR_HOSTDEV_SP_PCI instead of having in separate:
unsigned int hostdev_flags = VIR_HOSTDEV_SP_PCI; #ifdef LIBXL_HAVE_PVUSB hostdev_flags |= VIR_HOSTDEV_SP_USB; #endif
virHostdevReAttachDomainDevices(hostdev_mgr, LIBXL_DRIVER_NAME, - vm->def, VIR_HOSTDEV_SP_PCI, NULL); + vm->def, hostdev_flags, NULL);
VIR_FREE(priv->lockState); if (virDomainLockProcessPause(driver->lockManager, vm, &priv->lockState) < 0) @@ -1038,6 +1044,12 @@ libxlDomainStart(libxlDriverPrivatePtr driver, virHostdevManagerPtr hostdev_mgr = driver->hostdevMgr; libxl_asyncprogress_how aop_console_how; libxl_domain_restore_params params; + unsigned int hostdev_flags; + + hostdev_flags = VIR_HOSTDEV_SP_PCI; +#ifdef LIBXL_HAVE_PVUSB + hostdev_flags |= VIR_HOSTDEV_SP_USB; +#endif
libxl_domain_config_init(&d_config);
@@ -1114,7 +1126,7 @@ libxlDomainStart(libxlDriverPrivatePtr driver, goto cleanup_dom;
if (virHostdevPrepareDomainDevices(hostdev_mgr, LIBXL_DRIVER_NAME, - vm->def, VIR_HOSTDEV_SP_PCI) < 0) + vm->def, hostdev_flags) < 0) goto cleanup_dom;
/* Unlock virDomainObj while creating the domain */ diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c index 2c19ddb..960673f 100644 --- a/src/libxl/libxl_driver.c +++ b/src/libxl/libxl_driver.c @@ -352,6 +352,12 @@ libxlReconnectDomain(virDomainObjPtr vm, int len; uint8_t *data = NULL; virHostdevManagerPtr hostdev_mgr = driver->hostdevMgr; + unsigned int hostdev_flags; + + hostdev_flags = VIR_HOSTDEV_SP_PCI; +#ifdef LIBXL_HAVE_PVUSB + hostdev_flags |= VIR_HOSTDEV_SP_USB; +#endif
virObjectLock(vm);
@@ -379,7 +385,7 @@ libxlReconnectDomain(virDomainObjPtr vm,
/* Update hostdev state */ if (virHostdevUpdateActiveDomainDevices(hostdev_mgr, LIBXL_DRIVER_NAME, - vm->def, VIR_HOSTDEV_SP_PCI) < 0) + vm->def, hostdev_flags) < 0) goto out;
if (virAtomicIntInc(&driver->nactive) == 1 && driver->inhibitCallback)

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@suse.com> --- 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)) 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); -- 2.1.4

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@suse.com> --- 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?
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);

On 05/20/2016 04:32 AM, Joao Martins 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
s/Curretnly/Currently/
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@suse.com> --- 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?
I think there are two problems here. First, (VIR_DOMAIN_DEVICE_DISK || VIR_DOMAIN_DEVICE_LEASE) evaluates to 1, so essentially this is equivalent to if (hostdev->source.subsys.type != 1) Second, I agree that we don't want to add a USB device to the config if libxl cant support it. Regards, Jim

On 05/20/2016 02:25 PM, Jim Fehlig wrote:
On 05/20/2016 04:32 AM, Joao Martins 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 s/Curretnly/Currently/
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@suse.com> --- 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? I think there are two problems here. First, (VIR_DOMAIN_DEVICE_DISK || VIR_DOMAIN_DEVICE_LEASE) evaluates to 1, so essentially this is equivalent to
if (hostdev->source.subsys.type != 1)
Second, I agree that we don't want to add a USB device to the config if libxl cant support it.
Something like the below diff? Regards, Jim diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c index 9001f34..5b6f87a 100644 --- a/src/libxl/libxl_driver.c +++ b/src/libxl/libxl_driver.c @@ -3326,10 +3326,14 @@ 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 || - VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB)) + switch (hostdev->source.subsys.type) { + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI: +#ifndef LIBXL_HAVE_PVUSB + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: +#endif + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST: return -1; + } if (virDomainHostdevFind(vmdef, hostdev, &found) >= 0) { pcisrc = &hostdev->source.subsys.u.pci; l

On 5/21/2016 at 05:25 AM, in message <573F80E3.4070905@suse.com>, Jim Fehlig <jfehlig@suse.com> wrote: On 05/20/2016 02:25 PM, Jim Fehlig wrote: On 05/20/2016 04:32 AM, Joao Martins 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 s/Curretnly/Currently/
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@suse.com> --- 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? I think there are two problems here. First, (VIR_DOMAIN_DEVICE_DISK || VIR_DOMAIN_DEVICE_LEASE) evaluates to 1, so essentially this is equivalent to
if (hostdev->source.subsys.type != 1)
Oh, my god. Your are right. Stupid mistake.
Second, I agree that we don't want to add a USB device to the config if
libxl
cant support it.
Something like the below diff?
Yes, I think it's OK. And another place needs to be updated, since now it's not only pci device, but also could be usb device, so the error message should be updated. if (virDomainHostdevFind(vmdef, hostdev, &found) >= 0) { - pcisrc = &hostdev->source.subsys.u.pci; virReportError(VIR_ERR_OPERATION_FAILED, - _("target pci device %.4x:%.2x:%.2x.%.1x\ - already exists"), - pcisrc->addr.domain, pcisrc->addr.bus, - pcisrc->addr.slot, pcisrc->addr.function); + _("device already exists in domain configuration")); return -1; } Sorry for not noticing that in time. - Chunyan
Regards, Jim
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c index 9001f34..5b6f87a 100644 --- a/src/libxl/libxl_driver.c +++ b/src/libxl/libxl_driver.c @@ -3326,10 +3326,14 @@ 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 || - VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB)) + switch (hostdev->source.subsys.type) { + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI: +#ifndef LIBXL_HAVE_PVUSB + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: +#endif + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST: return -1; + }
if (virDomainHostdevFind(vmdef, hostdev, &found) >= 0) { pcisrc = &hostdev->source.subsys.u.pci; l

On 5/20/2016 at 06:32 PM, in message <573EE7C3.7000703@oracle.com>, Joao Martins <joao.m.martins@oracle.com> 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@suse.com> --- 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);

xl.cfg: usbdev = [ "hostbus=1,hostaddr=3" ] usb.xml: <hostdev mode='subsystem' type='usb' managed='no'> <source> <address bus='1' device='3'/> </source> </hostdev> Signed-off-by: Chunyan Liu <cyliu@suse.com> --- src/xenconfig/xen_xl.c | 151 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 151 insertions(+) diff --git a/src/xenconfig/xen_xl.c b/src/xenconfig/xen_xl.c index 15350f9..11e90b6 100644 --- a/src/xenconfig/xen_xl.c +++ b/src/xenconfig/xen_xl.c @@ -485,6 +485,85 @@ xenParseXLInputDevs(virConfPtr conf, virDomainDefPtr def) return 0; } +static int +xenParseXLUSB(virConfPtr conf, virDomainDefPtr def) +{ + virConfValuePtr list = virConfGetValue(conf, "usbdev"); + virDomainHostdevDefPtr hostdev = NULL; + + if (list && list->type == VIR_CONF_LIST) { + list = list->list; + while (list) { + char bus[3]; + char device[3]; + char *key; + int busNum; + int devNum; + + bus[0] = device[0] = '\0'; + + if ((list->type != VIR_CONF_STRING) || (list->str == NULL)) + goto skipusb; + /* usbdev=['hostbus=1,hostaddr=3'] */ + key = list->str; + while (key) { + char *data; + char *nextkey = strchr(key, ','); + + if (!(data = strchr(key, '='))) + goto skipusb; + data++; + + if (STRPREFIX(key, "hostbus=")) { + int len = nextkey ? (nextkey - data) : sizeof(bus) - 1; + if (virStrncpy(bus, data, len, sizeof(bus)) == NULL) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("bus %s too big for destination"), + data); + goto skipusb; + } + } else if (STRPREFIX(key, "hostaddr=")) { + int len = nextkey ? (nextkey - data) : sizeof(device) - 1; + if (virStrncpy(device, data, len, sizeof(device)) == NULL) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("device %s too big for destination"), + data); + goto skipusb; + } + } + + while (nextkey && (nextkey[0] == ',' || + nextkey[0] == ' ' || + nextkey[0] == '\t')) + nextkey++; + key = nextkey; + } + + if (virStrToLong_i(bus, NULL, 16, &busNum) < 0) + goto skipusb; + if (virStrToLong_i(device, NULL, 16, &devNum) < 0) + goto skipusb; + if (!(hostdev = virDomainHostdevDefAlloc(NULL))) + return -1; + + hostdev->managed = false; + hostdev->source.subsys.type = VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB; + hostdev->source.subsys.u.usb.bus = busNum; + hostdev->source.subsys.u.usb.device = devNum; + + if (VIR_APPEND_ELEMENT(def->hostdevs, def->nhostdevs, hostdev) < 0) { + virDomainHostdevDefFree(hostdev); + return -1; + } + + skipusb: + list = list->next; + } + } + + return 0; +} + virDomainDefPtr xenParseXL(virConfPtr conf, virCapsPtr caps, @@ -513,6 +592,9 @@ xenParseXL(virConfPtr conf, if (xenParseXLInputDevs(conf, def) < 0) goto cleanup; + if (xenParseXLUSB(conf, def) < 0) + goto cleanup; + if (virDomainDefPostParse(def, caps, VIR_DOMAIN_DEF_PARSE_ABI_UPDATE, xmlopt) < 0) goto cleanup; @@ -984,6 +1066,72 @@ xenFormatXLInputDevs(virConfPtr conf, virDomainDefPtr def) return -1; } +static int +xenFormatXLUSB(virConfPtr conf, + virDomainDefPtr def) +{ + virConfValuePtr usbVal = NULL; + int hasUSB = 0; + size_t i; + + for (i = 0; i < def->nhostdevs; i++) { + if (def->hostdevs[i]->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && + def->hostdevs[i]->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) { + hasUSB = 1; + break; + } + } + + if (!hasUSB) + return 0; + + if (VIR_ALLOC(usbVal) < 0) + return -1; + + usbVal->type = VIR_CONF_LIST; + usbVal->list = NULL; + + for (i = 0; i < def->nhostdevs; i++) { + if (def->hostdevs[i]->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && + def->hostdevs[i]->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) { + virConfValuePtr val, tmp; + char *buf; + + if (virAsprintf(&buf, "hostbus=%x,hostaddr=%x", + def->hostdevs[i]->source.subsys.u.usb.bus, + def->hostdevs[i]->source.subsys.u.usb.device) < 0) + goto error; + + if (VIR_ALLOC(val) < 0) { + VIR_FREE(buf); + goto error; + } + val->type = VIR_CONF_STRING; + val->str = buf; + tmp = usbVal->list; + while (tmp && tmp->next) + tmp = tmp->next; + if (tmp) + tmp->next = val; + else + usbVal->list = val; + } + } + + if (usbVal->list != NULL) { + int ret = virConfSetValue(conf, "usbdev", usbVal); + usbVal = NULL; + if (ret < 0) + return -1; + } + VIR_FREE(usbVal); + + return 0; + + error: + virConfFreeValue(usbVal); + return -1; +} virConfPtr xenFormatXL(virDomainDefPtr def, virConnectPtr conn) @@ -1008,6 +1156,9 @@ xenFormatXL(virDomainDefPtr def, virConnectPtr conn) if (xenFormatXLInputDevs(conf, def) < 0) goto cleanup; + if (xenFormatXLUSB(conf, def) < 0) + goto cleanup; + return conf; cleanup: -- 2.1.4

In subject, s/convertion/conversion of/ Otherwise, looks good. Regards, Jim On 05/19/2016 02:14 AM, Chunyan Liu wrote:
xl.cfg: usbdev = [ "hostbus=1,hostaddr=3" ]
usb.xml: <hostdev mode='subsystem' type='usb' managed='no'> <source> <address bus='1' device='3'/> </source> </hostdev>
Signed-off-by: Chunyan Liu <cyliu@suse.com> --- src/xenconfig/xen_xl.c | 151 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 151 insertions(+)
diff --git a/src/xenconfig/xen_xl.c b/src/xenconfig/xen_xl.c index 15350f9..11e90b6 100644 --- a/src/xenconfig/xen_xl.c +++ b/src/xenconfig/xen_xl.c @@ -485,6 +485,85 @@ xenParseXLInputDevs(virConfPtr conf, virDomainDefPtr def) return 0; }
+static int +xenParseXLUSB(virConfPtr conf, virDomainDefPtr def) +{ + virConfValuePtr list = virConfGetValue(conf, "usbdev"); + virDomainHostdevDefPtr hostdev = NULL; + + if (list && list->type == VIR_CONF_LIST) { + list = list->list; + while (list) { + char bus[3]; + char device[3]; + char *key; + int busNum; + int devNum; + + bus[0] = device[0] = '\0'; + + if ((list->type != VIR_CONF_STRING) || (list->str == NULL)) + goto skipusb; + /* usbdev=['hostbus=1,hostaddr=3'] */ + key = list->str; + while (key) { + char *data; + char *nextkey = strchr(key, ','); + + if (!(data = strchr(key, '='))) + goto skipusb; + data++; + + if (STRPREFIX(key, "hostbus=")) { + int len = nextkey ? (nextkey - data) : sizeof(bus) - 1; + if (virStrncpy(bus, data, len, sizeof(bus)) == NULL) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("bus %s too big for destination"), + data); + goto skipusb; + } + } else if (STRPREFIX(key, "hostaddr=")) { + int len = nextkey ? (nextkey - data) : sizeof(device) - 1; + if (virStrncpy(device, data, len, sizeof(device)) == NULL) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("device %s too big for destination"), + data); + goto skipusb; + } + } + + while (nextkey && (nextkey[0] == ',' || + nextkey[0] == ' ' || + nextkey[0] == '\t')) + nextkey++; + key = nextkey; + } + + if (virStrToLong_i(bus, NULL, 16, &busNum) < 0) + goto skipusb; + if (virStrToLong_i(device, NULL, 16, &devNum) < 0) + goto skipusb; + if (!(hostdev = virDomainHostdevDefAlloc(NULL))) + return -1; + + hostdev->managed = false; + hostdev->source.subsys.type = VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB; + hostdev->source.subsys.u.usb.bus = busNum; + hostdev->source.subsys.u.usb.device = devNum; + + if (VIR_APPEND_ELEMENT(def->hostdevs, def->nhostdevs, hostdev) < 0) { + virDomainHostdevDefFree(hostdev); + return -1; + } + + skipusb: + list = list->next; + } + } + + return 0; +} + virDomainDefPtr xenParseXL(virConfPtr conf, virCapsPtr caps, @@ -513,6 +592,9 @@ xenParseXL(virConfPtr conf, if (xenParseXLInputDevs(conf, def) < 0) goto cleanup;
+ if (xenParseXLUSB(conf, def) < 0) + goto cleanup; + if (virDomainDefPostParse(def, caps, VIR_DOMAIN_DEF_PARSE_ABI_UPDATE, xmlopt) < 0) goto cleanup; @@ -984,6 +1066,72 @@ xenFormatXLInputDevs(virConfPtr conf, virDomainDefPtr def) return -1; }
+static int +xenFormatXLUSB(virConfPtr conf, + virDomainDefPtr def) +{ + virConfValuePtr usbVal = NULL; + int hasUSB = 0; + size_t i; + + for (i = 0; i < def->nhostdevs; i++) { + if (def->hostdevs[i]->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && + def->hostdevs[i]->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) { + hasUSB = 1; + break; + } + } + + if (!hasUSB) + return 0; + + if (VIR_ALLOC(usbVal) < 0) + return -1; + + usbVal->type = VIR_CONF_LIST; + usbVal->list = NULL; + + for (i = 0; i < def->nhostdevs; i++) { + if (def->hostdevs[i]->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && + def->hostdevs[i]->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) { + virConfValuePtr val, tmp; + char *buf; + + if (virAsprintf(&buf, "hostbus=%x,hostaddr=%x", + def->hostdevs[i]->source.subsys.u.usb.bus, + def->hostdevs[i]->source.subsys.u.usb.device) < 0) + goto error; + + if (VIR_ALLOC(val) < 0) { + VIR_FREE(buf); + goto error; + } + val->type = VIR_CONF_STRING; + val->str = buf; + tmp = usbVal->list; + while (tmp && tmp->next) + tmp = tmp->next; + if (tmp) + tmp->next = val; + else + usbVal->list = val; + } + } + + if (usbVal->list != NULL) { + int ret = virConfSetValue(conf, "usbdev", usbVal); + usbVal = NULL; + if (ret < 0) + return -1; + } + VIR_FREE(usbVal); + + return 0; + + error: + virConfFreeValue(usbVal); + return -1; +}
virConfPtr xenFormatXL(virDomainDefPtr def, virConnectPtr conn) @@ -1008,6 +1156,9 @@ xenFormatXL(virDomainDefPtr def, virConnectPtr conn) if (xenFormatXLInputDevs(conf, def) < 0) goto cleanup;
+ if (xenFormatXLUSB(conf, def) < 0) + goto cleanup; + return conf;
cleanup:

Signed-off-by: Chunyan Liu <cyliu@suse.com> --- tests/xlconfigdata/test-usb.cfg | 13 +++++++++++++ tests/xlconfigdata/test-usb.xml | 35 +++++++++++++++++++++++++++++++++++ tests/xlconfigtest.c | 1 + 3 files changed, 49 insertions(+) create mode 100644 tests/xlconfigdata/test-usb.cfg create mode 100644 tests/xlconfigdata/test-usb.xml diff --git a/tests/xlconfigdata/test-usb.cfg b/tests/xlconfigdata/test-usb.cfg new file mode 100644 index 0000000..f0e616c --- /dev/null +++ b/tests/xlconfigdata/test-usb.cfg @@ -0,0 +1,13 @@ +name = "XenGuest1" +uuid = "45b60f51-88a9-47a8-a3b3-5e66d71b2283" +maxmem = 512 +memory = 512 +vcpus = 1 +localtime = 0 +on_poweroff = "preserve" +on_reboot = "restart" +on_crash = "preserve" +vif = [ "mac=5a:36:0e:be:00:09" ] +bootloader = "/usr/bin/pygrub" +disk = [ "format=qcow2,vdev=xvda,access=rw,backendtype=qdisk,target=/var/lib/xen/images/debian/disk.qcow2" ] +usbdev = [ "hostbus=1,hostaddr=3" ] diff --git a/tests/xlconfigdata/test-usb.xml b/tests/xlconfigdata/test-usb.xml new file mode 100644 index 0000000..7b5853d --- /dev/null +++ b/tests/xlconfigdata/test-usb.xml @@ -0,0 +1,35 @@ +<domain type='xen'> + <name>XenGuest1</name> + <uuid>45b60f51-88a9-47a8-a3b3-5e66d71b2283</uuid> + <memory unit='KiB'>524288</memory> + <currentMemory unit='KiB'>524288</currentMemory> + <vcpu placement='static'>1</vcpu> + <bootloader>/usr/bin/pygrub</bootloader> + <os> + <type arch='x86_64' machine='xenpv'>linux</type> + </os> + <clock offset='utc' adjustment='reset'/> + <on_poweroff>preserve</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>preserve</on_crash> + <devices> + <disk type='file' device='disk'> + <driver name='qemu' type='qcow2'/> + <source file='/var/lib/xen/images/debian/disk.qcow2'/> + <target dev='xvda' bus='xen'/> + </disk> + <interface type='ethernet'> + <mac address='5a:36:0e:be:00:09'/> + </interface> + <console type='pty'> + <target type='xen' port='0'/> + </console> + <input type='mouse' bus='xen'/> + <input type='keyboard' bus='xen'/> + <hostdev mode='subsystem' type='usb' managed='no'> + <source> + <address bus='1' device='3'/> + </source> + </hostdev> + </devices> +</domain> diff --git a/tests/xlconfigtest.c b/tests/xlconfigtest.c index 6819bad..456f373 100644 --- a/tests/xlconfigtest.c +++ b/tests/xlconfigtest.c @@ -229,6 +229,7 @@ mymain(void) DO_TEST_FORMAT("fullvirt-direct-kernel-boot-bogus-extra"); #endif DO_TEST("vif-typename"); + DO_TEST("usb"); virObjectUnref(caps); virObjectUnref(xmlopt); -- 2.1.4

I've change the commit message summary to "xlconfigtest: add test for USB config conversion" in my local branch. Otherwise looks good. Thanks! Regards, Jim On 05/19/2016 02:14 AM, Chunyan Liu wrote:
Signed-off-by: Chunyan Liu <cyliu@suse.com> --- tests/xlconfigdata/test-usb.cfg | 13 +++++++++++++ tests/xlconfigdata/test-usb.xml | 35 +++++++++++++++++++++++++++++++++++ tests/xlconfigtest.c | 1 + 3 files changed, 49 insertions(+) create mode 100644 tests/xlconfigdata/test-usb.cfg create mode 100644 tests/xlconfigdata/test-usb.xml
diff --git a/tests/xlconfigdata/test-usb.cfg b/tests/xlconfigdata/test-usb.cfg new file mode 100644 index 0000000..f0e616c --- /dev/null +++ b/tests/xlconfigdata/test-usb.cfg @@ -0,0 +1,13 @@ +name = "XenGuest1" +uuid = "45b60f51-88a9-47a8-a3b3-5e66d71b2283" +maxmem = 512 +memory = 512 +vcpus = 1 +localtime = 0 +on_poweroff = "preserve" +on_reboot = "restart" +on_crash = "preserve" +vif = [ "mac=5a:36:0e:be:00:09" ] +bootloader = "/usr/bin/pygrub" +disk = [ "format=qcow2,vdev=xvda,access=rw,backendtype=qdisk,target=/var/lib/xen/images/debian/disk.qcow2" ] +usbdev = [ "hostbus=1,hostaddr=3" ] diff --git a/tests/xlconfigdata/test-usb.xml b/tests/xlconfigdata/test-usb.xml new file mode 100644 index 0000000..7b5853d --- /dev/null +++ b/tests/xlconfigdata/test-usb.xml @@ -0,0 +1,35 @@ +<domain type='xen'> + <name>XenGuest1</name> + <uuid>45b60f51-88a9-47a8-a3b3-5e66d71b2283</uuid> + <memory unit='KiB'>524288</memory> + <currentMemory unit='KiB'>524288</currentMemory> + <vcpu placement='static'>1</vcpu> + <bootloader>/usr/bin/pygrub</bootloader> + <os> + <type arch='x86_64' machine='xenpv'>linux</type> + </os> + <clock offset='utc' adjustment='reset'/> + <on_poweroff>preserve</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>preserve</on_crash> + <devices> + <disk type='file' device='disk'> + <driver name='qemu' type='qcow2'/> + <source file='/var/lib/xen/images/debian/disk.qcow2'/> + <target dev='xvda' bus='xen'/> + </disk> + <interface type='ethernet'> + <mac address='5a:36:0e:be:00:09'/> + </interface> + <console type='pty'> + <target type='xen' port='0'/> + </console> + <input type='mouse' bus='xen'/> + <input type='keyboard' bus='xen'/> + <hostdev mode='subsystem' type='usb' managed='no'> + <source> + <address bus='1' device='3'/> + </source> + </hostdev> + </devices> +</domain> diff --git a/tests/xlconfigtest.c b/tests/xlconfigtest.c index 6819bad..456f373 100644 --- a/tests/xlconfigtest.c +++ b/tests/xlconfigtest.c @@ -229,6 +229,7 @@ mymain(void) DO_TEST_FORMAT("fullvirt-direct-kernel-boot-bogus-extra"); #endif DO_TEST("vif-typename"); + DO_TEST("usb");
virObjectUnref(caps); virObjectUnref(xmlopt);

On 05/19/2016 02:14 AM, Chunyan Liu wrote:
This patch series is to support pvusb in libxl driver.
--- Changes in v2: * add LIBXL_HAVE_PVUSB check * add convertion of domxml USB config to/from xl.cfg * address other comments
Chunyan Liu (4): libxl: support creating guest with USB hostdev
For this patch, I've fixed the nit Joao mentioned in my branch.
libxl: support hotplug USB host device
See my suggested change to patch2, which I have squashed in my branch.
Add convertion domxml USB config to/from xl.cfg xlconfigtest: add test on USB convertion
These look good. I've fixed the commit message nits in my local branch. Thanks for adding the conversion and test! I'll wait for your thoughts on my change to patch2 (and any other comments from Joao) before pushing the series. I'd also like to try all the pvusb work you've done in Xen and libvirt, but alas my test machine is having other problems now. I'll get that fixed and do some testing on Monday. Regards, Jim

On 05/20/2016 11:21 PM, Jim Fehlig wrote:
On 05/19/2016 02:14 AM, Chunyan Liu wrote:
This patch series is to support pvusb in libxl driver.
--- Changes in v2: * add LIBXL_HAVE_PVUSB check * add convertion of domxml USB config to/from xl.cfg * address other comments
Chunyan Liu (4): libxl: support creating guest with USB hostdev
For this patch, I've fixed the nit Joao mentioned in my branch.
libxl: support hotplug USB host device
See my suggested change to patch2, which I have squashed in my branch.
Add convertion domxml USB config to/from xl.cfg xlconfigtest: add test on USB convertion
These look good. I've fixed the commit message nits in my local branch. Thanks for adding the conversion and test!
I'll wait for your thoughts on my change to patch2 (and any other comments from Joao) before pushing the series. Jim, I have no further comments on patch 3 and 4 - these look good too. And based on discussion about your changes to patch 2 it all seems to be addressed too.
Joao
I'd also like to try all the pvusb work you've done in Xen and libvirt, but alas my test machine is having other problems now. I'll get that fixed and do some testing on Monday.
Regards, Jim

Chunyan Liu wrote:
This patch series is to support pvusb in libxl driver.
--- Changes in v2: * add LIBXL_HAVE_PVUSB check * add convertion of domxml USB config to/from xl.cfg * address other comments
Chunyan Liu (4): libxl: support creating guest with USB hostdev libxl: support hotplug USB host device Add convertion domxml USB config to/from xl.cfg xlconfigtest: add test on USB convertion
src/libxl/libxl_conf.c | 74 ++++++++++++++++++++ src/libxl/libxl_conf.h | 5 ++ src/libxl/libxl_domain.c | 16 ++++- src/libxl/libxl_driver.c | 144 +++++++++++++++++++++++++++++++++++++- src/xenconfig/xen_xl.c | 151 ++++++++++++++++++++++++++++++++++++++++ tests/xlconfigdata/test-usb.cfg | 13 ++++ tests/xlconfigdata/test-usb.xml | 35 ++++++++++ tests/xlconfigtest.c | 1 + 8 files changed, 435 insertions(+), 4 deletions(-) create mode 100644 tests/xlconfigdata/test-usb.cfg create mode 100644 tests/xlconfigdata/test-usb.xml
I've fixed all the nits and have pushed this series now. As Joao mentioned in the V1 review, we'll need a follow-up to add the USB subsys type to domaincapabilities now that the OVMF series containing an implementation of connectGetDomainCapabilities is pushed. I can take care of that. Thanks a lot Chunyan! Regards, Jim
participants (4)
-
Chun Yan Liu
-
Chunyan Liu
-
Jim Fehlig
-
Joao Martins