[libvirt] [PATCH 0/6] 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. Chunyan Liu (6): 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 docs/formatdomain.html.in | 6 +- docs/schemas/domaincommon.rng | 4 + src/conf/domain_conf.c | 4 + src/conf/domain_conf.h | 4 + src/libxl/libxl_conf.c | 94 +++++++++++++++++ src/libxl/libxl_conf.h | 4 + src/libxl/libxl_driver.c | 176 +++++++++++++++++++++++++++++++ src/qemu/qemu_command.c | 4 + src/xenconfig/xen_xl.c | 203 ++++++++++++++++++++++++++++++++++++ tests/xlconfigdata/test-usbctrl.cfg | 13 +++ tests/xlconfigdata/test-usbctrl.xml | 32 ++++++ tests/xlconfigtest.c | 1 + 12 files changed, 544 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). To match libxl support, extend usb controller schema to support more models: pvusb1 (pvusb, version 1.1), pvusb2 (pvusb, version 2.0), qusb1 (qusb, version 1.1) and 'qusb2' (qusb version 2.0). Signed-off-by: Chunyan Liu <cyliu@suse.com> --- docs/formatdomain.html.in | 6 +++++- docs/schemas/domaincommon.rng | 4 ++++ src/conf/domain_conf.c | 4 ++++ src/conf/domain_conf.h | 4 ++++ src/qemu/qemu_command.c | 4 ++++ 5 files changed, 21 insertions(+), 1 deletion(-) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index fb3ec5e..1492915 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -3063,7 +3063,11 @@ <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", "pvusb1" (xen pvusb + with dom0 backend, version 1.1), "pvusb2" (xen pvusb with dom0 + backend, version 2.0), "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 02078d7..5afa15d 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -1768,6 +1768,10 @@ <value>pci-ohci</value> <value>nec-xhci</value> <value>none</value> + <value>pvusb1</value> + <value>pvusb2</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 10e61da..ff3285f 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -356,6 +356,10 @@ VIR_ENUM_IMPL(virDomainControllerModelUSB, VIR_DOMAIN_CONTROLLER_MODEL_USB_LAST, "vt82c686b-uhci", "pci-ohci", "nec-xhci", + "pvusb1", + "pvusb2", + "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 3792562..6733b2d 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -675,6 +675,10 @@ 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_PVUSB1, + VIR_DOMAIN_CONTROLLER_MODEL_USB_PVUSB2, + 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 490260f..5c3de83 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -133,6 +133,10 @@ VIR_ENUM_IMPL(qemuControllerModelUSB, VIR_DOMAIN_CONTROLLER_MODEL_USB_LAST, "vt82c686b-usb-uhci", "pci-ohci", "nec-usb-xhci", + "pvusb1", + "pvusb2", + "qusb1", + "qusb2", "none"); VIR_ENUM_DECL(qemuDomainFSDriver) -- 2.1.4

On 06/12/2016 10:53 AM, 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).
IIUC, the pvusb backend has not gained any traction in the kernel and will not be accepted upstream. Adding Juergen to confirm. If that is the case, I think it should be dropped.
To match libxl support, extend usb controller schema to support more models: pvusb1 (pvusb, version 1.1), pvusb2 (pvusb, version 2.0), qusb1 (qusb, version 1.1) and 'qusb2' (qusb version 2.0).
Signed-off-by: Chunyan Liu <cyliu@suse.com> --- docs/formatdomain.html.in | 6 +++++- docs/schemas/domaincommon.rng | 4 ++++ src/conf/domain_conf.c | 4 ++++ src/conf/domain_conf.h | 4 ++++ src/qemu/qemu_command.c | 4 ++++ 5 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index fb3ec5e..1492915 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -3063,7 +3063,11 @@ <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", "pvusb1" (xen pvusb + with dom0 backend, version 1.1), "pvusb2" (xen pvusb with dom0 + backend, version 2.0), "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 02078d7..5afa15d 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -1768,6 +1768,10 @@ <value>pci-ohci</value> <value>nec-xhci</value> <value>none</value> + <value>pvusb1</value> + <value>pvusb2</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 10e61da..ff3285f 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -356,6 +356,10 @@ VIR_ENUM_IMPL(virDomainControllerModelUSB, VIR_DOMAIN_CONTROLLER_MODEL_USB_LAST, "vt82c686b-uhci", "pci-ohci", "nec-xhci", + "pvusb1", + "pvusb2", + "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 3792562..6733b2d 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -675,6 +675,10 @@ 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_PVUSB1, + VIR_DOMAIN_CONTROLLER_MODEL_USB_PVUSB2, + 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 490260f..5c3de83 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -133,6 +133,10 @@ VIR_ENUM_IMPL(qemuControllerModelUSB, VIR_DOMAIN_CONTROLLER_MODEL_USB_LAST, "vt82c686b-usb-uhci", "pci-ohci", "nec-usb-xhci", + "pvusb1", + "pvusb2", + "qusb1", + "qusb2", "none");
It seems odd that these need to be added to qemu_command.c. But sadly, I'm not familiar with how USB controllers are handled in the qemu driver to give much useful feedback at this time. I can certainly start investigating that, but in the meantime I've added Laine to the cc list. He has done quite a bit of work in this area in the past and might have a few minutes free to comment on these changes. I know you will be leaving soon to pursue other opportunities (/me sheds a tear since one of the few libxl driver contributors will be departing), but I can continue this work if it is not merged before your departure. Thanks a lot Chunyan for all your work on Xen-related matters in libvirt over the years! Regards, Jim

On 14/06/16 07:02, Jim Fehlig wrote:
On 06/12/2016 10:53 AM, 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).
IIUC, the pvusb backend has not gained any traction in the kernel and will not be accepted upstream. Adding Juergen to confirm. If that is the case, I think it should be dropped.
Correct. Upstream Linux doesn't have a pvusb backend and it seems unlikely it will have one. You are talking about dropping it from libvirt, right?
To match libxl support, extend usb controller schema to support more models: pvusb1 (pvusb, version 1.1), pvusb2 (pvusb, version 2.0), qusb1 (qusb, version 1.1) and 'qusb2' (qusb version 2.0).
Signed-off-by: Chunyan Liu <cyliu@suse.com> --- docs/formatdomain.html.in | 6 +++++- docs/schemas/domaincommon.rng | 4 ++++ src/conf/domain_conf.c | 4 ++++ src/conf/domain_conf.h | 4 ++++ src/qemu/qemu_command.c | 4 ++++ 5 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index fb3ec5e..1492915 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -3063,7 +3063,11 @@ <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", "pvusb1" (xen pvusb + with dom0 backend, version 1.1), "pvusb2" (xen pvusb with dom0 + backend, version 2.0), "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 02078d7..5afa15d 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -1768,6 +1768,10 @@ <value>pci-ohci</value> <value>nec-xhci</value> <value>none</value> + <value>pvusb1</value> + <value>pvusb2</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 10e61da..ff3285f 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -356,6 +356,10 @@ VIR_ENUM_IMPL(virDomainControllerModelUSB, VIR_DOMAIN_CONTROLLER_MODEL_USB_LAST, "vt82c686b-uhci", "pci-ohci", "nec-xhci", + "pvusb1", + "pvusb2", + "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 3792562..6733b2d 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -675,6 +675,10 @@ 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_PVUSB1, + VIR_DOMAIN_CONTROLLER_MODEL_USB_PVUSB2, + 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 490260f..5c3de83 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -133,6 +133,10 @@ VIR_ENUM_IMPL(qemuControllerModelUSB, VIR_DOMAIN_CONTROLLER_MODEL_USB_LAST, "vt82c686b-usb-uhci", "pci-ohci", "nec-usb-xhci", + "pvusb1", + "pvusb2", + "qusb1", + "qusb2", "none");
It seems odd that these need to be added to qemu_command.c. But sadly, I'm not familiar with how USB controllers are handled in the qemu driver to give much useful feedback at this time. I can certainly start investigating that, but in the meantime I've added Laine to the cc list. He has done quite a bit of work in this area in the past and might have a few minutes free to comment on these changes.
qusb (and pvusb, too) don't require any qemu interaction besides what is already done in libxl. There are no qmp commands or whatever involved, all communication is done via Xenstore.
I know you will be leaving soon to pursue other opportunities (/me sheds a tear since one of the few libxl driver contributors will be departing), but I can continue this work if it is not merged before your departure. Thanks a lot Chunyan for all your work on Xen-related matters in libvirt over the years!
Yeah, thanks especially for your pvusb work! Juergen

On 6/14/2016 at 01:27 PM, in message <575F95C4.4080201@suse.com>, Juergen Gross <jgross@suse.com> wrote: On 14/06/16 07:02, Jim Fehlig wrote: On 06/12/2016 10:53 AM, 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).
IIUC, the pvusb backend has not gained any traction in the kernel and will not be accepted upstream. Adding Juergen to confirm. If that is the case, I think it should be dropped.
Correct. Upstream Linux doesn't have a pvusb backend and it seems unlikely it will have one.
OK. If that will never happen, I will drop pvusb1 and pvusb2 models. It's easy. - Chunyan
You are talking about dropping it from libvirt, right?
To match libxl support, extend usb controller schema to support more models: pvusb1 (pvusb, version 1.1), pvusb2 (pvusb, version 2.0), qusb1 (qusb, version 1.1) and 'qusb2' (qusb version 2.0).
Signed-off-by: Chunyan Liu <cyliu@suse.com> --- docs/formatdomain.html.in | 6 +++++- docs/schemas/domaincommon.rng | 4 ++++ src/conf/domain_conf.c | 4 ++++ src/conf/domain_conf.h | 4 ++++ src/qemu/qemu_command.c | 4 ++++ 5 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index fb3ec5e..1492915 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -3063,7 +3063,11 @@ <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", "pvusb1" (xen pvusb + with dom0 backend, version 1.1), "pvusb2" (xen pvusb with dom0 + backend, version 2.0), "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 02078d7..5afa15d 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -1768,6 +1768,10 @@ <value>pci-ohci</value> <value>nec-xhci</value> <value>none</value> + <value>pvusb1</value> + <value>pvusb2</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 10e61da..ff3285f 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -356,6 +356,10 @@ VIR_ENUM_IMPL(virDomainControllerModelUSB, VIR_DOMAIN_CONTROLLER_MODEL_USB_LAST, "vt82c686b-uhci", "pci-ohci", "nec-xhci", + "pvusb1", + "pvusb2", + "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 3792562..6733b2d 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -675,6 +675,10 @@ 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_PVUSB1, + VIR_DOMAIN_CONTROLLER_MODEL_USB_PVUSB2, + 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 490260f..5c3de83 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -133,6 +133,10 @@ VIR_ENUM_IMPL(qemuControllerModelUSB, VIR_DOMAIN_CONTROLLER_MODEL_USB_LAST, "vt82c686b-usb-uhci", "pci-ohci", "nec-usb-xhci", + "pvusb1", + "pvusb2", + "qusb1", + "qusb2", "none");
It seems odd that these need to be added to qemu_command.c. But sadly, I'm not familiar with how USB controllers are handled in the qemu driver to give much useful feedback at this time. I can certainly start investigating that, but in the meantime I've added Laine to the cc list. He has done quite a bit of work in this area in the past and might have a few minutes free to comment on these changes.
qusb (and pvusb, too) don't require any qemu interaction besides what is already done in libxl. There are no qmp commands or whatever involved, all communication is done via Xenstore.
I know you will be leaving soon to pursue other opportunities (/me sheds a tear since one of the few libxl driver contributors will be departing), but I can continue this work if it is not merged before your departure. Thanks a lot Chunyan for all your work on Xen-related matters in libvirt over the years!
Yeah, thanks especially for your pvusb work!
Juergen

Juergen Gross wrote:
On 14/06/16 07:02, Jim Fehlig wrote:
On 06/12/2016 10:53 AM, 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). IIUC, the pvusb backend has not gained any traction in the kernel and will not be accepted upstream. Adding Juergen to confirm. If that is the case, I think it should be dropped.
Correct. Upstream Linux doesn't have a pvusb backend and it seems unlikely it will have one.
You are talking about dropping it from libvirt, right?
Yes. Well, dropping it from these patches, which will someday make it to libvirt :-). Regards, Jim

