From: Luiz Capitulino <lcapitulino@redhat.com>
To: peter.maydell@linaro.org
Cc: qemu-devel@nongnu.org, anthony@codemonkey.ws
Subject: [Qemu-devel] [PULL 16/22] dump: make kdump-compressed format available for 'dump-guest-memory'
Date: Thu, 13 Feb 2014 10:30:34 -0500 [thread overview]
Message-ID: <1392305440-30465-17-git-send-email-lcapitulino@redhat.com> (raw)
In-Reply-To: <1392305440-30465-1-git-send-email-lcapitulino@redhat.com>
From: qiaonuohan <qiaonuohan@cn.fujitsu.com>
Make monitor command 'dump-guest-memory' be able to dump in kdump-compressed
format. The command's usage:
dump [-p] protocol [begin] [length] [format]
'format' is used to specified the format of vmcore and can be:
1. 'elf': ELF format, without compression
2. 'kdump-zlib': kdump-compressed format, with zlib-compressed
3. 'kdump-lzo': kdump-compressed format, with lzo-compressed
4. 'kdump-snappy': kdump-compressed format, with snappy-compressed
Without 'format' being set, it is same as 'elf'. And if non-elf format is
specified, paging and filter is not allowed.
Note:
1. The kdump-compressed format is readable only with the crash utility and
makedumpfile, and it can be smaller than the ELF format because of the
compression support.
2. The kdump-compressed format is the 6th edition.
Signed-off-by: Qiao Nuohan <qiaonuohan@cn.fujitsu.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
dump.c | 131 ++++++++++++++++++++++++++++++++++++++++++++++++++++---
hmp.c | 5 ++-
qapi-schema.json | 25 ++++++++++-
qmp-commands.hx | 7 ++-
4 files changed, 158 insertions(+), 10 deletions(-)
diff --git a/dump.c b/dump.c
index 31be686..2ebbb23 100644
--- a/dump.c
+++ b/dump.c
@@ -1443,6 +1443,64 @@ out:
return ret;
}
+static int create_kdump_vmcore(DumpState *s)
+{
+ int ret;
+
+ /*
+ * the kdump-compressed format is:
+ * File offset
+ * +------------------------------------------+ 0x0
+ * | main header (struct disk_dump_header) |
+ * |------------------------------------------+ block 1
+ * | sub header (struct kdump_sub_header) |
+ * |------------------------------------------+ block 2
+ * | 1st-dump_bitmap |
+ * |------------------------------------------+ block 2 + X blocks
+ * | 2nd-dump_bitmap | (aligned by block)
+ * |------------------------------------------+ block 2 + 2 * X blocks
+ * | page desc for pfn 0 (struct page_desc) | (aligned by block)
+ * | page desc for pfn 1 (struct page_desc) |
+ * | : |
+ * |------------------------------------------| (not aligned by block)
+ * | page data (pfn 0) |
+ * | page data (pfn 1) |
+ * | : |
+ * +------------------------------------------+
+ */
+
+ ret = write_start_flat_header(s->fd);
+ if (ret < 0) {
+ dump_error(s, "dump: failed to write start flat header.\n");
+ return -1;
+ }
+
+ ret = write_dump_header(s);
+ if (ret < 0) {
+ return -1;
+ }
+
+ ret = write_dump_bitmap(s);
+ if (ret < 0) {
+ return -1;
+ }
+
+ ret = write_dump_pages(s);
+ if (ret < 0) {
+ return -1;
+ }
+
+ ret = write_end_flat_header(s->fd);
+ if (ret < 0) {
+ dump_error(s, "dump: failed to write end flat header.\n");
+ return -1;
+ }
+
+ dump_completed(s);
+
+ return 0;
+}
+
static ram_addr_t get_start_block(DumpState *s)
{
GuestPhysBlock *block;
@@ -1479,7 +1537,8 @@ static void get_max_mapnr(DumpState *s)
s->max_mapnr = paddr_to_pfn(last_block->target_end, s->page_shift);
}
-static int dump_init(DumpState *s, int fd, bool paging, bool has_filter,
+static int dump_init(DumpState *s, int fd, bool has_format,
+ DumpGuestMemoryFormat format, bool paging, bool has_filter,
int64_t begin, int64_t length, Error **errp)
{
CPUState *cpu;
@@ -1487,6 +1546,11 @@ static int dump_init(DumpState *s, int fd, bool paging, bool has_filter,
Error *err = NULL;
int ret;
+ /* kdump-compressed is conflict with paging and filter */
+ if (has_format && format != DUMP_GUEST_MEMORY_FORMAT_ELF) {
+ assert(!paging && !has_filter);
+ }
+
if (runstate_is_running()) {
vm_stop(RUN_STATE_SAVE_VM);
s->resume = true;
@@ -1557,6 +1621,28 @@ static int dump_init(DumpState *s, int fd, bool paging, bool has_filter,
tmp = DIV_ROUND_UP(DIV_ROUND_UP(s->max_mapnr, CHAR_BIT), s->page_size);
s->len_dump_bitmap = tmp * s->page_size;
+ /* init for kdump-compressed format */
+ if (has_format && format != DUMP_GUEST_MEMORY_FORMAT_ELF) {
+ switch (format) {
+ case DUMP_GUEST_MEMORY_FORMAT_KDUMP_ZLIB:
+ s->flag_compress = DUMP_DH_COMPRESSED_ZLIB;
+ break;
+
+ case DUMP_GUEST_MEMORY_FORMAT_KDUMP_LZO:
+ s->flag_compress = DUMP_DH_COMPRESSED_LZO;
+ break;
+
+ case DUMP_GUEST_MEMORY_FORMAT_KDUMP_SNAPPY:
+ s->flag_compress = DUMP_DH_COMPRESSED_SNAPPY;
+ break;
+
+ default:
+ s->flag_compress = 0;
+ }
+
+ return 0;
+ }
+
if (s->has_filter) {
memory_mapping_filter(&s->list, s->begin, s->length);
}
@@ -1616,14 +1702,25 @@ cleanup:
}
void qmp_dump_guest_memory(bool paging, const char *file, bool has_begin,
- int64_t begin, bool has_length, int64_t length,
- Error **errp)
+ int64_t begin, bool has_length,
+ int64_t length, bool has_format,
+ DumpGuestMemoryFormat format, Error **errp)
{
const char *p;
int fd = -1;
DumpState *s;
int ret;
+ /*
+ * kdump-compressed format need the whole memory dumped, so paging or
+ * filter is not supported here.
+ */
+ if ((has_format && format != DUMP_GUEST_MEMORY_FORMAT_ELF) &&
+ (paging || has_begin || has_length)) {
+ error_setg(errp, "kdump-compressed format doesn't support paging or "
+ "filter");
+ return;
+ }
if (has_begin && !has_length) {
error_set(errp, QERR_MISSING_PARAMETER, "length");
return;
@@ -1633,6 +1730,21 @@ void qmp_dump_guest_memory(bool paging, const char *file, bool has_begin,
return;
}
+ /* check whether lzo/snappy is supported */
+#ifndef CONFIG_LZO
+ if (has_format && format == DUMP_GUEST_MEMORY_FORMAT_KDUMP_LZO) {
+ error_setg(errp, "kdump-lzo is not available now");
+ return;
+ }
+#endif
+
+#ifndef CONFIG_SNAPPY
+ if (has_format && format == DUMP_GUEST_MEMORY_FORMAT_KDUMP_SNAPPY) {
+ error_setg(errp, "kdump-snappy is not available now");
+ return;
+ }
+#endif
+
#if !defined(WIN32)
if (strstart(file, "fd:", &p)) {
fd = monitor_get_fd(cur_mon, p, errp);
@@ -1657,14 +1769,21 @@ void qmp_dump_guest_memory(bool paging, const char *file, bool has_begin,
s = g_malloc0(sizeof(DumpState));
- ret = dump_init(s, fd, paging, has_begin, begin, length, errp);
+ ret = dump_init(s, fd, has_format, format, paging, has_begin,
+ begin, length, errp);
if (ret < 0) {
g_free(s);
return;
}
- if (create_vmcore(s) < 0 && !error_is_set(s->errp)) {
- error_set(errp, QERR_IO_ERROR);
+ if (has_format && format != DUMP_GUEST_MEMORY_FORMAT_ELF) {
+ if (create_kdump_vmcore(s) < 0 && !error_is_set(s->errp)) {
+ error_set(errp, QERR_IO_ERROR);
+ }
+ } else {
+ if (create_vmcore(s) < 0 && !error_is_set(s->errp)) {
+ error_set(errp, QERR_IO_ERROR);
+ }
}
g_free(s);
diff --git a/hmp.c b/hmp.c
index e3ddd46..2f279c4 100644
--- a/hmp.c
+++ b/hmp.c
@@ -1311,8 +1311,11 @@ void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict)
const char *file = qdict_get_str(qdict, "filename");
bool has_begin = qdict_haskey(qdict, "begin");
bool has_length = qdict_haskey(qdict, "length");
+ /* kdump-compressed format is not supported for HMP */
+ bool has_format = false;
int64_t begin = 0;
int64_t length = 0;
+ enum DumpGuestMemoryFormat dump_format = DUMP_GUEST_MEMORY_FORMAT_ELF;
char *prot;
if (has_begin) {
@@ -1325,7 +1328,7 @@ void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict)
prot = g_strconcat("file:", file, NULL);
qmp_dump_guest_memory(paging, prot, has_begin, begin, has_length, length,
- &errp);
+ has_format, dump_format, &errp);
hmp_handle_error(mon, &errp);
g_free(prot);
}
diff --git a/qapi-schema.json b/qapi-schema.json
index 9bca13a..6ff6d49 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -2738,6 +2738,24 @@
{ 'command': 'device_del', 'data': {'id': 'str'} }
##
+# @DumpGuestMemoryFormat:
+#
+# An enumeration of guest-memory-dump's format.
+#
+# @elf: elf format
+#
+# @kdump-zlib: kdump-compressed format with zlib-compressed
+#
+# @kdump-lzo: kdump-compressed format with lzo-compressed
+#
+# @kdump-snappy: kdump-compressed format with snappy-compressed
+#
+# Since: 2.0
+##
+{ 'enum': 'DumpGuestMemoryFormat',
+ 'data': [ 'elf', 'kdump-zlib', 'kdump-lzo', 'kdump-snappy' ] }
+
+##
# @dump-guest-memory
#
# Dump guest's memory to vmcore. It is a synchronous operation that can take
@@ -2773,13 +2791,18 @@
# want to dump all guest's memory, please specify the start @begin
# and @length
#
+# @format: #optional if specified, the format of guest memory dump. But non-elf
+# format is conflict with paging and filter, ie. @paging, @begin and
+# @length is not allowed to be specified with non-elf @format at the
+# same time (since 2.0)
+#
# Returns: nothing on success
#
# Since: 1.2
##
{ 'command': 'dump-guest-memory',
'data': { 'paging': 'bool', 'protocol': 'str', '*begin': 'int',
- '*length': 'int' } }
+ '*length': 'int', '*format': 'DumpGuestMemoryFormat' } }
##
# @netdev_add:
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 8a0e832..8da11ac 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -791,8 +791,8 @@ EQMP
{
.name = "dump-guest-memory",
- .args_type = "paging:b,protocol:s,begin:i?,end:i?",
- .params = "-p protocol [begin] [length]",
+ .args_type = "paging:b,protocol:s,begin:i?,end:i?,format:s?",
+ .params = "-p protocol [begin] [length] [format]",
.help = "dump guest memory to file",
.user_print = monitor_user_noop,
.mhandler.cmd_new = qmp_marshal_input_dump_guest_memory,
@@ -813,6 +813,9 @@ Arguments:
with length together (json-int)
- "length": the memory size, in bytes. It's optional, and should be specified
with begin together (json-int)
+- "format": the format of guest memory dump. It's optional, and can be
+ elf|kdump-zlib|kdump-lzo|kdump-snappy, but non-elf formats will
+ conflict with paging and filter, ie. begin and length (json-string)
Example:
--
1.8.1.4
next prev parent reply other threads:[~2014-02-13 15:31 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-02-13 15:30 [Qemu-devel] [PULL 00/22] QMP queue Luiz Capitulino
2014-02-13 15:30 ` [Qemu-devel] [PULL 01/22] hmp: migrate command (without -d) now blocks correctly Luiz Capitulino
2014-02-13 15:30 ` [Qemu-devel] [PULL 02/22] QMP: allow JSON dict arguments in qmp-shell Luiz Capitulino
2014-02-13 15:30 ` [Qemu-devel] [PULL 03/22] Use error_is_set() only when necessary Luiz Capitulino
2014-02-13 15:30 ` [Qemu-devel] [PULL 04/22] qmp: expose list of supported character device backends Luiz Capitulino
2014-02-13 15:30 ` [Qemu-devel] [PULL 05/22] dump: const-qualify the buf of WriteCoreDumpFunction Luiz Capitulino
2014-02-13 15:30 ` [Qemu-devel] [PULL 06/22] dump: add argument to write_elfxx_notes Luiz Capitulino
2014-02-13 15:30 ` [Qemu-devel] [PULL 07/22] dump: add API to write header of flatten format Luiz Capitulino
2014-02-13 15:30 ` [Qemu-devel] [PULL 08/22] dump: add API to write vmcore Luiz Capitulino
2014-02-13 15:30 ` [Qemu-devel] [PULL 09/22] dump: add API to write elf notes to buffer Luiz Capitulino
2014-02-13 15:30 ` [Qemu-devel] [PULL 10/22] dump: add support for lzo/snappy Luiz Capitulino
2014-02-13 15:30 ` [Qemu-devel] [PULL 11/22] dump: add members to DumpState and init some of them Luiz Capitulino
2014-02-13 15:30 ` [Qemu-devel] [PULL 12/22] dump: add API to write dump header Luiz Capitulino
2014-02-13 15:30 ` [Qemu-devel] [PULL 13/22] dump: add API to write dump_bitmap Luiz Capitulino
2014-02-13 15:30 ` [Qemu-devel] [PULL 14/22] dump: add APIs to operate DataCache Luiz Capitulino
2014-02-13 15:30 ` [Qemu-devel] [PULL 15/22] dump: add API to write dump pages Luiz Capitulino
2014-02-13 15:30 ` Luiz Capitulino [this message]
2014-02-13 15:30 ` [Qemu-devel] [PULL 17/22] dump: Define the architecture for compressed dump format Luiz Capitulino
2014-02-13 15:30 ` [Qemu-devel] [PULL 18/22] dump: add 'query-dump-guest-memory-capability' command Luiz Capitulino
2014-02-13 15:30 ` [Qemu-devel] [PULL 19/22] monitor: Add device_del id argument completion Luiz Capitulino
2014-02-13 15:30 ` [Qemu-devel] [PULL 20/22] monitor: Add device_add device " Luiz Capitulino
2014-02-13 15:30 ` [Qemu-devel] [PULL 21/22] monitor: Add object_del id " Luiz Capitulino
2014-02-13 15:30 ` [Qemu-devel] [PULL 22/22] monitor: Add object_add class " Luiz Capitulino
2014-02-15 15:36 ` [Qemu-devel] [PULL 00/22] QMP queue Peter Maydell
2014-02-17 17:46 ` Luiz Capitulino
2014-02-20 13:07 ` Peter Maydell
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1392305440-30465-17-git-send-email-lcapitulino@redhat.com \
--to=lcapitulino@redhat.com \
--cc=anthony@codemonkey.ws \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).