Signed-off-by: zhanglei <zhanglei@xxxxxxxxxx> --- src/qemu/qemu_agent.c | 9 +++-- src/qemu/qemu_agent.h | 3 +- src/qemu/qemu_driver.c | 89 +++++++++++++++++++++++++++++++++++++++++- tests/qemuagenttest.c | 2 +- 4 files changed, 96 insertions(+), 7 deletions(-) diff --git a/src/qemu/qemu_agent.c b/src/qemu/qemu_agent.c index 5f421be6f6..a7f943e0dc 100644 --- a/src/qemu/qemu_agent.c +++ b/src/qemu/qemu_agent.c @@ -2245,17 +2245,20 @@ qemuAgentGetAllInterfaceAddresses(virDomainInterfacePtr **ifaces_ret, */ int qemuAgentGetInterfaces(qemuAgent *agent, - virDomainInterfacePtr **ifaces) + virDomainInterfacePtr **ifaces, + bool report_unsupported) { g_autoptr(virJSONValue) cmd = NULL; g_autoptr(virJSONValue) reply = NULL; virJSONValue *ret_array = NULL; + int rc; if (!(cmd = qemuAgentMakeCommand("guest-network-get-interfaces", NULL))) return -1; - if (qemuAgentCommand(agent, cmd, &reply, agent->timeout) < 0) - return -1; + if ((rc = qemuAgentCommandFull(agent, cmd, &reply, agent->timeout, + report_unsupported)) < 0) + return rc; if (!(ret_array = virJSONValueObjectGetArray(reply, "return"))) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", diff --git a/src/qemu/qemu_agent.h b/src/qemu/qemu_agent.h index 81b45b8e5d..94eab9de9f 100644 --- a/src/qemu/qemu_agent.h +++ b/src/qemu/qemu_agent.h @@ -151,7 +151,8 @@ int qemuAgentSetTime(qemuAgent *mon, bool sync); int qemuAgentGetInterfaces(qemuAgent *mon, - virDomainInterfacePtr **ifaces); + virDomainInterfacePtr **ifaces, + bool report_unsupported); int qemuAgentSetUserPassword(qemuAgent *mon, const char *user, diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index dfc27572c4..ec5bf0a451 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -18950,7 +18950,7 @@ qemuDomainInterfaceAddresses(virDomainPtr dom, goto endjob; agent = qemuDomainObjEnterAgent(vm); - ret = qemuAgentGetInterfaces(agent, ifaces); + ret = qemuAgentGetInterfaces(agent, ifaces, true); qemuDomainObjExitAgent(vm, agent); endjob: @@ -19896,7 +19896,8 @@ static const unsigned int qemuDomainGetGuestInfoSupportedTypes = VIR_DOMAIN_GUEST_INFO_TIMEZONE | VIR_DOMAIN_GUEST_INFO_HOSTNAME | VIR_DOMAIN_GUEST_INFO_FILESYSTEM | - VIR_DOMAIN_GUEST_INFO_DISKS; + VIR_DOMAIN_GUEST_INFO_DISKS | + VIR_DOMAIN_GUEST_INFO_INTERFACES; static int qemuDomainGetGuestInfoCheckSupport(unsigned int types, @@ -20095,6 +20096,70 @@ qemuAgentFSInfoFormatParams(qemuAgentFSInfo **fsinfo, } } +static void +virDomainInterfaceFormatParams(virDomainInterfacePtr *ifaces, +int nifaces, +virTypedParameterPtr *params, +int *nparams, int * maxparams) +{ + size_t i, j; + const char *type = NULL; + + if (virTypedParamsAddUInt(params, nparams, maxparams, + "if.count", nifaces) < 0) + return; + + for (i = 0; i < nifaces; i++) { + char param_name[VIR_TYPED_PARAM_FIELD_LENGTH]; + + g_snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH, + "if.%zu.name", i); + if (virTypedParamsAddString(params, nparams, maxparams, + param_name, ifaces[i]->name) < 0) + return; + + g_snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH, + "if.%zu.hwaddr", i); + if (virTypedParamsAddString(params, nparams, maxparams, + param_name, ifaces[i]->hwaddr) < 0) + return; + + g_snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH, + "if.%zu.addr.count", i); + if (virTypedParamsAddUInt(params, nparams, maxparams, + param_name, ifaces[i]->naddrs) < 0) + return; + + for (j = 0; j < ifaces[i]->naddrs; j++) { + switch (ifaces[i]->addrs[j].type) { + case VIR_IP_ADDR_TYPE_IPV4: + type = "ipv4"; + break; + case VIR_IP_ADDR_TYPE_IPV6: + type = "ipv6"; + break; + } + + g_snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH, + "if.%zu.addr.%zu.type", i, j); + if (virTypedParamsAddString(params, nparams, maxparams, + param_name, type) < 0) + return; + + g_snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH, + "if.%zu.addr.%zu.addr", i, j); + if (virTypedParamsAddString(params, nparams, maxparams, + param_name, ifaces[i]->addrs[j].addr) < 0) + return; + + g_snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH, + "if.%zu.addr.%zu.prefix", i, j); + if (virTypedParamsAddUInt(params, nparams, maxparams, + param_name, ifaces[i]->addrs[j].prefix) < 0) + return; + } + } +} static int qemuDomainGetGuestInfo(virDomainPtr dom, @@ -20116,6 +20181,8 @@ qemuDomainGetGuestInfo(virDomainPtr dom, qemuAgentFSInfo **agentfsinfo = NULL; size_t ndisks = 0; qemuAgentDiskInfo **agentdiskinfo = NULL; + virDomainInterfacePtr *ifaces = NULL; + size_t nifaces = 0; size_t i; virCheckFlags(0, -1); @@ -20181,6 +20248,15 @@ qemuDomainGetGuestInfo(virDomainPtr dom, } } + if (supportedTypes & VIR_DOMAIN_GUEST_INFO_INTERFACES) { + rc = qemuAgentGetInterfaces(agent, &ifaces, report_unsupported); + if (rc == -1) { + goto exitagent; + } else if (rc >= 0) { + nifaces = rc; + } + } + qemuDomainObjExitAgent(vm, agent); qemuDomainObjEndAgentJob(vm); @@ -20203,6 +20279,10 @@ qemuDomainGetGuestInfo(virDomainPtr dom, qemuDomainObjEndJob(driver, vm); } + if (nifaces > 0) { + virDomainInterfaceFormatParams(ifaces, nifaces, params, nparams, &maxparams); + } + ret = 0; cleanup: @@ -20212,6 +20292,11 @@ qemuDomainGetGuestInfo(virDomainPtr dom, for (i = 0; i < ndisks; i++) qemuAgentDiskInfoFree(agentdiskinfo[i]); g_free(agentdiskinfo); + if (ifaces && nifaces > 0) { + for (i = 0; i < nifaces; i++) + virDomainInterfaceFree(ifaces[i]); + } + g_free(ifaces); virDomainObjEndAPI(&vm); return ret; diff --git a/tests/qemuagenttest.c b/tests/qemuagenttest.c index bef6dfd152..8fb3da7fef 100644 --- a/tests/qemuagenttest.c +++ b/tests/qemuagenttest.c @@ -907,7 +907,7 @@ testQemuAgentGetInterfaces(const void *data) goto cleanup; if ((ifaces_count = qemuAgentGetInterfaces(qemuMonitorTestGetAgent(test), - &ifaces)) < 0) + &ifaces, true)) < 0) goto cleanup; if (ifaces_count != 4) { -- 2.31.1