Now I can run qemu with the memory-backend-file option and use /usr/bin/crash in "live" mode using the file(s) specified by mem-path argument as a RAM dump. For example, $ qemu-kmv ...other-options... \ -object memory-backend-file,id=MEM,size=128m,mem-path=/tmp/MEM,share=on \ -numa node,memdev=MEM -m 128 and $ crash path-to-guests-vmlinux live:/tmp/MEM@0 NOTE: in this particular (and simple) case the offset is always zero. In more complex situations the ram-to-file mapping used by qemu can be nontrivial, but it is very simple to add the support for MEMORY-IMAGE@ADDRESS-LENGTH syntax. Signed-off-by: Oleg Nesterov <oleg@xxxxxxxxxx> --- defs.h | 5 +++-- filesys.c | 3 ++- main.c | 11 +++++++++++ memory.c | 1 + ramdump.c | 10 ++++++++++ 5 files changed, 27 insertions(+), 3 deletions(-) diff --git a/defs.h b/defs.h index f31d7f6..d3a03c1 100644 --- a/defs.h +++ b/defs.h @@ -212,6 +212,7 @@ struct number_option { #define DEVMEM (0x2000000ULL) #define REM_LIVE_SYSTEM (0x4000000ULL) #define NAMELIST_LOCAL (0x8000000ULL) +#define LIVEDUMP (0x10000000ULL) #define NAMELIST_SAVED (0x20000000ULL) #define DUMPFILE_SAVED (0x40000000ULL) #define UNLINK_NAMELIST (0x80000000ULL) @@ -253,8 +254,8 @@ struct number_option { #define LOCAL_ACTIVE() ((pc->flags & LIVE_SYSTEM) && (pc->flags2 & MEMSRC_LOCAL)) #define DUMPFILE() (!(pc->flags & LIVE_SYSTEM)) #define LIVE() (pc->flags2 & LIVE_DUMP || pc->flags & LIVE_SYSTEM) -#define MEMORY_SOURCES (NETDUMP|KDUMP|MCLXCD|LKCD|DEVMEM|S390D|MEMMOD|DISKDUMP|XENDUMP|CRASHBUILTIN|KVMDUMP|PROC_KCORE|SADUMP|VMWARE_VMSS) -#define DUMPFILE_TYPES (DISKDUMP|NETDUMP|KDUMP|MCLXCD|LKCD|S390D|XENDUMP|KVMDUMP|SADUMP|VMWARE_VMSS) +#define MEMORY_SOURCES (NETDUMP|KDUMP|MCLXCD|LKCD|DEVMEM|S390D|MEMMOD|DISKDUMP|XENDUMP|CRASHBUILTIN|KVMDUMP|PROC_KCORE|SADUMP|VMWARE_VMSS|LIVEDUMP) +#define DUMPFILE_TYPES (DISKDUMP|NETDUMP|KDUMP|MCLXCD|LKCD|S390D|XENDUMP|KVMDUMP|SADUMP|VMWARE_VMSS|LIVEDUMP) #define REMOTE() (pc->flags2 & REMOTE_DAEMON) #define REMOTE_ACTIVE() (pc->flags & REM_LIVE_SYSTEM) #define REMOTE_DUMPFILE() \ diff --git a/filesys.c b/filesys.c index 3b2ce05..2779b2f 100644 --- a/filesys.c +++ b/filesys.c @@ -209,7 +209,8 @@ memory_source_init(void) } if (pc->dumpfile) { - if (!file_exists(pc->dumpfile, NULL)) + if (!(pc->flags & LIVEDUMP) && + !file_exists(pc->dumpfile, NULL)) error(FATAL, "%s: %s\n", pc->dumpfile, strerror(ENOENT)); diff --git a/main.c b/main.c index a4db88d..0fbd10a 100644 --- a/main.c +++ b/main.c @@ -428,6 +428,17 @@ main(int argc, char **argv) "too many dumpfile arguments\n"); program_usage(SHORT_FORM); } + + if (ACTIVE()) { + pc->flags |= LIVEDUMP; + /* disable get_live_memory_source() logic in fd_init() */ + pc->dumpfile = "livedump"; + pc->readmem = read_ramdump; + pc->writemem = NULL; + optind++; + continue; + } + pc->dumpfile = ramdump_to_elf(); if (is_kdump(pc->dumpfile, KDUMP_LOCAL)) { pc->flags |= KDUMP; diff --git a/memory.c b/memory.c index 693516e..3339aa2 100644 --- a/memory.c +++ b/memory.c @@ -16463,6 +16463,7 @@ memory_page_size(void) case CRASHBUILTIN: case KVMDUMP: case PROC_KCORE: + case LIVEDUMP: psz = (uint)getpagesize(); break; diff --git a/ramdump.c b/ramdump.c index c6a8a85..12bfe05 100644 --- a/ramdump.c +++ b/ramdump.c @@ -232,14 +232,21 @@ end: return e_file; } +#define PREFIX(ptr, pat) \ + (strncmp((ptr), (pat), sizeof(pat)-1) ? 0 : \ + ((ptr) += sizeof(pat)-1, 1)) + int is_ramdump(char *p) { char *x = NULL, *y = NULL, *pat; size_t len; char *pattern; struct stat64 st; + int is_live = 0; int err = 0; + is_live = PREFIX(p, "live:"); + if (nodes || !strchr(p, '@')) return 0; @@ -276,6 +283,9 @@ int is_ramdump(char *p) pat = NULL; } + if (nodes && is_live) + pc->flags |= LIVE_SYSTEM; + return nodes; } -- 2.5.0 -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility