Re: Crash setup!

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Jayaraman, Bhaskar wrote:
Hi i want to run crash on a dom0 or paravirtualized guest. Please let me know if there's a patch which I can include with the linux source to build the /dev/crash driver with the xen kernel. Also is there any specific way to build crash command line to be used on a xen kernel.
Any pointers to documentation also will be very useful.
Thanks in advance.
Bhaskar.

A bit of background would help here, such as what architecture, what distribution,
and what kernel version you're running with.

Since you're asking, I'm presuming that you're running with something other
than RHEL5.  But just in case you are running RHEL5, dom0 hosts and paravirtualized x86
and x86_64 guests have the /dev/crash driver built in.  So, for a live system,
either dom0 or domU, and presuming that you've got the appropriate kernel debuginfo
package installed, you can just enter:

 $ crash

and it will look for the correct vmlinux file based upon what it sees in /proc/version.
If it can't find it, you can just enter it:

 $ crash /path/to/vmlinux

For dom0/hypervisor kdumps, or for domU xendumps, you have to enter both the vmlinux and
vmcore arguments, as in:

 $ crash /path/to/vmlinux /path/to/vmcore

Also, for dom0/hypervisor kdumps, you can alternatively look at the vmcore
from the perspective of the xen hypervisor:

 $ crash /path/to/xen-syms /path/to/vmcore

Now, for architectures other than x86 and x86_64 on RHEL5, the /dev/mem driver will
most because it is not restricted to the first 256 pages (1MB).  For 32-bit kernels,
however, you will run into the /dev/mem restriction that only allows lowmem access.
But your session should come up, although it may run into some command errors if
highmem access is required for mapped virtual-to-physical address translation of
user or kernel vmalloc virtual addresses.

And then recently the upstream kernel has adopted the new CONFIG_STRICT_DEVMEM
option, which cripples the use of /dev/mem by crash in the same way that
RHEL kernels do.  If you have no control of your kernel, and it has the
CONFIG_STRICT_DEVMEM restriction, then you either have to roll your own kernel
memory access driver (like the /dev/crash driver), or if you're really adventurous,
you can write a kprobe module that modifies the return value of devmem_is_allowed().

In any case, it would be nice if the RHEL5 /dev/crash driver could be packaged
such that anybody could simply build it externally for any kernel without any modifications
to the kernel source tree -- in a similar manner to the way the kprobes developers show how
to build their modules do in the RHEL5 "Documentation/kprobes.txt" file, or in the
upstream "samples/kprobes" directory.  But the /dev/crash driver does require small
modifications to the kernel source, primarily to EXPORT_SYMBOL_GPL() the page_is_ram()
function.

I can't help much more than attaching the two patches to the RHEL5 tree that
implement the /dev/crash driver, linux-2.6-crash-driver.patch and
linux-2.6-crash-driver-xen.patch, and letting you run with them:

  $ lsdiff linux-2.6-crash-driver.patch
  linux-1050/arch/i386/mm/init.c
  linux-1050/arch/ia64/kernel/ia64_ksyms.c
  linux-1050/arch/x86_64/mm/init.c
  linux-1050/drivers/char/crash.c
  linux-1050/drivers/char/Kconfig
  linux-2.6.16.noarch/drivers/char/Makefile
  linux-1050/include/asm-i386/crash.h
  linux-1050/include/asm-ia64/crash.h
  linux-1050/include/asm-x86_64/crash.h
  $ lsdiff linux-2.6-crash-driver-xen.patch
  a/arch/i386/mm/init-xen.c
  a/arch/x86_64/mm/init-xen.c
  $

and depending upon how your distro is built, you'll need to turn on
CONFIG_CRASH so the Makefile will build it.

Note that the ia64 stuff in the patch is cruft, won't compile, and is
unnecessary since the /dev/mem driver for that architecture still works
just fine.

That all being said, if you're only dealing with x86_64, then the
simplest route would be to remove any /dev/mem restrictions, because
then that driver will also work just fine.  You can do the same for
x86, but just be aware that you may run into some bumps in the road
if you need to access any highmem physical addresses.  But the basic
crash session should come up OK.

Dave






diff -urNp --exclude-from=/home/davej/.exclude linux-1050/arch/i386/mm/init.c linux-1060/arch/i386/mm/init.c
--- linux-1050/arch/i386/mm/init.c
+++ linux-1060/arch/i386/mm/init.c
@@ -248,6 +248,8 @@ int devmem_is_allowed(unsigned long page
    return 0;
 }
 
+EXPORT_SYMBOL_GPL(page_is_ram);
+
 #ifdef CONFIG_HIGHMEM
 pte_t *kmap_pte;
 pgprot_t kmap_prot;
