Enhance help -D to parse NT_VMCOREDD ELF notes present in KDUMP vmcore.
Example:
crash> help -D
[...]
num_vmcoredd_notes: 2
notes[0]: 7ff9a578d010 (NT_VMCOREDD)
name: "cxgb4_0000:02:00.4"
size: 33558464
notes[1]: 7ff9a778e010 (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>
---
rfc:
- No changes.
diskdump.c | 38 ++++++++++++++++++++++++++++++++++++++
1 file changed, 38 insertions(+)
diff --git a/diskdump.c b/diskdump.c
index 8085712..6b7a91b 100644
--- a/diskdump.c
+++ b/diskdump.c
@@ -26,6 +26,7 @@
#include "defs.h"
#include "diskdump.h"
#include "xen_dom0.h"
+#include "vmcore.h"
#define BITMAP_SECT_LEN 4096
@@ -58,6 +59,8 @@ struct diskdump_data {
void **nt_qemu_percpu;
void **nt_qemucs_percpu;
uint num_qemu_notes;
+ void **nt_vmcoredd_array;
+ uint num_vmcoredd_notes;
/* page cache */
struct page_cache_hdr { /* header for each cached page */
@@ -279,6 +282,7 @@ process_elf32_notes(void *note_buf, unsigned long size_note)
Elf32_Nhdr *nt;
size_t index, len = 0;
int num = 0;
+ int vmcoredd_num = 0;
int qemu_num = 0;
for (index = 0; index < size_note; index += len) {
@@ -304,6 +308,12 @@ process_elf32_notes(void *note_buf, unsigned long size_note)
process_xen_note(nt->n_type, data, nt->n_descsz);
}
+ if (nt->n_type == NT_VMCOREDD &&
+ vmcoredd_num < NR_DEVICE_DUMPS) {
+ dd->nt_vmcoredd_array[vmcoredd_num] = nt;
+ vmcoredd_num++;
+ }
+
len = roundup(len + nt->n_namesz, 4);
len = roundup(len + nt->n_descsz, 4);
}
@@ -317,6 +327,9 @@ process_elf32_notes(void *note_buf, unsigned long size_note)
pc->flags2 |= QEMU_MEM_DUMP_COMPRESSED;
dd->num_qemu_notes = qemu_num;
}
+ if (vmcoredd_num > 0)
+ dd->num_vmcoredd_notes = vmcoredd_num;
+
return;
}
@@ -326,6 +339,7 @@ process_elf64_notes(void *note_buf, unsigned long size_note)
Elf64_Nhdr *nt;
size_t index, len = 0;
int num = 0;
+ int vmcoredd_num = 0;
int qemu_num = 0;
for (index = 0; index < size_note; index += len) {
@@ -357,6 +371,12 @@ process_elf64_notes(void *note_buf, unsigned long size_note)
process_xen_note(nt->n_type, data, nt->n_descsz);
}
+ if (nt->n_type == NT_VMCOREDD &&
+ vmcoredd_num < NR_DEVICE_DUMPS) {
+ dd->nt_vmcoredd_array[vmcoredd_num] = nt;
+ vmcoredd_num++;
+ }
+
len = roundup(len + nt->n_namesz, 4);
len = roundup(len + nt->n_descsz, 4);
}
@@ -370,6 +390,9 @@ process_elf64_notes(void *note_buf, unsigned long size_note)
pc->flags2 |= QEMU_MEM_DUMP_COMPRESSED;
dd->num_qemu_notes = qemu_num;
}
+ if (vmcoredd_num > 0)
+ dd->num_vmcoredd_notes = vmcoredd_num;
+
return;
}
@@ -778,6 +801,10 @@ restart:
error(FATAL, "qemu mem dump compressed: cannot malloc pointer"
" to QEMUCS notes\n");
+ if ((dd->nt_vmcoredd_array = malloc(NR_DEVICE_DUMPS * sizeof(void *))) == NULL)
+ error(FATAL, "compressed kdump: cannot malloc array for "
+ "vmcore device dump notes\n");
+
if (FLAT_FORMAT()) {
if (!read_flattened_format(dd->dfd, offset, dd->notes_buf, size)) {
error(INFO, "compressed kdump: cannot read notes data"
@@ -875,6 +902,8 @@ err:
free(dd->nt_qemu_percpu);
if (dd->nt_qemucs_percpu)
free(dd->nt_qemucs_percpu);
+ if (dd->nt_vmcoredd_array)
+ free(dd->nt_vmcoredd_array);
dd->flags &= ~(DISKDUMP_LOCAL|KDUMP_CMPRS_LOCAL);
pc->flags2 &= ~ELF_NOTES;
@@ -1948,6 +1977,15 @@ __diskdump_memory_dump(FILE *fp)
dd->sub_header_kdump->size_note);
fprintf(fp, " notes_buf: %lx\n",
(ulong)dd->notes_buf);
+ fprintf(fp, " num_vmcoredd_notes: %d\n",
+ dd->num_vmcoredd_notes);
+ for (i = 0; i < dd->num_vmcoredd_notes; i++) {
+ fprintf(fp, " notes[%d]: %lx %s\n",
+ i, (ulong)dd->nt_vmcoredd_array[i],
+ dd->nt_vmcoredd_array[i] ? "(NT_VMCOREDD)" : "");
+ display_vmcoredd_note(dd->nt_vmcoredd_array[i], fp);
+ }
+
fprintf(fp, " num_prstatus_notes: %d\n",
dd->num_prstatus_notes);
for (i = 0; i < dd->num_prstatus_notes; i++) {
--
2.21.0