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

Michal Privoznik mprivozn at redhat.com
Thu Jan 3 13:46:20 UTC 2013


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();
+        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++) {
+            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"));
+                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"));
+                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]);
+        VIR_FREE(*ifaces);
+    }
+    return ret;
+}
+
+int
+qemuAgentGetInterfaces(qemuAgentPtr mon,
+                       virDomainInterfacePtr **ifaces)
+{
+    int ret = -1;
+    virJSONValuePtr cmd;
+    virJSONValuePtr reply = NULL;
+
+    cmd = qemuAgentMakeCommand("guest-network-get-interfaces", NULL);
+
+    if (!cmd)
+        return ret;
+
+    ret = qemuAgentCommand(mon, cmd, &reply,
+                           VIR_DOMAIN_QEMU_AGENT_COMMAND_BLOCK);
+
+    if (reply && ret == 0)
+        ret = qemuAgentCheckError(cmd, reply);
+
+    if (ret == 0)
+        ret = getInterfaces(reply, ifaces);
+
+    virJSONValueFree(cmd);
+    virJSONValueFree(reply);
+    return ret;
+}
diff --git a/src/qemu/qemu_agent.h b/src/qemu/qemu_agent.h
index dad068b..0c22920 100644
--- a/src/qemu/qemu_agent.h
+++ b/src/qemu/qemu_agent.h
@@ -85,4 +85,6 @@ int qemuAgentArbitraryCommand(qemuAgentPtr mon,
                               int timeout);
 int qemuAgentFSTrim(qemuAgentPtr mon,
                     unsigned long long minimum);
+int qemuAgentGetInterfaces(qemuAgentPtr mon,
+                           virDomainInterfacePtr **ifaces);
 #endif /* __QEMU_AGENT_H__ */
-- 
1.8.0.2




More information about the libvir-list mailing list