[libvirt] [PATCH v7 0/4] support dumping guest memory in compressed format

dumping guest's memory is introduced without compression supported, but now qemu can dump guest's memory in kdump-compressed format. This patchset is used to add support in libvirt side to let qemu do the dump in compressed format and please refer the following address to see implementation of the qemu side, the lastest version of qemu side is v9. http://lists.nongnu.org/archive/html/qemu-devel/2014-02/msg03016.html ChangLog: Changes from v6 to v7: 1. revert changing dumpformat of virDomainCoreDumpWithFormat back to an enum Changes from v5 to v6: 1. add qemuMonitorGetDumpGuestMemoryCapability API to check the available dump format Changes from v4 to v5: 1. modify some restriction check Changes from v3 to v4: 1. dropping patch "add dump_memory_format in qemu.conf" 2. fix to follow some conventions Changes from v2 to v3: 1. address Jiri Denemark's comment about adding a new public API instead of changing an old one. Changes from v1 to v2: 1. address Daniel P. Berrange's comment about using a new parameter to replace flags like VIR_DUMP_COMPRESS_ZLIB. qiaonuohan (4): add new virDomainCoreDumpWithFormat API qemu: add qemuMonitorGetDumpGuestMemoryCapability qemu: add support for virDomainCoreDumpWithFormat API allow "virsh dump --memory-only" specify dump format include/libvirt/libvirt.h.in | 31 ++++++++++++++ src/driver.h | 7 ++++ src/libvirt.c | 98 ++++++++++++++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 5 +++ src/qemu/qemu_driver.c | 70 ++++++++++++++++++++++++++----- src/qemu/qemu_monitor.c | 27 ++++++++++-- src/qemu/qemu_monitor.h | 6 ++- src/qemu/qemu_monitor_json.c | 69 ++++++++++++++++++++++++++++++- src/qemu/qemu_monitor_json.h | 6 ++- src/remote/remote_driver.c | 1 + src/remote/remote_protocol.x | 15 ++++++- src/remote_protocol-structs | 7 ++++ src/test/test_driver.c | 22 ++++++++-- tests/qemumonitorjsontest.c | 2 +- tools/virsh-domain.c | 45 ++++++++++++++++++-- tools/virsh.pod | 5 +++ 16 files changed, 391 insertions(+), 25 deletions(-) -- 1.8.5.3