On 06/14/2016 01:02 AM, Jim Fehlig wrote:
index 490260f..5c3de83 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -133,6 +133,10 @@ VIR_ENUM_IMPL(qemuControllerModelUSB, VIR_DOMAIN_CONTROLLER_MODEL_USB_LAST, "vt82c686b-usb-uhci", "pci-ohci", "nec-usb-xhci", + "pvusb1", + "pvusb2", + "qusb1", + "qusb2", "none"); It seems odd that these need to be added to qemu_command.c. But sadly, I'm not familiar with how USB controllers are handled in the qemu driver to give much useful feedback at this time. I can certainly start investigating that, but in
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c the meantime I've added Laine to the cc list. He has done quite a bit of work in this area in the past and might have a few minutes free to comment on these changes.
This enum exists because the model strings recognized/stored by libvirt's XML parser are slightly different from the exact name of the devices on the qemu commandline. For example, if you put "ehci" in the XML, the device that qemu uses is called "usb-ehci". Internally (in the domain object) it is stored as an enum value, and when we create the qemu commandline we use qemuControllerModelUSBTypeToString(model) to get the name of the device. This points out a couple of things: 1) the VIR_ENUM_IMPL for qemuControllerModelUSB and virDomainontrollerModelUSB must be kept in sync (this is partly enforced by the VIR_ENUM_IMPL() macro, which checks that the array of strings has as many entries as VIR_DOMAIN_CONTROLLER_MODEL_USB_LAST). 2) If new models are added that aren't supported in a particular hypervisor, the post-parse validation for that hypervisor should check for those models and flag them as errors.

