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(a)chelsio.com>
Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy(a)chelsio.com>
---
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 */
--
1.8.3.1