This patch enables crash utility to handle elf notes content in DUMPFILE if kdump hedaer version >= 4. The processing of data content will be architecture dependent. makedumpfile tool is enhanced to store elf notes content from vmcore to DUMPFILE starting from kdump header version 4. --------------------------------------------------------------- commit 1fb344e934f87b9c124e487a21e111c7bdc977ba Author: Ken'ichi Ohmichi <oomichi@xxxxxxxxxxxxxxxxx> Date: Fri Oct 8 09:18:59 2010 +0900 [PATCH] Add ELF note section to the kdump-compressed format. --------------------------------------------------------------- A new arch dependent interface has been added to machdep_table structure which needs to be populated during machdep_init(SETUP_ENV) call. struct machdep_table { ... ... void (*process_elf_notes)(void *, unsigned long); } ChangeLog: - Modified __diskdump_memory_dump() function to display contents of all 4 additional fields in the kdump_sub_header. - Modified __diskdump_memory_dump() to dump the vmcoreinfo ASCII strings. Signed-off-by: Mahesh Salgaonkar <mahesh@xxxxxxxxxxxxxxxxxx> --- defs.h | 1 diskdump.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ diskdump.h | 4 +++ 3 files changed, 86 insertions(+) Index: crash-5.0.9/diskdump.c =================================================================== --- crash-5.0.9.orig/diskdump.c +++ crash-5.0.9/diskdump.c @@ -189,6 +189,7 @@ static int read_dump_header(char *file) struct disk_dump_header *header = NULL; struct disk_dump_sub_header *sub_header = NULL; struct kdump_sub_header *sub_header_kdump = NULL; + unsigned char *notes_buf = NULL; int bitmap_len; int block_size = (int)sysconf(_SC_PAGESIZE); off_t offset; @@ -355,6 +356,31 @@ restart: goto err; } + /* process elf notes data */ + if (KDUMP_CMPRS_VALID() && (dd->header->header_version >= 4) && + (sub_header_kdump->offset_note) && + (sub_header_kdump->size_note) && (machdep->process_elf_notes)) { + unsigned long size_note = sub_header_kdump->size_note; + offset = sub_header_kdump->offset_note; + + if (lseek(dd->dfd, offset, SEEK_SET) == failed) { + error(INFO, "compressed kdump: cannot lseek dump elf" + " notes\n"); + goto err; + } + + if ((notes_buf = malloc(size_note)) == NULL) + error(FATAL, "compressed kdump: cannot malloc notes" + " buffer\n"); + + if (read(dd->dfd, notes_buf, size_note) < size_note) { + error(INFO, "compressed kdump: cannot read notes data" + "\n"); + goto err; + } + machdep->process_elf_notes(notes_buf, size_note); + } + /* For split dumpfile */ if (KDUMP_CMPRS_VALID()) { is_split = ((dd->header->header_version >= 2) && @@ -399,6 +425,8 @@ err: free(sub_header); if (sub_header_kdump) free(sub_header_kdump); + if (notes_buf) + free(notes_buf); if (dd->bitmap) free(dd->bitmap); if (dd->dumpable_bitmap) @@ -786,6 +814,43 @@ int diskdump_memory_used(void) return 0; } +void dump_vmcoreinfo(FILE *fp) +{ + char *buf = NULL; + unsigned long i = 0; + unsigned long size_vmcoreinfo = dd->sub_header_kdump->size_vmcoreinfo; + off_t offset = dd->sub_header_kdump->offset_vmcoreinfo; + const off_t failed = (off_t)-1; + + if (lseek(dd->dfd, offset, SEEK_SET) == failed) { + error(INFO, "compressed kdump: cannot lseek dump vmcoreinfo\n"); + return; + } + + if ((buf = malloc(size_vmcoreinfo)) == NULL) { + error(FATAL, "compressed kdump: cannot malloc vmcoreinfo" + " buffer\n"); + } + + if (read(dd->dfd, buf, size_vmcoreinfo) < size_vmcoreinfo) { + error(INFO, "compressed kdump: cannot read vmcoreinfo data\n"); + goto err; + } + + fprintf(fp, " "); + for (i = 0; i < size_vmcoreinfo; i++) { + fprintf(fp, "%c", buf[i]); + if (buf[i] == '\n') + fprintf(fp, " "); + } + if (buf[i - 1] != '\n') + fprintf(fp, "\n"); +err: + if (buf) + free(buf); + return; +} + /* * This function is dump-type independent, and could be used * to dump the diskdump_data structure contents and perhaps @@ -954,6 +1019,22 @@ __diskdump_memory_dump(FILE *fp) fprintf(fp, " start_pfn: %lu\n", dd->sub_header_kdump->start_pfn); fprintf(fp, " end_pfn: %lu\n", dd->sub_header_kdump->end_pfn); } + if (dh->header_version >= 3) { + fprintf(fp, " offset_vmcoreinfo: %lx\n", + dd->sub_header_kdump->offset_vmcoreinfo); + fprintf(fp, " size_vmcoreinfo: %lu\n", + dd->sub_header_kdump->size_vmcoreinfo); + if (dd->sub_header_kdump->offset_vmcoreinfo && + dd->sub_header_kdump->size_vmcoreinfo) { + dump_vmcoreinfo(fp); + } + } + if (dh->header_version >= 4) { + fprintf(fp, " offset_note: %lx\n", + dd->sub_header_kdump->offset_note); + fprintf(fp, " size_note: %lu\n", + dd->sub_header_kdump->size_note); + } fprintf(fp, "\n"); } else fprintf(fp, "(n/a)\n\n"); Index: crash-5.0.9/diskdump.h =================================================================== --- crash-5.0.9.orig/diskdump.h +++ crash-5.0.9/diskdump.h @@ -63,6 +63,10 @@ struct kdump_sub_header { int split; /* header_version 2 and later */ unsigned long start_pfn; /* header_version 2 and later */ unsigned long end_pfn; /* header_version 2 and later */ + off_t offset_vmcoreinfo;/* header_version 3 and later */ + unsigned long size_vmcoreinfo; /* header_version 3 and later */ + off_t offset_note; /* header_version 4 and later */ + unsigned long size_note; /* header_version 4 and later */ }; /* page flags */ Index: crash-5.0.9/defs.h =================================================================== --- crash-5.0.9.orig/defs.h +++ crash-5.0.9/defs.h @@ -807,6 +807,7 @@ struct machdep_table { int (*xen_kdump_p2m_create)(struct xen_kdump_data *); int (*in_alternate_stack)(int, ulong); void (*dumpfile_init)(int, void *); + void (*process_elf_notes)(void *, unsigned long); }; /* -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility