Re: [Qemu-devel] [PATCH v6 10/11] dump: Make kdump-compressed format available for 'dump-guest-memory'
comments below On 01/05/14 08:27, Qiao Nuohan 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 And without 'format' being set, it is same as 'elf'. 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 qiaonuo...@cn.fujitsu.com --- dump.c | 163 -- hmp-commands.hx | 12 +++- hmp.c| 23 +++- qapi-schema.json | 22 +++- qmp-commands.hx |6 +- 5 files changed, 212 insertions(+), 14 deletions(-) diff --git a/dump.c b/dump.c index 848957c..b4e79ff 100644 --- a/dump.c +++ b/dump.c @@ -1398,6 +1398,70 @@ 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) | Also including the note. ... Come to think of it, note_buf could actually be local to create_headerXX(), no need to add it to DumpState. + * |--+ 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) | + * |: | + * | page desc for pfn Z (struct page_desc) | + * |--| (not aligned by block) + * | page data (pfn 0)| + * | page data (pfn 1)| + * |: | + * | page data (pfn Z)| + * +--+ offset_eraseinfo I think this offset_eraseinfo is a bit misleading, because we never set that field in KdumpSubHeaderXX to nonzero, and we also never write the trailing portion here. Maybe a zero value of offset_eraseinfo implies presicely that the portion marked below as : is never written, but still offset_eraseinfo (== 0) doesn't match the end of the page data. Also, using the same Z as final subscript for page data as for page desc is misleading. There can be fewer, equal number of, and more page data entries than page desc entries. We'll have fewer page data entries if the guest has at least two zero pages. We'll have more page data entries if the guest has no zero pages (because we dump exactly one zero page data entry). + * |: | + * +--+ + */ + +if (s-flag_flatten) { +ret = write_start_flat_header(s-fd); +if (ret 0) { +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; +} + +if (s-flag_flatten) { +ret = write_end_flat_header(s-fd); +if (ret 0) { +return -1; +} +} + +dump_completed(s); + +return 0; +} + static ram_addr_t get_start_block(DumpState *s) { GuestPhysBlock *block; @@ -1426,7 +1490,27 @@ static ram_addr_t get_start_block(DumpState *s) return -1; } -static int dump_init(DumpState *s, int fd, bool paging, bool has_filter, +static bool use_flatten_format(int fd) +{ +if (lseek(fd, 0, SEEK_SET) 0) { +return true; +} + +return false; +} + +static void get_max_mapnr(DumpState *s) +{ +MemoryMapping *memory_mapping; + +QTAILQ_FOREACH(memory_mapping, s-list.head, next) { +s-max_mapnr = paddr_to_pfn(memory_mapping-phys_addr + +memory_mapping-length, s-page_shift); +} +} I'm a bit confused about the difference between
[Qemu-devel] [PATCH v6 10/11] dump: Make kdump-compressed format available for 'dump-guest-memory'
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 And without 'format' being set, it is same as 'elf'. 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 qiaonuo...@cn.fujitsu.com --- dump.c | 163 -- hmp-commands.hx | 12 +++- hmp.c| 23 +++- qapi-schema.json | 22 +++- qmp-commands.hx |6 +- 5 files changed, 212 insertions(+), 14 deletions(-) diff --git a/dump.c b/dump.c index 848957c..b4e79ff 100644 --- a/dump.c +++ b/dump.c @@ -1398,6 +1398,70 @@ 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) | + * |: | + * | page desc for pfn Z (struct page_desc) | + * |--| (not aligned by block) + * | page data (pfn 0)| + * | page data (pfn 1)| + * |: | + * | page data (pfn Z)| + * +--+ offset_eraseinfo + * |: | + * +--+ + */ + +if (s-flag_flatten) { +ret = write_start_flat_header(s-fd); +if (ret 0) { +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; +} + +if (s-flag_flatten) { +ret = write_end_flat_header(s-fd); +if (ret 0) { +return -1; +} +} + +dump_completed(s); + +return 0; +} + static ram_addr_t get_start_block(DumpState *s) { GuestPhysBlock *block; @@ -1426,7 +1490,27 @@ static ram_addr_t get_start_block(DumpState *s) return -1; } -static int dump_init(DumpState *s, int fd, bool paging, bool has_filter, +static bool use_flatten_format(int fd) +{ +if (lseek(fd, 0, SEEK_SET) 0) { +return true; +} + +return false; +} + +static void get_max_mapnr(DumpState *s) +{ +MemoryMapping *memory_mapping; + +QTAILQ_FOREACH(memory_mapping, s-list.head, next) { +s-max_mapnr = paddr_to_pfn(memory_mapping-phys_addr + +memory_mapping-length, s-page_shift); +} +} + +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; @@ -1494,6 +1578,44 @@ static int dump_init(DumpState *s, int fd, bool paging, bool has_filter, qemu_get_guest_simple_memory_mapping(s-list, s-guest_phys_blocks); } +/* 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; +} + +/* + * check to see if fd is available to seek. + * if not, flatten format is used