index 490260f..5c3de83 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -133,6 +133,10 @@ VIR_ENUM_IMPL(qemuControllerModelUSB, VIR_DOMAIN_CONTROLLER_MODEL_USB_LAST, "vt82c686b-usb-uhci", "pci-ohci", "nec-usb-xhci", + "pvusb1", + "pvusb2", + "qusb1", + "qusb2", "none"); It seems odd that these need to be added to qemu_command.c. But sadly, I'm not familiar with how USB controllers are handled in the qemu driver to give much useful feedback at this time. I can certainly start investigating that, but in
On 6/14/2016 at 11:29 PM, in message <75f3d94f-19d3-b466-781f-abb2830637bc@laine.org>, Laine Stump <laine@laine.org> wrote: On 06/14/2016 01:02 AM, Jim Fehlig wrote: diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c the meantime I've added Laine to the cc list. He has done quite a bit of work in this area in the past and might have a few minutes free to comment on these changes.
This enum exists because the model strings recognized/stored by libvirt's XML parser are slightly different from the exact name of the devices on the qemu commandline. For example, if you put "ehci" in the XML, the device that qemu uses is called "usb-ehci". Internally (in the domain object) it is stored as an enum value, and when we create the qemu commandline we use qemuControllerModelUSBTypeToString(model) to get the name of the device.
This points out a couple of things:
1) the VIR_ENUM_IMPL for qemuControllerModelUSB and virDomainontrollerModelUSB must be kept in sync (this is partly enforced by the VIR_ENUM_IMPL() macro, which checks that the array of strings has as many entries as VIR_DOMAIN_CONTROLLER_MODEL_USB_LAST).
Yes, that's why we have to update qemuControllerModelUSB too.
2) If new models are added that aren't supported in a particular hypervisor, the post-parse validation for that hypervisor should check for those models and flag them as errors.
Right. I'll add a check in qemu post-parse. Thanks, Chunyan

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> --- src/libxl/libxl_conf.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/libxl/libxl_conf.h | 4 +++ 2 files changed, 98 insertions(+) diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c index f66264e..7bc9e7a 100644 --- a/src/libxl/libxl_conf.c +++ b/src/libxl/libxl_conf.c @@ -1866,6 +1866,97 @@ 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_PVUSB1: + usbctrl->version = 1; + usbctrl->type = LIBXL_USBCTRL_TYPE_PV; + break; + + case VIR_DOMAIN_CONTROLLER_MODEL_USB_PVUSB2: + usbctrl->version = 2; + usbctrl->type = LIBXL_USBCTRL_TYPE_PV; + break; + + 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; @@ -2165,6 +2256,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 df318f4..de2a883 100644 --- a/src/libxl/libxl_conf.h +++ b/src/libxl/libxl_conf.h @@ -198,6 +198,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

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 069616f..d1dd160 100644 --- a/src/libxl/libxl_driver.c +++ b/src/libxl/libxl_driver.c @@ -3029,6 +3029,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) @@ -3263,6 +3317,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); @@ -3293,6 +3353,7 @@ libxlDomainAttachDeviceConfig(virDomainDefPtr vmdef, virDomainDeviceDefPtr dev) virDomainDiskDefPtr disk; virDomainNetDefPtr net; virDomainHostdevDefPtr hostdev; + virDomainControllerDefPtr controller; virDomainHostdevDefPtr found; char mac[VIR_MAC_STRING_BUFLEN]; @@ -3310,6 +3371,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)) { @@ -3455,6 +3531,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) @@ -3618,6 +3745,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); @@ -3652,6 +3783,7 @@ libxlDomainDetachDeviceConfig(virDomainDefPtr vmdef, virDomainDeviceDefPtr dev) { virDomainDiskDefPtr disk, detach; virDomainHostdevDefPtr hostdev, det_hostdev; + virDomainControllerDefPtr cont, det_cont; virDomainNetDefPtr net; int idx; @@ -3666,6 +3798,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

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 d1dd160..d95aa8d 100644 --- a/src/libxl/libxl_driver.c +++ b/src/libxl/libxl_driver.c @@ -3091,6 +3091,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); @@ -3098,6 +3100,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

