From: Cliff Wickman <[email protected]>

makedumpfile needs the debug info from either /proc/vmcore or in vmlinux
to know how to find free pages using the buddy method.

The distro procedures do not pass the vmlinux (with the -x option), so
add a search for a debug vmlinux in the usual locations.
It's not needed if the page info is in vmcore.  But warn if it is found
in neither place.

Diffed against makedumpfile-1.5.4
Signed-off-by: Cliff Wickman <[email protected]>
---
 makedumpfile.c |   97 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 97 insertions(+)

Index: makedumpfile-1.5.4/makedumpfile.c
===================================================================
--- makedumpfile-1.5.4.orig/makedumpfile.c
+++ makedumpfile-1.5.4/makedumpfile.c
@@ -23,6 +23,7 @@
 #include <stddef.h>
 #include <ctype.h>
 #include <sys/time.h>
+#include <sys/stat.h>
 
 struct symbol_table    symbol_table;
 struct size_table      size_table;
@@ -33,6 +34,7 @@ struct srcfile_table  srcfile_table;
 
 struct vm_table                vt = { 0 };
 struct DumpInfo                *info = NULL;
+struct utsname         utsname;
 
 char filename_stdout[] = FILENAME_STDOUT;
 
@@ -62,6 +64,7 @@ unsigned long long num_dumped;
 int retcd = FAILED;    /* return code */
 int aflag = 0;
 int total_cycles = 0;
+static int no_vmlinux;
 
 #define INITIALIZE_LONG_TABLE(table, value) \
 do { \
@@ -2987,6 +2990,9 @@ initial(void)
                if (!read_vmcoreinfo_from_vmcore(offset, size, FALSE))
                        return FALSE;
                debug_info = TRUE;
+               if ((OFFSET(page.private) == NOT_FOUND_STRUCTURE) &&
+                   no_vmlinux)
+                       PROGRESS_MSG("No vmlinux and no page info in vmcore\n");
        }
 
 out:
@@ -7799,6 +7805,7 @@ create_dumpfile(void)
                return FALSE;
 
        if (!info->flag_refiltering && !info->flag_sadump) {
+               /* cpw: we get debug info from /proc/vmcore here */
                if (!get_elf_info(info->fd_memory, info->name_memory))
                        return FALSE;
        }
@@ -8740,6 +8747,91 @@ static struct option longopts[] = {
        {0, 0, 0, 0}
 };
 
+/*
+ * Look for a debug vmlinux in the usual places.
+ */
+void
+find_vmlinux()
+{
+       int ret;
+       char pathname[200];
+       struct stat stat_buf;
+
+       ret = uname(&utsname);
+       if (ret < 0) {
+               fprintf(stderr, "uname failed; errno %d", errno);
+       }
+
+       /* these may work if the crash kernel is in multi-user mode */
+       sprintf(pathname, "/usr/lib/debug/lib/modules/%s/vmlinux",
+               utsname.release);
+       if (stat(pathname, &stat_buf) == 0) {
+               info->name_vmlinux = pathname;
+               PROGRESS_MSG("Using %s.\n", pathname);
+               return;
+       }
+       sprintf(pathname, "/usr/lib/debug/boot/vmlinux-%s.debug",
+               utsname.release);
+       if (stat(pathname, &stat_buf) == 0) {
+               info->name_vmlinux = pathname;
+               PROGRESS_MSG("Using %s.\n", pathname);
+               return;
+       }
+       sprintf(pathname, "/boot/vmlinux-%s", utsname.release);
+       if (stat(pathname, &stat_buf) == 0) {
+               info->name_vmlinux = pathname;
+               PROGRESS_MSG("Using %s.\n", pathname);
+               return;
+       }
+
+       /*
+        * the crash kernel normally runs with the root device mounted
+        * as /root or /mnt
+        */
+       sprintf(pathname, "/root/usr/lib/debug/lib/modules/%s/vmlinux",
+               utsname.release);
+       if (stat(pathname, &stat_buf) == 0) {
+               info->name_vmlinux = pathname;
+               PROGRESS_MSG("Using %s.\n", pathname);
+               return;
+       }
+       sprintf(pathname, "/root/usr/lib/debug/boot/vmlinux-%s.debug",
+               utsname.release);
+       if (stat(pathname, &stat_buf) == 0) {
+               info->name_vmlinux = pathname;
+               PROGRESS_MSG("Using %s.\n", pathname);
+               return;
+       }
+       sprintf(pathname, "/root/boot/vmlinux-%s", utsname.release);
+       if (stat(pathname, &stat_buf) == 0) {
+               info->name_vmlinux = pathname;
+               PROGRESS_MSG("Using %s.\n", pathname);
+               return;
+       }
+       sprintf(pathname, "/mnt/usr/lib/debug/lib/modules/%s/vmlinux",
+               utsname.release);
+       if (stat(pathname, &stat_buf) == 0) {
+               info->name_vmlinux = pathname;
+               PROGRESS_MSG("Using %s.\n", pathname);
+               return;
+       }
+       sprintf(pathname, "/mnt/usr/lib/debug/boot/vmlinux-%s.debug",
+               utsname.release);
+       if (stat(pathname, &stat_buf) == 0) {
+               info->name_vmlinux = pathname;
+               PROGRESS_MSG("Using %s.\n", pathname);
+               return;
+       }
+       sprintf(pathname, "/mnt/boot/vmlinux-%s", utsname.release);
+       if (stat(pathname, &stat_buf) == 0) {
+               info->name_vmlinux = pathname;
+               PROGRESS_MSG("Using %s.\n", pathname);
+               return;
+       }
+
+       no_vmlinux = 1;
+}
+
 int
 main(int argc, char *argv[])
 {
@@ -8888,6 +8980,11 @@ main(int argc, char *argv[])
        if (flag_debug)
                message_level |= ML_PRINT_DEBUG_MSG;
 
+       if (!info->flag_read_vmcoreinfo && !info->name_vmlinux) {
+               /* -x not specified, so look in standard places */
+               find_vmlinux();
+       }
+
        if (info->flag_show_usage) {
                print_usage();
                return COMPLETED;

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

Reply via email to