diff -urNp --exclude-from=/home/davej/.exclude linux-1050/arch/ia64/kernel/ia64_ksyms.c linux-1060/arch/ia64/kernel/ia64_ksyms.c
--- linux-1050/arch/ia64/kernel/ia64_ksyms.c
+++ linux-1060/arch/ia64/kernel/ia64_ksyms.c
@@ -106,6 +106,9 @@ EXPORT_SYMBOL(ia64_save_scratch_fpregs);
 #include <asm/unwind.h>
 EXPORT_SYMBOL(unw_init_running);
 
+#include <linux/efi.h>
+EXPORT_SYMBOL_GPL(efi_mem_type);
+
 #ifdef ASM_SUPPORTED
 # ifdef CONFIG_SMP
 #  if __GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 3)
diff -urNp --exclude-from=/home/davej/.exclude linux-1050/arch/x86_64/mm/init.c linux-1060/arch/x86_64/mm/init.c
--- linux-1050/arch/x86_64/mm/init.c
+++ linux-1060/arch/x86_64/mm/init.c
@@ -6,5 +6,6 @@
  */
 
+#include <linux/module.h>
 #include <linux/signal.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
@@ -417,6 +418,8 @@ int devmem_is_allowed(unsigned long page
 }
 
 
+EXPORT_SYMBOL_GPL(page_is_ram);
+
 static struct kcore_list kcore_mem, kcore_vmalloc, kcore_kernel, kcore_modules,
 			 kcore_vsyscall;
 
diff -urNp --exclude-from=/home/davej/.exclude linux-1050/drivers/char/crash.c linux-1060/drivers/char/crash.c
--- linux-1050/drivers/char/crash.c
+++ linux-1060/drivers/char/crash.c
@@ -0,0 +1,128 @@
+/*
+ *  linux/drivers/char/crash.c
+ *
+ *  Copyright (C) 2004  Dave Anderson <anderson@xxxxxxxxxx>
+ *  Copyright (C) 2004  Red Hat, Inc.
+ */
+
+/******************************************************************************
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2, or (at your option)
+ *   any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *****************************************************************************/
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/miscdevice.h>
+#include <linux/init.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/types.h>
+#include <asm/crash.h>
+
+#define CRASH_VERSION   "1.0"
+
+/*
+ *  These are the file operation functions that allow crash utility
+ *  access to physical memory.
+ */
+
+static loff_t 
+crash_llseek(struct file * file, loff_t offset, int orig)
+{
+	switch (orig) {
+	case 0:
+		file->f_pos = offset;
+		return file->f_pos;
+	case 1:
+		file->f_pos += offset;
+		return file->f_pos;
+	default:
+		return -EINVAL;
+	}
+}
+
+/*
+ *  Determine the page address for an address offset value, 
+ *  get a virtual address for it, and copy it out.
+ *  Accesses must fit within a page.
+ */
+static ssize_t
+crash_read(struct file *file, char *buf, size_t count, loff_t *poff)
+{
+	void *vaddr;
+	struct page *page;
+	u64 offset;
+	ssize_t read;
+
+	offset = *poff;
+	if (offset >> PAGE_SHIFT != (offset+count-1) >> PAGE_SHIFT) 
+		return -EINVAL;
+
+	vaddr = map_virtual(offset, &page);
+	if (!vaddr)
+		return -EFAULT;
+
+	if (copy_to_user(buf, vaddr, count)) {
+		unmap_virtual(page);
+		return -EFAULT;
+	}
+	unmap_virtual(page);
+
+	read = count;
+	*poff += read;
+	return read;
+}
+
+static struct file_operations crash_fops = {
+	.owner = THIS_MODULE,
+	.llseek = crash_llseek,
+	.read = crash_read,
+};
+
+static struct miscdevice crash_dev = {
+	MISC_DYNAMIC_MINOR,
+	"crash",
+	&crash_fops
+};
+
+static int __init
+crash_init(void)
+{
+	int ret;
+
+	ret = misc_register(&crash_dev);
+	if (ret) {
+		printk(KERN_ERR 
+		    "crash memory driver: cannot misc_register (MISC_DYNAMIC_MINOR)\n");
+		goto out;
+	}
+	
+	ret = 0;
+	printk(KERN_INFO "crash memory driver: version %s\n", CRASH_VERSION);
+out:
+	return ret;
+}
+
+static void __exit
+crash_cleanup_module(void)
+{
+	misc_deregister(&crash_dev);
+}
+
+module_init(crash_init);
+module_exit(crash_cleanup_module);
+
+MODULE_LICENSE("GPL");
diff -urNp --exclude-from=/home/davej/.exclude linux-1050/drivers/char/Kconfig linux-1060/drivers/char/Kconfig
--- linux-1050/drivers/char/Kconfig
+++ linux-1060/drivers/char/Kconfig
@@ -441,6 +441,8 @@ config LEGACY_PTYS
 	  security.  This option enables these legacy devices; on most
 	  systems, it is safe to say N.
 
