[libvirt] [PATCHv4 4/9] Add functions for adding USB controllers to addrs

John Ferlan jferlan at redhat.com
Wed Jul 13 21:53:34 UTC 2016



On 07/01/2016 11:38 AM, Ján Tomko wrote:
> Walk through all the usb controllers in the domain definition
> and create the corresponding structures in the virDomainUSBAddressSet.
> ---
>  src/conf/domain_addr.c   | 121 +++++++++++++++++++++++++++++++++++++++++++++++
>  src/conf/domain_addr.h   |   4 ++
>  src/libvirt_private.syms |   1 +
>  3 files changed, 126 insertions(+)
> 
> diff --git a/src/conf/domain_addr.c b/src/conf/domain_addr.c
> index 5e84751..82fe295 100644
> --- a/src/conf/domain_addr.c
> +++ b/src/conf/domain_addr.c
> @@ -1330,3 +1330,124 @@ virDomainUSBAddressSetFree(virDomainUSBAddressSetPtr addrs)
>      VIR_FREE(addrs->buses);
>      VIR_FREE(addrs);
>  }
> +
> +
> +static size_t
> +virDomainUSBAddressControllerModelToPorts(virDomainControllerDefPtr cont)
> +{
> +    int model = cont->model;
> +
> +    if (model == -1)
> +        model = VIR_DOMAIN_CONTROLLER_MODEL_USB_PIIX3_UHCI;
> +
> +    switch ((virDomainControllerModelUSB) model) {
> +    case VIR_DOMAIN_CONTROLLER_MODEL_USB_PIIX3_UHCI:
> +    case VIR_DOMAIN_CONTROLLER_MODEL_USB_PIIX4_UHCI:
> +    case VIR_DOMAIN_CONTROLLER_MODEL_USB_VT82C686B_UHCI:
> +        return 2;
> +
> +    case VIR_DOMAIN_CONTROLLER_MODEL_USB_EHCI:
> +    case VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_EHCI1:
> +        return 6;
> +
> +    case VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_UHCI1:
> +    case VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_UHCI2:
> +    case VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_UHCI3:
> +        /* These have two ports each and are used to provide USB1.1
> +         * ports while ICH9_EHCI1 provides 6 USB2.0 ports.
> +         * Ignore these since we will add the EHCI1 too. */
> +        return 0;
> +
> +    case VIR_DOMAIN_CONTROLLER_MODEL_USB_PCI_OHCI:
> +        return 3;
> +
> +    case VIR_DOMAIN_CONTROLLER_MODEL_USB_NEC_XHCI:
> +        if (cont->opts.usbopts.ports != -1)
> +            return cont->opts.usbopts.ports;
> +        return 4;
> +
> +    case VIR_DOMAIN_CONTROLLER_MODEL_USB_NONE:
> +    case VIR_DOMAIN_CONTROLLER_MODEL_USB_LAST:
> +        /* yoda */

Prior review by Erik asked for this to be removed...

> +        break;
> +    }
> +    return 0;
> +}
> +
> +
> +static virDomainUSBAddressHubPtr
> +virDomainUSBAddressHubNew(size_t nports)
> +{
> +    virDomainUSBAddressHubPtr hub = NULL, ret = NULL;
> +
> +    if (VIR_ALLOC(hub) < 0)
> +        goto cleanup;
> +
> +    if (!(hub->ports = virBitmapNew(nports)))
> +        goto cleanup;
> +
> +    if (VIR_ALLOC_N(hub->hubs, nports) < 0)
> +        goto cleanup;
> +    hub->nports = nports;
> +
> +    ret = hub;
> +    hub = NULL;
> + cleanup:
> +    virDomainUSBAddressHubFree(hub);
> +    return ret;
> +}
> +
> +
> +static int
> +virDomainUSBAddressSetAddController(virDomainUSBAddressSetPtr addrs,
> +                                    virDomainControllerDefPtr cont)
> +{
> +    size_t nports = virDomainUSBAddressControllerModelToPorts(cont);
> +    virDomainUSBAddressHubPtr hub = NULL;
> +    int ret = -1;
> +
> +    VIR_DEBUG("Adding a USB controller model=%s with %zu ports",
> +              virDomainControllerModelUSBTypeToString(cont->model),
> +              nports);
> +
> +    /* Skip UHCI{1,2,3} companions; only add the EHCI1 */
> +    if (nports == 0)
> +        return 0;
> +
> +    if (addrs->nbuses <= cont->idx) {
> +        if (VIR_EXPAND_N(addrs->buses, addrs->nbuses, cont->idx - addrs->nbuses + 1) < 0)
> +            goto cleanup;


So if "someone" decides to be cute and have 1 USB controller, but number
it like 1000, then you're allocating and wasting a lot of memory. I
understand it makes the access a lot faster, but is that what we want?
Someone would have to be "malicious" and equally powerful as yoda to
adjust their XML thusly - of course in the alternate reality 1000000
would take a bigger hit.

Unless someone else has severe heartburn over this (and it wasn't
mentioned by Eric for his ACK), I'm OK with it...


> +    } else if (addrs->buses[cont->idx]) {
> +        virReportError(VIR_ERR_XML_ERROR,
> +                       _("Duplicate USB controllers with index %u"),
> +                       cont->idx);
> +        goto cleanup;
> +    }
> +
> +    if (!(hub = virDomainUSBAddressHubNew(nports)))
> +        goto cleanup;
> +
> +    addrs->buses[cont->idx] = hub;
> +    hub = NULL;
> +
> +    ret = 0;
> + cleanup:
> +    virDomainUSBAddressHubFree(hub);
> +    return ret;
> +}
> +
> +
> +int virDomainUSBAddressSetAddControllers(virDomainUSBAddressSetPtr addrs,
> +                                         virDomainDefPtr def)

