Re: [Qemu-devel] [PATCH 08/13 v7] dump: add API to write dump header

2014-01-23 Thread Ekaterina Tumanova

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 qiaonuo...@cn.fujitsu.com
Reviewed-by: Laszlo Ersek ler...@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 = 

Re: [Qemu-devel] [PATCH 08/13 v7] dump: add API to write dump header

2014-01-22 Thread Laszlo Ersek
remarks below

On 01/17/14 08:46, 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 qiaonuo...@cn.fujitsu.com
 Reviewed-by: Laszlo Ersek ler...@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 */

thanks for fixing the comment

 +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);
 +
 +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);

taking care about endianness looks reasonable to me thus far


 +
 +if (write_buffer(s-fd, 0, dh, size)  0) {
 +dump_error(s, dump: failed to write disk dump header.\n);
 +ret = -1;
 +goto out;
 +}

calling dump_error() for cleanup, looks good

(of course I'm not checking completeness, either for the endianness
question or cleanup-on-error coverage, but they do seem sound)

 +
 +/* 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);

looks good

 +
 +if (write_buffer(s-fd, DISKDUMP_HEADER_BLOCKS *
 + block_size, kh, size)  0) {

OK, flag_flatten is dropped. Plus the multiplication that I asked for is
being done; thanks.

 +dump_error(s, dump: failed to write kdump sub header.\n);
 +ret = -1;
 +goto out;
 +}

dump_error() looks good

 +
 +/* write note */
 +s-note_buf = g_malloc0(s-note_size);

zeroing it out is now consistent with the 64-bit version

 +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;
 +}

OK, you opted for the third option here, 'allocating s-note_buf with
g_malloc0()', thanks.

 +
 +/* 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);
 + 

[Qemu-devel] [PATCH 08/13 v7] dump: add API to write dump header

2014-01-16 Thread qiaonuohan
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 qiaonuo...@cn.fujitsu.com
Reviewed-by: Laszlo Ersek ler...@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);
+
+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);
+