From d5b5a890dd6941e1cb05fa8e6c12d21fd449c8ad Mon Sep 17 00:00:00 2001 From: Jonathon Jongsma Date: Fri, 23 Aug 2019 11:31:18 -0500 Subject: [PATCH] qemu: add helper function for querying OS info This function queries the guest operating system information and adds the returned information to an array of typed parameters with field names intended to be returned in virDomainGetGuestInfo(). Signed-off-by: Jonathon Jongsma Signed-off-by: Michal Privoznik Reviewed-by: Michal Privoznik Reviewed-by: Daniel Henrique Barboza Tested-by: Daniel Henrique Barboza --- src/qemu/qemu_agent.c | 47 ++++++++++++++++ src/qemu/qemu_agent.h | 5 ++ tests/qemuagenttest.c | 122 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 174 insertions(+) diff --git a/src/qemu/qemu_agent.c b/src/qemu/qemu_agent.c index 0dea7ebfa4..8eb19ac3be 100644 --- a/src/qemu/qemu_agent.c +++ b/src/qemu/qemu_agent.c @@ -2325,3 +2325,50 @@ qemuAgentGetUsers(qemuAgentPtr mon, return ndata; } + +int +qemuAgentGetOSInfo(qemuAgentPtr mon, + virTypedParameterPtr *params, + int *nparams, + int *maxparams) +{ + VIR_AUTOPTR(virJSONValue) cmd = NULL; + VIR_AUTOPTR(virJSONValue) reply = NULL; + virJSONValuePtr data = NULL; + + if (!(cmd = qemuAgentMakeCommand("guest-get-osinfo", NULL))) + return -1; + + if (qemuAgentCommand(mon, cmd, &reply, true, + VIR_DOMAIN_QEMU_AGENT_COMMAND_BLOCK) < 0) + return -1; + + if (!(data = virJSONValueObjectGetObject(reply, "return"))) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("guest-get-osinfo reply was missing return data")); + return -1; + } + +#define OSINFO_ADD_PARAM(agent_string_, param_string_) \ + do { \ + const char *result; \ + if ((result = virJSONValueObjectGetString(data, agent_string_))) { \ + if (virTypedParamsAddString(params, nparams, maxparams, \ + param_string_, result) < 0) { \ + return -1; \ + } \ + } \ + } while (0) + OSINFO_ADD_PARAM("id", "os.id"); + OSINFO_ADD_PARAM("name", "os.name"); + OSINFO_ADD_PARAM("pretty-name", "os.pretty-name"); + OSINFO_ADD_PARAM("version", "os.version"); + OSINFO_ADD_PARAM("version-id", "os.version-id"); + OSINFO_ADD_PARAM("machine", "os.machine"); + OSINFO_ADD_PARAM("variant", "os.variant"); + OSINFO_ADD_PARAM("variant-id", "os.variant-id"); + OSINFO_ADD_PARAM("kernel-release", "os.kernel-release"); + OSINFO_ADD_PARAM("kernel-version", "os.kernel-version"); + + return 0; +} diff --git a/src/qemu/qemu_agent.h b/src/qemu/qemu_agent.h index 9b36427ee7..558f5cc7fd 100644 --- a/src/qemu/qemu_agent.h +++ b/src/qemu/qemu_agent.h @@ -125,3 +125,8 @@ int qemuAgentGetUsers(qemuAgentPtr mon, virTypedParameterPtr *params, int *nparams, int *maxparams); + +int qemuAgentGetOSInfo(qemuAgentPtr mon, + virTypedParameterPtr *params, + int *nparams, + int *maxparams); diff --git a/tests/qemuagenttest.c b/tests/qemuagenttest.c index 81e0c41e61..d0603f9efb 100644 --- a/tests/qemuagenttest.c +++ b/tests/qemuagenttest.c @@ -1048,6 +1048,127 @@ testQemuAgentUsers(const void *data) return ret; } +static const char testQemuAgentOSInfoResponse[] = + "{\"return\": " + " {\"name\":\"CentOS Linux\", " + " \"kernel-release\":\"3.10.0-862.14.4.el7.x86_64\", " + " \"version\":\"7 (Core)\", " + " \"pretty-name\":\"CentOS Linux 7 (Core)\", " + " \"version-id\":\"7\", " + " \"kernel-version\":\"#1 SMP Wed Sep 26 15:12:11 UTC 2018\", " + " \"machine\":\"x86_64\", " + " \"id\":\"centos\"} " + "}"; + +static const char testQemuAgentOSInfoResponse2[] = + "{\"return\": " + " {\"name\":\"Microsoft Windows\", " + " \"kernel-release\":\"7601\", " + " \"version\":\"Microsoft Windows 77\", " + " \"variant\":\"client\", " + " \"pretty-name\":\"Windows 7 Professional\", " + " \"version-id\":\"\", " + " \"variant-id\":\"client\", " + " \"kernel-version\":\"6.1\", " + " \"machine\":\"x86_64\", " + " \"id\":\"mswindows\"} " + "}"; + +static int +testQemuAgentOSInfo(const void *data) +{ + virDomainXMLOptionPtr xmlopt = (virDomainXMLOptionPtr)data; + qemuMonitorTestPtr test = qemuMonitorTestNewAgent(xmlopt); + virTypedParameterPtr params = NULL; + int nparams = 0; + int maxparams = 0; + int ret = -1; + + if (!test) + return -1; + + if (qemuMonitorTestAddAgentSyncResponse(test) < 0) + goto cleanup; + + if (qemuMonitorTestAddItem(test, "guest-get-osinfo", + testQemuAgentOSInfoResponse) < 0) + goto cleanup; + + /* get osinfo */ + if (qemuAgentGetOSInfo(qemuMonitorTestGetAgent(test), + ¶ms, &nparams, &maxparams) < 0) + goto cleanup; + + if (nparams != 8) { + virReportError(VIR_ERR_INTERNAL_ERROR, + "Expected 8 params, got %d", nparams); + goto cleanup; + } +#define VALIDATE_PARAM(param_name_, expected_) \ + do { \ + const char *value_ = NULL; \ + if (virTypedParamsGetString(params, nparams, param_name_, &value_) < 0 || \ + value_ == NULL) { \ + virReportError(VIR_ERR_INTERNAL_ERROR, "missing param '%s'", param_name_); \ + goto cleanup; \ + } \ + if (STRNEQ(value_, expected_)) { \ + virReportError(VIR_ERR_INTERNAL_ERROR, \ + "Expected name '%s', got '%s'", expected_, value_); \ + goto cleanup; \ + } \ + } while (0) + + VALIDATE_PARAM("os.id", "centos"); + VALIDATE_PARAM("os.name", "CentOS Linux"); + VALIDATE_PARAM("os.version", "7 (Core)"); + VALIDATE_PARAM("os.version-id", "7"); + VALIDATE_PARAM("os.pretty-name", "CentOS Linux 7 (Core)"); + VALIDATE_PARAM("os.kernel-release", "3.10.0-862.14.4.el7.x86_64"); + VALIDATE_PARAM("os.kernel-version", "#1 SMP Wed Sep 26 15:12:11 UTC 2018"); + VALIDATE_PARAM("os.machine", "x86_64"); + virTypedParamsFree(params, nparams); + params = NULL; + nparams = 0; + maxparams = 0; + + if (qemuMonitorTestAddAgentSyncResponse(test) < 0) + goto cleanup; + + if (qemuMonitorTestAddItem(test, "guest-get-osinfo", + testQemuAgentOSInfoResponse2) < 0) + goto cleanup; + + /* get users with domain */ + if (qemuAgentGetOSInfo(qemuMonitorTestGetAgent(test), + ¶ms, &nparams, &maxparams) < 0) + goto cleanup; + + if (nparams != 10) { + virReportError(VIR_ERR_INTERNAL_ERROR, + "Expected 10 params, got %d", nparams); + goto cleanup; + } + + VALIDATE_PARAM("os.id", "mswindows"); + VALIDATE_PARAM("os.name", "Microsoft Windows"); + VALIDATE_PARAM("os.pretty-name", "Windows 7 Professional"); + VALIDATE_PARAM("os.version", "Microsoft Windows 77"); + VALIDATE_PARAM("os.version-id", ""); + VALIDATE_PARAM("os.variant", "client"); + VALIDATE_PARAM("os.variant-id", "client"); + VALIDATE_PARAM("os.kernel-release", "7601"); + VALIDATE_PARAM("os.kernel-version", "6.1"); + VALIDATE_PARAM("os.machine", "x86_64"); + virTypedParamsFree(params, nparams); + + ret = 0; + + cleanup: + qemuMonitorTestFree(test); + return ret; +} + static int mymain(void) @@ -1079,6 +1200,7 @@ mymain(void) DO_TEST(ArbitraryCommand); DO_TEST(GetInterfaces); DO_TEST(Users); + DO_TEST(OSInfo); DO_TEST(Timeout); /* Timeout should always be called last */