--memory-only option is introduced without compression supported. Now qemu has support dumping domain's memory in kdump-compressed format. This patch is adding new virDomainCoreDumpWithFormat API, so that the format in which qemu dumps domain's memory can be specified. Signed-off-by: Qiao Nuohan <qiaonuohan@cn.fujitsu.com> --- include/libvirt/libvirt.h.in | 31 ++++++++++++++ src/driver.h | 7 ++++ src/libvirt.c | 98 ++++++++++++++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 5 +++ src/remote/remote_driver.c | 1 + src/remote/remote_protocol.x | 15 ++++++- src/remote_protocol-structs | 7 ++++ src/test/test_driver.c | 22 ++++++++-- 8 files changed, 182 insertions(+), 4 deletions(-) diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index 295d551..41cd28c 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -1180,6 +1180,29 @@ typedef enum { VIR_DUMP_MEMORY_ONLY = (1 << 4), /* use dump-guest-memory */ } virDomainCoreDumpFlags; +/** + * virDomainCoreDumpFormat: + * + * Values for specifying different formats of domain core dumps. + */ +typedef enum { + VIR_DOMAIN_CORE_DUMP_FORMAT_RAW, /* dump guest memory in raw format */ + VIR_DOMAIN_CORE_DUMP_FORMAT_KDUMP_ZLIB, /* kdump-compressed format, with + * zlib compression */ + VIR_DOMAIN_CORE_DUMP_FORMAT_KDUMP_LZO, /* kdump-compressed format, with + * lzo compression */ + VIR_DOMAIN_CORE_DUMP_FORMAT_KDUMP_SNAPPY, /* kdump-compressed format, with + * snappy compression */ +#ifdef VIR_ENUM_SENTINELS + VIR_DOMAIN_CORE_DUMP_FORMAT_LAST + /* + * NB: this enum value will increase over time as new events are + * added to the libvirt API. It reflects the last state supported + * by this version of the libvirt API. + */ +#endif +} virDomainCoreDumpFormat; + /* Domain migration flags. */ typedef enum { VIR_MIGRATE_LIVE = (1 << 0), /* live migration */ @@ -1731,6 +1754,14 @@ int virDomainCoreDump (virDomainPtr domain, unsigned int flags); /* + * Domain core dump with format specified + */ +int virDomainCoreDumpWithFormat (virDomainPtr domain, + const char *to, + unsigned int dumpformat, + unsigned int flags); + +/* * Screenshot of current domain console */ char * virDomainScreenshot (virDomainPtr domain, diff --git a/src/driver.h b/src/driver.h index fbfaac4..d613f64 100644 --- a/src/driver.h +++ b/src/driver.h @@ -306,6 +306,12 @@ typedef int const char *to, unsigned int flags); +typedef int +(*virDrvDomainCoreDumpWithFormat)(virDomainPtr domain, + const char *to, + unsigned int dumpformat, + unsigned int flags); + typedef char * (*virDrvDomainScreenshot)(virDomainPtr domain, virStreamPtr stream, @@ -1200,6 +1206,7 @@ struct _virDriver { virDrvDomainSaveImageGetXMLDesc domainSaveImageGetXMLDesc; virDrvDomainSaveImageDefineXML domainSaveImageDefineXML; virDrvDomainCoreDump domainCoreDump; + virDrvDomainCoreDumpWithFormat domainCoreDumpWithFormat; virDrvDomainScreenshot domainScreenshot; virDrvDomainSetVcpus domainSetVcpus; virDrvDomainSetVcpusFlags domainSetVcpusFlags; diff --git a/src/libvirt.c b/src/libvirt.c index a385935..6cfa2ce 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -2997,6 +2997,104 @@ error: return -1; } +/** + * virDomainCoreDumpWithFormat: + * @domain: a domain object + * @to: path for the core file + * @dumpformat: format of domain memory's dump + * @flags: bitwise-OR of virDomainCoreDumpFlags + * + * This method will dump the core of a domain on a given file for analysis. + * Note that for remote Xen Daemon the file path will be interpreted in + * the remote host. Hypervisors may require the user to manually ensure + * proper permissions on the file named by @to. + * + * If @flags includes VIR_DUMP_MEMORY_ONLY and dumpformat is set, libvirt + * will ask qemu dump domain's memory in kdump-compressed format. + * + * If @flags includes VIR_DUMP_CRASH, then leave the guest shut off with + * a crashed state after the dump completes. If @flags includes + * VIR_DUMP_LIVE, then make the core dump while continuing to allow + * the guest to run; otherwise, the guest is suspended during the dump. + * VIR_DUMP_RESET flag forces reset of the quest after dump. + * The above three flags are mutually exclusive. + * + * Additionally, if @flags includes VIR_DUMP_BYPASS_CACHE, then libvirt + * will attempt to bypass the file system cache while creating the file, + * or fail if it cannot do so for the given system; this can allow less + * pressure on file system cache, but also risks slowing saves to NFS. + * + * Returns 0 in case of success and -1 in case of failure. + */ +int +virDomainCoreDumpWithFormat(virDomainPtr domain, const char *to, unsigned int + dumpformat, unsigned int flags) +{ + virConnectPtr conn; + + VIR_DOMAIN_DEBUG(domain, "to=%s, dumpformat=%u, flags=%x", + to, dumpformat, flags); + + virResetLastError(); + + virCheckDomainReturn(domain, -1); + conn = domain->conn; + + virCheckReadOnlyGoto(conn->flags, error); + virCheckNonNullArgGoto(to, error); + + if (dumpformat >= VIR_DOMAIN_CORE_DUMP_FORMAT_LAST) { + virReportInvalidArg(flags, _("dumpformat '%d' is not supported"), + dumpformat); + goto error; + } + + if ((flags & VIR_DUMP_CRASH) && (flags & VIR_DUMP_LIVE)) { + virReportInvalidArg(flags, "%s", + _("crash and live flags are mutually exclusive")); + goto error; + } + + if ((flags & VIR_DUMP_CRASH) && (flags & VIR_DUMP_RESET)) { + virReportInvalidArg(flags, "%s", + _("crash and reset flags are mutually exclusive")); + goto error; + } + + if ((flags & VIR_DUMP_LIVE) && (flags & VIR_DUMP_RESET)) { + virReportInvalidArg(flags, "%s", + _("live and reset flags are mutually exclusive")); + goto error; + } + + if (conn->driver->domainCoreDumpWithFormat) { + int ret; + char *absolute_to; + + /* We must absolutize the file path as the save is done out of process */ + if (virFileAbsPath(to, &absolute_to) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("could not build absolute core file path")); + goto error; + } + + ret = conn->driver->domainCoreDumpWithFormat(domain, absolute_to, + dumpformat, flags); + + VIR_FREE(absolute_to); + + if (ret < 0) + goto error; + return ret; + } + + virReportUnsupportedError(); + +error: + virDispatchError(domain->conn); + return -1; +} + /** * virDomainScreenshot: diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms index 6ed6ce6..9ab0c92 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -645,5 +645,10 @@ LIBVIRT_1.2.1 { virConnectNetworkEventDeregisterAny; } LIBVIRT_1.1.3; +LIBVIRT_1.2.3 { + global: + virDomainCoreDumpWithFormat; +} LIBVIRT_1.2.1; + # .... define new API here using predicted next version number .... diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 955465a..0a15267 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -7516,6 +7516,7 @@ static virDriver remote_driver = { .domainSaveImageGetXMLDesc = remoteDomainSaveImageGetXMLDesc, /* 0.9.4 */ .domainSaveImageDefineXML = remoteDomainSaveImageDefineXML, /* 0.9.4 */ .domainCoreDump = remoteDomainCoreDump, /* 0.3.0 */ + .domainCoreDumpWithFormat = remoteDomainCoreDumpWithFormat, /* 1.2.3 */ .domainScreenshot = remoteDomainScreenshot, /* 0.9.2 */ .domainSetVcpus = remoteDomainSetVcpus, /* 0.3.0 */ .domainSetVcpusFlags = remoteDomainSetVcpusFlags, /* 0.8.5 */ diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index f1f2359..6c445cc 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -904,6 +904,13 @@ struct remote_domain_core_dump_args { unsigned int flags; }; +struct remote_domain_core_dump_with_format_args { + remote_nonnull_domain dom; + remote_nonnull_string to; + unsigned int dumpformat; + unsigned int flags; +}; + struct remote_domain_screenshot_args { remote_nonnull_domain dom; unsigned int screen; @@ -5262,5 +5269,11 @@ enum remote_procedure { * @generate: both * @acl: none */ - REMOTE_PROC_DOMAIN_EVENT_CALLBACK_DEVICE_REMOVED = 333 + REMOTE_PROC_DOMAIN_EVENT_CALLBACK_DEVICE_REMOVED = 333, + + /** + * @generate: both + * @acl: domain:core_dump + */ + REMOTE_PROC_DOMAIN_CORE_DUMP_WITH_FORMAT = 334 }; diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs index 5636d55..456d0da 100644 --- a/src/remote_protocol-structs +++ b/src/remote_protocol-structs @@ -557,6 +557,12 @@ struct remote_domain_core_dump_args { remote_nonnull_string to; u_int flags; }; +struct remote_domain_core_dump_with_format_args { + remote_nonnull_domain dom; + remote_nonnull_string to; + u_int dumpformat; + u_int flags; +}; struct remote_domain_screenshot_args { remote_nonnull_domain dom; u_int screen; @@ -2755,4 +2761,5 @@ enum remote_procedure { REMOTE_PROC_DOMAIN_EVENT_CALLBACK_BALLOON_CHANGE = 331, REMOTE_PROC_DOMAIN_EVENT_CALLBACK_PMSUSPEND_DISK = 332, REMOTE_PROC_DOMAIN_EVENT_CALLBACK_DEVICE_REMOVED = 333, + REMOTE_PROC_DOMAIN_CORE_DUMP_WITH_FORMAT = 334, }; diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 6806ffd..96ec538 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -2427,9 +2427,10 @@ testDomainRestore(virConnectPtr conn, return testDomainRestoreFlags(conn, path, NULL, 0); } -static int testDomainCoreDump(virDomainPtr domain, - const char *to, - unsigned int flags) +static int testDomainCoreDumpWithFormat(virDomainPtr domain, + const char *to, + unsigned int dumpformat, + unsigned int flags) { testConnPtr privconn = domain->conn->privateData; int fd = -1; @@ -2467,6 +2468,13 @@ static int testDomainCoreDump(virDomainPtr domain, goto cleanup; } + /* we don't support non-raw formats in test driver */ + if (dumpformat != VIR_DOMAIN_CORE_DUMP_FORMAT_RAW) { + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", + _("kdump-compressed format is not supported here")); + goto cleanup; + } + if (flags & VIR_DUMP_CRASH) { testDomainShutdownState(domain, privdom, VIR_DOMAIN_SHUTOFF_CRASHED); event = virDomainEventLifecycleNewFromObj(privdom, @@ -2490,6 +2498,13 @@ cleanup: return ret; } +static int testDomainCoreDump(virDomainPtr domain, + const char *to, + unsigned int flags) { + return testDomainCoreDumpWithFormat(domain, to, + VIR_DOMAIN_CORE_DUMP_FORMAT_RAW, flags); +} + static char *testDomainGetOSType(virDomainPtr dom ATTRIBUTE_UNUSED) { char *ret; @@ -7359,6 +7374,7 @@ static virDriver testDriver = { .domainRestore = testDomainRestore, /* 0.3.2 */ .domainRestoreFlags = testDomainRestoreFlags, /* 0.9.4 */ .domainCoreDump = testDomainCoreDump, /* 0.3.2 */ + .domainCoreDumpWithFormat = testDomainCoreDumpWithFormat, /* 1.2.3 */ .domainSetVcpus = testDomainSetVcpus, /* 0.1.4 */ .domainSetVcpusFlags = testDomainSetVcpusFlags, /* 0.8.5 */ .domainGetVcpusFlags = testDomainGetVcpusFlags, /* 0.8.5 */ -- 1.8.5.3

On Tue, Mar 18, 2014 at 07:12:02AM +0000, qiaonuohan@cn.fujitsu.com wrote:
--memory-only option is introduced without compression supported. Now qemu has support dumping domain's memory in kdump-compressed format. This patch is adding new virDomainCoreDumpWithFormat API, so that the format in which qemu dumps domain's memory can be specified.
Signed-off-by: Qiao Nuohan <qiaonuohan@cn.fujitsu.com> --- include/libvirt/libvirt.h.in | 31 ++++++++++++++ src/driver.h | 7 ++++ src/libvirt.c | 98 ++++++++++++++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 5 +++ src/remote/remote_driver.c | 1 + src/remote/remote_protocol.x | 15 ++++++- src/remote_protocol-structs | 7 ++++ src/test/test_driver.c | 22 ++++++++-- 8 files changed, 182 insertions(+), 4 deletions(-)
ACK Regards, Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

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 <qiaonuohan@cn.fujitsu.com> --- 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 ++ 4 files changed, 92 insertions(+) diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index a2769db..8104104 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -2344,6 +2344,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 eabf000..00a6554 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -494,6 +494,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 ee3ae15..2cf706c 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -2635,6 +2635,71 @@ int qemuMonitorJSONMigrateCancel(qemuMonitorPtr mon) } 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 a93c51e..37e9456 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); -- 1.8.5.3

