On 06/15/2016 02:00 AM, Chunyan Liu wrote: > Support USB controller hot-plug and hot-unplug. > > #virsh attach-device dom usbctrl.xml > #virsh detach-device dom usbctrl.xml > usbctrl.xml example: > <controller type='usb' index='0' model='qusb2'> > > Signed-off-by: Chunyan Liu <cyliu@xxxxxxxx> > --- > src/libxl/libxl_driver.c | 144 +++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 144 insertions(+) > Looks like this is also partially responsible for recent build failures as libxlDomainAttachControllerDevice can be called from outside the LIBXL_HAVE_PVUSB conditional... Similarly libxlDomainDetachDeviceLive has the same issue ... 'libxl/libvirt_driver_libxl_impl_la-libxl_domain.lo' failed make[5]: *** [libxl/libvirt_driver_libxl_impl_la-libxl_domain.lo] Error 1 make[5]: *** Waiting for unfinished jobs.... libxl/libxl_driver.c: In function 'libxlDomainAttachDeviceLive': libxl/libxl_driver.c:3409:19: error: implicit declaration of function 'libxlDomainAttachControllerDevice' [-Werror=implicit-function-declaration] ret = libxlDomainAttachControllerDevice(driver, vm, dev->data.controller); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ libxl/libxl_driver.c:3409:13: error: nested extern declaration of 'libxlDomainAttachControllerDevice' [-Werror=nested-externs] ret = libxlDomainAttachControllerDevice(driver, vm, dev->data.controller); ^~~ libxl/libxl_driver.c: In function 'libxlDomainDetachDeviceLive': libxl/libxl_driver.c:3830:19: error: implicit declaration of function 'libxlDomainDetachControllerDevice' [-Werror=implicit-function-declaration] ret = libxlDomainDetachControllerDevice(driver, vm, dev); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ libxl/libxl_driver.c:3830:13: error: nested extern declaration of 'libxlDomainDetachControllerDevice' [-Werror=nested-externs] ret = libxlDomainDetachControllerDevice(driver, vm, dev); ^~~ cc1: all warnings being treated as errors Makefile:8678: recipe for target 'libxl/libvirt_driver_libxl_impl_la-libxl_driver.lo' failed John > diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c > index f507265..f614769 100644 > --- a/src/libxl/libxl_driver.c > +++ b/src/libxl/libxl_driver.c > @@ -3006,6 +3006,60 @@ libxlDomainAttachHostPCIDevice(libxlDriverPrivatePtr driver, > > #ifdef LIBXL_HAVE_PVUSB > static int > +libxlDomainAttachControllerDevice(libxlDriverPrivatePtr driver, > + virDomainObjPtr vm, > + virDomainControllerDefPtr controller) > +{ > + libxlDriverConfigPtr cfg = libxlDriverConfigGet(driver); > + const char *type = virDomainControllerTypeToString(controller->type); > + libxl_device_usbctrl usbctrl; > + int ret = -1; > + > + libxl_device_usbctrl_init(&usbctrl); > + > + if (controller->type != VIR_DOMAIN_CONTROLLER_TYPE_USB) { > + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, > + _("'%s' controller cannot be hot plugged."), > + type); > + goto cleanup; > + } > + > + if (controller->idx == -1) > + controller->idx = virDomainControllerFindUnusedIndex(vm->def, > + controller->type); > + > + if (controller->opts.usbopts.ports == -1) > + controller->opts.usbopts.ports = 8; > + > + if (virDomainControllerFind(vm->def, controller->type, controller->idx) >= 0) { > + virReportError(VIR_ERR_OPERATION_FAILED, > + _("target %s:%d already exists"), > + type, controller->idx); > + goto cleanup; > + } > + > + if (VIR_REALLOC_N(vm->def->controllers, vm->def->ncontrollers + 1) < 0) > + goto cleanup; > + > + if (libxlMakeUSBController(controller, &usbctrl) < 0) > + goto cleanup; > + > + if (libxl_device_usbctrl_add(cfg->ctx, vm->def->id, &usbctrl, 0) < 0) { > + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", > + _("libxenlight failed to attach USB controller")); > + goto cleanup; > + } > + > + virDomainControllerInsertPreAlloced(vm->def, controller); > + ret = 0; > + > + cleanup: > + virObjectUnref(cfg); > + libxl_device_usbctrl_dispose(&usbctrl); > + return ret; > +} > + > +static int > libxlDomainAttachHostUSBDevice(libxlDriverPrivatePtr driver, > virDomainObjPtr vm, > virDomainHostdevDefPtr hostdev) > @@ -3240,6 +3294,12 @@ libxlDomainAttachDeviceLive(libxlDriverPrivatePtr driver, > dev->data.disk = NULL; > break; > > + case VIR_DOMAIN_DEVICE_CONTROLLER: > + ret = libxlDomainAttachControllerDevice(driver, vm, dev->data.controller); > + if (!ret) > + dev->data.controller = NULL; > + break; > + ^^^^^^^ > case VIR_DOMAIN_DEVICE_NET: > ret = libxlDomainAttachNetDevice(driver, vm, > dev->data.net); > @@ -3270,6 +3330,7 @@ libxlDomainAttachDeviceConfig(virDomainDefPtr vmdef, virDomainDeviceDefPtr dev) > virDomainDiskDefPtr disk; > virDomainNetDefPtr net; > virDomainHostdevDefPtr hostdev; > + virDomainControllerDefPtr controller; > virDomainHostdevDefPtr found; > char mac[VIR_MAC_STRING_BUFLEN]; > > @@ -3287,6 +3348,21 @@ libxlDomainAttachDeviceConfig(virDomainDefPtr vmdef, virDomainDeviceDefPtr dev) > dev->data.disk = NULL; > break; > > + case VIR_DOMAIN_DEVICE_CONTROLLER: > + controller = dev->data.controller; > + if (controller->idx != -1 && > + virDomainControllerFind(vmdef, controller->type, > + controller->idx) >= 0) { > + virReportError(VIR_ERR_OPERATION_INVALID, "%s", > + _("Target already exists")); > + return -1; > + } > + > + if (virDomainControllerInsert(vmdef, controller) < 0) > + return -1; > + dev->data.controller = NULL; > + break; > + > case VIR_DOMAIN_DEVICE_NET: > net = dev->data.net; > if (virDomainHasNet(vmdef, net)) { > @@ -3425,6 +3501,57 @@ libxlDomainDetachHostPCIDevice(libxlDriverPrivatePtr driver, > > #ifdef LIBXL_HAVE_PVUSB > static int > +libxlDomainDetachControllerDevice(libxlDriverPrivatePtr driver, > + virDomainObjPtr vm, > + virDomainDeviceDefPtr dev) > +{ > + int idx, ret = -1; > + virDomainControllerDefPtr detach = NULL; > + virDomainControllerDefPtr controller = dev->data.controller; > + const char *type = virDomainControllerTypeToString(controller->type); > + libxl_device_usbctrl usbctrl; > + libxlDriverConfigPtr cfg = libxlDriverConfigGet(driver); > + > + libxl_device_usbctrl_init(&usbctrl); > + > + if (controller->type != VIR_DOMAIN_CONTROLLER_TYPE_USB) { > + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, > + _("'%s' controller cannot be hot plugged."), > + type); > + goto cleanup; > + } > + > + if ((idx = virDomainControllerFind(vm->def, > + controller->type, > + controller->idx)) < 0) { > + virReportError(VIR_ERR_OPERATION_FAILED, > + _("controller %s:%d not found"), > + type, controller->idx); > + goto cleanup; > + } > + > + detach = vm->def->controllers[idx]; > + > + if (libxlMakeUSBController(controller, &usbctrl) < 0) > + goto cleanup; > + > + if (libxl_device_usbctrl_remove(cfg->ctx, vm->def->id, &usbctrl, 0) < 0) { > + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", > + _("libxenlight failed to detach USB controller")); > + goto cleanup; > + } > + > + virDomainControllerRemove(vm->def, idx); > + ret = 0; > + > + cleanup: > + virDomainControllerDefFree(detach); > + virObjectUnref(cfg); > + libxl_device_usbctrl_dispose(&usbctrl); > + return ret; > +} > + > +static int > libxlDomainDetachHostUSBDevice(libxlDriverPrivatePtr driver, > virDomainObjPtr vm, > virDomainHostdevDefPtr hostdev) > @@ -3588,6 +3715,10 @@ libxlDomainDetachDeviceLive(libxlDriverPrivatePtr driver, > ret = libxlDomainDetachDeviceDiskLive(vm, dev); > break; > > + case VIR_DOMAIN_DEVICE_CONTROLLER: > + ret = libxlDomainDetachControllerDevice(driver, vm, dev); > + break; > + ^^^^ > case VIR_DOMAIN_DEVICE_NET: > ret = libxlDomainDetachNetDevice(driver, vm, > dev->data.net); > @@ -3622,6 +3753,7 @@ libxlDomainDetachDeviceConfig(virDomainDefPtr vmdef, virDomainDeviceDefPtr dev) > { > virDomainDiskDefPtr disk, detach; > virDomainHostdevDefPtr hostdev, det_hostdev; > + virDomainControllerDefPtr cont, det_cont; > virDomainNetDefPtr net; > int idx; > > @@ -3636,6 +3768,18 @@ libxlDomainDetachDeviceConfig(virDomainDefPtr vmdef, virDomainDeviceDefPtr dev) > virDomainDiskDefFree(detach); > break; > > + case VIR_DOMAIN_DEVICE_CONTROLLER: > + cont = dev->data.controller; > + if ((idx = virDomainControllerFind(vmdef, cont->type, > + cont->idx)) < 0) { > + virReportError(VIR_ERR_INVALID_ARG, "%s", > + _("device not present in domain configuration")); > + return -1; > + } > + det_cont = virDomainControllerRemove(vmdef, idx); > + virDomainControllerDefFree(det_cont); > + break; > + > case VIR_DOMAIN_DEVICE_NET: > net = dev->data.net; > if ((idx = virDomainNetFindIdx(vmdef, net)) < 0) > -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list