On Fri, Aug 26, 2011 at 01:44:24AM +0300, Marc-André Lureau wrote: > --- > docs/formatdomain.html.in | 27 ++++ > docs/schemas/domain.rng | 13 ++ > src/conf/domain_conf.c | 157 +++++++++++++++++++++- > src/conf/domain_conf.h | 20 +++ > src/libvirt_private.syms | 2 + > src/qemu/qemu_capabilities.c | 3 + > src/qemu/qemu_capabilities.h | 1 + > src/qemu/qemu_command.c | 56 ++++++++- > src/qemu/qemu_command.h | 1 + > tests/qemuhelptest.c | 9 +- > tests/qemuxml2argvdata/qemuxml2argv-usb-hub.args | 1 + > tests/qemuxml2argvdata/qemuxml2argv-usb-hub.xml | 19 +++ > tests/qemuxml2argvtest.c | 3 + > 13 files changed, 307 insertions(+), 5 deletions(-) > create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-usb-hub.args > create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-usb-hub.xml > > diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in > index 633cea1..e35b76b 100644 > --- a/docs/formatdomain.html.in > +++ b/docs/formatdomain.html.in > @@ -2084,6 +2084,33 @@ qemu-kvm -net nic,model=? /dev/null > device to a particular PCI slot. > </p> > > + <h4><a name="elementsHub">Hub devices</a></h4> > + > + <p> > + A hub is a device that expands a single port into several so > + that there are more ports available to connect devices to a host > + system. > + </p> > + > +<pre> > + ... > + <devices> > + <hub type='usb'/> > + </devices> > + ...</pre> > + > + <dl> > + <dt><code>hub</code></dt> > + <dd>The <code>hub</code> element has one mandatory attribute, > + the <code>type</code> whose value can only be 'usb'.</dd> > + </dl> > + > + <p> > + The <code>hub</code> element has an optional > + sub-element <code><address></code> which can tie the > + device to a particular controller. > + </p> > + > <h4><a name="elementsGraphics">Graphical framebuffers</a></h4> > > <p> > diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng > index 455f57d..16e9687 100644 > --- a/docs/schemas/domain.rng > +++ b/docs/schemas/domain.rng > @@ -1962,6 +1962,18 @@ > </optional> > </element> > </define> > + <define name="hub"> > + <element name="hub"> > + <attribute name="type"> > + <choice> > + <value>usb</value> > + </choice> > + </attribute> > + <optional> > + <ref name="address"/> > + </optional> > + </element> > + </define> > <define name="hostdev"> > <element name="hostdev"> > <optional> > @@ -2125,6 +2137,7 @@ > <ref name="serial"/> > <ref name="channel"/> > <ref name="smartcard"/> > + <ref name="hub"/> > </choice> > </zeroOrMore> > <optional> > diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c > index 5ef062a..bd05c2a 100644 > --- a/src/conf/domain_conf.c > +++ b/src/conf/domain_conf.c > @@ -126,7 +126,8 @@ VIR_ENUM_IMPL(virDomainDevice, VIR_DOMAIN_DEVICE_LAST, > "hostdev", > "watchdog", > "controller", > - "graphics") > + "graphics", > + "usb") > > VIR_ENUM_IMPL(virDomainDeviceAddress, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST, > "none", > @@ -436,6 +437,9 @@ VIR_ENUM_IMPL(virDomainState, VIR_DOMAIN_CRASHED+1, > "shutoff", > "crashed") > > +VIR_ENUM_IMPL(virDomainHub, VIR_DOMAIN_HUB_TYPE_LAST, > + "usb") > + > #define VIR_DOMAIN_NOSTATE_LAST (VIR_DOMAIN_NOSTATE_UNKNOWN + 1) > VIR_ENUM_IMPL(virDomainNostateReason, VIR_DOMAIN_NOSTATE_LAST, > "unknown") > @@ -999,6 +1003,15 @@ void virDomainHostdevDefFree(virDomainHostdevDefPtr def) > VIR_FREE(def); > } > > +void virDomainHubDefFree(virDomainHubDefPtr def) > +{ > + if (!def) > + return; > + > + virDomainDeviceInfoClear(&def->info); > + VIR_FREE(def); > +} > + > void virDomainDeviceDefFree(virDomainDeviceDefPtr def) > { > if (!def) > @@ -1035,6 +1048,9 @@ void virDomainDeviceDefFree(virDomainDeviceDefPtr def) > case VIR_DOMAIN_DEVICE_GRAPHICS: > virDomainGraphicsDefFree(def->data.graphics); > break; > + case VIR_DOMAIN_DEVICE_HUB: > + virDomainHubDefFree(def->data.hub); > + break; > } > > VIR_FREE(def); > @@ -1144,6 +1160,10 @@ void virDomainDefFree(virDomainDefPtr def) > virDomainHostdevDefFree(def->hostdevs[i]); > VIR_FREE(def->hostdevs); > > + for (i = 0 ; i < def->nhubs ; i++) > + virDomainHubDefFree(def->hubs[i]); > + VIR_FREE(def->hubs); > + > VIR_FREE(def->os.type); > VIR_FREE(def->os.arch); > VIR_FREE(def->os.machine); > @@ -1527,6 +1547,9 @@ int virDomainDeviceInfoIterate(virDomainDefPtr def, > if (def->console) > if (cb(def, &def->console->info, opaque) < 0) > return -1; > + for (i = 0; i < def->nhubs ; i++) > + if (cb(def, &def->hubs[i]->info, opaque) < 0) > + return -1; > return 0; > } > > @@ -1591,6 +1614,12 @@ virDomainDeviceInfoFormat(virBufferPtr buf, > info->addr.ccid.slot); > break; > > + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB: > + virBufferAsprintf(buf, " bus='%d' port='%d'", > + info->addr.usb.bus, > + info->addr.usb.port); > + break; > + > default: > virDomainReportError(VIR_ERR_INTERNAL_ERROR, > _("unknown address type '%d'"), info->type); > @@ -3990,6 +4019,47 @@ error: > } > > > +/* Parse the XML definition for an hub device */ > +static virDomainHubDefPtr > +virDomainHubDefParseXML(xmlNodePtr node, unsigned int flags) > +{ > + virDomainHubDefPtr def; > + char *type = NULL; > + > + if (VIR_ALLOC(def) < 0) { > + virReportOOMError(); > + return NULL; > + } > + > + type = virXMLPropString(node, "type"); > + > + if (!type) { > + virDomainReportError(VIR_ERR_INTERNAL_ERROR, > + "%s", _("missing hub device type")); > + goto error; > + } > + > + if ((def->type = virDomainHubTypeFromString(type)) < 0) { > + virDomainReportError(VIR_ERR_INTERNAL_ERROR, > + _("unknown hub device type '%s'"), type); > + goto error; > + } > + > + if (virDomainDeviceInfoParseXML(node, &def->info, flags) < 0) > + goto error; > + > +cleanup: > + VIR_FREE(type); > + > + return def; > + > +error: > + virDomainHubDefFree(def); > + def = NULL; > + goto cleanup; > +} > + > + > /* Parse the XML definition for a clock timer */ > static virDomainTimerDefPtr > virDomainTimerDefParseXML(const xmlNodePtr node, > @@ -5567,6 +5637,10 @@ virDomainDeviceDefPtr virDomainDeviceDefParse(virCapsPtr caps, > dev->type = VIR_DOMAIN_DEVICE_GRAPHICS; > if (!(dev->data.graphics = virDomainGraphicsDefParseXML(node, ctxt, flags))) > goto error; > + } else if (xmlStrEqual(node->name, BAD_CAST "hub")) { > + dev->type = VIR_DOMAIN_DEVICE_HUB; > + if (!(dev->data.hub = virDomainHubDefParseXML(node, flags))) > + goto error; > } else { > virDomainReportError(VIR_ERR_XML_ERROR, > "%s", _("unknown device type")); > @@ -6971,6 +7045,21 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps, > } > } > > + /* analysis of the hub devices */ > + if ((n = virXPathNodeSet("./devices/hub", ctxt, &nodes)) < 0) { > + goto error; > + } > + if (n && VIR_ALLOC_N(def->hubs, n) < 0) > + goto no_memory; > + for (i = 0 ; i < n ; i++) { > + virDomainHubDefPtr hub = virDomainHubDefParseXML(nodes[i], flags); > + if (!hub) > + goto error; > + > + def->hubs[def->nhubs++] = hub; > + } > + VIR_FREE(nodes); > + > /* analysis of security label */ > if (virSecurityLabelDefParseXML(def, ctxt, flags) == -1) > goto error; > @@ -7881,6 +7970,29 @@ cleanup: > } > > > +static bool virDomainHubDefCheckABIStability(virDomainHubDefPtr src, > + virDomainHubDefPtr dst) > +{ > + bool identical = false; > + > + if (src->type != dst->type) { > + virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED, > + _("Target hub device type %s does not match source %s"), > + virDomainHubTypeToString(dst->type), > + virDomainHubTypeToString(src->type)); > + goto cleanup; > + } > + > + if (!virDomainDeviceInfoCheckABIStability(&src->info, &dst->info)) > + goto cleanup; > + > + identical = true; > + > +cleanup: > + return identical; > +} > + > + > /* This compares two configurations and looks for any differences > * which will affect the guest ABI. This is primarily to allow > * validation of custom XML config passed in during migration > @@ -8114,6 +8226,17 @@ bool virDomainDefCheckABIStability(virDomainDefPtr src, > goto cleanup; > } > > + if (src->nhubs != dst->nhubs) { > + virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED, > + _("Target domain hub device count %d does not match source %d"), > + dst->nhubs, src->nhubs); > + goto cleanup; > + } > + > + for (i = 0 ; i < src->nhubs ; i++) > + if (!virDomainHubDefCheckABIStability(src->hubs[i], dst->hubs[i])) > + goto cleanup; > + > if (src->console && > !virDomainConsoleDefCheckABIStability(src->console, dst->console)) > goto cleanup; > @@ -10027,6 +10150,34 @@ virDomainHostdevDefFormat(virBufferPtr buf, > } > > > +static int > +virDomainHubDefFormat(virBufferPtr buf, > + virDomainHubDefPtr def, > + unsigned int flags) > +{ > + const char *type = virDomainHubTypeToString(def->type); > + > + if (!type) { > + virDomainReportError(VIR_ERR_INTERNAL_ERROR, > + _("unexpected hub type %d"), def->type); > + return -1; > + } > + > + virBufferAsprintf(buf, " <hub type='%s'", type); > + > + if (virDomainDeviceInfoIsSet(&def->info, flags)) { > + virBufferAddLit(buf, ">\n"); > + if (virDomainDeviceInfoFormat(buf, &def->info, flags) < 0) > + return -1; > + virBufferAddLit(buf, " </hub>\n"); > + } else { > + virBufferAddLit(buf, "/>\n"); > + } > + > + return 0; > +} > + > + > #define DUMPXML_FLAGS \ > (VIR_DOMAIN_XML_SECURE | \ > VIR_DOMAIN_XML_INACTIVE | \ > @@ -10432,6 +10583,10 @@ virDomainDefFormatInternal(virDomainDefPtr def, > if (virDomainHostdevDefFormat(&buf, def->hostdevs[n], flags) < 0) > goto cleanup; > > + for (n = 0 ; n < def->nhubs ; n++) > + if (virDomainHubDefFormat(&buf, def->hubs[n], flags) < 0) > + goto cleanup; > + > if (def->watchdog) > virDomainWatchdogDefFormat (&buf, def->watchdog, flags); > > diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h > index 07d60a4..f880264 100644 > --- a/src/conf/domain_conf.h > +++ b/src/conf/domain_conf.h > @@ -616,6 +616,13 @@ struct _virDomainSmartcardDef { > virDomainDeviceInfo info; > }; > > +typedef struct _virDomainHubDef virDomainHubDef; > +typedef virDomainHubDef *virDomainHubDefPtr; > +struct _virDomainHubDef { > + int type; > + virDomainDeviceInfo info; > +}; > + > enum virDomainInputType { > VIR_DOMAIN_INPUT_TYPE_MOUSE, > VIR_DOMAIN_INPUT_TYPE_TABLET, > @@ -825,6 +832,12 @@ enum virDomainGraphicsListenType { > VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_LAST, > }; > > +enum virDomainHubType { > + VIR_DOMAIN_HUB_TYPE_USB, > + > + VIR_DOMAIN_HUB_TYPE_LAST, > +}; > + > typedef struct _virDomainGraphicsListenDef virDomainGraphicsListenDef; > typedef virDomainGraphicsListenDef *virDomainGraphicsListenDefPtr; > struct _virDomainGraphicsListenDef { > @@ -965,6 +978,7 @@ enum virDomainDeviceType { > VIR_DOMAIN_DEVICE_WATCHDOG, > VIR_DOMAIN_DEVICE_CONTROLLER, > VIR_DOMAIN_DEVICE_GRAPHICS, > + VIR_DOMAIN_DEVICE_HUB, > > VIR_DOMAIN_DEVICE_LAST, > }; > @@ -985,6 +999,7 @@ struct _virDomainDeviceDef { > virDomainHostdevDefPtr hostdev; > virDomainWatchdogDefPtr watchdog; > virDomainGraphicsDefPtr graphics; > + virDomainHubDefPtr hub; > } data; > }; > > @@ -1312,6 +1327,9 @@ struct _virDomainDef { > size_t nleases; > virDomainLeaseDefPtr *leases; > > + int nhubs; > + virDomainHubDefPtr *hubs; > + > /* Only 1 */ > virDomainChrDefPtr console; > virSecurityLabelDef seclabel; > @@ -1458,6 +1476,7 @@ void virDomainMemballoonDefFree(virDomainMemballoonDefPtr def); > void virDomainWatchdogDefFree(virDomainWatchdogDefPtr def); > void virDomainVideoDefFree(virDomainVideoDefPtr def); > void virDomainHostdevDefFree(virDomainHostdevDefPtr def); > +void virDomainHubDefFree(virDomainHubDefPtr def); > void virDomainDeviceDefFree(virDomainDeviceDefPtr def); > int virDomainDeviceAddressIsValid(virDomainDeviceInfoPtr info, > int type); > @@ -1738,6 +1757,7 @@ VIR_ENUM_DECL(virDomainWatchdogAction) > VIR_ENUM_DECL(virDomainVideo) > VIR_ENUM_DECL(virDomainHostdevMode) > VIR_ENUM_DECL(virDomainHostdevSubsys) > +VIR_ENUM_DECL(virDomainHub) > VIR_ENUM_DECL(virDomainInput) > VIR_ENUM_DECL(virDomainInputBus) > VIR_ENUM_DECL(virDomainGraphics) > diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms > index 74948b8..6642ba9 100644 > --- a/src/libvirt_private.syms > +++ b/src/libvirt_private.syms > @@ -327,6 +327,8 @@ virDomainGraphicsTypeToString; > virDomainHostdevDefFree; > virDomainHostdevModeTypeToString; > virDomainHostdevSubsysTypeToString; > +virDomainHubTypeFromString; > +virDomainHubTypeToString; > virDomainInputDefFree; > virDomainIoEventFdTypeFromString; > virDomainIoEventFdTypeToString; > diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c > index a776a0c..5b72a60 100644 > --- a/src/qemu/qemu_capabilities.c > +++ b/src/qemu/qemu_capabilities.c > @@ -134,6 +134,7 @@ VIR_ENUM_IMPL(qemuCaps, QEMU_CAPS_LAST, > > "pci-ohci", /* 70 */ > "usb-redir", > + "usb-hub", > ); > > struct qemu_feature_flags { > @@ -1220,6 +1221,8 @@ qemuCapsParseDeviceStr(const char *str, virBitmapPtr flags) > qemuCapsSet(flags, QEMU_CAPS_PCI_OHCI); > if (strstr(str, "name \"usb-redir\"")) > qemuCapsSet(flags, QEMU_CAPS_USB_REDIR); > + if (strstr(str, "name \"usb-hub\"")) > + qemuCapsSet(flags, QEMU_CAPS_USB_HUB); > > /* Prefer -chardev spicevmc (detected earlier) over -device spicevmc */ > if (!qemuCapsGet(flags, QEMU_CAPS_CHARDEV_SPICEVMC) && > diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h > index f4bb368..c9b9b45 100644 > --- a/src/qemu/qemu_capabilities.h > +++ b/src/qemu/qemu_capabilities.h > @@ -108,6 +108,7 @@ enum qemuCapsFlags { > QEMU_CAPS_VT82C686B_USB_UHCI = 69, /* -device vt82c686b-usb-uhci */ > QEMU_CAPS_PCI_OHCI = 70, /* -device pci-ohci */ > QEMU_CAPS_USB_REDIR = 71, /* -device usb-redir */ > + QEMU_CAPS_USB_HUB = 72, /* -device usb-hub */ > > QEMU_CAPS_LAST, /* this must always be the last item */ > }; > diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c > index 835d06f..9b09daa 100644 > --- a/src/qemu/qemu_command.c > +++ b/src/qemu/qemu_command.c > @@ -689,6 +689,10 @@ qemuAssignDeviceAliases(virDomainDefPtr def, virBitmapPtr qemuCaps) > if (virAsprintf(&def->smartcards[i]->info.alias, "smartcard%d", i) < 0) > goto no_memory; > } > + for (i = 0; i < def->nhubs ; i++) { > + if (virAsprintf(&def->hubs[i]->info.alias, "hub%d", i) < 0) > + goto no_memory; > + } > if (def->console) { > if (virAsprintf(&def->console->info.alias, "console%d", i) < 0) > goto no_memory; > @@ -1272,6 +1276,9 @@ qemuAssignDevicePCISlots(virDomainDefPtr def, qemuDomainPCIAddressSetPtr addrs) > for (i = 0; i < def->nchannels ; i++) { > /* Nada - none are PCI based (yet) */ > } > + for (i = 0; i < def->nhubs ; i++) { > + /* Nada - none are PCI based (yet) */ > + } > > return 0; > > @@ -1767,7 +1774,6 @@ qemuBuildUSBControllerDevStr(virDomainControllerDefPtr def, > virBufferAsprintf(buf, ",id=usb%d", def->idx); > } > > - > return 0; > } > > @@ -2336,6 +2342,43 @@ error: > > > char * > +qemuBuildHubDevStr(virDomainHubDefPtr dev, > + virBitmapPtr qemuCaps) > +{ > + virBuffer buf = VIR_BUFFER_INITIALIZER; > + > + if (dev->type != VIR_DOMAIN_HUB_TYPE_USB) { > + qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, > + _("hub type %s not supported"), > + virDomainHubTypeToString(dev->type)); > + goto error; > + } > + > + if (!qemuCapsGet(qemuCaps, QEMU_CAPS_USB_HUB)) { > + qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, > + _("usb-hub not supported by QEMU binary")); > + goto error; > + } > + > + virBufferAddLit(&buf, "usb-hub"); > + virBufferAsprintf(&buf, ",id=%s", dev->info.alias); > + if (qemuBuildDeviceAddressStr(&buf, &dev->info, qemuCaps) < 0) > + goto error; > + > + if (virBufferError(&buf)) { > + virReportOOMError(); > + goto error; > + } > + > + return virBufferContentAndReset(&buf); > + > +error: > + virBufferFreeAndReset(&buf); > + return NULL; > +} > + > + > +char * > qemuBuildUSBHostdevUsbDevStr(virDomainHostdevDefPtr dev) > { > char *ret = NULL; > @@ -4245,6 +4288,17 @@ qemuBuildCommandLine(virConnectPtr conn, > if (usbcontroller == 0) > virCommandAddArg(cmd, "-usb"); > > + for (i = 0 ; i < def->nhubs ; i++) { > + virDomainHubDefPtr hub = def->hubs[i]; > + char *optstr; > + > + virCommandAddArg(cmd, "-device"); > + if (!(optstr = qemuBuildHubDevStr(hub, qemuCaps))) > + goto error; > + virCommandAddArg(cmd, optstr); > + VIR_FREE(optstr); > + } > + > for (i = 0 ; i < def->ninputs ; i++) { > virDomainInputDefPtr input = def->inputs[i]; > > diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h > index de09577..22bc15d 100644 > --- a/src/qemu/qemu_command.h > +++ b/src/qemu/qemu_command.h > @@ -119,6 +119,7 @@ char * qemuBuildUSBHostdevUsbDevStr(virDomainHostdevDefPtr dev); > char * qemuBuildUSBHostdevDevStr(virDomainHostdevDefPtr dev, > virBitmapPtr qemuCaps); > > +char * qemuBuildHubDevStr(virDomainHubDefPtr dev, virBitmapPtr qemuCaps); > > > int qemuNetworkIfaceConnect(virDomainDefPtr def, > diff --git a/tests/qemuhelptest.c b/tests/qemuhelptest.c > index d57e499..ffd30e2 100644 > --- a/tests/qemuhelptest.c > +++ b/tests/qemuhelptest.c > @@ -349,7 +349,8 @@ mymain(void) > QEMU_CAPS_DRIVE_AIO, > QEMU_CAPS_DEVICE_SPICEVMC, > QEMU_CAPS_PIIX3_USB_UHCI, > - QEMU_CAPS_PIIX4_USB_UHCI); > + QEMU_CAPS_PIIX4_USB_UHCI, > + QEMU_CAPS_USB_HUB); > DO_TEST("qemu-kvm-0.12.3", 12003, 1, 0, > QEMU_CAPS_VNC_COLON, > QEMU_CAPS_NO_REBOOT, > @@ -437,7 +438,8 @@ mymain(void) > QEMU_CAPS_PIIX3_USB_UHCI, > QEMU_CAPS_PIIX4_USB_UHCI, > QEMU_CAPS_VT82C686B_USB_UHCI, > - QEMU_CAPS_PCI_OHCI); > + QEMU_CAPS_PCI_OHCI, > + QEMU_CAPS_USB_HUB); > DO_TEST("qemu-kvm-0.12.1.2-rhel61", 12001, 1, 0, > QEMU_CAPS_VNC_COLON, > QEMU_CAPS_NO_REBOOT, > @@ -484,7 +486,8 @@ mymain(void) > QEMU_CAPS_VIRTIO_TX_ALG, > QEMU_CAPS_VIRTIO_IOEVENTFD, > QEMU_CAPS_PIIX3_USB_UHCI, > - QEMU_CAPS_PIIX4_USB_UHCI); > + QEMU_CAPS_PIIX4_USB_UHCI, > + QEMU_CAPS_USB_HUB); > > return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; > } > diff --git a/tests/qemuxml2argvdata/qemuxml2argv-usb-hub.args b/tests/qemuxml2argvdata/qemuxml2argv-usb-hub.args > new file mode 100644 > index 0000000..4911dd4 > --- /dev/null > +++ b/tests/qemuxml2argvdata/qemuxml2argv-usb-hub.args > @@ -0,0 +1 @@ > +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefconfig -nodefaults -chardev socket,id=charmonitor,path=/tmp/test-monitor,server,nowait -mon chardev=charmonitor,id=monitor,mode=readline -no-acpi -boot c -usb -device usb-hub,id=hub0,bus=usb.0,port=1 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x4 > diff --git a/tests/qemuxml2argvdata/qemuxml2argv-usb-hub.xml b/tests/qemuxml2argvdata/qemuxml2argv-usb-hub.xml > new file mode 100644 > index 0000000..5e0b256 > --- /dev/null > +++ b/tests/qemuxml2argvdata/qemuxml2argv-usb-hub.xml > @@ -0,0 +1,19 @@ > +<domain type='qemu'> > + <name>QEMUGuest1</name> > + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> > + <memory>219136</memory> > + <currentMemory>219200</currentMemory> > + <vcpu>1</vcpu> > + <os> > + <type arch='i686' machine='pc'>hvm</type> > + <boot dev='hd'/> > + </os> > + <devices> > + <emulator>/usr/bin/qemu</emulator> > + <controller type='usb' index='0'/> > + <memballoon model='virtio'/> > + <hub type='usb'> > + <address type='usb' bus='0' port='1'/> > + </hub> > + </devices> > +</domain> > diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c > index 33588d0..a053693 100644 > --- a/tests/qemuxml2argvtest.c > +++ b/tests/qemuxml2argvtest.c > @@ -498,6 +498,9 @@ mymain(void) > DO_TEST("usb-ich9-companion", false, > QEMU_CAPS_CHARDEV, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG, > QEMU_CAPS_PCI_MULTIFUNCTION, QEMU_CAPS_ICH9_USB_EHCI1); > + DO_TEST("usb-hub", false, > + QEMU_CAPS_CHARDEV, QEMU_CAPS_DEVICE, QEMU_CAPS_USB_HUB, > + QEMU_CAPS_NODEFCONFIG); > > DO_TEST("smbios", false, QEMU_CAPS_SMBIOS_TYPE); > ACK Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list