From b11f485382eec34cd92276499c1e8cf2ac858795 Mon Sep 17 00:00:00 2001 From: Jonathon Jongsma Date: Fri, 23 Aug 2019 11:31:19 -0500 Subject: [PATCH] qemu: add helper for querying timezone info This function queries timezone information within the guest and adds the information to an array of typed parameters with field names intended to be returned to 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 | 43 ++++++++++++++++++++++++ src/qemu/qemu_agent.h | 5 +++ tests/qemuagenttest.c | 76 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 124 insertions(+) diff --git a/src/qemu/qemu_agent.c b/src/qemu/qemu_agent.c index 8eb19ac3be..a92e530dd1 100644 --- a/src/qemu/qemu_agent.c +++ b/src/qemu/qemu_agent.c @@ -2372,3 +2372,46 @@ qemuAgentGetOSInfo(qemuAgentPtr mon, return 0; } + +int +qemuAgentGetTimezone(qemuAgentPtr mon, + virTypedParameterPtr *params, + int *nparams, + int *maxparams) +{ + VIR_AUTOPTR(virJSONValue) cmd = NULL; + VIR_AUTOPTR(virJSONValue) reply = NULL; + virJSONValuePtr data = NULL; + const char *name; + int offset; + + if (!(cmd = qemuAgentMakeCommand("guest-get-timezone", 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-timezone reply was missing return data")); + return -1; + } + + if ((name = virJSONValueObjectGetString(data, "zone")) && + virTypedParamsAddString(params, nparams, maxparams, + "timezone.name", name) < 0) + return -1; + + if ((virJSONValueObjectGetNumberInt(data, "offset", &offset)) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("'offset' missing in reply of guest-get-timezone")); + return -1; + } + + if (virTypedParamsAddInt(params, nparams, maxparams, + "timezone.offset", offset) < 0) + return -1; + + return 0; +} diff --git a/src/qemu/qemu_agent.h b/src/qemu/qemu_agent.h index 558f5cc7fd..1224efcadc 100644 --- a/src/qemu/qemu_agent.h +++ b/src/qemu/qemu_agent.h @@ -130,3 +130,8 @@ int qemuAgentGetOSInfo(qemuAgentPtr mon, virTypedParameterPtr *params, int *nparams, int *maxparams); + +int qemuAgentGetTimezone(qemuAgentPtr mon, + virTypedParameterPtr *params, + int *nparams, + int *maxparams); diff --git a/tests/qemuagenttest.c b/tests/qemuagenttest.c index d0603f9efb..e6846efc13 100644 --- a/tests/qemuagenttest.c +++ b/tests/qemuagenttest.c @@ -1169,7 +1169,82 @@ testQemuAgentOSInfo(const void *data) return ret; } +static const char testQemuAgentTimezoneResponse1[] = +"{\"return\":{\"zone\":\"IST\",\"offset\":19800}}"; +static const char testQemuAgentTimezoneResponse2[] = +"{\"return\":{\"zone\":\"CEST\",\"offset\":7200}}"; +static const char testQemuAgentTimezoneResponse3[] = +"{\"return\":{\"zone\":\"NDT\",\"offset\":-9000}}"; +static const char testQemuAgentTimezoneResponse4[] = +"{\"return\":{\"zone\":\"PDT\",\"offset\":-25200}}"; +static int +testQemuAgentTimezone(const void *data) +{ + virDomainXMLOptionPtr xmlopt = (virDomainXMLOptionPtr)data; + qemuMonitorTestPtr test = qemuMonitorTestNewAgent(xmlopt); + int ret = -1; + + if (!test) + return -1; + +#define VALIDATE_TIMEZONE(response_, expected_name_, expected_offset_) \ + do { \ + virTypedParameterPtr params_ = NULL; \ + int nparams_ = 0; \ + int maxparams_ = 0; \ + const char *name_ = NULL; \ + int offset_; \ + if (qemuMonitorTestAddAgentSyncResponse(test) < 0) \ + goto cleanup; \ + if (qemuMonitorTestAddItem(test, "guest-get-timezone", \ + response_) < 0) \ + goto cleanup; \ + if (qemuAgentGetTimezone(qemuMonitorTestGetAgent(test), \ + ¶ms_, &nparams_, &maxparams_) < 0) \ + goto cleanup; \ + if (nparams_ != 2) { \ + virReportError(VIR_ERR_INTERNAL_ERROR, \ + "Expected 2 params, got %d", nparams_); \ + goto cleanup; \ + } \ + if (virTypedParamsGetString(params_, nparams_, \ + "timezone.name", &name_) < 0) { \ + virReportError(VIR_ERR_INTERNAL_ERROR, "missing param '%s'", \ + "tiemzone.name"); \ + goto cleanup; \ + } \ + if (STRNEQ(name_, expected_name_)) { \ + virReportError(VIR_ERR_INTERNAL_ERROR, \ + "Expected name '%s', got '%s'", expected_name_, name_); \ + goto cleanup; \ + } \ + if (virTypedParamsGetInt(params_, nparams_, \ + "timezone.offset", &offset_) < 0) { \ + virReportError(VIR_ERR_INTERNAL_ERROR, "missing param '%s'", \ + "tiemzone.offset"); \ + goto cleanup; \ + } \ + if (offset_ != expected_offset_) { \ + virReportError(VIR_ERR_INTERNAL_ERROR, \ + "Expected offset '%i', got '%i'", offset_, \ + expected_offset_); \ + goto cleanup; \ + } \ + virTypedParamsFree(params_, nparams_); \ + } while (0) + + VALIDATE_TIMEZONE(testQemuAgentTimezoneResponse1, "IST", 19800); + VALIDATE_TIMEZONE(testQemuAgentTimezoneResponse2, "CEST", 7200); + VALIDATE_TIMEZONE(testQemuAgentTimezoneResponse3, "NDT", -9000); + VALIDATE_TIMEZONE(testQemuAgentTimezoneResponse4, "PDT", -25200); + + ret = 0; + + cleanup: + qemuMonitorTestFree(test); + return ret; +} static int mymain(void) { @@ -1201,6 +1276,7 @@ mymain(void) DO_TEST(GetInterfaces); DO_TEST(Users); DO_TEST(OSInfo); + DO_TEST(Timezone); DO_TEST(Timeout); /* Timeout should always be called last */ -- 2.39.5