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)