All of lore.kernel.org
 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.