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

Michal Privoznik mprivozn at redhat.com
Thu Jun 21 13:56:00 UTC 2012


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"));
+            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"));
+                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;
+}
diff --git a/src/qemu/qemu_agent.h b/src/qemu/qemu_agent.h
index 0816d90..1561652 100644
--- a/src/qemu/qemu_agent.h
+++ b/src/qemu/qemu_agent.h
@@ -80,4 +80,6 @@ int qemuAgentFSThaw(qemuAgentPtr mon);
 
 int qemuAgentSuspend(qemuAgentPtr mon,
                      unsigned int target);
+
+char *qemuAgentGetInterfaces(qemuAgentPtr mon);
 #endif /* __QEMU_AGENT_H__ */
-- 
1.7.8.5




More information about the libvir-list mailing list