[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

Re: [libvirt] [v2 08/13] Add USB hub device



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>
> +  ...
> +  &lt;devices&gt;
> +    &lt;hub type='usb'/&gt;
> +  &lt;/devices&gt;
> +  ...</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>&lt;address&gt;</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 :|


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]