[Crash-utility] [PATCH v2 10/10] teach crash to accept live:MEMORY-IMAGE[@ADDRESS]

Oleg Nesterov oleg at redhat.com
Fri Apr 29 16:22:36 UTC 2016


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 at 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 at ADDRESS-LENGTH syntax.

Signed-off-by: Oleg Nesterov <oleg at redhat.com>
---
 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




More information about the Crash-utility mailing list