+config CRASH
+        tristate "Crash Utility memory driver"
 
 config LEGACY_PTY_COUNT
 	int "Maximum number of legacy PTY in use"
--- linux-2.6.16.noarch/drivers/char/Makefile~	2006-03-25 18:50:42.000000000 -0500
+++ linux-2.6.16.noarch/drivers/char/Makefile	2006-03-25 18:50:59.000000000 -0500
@@ -95,6 +95,7 @@ obj-$(CONFIG_IPMI_HANDLER)	+= ipmi/
 
 obj-$(CONFIG_HANGCHECK_TIMER)	+= hangcheck-timer.o
 obj-$(CONFIG_TCG_TPM)		+= tpm/
+obj-$(CONFIG_CRASH)		+= crash.o
 
 # Files generated that shall be removed upon make clean
 clean-files := consolemap_deftbl.c defkeymap.c qtronixmap.c
diff -urNp --exclude-from=/home/davej/.exclude linux-1050/include/asm-i386/crash.h linux-1060/include/asm-i386/crash.h
--- linux-1050/include/asm-i386/crash.h
+++ linux-1060/include/asm-i386/crash.h
@@ -0,0 +1,75 @@
+#ifndef _ASM_I386_CRASH_H
+#define _ASM_I386_CRASH_H
+
+/*
+ * linux/include/asm-i386/crash.h
+ *
+ * Copyright (c) 2004 Red Hat, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifdef __KERNEL__
+
+#include <linux/mm.h>
+#include <linux/highmem.h>
+#include <asm/mmzone.h>
+
+extern int page_is_ram(unsigned long);
+
+static inline void *
+map_virtual(u64 offset, struct page **pp)
+{
+	struct page *page;
+	unsigned long pfn;
+	void *vaddr;
+
+	pfn = (unsigned long)(offset >> PAGE_SHIFT);
+
+	if (!page_is_ram(pfn)) {
+		printk(KERN_INFO
+		    "crash memory driver: !page_is_ram(pfn: %lx)\n", pfn);
+		return NULL;
+	}
+
+	if (!pfn_valid(pfn)) {
+		printk(KERN_INFO
+		    "crash memory driver: invalid pfn: %lx )\n", pfn);
+		return NULL;
+	}
+
+	page = pfn_to_page(pfn);
+
+	vaddr = kmap(page);
+	if (!vaddr) {
+		printk(KERN_INFO
+		    "crash memory driver: pfn: %lx kmap(page: %lx) failed\n", 
+			pfn, (unsigned long)page);
+		return NULL;
+	}
+
+	*pp = page;
+	return (vaddr + (offset & (PAGE_SIZE-1)));
+}
+
+static inline void unmap_virtual(struct page *page) 
+{ 
+	kunmap(page);
+}
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_I386_CRASH_H */
diff -urNp --exclude-from=/home/davej/.exclude linux-1050/include/asm-ia64/crash.h linux-1060/include/asm-ia64/crash.h
--- linux-1050/include/asm-ia64/crash.h
+++ linux-1060/include/asm-ia64/crash.h
@@ -0,0 +1,90 @@
+#ifndef _ASM_IA64_CRASH_H
+#define _ASM_IA64_CRASH_H
+
+/*
+ * linux/include/asm-ia64/crash.h
+ *
+ * Copyright (c) 2004 Red Hat, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifdef __KERNEL__
+
+#include <linux/efi.h>
+#include <linux/mm.h>
+#include <asm/mmzone.h>
+
+static inline void *
+map_virtual(u64 offset, struct page **pp)
+{
+	struct page *page;
+	unsigned long pfn;
+	u32 type;
+
+	if (REGION_NUMBER(offset) == 5) {
+		char byte;
+
+		if (__get_user(byte, (char *)offset) == 0)
+			return (void *)offset;
+		else
+			return NULL;
+	}
+
+	switch (type = efi_mem_type(offset)) 
+	{
+	case EFI_LOADER_CODE:
+	case EFI_LOADER_DATA:
+	case EFI_BOOT_SERVICES_CODE:
+	case EFI_BOOT_SERVICES_DATA:
+	case EFI_CONVENTIONAL_MEMORY:
+		break;
+
+	default:
+		printk(KERN_INFO
+		    "crash memory driver: invalid memory type for %lx: %d\n", 
+			offset, type);
+		return NULL;
+	}
+
+	pfn = offset >> PAGE_SHIFT;
+
+	if (!pfn_valid(pfn)) {
+		printk(KERN_INFO
+			"crash memory driver: invalid pfn: %lx )\n", pfn);
+		return NULL;
+	}
+
+	page = pfn_to_page(pfn);
+
+	if (!page->virtual) {
+		printk(KERN_INFO
+		    "crash memory driver: offset: %lx page: %lx page->virtual: NULL\n", 
+			offset, (unsigned long)page);
+		return NULL;
+	}
+
+	return (page->virtual + (offset & (PAGE_SIZE-1)));
+}
+
+static inline void unmap_virtual(struct page *page) 
+{ 
+	return;
+}
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_IA64_CRASH_H */
diff -urNp --exclude-from=/home/davej/.exclude linux-1050/include/asm-x86_64/crash.h linux-1060/include/asm-x86_64/crash.h
--- linux-1050/include/asm-x86_64/crash.h
+++ linux-1060/include/asm-x86_64/crash.h
@@ -0,0 +1,75 @@
+#ifndef _ASM_X86_64_CRASH_H
+#define _ASM_X86_64_CRASH_H
+
+/*
+ * linux/include/asm-x86_64/crash.h
+ *
+ * Copyright (c) 2004 Red Hat, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifdef __KERNEL__
+
+#include <linux/mm.h>
+#include <linux/highmem.h>
+#include <asm/mmzone.h>
+
+extern int page_is_ram(unsigned long);
+
+static inline void *
+map_virtual(u64 offset, struct page **pp)
+{
+	struct page *page;
+	unsigned long pfn;
+	void *vaddr;
+
+	pfn = (unsigned long)(offset >> PAGE_SHIFT);
+
+	if (!page_is_ram(pfn)) {
+		printk(KERN_INFO
+		    "crash memory driver: !page_is_ram(pfn: %lx)\n", pfn);
+		return NULL;
+	}
+
+	if (!pfn_valid(pfn)) {
+		printk(KERN_INFO
+		    "crash memory driver: invalid pfn: %lx )\n", pfn);
+		return NULL;
+	}
+
+	page = pfn_to_page(pfn);
+
+	vaddr = kmap(page);
+	if (!vaddr) {
+		printk(KERN_INFO
+		    "crash memory driver: pfn: %lx kmap(page: %lx) failed\n", 
+			pfn, (unsigned long)page);
+		return NULL;
+	}
+
+	*pp = page;
+	return (vaddr + (offset & (PAGE_SIZE-1)));
+}
+
+static inline void unmap_virtual(struct page *page) 
+{ 
+	kunmap(page);
+}
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_X86_64_CRASH_H */
# HG changeset patch
# User quintela@xxxxxxxxxxx
# Node ID ed87076d010ee2f549658308cf2298fd888ba94a
# Parent  7bad01eaf8f795b08be97187c9ed41891cca9bab
crash xen bits

