This command returns an array of all guest interfaces among with their IP and HW addresses. --- src/qemu/qemu_agent.c | 164 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_agent.h | 2 + 2 files changed, 166 insertions(+) diff --git a/src/qemu/qemu_agent.c b/src/qemu/qemu_agent.c index bb421bd..ba17a26 100644 --- a/src/qemu/qemu_agent.c +++ b/src/qemu/qemu_agent.c @@ -1474,3 +1474,167 @@ 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) < 0) { + virReportOOMError(); + goto cleanup; + } + + for (i = 0; i < size; i++) { + virJSONValuePtr jsonIface = virJSONValueArrayGet(replyArray, i); + virDomainInterfacePtr tmpIface = &((*ifaces)[i]); + virJSONValuePtr jsonIpAddrArr = NULL; + int j, jsonIpAddrArrSize = 0; + const char *name, *hwaddr; + + /* 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) { + virDomainInterfaceFree(*ifaces, size); + *ifaces = NULL; + } + 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..43c78ff 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list