[libvirt] [PATCH V2 0/7] libxl: add support of pvusb controller

This patch series is to add pvusb controller support in libxl driver. It should be applied on previous pvusb device support patch series. --- Changes: * drop pvusb1 and pvusb2 model * add check in qemu device post-parse to report error of unsupported 'qusb1' and 'qusb2' model Chunyan Liu (7): extend usb controller model to support xen pvusb libxl: support USB controllers in creation time libxl: support usb controller hotplug libxl: check available controller and port when hotplugging USB device xenconfig: add conversion of usb controller config to and from xml xlconfigtest: add test for usb controller conversion qemuDomainDeviceDefPostParse: add USB controller model check docs/formatdomain.html.in | 4 +- docs/schemas/domaincommon.rng | 2 + src/conf/domain_conf.c | 2 + src/conf/domain_conf.h | 2 + src/libxl/libxl_conf.c | 84 ++++++++++++++++ src/libxl/libxl_conf.h | 4 + src/libxl/libxl_driver.c | 176 +++++++++++++++++++++++++++++++++ src/qemu/qemu_command.c | 2 + src/qemu/qemu_domain.c | 13 +++ src/xenconfig/xen_xl.c | 190 ++++++++++++++++++++++++++++++++++++ tests/xlconfigdata/test-usbctrl.cfg | 13 +++ tests/xlconfigdata/test-usbctrl.xml | 31 ++++++ tests/xlconfigtest.c | 1 + 13 files changed, 523 insertions(+), 1 deletion(-) create mode 100644 tests/xlconfigdata/test-usbctrl.cfg create mode 100644 tests/xlconfigdata/test-usbctrl.xml -- 2.1.4

