With this change /usr/bin/crash will try to work with ramdump files without
creating the temporary KDUMP elf header if MEMORY-IMAGE starts with the "raw:"
prefix. This looks useful to me, especially because ramdump_to_elf() doesn't
support x86-64.

For example, I am running qemu with

        -object memory-backend-file,id=MEM,size=128m,mem-path=/tmp/MEM,share=on
        -numa node,memdev=MEM

options and after I crash the kernel (/bin/bash running as "init" exits)

        $ ./crash ../VMLINUX raw:/tmp/MEM@0

reports:

              KERNEL: ../VMLINUX
           DUMPFILES: ramdump [raw]
                      /tmp/MEM
                CPUS: 2 [OFFLINE: 1]
                DATE: Mon Apr 25 11:47:26 2016
              UPTIME: 00:00:07
        LOAD AVERAGE: 0.00, 0.00, 0.00
               TASKS: 45
            NODENAME: (none)
             RELEASE: 3.10.0+
             VERSION: #42 SMP Sun Apr 3 17:09:09 CEST 2016
             MACHINE: x86_64  (2593 Mhz)
              MEMORY: 127.5 MB
               PANIC: "Kernel panic - not syncing: Attempted to kill init! 
exitcode=0x00000000"
                 PID: 1
             COMMAND: "bash"
                TASK: ffff880007150000  [THREAD_INFO: ffff880007158000]
                 CPU: 0
               STATE: TASK_RUNNING (PANIC)

        crash> bt
        PID: 1      TASK: ffff880007150000  CPU: 0   COMMAND: "bash"
         #0 [ffff88000715bc28] __schedule at ffffffff816801c0
         #1 [ffff88000715bc40] __module_text_address at ffffffff810ef782
         #2 [ffff88000715bc58] is_module_text_address at ffffffff810f625e
         #3 [ffff88000715bc68] __kernel_text_address at ffffffff810a85ad
         #4 [ffff88000715bc80] print_context_stack at ffffffff810174e3
         #5 [ffff88000715bce0] dump_trace at ffffffff81016391
         #6 [ffff88000715bd60] show_trace_log_lvl at ffffffff810176ad
         #7 [ffff88000715bda8] up at ffffffff810b1cf2
         #8 [ffff88000715bdc8] console_unlock at ffffffff8108137e
         #9 [ffff88000715be08] i8042_panic_blink at ffffffff814c362d
        #10 [ffff88000715be28] panic at ffffffff81679de0
        #11 [ffff88000715beb0] do_exit at ffffffff810870ff
        #12 [ffff88000715bf40] do_group_exit at ffffffff81087183
        #13 [ffff88000715bf70] sys_exit_group at ffffffff81087204
        #14 [ffff88000715bf80] system_call_fastpath at ffffffff8168ba89
            RIP: 00007f2493bdaaf8  RSP: 00007fff2ae49ee8  RFLAGS: 00010206
            RAX: 00000000000000e7  RBX: ffffffff8168ba89  RCX: 0000000000000000
            RDX: 0000000000000000  RSI: 000000000000003c  RDI: 0000000000000000
            RBP: 00007f2493ec98b8   R8: 00000000000000e7   R9: ffffffffffffff98
            R10: 00007f24934dcd98  R11: 0000000000000246  R12: ffffffff81087204
            R13: ffff88000715bf78  R14: 0000000000000000  R15: 00007f2493ecec60
            ORIG_RAX: 00000000000000e7  CS: 0033  SS: 002b

and everything else seems to work too.

Note:

        - The usage of CRASHBUILTIN doesn't look nice, we need to cleanup
          this logic. I hope we can do this later, and it seems to me that
          the usage of MEMORY_SOURCES/DUMPFILE_TYPES needs some cleanups in
          any case.

        - I can't verify this because x86-64 is not supported, but afaics
          the current usage of RAMDUMP/is_ramdump_image/read_ramdump is not
          right. RAMDUMP should be always set if is_ramdump() returns true,
          and read_ramdump() should not be used if we set KDUMP.

          But I can't test this, so the patch adds another is_ramdump_image()
          block before ramdump_to_elf(). Which obviously asks for cleanup too.

Signed-off-by: Oleg Nesterov <[email protected]>
---
 filesys.c |  2 +-
 main.c    | 11 +++++++++++
 ramdump.c | 21 ++++++++++++++++++++-
 3 files changed, 32 insertions(+), 2 deletions(-)

diff --git a/filesys.c b/filesys.c
index de04486..a1d1d1e 100644
--- a/filesys.c
+++ b/filesys.c
@@ -207,7 +207,7 @@ memory_source_init(void)
                return;
         } 
 
-       if (pc->dumpfile) {
+       if (pc->dumpfile && !(pc->flags & CRASHBUILTIN)) {
                if (!file_exists(pc->dumpfile, NULL))
                        error(FATAL, "%s: %s\n", pc->dumpfile, 
                                strerror(ENOENT));
diff --git a/main.c b/main.c
index 821bb4e..9b72c7e 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 (is_ramdump_image()) {
+                               /*
+                                * FIXME: we set CRASHBUILTIN to tell 
memory_source_init()
+                                * it should ignore pc->dumpfile and for 
memory_page_size().
+                                */
+                               pc->flags |= CRASHBUILTIN;
+                               optind++;
+                               continue;
+                       }
+
                        pc->dumpfile = ramdump_to_elf();
                        if (is_kdump(pc->dumpfile, KDUMP_LOCAL)) {
                                pc->flags |= KDUMP;
diff --git a/ramdump.c b/ramdump.c
index c6a8a85..e9716ae 100644
--- a/ramdump.c
+++ b/ramdump.c
@@ -232,14 +232,22 @@ 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_raw = 0;
        int err = 0;
 
+       if (PREFIX(p, "raw:"))
+               is_raw = 1;
+
        if (nodes || !strchr(p, '@'))
                return 0;
 
@@ -276,6 +284,13 @@ int is_ramdump(char *p)
                pat = NULL;
        }
 
+       if (nodes && is_raw) {
+               pc->flags2 |= RAMDUMP;
+               /* also disables get_live_memory_source() logic in fd_init() */
+               pc->dumpfile = "ramdump";
+               pc->readmem = read_ramdump;
+               pc->writemem = NULL;
+       }
        return nodes;
 }
 
@@ -345,7 +360,11 @@ show_ramdump_files(void)
 {
        int i;
 
-       fprintf(fp, "%s [temporary ELF header]\n", elf_default);
+       if (pc->flags & KDUMP)
+               fprintf(fp, "%s [temporary ELF header]\n", elf_default);
+       else
+               fprintf(fp, "%s [raw]\n", pc->dumpfile);
+
        for (i = 0; i < nodes; i++) {
                fprintf(fp, "%s              %s", 
                        i ? "\n" : "", ramdump[i].path);
-- 
2.5.0

--
Crash-utility mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/crash-utility

Reply via email to