The core file contains information about the xen version. The Xen version is determined and different functions will be called for different Xen versions. Additionally a Xen3 problem with the page_info _domain offset for x86_64 gets repaired. In Xen3 xen/common/kexec.c the page_info _domain offset was set with: VMCOREINFO_OFFSET_ALIAS(page_info, u, _domain); which is wrong for x86_in because the _domain is in union v. (xen/include/asm-x86/mm.h) For Xen3 in makedumpfile.c the offset is simply modified to 24 for x86_64. For Xen4 we asked Xen development to use: #ifdef __ia64__ VMCOREINFO_OFFSET_SUB(page_info, u.inuse, _domain); #else VMCOREINFO_OFFSET_SUB(page_info, v.inuse, _domain); #endif Signed-off-by: Norbert Trapp <norbert.trapp at ts.fujitsu.com> --- elf_info.c | 2 + makedumpfile.c | 90 +++++++++++++++++++++++++++++++++++++++++++------------- makedumpfile.h | 3 ++ 3 files changed, 74 insertions(+), 21 deletions(-) diff --git a/elf_info.c b/elf_info.c index cf476a3..e723720 100644 --- a/elf_info.c +++ b/elf_info.c @@ -159,6 +159,7 @@ check_elf_format(int fd, char *filename, int *phnum, unsigned int *num_load) if ((ehdr64.e_ident[EI_CLASS] == ELFCLASS64) && (ehdr32.e_ident[EI_CLASS] != ELFCLASS32)) { (*phnum) = ehdr64.e_phnum; + info->elf_machine = ehdr64.e_machine; for (i = 0; i < ehdr64.e_phnum; i++) { if (!get_elf64_phdr(fd, filename, i, &load64)) { ERRMSG("Can't find Phdr %d.\n", i); @@ -172,6 +173,7 @@ check_elf_format(int fd, char *filename, int *phnum, unsigned int *num_load) } else if ((ehdr64.e_ident[EI_CLASS] != ELFCLASS64) && (ehdr32.e_ident[EI_CLASS] == ELFCLASS32)) { (*phnum) = ehdr32.e_phnum; + info->elf_machine = ehdr32.e_machine; for (i = 0; i < ehdr32.e_phnum; i++) { if (!get_elf32_phdr(fd, filename, i, &load32)) { ERRMSG("Can't find Phdr %d.\n", i); diff --git a/makedumpfile.c b/makedumpfile.c index d024e95..7398f17 100644 --- a/makedumpfile.c +++ b/makedumpfile.c @@ -5300,10 +5300,7 @@ get_structure_info_xen(void) { SIZE_INIT(page_info, "page_info"); OFFSET_INIT(page_info.count_info, "page_info", "count_info"); - /* - * _domain is the first member of union u - */ - OFFSET_INIT(page_info._domain, "page_info", "u"); + OFFSET_IN_UNION_INIT(page_info._domain, "page_info", "_domain"); SIZE_INIT(domain, "domain"); OFFSET_INIT(domain.domain_id, "domain", "domain_id"); @@ -5313,6 +5310,41 @@ get_structure_info_xen(void) } int +get_xen_version(void) +{ + unsigned long xen_major_version; + unsigned long xen_minor_version; + off_t offset_xen_crash_info; + unsigned long size_xen_crash_info; + const off_t failed = (off_t)-1; + + get_xen_crash_info(&offset_xen_crash_info, &size_xen_crash_info); + if (info->xen_major_version && info->xen_minor_version) + return TRUE; + + if (lseek(info->fd_memory, offset_xen_crash_info, SEEK_SET) == failed) { + ERRMSG("Can't seek the dump memory(%s). %s\n", + info->name_memory, strerror(errno)); + return FALSE; + } + if (read(info->fd_memory, &xen_major_version, sizeof(xen_major_version)) + != sizeof(xen_major_version)) { + ERRMSG("Can't read the dump memory(%s). %s\n", + info->name_memory, strerror(errno)); + return FALSE; + } + if (read(info->fd_memory, &xen_minor_version, sizeof(xen_minor_version)) + != sizeof(xen_major_version)) { + ERRMSG("Can't read the dump memory(%s). %s\n", + info->name_memory, strerror(errno)); + return FALSE; + } + info->xen_major_version = xen_major_version; + info->xen_minor_version = xen_minor_version; + return TRUE; +} + +int get_xen_phys_start(void) { off_t offset, offset_xen_crash_info; @@ -5350,23 +5382,25 @@ get_xen_info(void) unsigned int domain_id; int num_domain; - if (SYMBOL(alloc_bitmap) == NOT_FOUND_SYMBOL) { - ERRMSG("Can't get the symbol of alloc_bitmap.\n"); - return FALSE; - } - if (!readmem(VADDR_XEN, SYMBOL(alloc_bitmap), &info->alloc_bitmap, - sizeof(info->alloc_bitmap))) { - ERRMSG("Can't get the value of alloc_bitmap.\n"); - return FALSE; - } - if (SYMBOL(max_page) == NOT_FOUND_SYMBOL) { - ERRMSG("Can't get the symbol of max_page.\n"); - return FALSE; - } - if (!readmem(VADDR_XEN, SYMBOL(max_page), &info->max_page, - sizeof(info->max_page))) { - ERRMSG("Can't get the value of max_page.\n"); - return FALSE; + if (info->xen_major_version <= 3) { + if (SYMBOL(alloc_bitmap) == NOT_FOUND_SYMBOL) { + ERRMSG("Can't get the symbol of alloc_bitmap.\n"); + return FALSE; + } + if (!readmem(VADDR_XEN, SYMBOL(alloc_bitmap), &info->alloc_bitmap, + sizeof(info->alloc_bitmap))) { + ERRMSG("Can't get the value of alloc_bitmap.\n"); + return FALSE; + } + if (SYMBOL(max_page) == NOT_FOUND_SYMBOL) { + ERRMSG("Can't get the symbol of max_page.\n"); + return FALSE; + } + if (!readmem(VADDR_XEN, SYMBOL(max_page), &info->max_page, + sizeof(info->max_page))) { + ERRMSG("Can't get the value of max_page.\n"); + return FALSE; + } } /* @@ -5503,6 +5537,8 @@ show_data_xen(void) MSG("OFFSET(domain.next_in_list): %ld\n", OFFSET(domain.next_in_list)); MSG("\n"); + MSG("xen_major_version: %lx\n", info->xen_major_version); + MSG("xen_minor_version: %lx\n", info->xen_minor_version); MSG("xen_phys_start: %lx\n", info->xen_phys_start); MSG("frame_table_vaddr: %lx\n", info->frame_table_vaddr); MSG("xen_heap_start: %lx\n", info->xen_heap_start); @@ -5640,6 +5676,12 @@ read_vmcoreinfo_xen(void) READ_MEMBER_OFFSET("page_info.count_info", page_info.count_info); READ_MEMBER_OFFSET("page_info._domain", page_info._domain); + if (info->elf_machine == EM_X86_64) { + if (info->xen_major_version < 4) { + MSG("modified offset_table.page_info._domain from %ld to 24\n", offset_table.page_info._domain); + offset_table.page_info._domain = 24; + } + } READ_MEMBER_OFFSET("domain.domain_id", domain.domain_id); READ_MEMBER_OFFSET("domain.next_in_list", domain.next_in_list); @@ -5763,6 +5805,12 @@ initial_xen(void) off_t offset; unsigned long size; + if (!get_xen_version()) + return FALSE; + if ((info->elf_machine != EM_X86_64) && (info->xen_major_version >= 4)) { + MSG("Xen major version %lu is not supported yet for this machine.\n", info->xen_major_version); + return FALSE; + } #if defined(__powerpc64__) || defined(__powerpc32__) MSG("\n"); MSG("Xen is not supported on powerpc.\n"); diff --git a/makedumpfile.h b/makedumpfile.h index 6f5489d..d8d7779 100644 --- a/makedumpfile.h +++ b/makedumpfile.h @@ -843,6 +843,7 @@ struct DumpInfo { /* * ELF header info: */ + int elf_machine; unsigned int num_load_dumpfile; size_t offset_load_dumpfile; @@ -902,6 +903,8 @@ struct DumpInfo { /* * for Xen extraction */ + unsigned long xen_major_version; + unsigned long xen_minor_version; unsigned long long dom0_mapnr; /* The number of page in domain-0. * Different from max_mapnr. * max_mapnr is the number of page -- 1.6.0.2 With kind regards Norbert Trapp PDG ES&S SWE OS 6 FUJITSU Fujitsu Technology Solutions GmbH Domagkstrasse 28, D-80807 Muenchen, Germany E-mail: Norbert.Trapp at xxxxxxxxxxxxxx Web: ts.fujitsu.com Company details: ts.fujitsu.com/imprint Please be advised that neither Fujitsu, its affiliates, its employees or agents accept liability for any errors, omissions or damages caused by delays of receipt or by any virus infection in this message or its attachments, or which may otherwise arise as a result of this e-mail transmission.