Signed-off-by: Chunyan Liu <cyliu@suse.com> --- src/xenconfig/xen_xl.c | 203 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 203 insertions(+) diff --git a/src/xenconfig/xen_xl.c b/src/xenconfig/xen_xl.c index c11cd1b..36d352c 100644 --- a/src/xenconfig/xen_xl.c +++ b/src/xenconfig/xen_xl.c @@ -486,6 +486,115 @@ 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, "pv", 2)) { + if (usbctrl_version == 1) + usbctrl_type = VIR_DOMAIN_CONTROLLER_MODEL_USB_PVUSB1; + else + usbctrl_type = VIR_DOMAIN_CONTROLLER_MODEL_USB_PVUSB2; + } 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"); @@ -595,6 +704,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; @@ -1067,6 +1179,94 @@ 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_PVUSB1: + virBufferAddLit(&buf, "type=pv,version=1,"); + break; + + case VIR_DOMAIN_CONTROLLER_MODEL_USB_PVUSB2: + virBufferAddLit(&buf, "type=pv,version=2,"); + break; + + 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) { @@ -1159,6 +1359,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

Signed-off-by: Chunyan Liu <cyliu@suse.com> --- tests/xlconfigdata/test-usbctrl.cfg | 13 +++++++++++++ tests/xlconfigdata/test-usbctrl.xml | 32 ++++++++++++++++++++++++++++++++ tests/xlconfigtest.c | 1 + 3 files changed, 46 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..319d493 --- /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=pv,version=1,ports=4", "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..55dd0e0 --- /dev/null +++ b/tests/xlconfigdata/test-usbctrl.xml @@ -0,0 +1,32 @@ +<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='pvusb1' ports='4'/> + <controller type='usb' index='1' 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 c5e2252..4c4ebf2 100644 --- a/tests/xlconfigtest.c +++ b/tests/xlconfigtest.c @@ -230,6 +230,7 @@ mymain(void) #endif DO_TEST("vif-typename"); DO_TEST("usb"); + DO_TEST("usbctrl"); virObjectUnref(caps); virObjectUnref(xmlopt); -- 2.1.4
participants (5)
-
Chun Yan Liu
-
Chunyan Liu
-
Jim Fehlig
-
Juergen Gross
-
Laine Stump