[libvirt] [PATCH v2 3/8] qemu_agent: Implement 'guest-network-get-interfaces' command handling

Ján Tomko jtomko at redhat.com
Fri Jan 4 14:22:01 UTC 2013


On 01/03/13 14:46, Michal Privoznik wrote:
> This command returns an array of all guest interfaces among
> with their IP and HW addresses.
> ---
>  src/qemu/qemu_agent.c | 171 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  src/qemu/qemu_agent.h |   2 +
>  2 files changed, 173 insertions(+)
> 
> diff --git a/src/qemu/qemu_agent.c b/src/qemu/qemu_agent.c
> index bb421bd..409ba04 100644
> --- a/src/qemu/qemu_agent.c
> +++ b/src/qemu/qemu_agent.c
> @@ -1474,3 +1474,174 @@ qemuAgentFSTrim(qemuAgentPtr mon,
>      virJSONValueFree(reply);
>      return ret;
>  }
> +
> +static int
> +getInterfaces(virJSONValuePtr reply,
> +              virDomainInterfacePtr **ifaces)
> +{
> +    int ret = -1;
> +    int i, size = 0;
> +    virJSONValuePtr replyArray = NULL;
> +
> +    if (!(replyArray = virJSONValueObjectGet(reply, "return"))) {
> +        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> +                       _("qemu agent did not provide 'return' object"));
> +        goto cleanup;
> +    }
> +
> +    if ((size = virJSONValueArraySize(replyArray)) < 0) {
> +        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> +                       _("qemu agent did not provide any interface"));
> +        goto cleanup;
> +    }
> +
> +    if (size && VIR_ALLOC_N(*ifaces, size * sizeof(virDomainInterfacePtr)) < 0) {
> +        virReportOOMError();

size is > 0 now and *ifaces = NULL, if you jump to cleanup you'll
dereference it. I'd suggest just returning -1 here and above.

> +        goto cleanup;
> +    }
> +
> +    for (i = 0; i < size; i++) {
> +        virJSONValuePtr jsonIface = virJSONValueArrayGet(replyArray, i);
> +        virDomainInterfacePtr tmpIface = NULL;
> +        virJSONValuePtr jsonIpAddrArr = NULL;
> +        int j, jsonIpAddrArrSize = 0;
> +        const char *name, *hwaddr;
> +
> +        if (VIR_ALLOC(tmpIface) < 0) {
> +            virReportOOMError();
> +            goto cleanup;
> +        }
> +
> +        (*ifaces)[i] = tmpIface;
> +        /* should not happen, but doesn't hurt to check */
> +        if (!jsonIface) {
> +            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> +                           _("Something went really wrong while processing "
> +                             "guest agent reply"));
> +            goto cleanup;
> +        }
> +
> +        name = virJSONValueObjectGetString(jsonIface, "name");
> +        if (!name) {
> +            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> +                           _("qemu agent did not provide 'name' object"));
> +            goto cleanup;
> +        }
> +
> +        if (!(tmpIface->name = strdup(name))) {
> +            virReportOOMError();
> +            goto cleanup;
> +        }
> +
> +        /* hwaddr might be omitted */
> +        hwaddr = virJSONValueObjectGetString(jsonIface, "hardware-address");
> +        if (hwaddr && !(tmpIface->hwaddr = strdup(hwaddr))) {
> +            virReportOOMError();
> +            goto cleanup;
> +        }
> +
> +        /* as well as ip-addresses */
> +        jsonIpAddrArr = virJSONValueObjectGet(jsonIface, "ip-addresses");
> +        if (!jsonIpAddrArr)
> +            continue;
> +
> +        if ((jsonIpAddrArrSize = virJSONValueArraySize(jsonIpAddrArr)) < 0) {
> +            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> +                           _("qemu agent provided malformed "
> +                             "ip-addresses field"));
> +            goto cleanup;
> +        }
> +
> +        if (VIR_ALLOC_N(tmpIface->ip_addrs, jsonIpAddrArrSize) < 0) {
> +            virReportOOMError();
> +            goto cleanup;
> +        }
> +        tmpIface->ip_addrs_count = jsonIpAddrArrSize;
> +
> +        for (j = 0; j <  jsonIpAddrArrSize; j++) {

extra space

> +            virJSONValuePtr jsonIpAddr = virJSONValueArrayGet(jsonIpAddrArr, j);
> +            virDomainIPAddressPtr tmpIpAddr = &(tmpIface->ip_addrs[j]);
> +            const char *ipAddr, *ipAddrType;
> +
> +            if (!(ipAddr = virJSONValueObjectGetString(jsonIpAddr,
> +                                                       "ip-address"))) {
> +                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> +                               _("qemu-agent didn't provided "
> +                                 "an ip-address field"));

didn't provide

> +                goto cleanup;
> +            }
> +
> +            if (!(tmpIpAddr->addr = strdup(ipAddr))) {
> +                virReportOOMError();
> +                goto cleanup;
> +            }
> +
> +            if (!(ipAddrType = virJSONValueObjectGetString(jsonIpAddr,
> +                                                           "ip-address-type"))) {
> +                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> +                               _("qemu-agent didn't provided "
> +                                 "an ip-address-type field"));

here too

> +                goto cleanup;
> +            }
> +
> +            if (STREQ(ipAddrType, "ipv4"))
> +                tmpIpAddr->type = VIR_IP_ADDR_TYPE_IPV4;
> +            else if (STREQ(ipAddrType, "ipv6"))
> +                tmpIpAddr->type = VIR_IP_ADDR_TYPE_IPV6;
> +            else {
> +                virReportError(VIR_ERR_INTERNAL_ERROR,
> +                               _("qemu agent provided unknown "
> +                                 "ip-address-type '%s'"),
> +                               ipAddrType);
> +                goto cleanup;
> +            }
> +
> +            if (virJSONValueObjectGetNumberInt(jsonIpAddr, "prefix",
> +                                               &(tmpIpAddr->prefix)) < 0) {
> +                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> +                               _("qemu agent provided "
> +                                 "malformed prefix field"));
> +                goto cleanup;
> +            }
> +
> +            /* Nor broadcast address is reported */
> +        }
> +    }
> +
> +    ret = size;
> +
> +cleanup:
> +    if (ret < 0) {
> +        for (i = 0; i < size; i++)
> +            virDomainInterfaceFree((*ifaces)[i]);

(*ifaces)[i] might be NULL here, but virDomainInterfaceFree doesn't
check for that.

> +        VIR_FREE(*ifaces);
> +    }
> +    return ret;
> +}
> +




More information about the libvir-list mailing list