According to libxl implementation, it supports pvusb controller of version 1.1 and version 2.0, and it supports two types of backend, 'pvusb' (dom0 backend) and 'qusb' (qemu backend). But currently pvusb backend is not checked in yet. To match libxl support, extend usb controller schema to support two more models: qusb1 (qusb, version 1.1) and 'qusb2' (qusb version 2.0). Signed-off-by: Chunyan Liu <cyliu@suse.com> --- Changes: drop pvusb1 and pvusb2 definition docs/formatdomain.html.in | 4 +++- docs/schemas/domaincommon.rng | 2 ++ src/conf/domain_conf.c | 2 ++ src/conf/domain_conf.h | 2 ++ src/qemu/qemu_command.c | 2 ++ 5 files changed, 11 insertions(+), 1 deletion(-) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 82b6aae..b778705 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -3075,7 +3075,9 @@ <dd>A <code>usb</code> controller has an optional attribute <code>model</code>, which is one of "piix3-uhci", "piix4-uhci", "ehci", "ich9-ehci1", "ich9-uhci1", "ich9-uhci2", "ich9-uhci3", - "vt82c686b-uhci", "pci-ohci" or "nec-xhci". Additionally, + "vt82c686b-uhci", "pci-ohci", "nec-xhci", "qusb1" (xen pvusb + with qemu backend, version 1.1) or "qusb2" (xen pvusb with qemu + backend, version 2.0). Additionally, <span class="since">since 0.10.0</span>, if the USB bus needs to be explicitly disabled for the guest, <code>model='none'</code> may be used. <span class="since">Since 1.0.5</span>, no default diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 2e07505..311c1bf 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -1780,6 +1780,8 @@ <value>pci-ohci</value> <value>nec-xhci</value> <value>none</value> + <value>qusb1</value> + <value>qusb2</value> </choice> </attribute> </optional> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 9504e5f..5fb18cc 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -356,6 +356,8 @@ VIR_ENUM_IMPL(virDomainControllerModelUSB, VIR_DOMAIN_CONTROLLER_MODEL_USB_LAST, "vt82c686b-uhci", "pci-ohci", "nec-xhci", + "qusb1", + "qusb2", "none") VIR_ENUM_IMPL(virDomainFS, VIR_DOMAIN_FS_TYPE_LAST, diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 15f9c80..4c9e1e3 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -685,6 +685,8 @@ typedef enum { VIR_DOMAIN_CONTROLLER_MODEL_USB_VT82C686B_UHCI, VIR_DOMAIN_CONTROLLER_MODEL_USB_PCI_OHCI, VIR_DOMAIN_CONTROLLER_MODEL_USB_NEC_XHCI, + VIR_DOMAIN_CONTROLLER_MODEL_USB_QUSB1, + VIR_DOMAIN_CONTROLLER_MODEL_USB_QUSB2, VIR_DOMAIN_CONTROLLER_MODEL_USB_NONE, VIR_DOMAIN_CONTROLLER_MODEL_USB_LAST diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 48be399..1998384 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -133,6 +133,8 @@ VIR_ENUM_IMPL(qemuControllerModelUSB, VIR_DOMAIN_CONTROLLER_MODEL_USB_LAST, "vt82c686b-usb-uhci", "pci-ohci", "nec-usb-xhci", + "qusb1", + "qusb2", "none"); VIR_ENUM_DECL(qemuDomainFSDriver) -- 2.1.4

On Wed, 2016-06-15 at 14:00 +0800, Chunyan Liu wrote:
According to libxl implementation, it supports pvusb controller of version 1.1 and version 2.0, and it supports two types of backend, 'pvusb' (dom0 backend) and 'qusb' (qemu backend). But currently pvusb backend is not checked in yet.
To match libxl support, extend usb controller schema to support two more models: qusb1 (qusb, version 1.1) and 'qusb2' (qusb version 2.0).
Signed-off-by: Chunyan Liu <cyliu@suse.com> --- Changes: drop pvusb1 and pvusb2 definition
docs/formatdomain.html.in | 4 +++- docs/schemas/domaincommon.rng | 2 ++ src/conf/domain_conf.c | 2 ++ src/conf/domain_conf.h | 2 ++ src/qemu/qemu_command.c | 2 ++ 5 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 82b6aae..b778705 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -3075,7 +3075,9 @@ <dd>A <code>usb</code> controller has an optional attribute <code>model</code>, which is one of "piix3-uhci", "piix4-uhci", "ehci", "ich9-ehci1", "ich9-uhci1", "ich9-uhci2", "ich9-uhci3", - "vt82c686b-uhci", "pci-ohci" or "nec-xhci". Additionally, + "vt82c686b-uhci", "pci-ohci", "nec-xhci", "qusb1" (xen pvusb + with qemu backend, version 1.1) or "qusb2" (xen pvusb with qemu + backend, version 2.0). Additionally, <span class="since">since 0.10.0</span>, if the USB bus needs to be explicitly disabled for the guest, <code>model='none'</code> may be used. <span class="since">Since 1.0.5</span>, no default diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 2e07505..311c1bf 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -1780,6 +1780,8 @@ <value>pci-ohci</value> <value>nec-xhci</value> <value>none</value> + <value>qusb1</value> + <value>qusb2</value> </choice> </attribute> </optional> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 9504e5f..5fb18cc 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -356,6 +356,8 @@ VIR_ENUM_IMPL(virDomainControllerModelUSB, VIR_DOMAIN_CONTROLLER_MODEL_USB_LAST, "vt82c686b-uhci", "pci-ohci", "nec-xhci", + "qusb1", + "qusb2", "none")
VIR_ENUM_IMPL(virDomainFS, VIR_DOMAIN_FS_TYPE_LAST, diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 15f9c80..4c9e1e3 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -685,6 +685,8 @@ typedef enum { VIR_DOMAIN_CONTROLLER_MODEL_USB_VT82C686B_UHCI, VIR_DOMAIN_CONTROLLER_MODEL_USB_PCI_OHCI, VIR_DOMAIN_CONTROLLER_MODEL_USB_NEC_XHCI, + VIR_DOMAIN_CONTROLLER_MODEL_USB_QUSB1, + VIR_DOMAIN_CONTROLLER_MODEL_USB_QUSB2, VIR_DOMAIN_CONTROLLER_MODEL_USB_NONE,
VIR_DOMAIN_CONTROLLER_MODEL_USB_LAST diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 48be399..1998384 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -133,6 +133,8 @@ VIR_ENUM_IMPL(qemuControllerModelUSB, VIR_DOMAIN_CONTROLLER_MODEL_USB_LAST, "vt82c686b-usb-uhci", "pci-ohci", "nec-usb-xhci", + "qusb1", + "qusb2", "none");
VIR_ENUM_DECL(qemuDomainFSDriver)
Got a build failure in virDomainUSBAddressControllerModelToPorts. This function will need to handle the new values. Other than that, ACK. I'll push the patch with this more hunk: --- a/src/conf/domain_addr.c +++ b/src/conf/domain_addr.c @@ -1393,6 +1393,12 @@ virDomainUSBAddressControllerModelToPorts(virDomainControllerDefPtr cont) return cont->opts.usbopts.ports; return 4; + case VIR_DOMAIN_CONTROLLER_MODEL_USB_QUSB1: + case VIR_DOMAIN_CONTROLLER_MODEL_USB_QUSB2: + if (cont->opts.usbopts.ports != -1) + return cont->opts.usbopts.ports; + return 8; + case VIR_DOMAIN_CONTROLLER_MODEL_USB_NONE: case VIR_DOMAIN_CONTROLLER_MODEL_USB_LAST: break; -- Cedric

To support USB Controller in xen guest domains, just add USB controller in domain config xml as following: <controller type='usb' model='qusb2' ports='4'/> Signed-off-by: Chunyan Liu <cyliu@suse.com> --- Changes: drop pvusb1 and pvusb2 models src/libxl/libxl_conf.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/libxl/libxl_conf.h | 4 +++ 2 files changed, 88 insertions(+) diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c index 5989819..a7d91d3 100644 --- a/src/libxl/libxl_conf.c +++ b/src/libxl/libxl_conf.c @@ -1516,6 +1516,87 @@ int libxlDriverConfigLoadFile(libxlDriverConfigPtr cfg, #ifdef LIBXL_HAVE_PVUSB int +libxlMakeUSBController(virDomainControllerDefPtr controller, + libxl_device_usbctrl *usbctrl) +{ + usbctrl->devid = controller->idx; + + if (controller->type != VIR_DOMAIN_CONTROLLER_TYPE_USB) + return -1; + + if (controller->model == -1) { + usbctrl->version = 2; + usbctrl->type = LIBXL_USBCTRL_TYPE_QUSB; + } else { + switch (controller->model) { + case VIR_DOMAIN_CONTROLLER_MODEL_USB_QUSB1: + usbctrl->version = 1; + usbctrl->type = LIBXL_USBCTRL_TYPE_QUSB; + break; + + case VIR_DOMAIN_CONTROLLER_MODEL_USB_QUSB2: + usbctrl->version = 2; + usbctrl->type = LIBXL_USBCTRL_TYPE_QUSB; + break; + + default: + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("unsupported usb model")); + return -1; + } + } + + if (controller->opts.usbopts.ports == -1) + usbctrl->ports = 8; + else + usbctrl->ports = controller->opts.usbopts.ports; + + return 0; +} + +static int +libxlMakeUSBControllerList(virDomainDefPtr def, libxl_domain_config *d_config) +{ + virDomainControllerDefPtr *l_controllers = def->controllers; + size_t ncontrollers = def->ncontrollers; + size_t nusbctrls = 0; + libxl_device_usbctrl *x_usbctrls; + size_t i; + + if (ncontrollers == 0) + return 0; + + if (VIR_ALLOC_N(x_usbctrls, ncontrollers) < 0) + return -1; + + for (i = 0; i < ncontrollers; i++) { + if (l_controllers[i]->type != VIR_DOMAIN_CONTROLLER_TYPE_USB) + continue; + + libxl_device_usbctrl_init(&x_usbctrls[nusbctrls]); + + if (libxlMakeUSBController(l_controllers[i], + &x_usbctrls[nusbctrls]) < 0) + goto error; + + nusbctrls++; + } + + VIR_SHRINK_N(x_usbctrls, ncontrollers, ncontrollers - nusbctrls); + d_config->usbctrls = x_usbctrls; + d_config->num_usbctrls = nusbctrls; + + return 0; + + error: + for (i = 0; i < nusbctrls; i++) + libxl_device_usbctrl_dispose(&x_usbctrls[i]); + + VIR_FREE(x_usbctrls); + return -1; +} + +int libxlMakeUSB(virDomainHostdevDefPtr hostdev, libxl_device_usbdev *usbdev) { virDomainHostdevSubsysUSBPtr usbsrc = &hostdev->source.subsys.u.usb; @@ -1787,6 +1868,9 @@ libxlBuildDomainConfig(virPortAllocatorPtr graphicsports, return -1; #ifdef LIBXL_HAVE_PVUSB + if (libxlMakeUSBControllerList(def, d_config) < 0) + return -1; + if (libxlMakeUSBList(def, d_config) < 0) return -1; #endif diff --git a/src/libxl/libxl_conf.h b/src/libxl/libxl_conf.h index 8cb2b14..ed5a3de 100644 --- a/src/libxl/libxl_conf.h +++ b/src/libxl/libxl_conf.h @@ -186,6 +186,10 @@ libxlMakePCI(virDomainHostdevDefPtr hostdev, libxl_device_pci *pcidev); # ifdef LIBXL_HAVE_PVUSB int +libxlMakeUSBController(virDomainControllerDefPtr controller, + libxl_device_usbctrl *usbctrl); + +int libxlMakeUSB(virDomainHostdevDefPtr hostdev, libxl_device_usbdev *usbdev); # endif -- 2.1.4

On Wed, 2016-06-15 at 14:00 +0800, Chunyan Liu wrote:
To support USB Controller in xen guest domains, just add USB controller in domain config xml as following: <controller type='usb' model='qusb2' ports='4'/>
Signed-off-by: Chunyan Liu <cyliu@suse.com> --- Changes: drop pvusb1 and pvusb2 models
src/libxl/libxl_conf.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/libxl/libxl_conf.h | 4 +++ 2 files changed, 88 insertions(+)
diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c index 5989819..a7d91d3 100644 --- a/src/libxl/libxl_conf.c +++ b/src/libxl/libxl_conf.c @@ -1516,6 +1516,87 @@ int libxlDriverConfigLoadFile(libxlDriverConfigPtr cfg,
#ifdef LIBXL_HAVE_PVUSB int +libxlMakeUSBController(virDomainControllerDefPtr controller, + libxl_device_usbctrl *usbctrl) +{ + usbctrl->devid = controller->idx; + + if (controller->type != VIR_DOMAIN_CONTROLLER_TYPE_USB) + return -1; + + if (controller->model == -1) { + usbctrl->version = 2; + usbctrl->type = LIBXL_USBCTRL_TYPE_QUSB; + } else { + switch (controller->model) { + case VIR_DOMAIN_CONTROLLER_MODEL_USB_QUSB1: + usbctrl->version = 1; + usbctrl->type = LIBXL_USBCTRL_TYPE_QUSB; + break; + + case VIR_DOMAIN_CONTROLLER_MODEL_USB_QUSB2: + usbctrl->version = 2; + usbctrl->type = LIBXL_USBCTRL_TYPE_QUSB; + break; + + default: + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("unsupported usb model")); + return -1; + } + } + + if (controller->opts.usbopts.ports == -1) + usbctrl->ports = 8; + else + usbctrl->ports = controller->opts.usbopts.ports; + + return 0; +} + +static int +libxlMakeUSBControllerList(virDomainDefPtr def, libxl_domain_config *d_config) +{ + virDomainControllerDefPtr *l_controllers = def->controllers; + size_t ncontrollers = def->ncontrollers; + size_t nusbctrls = 0; + libxl_device_usbctrl *x_usbctrls; + size_t i; + + if (ncontrollers == 0) + return 0; + + if (VIR_ALLOC_N(x_usbctrls, ncontrollers) < 0) + return -1; + + for (i = 0; i < ncontrollers; i++) { + if (l_controllers[i]->type != VIR_DOMAIN_CONTROLLER_TYPE_USB) + continue; + + libxl_device_usbctrl_init(&x_usbctrls[nusbctrls]); + + if (libxlMakeUSBController(l_controllers[i], + &x_usbctrls[nusbctrls]) < 0) + goto error; + + nusbctrls++; + } + + VIR_SHRINK_N(x_usbctrls, ncontrollers, ncontrollers - nusbctrls); + d_config->usbctrls = x_usbctrls; + d_config->num_usbctrls = nusbctrls; + + return 0; + + error: + for (i = 0; i < nusbctrls; i++) + libxl_device_usbctrl_dispose(&x_usbctrls[i]); + + VIR_FREE(x_usbctrls); + return -1; +} + +int libxlMakeUSB(virDomainHostdevDefPtr hostdev, libxl_device_usbdev *usbdev) { virDomainHostdevSubsysUSBPtr usbsrc = &hostdev->source.subsys.u.usb; @@ -1787,6 +1868,9 @@ libxlBuildDomainConfig(virPortAllocatorPtr graphicsports, return -1;
#ifdef LIBXL_HAVE_PVUSB + if (libxlMakeUSBControllerList(def, d_config) < 0) + return -1; + if (libxlMakeUSBList(def, d_config) < 0) return -1; #endif diff --git a/src/libxl/libxl_conf.h b/src/libxl/libxl_conf.h index 8cb2b14..ed5a3de 100644 --- a/src/libxl/libxl_conf.h +++ b/src/libxl/libxl_conf.h @@ -186,6 +186,10 @@ libxlMakePCI(virDomainHostdevDefPtr hostdev, libxl_device_pci *pcidev);
# ifdef LIBXL_HAVE_PVUSB int +libxlMakeUSBController(virDomainControllerDefPtr controller, + libxl_device_usbctrl *usbctrl); + +int libxlMakeUSB(virDomainHostdevDefPtr hostdev, libxl_device_usbdev *usbdev); # endif
ACK and pushed -- Cedric

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@suse.com> --- src/libxl/libxl_driver.c | 144 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) 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) -- 2.1.4

On Wed, 2016-06-15 at 14:00 +0800, 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@suse.com> --- src/libxl/libxl_driver.c | 144 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 144 insertions(+)
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)
ACK and pushed -- Cedric

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

When hotplug a USB device, check if there is available controller and port, if not, automatically create a USB controller of version 2.0 and 8 ports. Signed-off-by: Chunyan Liu <cyliu@suse.com> --- src/libxl/libxl_driver.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c index f614769..d9d7e3c 100644 --- a/src/libxl/libxl_driver.c +++ b/src/libxl/libxl_driver.c @@ -3068,6 +3068,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); @@ -3075,6 +3077,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 USB controller")); + virDomainControllerDefFree(controller); + goto cleanup; + } + } + if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs + 1) < 0) goto cleanup; -- 2.1.4

On Wed, 2016-06-15 at 14:00 +0800, Chunyan Liu wrote:
When hotplug a USB device, check if there is available controller
typos: 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 <cyliu@suse.com> --- src/libxl/libxl_driver.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+)
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c index f614769..d9d7e3c 100644 --- a/src/libxl/libxl_driver.c +++ b/src/libxl/libxl_driver.c @@ -3068,6 +3068,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);
@@ -3075,6 +3077,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 USB controller"));
Rewording: "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;
ACK and pushed with the wording changes. -- Cedric

