From 43177e2fd0e05e56f72f0792d237e492145b7337 Mon Sep 17 00:00:00 2001 From: Qiao Nuohan Date: Sun, 23 Mar 2014 11:51:13 +0800 Subject: [PATCH] qemu: add qemuMonitorGetDumpGuestMemoryCapability This patch adds qemuMonitorGetDumpGuestMemoryCapability, which is used to check whether the specified dump-guest-memory format is supported by qemu. Signed-off-by: Qiao Nuohan --- src/qemu/qemu_monitor.c | 21 ++++++++++++ src/qemu/qemu_monitor.h | 3 ++ src/qemu/qemu_monitor_json.c | 65 ++++++++++++++++++++++++++++++++++++ src/qemu/qemu_monitor_json.h | 3 ++ tests/qemumonitorjsontest.c | 43 ++++++++++++++++++++++++ 5 files changed, 135 insertions(+) diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 357c9709fc..976a95453e 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -2368,6 +2368,27 @@ int qemuMonitorMigrateCancel(qemuMonitorPtr mon) return ret; } +/** + * Returns 1 if @capability is supported, 0 if it's not, or -1 on error. + */ +int qemuMonitorGetDumpGuestMemoryCapability(qemuMonitorPtr mon, + const char *capability) +{ + VIR_DEBUG("mon=%p capability=%s", mon, capability); + + if (!mon) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("monitor must not be NULL")); + return -1; + } + + /* No capability is supported without JSON monitor */ + if (!mon->json) + return 0; + + return qemuMonitorJSONGetDumpGuestMemoryCapability(mon, capability); +} + int qemuMonitorDumpToFd(qemuMonitorPtr mon, int fd) { diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index d8f1d10c32..e896911107 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -506,6 +506,9 @@ int qemuMonitorMigrateToUnix(qemuMonitorPtr mon, int qemuMonitorMigrateCancel(qemuMonitorPtr mon); +int qemuMonitorGetDumpGuestMemoryCapability(qemuMonitorPtr mon, + const char *capability); + int qemuMonitorDumpToFd(qemuMonitorPtr mon, int fd); diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index 7a6aac0afe..ab5890babf 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -2657,6 +2657,71 @@ int qemuMonitorJSONMigrateCancel(qemuMonitorPtr mon) return ret; } +int +qemuMonitorJSONGetDumpGuestMemoryCapability(qemuMonitorPtr mon, + const char *capability) +{ + int ret; + virJSONValuePtr cmd; + virJSONValuePtr reply = NULL; + virJSONValuePtr caps; + virJSONValuePtr formats; + size_t i; + + if (!(cmd = qemuMonitorJSONMakeCommand("query-dump-guest-memory-capability", + NULL))) + return -1; + + ret = qemuMonitorJSONCommand(mon, cmd, &reply); + + if (ret == 0) { + if (qemuMonitorJSONHasError(reply, "CommandNotFound")) + goto cleanup; + ret = qemuMonitorJSONCheckError(cmd, reply); + } + + if (ret < 0) + goto cleanup; + + ret = -1; + + caps = virJSONValueObjectGet(reply, "return"); + if (!caps || caps->type != VIR_JSON_TYPE_OBJECT) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("missing dump guest memory capabilities")); + goto cleanup; + } + + formats = virJSONValueObjectGet(caps, "formats"); + if (!formats || formats->type != VIR_JSON_TYPE_ARRAY) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("missing supported dump formats")); + goto cleanup; + } + + for (i = 0; i < virJSONValueArraySize(formats); i++) { + virJSONValuePtr dumpformat = virJSONValueArrayGet(formats, i); + + if (!dumpformat || dumpformat->type != VIR_JSON_TYPE_STRING) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("missing entry in supported dump formats")); + goto cleanup; + } + + if (STREQ(virJSONValueGetString(dumpformat), capability)) { + ret = 1; + goto cleanup; + } + + ret = 0; + } + +cleanup: + virJSONValueFree(cmd); + virJSONValueFree(reply); + return ret; +} + int qemuMonitorJSONDump(qemuMonitorPtr mon, const char *protocol) diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index ef71588269..631b9e4ec6 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -147,6 +147,9 @@ int qemuMonitorJSONGetSpiceMigrationStatus(qemuMonitorPtr mon, int qemuMonitorJSONMigrateCancel(qemuMonitorPtr mon); +int qemuMonitorJSONGetDumpGuestMemoryCapability(qemuMonitorPtr mon, + const char *capability); + int qemuMonitorJSONDump(qemuMonitorPtr mon, const char *protocol); diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c index d7da5a8390..d21e1ce9e9 100644 --- a/tests/qemumonitorjsontest.c +++ b/tests/qemumonitorjsontest.c @@ -1959,6 +1959,48 @@ cleanup: return ret; } +static int +testQemuMonitorJSONqemuMonitorJSONGetDumpGuestMemoryCapability(const void *data) +{ + virDomainXMLOptionPtr xmlopt = (virDomainXMLOptionPtr)data; + qemuMonitorTestPtr test = qemuMonitorTestNewSimple(true, xmlopt); + int ret = -1; + int cap; + const char *reply = + "{" + " \"return\": {" + " \"formats\": [" + " \"elf\"," + " \"kdump-zlib\"," + " \"kdump-lzo\"," + " \"kdump-snappy\"" + " ]" + " }," + " \"id\": \"libvirt-9\"" + "}"; + + if (!test) + return -1; + + if (qemuMonitorTestAddItem(test, "query-dump-guest-memory-capability", + reply) < 0) + goto cleanup; + + cap = qemuMonitorJSONGetDumpGuestMemoryCapability( + qemuMonitorTestGetMonitor(test), "elf"); + + if (cap != 1) { + virReportError(VIR_ERR_INTERNAL_ERROR, + "Unexpected capability: %d, expecting 1", + cap); + goto cleanup; + } + + ret = 0; +cleanup: + qemuMonitorTestFree(test); + return ret; +} struct testCPUData { const char *name; @@ -2187,6 +2229,7 @@ mymain(void) DO_TEST(qemuMonitorJSONGetCPUInfo); DO_TEST(qemuMonitorJSONGetVirtType); DO_TEST(qemuMonitorJSONSendKey); + DO_TEST(qemuMonitorJSONGetDumpGuestMemoryCapability); DO_TEST_CPU_DATA("host"); DO_TEST_CPU_DATA("full");