diff -up kexec-tools-testing-20070330/makedumpfile/makedumpfile.8.orig kexec-tools-testing-20070330/makedumpfile/makedumpfile.8 --- kexec-tools-testing-20070330/makedumpfile/makedumpfile.8.orig 2009-05-19 06:59:47.000000000 -0400 +++ kexec-tools-testing-20070330/makedumpfile/makedumpfile.8 2009-05-19 06:59:23.000000000 -0400 @@ -134,6 +134,13 @@ Note that dump_level for Xen dump filter 30 | | X | X | X | X 31 | X | X | X | X | X +.TP +\fB\-\-dump-dmesg +This option overrides the normal behavior of makedumpfile. Instead of +compressing and filtering a vmcore to make it smaller, it simply extracts the +dmesg log from the core and writes it to the specified output file. This option +assumes that a vmcoreinfo section is present in the vmcore file and contains the +symbols for the location of the dmesg log .TP \fB\-E\fR diff -up kexec-tools-testing-20070330/makedumpfile/makedumpfile.c.orig kexec-tools-testing-20070330/makedumpfile/makedumpfile.c --- kexec-tools-testing-20070330/makedumpfile/makedumpfile.c.orig 2009-05-19 06:59:47.000000000 -0400 +++ kexec-tools-testing-20070330/makedumpfile/makedumpfile.c 2009-05-19 06:59:41.000000000 -0400 @@ -31,6 +31,9 @@ int message_level; int retcd = FAILED; /* return code */ +int +close_files_for_creating_dumpfile(); + void show_version() { @@ -1813,6 +1816,10 @@ get_symbol_info() SYMBOL_INIT(node_data, "node_data"); SYMBOL_INIT(pgdat_list, "pgdat_list"); SYMBOL_INIT(contig_page_data, "contig_page_data"); + SYMBOL_INIT(log_buf, "log_buf"); + SYMBOL_INIT(log_buf_len, "log_buf_len"); + SYMBOL_INIT(log_end, "log_end"); + SYMBOL_INIT(logged_chars, "logged_chars"); if (SYMBOL(node_data) != NOT_FOUND_SYMBOL) SYMBOL_ARRAY_TYPE_INIT(node_data, "node_data"); @@ -2085,6 +2092,10 @@ generate_vmcoreinfo() WRITE_SYMBOL("node_data", node_data); WRITE_SYMBOL("pgdat_list", pgdat_list); WRITE_SYMBOL("contig_page_data", contig_page_data); + WRITE_SYMBOL("log_buf", log_buf); + WRITE_SYMBOL("log_buf_len", log_buf_len); + WRITE_SYMBOL("log_end", log_end); + WRITE_SYMBOL("logged_chars", logged_chars); /* * write the structure size of 1st kernel @@ -2319,6 +2330,10 @@ read_vmcoreinfo() READ_SYMBOL("node_data", node_data); READ_SYMBOL("pgdat_list", pgdat_list); READ_SYMBOL("contig_page_data", contig_page_data); + READ_SYMBOL("log_buf", log_buf); + READ_SYMBOL("log_buf_len", log_buf_len); + READ_SYMBOL("log_end", log_end); + READ_SYMBOL("logged_chars", logged_chars); READ_STRUCTURE_SIZE("page", page); READ_STRUCTURE_SIZE("mem_section", mem_section); @@ -3890,6 +3905,99 @@ exclude_free_page(struct cache_data *bm2 } int +dump_dmesg() +{ + int log_buf_len, length_log, length_oldlog, ret = FALSE; + unsigned long log_addr, logged_chars, index; + char *log_buffer = NULL; + + if (!open_files_for_creating_dumpfile()) + return FALSE; + + if (!get_elf_info()) + return FALSE; + + if (!initial()) + return FALSE; + + if ((SYMBOL(log_buf) == NOT_FOUND_SYMBOL) + || (SYMBOL(log_buf_len) == NOT_FOUND_SYMBOL) + || (SYMBOL(logged_chars) == NOT_FOUND_SYMBOL) + || (SYMBOL(log_end) == NOT_FOUND_SYMBOL)) { + printf("Cannot find some symbols for log_buf.\n"); + return FALSE; + } + if (!readmem(VADDR, SYMBOL(log_buf), &log_addr, sizeof(log_addr))) { + printf("Failed to get log addr.\n"); + return FALSE; + } + if (!readmem(VADDR, SYMBOL(log_buf_len), &log_buf_len, + sizeof(log_buf_len))) { + printf("Failed to get log_buf_len.\n"); + return FALSE; + } + if (!readmem(VADDR, SYMBOL(logged_chars), &logged_chars, + sizeof(logged_chars))) { + printf("Failed to get logged_chars.\n"); + return FALSE; + } + DEBUG_MSG("\n"); + DEBUG_MSG("log_addr : %lx\n", log_addr); + DEBUG_MSG("log_buf_len : %d\n", log_buf_len); + DEBUG_MSG("logged_chars : %ld\n", logged_chars); + + if ((log_buffer = malloc(log_buf_len)) == NULL) { + ERRMSG("Can't allocate memory for log_buf. %s\n", + strerror(errno)); + return FALSE; + } + + if (logged_chars < log_buf_len) { + index = 0; + length_log = logged_chars; + + if(!readmem(VADDR, log_addr, log_buffer, length_log)) { + printf("Failed to read dmesg log.\n"); + goto out; + } + } else { + if (!readmem(VADDR, SYMBOL(log_end), &index, sizeof(index))) { + printf("Failed to get log_end.\n"); + goto out; + } + DEBUG_MSG("log_end : %lx\n", index); + index &= log_buf_len - 1; + length_log = log_buf_len; + length_oldlog = log_buf_len - index; + + if(!readmem(VADDR, log_addr + index, log_buffer, length_oldlog)) { + printf("Failed to read dmesg log.\n"); + goto out; + } + DEBUG_MSG("log_addr : %lx\n", log_addr); + DEBUG_MSG("length_oldlog: %d\n", length_oldlog); + + if(!readmem(VADDR, log_addr, log_buffer + length_oldlog, index)) { + printf("Failed to read dmesg log.\n"); + goto out; + } + } + + if (write(info->fd_dumpfile, log_buffer, length_log) < 0) + goto out; + + if (!close_files_for_creating_dumpfile()) + goto out; + + ret = TRUE; + out: + if (log_buffer) + free(log_buffer); + + return ret; +} + +int create_dump_bitmap() { int val, not_found_mem_map; @@ -5995,6 +6103,7 @@ static struct option longopts[] = { {"xen-vmcoreinfo", required_argument, NULL, 'z'}, {"xen_phys_start", required_argument, NULL, 'P'}, {"message-level", required_argument, NULL, 'm'}, + {"dump-dmesg", no_argument, NULL, 'M'}, {"help", no_argument, NULL, 'h'}, {0, 0, 0, 0} }; @@ -6018,7 +6127,7 @@ main(int argc, char *argv[]) info->block_order = DEFAULT_ORDER; message_level = DEFAULT_MSG_LEVEL; - while ((opt = getopt_long(argc, argv, "b:cDd:EFfg:hi:RvXx:y:", longopts, + while ((opt = getopt_long(argc, argv, "b:cDd:EFfg:hi:MRvXx:y:", longopts, NULL)) != -1) { switch (opt) { case 'b': @@ -6058,6 +6167,9 @@ main(int argc, char *argv[]) case 'm': message_level = atoi(optarg); break; + case 'M': + info->flag_dmesg = 1; + break; case 'P': info->xen_phys_start = strtoul(optarg, NULL, 0); break; @@ -6166,9 +6278,11 @@ main(int argc, char *argv[]) info->name_dumpfile = argv[optind]; } else { - MSG("Commandline parameter is invalid.\n"); - print_usage(); - goto out; + if (!info->flag_dmesg) { + MSG("Commandline parameter is invalid.\n"); + print_usage(); + goto out; + } } } @@ -6223,6 +6337,12 @@ main(int argc, char *argv[]) MSG("\n"); MSG("The dumpfile is saved to %s.\n", info->name_dumpfile); } else { + if (info->flag_dmesg) { + dump_dmesg(); + retcd = COMPLETED; + goto out; + } + if (!open_files_for_creating_dumpfile()) goto out; diff -up kexec-tools-testing-20070330/makedumpfile/makedumpfile.h.orig kexec-tools-testing-20070330/makedumpfile/makedumpfile.h --- kexec-tools-testing-20070330/makedumpfile/makedumpfile.h.orig 2009-05-19 06:59:47.000000000 -0400 +++ kexec-tools-testing-20070330/makedumpfile/makedumpfile.h 2009-05-19 06:59:23.000000000 -0400 @@ -653,6 +653,7 @@ struct DumpInfo { flattened format */ int flag_force; /* overwrite existing stuff */ int flag_exclude_xen_dom;/* exclude Domain-U from xen-kdump */ + int flag_dmesg; /* dump the dmesg log out of the vmcore file */ long page_size; /* size of page */ long page_shift; unsigned long long max_mapnr; /* number of page descriptor */ @@ -769,6 +770,10 @@ struct symbol_table { unsigned long node_data; unsigned long pgdat_list; unsigned long contig_page_data; + unsigned long log_buf; + unsigned long log_end; + unsigned long log_buf_len; + unsigned long logged_chars; /* * for Xen extraction