Fix for the support of compressed kdump clones created with the KVM

"virsh dump --memory-only --format <compression-type>" command,
where the compression-type is either "kdump-zlib", "kdump-lzo" or
"kdump-snappy".  Without the patch, if an x86_64 guest kernel was loaded
with a non-zero "phys_base", the "--machdep phys_base=<offset>" command
line option was required as a workaround or the crash session would fail
with the warning message "WARNING: cannot read linux_banner string"
followed by the fatal error message "crash: vmlinux and <dumpfile name>
do not match!".
(anderson@redhat.com)
This commit is contained in:
Dave Anderson 2014-11-13 14:40:54 -05:00
parent c964753dde
commit 51e17d89d7
7 changed files with 25 additions and 12 deletions

3
defs.h
View File

@ -499,7 +499,7 @@ struct program_context {
#define FLAT_FORMAT() (pc->flags2 & FLAT)
#define ELF_NOTES_VALID() (pc->flags2 & ELF_NOTES)
#define RADIX_OVERRIDE (0x80ULL)
#define QEMU_MEM_DUMP (0x100ULL)
#define QEMU_MEM_DUMP_ELF (0x100ULL)
#define GET_LOG (0x200ULL)
#define VMCOREINFO (0x400ULL)
#define ALLOW_FP (0x800ULL)
@ -509,6 +509,7 @@ struct program_context {
#define OFFLINE_HIDE (0x4000ULL)
#define INCOMPLETE_DUMP (0x8000ULL)
#define is_incomplete_dump() (pc->flags2 & INCOMPLETE_DUMP)
#define QEMU_MEM_DUMP_COMPRESSED (0x10000ULL)
char *cleanup;
char *namelist_orig;
char *namelist_debug_orig;

View File

@ -249,11 +249,13 @@ process_elf32_notes(void *note_buf, unsigned long size_note)
for (index = 0; index < size_note; index += len) {
nt = note_buf + index;
if(nt->n_type == NT_PRSTATUS) {
if (nt->n_type == NT_PRSTATUS) {
dd->nt_prstatus_percpu[num] = nt;
num++;
}
len = sizeof(Elf32_Nhdr);
if (STRNEQ((char *)nt + len, "QEMU"))
pc->flags2 |= QEMU_MEM_DUMP_COMPRESSED;
len = roundup(len + nt->n_namesz, 4);
len = roundup(len + nt->n_descsz, 4);
}
@ -275,11 +277,13 @@ process_elf64_notes(void *note_buf, unsigned long size_note)
for (index = 0; index < size_note; index += len) {
nt = note_buf + index;
if(nt->n_type == NT_PRSTATUS) {
if (nt->n_type == NT_PRSTATUS) {
dd->nt_prstatus_percpu[num] = nt;
num++;
}
len = sizeof(Elf64_Nhdr);
if (STRNEQ((char *)nt + len, "QEMU"))
pc->flags2 |= QEMU_MEM_DUMP_COMPRESSED;
len = roundup(len + nt->n_namesz, 4);
len = roundup(len + nt->n_descsz, 4);
}

2
help.c
View File

@ -688,7 +688,7 @@ cmd_help(void)
static void
dump_registers(void)
{
if (pc->flags2 & QEMU_MEM_DUMP) {
if (pc->flags2 & QEMU_MEM_DUMP_ELF) {
dump_registers_for_qemu_mem_dump();
return;
} else if (DISKDUMP_DUMPFILE()) {

6
main.c
View File

@ -1401,8 +1401,10 @@ dump_program_context(void)
fprintf(fp, "%sLIVE_DUMP", others++ ? "|" : "");
if (pc->flags2 & RADIX_OVERRIDE)
fprintf(fp, "%sRADIX_OVERRIDE", others++ ? "|" : "");
if (pc->flags2 & QEMU_MEM_DUMP)
fprintf(fp, "%sQEMU_MEM_DUMP", others++ ? "|" : "");
if (pc->flags2 & QEMU_MEM_DUMP_ELF)
fprintf(fp, "%sQEMU_MEM_DUMP_ELF", others++ ? "|" : "");
if (pc->flags2 & QEMU_MEM_DUMP_COMPRESSED)
fprintf(fp, "%sQEMU_MEM_DUMP_COMPRESSED", others++ ? "|" : "");
if (pc->flags2 & GET_LOG)
fprintf(fp, "%sGET_LOG", others++ ? "|" : "");
if (pc->flags2 & VMCOREINFO)

View File

@ -1883,7 +1883,7 @@ dump_Elf32_Nhdr(Elf32_Off offset, int store)
netdump_print("(?)\n");
if (qemuinfo)
pc->flags2 |= QEMU_MEM_DUMP;
pc->flags2 |= QEMU_MEM_DUMP_ELF;
break;
case NT_XEN_KDUMP_CR3:
@ -2163,7 +2163,7 @@ dump_Elf64_Nhdr(Elf64_Off offset, int store)
netdump_print("(?)\n");
if (qemuinfo)
pc->flags2 |= QEMU_MEM_DUMP;
pc->flags2 |= QEMU_MEM_DUMP_ELF;
break;
case NT_XEN_KDUMP_CR3:
@ -3939,7 +3939,7 @@ kdump_backup_region_init(void)
sd = get_sadump_data();
is_32_bit = FALSE;
sprintf(typename, "sadump");
} else if (pc->flags2 & QEMU_MEM_DUMP) {
} else if (pc->flags2 & QEMU_MEM_DUMP_ELF) {
vd = get_kdump_vmcore_data();
if (vd->flags & KDUMP_ELF32)
is_32_bit = TRUE;
@ -4122,7 +4122,7 @@ kdump_backup_region_init(void)
sd->backup_src_start = backup_src_start;
sd->backup_src_size = backup_src_size;
sd->backup_offset = backup_offset;
} else if (pc->flags2 & QEMU_MEM_DUMP) {
} else if (pc->flags2 & QEMU_MEM_DUMP_ELF) {
vd->flags |= QEMU_MEM_DUMP_KDUMP_BACKUP;
vd->backup_src_start = backup_src_start;
vd->backup_src_size = backup_src_size;

2
task.c
View File

@ -483,7 +483,7 @@ task_init(void)
tt->this_task = pid_to_task(active_pid);
}
else {
if (KDUMP_DUMPFILE() && !(pc->flags2 & QEMU_MEM_DUMP))
if (KDUMP_DUMPFILE() && !(pc->flags2 & QEMU_MEM_DUMP_ELF))
map_cpus_to_prstatus();
else if (ELF_NOTES_VALID() && DISKDUMP_DUMPFILE())
map_cpus_to_prstatus_kdump_cmprs();

View File

@ -6039,6 +6039,12 @@ x86_64_calc_phys_base(void)
if (DISKDUMP_DUMPFILE()) {
if (diskdump_phys_base(&phys_base)) {
machdep->machspec->phys_base = phys_base;
if ((pc->flags2 & QEMU_MEM_DUMP_COMPRESSED) &&
!x86_64_virt_phys_base())
error(WARNING,
"cannot determine physical base address:"
" defaulting to %lx\n\n",
machdep->machspec->phys_base);
if (CRASHDEBUG(1))
fprintf(fp, "compressed kdump: phys_base: %lx\n",
phys_base);
@ -6099,7 +6105,7 @@ x86_64_calc_phys_base(void)
}
}
if ((pc->flags2 & QEMU_MEM_DUMP) && !x86_64_virt_phys_base())
if ((pc->flags2 & QEMU_MEM_DUMP_ELF) && !x86_64_virt_phys_base())
error(WARNING,
"cannot determine physical base address:"
" defaulting to %lx\n\n",