diff -r 7bad01eaf8f7 -r ed87076d010e arch/i386/mm/init-xen.c
--- a/arch/i386/mm/init-xen.c	Thu Jul 27 02:44:10 2006 +0200
+++ b/arch/i386/mm/init-xen.c	Thu Jul 27 02:50:45 2006 +0200
@@ -275,6 +275,7 @@ int page_is_ram(unsigned long pagenr)
 	}
 	return 0;
 }
+EXPORT_SYMBOL_GPL(page_is_ram);
 
 /*
  * devmem_is_allowed() checks to see if /dev/mem access to a certain address is
diff -r 7bad01eaf8f7 -r ed87076d010e arch/x86_64/mm/init-xen.c
--- a/arch/x86_64/mm/init-xen.c	Thu Jul 27 02:44:10 2006 +0200
+++ b/arch/x86_64/mm/init-xen.c	Thu Jul 27 02:50:45 2006 +0200
@@ -964,6 +964,7 @@ static inline int page_is_ram (unsigned 
 {
 	return 1;
 }
+EXPORT_SYMBOL_GPL(page_is_ram);
 
 /*
  * devmem_is_allowed() checks to see if /dev/mem access to a certain address is
--
Crash-utility mailing list
Crash-utility@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/crash-utility

[Index of Archives]     [Fedora Development]     [Fedora Desktop]     [Fedora SELinux]     [Yosemite News]     [KDE Users]     [Fedora Tools]

 

Powered by Linux