On Tue, Mar 18, 2014 at 07:12:02AM +0000, qiaonuohan@cn.fujitsu.com wrote:
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 <qiaonuohan@cn.fujitsu.com> --- 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 ++ 4 files changed, 92 insertions(+)
The code looks ok, but this could do with an addition to tests/qemumonitorjsontest.c Regards, Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

This patch makes qemu driver support virDomainCoreDumpWithFormat API. Signed-off-by: Qiao Nuohan <qiaonuohan@cn.fujitsu.com> --- src/qemu/qemu_driver.c | 70 +++++++++++++++++++++++++++++++++++++------- src/qemu/qemu_monitor.c | 6 ++-- src/qemu/qemu_monitor.h | 3 +- src/qemu/qemu_monitor_json.c | 4 ++- src/qemu/qemu_monitor_json.h | 3 +- tests/qemumonitorjsontest.c | 2 +- 6 files changed, 70 insertions(+), 18 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 9aad2dc..31a5f3f 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -2676,6 +2676,13 @@ VIR_ENUM_IMPL(qemuSaveCompression, QEMU_SAVE_FORMAT_LAST, "xz", "lzop") +VIR_ENUM_DECL(qemuDumpFormat) +VIR_ENUM_IMPL(qemuDumpFormat, VIR_DOMAIN_CORE_DUMP_FORMAT_LAST, + "elf", + "kdump-zlib", + "kdump-lzo", + "kdump-snappy") + typedef struct _virQEMUSaveHeader virQEMUSaveHeader; typedef virQEMUSaveHeader *virQEMUSaveHeaderPtr; struct _virQEMUSaveHeader { @@ -3389,7 +3396,8 @@ cleanup: } static int qemuDumpToFd(virQEMUDriverPtr driver, virDomainObjPtr vm, - int fd, enum qemuDomainAsyncJob asyncJob) + int fd, enum qemuDomainAsyncJob asyncJob, + const char *dumpformat) { qemuDomainObjPrivatePtr priv = vm->privateData; int ret = -1; @@ -3409,7 +3417,20 @@ static int qemuDumpToFd(virQEMUDriverPtr driver, virDomainObjPtr vm, if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) return -1; - ret = qemuMonitorDumpToFd(priv->mon, fd); + if (dumpformat) { + ret = qemuMonitorGetDumpGuestMemoryCapability(priv->mon, dumpformat); + + if (ret <= 0) { + virReportError(VIR_ERR_INVALID_ARG, + _("unsupported dumpformat '%s'"), dumpformat); + ret = -1; + goto cleanup; + } + } + + ret = qemuMonitorDumpToFd(priv->mon, fd, dumpformat); + +cleanup: qemuDomainObjExitMonitor(driver, vm); return ret; @@ -3420,13 +3441,15 @@ doCoreDump(virQEMUDriverPtr driver, virDomainObjPtr vm, const char *path, virQEMUSaveFormat compress, - unsigned int dump_flags) + unsigned int dump_flags, + unsigned int dumpformat) { int fd = -1; int ret = -1; virFileWrapperFdPtr wrapperFd = NULL; int directFlag = 0; unsigned int flags = VIR_FILE_WRAPPER_NON_BLOCKING; + const char *memory_dump_format = NULL; /* Create an empty file with appropriate ownership. */ if (dump_flags & VIR_DUMP_BYPASS_CACHE) { @@ -3450,8 +3473,20 @@ doCoreDump(virQEMUDriverPtr driver, goto cleanup; if (dump_flags & VIR_DUMP_MEMORY_ONLY) { - ret = qemuDumpToFd(driver, vm, fd, QEMU_ASYNC_JOB_DUMP); + if (!(memory_dump_format = qemuDumpFormatTypeToString(dumpformat))) { + virReportError(VIR_ERR_INVALID_ARG, + _("unknown dumpformat '%d'"), dumpformat); + goto cleanup; + } + ret = qemuDumpToFd(driver, vm, fd, QEMU_ASYNC_JOB_DUMP, + memory_dump_format); } else { + if (dumpformat != VIR_DOMAIN_CORE_DUMP_FORMAT_RAW) { + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", + _("kdump-compressed format is only supported with " + "memory-only dump")); + goto cleanup; + } ret = qemuMigrationToFile(driver, vm, fd, 0, path, qemuCompressProgramName(compress), false, QEMU_ASYNC_JOB_DUMP); @@ -3513,9 +3548,10 @@ cleanup: return ret; } -static int qemuDomainCoreDump(virDomainPtr dom, - const char *path, - unsigned int flags) +static int qemuDomainCoreDumpWithFormat(virDomainPtr dom, + const char *path, + unsigned int dumpformat, + unsigned int flags) { virQEMUDriverPtr driver = dom->conn->privateData; virDomainObjPtr vm; @@ -3531,7 +3567,7 @@ static int qemuDomainCoreDump(virDomainPtr dom, if (!(vm = qemuDomObjFromDomain(dom))) return -1; - if (virDomainCoreDumpEnsureACL(dom->conn, vm->def) < 0) + if (virDomainCoreDumpWithFormatEnsureACL(dom->conn, vm->def) < 0) goto cleanup; if (qemuDomainObjBeginAsyncJob(driver, vm, @@ -3563,7 +3599,8 @@ static int qemuDomainCoreDump(virDomainPtr dom, } } - ret = doCoreDump(driver, vm, path, getCompressionType(driver), flags); + ret = doCoreDump(driver, vm, path, getCompressionType(driver), flags, + dumpformat); if (ret < 0) goto endjob; @@ -3617,6 +3654,14 @@ cleanup: return ret; } +static int qemuDomainCoreDump(virDomainPtr dom, + const char *path, + unsigned int flags) +{ + return qemuDomainCoreDumpWithFormat(dom, path, + VIR_DOMAIN_CORE_DUMP_FORMAT_RAW, flags); +} + static char * qemuDomainScreenshot(virDomainPtr dom, virStreamPtr st, @@ -3740,7 +3785,8 @@ static void processWatchdogEvent(virQEMUDriverPtr driver, virDomainObjPtr vm, in flags |= cfg->autoDumpBypassCache ? VIR_DUMP_BYPASS_CACHE: 0; ret = doCoreDump(driver, vm, dumpfile, - getCompressionType(driver), flags); + getCompressionType(driver), flags, + VIR_DOMAIN_CORE_DUMP_FORMAT_RAW); if (ret < 0) virReportError(VIR_ERR_OPERATION_FAILED, "%s", _("Dump failed")); @@ -3804,7 +3850,8 @@ doCoreDumpToAutoDumpPath(virQEMUDriverPtr driver, flags |= cfg->autoDumpBypassCache ? VIR_DUMP_BYPASS_CACHE: 0; ret = doCoreDump(driver, vm, dumpfile, - getCompressionType(driver), flags); + getCompressionType(driver), flags, + VIR_DOMAIN_CORE_DUMP_FORMAT_RAW); if (ret < 0) virReportError(VIR_ERR_OPERATION_FAILED, "%s", _("Dump failed")); @@ -16625,6 +16672,7 @@ static virDriver qemuDriver = { .domainSaveImageGetXMLDesc = qemuDomainSaveImageGetXMLDesc, /* 0.9.4 */ .domainSaveImageDefineXML = qemuDomainSaveImageDefineXML, /* 0.9.4 */ .domainCoreDump = qemuDomainCoreDump, /* 0.7.0 */ + .domainCoreDumpWithFormat = qemuDomainCoreDumpWithFormat, /* 1.2.3 */ .domainScreenshot = qemuDomainScreenshot, /* 0.9.2 */ .domainSetVcpus = qemuDomainSetVcpus, /* 0.4.4 */ .domainSetVcpusFlags = qemuDomainSetVcpusFlags, /* 0.8.5 */ diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 8104104..78b0634 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -2366,10 +2366,10 @@ int qemuMonitorGetDumpGuestMemoryCapability(qemuMonitorPtr mon, } int -qemuMonitorDumpToFd(qemuMonitorPtr mon, int fd) +qemuMonitorDumpToFd(qemuMonitorPtr mon, int fd, const char *dumpformat) { int ret; - VIR_DEBUG("mon=%p fd=%d", mon, fd); + VIR_DEBUG("mon=%p fd=%d dumpformat=%s", mon, fd, dumpformat); if (!mon) { virReportError(VIR_ERR_INVALID_ARG, "%s", @@ -2389,7 +2389,7 @@ qemuMonitorDumpToFd(qemuMonitorPtr mon, int fd) if (qemuMonitorSendFileHandle(mon, "dump", fd) < 0) return -1; - ret = qemuMonitorJSONDump(mon, "fd:dump"); + ret = qemuMonitorJSONDump(mon, "fd:dump", dumpformat); if (ret < 0) { if (qemuMonitorCloseFileHandle(mon, "dump") < 0) diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 00a6554..603a9f8 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -498,7 +498,8 @@ int qemuMonitorGetDumpGuestMemoryCapability(qemuMonitorPtr mon, const char *capability); int qemuMonitorDumpToFd(qemuMonitorPtr mon, - int fd); + int fd, + const char *dumpformat); int qemuMonitorGraphicsRelocate(qemuMonitorPtr mon, int type, diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index 2cf706c..e142cc9 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -2701,7 +2701,8 @@ cleanup: int qemuMonitorJSONDump(qemuMonitorPtr mon, - const char *protocol) + const char *protocol, + const char *dumpformat) { int ret; virJSONValuePtr cmd = NULL; @@ -2710,6 +2711,7 @@ qemuMonitorJSONDump(qemuMonitorPtr mon, cmd = qemuMonitorJSONMakeCommand("dump-guest-memory", "b:paging", false, "s:protocol", protocol, + "s:format", dumpformat, NULL); if (!cmd) return -1; diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index 37e9456..26a9f1e 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -151,7 +151,8 @@ int qemuMonitorJSONGetDumpGuestMemoryCapability(qemuMonitorPtr mon, const char *capability); int qemuMonitorJSONDump(qemuMonitorPtr mon, - const char *protocol); + const char *protocol, + const char *dumpformat); int qemuMonitorJSONGraphicsRelocate(qemuMonitorPtr mon, int type, diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c index d7da5a8..f21de84 100644 --- a/tests/qemumonitorjsontest.c +++ b/tests/qemumonitorjsontest.c @@ -1154,7 +1154,7 @@ GEN_TEST_FUNC(qemuMonitorJSONSetMigrationDowntime, 1) GEN_TEST_FUNC(qemuMonitorJSONMigrate, QEMU_MONITOR_MIGRATE_BACKGROUND | QEMU_MONITOR_MIGRATE_NON_SHARED_DISK | QEMU_MONITOR_MIGRATE_NON_SHARED_INC, "tcp:localhost:12345") -GEN_TEST_FUNC(qemuMonitorJSONDump, "dummy_protocol") +GEN_TEST_FUNC(qemuMonitorJSONDump, "dummy_protocol", "dummy_memory_dump_format") GEN_TEST_FUNC(qemuMonitorJSONGraphicsRelocate, VIR_DOMAIN_GRAPHICS_TYPE_SPICE, "localhost", 12345, 12346, NULL) GEN_TEST_FUNC(qemuMonitorJSONAddNetdev, "some_dummy_netdevstr") -- 1.8.5.3

On Tue, Mar 18, 2014 at 07:12:03AM +0000, qiaonuohan@cn.fujitsu.com wrote:
static int qemuDumpToFd(virQEMUDriverPtr driver, virDomainObjPtr vm, - int fd, enum qemuDomainAsyncJob asyncJob) + int fd, enum qemuDomainAsyncJob asyncJob, + const char *dumpformat) { qemuDomainObjPrivatePtr priv = vm->privateData; int ret = -1; @@ -3409,7 +3417,20 @@ static int qemuDumpToFd(virQEMUDriverPtr driver, virDomainObjPtr vm, if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) return -1;
- ret = qemuMonitorDumpToFd(priv->mon, fd); + if (dumpformat) { + ret = qemuMonitorGetDumpGuestMemoryCapability(priv->mon, dumpformat);
What happens when we query support for VIR_DOMAIN_CORE_DUMP_FORMAT_RAW but run on older QEMU which lacks this capability reporting. It looks like this code will raise an error, but it should simply call the old monitor code for this.
+ + if (ret <= 0) { + virReportError(VIR_ERR_INVALID_ARG, + _("unsupported dumpformat '%s'"), dumpformat); + ret = -1; + goto cleanup; + } + } + + ret = qemuMonitorDumpToFd(priv->mon, fd, dumpformat); + +cleanup: qemuDomainObjExitMonitor(driver, vm);
return ret; @@ -3420,13 +3441,15 @@ doCoreDump(virQEMUDriverPtr driver, virDomainObjPtr vm, const char *path, virQEMUSaveFormat compress, - unsigned int dump_flags) + unsigned int dump_flags, + unsigned int dumpformat) { int fd = -1; int ret = -1; virFileWrapperFdPtr wrapperFd = NULL; int directFlag = 0; unsigned int flags = VIR_FILE_WRAPPER_NON_BLOCKING; + const char *memory_dump_format = NULL;
/* Create an empty file with appropriate ownership. */ if (dump_flags & VIR_DUMP_BYPASS_CACHE) { @@ -3450,8 +3473,20 @@ doCoreDump(virQEMUDriverPtr driver, goto cleanup;
if (dump_flags & VIR_DUMP_MEMORY_ONLY) { - ret = qemuDumpToFd(driver, vm, fd, QEMU_ASYNC_JOB_DUMP); + if (!(memory_dump_format = qemuDumpFormatTypeToString(dumpformat))) { + virReportError(VIR_ERR_INVALID_ARG, + _("unknown dumpformat '%d'"), dumpformat); + goto cleanup; + } + ret = qemuDumpToFd(driver, vm, fd, QEMU_ASYNC_JOB_DUMP, + memory_dump_format); } else { + if (dumpformat != VIR_DOMAIN_CORE_DUMP_FORMAT_RAW) { + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", + _("kdump-compressed format is only supported with " + "memory-only dump")); + goto cleanup; + } ret = qemuMigrationToFile(driver, vm, fd, 0, path, qemuCompressProgramName(compress), false, QEMU_ASYNC_JOB_DUMP);
Regards, Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

This patch adds "[--compression-format] <string>" to "virsh dump --memory-only", which is changed to use the new virDomainCoreDumpWithFormat API. And "--compress" is added as an alias for "--compression-format zlib". Signed-off-by: Qiao Nuohan <qiaonuohan@cn.fujitsu.com> --- tools/virsh-domain.c | 45 ++++++++++++++++++++++++++++++++++++++++++--- tools/virsh.pod | 5 +++++ 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index 1d3c5f0..f7e2226 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -4486,6 +4486,14 @@ static const vshCmdOptDef opts_dump[] = { .type = VSH_OT_BOOL, .help = N_("dump domain's memory only") }, + {.name = "compress", + .type = VSH_OT_ALIAS, + .help = "compression-format=zlib", + }, + {.name = "compression-format", + .type = VSH_OT_DATA, + .help = N_("specify the compression format of kdump-compressed format") + }, {.name = NULL} }; @@ -4501,6 +4509,8 @@ doDump(void *opaque) const char *name = NULL; const char *to = NULL; unsigned int flags = 0; + const char *compression_format = NULL; + unsigned int dumpformat = VIR_DOMAIN_CORE_DUMP_FORMAT_RAW; sigemptyset(&sigmask); sigaddset(&sigmask, SIGINT); @@ -4524,9 +4534,38 @@ doDump(void *opaque) if (vshCommandOptBool(cmd, "memory-only")) flags |= VIR_DUMP_MEMORY_ONLY; - if (virDomainCoreDump(dom, to, flags) < 0) { - vshError(ctl, _("Failed to core dump domain %s to %s"), name, to); - goto out; + if (vshCommandOptBool(cmd, "compression-format")) { + if (!(flags & VIR_DUMP_MEMORY_ONLY)) { + vshError(ctl, "%s", + _("--compression-format only work with --memory-only")); + goto out; + } + + if (vshCommandOptString(cmd, "compression-format", + &compression_format)) { + if (STREQ(compression_format, "zlib")) + dumpformat = VIR_DOMAIN_CORE_DUMP_FORMAT_KDUMP_ZLIB; + else if (STREQ(compression_format, "lzo")) + dumpformat = VIR_DOMAIN_CORE_DUMP_FORMAT_KDUMP_LZO; + else if (STREQ(compression_format, "snappy")) + dumpformat = VIR_DOMAIN_CORE_DUMP_FORMAT_KDUMP_SNAPPY; + else { + vshError(ctl, _("compression format '%s' is not supported, " + "expecting 'zlib', 'lzo' or 'snappy'."), + compression_format); + goto out; + } + } + + if (virDomainCoreDumpWithFormat(dom, to, dumpformat, flags) < 0) { + vshError(ctl, _("Failed to core dump domain %s to %s"), name, to); + goto out; + } + } else { + if (virDomainCoreDump(dom, to, flags) < 0) { + vshError(ctl, _("Failed to core dump domain %s to %s"), name, to); + goto out; + } } ret = '0'; diff --git a/tools/virsh.pod b/tools/virsh.pod index cafbb9a..e1d3dc2 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -995,6 +995,7 @@ I<format> argument may be B<xen-xm> or B<xen-sxpr>. =item B<dump> I<domain> I<corefilepath> [I<--bypass-cache>] { [I<--live>] | [I<--crash>] | [I<--reset>] } [I<--verbose>] [I<--memory-only>] +[I<--compression-format> I<string>] Dumps the core of a domain to a file for analysis. If I<--live> is specified, the domain continues to run until the core @@ -1008,6 +1009,10 @@ cache, although this may slow down the operation. If I<--memory-only> is specified, the file is elf file, and will only include domain's memory and cpu common register value. It is very useful if the domain uses host devices directly. +I<--compression-format> I<string> can be used to specify that the +output file should be in kdump-compressed format using the specified +compression: zlib, lzo, snappy. +I<--compress> is an alias for I<--compression-format> I<zlib>. The progress may be monitored using B<domjobinfo> virsh command and canceled with B<domjobabort> command (sent by another virsh instance). Another option -- 1.8.5.3

On Tue, Mar 18, 2014 at 07:12:03AM +0000, qiaonuohan@cn.fujitsu.com wrote:
This patch adds "[--compression-format] <string>" to "virsh dump --memory-only", which is changed to use the new virDomainCoreDumpWithFormat API. And "--compress" is added as an alias for "--compression-format zlib".
Signed-off-by: Qiao Nuohan <qiaonuohan@cn.fujitsu.com> --- tools/virsh-domain.c | 45 ++++++++++++++++++++++++++++++++++++++++++--- tools/virsh.pod | 5 +++++ 2 files changed, 47 insertions(+), 3 deletions(-)
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index 1d3c5f0..f7e2226 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -4486,6 +4486,14 @@ static const vshCmdOptDef opts_dump[] = { .type = VSH_OT_BOOL, .help = N_("dump domain's memory only") }, + {.name = "compress", + .type = VSH_OT_ALIAS, + .help = "compression-format=zlib", + },
This name is ok, but...
+ {.name = "compression-format", + .type = VSH_OT_DATA, + .help = N_("specify the compression format of kdump-compressed format") + },
...I actually think this second arg should just be called 'format' since not all formats imply compression. Regards, Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

On 03/20/2014 11:07 PM, Daniel P. Berrange wrote:
+ {.name = "compression-format", + .type = VSH_OT_DATA, + .help = N_("specify the compression format of kdump-compressed format") + }, ...I actually think this second arg should just be called 'format' since not all formats imply compression.
Ok, I will change it to "--format elf/kdump-zlib/...". Please correct me if it is not acceptable. -- Regards Qiao Nuohan

On Tue, Mar 18, 2014 at 07:12:03AM +0000, qiaonuohan@cn.fujitsu.com wrote:
This patch adds "[--compression-format] <string>" to "virsh dump --memory-only", which is changed to use the new virDomainCoreDumpWithFormat API. And "--compress" is added as an alias for "--compression-format zlib".
Signed-off-by: Qiao Nuohan <qiaonuohan@cn.fujitsu.com> --- tools/virsh-domain.c | 45 ++++++++++++++++++++++++++++++++++++++++++--- tools/virsh.pod | 5 +++++ 2 files changed, 47 insertions(+), 3 deletions(-)
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index 1d3c5f0..f7e2226 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -4486,6 +4486,14 @@ static const vshCmdOptDef opts_dump[] = { .type = VSH_OT_BOOL, .help = N_("dump domain's memory only") }, + {.name = "compress", + .type = VSH_OT_ALIAS, + .help = "compression-format=zlib", + }, + {.name = "compression-format", + .type = VSH_OT_DATA, + .help = N_("specify the compression format of kdump-compressed format") + }, {.name = NULL} };
@@ -4501,6 +4509,8 @@ doDump(void *opaque) const char *name = NULL; const char *to = NULL; unsigned int flags = 0; + const char *compression_format = NULL; + unsigned int dumpformat = VIR_DOMAIN_CORE_DUMP_FORMAT_RAW;
sigemptyset(&sigmask); sigaddset(&sigmask, SIGINT); @@ -4524,9 +4534,38 @@ doDump(void *opaque) if (vshCommandOptBool(cmd, "memory-only")) flags |= VIR_DUMP_MEMORY_ONLY;
- if (virDomainCoreDump(dom, to, flags) < 0) { - vshError(ctl, _("Failed to core dump domain %s to %s"), name, to); - goto out; + if (vshCommandOptBool(cmd, "compression-format")) { + if (!(flags & VIR_DUMP_MEMORY_ONLY)) { + vshError(ctl, "%s", + _("--compression-format only work with --memory-only")); + goto out; + } + + if (vshCommandOptString(cmd, "compression-format", + &compression_format)) { + if (STREQ(compression_format, "zlib")) + dumpformat = VIR_DOMAIN_CORE_DUMP_FORMAT_KDUMP_ZLIB; + else if (STREQ(compression_format, "lzo")) + dumpformat = VIR_DOMAIN_CORE_DUMP_FORMAT_KDUMP_LZO; + else if (STREQ(compression_format, "snappy")) + dumpformat = VIR_DOMAIN_CORE_DUMP_FORMAT_KDUMP_SNAPPY;
This is missing handling of FORMAT_RAW, and if that format is requested, we should call virDomainCoreDump instead. IOW, don't do if (vshCommandOptBool(cmd, "compression-format")) { ... } else { ... } Do ....get format... if (format != VIR_DOMAIN_CORE_DUMP_FORMAT_RAW) ...virDomainCoreDumpWithFormat } else { ...virDomainCoreDump }
+ else { + vshError(ctl, _("compression format '%s' is not supported, " + "expecting 'zlib', 'lzo' or 'snappy'."), + compression_format); + goto out; + } + } + + if (virDomainCoreDumpWithFormat(dom, to, dumpformat, flags) < 0) { + vshError(ctl, _("Failed to core dump domain %s to %s"), name, to); + goto out; + } + } else { + if (virDomainCoreDump(dom, to, flags) < 0) { + vshError(ctl, _("Failed to core dump domain %s to %s"), name, to); + goto out; + } }
Regards, Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

Hello, Do you have some comments? On 03/18/2014 03:12 PM, Qiao, Nuohan/乔 诺涵 wrote:
dumping guest's memory is introduced without compression supported, but now qemu can dump guest's memory in kdump-compressed format. This patchset is used to add support in libvirt side to let qemu do the dump in compressed format and please refer the following address to see implementation of the qemu side, the lastest version of qemu side is v9.
http://lists.nongnu.org/archive/html/qemu-devel/2014-02/msg03016.html
ChangLog: Changes from v6 to v7: 1. revert changing dumpformat of virDomainCoreDumpWithFormat back to an enum
Changes from v5 to v6: 1. add qemuMonitorGetDumpGuestMemoryCapability API to check the available dump format
Changes from v4 to v5: 1. modify some restriction check
Changes from v3 to v4: 1. dropping patch "add dump_memory_format in qemu.conf" 2. fix to follow some conventions
Changes from v2 to v3: 1. address Jiri Denemark's comment about adding a new public API instead of changing an old one.
Changes from v1 to v2: 1. address Daniel P. Berrange's comment about using a new parameter to replace flags like VIR_DUMP_COMPRESS_ZLIB.
qiaonuohan (4): add new virDomainCoreDumpWithFormat API qemu: add qemuMonitorGetDumpGuestMemoryCapability qemu: add support for virDomainCoreDumpWithFormat API allow "virsh dump --memory-only" specify dump format
include/libvirt/libvirt.h.in | 31 ++++++++++++++ src/driver.h | 7 ++++ src/libvirt.c | 98 ++++++++++++++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 5 +++ src/qemu/qemu_driver.c | 70 ++++++++++++++++++++++++++----- src/qemu/qemu_monitor.c | 27 ++++++++++-- src/qemu/qemu_monitor.h | 6 ++- src/qemu/qemu_monitor_json.c | 69 ++++++++++++++++++++++++++++++- src/qemu/qemu_monitor_json.h | 6 ++- src/remote/remote_driver.c | 1 + src/remote/remote_protocol.x | 15 ++++++- src/remote_protocol-structs | 7 ++++ src/test/test_driver.c | 22 ++++++++-- tests/qemumonitorjsontest.c | 2 +- tools/virsh-domain.c | 45 ++++++++++++++++++-- tools/virsh.pod | 5 +++ 16 files changed, 391 insertions(+), 25 deletions(-)
-- Regards Qiao Nuohan
participants (2)
-
Daniel P. Berrange
-
qiaonuohan@cn.fujitsu.com