From 2a58ed0bce8f2b5f1966fc67e56188a8175dd149 Mon Sep 17 00:00:00 2001 From: Chunyan Liu Date: Thu, 19 May 2016 16:14:33 +0800 Subject: [PATCH] libxl: support creating guest with USB hostdev 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:
Signed-off-by: Chunyan Liu Signed-off-by: Jim Fehlig --- src/libxl/libxl_conf.c | 74 ++++++++++++++++++++++++++++++++++++++++ src/libxl/libxl_conf.h | 5 +++ src/libxl/libxl_domain.c | 14 ++++++-- src/libxl/libxl_driver.c | 7 +++- 4 files changed, 97 insertions(+), 3 deletions(-) diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c index acb6594bc3..5989819377 100644 --- a/src/libxl/libxl_conf.c +++ b/src/libxl/libxl_conf.c @@ -1514,6 +1514,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) { @@ -1717,6 +1786,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 6547056dfe..8cb2b14c8d 100644 --- a/src/libxl/libxl_conf.h +++ b/src/libxl/libxl_conf.h @@ -184,6 +184,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 76379eb096..221af8754d 100644 --- a/src/libxl/libxl_domain.c +++ b/src/libxl/libxl_domain.c @@ -731,9 +731,14 @@ libxlDomainCleanup(libxlDriverPrivatePtr driver, int vnc_port; char *file; virHostdevManagerPtr hostdev_mgr = driver->hostdevMgr; + 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) @@ -1043,6 +1048,11 @@ libxlDomainStart(libxlDriverPrivatePtr driver, virHostdevManagerPtr hostdev_mgr = driver->hostdevMgr; libxl_asyncprogress_how aop_console_how; libxl_domain_restore_params params; + unsigned int hostdev_flags = VIR_HOSTDEV_SP_PCI; + +#ifdef LIBXL_HAVE_PVUSB + hostdev_flags |= VIR_HOSTDEV_SP_USB; +#endif libxl_domain_config_init(&d_config); @@ -1118,7 +1128,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 0644f60467..2c5d322248 100644 --- a/src/libxl/libxl_driver.c +++ b/src/libxl/libxl_driver.c @@ -351,6 +351,11 @@ libxlReconnectDomain(virDomainObjPtr vm, int len; uint8_t *data = NULL; virHostdevManagerPtr hostdev_mgr = driver->hostdevMgr; + unsigned int hostdev_flags = VIR_HOSTDEV_SP_PCI; + +#ifdef LIBXL_HAVE_PVUSB + hostdev_flags |= VIR_HOSTDEV_SP_USB; +#endif virObjectLock(vm); @@ -378,7 +383,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.39.5