qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Ekaterina Tumanova <tumanova@linux.vnet.ibm.com>
To: qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH 12/13 v7] dump: make kdump-compressed format available for 'dump-guest-memory'
Date: Thu, 23 Jan 2014 19:17:22 +0400	[thread overview]
Message-ID: <52E13282.2080704@linux.vnet.ibm.com> (raw)
In-Reply-To: <1389944779-31899-13-git-send-email-qiaonuohan@cn.fujitsu.com>

On 01/17/2014 11:46 AM, qiaonuohan wrote:
> 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>
> ---
>   dump.c           |  129 +++++++++++++++++++++++++++++++++++++++++++++++++++---
>   hmp.c            |    5 ++-
>   qapi-schema.json |   25 ++++++++++-
>   qmp-commands.hx  |    7 ++-
>   4 files changed, 156 insertions(+), 10 deletions(-)
>
> diff --git a/dump.c b/dump.c
> index bb03ef7..dbf4bb6 100644
> --- a/dump.c
> +++ b/dump.c
> @@ -1449,6 +1449,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;
> @@ -1487,7 +1545,8 @@ static void get_max_mapnr(DumpState *s)
>       }
>   }
>
> -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;
> @@ -1495,6 +1554,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;
> @@ -1565,6 +1629,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);
>       }
> @@ -1624,14 +1710,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;
> @@ -1641,6 +1738,19 @@ 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");
> +    }
> +#endif

When kdump-lzo is not available, command still writes a dump,
which is half smaller then uncompressed one (and is read as partial
dump), but is much bigger then the compressed one. Is it supposed to
behave like that?

Kate.

> +
> +#ifndef CONFIG_SNAPPY
> +    if (has_format && format == DUMP_GUEST_MEMORY_FORMAT_KDUMP_SNAPPY) {
> +        error_setg(errp, "kdump-snappy is not available now");
> +    }
> +#endif
> +
>   #if !defined(WIN32)
>       if (strstart(file, "fd:", &p)) {
>           fd = monitor_get_fd(cur_mon, p, errp);
> @@ -1665,14 +1775,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 79f9c7d..5245e62 100644
> --- a/hmp.c
> +++ b/hmp.c
> @@ -1308,8 +1308,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) {
> @@ -1322,7 +1325,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 f27c48a..52df894 100644
> --- a/qapi-schema.json
> +++ b/qapi-schema.json
> @@ -2677,6 +2677,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
> @@ -2712,13 +2730,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 @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 02cc815..9158f22 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:
>

  reply	other threads:[~2014-01-23 15:17 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-01-17  7:46 [Qemu-devel] [PATCH 00/13 v7] Make 'dump-guest-memory' dump in kdump-compressed format qiaonuohan
2014-01-17  7:46 ` [Qemu-devel] [PATCH 01/13 v7] dump: const-qualify the buf of WriteCoreDumpFunction qiaonuohan
2014-01-22 15:48   ` Laszlo Ersek
2014-01-17  7:46 ` [Qemu-devel] [PATCH 02/13 v7] dump: add argument to write_elfxx_notes qiaonuohan
2014-01-22 15:56   ` Laszlo Ersek
2014-01-17  7:46 ` [Qemu-devel] [PATCH 03/13 v7] dump: add API to write header of flatten format qiaonuohan
2014-01-22 16:03   ` Laszlo Ersek
2014-01-17  7:46 ` [Qemu-devel] [PATCH 04/13 v7] dump: add API to write vmcore qiaonuohan
2014-01-22 16:06   ` Laszlo Ersek
2014-01-17  7:46 ` [Qemu-devel] [PATCH 05/13 v7] dump: add API to write elf notes to buffer qiaonuohan
2014-01-22 16:09   ` Laszlo Ersek
2014-01-17  7:46 ` [Qemu-devel] [PATCH 06/13 v7] dump: add support for lzo/snappy qiaonuohan
2014-01-22 16:12   ` Laszlo Ersek
2014-01-17  7:46 ` [Qemu-devel] [PATCH 07/13 v7] dump: add members to DumpState and init some of them qiaonuohan
2014-01-22 17:04   ` Laszlo Ersek
2014-01-24  1:52     ` Qiao Nuohan
2014-01-24 10:00       ` Laszlo Ersek
2014-01-17  7:46 ` [Qemu-devel] [PATCH 08/13 v7] dump: add API to write dump header qiaonuohan
2014-01-22 18:07   ` Laszlo Ersek
2014-01-23 14:29   ` Ekaterina Tumanova
2014-01-17  7:46 ` [Qemu-devel] [PATCH 09/13 v7] dump: add API to write dump_bitmap qiaonuohan
2014-01-23 13:56   ` Laszlo Ersek
2014-01-17  7:46 ` [Qemu-devel] [PATCH 10/13 v7] dump: add APIs to operate DataCache qiaonuohan
2014-01-23 14:50   ` Laszlo Ersek
2014-01-17  7:46 ` [Qemu-devel] [PATCH 11/13 v7] dump: add API to write dump pages qiaonuohan
2014-01-23 15:32   ` Laszlo Ersek
2014-01-17  7:46 ` [Qemu-devel] [PATCH 12/13 v7] dump: make kdump-compressed format available for 'dump-guest-memory' qiaonuohan
2014-01-23 15:17   ` Ekaterina Tumanova [this message]
2014-01-24 11:27     ` Laszlo Ersek
2014-01-24 12:06   ` Laszlo Ersek
2014-01-17  7:46 ` [Qemu-devel] [PATCH 13/13 v7] dump: add 'query-dump-guest-memory-capability' command qiaonuohan
2014-01-24 12:31   ` Laszlo Ersek
2014-01-17  8:50 ` [Qemu-devel] [PATCH 00/13 v7] Make 'dump-guest-memory' dump in kdump-compressed format Christian Borntraeger
2014-01-17  9:04   ` Qiao Nuohan
2014-01-21  9:56 ` Qiao Nuohan
2014-01-21 10:14   ` Laszlo Ersek
2014-01-22  1:27     ` Qiao Nuohan

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=52E13282.2080704@linux.vnet.ibm.com \
    --to=tumanova@linux.vnet.ibm.com \
    --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).