Signed-off-by: Chunyan Liu <cyliu@suse.com> --- Changes: drop pvusb1 and pvusb2 models src/xenconfig/xen_xl.c | 190 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 190 insertions(+) diff --git a/src/xenconfig/xen_xl.c b/src/xenconfig/xen_xl.c index 5879c66..90213ec 100644 --- a/src/xenconfig/xen_xl.c +++ b/src/xenconfig/xen_xl.c @@ -503,6 +503,110 @@ xenParseXLInputDevs(virConfPtr conf, virDomainDefPtr def) } static int +xenParseXLUSBController(virConfPtr conf, virDomainDefPtr def) +{ + virConfValuePtr list = virConfGetValue(conf, "usbctrl"); + virDomainControllerDefPtr controller = NULL; + + if (list && list->type == VIR_CONF_LIST) { + list = list->list; + while (list) { + char type[8]; + char version[4]; + char ports[4]; + char *key; + int usbctrl_version = 2; /* by default USB 2.0 */ + int usbctrl_ports = 8; /* by default 8 ports */ + int usbctrl_type = -1; + + type[0] = version[0] = ports[0] = '\0'; + + if ((list->type != VIR_CONF_STRING) || (list->str == NULL)) + goto skipusbctrl; + /* usbctrl=['type=pv,version=2,ports=8'] */ + key = list->str; + while (key) { + char *data; + char *nextkey = strchr(key, ','); + + if (!(data = strchr(key, '='))) + goto skipusbctrl; + data++; + + if (STRPREFIX(key, "type=")) { + int len = nextkey ? (nextkey - data) : sizeof(type) - 1; + if (virStrncpy(type, data, len, sizeof(type)) == NULL) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("type %s invalid"), + data); + goto skipusbctrl; + } + } else if (STRPREFIX(key, "version=")) { + int len = nextkey ? (nextkey - data) : sizeof(version) - 1; + if (virStrncpy(version, data, len, sizeof(version)) == NULL) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("version %s invalid"), + data); + goto skipusbctrl; + } + if (virStrToLong_i(version, NULL, 16, &usbctrl_version) < 0) + goto skipusbctrl; + } else if (STRPREFIX(key, "ports=")) { + int len = nextkey ? (nextkey - data) : sizeof(ports) - 1; + if (virStrncpy(ports, data, len, sizeof(ports)) == NULL) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("version %s invalid"), + data); + goto skipusbctrl; + } + if (virStrToLong_i(ports, NULL, 16, &usbctrl_ports) < 0) + goto skipusbctrl; + } + + while (nextkey && (nextkey[0] == ',' || + nextkey[0] == ' ' || + nextkey[0] == '\t')) + nextkey++; + key = nextkey; + } + + if (type[0] == '\0') { + if (usbctrl_version == 1) + usbctrl_type = VIR_DOMAIN_CONTROLLER_MODEL_USB_QUSB1; + else + usbctrl_type = VIR_DOMAIN_CONTROLLER_MODEL_USB_QUSB2; + } else { + if (STREQLEN(type, "qusb", 4)) { + if (usbctrl_version == 1) + usbctrl_type = VIR_DOMAIN_CONTROLLER_MODEL_USB_QUSB1; + else + usbctrl_type = VIR_DOMAIN_CONTROLLER_MODEL_USB_QUSB2; + } else { + goto skipusbctrl; + } + } + + if (!(controller = virDomainControllerDefNew(VIR_DOMAIN_CONTROLLER_TYPE_USB))) + return -1; + + controller->type = VIR_DOMAIN_CONTROLLER_TYPE_USB; + controller->model = usbctrl_type; + controller->opts.usbopts.ports = usbctrl_ports; + + if (VIR_APPEND_ELEMENT(def->controllers, def->ncontrollers, controller) < 0) { + virDomainControllerDefFree(controller); + return -1; + } + + skipusbctrl: + list = list->next; + } + } + + return 0; +} + +static int xenParseXLUSB(virConfPtr conf, virDomainDefPtr def) { virConfValuePtr list = virConfGetValue(conf, "usbdev"); @@ -612,6 +716,9 @@ xenParseXL(virConfPtr conf, if (xenParseXLUSB(conf, def) < 0) goto cleanup; + if (xenParseXLUSBController(conf, def) < 0) + goto cleanup; + if (virDomainDefPostParse(def, caps, VIR_DOMAIN_DEF_PARSE_ABI_UPDATE, xmlopt) < 0) goto cleanup; @@ -1090,6 +1197,86 @@ xenFormatXLInputDevs(virConfPtr conf, virDomainDefPtr def) } static int +xenFormatXLUSBController(virConfPtr conf, + virDomainDefPtr def) +{ + virConfValuePtr usbctrlVal = NULL; + int hasUSBCtrl = 0; + size_t i; + + for (i = 0; i < def->ncontrollers; i++) { + if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_USB) { + hasUSBCtrl = 1; + break; + } + } + + if (!hasUSBCtrl) + return 0; + + if (VIR_ALLOC(usbctrlVal) < 0) + return -1; + + usbctrlVal->type = VIR_CONF_LIST; + usbctrlVal->list = NULL; + + for (i = 0; i < def->ncontrollers; i++) { + if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_USB) { + virConfValuePtr val, tmp; + virBuffer buf = VIR_BUFFER_INITIALIZER; + + if (def->controllers[i]->model != -1) { + switch (def->controllers[i]->model) { + case VIR_DOMAIN_CONTROLLER_MODEL_USB_QUSB1: + virBufferAddLit(&buf, "type=qusb,version=1,"); + break; + + case VIR_DOMAIN_CONTROLLER_MODEL_USB_QUSB2: + virBufferAddLit(&buf, "type=qusb,version=2,"); + break; + + default: + goto error; + } + } + + if (def->controllers[i]->opts.usbopts.ports != -1) + virBufferAsprintf(&buf, "ports=%x", + def->controllers[i]->opts.usbopts.ports); + + if (VIR_ALLOC(val) < 0) { + virBufferFreeAndReset(&buf); + goto error; + } + val->type = VIR_CONF_STRING; + val->str = virBufferContentAndReset(&buf); + tmp = usbctrlVal->list; + while (tmp && tmp->next) + tmp = tmp->next; + if (tmp) + tmp->next = val; + else + usbctrlVal->list = val; + } + } + + if (usbctrlVal->list != NULL) { + int ret = virConfSetValue(conf, "usbctrl", usbctrlVal); + usbctrlVal = NULL; + if (ret < 0) + return -1; + } + VIR_FREE(usbctrlVal); + + return 0; + + error: + virConfFreeValue(usbctrlVal); + return -1; +} + + +static int xenFormatXLUSB(virConfPtr conf, virDomainDefPtr def) { @@ -1182,6 +1369,9 @@ xenFormatXL(virDomainDefPtr def, virConnectPtr conn) if (xenFormatXLUSB(conf, def) < 0) goto cleanup; + if (xenFormatXLUSBController(conf, def) < 0) + goto cleanup; + return conf; cleanup: -- 2.1.4

On Wed, 2016-06-15 at 14:00 +0800, Chunyan Liu wrote: Missing a commit description, even a short one to say we're adding USB controller conversion to and from libxl's config files.
Signed-off-by: Chunyan Liu <cyliu@suse.com> --- Changes: drop pvusb1 and pvusb2 models
src/xenconfig/xen_xl.c | 190 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 190 insertions(+)
diff --git a/src/xenconfig/xen_xl.c b/src/xenconfig/xen_xl.c index 5879c66..90213ec 100644 --- a/src/xenconfig/xen_xl.c +++ b/src/xenconfig/xen_xl.c @@ -503,6 +503,110 @@ xenParseXLInputDevs(virConfPtr conf, virDomainDefPtr def) }
static int +xenParseXLUSBController(virConfPtr conf, virDomainDefPtr def) +{ + virConfValuePtr list = virConfGetValue(conf, "usbctrl"); + virDomainControllerDefPtr controller = NULL; + + if (list && list->type == VIR_CONF_LIST) { + list = list->list; + while (list) { + char type[8]; + char version[4]; + char ports[4]; + char *key; + int usbctrl_version = 2; /* by default USB 2.0 */ + int usbctrl_ports = 8; /* by default 8 ports */ + int usbctrl_type = -1; + + type[0] = version[0] = ports[0] = '\0'; + + if ((list->type != VIR_CONF_STRING) || (list->str == NULL)) + goto skipusbctrl; + /* usbctrl=['type=pv,version=2,ports=8'] */ + key = list->str; + while (key) { + char *data; + char *nextkey = strchr(key, ','); + + if (!(data = strchr(key, '='))) + goto skipusbctrl; + data++; + + if (STRPREFIX(key, "type=")) { + int len = nextkey ? (nextkey - data) : sizeof(type) - 1; + if (virStrncpy(type, data, len, sizeof(type)) == NULL) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("type %s invalid"), + data); + goto skipusbctrl; + } + } else if (STRPREFIX(key, "version=")) { + int len = nextkey ? (nextkey - data) : sizeof(version) - 1; + if (virStrncpy(version, data, len, sizeof(version)) == NULL) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("version %s invalid"), + data); + goto skipusbctrl; + } + if (virStrToLong_i(version, NULL, 16, &usbctrl_version) < 0) + goto skipusbctrl; + } else if (STRPREFIX(key, "ports=")) { + int len = nextkey ? (nextkey - data) : sizeof(ports) - 1; + if (virStrncpy(ports, data, len, sizeof(ports)) == NULL) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("version %s invalid"), + data); + goto skipusbctrl; + } + if (virStrToLong_i(ports, NULL, 16, &usbctrl_ports) < 0) + goto skipusbctrl; + } + + while (nextkey && (nextkey[0] == ',' || + nextkey[0] == ' ' || + nextkey[0] == '\t')) + nextkey++; + key = nextkey; + } + + if (type[0] == '\0') { + if (usbctrl_version == 1) + usbctrl_type = VIR_DOMAIN_CONTROLLER_MODEL_USB_QUSB1; + else + usbctrl_type = VIR_DOMAIN_CONTROLLER_MODEL_USB_QUSB2; + } else { + if (STREQLEN(type, "qusb", 4)) { + if (usbctrl_version == 1) + usbctrl_type = VIR_DOMAIN_CONTROLLER_MODEL_USB_QUSB1; + else + usbctrl_type = VIR_DOMAIN_CONTROLLER_MODEL_USB_QUSB2; + } else { + goto skipusbctrl; + } + } + + if (!(controller = virDomainControllerDefNew(VIR_DOMAIN_CONTROLLER_TYPE_USB))) + return -1; + + controller->type = VIR_DOMAIN_CONTROLLER_TYPE_USB; + controller->model = usbctrl_type; + controller->opts.usbopts.ports = usbctrl_ports; + + if (VIR_APPEND_ELEMENT(def->controllers, def->ncontrollers, controller) < 0) { + virDomainControllerDefFree(controller); + return -1; + } + + skipusbctrl: + list = list->next; + } + } + + return 0; +} + +static int xenParseXLUSB(virConfPtr conf, virDomainDefPtr def) { virConfValuePtr list = virConfGetValue(conf, "usbdev"); @@ -612,6 +716,9 @@ xenParseXL(virConfPtr conf, if (xenParseXLUSB(conf, def) < 0) goto cleanup;
+ if (xenParseXLUSBController(conf, def) < 0) + goto cleanup; + if (virDomainDefPostParse(def, caps, VIR_DOMAIN_DEF_PARSE_ABI_UPDATE, xmlopt) < 0) goto cleanup; @@ -1090,6 +1197,86 @@ xenFormatXLInputDevs(virConfPtr conf, virDomainDefPtr def) }
static int +xenFormatXLUSBController(virConfPtr conf, + virDomainDefPtr def) +{ + virConfValuePtr usbctrlVal = NULL; + int hasUSBCtrl = 0; + size_t i; + + for (i = 0; i < def->ncontrollers; i++) { + if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_USB) { + hasUSBCtrl = 1; + break; + } + } + + if (!hasUSBCtrl) + return 0; + + if (VIR_ALLOC(usbctrlVal) < 0) + return -1; + + usbctrlVal->type = VIR_CONF_LIST; + usbctrlVal->list = NULL; + + for (i = 0; i < def->ncontrollers; i++) { + if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_USB) { + virConfValuePtr val, tmp; + virBuffer buf = VIR_BUFFER_INITIALIZER; + + if (def->controllers[i]->model != -1) { + switch (def->controllers[i]->model) { + case VIR_DOMAIN_CONTROLLER_MODEL_USB_QUSB1: + virBufferAddLit(&buf, "type=qusb,version=1,"); + break; + + case VIR_DOMAIN_CONTROLLER_MODEL_USB_QUSB2: + virBufferAddLit(&buf, "type=qusb,version=2,"); + break; + + default: + goto error; + } + } + + if (def->controllers[i]->opts.usbopts.ports != -1) + virBufferAsprintf(&buf, "ports=%x", + def->controllers[i]->opts.usbopts.ports); + + if (VIR_ALLOC(val) < 0) { + virBufferFreeAndReset(&buf); + goto error; + } + val->type = VIR_CONF_STRING; + val->str = virBufferContentAndReset(&buf); + tmp = usbctrlVal->list; + while (tmp && tmp->next) + tmp = tmp->next; + if (tmp) + tmp->next = val; + else + usbctrlVal->list = val; + } + } + + if (usbctrlVal->list != NULL) { + int ret = virConfSetValue(conf, "usbctrl", usbctrlVal); + usbctrlVal = NULL; + if (ret < 0) + return -1; + } + VIR_FREE(usbctrlVal); + + return 0; + + error: + virConfFreeValue(usbctrlVal); + return -1; +} + + +static int xenFormatXLUSB(virConfPtr conf, virDomainDefPtr def) { @@ -1182,6 +1369,9 @@ xenFormatXL(virDomainDefPtr def, virConnectPtr conn) if (xenFormatXLUSB(conf, def) < 0) goto cleanup;
+ if (xenFormatXLUSBController(conf, def) < 0) + goto cleanup; + return conf;
cleanup:
ACK and pushed with a commit message description -- Cedric

Signed-off-by: Chunyan Liu <cyliu@suse.com> --- Changes: drop pvusb items tests/xlconfigdata/test-usbctrl.cfg | 13 +++++++++++++ tests/xlconfigdata/test-usbctrl.xml | 31 +++++++++++++++++++++++++++++++ tests/xlconfigtest.c | 1 + 3 files changed, 45 insertions(+) create mode 100644 tests/xlconfigdata/test-usbctrl.cfg create mode 100644 tests/xlconfigdata/test-usbctrl.xml diff --git a/tests/xlconfigdata/test-usbctrl.cfg b/tests/xlconfigdata/test-usbctrl.cfg new file mode 100644 index 0000000..91e9460 --- /dev/null +++ b/tests/xlconfigdata/test-usbctrl.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" ] +usbctrl = [ "type=qusb,version=2,ports=6" ] diff --git a/tests/xlconfigdata/test-usbctrl.xml b/tests/xlconfigdata/test-usbctrl.xml new file mode 100644 index 0000000..3c03f37 --- /dev/null +++ b/tests/xlconfigdata/test-usbctrl.xml @@ -0,0 +1,31 @@ +<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> + <controller type='usb' index='0' model='qusb2' ports='6'/> + <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'/> + </devices> +</domain> diff --git a/tests/xlconfigtest.c b/tests/xlconfigtest.c index 4248da1..401e560 100644 --- a/tests/xlconfigtest.c +++ b/tests/xlconfigtest.c @@ -278,6 +278,7 @@ mymain(void) #endif DO_TEST("vif-typename"); DO_TEST("usb"); + DO_TEST("usbctrl"); virObjectUnref(caps); virObjectUnref(xmlopt); -- 2.1.4

On Wed, 2016-06-15 at 14:00 +0800, Chunyan Liu wrote:
Signed-off-by: Chunyan Liu <cyliu@suse.com> --- Changes: drop pvusb items
tests/xlconfigdata/test-usbctrl.cfg | 13 +++++++++++++ tests/xlconfigdata/test-usbctrl.xml | 31 +++++++++++++++++++++++++++++++ tests/xlconfigtest.c | 1 + 3 files changed, 45 insertions(+) create mode 100644 tests/xlconfigdata/test-usbctrl.cfg create mode 100644 tests/xlconfigdata/test-usbctrl.xml
diff --git a/tests/xlconfigdata/test-usbctrl.cfg b/tests/xlconfigdata/test-usbctrl.cfg new file mode 100644 index 0000000..91e9460 --- /dev/null +++ b/tests/xlconfigdata/test-usbctrl.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" ] +usbctrl = [ "type=qusb,version=2,ports=6" ] diff --git a/tests/xlconfigdata/test-usbctrl.xml b/tests/xlconfigdata/test-usbctrl.xml new file mode 100644 index 0000000..3c03f37 --- /dev/null +++ b/tests/xlconfigdata/test-usbctrl.xml @@ -0,0 +1,31 @@ +<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> + <controller type='usb' index='0' model='qusb2' ports='6'/> + <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'/> + </devices> +</domain> diff --git a/tests/xlconfigtest.c b/tests/xlconfigtest.c index 4248da1..401e560 100644 --- a/tests/xlconfigtest.c +++ b/tests/xlconfigtest.c @@ -278,6 +278,7 @@ mymain(void) #endif DO_TEST("vif-typename"); DO_TEST("usb"); + DO_TEST("usbctrl");
virObjectUnref(caps); virObjectUnref(xmlopt);
ACK, but merged with the previous patch introducing the feature. -- Cedric

To sync with virDomainControllerModelUSB, we add two models in qemuControllerModelUSB 'qusb1' and 'qusb2', but those models are not supported in qemu driver. So add check in device post parse to report errors if 'qusb1' and 'qusb2' are specified. Signed-off-by: Chunyan Liu <cyliu@suse.com> --- src/qemu/qemu_domain.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index d1f8175..ed72393 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -2301,6 +2301,19 @@ qemuDomainDeviceDefPostParse(virDomainDeviceDefPtr dev, ARCH_IS_S390(def->os.arch)) dev->data.controller->model = VIR_DOMAIN_CONTROLLER_MODEL_USB_NONE; + /* forbid usb model 'qusb1' and 'qusb2' in this kind of hyperviosr */ + if (dev->type == VIR_DOMAIN_DEVICE_CONTROLLER && + dev->data.controller->type == VIR_DOMAIN_CONTROLLER_TYPE_USB && + (dev->data.controller->model == VIR_DOMAIN_CONTROLLER_MODEL_USB_QUSB1 || + dev->data.controller->model == VIR_DOMAIN_CONTROLLER_MODEL_USB_QUSB2)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("USB controller model type 'qusb1' or 'qusb2' " + "is not supported in %s"), + virDomainVirtTypeToString(def->virtType)); + goto cleanup; + } + + /* set the default SCSI controller model for S390 arches */ if (dev->type == VIR_DOMAIN_DEVICE_CONTROLLER && dev->data.controller->type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI && -- 2.1.4

On Wed, 2016-06-15 at 14:00 +0800, Chunyan Liu wrote:
To sync with virDomainControllerModelUSB, we add two models in qemuControllerModelUSB 'qusb1' and 'qusb2', but those models are not supported in qemu driver. So add check in device post parse to report errors if 'qusb1' and 'qusb2' are specified.
Signed-off-by: Chunyan Liu <cyliu@suse.com> --- src/qemu/qemu_domain.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index d1f8175..ed72393 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -2301,6 +2301,19 @@ qemuDomainDeviceDefPostParse(virDomainDeviceDefPtr dev, ARCH_IS_S390(def->os.arch)) dev->data.controller->model = VIR_DOMAIN_CONTROLLER_MODEL_USB_NONE;
+ /* forbid usb model 'qusb1' and 'qusb2' in this kind of hyperviosr */ + if (dev->type == VIR_DOMAIN_DEVICE_CONTROLLER && + dev->data.controller->type == VIR_DOMAIN_CONTROLLER_TYPE_USB && + (dev->data.controller->model == VIR_DOMAIN_CONTROLLER_MODEL_USB_QUSB1 || + dev->data.controller->model == VIR_DOMAIN_CONTROLLER_MODEL_USB_QUSB2)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("USB controller model type 'qusb1' or 'qusb2' " + "is not supported in %s"), + virDomainVirtTypeToString(def->virtType)); + goto cleanup; + } + + /* set the default SCSI controller model for S390 arches */ if (dev->type == VIR_DOMAIN_DEVICE_CONTROLLER && dev->data.controller->type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI &&
ACK and pushed -- Cedric
participants (3)
-
Cedric Bosdonnat
-
Chunyan Liu
-
John Ferlan