From: Ekaterina Tumanova <tumanova@linux.vnet.ibm.com>
To: qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH 08/13 v7] dump: add API to write dump header
Date: Thu, 23 Jan 2014 18:29:53 +0400 [thread overview]
Message-ID: <52E12761.70302@linux.vnet.ibm.com> (raw)
In-Reply-To: <1389944779-31899-9-git-send-email-qiaonuohan@cn.fujitsu.com>
On 01/17/2014 11:46 AM, qiaonuohan wrote:
> the functions are used to write header of kdump-compressed format to vmcore.
> Header of kdump-compressed format includes:
> 1. common header: DiskDumpHeader32 / DiskDumpHeader64
> 2. sub header: KdumpSubHeader32 / KdumpSubHeader64
> 3. extra information: only elf notes here
>
> Signed-off-by: Qiao Nuohan <qiaonuohan@cn.fujitsu.com>
> Reviewed-by: Laszlo Ersek <lersek@redhat.com>
> ---
> dump.c | 223 +++++++++++++++++++++++++++++++++++++++++++++++++
> include/sysemu/dump.h | 96 +++++++++++++++++++++
> 2 files changed, 319 insertions(+), 0 deletions(-)
>
> diff --git a/dump.c b/dump.c
> index bf7d31d..a7fdc3f 100644
> --- a/dump.c
> +++ b/dump.c
> @@ -778,6 +778,229 @@ static int buf_write_note(const void *buf, size_t size, void *opaque)
> return 0;
> }
>
> +/* write common header, sub header and elf note to vmcore */
> +static int create_header32(DumpState *s)
> +{
> + int ret = 0;
> + DiskDumpHeader32 *dh = NULL;
> + KdumpSubHeader32 *kh = NULL;
> + size_t size;
> + int endian = s->dump_info.d_endian;
> + uint32_t block_size;
> + uint32_t sub_hdr_size;
> + uint32_t bitmap_blocks;
> + uint32_t status = 0;
> + uint64_t offset_note;
> +
> + /* write common header, the version of kdump-compressed format is 6th */
> + size = sizeof(DiskDumpHeader32);
> + dh = g_malloc0(size);
> +
> + strncpy(dh->signature, KDUMP_SIGNATURE, strlen(KDUMP_SIGNATURE));
> + dh->header_version = cpu_convert_to_target32(6, endian);
> + block_size = s->page_size;
> + dh->block_size = cpu_convert_to_target32(block_size, endian);
> + sub_hdr_size = sizeof(struct KdumpSubHeader32) + s->note_size;
> + sub_hdr_size = DIV_ROUND_UP(sub_hdr_size, block_size);
> + dh->sub_hdr_size = cpu_convert_to_target32(sub_hdr_size, endian);
> + /* dh->max_mapnr may be truncated, full 64bit is in kh.max_mapnr_64 */
> + dh->max_mapnr = cpu_convert_to_target32(MIN(s->max_mapnr, UINT_MAX),
> + endian);
> + dh->nr_cpus = cpu_convert_to_target32(s->nr_cpus, endian);
> + bitmap_blocks = DIV_ROUND_UP(s->len_dump_bitmap, block_size) * 2;
> + dh->bitmap_blocks = cpu_convert_to_target32(bitmap_blocks, endian);
> + memcpy(&(dh->utsname.machine), "i686", 4);
I actually tried to use your patch on s390x, and the only problem I
found is that you hardcode the architecture into the header in
arch-independent dump.c file here. Then it becomes unreadable for crash
utility on different architecture. If would be great, if you could
somehow get rid of hardcoding the arch in
create_header32/create_header64 and instead use the target arch.
> +
> + if (s->flag_compress & DUMP_DH_COMPRESSED_ZLIB) {
> + status |= DUMP_DH_COMPRESSED_ZLIB;
> + }
> +#ifdef CONFIG_LZO
> + if (s->flag_compress & DUMP_DH_COMPRESSED_LZO) {
> + status |= DUMP_DH_COMPRESSED_LZO;
> + }
> +#endif
> +#ifdef CONFIG_SNAPPY
> + if (s->flag_compress & DUMP_DH_COMPRESSED_SNAPPY) {
> + status |= DUMP_DH_COMPRESSED_SNAPPY;
> + }
> +#endif
> + dh->status = cpu_convert_to_target32(status, endian);
> +
> + if (write_buffer(s->fd, 0, dh, size) < 0) {
> + dump_error(s, "dump: failed to write disk dump header.\n");
> + ret = -1;
> + goto out;
> + }
> +
> + /* write sub header */
> + size = sizeof(KdumpSubHeader32);
> + kh = g_malloc0(size);
> +
> + /* 64bit max_mapnr_64 */
> + kh->max_mapnr_64 = cpu_convert_to_target64(s->max_mapnr, endian);
> + kh->phys_base = cpu_convert_to_target32(PHYS_BASE, endian);
> + kh->dump_level = cpu_convert_to_target32(DUMP_LEVEL, endian);
> +
> + offset_note = DISKDUMP_HEADER_BLOCKS * block_size + size;
> + kh->offset_note = cpu_convert_to_target64(offset_note, endian);
> + kh->note_size = cpu_convert_to_target32(s->note_size, endian);
> +
> + if (write_buffer(s->fd, DISKDUMP_HEADER_BLOCKS *
> + block_size, kh, size) < 0) {
> + dump_error(s, "dump: failed to write kdump sub header.\n");
> + ret = -1;
> + goto out;
> + }
> +
> + /* write note */
> + s->note_buf = g_malloc0(s->note_size);
> + s->note_buf_offset = 0;
> +
> + /* use s->note_buf to store notes temporarily */
> + if (write_elf32_notes(buf_write_note, s) < 0) {
> + ret = -1;
> + goto out;
> + }
> +
> + if (write_buffer(s->fd, offset_note, s->note_buf,
> + s->note_size) < 0) {
> + dump_error(s, "dump: failed to write notes");
> + ret = -1;
> + goto out;
> + }
> +
> + /* get offset of dump_bitmap */
> + s->offset_dump_bitmap = (DISKDUMP_HEADER_BLOCKS + sub_hdr_size) *
> + block_size;
> +
> + /* get offset of page */
> + s->offset_page = (DISKDUMP_HEADER_BLOCKS + sub_hdr_size + bitmap_blocks) *
> + block_size;
> +
> +out:
> + g_free(dh);
> + g_free(kh);
> + g_free(s->note_buf);
> +
> + return ret;
> +}
> +
> +/* write common header, sub header and elf note to vmcore */
> +static int create_header64(DumpState *s)
> +{
> + int ret = 0;
> + DiskDumpHeader64 *dh = NULL;
> + KdumpSubHeader64 *kh = NULL;
> + size_t size;
> + int endian = s->dump_info.d_endian;
> + uint32_t block_size;
> + uint32_t sub_hdr_size;
> + uint32_t bitmap_blocks;
> + uint32_t status = 0;
> + uint64_t offset_note;
> +
> + /* write common header, the version of kdump-compressed format is 6th */
> + size = sizeof(DiskDumpHeader64);
> + dh = g_malloc0(size);
> +
> + strncpy(dh->signature, KDUMP_SIGNATURE, strlen(KDUMP_SIGNATURE));
> + dh->header_version = cpu_convert_to_target32(6, endian);
> + block_size = s->page_size;
> + dh->block_size = cpu_convert_to_target32(block_size, endian);
> + sub_hdr_size = sizeof(struct KdumpSubHeader64) + s->note_size;
> + sub_hdr_size = DIV_ROUND_UP(sub_hdr_size, dh->block_size);
> + dh->sub_hdr_size = cpu_convert_to_target32(sub_hdr_size, endian);
> + /* dh->max_mapnr may be truncated, full 64bit is in kh.max_mapnr_64 */
> + dh->max_mapnr = cpu_convert_to_target32(MIN(s->max_mapnr, UINT_MAX),
> + endian);
> + dh->nr_cpus = cpu_convert_to_target32(s->nr_cpus, endian);
> + bitmap_blocks = DIV_ROUND_UP(s->len_dump_bitmap, dh->block_size) * 2;
> + dh->bitmap_blocks = cpu_convert_to_target32(bitmap_blocks, endian);
> + memcpy(&(dh->utsname.machine), "x86_64", 6);
Same problem here
> +
> + if (s->flag_compress & DUMP_DH_COMPRESSED_ZLIB) {
> + status |= DUMP_DH_COMPRESSED_ZLIB;
> + }
> +#ifdef CONFIG_LZO
> + if (s->flag_compress & DUMP_DH_COMPRESSED_LZO) {
> + status |= DUMP_DH_COMPRESSED_LZO;
> + }
> +#endif
> +#ifdef CONFIG_SNAPPY
> + if (s->flag_compress & DUMP_DH_COMPRESSED_SNAPPY) {
> + status |= DUMP_DH_COMPRESSED_SNAPPY;
> + }
> +#endif
> + dh->status = cpu_convert_to_target32(status, endian);
> +
> + if (write_buffer(s->fd, 0, dh, size) < 0) {
> + dump_error(s, "dump: failed to write disk dump header.\n");
> + ret = -1;
> + goto out;
> + }
> +
> + /* write sub header */
> + size = sizeof(KdumpSubHeader64);
> + kh = g_malloc0(size);
> +
> + /* 64bit max_mapnr_64 */
> + kh->max_mapnr_64 = cpu_convert_to_target64(s->max_mapnr, endian);
> + kh->phys_base = cpu_convert_to_target64(PHYS_BASE, endian);
> + kh->dump_level = cpu_convert_to_target32(DUMP_LEVEL, endian);
> +
> + offset_note = DISKDUMP_HEADER_BLOCKS * dh->block_size + size;
> + kh->offset_note = cpu_convert_to_target64(offset_note, endian);
> + kh->note_size = cpu_convert_to_target64(s->note_size, endian);
> +
> + if (write_buffer(s->fd, DISKDUMP_HEADER_BLOCKS *
> + dh->block_size, kh, size) < 0) {
> + dump_error(s, "dump: failed to write kdump sub header.\n");
> + ret = -1;
> + goto out;
> + }
> +
> + /* write note */
> + s->note_buf = g_malloc0(s->note_size);
> + s->note_buf_offset = 0;
> +
> + /* use s->note_buf to store notes temporarily */
> + if (write_elf64_notes(buf_write_note, s) < 0) {
> + ret = -1;
> + goto out;
> + }
> +
> + if (write_buffer(s->fd, offset_note, s->note_buf,
> + s->note_size) < 0) {
> + dump_error(s, "dump: failed to write notes");
> + ret = -1;
> + goto out;
> + }
> +
> + /* get offset of dump_bitmap */
> + s->offset_dump_bitmap = (DISKDUMP_HEADER_BLOCKS + sub_hdr_size) *
> + block_size;
> +
> + /* get offset of page */
> + s->offset_page = (DISKDUMP_HEADER_BLOCKS + sub_hdr_size + bitmap_blocks) *
> + block_size;
> +
> +out:
> + g_free(dh);
> + g_free(kh);
> + g_free(s->note_buf);
> +
> + return ret;
> +}
> +
> +static int write_dump_header(DumpState *s)
> +{
> + if (s->dump_info.d_machine == EM_386) {
> + return create_header32(s);
> + } else {
> + return create_header64(s);
> + }
> +}
> +
> static ram_addr_t get_start_block(DumpState *s)
> {
> GuestPhysBlock *block;
> diff --git a/include/sysemu/dump.h b/include/sysemu/dump.h
> index 995bf47..dfee238 100644
> --- a/include/sysemu/dump.h
> +++ b/include/sysemu/dump.h
> @@ -27,6 +27,19 @@
> #define pfn_to_paddr(X, page_shift) \
> (((unsigned long long)(X) + ARCH_PFN_OFFSET) << (page_shift))
>
> +/*
> + * flag for compressed format
> + */
> +#define DUMP_DH_COMPRESSED_ZLIB (0x1)
> +#define DUMP_DH_COMPRESSED_LZO (0x2)
> +#define DUMP_DH_COMPRESSED_SNAPPY (0x4)
> +
> +#define KDUMP_SIGNATURE "KDUMP "
> +#define SIG_LEN (sizeof(KDUMP_SIGNATURE) - 1)
> +#define PHYS_BASE (0)
> +#define DUMP_LEVEL (1)
> +#define DISKDUMP_HEADER_BLOCKS (1)
> +
> typedef struct ArchDumpInfo {
> int d_machine; /* Architecture */
> int d_endian; /* ELFDATA2LSB or ELFDATA2MSB */
> @@ -44,6 +57,89 @@ typedef struct QEMU_PACKED MakedumpfileDataHeader {
> int64_t buf_size;
> } MakedumpfileDataHeader;
>
> +typedef struct QEMU_PACKED NewUtsname {
> + char sysname[65];
> + char nodename[65];
> + char release[65];
> + char version[65];
> + char machine[65];
> + char domainname[65];
> +} NewUtsname;
> +
> +typedef struct QEMU_PACKED DiskDumpHeader32 {
> + char signature[SIG_LEN]; /* = "KDUMP " */
> + uint32_t header_version; /* Dump header version */
> + NewUtsname utsname; /* copy of system_utsname */
> + char timestamp[10]; /* Time stamp */
> + uint32_t status; /* Above flags */
> + uint32_t block_size; /* Size of a block in byte */
> + uint32_t sub_hdr_size; /* Size of arch dependent header in block */
> + uint32_t bitmap_blocks; /* Size of Memory bitmap in block */
> + uint32_t max_mapnr; /* = max_mapnr ,
> + obsoleted in header_version 6 */
> + uint32_t total_ram_blocks; /* Number of blocks should be written */
> + uint32_t device_blocks; /* Number of total blocks in dump device */
> + uint32_t written_blocks; /* Number of written blocks */
> + uint32_t current_cpu; /* CPU# which handles dump */
> + uint32_t nr_cpus; /* Number of CPUs */
> +} DiskDumpHeader32;
> +
> +typedef struct QEMU_PACKED DiskDumpHeader64 {
> + char signature[SIG_LEN]; /* = "KDUMP " */
> + uint32_t header_version; /* Dump header version */
> + NewUtsname utsname; /* copy of system_utsname */
> + char timestamp[22]; /* Time stamp */
> + uint32_t status; /* Above flags */
> + uint32_t block_size; /* Size of a block in byte */
> + uint32_t sub_hdr_size; /* Size of arch dependent header in block */
> + uint32_t bitmap_blocks; /* Size of Memory bitmap in block */
> + uint32_t max_mapnr; /* = max_mapnr,
> + obsoleted in header_version 6 */
> + uint32_t total_ram_blocks; /* Number of blocks should be written */
> + uint32_t device_blocks; /* Number of total blocks in dump device */
> + uint32_t written_blocks; /* Number of written blocks */
> + uint32_t current_cpu; /* CPU# which handles dump */
> + uint32_t nr_cpus; /* Number of CPUs */
> +} DiskDumpHeader64;
> +
> +typedef struct QEMU_PACKED KdumpSubHeader32 {
> + uint32_t phys_base;
> + uint32_t dump_level; /* header_version 1 and later */
> + uint32_t split; /* header_version 2 and later */
> + uint32_t start_pfn; /* header_version 2 and later,
> + obsoleted in header_version 6 */
> + uint32_t end_pfn; /* header_version 2 and later,
> + obsoleted in header_version 6 */
> + uint64_t offset_vmcoreinfo; /* header_version 3 and later */
> + uint32_t size_vmcoreinfo; /* header_version 3 and later */
> + uint64_t offset_note; /* header_version 4 and later */
> + uint32_t note_size; /* header_version 4 and later */
> + uint64_t offset_eraseinfo; /* header_version 5 and later */
> + uint32_t size_eraseinfo; /* header_version 5 and later */
> + uint64_t start_pfn_64; /* header_version 6 and later */
> + uint64_t end_pfn_64; /* header_version 6 and later */
> + uint64_t max_mapnr_64; /* header_version 6 and later */
> +} KdumpSubHeader32;
> +
> +typedef struct QEMU_PACKED KdumpSubHeader64 {
> + uint64_t phys_base;
> + uint32_t dump_level; /* header_version 1 and later */
> + uint32_t split; /* header_version 2 and later */
> + uint64_t start_pfn; /* header_version 2 and later,
> + obsoleted in header_version 6 */
> + uint64_t end_pfn; /* header_version 2 and later,
> + obsoleted in header_version 6 */
> + uint64_t offset_vmcoreinfo; /* header_version 3 and later */
> + uint64_t size_vmcoreinfo; /* header_version 3 and later */
> + uint64_t offset_note; /* header_version 4 and later */
> + uint64_t note_size; /* header_version 4 and later */
> + uint64_t offset_eraseinfo; /* header_version 5 and later */
> + uint64_t size_eraseinfo; /* header_version 5 and later */
> + uint64_t start_pfn_64; /* header_version 6 and later */
> + uint64_t end_pfn_64; /* header_version 6 and later */
> + uint64_t max_mapnr_64; /* header_version 6 and later */
> +} KdumpSubHeader64;
> +
> struct GuestPhysBlockList; /* memory_mapping.h */
> int cpu_get_dump_info(ArchDumpInfo *info,
> const struct GuestPhysBlockList *guest_phys_blocks);
>
next prev parent reply other threads:[~2014-01-23 14:30 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 [this message]
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
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=52E12761.70302@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.