[libvirt] [PATCH v3 10/11] esx: implement domainInterfaceAddresses

Michal Privoznik mprivozn at redhat.com
Wed Jan 8 12:36:19 UTC 2020


On 12/20/19 3:58 PM, Pino Toscano wrote:
> Implement the .domainInterfaceAddresses hypervisor API, although only
> functional for the VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT source.
> 
> Signed-off-by: Pino Toscano <ptoscano at redhat.com>
> ---
>   docs/drvesx.html.in  |   4 ++
>   src/esx/esx_driver.c | 166 +++++++++++++++++++++++++++++++++++++++++++
>   2 files changed, 170 insertions(+)
> 
> diff --git a/docs/drvesx.html.in b/docs/drvesx.html.in
> index 465daafc2e..c4a2ae78a8 100644
> --- a/docs/drvesx.html.in
> +++ b/docs/drvesx.html.in
> @@ -792,6 +792,10 @@ Enter administrator password for example-vcenter.com:
>           <li>
>               <code>virDomainGetHostname</code>
>           </li>
> +        <li>
> +            <code>virDomainInterfaceAddresses</code> (only for the
> +            <code>VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT</code> source)
> +        </li>
>           <li>
>               <code>virDomainReboot</code>
>           </li>
> diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c
> index 39e3faeb8f..73b8f32f1b 100644
> --- a/src/esx/esx_driver.c
> +++ b/src/esx/esx_driver.c
> @@ -5122,6 +5122,171 @@ esxDomainGetHostname(virDomainPtr domain,
>   }
>   
>   
> +static int
> +esxParseIPAddress(const char *ipAddress, int prefixLength,
> +                  virDomainIPAddress *addr)
> +{
> +    virSocketAddr tmp_addr;
> +    virIPAddrType addr_type;
> +
> +    if (virSocketAddrParseAny(&tmp_addr, ipAddress, AF_UNSPEC, false) <= 0)
> +        return 0;
> +
> +    switch (VIR_SOCKET_ADDR_FAMILY(&tmp_addr)) {
> +    case AF_INET:
> +        addr_type = VIR_IP_ADDR_TYPE_IPV4;
> +        break;
> +    case AF_INET6:
> +        addr_type = VIR_IP_ADDR_TYPE_IPV6;
> +        break;
> +    default:
> +        return 0;
> +    }
> +
> +    addr->type = addr_type;
> +    addr->addr = g_strdup(ipAddress);
> +    addr->prefix = prefixLength;
> +
> +    return 1;
> +}
> +
> +
> +static int
> +esxDomainInterfaceAddresses(virDomainPtr domain,
> +                            virDomainInterfacePtr **ifaces,
> +                            unsigned int source,
> +                            unsigned int flags)
> +{
> +    int result = -1;
> +    esxPrivate *priv = domain->conn->privateData;
> +    esxVI_String *propertyNameList = NULL;
> +    esxVI_ObjectContent *virtualMachine = NULL;
> +    esxVI_VirtualMachinePowerState powerState;
> +    esxVI_DynamicProperty *dynamicProperty;
> +    esxVI_GuestNicInfo *guestNicInfoList = NULL;
> +    esxVI_GuestNicInfo *guestNicInfo = NULL;
> +    virDomainInterfacePtr *ifaces_ret = NULL;
> +    size_t ifaces_count = 0;
> +    size_t i;
> +    int ret;
> +
> +    virCheckFlags(0, -1);
> +    if (source != VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT) {
> +        virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED,
> +                       _("Unknown IP address data source %d"),
> +                       source);
> +        return -1;
> +    }
> +
> +    if (esxVI_EnsureSession(priv->primary) < 0)
> +        return -1;
> +
> +    if (esxVI_String_AppendValueListToList(&propertyNameList,
> +                                           "runtime.powerState\0"
> +                                           "guest.net") < 0 ||
> +        esxVI_LookupVirtualMachineByUuid(priv->primary, domain->uuid,
> +                                         propertyNameList, &virtualMachine,
> +                                         esxVI_Occurrence_RequiredItem) ||
> +        esxVI_GetVirtualMachinePowerState(virtualMachine, &powerState) < 0) {
> +        goto cleanup;
> +    }
> +
> +    if (powerState != esxVI_VirtualMachinePowerState_PoweredOn) {
> +        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
> +                       _("Domain is not powered on"));
> +        goto cleanup;
> +    }
> +
> +    for (dynamicProperty = virtualMachine->propSet; dynamicProperty;
> +         dynamicProperty = dynamicProperty->_next) {
> +        if (STREQ(dynamicProperty->name, "guest.net")) {
> +            if (esxVI_GuestNicInfo_CastListFromAnyType
> +                     (dynamicProperty->val, &guestNicInfoList) < 0) {
> +                goto cleanup;
> +            }
> +        }
> +    }
> +
> +    if (!guestNicInfoList)
> +        goto cleanup;
> +
> +    for (guestNicInfo = guestNicInfoList; guestNicInfo;
> +         guestNicInfo = guestNicInfo->_next) {
> +        virDomainInterfacePtr iface = NULL;
> +        size_t addrs_count = 0;
> +
> +        if (guestNicInfo->connected != esxVI_Boolean_True ||
> +            !guestNicInfo->network) {
> +            continue;
> +        }
> +
> +        if (VIR_EXPAND_N(ifaces_ret, ifaces_count, 1) < 0)
> +            goto cleanup;
> +
> +        if (VIR_ALLOC(ifaces_ret[ifaces_count - 1]) < 0)
> +            goto cleanup;
> +
> +        iface = ifaces_ret[ifaces_count - 1];
> +        iface->naddrs = 0;
> +        iface->name = g_strdup(guestNicInfo->network);
> +        iface->hwaddr = g_strdup(guestNicInfo->macAddress);
> +
> +        if (guestNicInfo->ipConfig) {
> +            esxVI_NetIpConfigInfoIpAddress *ipAddress;
> +            for (ipAddress = guestNicInfo->ipConfig->ipAddress; ipAddress;
> +                 ipAddress = ipAddress->_next) {
> +                virDomainIPAddress ip_addr;
> +
> +                ret = esxParseIPAddress(ipAddress->ipAddress,
> +                                        ipAddress->prefixLength->value, &ip_addr);
> +                if (ret < 0)
> +                    goto cleanup;
> +                else if (ret == 0)
> +                    continue;
> +
> +                if (VIR_APPEND_ELEMENT(iface->addrs, addrs_count, ip_addr)  < 0)
> +                    goto cleanup;
> +            }
> +        } else {
> +            esxVI_String *str;
> +            for (str = guestNicInfo->ipAddress; str;
> +                 str = str->_next) {
> +                virDomainIPAddress ip_addr;
> +
> +                /* Not even the netmask seems available... */
> +                ret = esxParseIPAddress(str->value, 0, &ip_addr);
> +                if (ret < 0)
> +                    goto cleanup;
> +                else if (ret == 0)
> +                    continue;
> +
> +                if (VIR_APPEND_ELEMENT(iface->addrs, addrs_count, ip_addr)  < 0)
> +                    goto cleanup;
> +
> +            }
> +        }
> +
> +        iface->naddrs = addrs_count;
> +    }
> +
> +    *ifaces = ifaces_ret;
> +    result = ifaces_count;
> +
> + cleanup:
> +    if (result < 0) {
> +        if (ifaces_ret) {
> +            for (i = 0; i < ifaces_count; i++)
> +                virDomainInterfaceFree(ifaces_ret[i]);
> +        }

Small nit, ifaces_count can't be anything else than zero without 
ifaces_ret being not NULL. So I'd drop the ifces_ret check. I'll also 
post a patch to remove it from other places around our code.

Michal




More information about the libvir-list mailing list