From: Chunyan Liu Date: Wed, 15 Jun 2016 06:00:11 +0000 (+0800) Subject: libxl: check available controller and port when hotplugging USB device X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=f5359e55ec3bceb0e156445305881d5274fc58dc;p=libvirt.git libxl: check available controller and port when hotplugging USB device When hotplugging a USB device, check if there is an available controller and port, if not, automatically create a USB controller of version 2.0 and 8 ports. Signed-off-by: Chunyan Liu --- diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c index 3eea69341b..1dedb3f361 100644 --- a/src/libxl/libxl_driver.c +++ b/src/libxl/libxl_driver.c @@ -3119,6 +3119,8 @@ libxlDomainAttachHostUSBDevice(libxlDriverPrivatePtr driver, libxl_device_usbdev usbdev; virHostdevManagerPtr hostdev_mgr = driver->hostdevMgr; int ret = -1; + size_t i; + int ports = 0, usbdevs = 0; libxl_device_usbdev_init(&usbdev); @@ -3126,6 +3128,36 @@ libxlDomainAttachHostUSBDevice(libxlDriverPrivatePtr driver, hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) goto cleanup; + /* search for available controller:port */ + for (i = 0; i < vm->def->ncontrollers; i++) + ports += vm->def->controllers[i]->opts.usbopts.ports; + + for (i = 0; i < vm->def->nhostdevs; i++) { + if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && + hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) + usbdevs++; + } + + if (ports <= usbdevs) { + /* no free ports, we will create a new usb controller */ + virDomainControllerDefPtr controller; + + if (!(controller = virDomainControllerDefNew(VIR_DOMAIN_CONTROLLER_TYPE_USB))) + goto cleanup; + + controller->model = VIR_DOMAIN_CONTROLLER_MODEL_USB_QUSB2; + controller->idx = -1; + controller->opts.usbopts.ports = 8; + + if (libxlDomainAttachControllerDevice(driver, vm, controller) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("No available USB controller and port, and " + "failed to attach a new one")); + virDomainControllerDefFree(controller); + goto cleanup; + } + } + if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs + 1) < 0) goto cleanup;