This one almost escaped attention (multiline the function)

ACK w/ at least this adjustment

John

I also didn't go through any practice uses under the environment like
Erik seemed to do in his review of the previous version.

> +{
> +    size_t i;
> +
> +    for (i = 0; i < def->ncontrollers; i++) {
> +        virDomainControllerDefPtr cont = def->controllers[i];
> +        if (cont->type == VIR_DOMAIN_CONTROLLER_TYPE_USB) {
> +            if (virDomainUSBAddressSetAddController(addrs, cont) < 0)
> +                return -1;
> +        }
> +    }
> +    return 0;
> +}
> diff --git a/src/conf/domain_addr.h b/src/conf/domain_addr.h
> index c62ff6a..4cb0212 100644
> --- a/src/conf/domain_addr.h
> +++ b/src/conf/domain_addr.h
> @@ -269,6 +269,10 @@ typedef struct _virDomainUSBAddressSet virDomainUSBAddressSet;
>  typedef virDomainUSBAddressSet *virDomainUSBAddressSetPtr;
>  
>  virDomainUSBAddressSetPtr virDomainUSBAddressSetCreate(void);
> +
> +int virDomainUSBAddressSetAddControllers(virDomainUSBAddressSetPtr addrs,
> +                                         virDomainDefPtr def)
> +    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
>  void virDomainUSBAddressSetFree(virDomainUSBAddressSetPtr addrs);
>  
>  #endif /* __DOMAIN_ADDR_H__ */
> diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> index 49f8d6c..f0fed8e 100644
> --- a/src/libvirt_private.syms
> +++ b/src/libvirt_private.syms
> @@ -110,6 +110,7 @@ virDomainPCIControllerModelToConnectType;
>  virDomainUSBAddressPortFormat;
>  virDomainUSBAddressPortFormatBuf;
>  virDomainUSBAddressPortIsValid;
> +virDomainUSBAddressSetAddControllers;
>  virDomainUSBAddressSetCreate;
>  virDomainUSBAddressSetFree;
>  virDomainVirtioSerialAddrAssign;
> 




More information about the libvir-list mailing list