Enhance help -D to parse NT_VMCOREDD ELF notes present in ELF vmcore. Example: crash> help -D [...] Elf64_Nhdr: n_namesz: 8 ("LINUX") n_descsz: 33558508 n_type: 700 (NT_VMCOREDD) name: "cxgb4_0000:02:00.4" size: 33558464 Elf64_Nhdr: n_namesz: 8 ("LINUX") n_descsz: 33558508 n_type: 700 (NT_VMCOREDD) name: "cxgb4_0000:03:00.4" size: 33558464 [...] Signed-off-by: Surendra Mobiya <surendra@xxxxxxxxxxx> Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@xxxxxxxxxxx> --- rfc: - No changes. defs.h | 3 +++ netdump.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++-- netdump.h | 3 +++ vmcore.h | 36 ++++++++++++++++++++++++++++++++++++ 4 files changed, 89 insertions(+), 2 deletions(-) create mode 100644 vmcore.h diff --git a/defs.h b/defs.h index 2466681..0925a46 100644 --- a/defs.h +++ b/defs.h @@ -148,6 +148,8 @@ #define NR_CPUS (4096) #endif +#define NR_DEVICE_DUMPS (64) + /* Some architectures require memory accesses to be aligned. */ #if defined(SPARC64) #define NEED_ALIGNED_MEM_ACCESS @@ -6396,6 +6398,7 @@ void display_regs_from_elf_notes(int, FILE *); void display_ELF_note(int, int, void *, FILE *); void *netdump_get_prstatus_percpu(int); int kdump_kaslr_check(void); +void display_vmcoredd_note(void *ptr, FILE *ofp); QEMUCPUState *kdump_get_qemucpustate(int); #define PRSTATUS_NOTE (1) #define QEMU_NOTE (2) diff --git a/netdump.c b/netdump.c index 96d1e86..c4e9b3e 100644 --- a/netdump.c +++ b/netdump.c @@ -1898,6 +1898,21 @@ vmcoreinfo_read_integer(const char *key, long default_value) return retval; } +void +display_vmcoredd_note(void *ptr, FILE *ofp) +{ + int sp; + unsigned int dump_size; + struct vmcoredd_header *vh; + + sp = VMCORE_VALID() ? 25 : 22; + vh = (struct vmcoredd_header *)ptr; + + dump_size = vh->n_descsz - VMCOREDD_MAX_NAME_BYTES; + fprintf(ofp, "%sname: \"%s\"\n", space(sp), vh->dump_name); + fprintf(ofp, "%ssize: %u\n", space(sp), dump_size); +} + /* * Dump a note section header -- the actual data is defined by netdump */ @@ -2002,6 +2017,18 @@ dump_Elf32_Nhdr(Elf32_Off offset, int store) } break; #endif + case NT_VMCOREDD: + netdump_print("(NT_VMCOREDD)\n"); + if (store) { + for (i = 0; i < NR_DEVICE_DUMPS; i++) { + if (!nd->nt_vmcoredd_array[i]) { + nd->nt_vmcoredd_array[i] = (void *)note; + nd->num_vmcoredd_notes++; + break; + } + } + } + break; default: xen_core = STRNEQ(buf, "XEN CORE") || STRNEQ(buf, "Xen"); if (STRNEQ(buf, "VMCOREINFO_XEN")) @@ -2092,6 +2119,9 @@ dump_Elf32_Nhdr(Elf32_Off offset, int store) netdump_print(" "); } lf = 0; + } else if (note->n_type == NT_VMCOREDD) { + if (nd->ofp) + display_vmcoredd_note(note, nd->ofp); } else { if (nd->ofp && !XEN_CORE_DUMPFILE() && !(pc->flags2 & LIVE_DUMP)) { if (machine_type("X86")) { @@ -2126,7 +2156,7 @@ dump_Elf32_Nhdr(Elf32_Off offset, int store) static size_t dump_Elf64_Nhdr(Elf64_Off offset, int store) { - int i, lf; + int i = 0, lf = 0; Elf64_Nhdr *note; size_t len; char buf[BUFSIZE]; @@ -2271,6 +2301,18 @@ dump_Elf64_Nhdr(Elf64_Off offset, int store) } break; #endif + case NT_VMCOREDD: + netdump_print("(NT_VMCOREDD)\n"); + if (store) { + for (i = 0; i < NR_DEVICE_DUMPS; i++) { + if (!nd->nt_vmcoredd_array[i]) { + nd->nt_vmcoredd_array[i] = (void *)note; + nd->num_vmcoredd_notes++; + break; + } + } + } + break; default: xen_core = STRNEQ(buf, "XEN CORE") || STRNEQ(buf, "Xen"); if (STRNEQ(buf, "VMCOREINFO_XEN")) @@ -2364,7 +2406,10 @@ dump_Elf64_Nhdr(Elf64_Off offset, int store) } } - if (BITS32() && (xen_core || (note->n_type == NT_PRSTATUS) || qemuinfo)) { + if (note->n_type == NT_VMCOREDD) { + if (nd->ofp) + display_vmcoredd_note(note, nd->ofp); + } else if (BITS32() && (xen_core || (note->n_type == NT_PRSTATUS) || qemuinfo)) { if (nd->ofp && !XEN_CORE_DUMPFILE() && !(pc->flags2 & LIVE_DUMP)) { if (machine_type("X86")) { if (note->n_type == NT_PRSTATUS) diff --git a/netdump.h b/netdump.h index 1aeeaae..5f49c02 100644 --- a/netdump.h +++ b/netdump.h @@ -17,6 +17,7 @@ */ #include <elf.h> +#include "vmcore.h" #define MIN_NETDUMP_ELF32_HEADER_SIZE \ sizeof(Elf32_Ehdr)+sizeof(Elf32_Phdr)+sizeof(Elf32_Phdr) @@ -74,6 +75,8 @@ struct vmcore_data { #define KEXEC_BACKUP_SRC_END 0x0009ffff uint num_qemu_notes; void *nt_qemu_percpu[NR_CPUS]; + void *nt_vmcoredd_array[NR_DEVICE_DUMPS]; + uint num_vmcoredd_notes; ulonglong backup_src_start; ulong backup_src_size; ulonglong backup_offset; diff --git a/vmcore.h b/vmcore.h new file mode 100644 index 0000000..69b2cae --- /dev/null +++ b/vmcore.h @@ -0,0 +1,36 @@ +/* + * vmcore.h + * + * Copyright (C) 2019 Chelsio Communications. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef _VMCORE_H +#define _VMCORE_H + +#include <linux/types.h> + +#ifndef NT_VMCOREDD +#define NT_VMCOREDD 0x700 +#endif + +#define VMCOREDD_NOTE_NAME "LINUX" +#define VMCOREDD_MAX_NAME_BYTES 44 + +struct vmcoredd_header { + __u32 n_namesz; /* Name size */ + __u32 n_descsz; /* Content size */ + __u32 n_type; /* NT_VMCOREDD */ + __u8 name[8]; /* LINUX\0\0\0 */ + __u8 dump_name[VMCOREDD_MAX_NAME_BYTES]; /* Device dump's name */ +}; + +#endif /* _VMCORE_H */ -- 2.21.0 -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility