#! /bin/sh # # Copyright 2005 Red Hat, Inc. # Author: Jeff Moyer # Modifications for SUSE from Chris Mason # Takashi Iwai # # kdump # # Description: The kdump init script provides the support necessary for # loading a kdump kernel into memory at system bootup time, # and for copying away a vmcore at system panic time. # # # /etc/init.d/kexec ### BEGIN INIT INFO # Provides: kdump # Required-Start: boot.localfs $remote_fs # Should-Start: # Required-Stop: # Default-Start: 1 2 3 5 # Default-Stop: # Short-Description: kdump core saving and boot configuration # Description: kdump core saving and boot configuration ### END INIT INFO . /etc/sysconfig/kdump . /etc/rc.status KEXEC=/sbin/kexec KDUMP_HELPER=/usr/sbin/kdump-helper KDUMP_CLEANUP_DUMPS=/usr/sbin/kdump-cleanup_dumps KDUMP_SAVE_DUMP=/usr/sbin/kdump-save_dump KDUMP_IDENTIFY_KERNEL=/usr/sbin/kdump-identify_kernel BOOTDIR="/boot" # The default dumper # # Clean up old stuff if necessary, check the free size # and save the vmcore save_core() { $KDUMP_CLEANUP_DUMPS if [ "$?" -ne 0 ] ; then rc_status -v return 1 fi $KDUMP_SAVE_DUMP /proc/vmcore rc_status -v return 0 } # print the available kdump kernel path # empty if no matching file is found check_boot_kernel () { local kstr # if the kernel is relocatable, try vmlinuz first because # currently there are bugs with relocatable ELF-Images # (ET_DYN => GDB doesn't work / ET_EXEC => kexec-tools doesn't # detect) case `uname -i` in x86_64|i386) kstr="${BOOTDIR}/vmlinuz-$1$2" if [ -f $kstr ] ; then if $KDUMP_IDENTIFY_KERNEL -r $kstr &>/dev/null ; then echo $kstr return fi fi esac kstr="${BOOTDIR}/vmlinux-$1$2" if [ -f $kstr ]; then echo $kstr return fi kstr="$kstr.gz" if [ -f $kstr ]; then echo $kstr return fi case `uname -i` in ia64) # ia64 uses vmlinuz as of vmlinux.gz kstr="${BOOTDIR}/vmlinuz-$1$2" if [ -f $kstr ]; then echo $kstr return fi ;; esac } # Load the kdump kerel specified in /etc/sysconfig/kdump # If none is specified, try to load a kdump kernel with the same version # as the currently running kernel. load_kdump() { echo -n "Loading kdump " if [ -z "$KDUMP_KERNELVER" ]; then kdump_kver=`uname -r | sed -e's/-[^-]*$//g'` kdump_kernel=`check_boot_kernel $kdump_kver -kdump` if [ -n "$kdump_kernel" ]; then kdump_kver="${kdump_kver}-kdump" elif [ -z "$kdump_kernel" ]; then kdump_kver=`uname -r` kdump_kernel=`check_boot_kernel $kdump_kver` fi else kdump_kver="$KDUMP_KERNELVER" kdump_kernel=`check_boot_kernel $kdump_kver` fi if [ -z "$kdump_kernel" -o ! -f "$kdump_kernel" ]; then echo -n ": No kdump kernel image found for kernel $kdump_kver." rc_status -s rc_failed 6 rc_exit fi kdump_initrd="${BOOTDIR}/initrd-${kdump_kver}" if [ ! -f $kdump_initrd ]; then echo -n ": No kdump initial ramdisk found." echo "Tried to locate ${kdump_initrd}" rc_status -s rc_failed 6 rc_exit fi if [ -z "$KDUMP_COMMANDLINE" ]; then KDUMP_COMMANDLINE=`cat /proc/cmdline | \ sed -e 's/crashkernel=[0-9]\+[mM]\(@[0-9]\+[Mm]\?\)\?//g' \ -e 's/ *splash=[^ ]*/ /g' \ -e 's/ *BOOT_IMAGE=[^ ]* / /g' \ -e 's/ *showopts/ /g'` # Use deadline for saving the memory footprint KDUMP_COMMANDLINE="$KDUMP_COMMANDLINE elevator=deadline sysrq=1" case `uname -i` in i?86|x86_64|ia64) KDUMP_COMMANDLINE="$KDUMP_COMMANDLINE irqpoll" ;; esac fi KDUMP_COMMANDLINE="CRASH=1 $KDUMP_COMMANDLINE" if [ -n "$KDUMP_COMMANDLINE_APPEND" ] ; then KDUMP_COMMANDLINE="$KDUMP_COMMANDLINE $KDUMP_COMMANDLINE_APPEND" fi if [ -n "$KDUMP_RUNLEVEL" ]; then case "$KDUMP_RUNLEVEL" in [1-5s]) KDUMP_COMMANDLINE="$KDUMP_COMMANDLINE $KDUMP_RUNLEVEL" ;; *) echo " : Invalid KDUMP_RUNLEVEL=$KDUMP_RUNLEVEL, ignored" ;; esac fi # add the dump device if [ -n "$KDUMP_DUMPDEV" ] ; then KDUMP_COMMANDLINE="dumpdev=$KDUMP_DUMPDEV $KDUMP_COMMANDLINE" fi echo 1 > /proc/sys/kernel/panic_on_oops # remove `--args-linux' for x86 type kernel files here if [ "$($KDUMP_IDENTIFY_KERNEL -t $kdump_kernel)" = "x86" ] ; then KEXEC_OPTIONS=$(echo $KEXEC_OPTIONS | sed -e 's/--args-linux//g') fi KEXEC_CALL="$KEXEC -p $kdump_kernel --append=\"$KDUMP_COMMANDLINE\"" KEXEC_CALL="$KEXEC_CALL --initrd=$kdump_initrd $KEXEC_OPTIONS" if [ $(($KDUMP_VERBOSE & 1)) -gt 0 ] ; then logger -i -t kdump "Loading kdump kernel: $KEXEC_CALL" fi if [ $(($KDUMP_VERBOSE & 4)) -gt 0 ] ; then echo "Loading kdump kernel: $KEXEC_CALL" fi eval "$KEXEC_CALL" rc_status -v } # return success if running in a crash environemnt is_crash_kernel () { test -f /proc/vmcore || return 1 # FIXME: any better way to detect crash environment? test -n "$CRASH" && return 0 grep -q elfcorehdr= /proc/cmdline && return 0 return 1 } # return success if we have a valid dump on the dump device have_valid_dump_in_dumpdev () { if [ ! -b "$KDUMP_DUMPDEV" ] ; then return 1 fi # return the return code from this command $KDUMP_HELPER -c "$KDUMP_DUMPDEV" >> /dev/null } # invalidate the dump device so that it's not read on next boot invalidate_dumpdev () { dd if=/dev/zero of=$KDUMP_DUMPDEV bs=512 count=1 &>/dev/null } case "$1" in start) if is_crash_kernel; then if [ -z "$KDUMP_DUMPDEV" ] ; then if [ -n "$KDUMP_TRANSFER" ]; then $KDUMP_TRANSFER else save_core fi fi if test "$KDUMP_IMMEDIATE_REBOOT" = "yes"; then /sbin/reboot # sleep to avoid the conflict with script "single" sleep 600 fi else if have_valid_dump_in_dumpdev ; then $KDUMP_SAVE_DUMP $KDUMP_DUMPDEV rc_status -v if [ "$?" -eq 0 ] ; then invalidate_dumpdev rc_status fi fi load_kdump fi ;; stop) if ! is_crash_kernel ; then if [ "$RUNLEVEL" != "" ]; then echo -n "Not unloading kdump during runlevel changes" rc_status -s else echo -n "Unloading kdump" $KEXEC -p -u rc_status -v fi fi ;; status) echo "not implemented" ;; restart|reload) $0 stop $0 start ;; condrestart) ;; *) echo $"Usage: $0 {start|stop|status|restart|reload}" exit 1 esac exit $? # vim: set ts=8 sw=4 sts=4 noet: