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

Peter Krempa pkrempa at redhat.com
Tue Jun 26 09:59:20 UTC 2012


On 06/21/12 15:56, Michal Privoznik wrote:
> This command returns an array of all guest interfaces among
> with their IP and HW addresses.
> ---
>   src/qemu/qemu_agent.c |  135 +++++++++++++++++++++++++++++++++++++++++++++++++
>   src/qemu/qemu_agent.h |    2 +
>   2 files changed, 137 insertions(+), 0 deletions(-)
>
> diff --git a/src/qemu/qemu_agent.c b/src/qemu/qemu_agent.c
> index 7a0381c..cab02a0 100644
> --- a/src/qemu/qemu_agent.c
> +++ b/src/qemu/qemu_agent.c
> @@ -1410,3 +1410,138 @@ qemuAgentSuspend(qemuAgentPtr mon,
>       virJSONValueFree(reply);
>       return ret;
>   }
> +
> +char *
> +qemuAgentGetInterfaces(qemuAgentPtr mon)
> +{
> +    char *ret = NULL;
> +    int i, j, size = -1;
> +    virJSONValuePtr cmd;
> +    virJSONValuePtr reply = NULL;
> +    virJSONValuePtr ret_array = NULL;
> +    virBuffer buf = VIR_BUFFER_INITIALIZER;
> +
> +    cmd = qemuAgentMakeCommand("guest-network-get-interfaces", NULL);
> +
> +    if (!cmd)
> +        return NULL;
> +
> +    if (qemuAgentCommand(mon, cmd, &reply) < 0 ||
> +        qemuAgentCheckError(cmd, reply) < 0)
> +        goto cleanup;
> +
> +    if (!(ret_array = virJSONValueObjectGet(reply, "return"))) {
> +        qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> +                        _("qemu agent didn't provide 'return' field"));
> +        goto cleanup;
> +    }
> +
> +    if ((size = virJSONValueArraySize(ret_array)) < 0) {
> +        qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> +                        _("qemu agent didn't return an array of interfaces"));
> +        goto cleanup;
> +    }
> +
> +    virBufferAddLit(&buf, "<interfaces>\n");
> +    virBufferAdjustIndent(&buf, 2);
> +
> +    for (i = 0; i < size; i++) {
> +        virJSONValuePtr tmp_iface = virJSONValueArrayGet(ret_array, i);
> +        virJSONValuePtr ip_addr_arr = NULL;
> +        const char *name, *hwaddr;
> +        int ip_addr_arr_size;
> +
> +        /* Shouldn't happen but doesn't hurt to check neither */
> +        if (!tmp_iface) {
> +            qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> +                            _("something has went really wrong"));

If you check for this to happen, you should provide a more helpful 
message for both the user and for you if somebody complains:
"failed to extract interface information" perhaps?

> +            goto cleanup;
> +        }
> +
> +        virBufferAddLit(&buf, "<interface>\n");
> +        virBufferAdjustIndent(&buf, 2);
> +
> +        /* interface name is required to be presented */
> +        name = virJSONValueObjectGetString(tmp_iface, "name");
> +        if (!name) {
> +            qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> +                            _("qemu agent didn't provide 'name' field"));
> +            goto cleanup;
> +        }
> +        virBufferAsprintf(&buf, "<name>%s</name>\n", name);
> +
> +        /* hwaddr might be omitted */
> +        hwaddr = virJSONValueObjectGetString(tmp_iface, "hardware-address");
> +        if (hwaddr)
> +            virBufferAsprintf(&buf, "<hwaddr>%s</hwaddr>\n", hwaddr);
> +
> +        /* as well as IP address which - moreover -
> +         * can be presented multiple times */
> +        ip_addr_arr = virJSONValueObjectGet(tmp_iface, "ip-addresses");
> +        if (!ip_addr_arr)
> +            goto interface_cont;
> +
> +        if ((ip_addr_arr_size = virJSONValueArraySize(ip_addr_arr)) < 0) {
> +            /* Mmm, empty 'ip-address'? */
> +            goto interface_cont;
> +        }
> +
> +        virBufferAddLit(&buf, "<addresses>\n");
> +        virBufferAdjustIndent(&buf, 2);
> +        for (j = 0; j < ip_addr_arr_size; j++) {
> +            virJSONValuePtr ip_addr_obj = virJSONValueArrayGet(ip_addr_arr, j);
> +            const char *type, *addr;
> +            int prefix;
> +
> +            /* Shouldn't happen but doesn't hurt to check neither */
> +            if (!ip_addr_obj) {
> +                qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> +                                _("something has went really wrong"));

Same as above. A bit more explanatory error message would be great.

> +                goto cleanup;
> +            }
> +
> +            type = virJSONValueObjectGetString(ip_addr_obj, "ip-address-type");
> +            if (!type) {
> +                qemuReportError(VIR_ERR_INTERNAL_ERROR,
> +                                _("qemu agent didn't provide 'ip-address-type'"
> +                                  " field for interface '%s'"), name);
> +                goto cleanup;
> +            }
> +
> +            addr = virJSONValueObjectGetString(ip_addr_obj, "ip-address");
> +            if (!addr) {
> +                qemuReportError(VIR_ERR_INTERNAL_ERROR,
> +                                _("qemu agent didn't provide 'ip-address'"
> +                                  " field for interface '%s'"), name);
> +                goto cleanup;
> +            }
> +
> +            if (virJSONValueObjectGetNumberInt(ip_addr_obj, "prefix",
> +                                               &prefix) < 0) {
> +                qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> +                                _("malformed 'prefix' field"));
> +                goto cleanup;
> +            }
> +            virBufferAsprintf(&buf, "<ip type='%s' prefix='%d'>%s</ip>\n",
> +                              type, prefix, addr);
> +        }
> +
> +        virBufferAdjustIndent(&buf, -2);
> +        virBufferAddLit(&buf, "</addresses>\n");
> +
> +interface_cont:
> +        virBufferAdjustIndent(&buf, -2);
> +        virBufferAddLit(&buf, "</interface>\n");
> +    }
> +
> +    virBufferAdjustIndent(&buf, -2);
> +    virBufferAddLit(&buf, "</interfaces>\n");
> +
> +    ret = virBufferContentAndReset(&buf);
> +
> +cleanup:
> +    virBufferFreeAndReset(&buf);
> +    virJSONValueFree(cmd);
> +    virJSONValueFree(reply);
> +    return ret;
> +}


ACK with error messages tweaked.

Peter




More information about the libvir-list mailing list