summaryrefslogtreecommitdiff
path: root/debian/kdump-config.in
diff options
context:
space:
mode:
Diffstat (limited to 'debian/kdump-config.in')
-rwxr-xr-xdebian/kdump-config.in960
1 files changed, 960 insertions, 0 deletions
diff --git a/debian/kdump-config.in b/debian/kdump-config.in
new file mode 100755
index 0000000..a1c3b4e
--- /dev/null
+++ b/debian/kdump-config.in
@@ -0,0 +1,960 @@
+#!/bin/bash
+
+# kdump-config
+# Copyright (C) 2007-2009 Hewlett-Packard Development Company, L.P.
+# Written by Terry Loftin <terry.loftin@hp.com>
+#
+# 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 of the License, 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.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+# kdump-config
+# a shell script utility to manage:
+# * loading a kdump kernel
+# * unloading a kdump kernel
+# * saving a vmcore kdump kernel
+# * determining the status of kdump
+# * propagate ssh key to remote host
+
+PATH=/bin:/usr/bin:/sbin:/usr/sbin
+NAME=${NAME:="kdump-config"}
+
+. /lib/lsb/init-functions
+. /lib/init/vars.sh
+
+# Global Setup
+KDUMP_DEFAULTS=/etc/default/kdump-tools
+[ -r $KDUMP_DEFAULTS ] && . $KDUMP_DEFAULTS
+
+KEXEC=/sbin/kexec
+[ -e $KEXEC ] || exit 1;
+
+KVER=`uname -r`
+ARCH=`uname -m`
+
+# Set up defaults
+KDUMP_SYSCTL=${KDUMP_SYSCTL:="kernel.panic_on_oops=1"}
+KDUMP_COREDIR=${KDUMP_COREDIR:=/var/crash}
+KDUMP_DUMP_DMESG=${KDUMP_DUMP_DMESG:=1}
+KDUMP_DIR="/var/lib/kdump"
+KDUMP_NUM_DUMPS=${KDUMP_NUM_DUMPS:=0}
+NFS_TIMEO=${NFS_TIMEO:=600}
+NFS_RETRANS=${NFS_RETRANS:=3}
+MAKEDUMP_ARGS=${MAKEDUMP_ARGS:="-c -d 31"}
+KDUMP_CMDLINE_APPEND=${KDUMP_CMDLINE_APPEND:="@KDUMP_CMDLINE_APPEND@"}
+KDUMP_KERNEL_HOOK="/etc/kernel/postinst.d/kdump-tools"
+[ -d $KDUMP_COREDIR ] || mkdir -p $KDUMP_COREDIR ;
+
+IOMEM_ADDR=`grep -i "Crash kernel" /proc/iomem | sed "s/-..*//" | sed "s/^[ 0]*/0x/"`
+
+# Constants
+vmcore_file=/proc/vmcore
+sys_kexec_crash=/sys/kernel/kexec_crash_loaded
+sys_fadump_enabled=/sys/kernel/fadump_enabled
+sys_fadump_registered=/sys/kernel/fadump_registered
+kexec_cmd_file=$KDUMP_COREDIR/kexec_cmd
+
+# DUMP_MODE = kdump/fadump
+# The default dump mode is kdump.
+DUMP_MODE="kdump"
+
+# If /sys/kernel/fadump_enabled is set to `1`, use fadump as dump mechanism
+if [ -e $sys_fadump_enabled ] && [ `cat $sys_fadump_enabled` -eq 1 ]; then
+ DUMP_MODE="fadump"
+fi
+
+# Utility Functions
+#
+function kdump_help()
+{
+cat <<EOHELP
+Usage:
+kdump-config {help|test|show|status|load|unload|savecore|propagate|symlinks kernel-version}"
+ help - print this page
+ test - Do a dry-run of kdump kernel load command by showing
+ the kernels and parameters that will be used and echo'ing
+ the kexec command. The kexec command will not be executed.
+ If using fadump, check if required sysfs directories exist.
+ show - Show dump mode, status, any current parameters.
+ Show kexec command for kdump.
+ status - evaluate /sys/kernel/{kexec_crash_loaded,fadump_registered}
+ depending on dump mode. Print appropriate message
+ load - Locate the kdump kernel, debug kernel, and establish links for
+ makedumpfile. Then load the kdump kernel using kexec
+ If using fadump, register.
+ unload - unload the kdump kernel using kexec
+ If using fadump, unregister.
+ savecore - use previously made links to save /proc/vmcore
+ propagate - Send public ssh key to remote host for passwordless connection
+ symlinks - Verify and create vmlinuz and initrd.img links in /var/lib/kdump
+ according to the provided kernel version. If the target
+ initrd.img file is absent, it will create it.
+EOHELP
+}
+
+function kdump_show()
+{
+ echo "DUMP_MODE: $DUMP_MODE"
+ echo "USE_KDUMP: $USE_KDUMP"
+ echo "KDUMP_SYSCTL: $KDUMP_SYSCTL"
+ echo "KDUMP_COREDIR: $KDUMP_COREDIR"
+ if [ "$DUMP_MODE" == "kdump" ]; then
+ echo "crashkernel addr: $IOMEM_ADDR"
+ fi
+ if [ -h "$KDUMP_KERNEL" ];then
+ echo " "$(file $KDUMP_KERNEL)
+ else
+ echo " "$KDUMP_KERNEL
+ fi
+ echo "kdump initrd: "
+ if [ -h "$KDUMP_INITRD" ];then
+ echo " "$(file $KDUMP_INITRD)
+ else
+ echo " "$KDUMP_INITRD
+ fi
+
+ if [ -n "$SSH" ];then
+ echo "SSH: $SSH"
+ SSH_KEY="${SSH_KEY:=/root/.ssh/kdump_id_rsa}"
+ echo "SSH_KEY: $SSH_KEY"
+ fi
+ if [ -n "$NFS" ]; then
+ echo "NFS: $NFS"
+ echo "NFS_TIMEO: ${NFS_TIMEO:=600}"
+ echo "NFS_RETRANS ${NFS_RETRANS:=3}"
+ fi
+
+ if [ -n "$SSH" ] || [ -n "$NFS" ]; then
+ HOSTTAG="${HOSTTAG:=ip}"
+ echo "HOSTTAG: $HOSTTAG"
+ fi
+
+ if [ "$DUMP_MODE" == "fadump" ]; then
+ if [ -e $sys_fadump_registered ] &&
+ [ `cat $sys_fadump_registered` -eq 1 ] ; then
+ echo "current state: ready to fadump";
+ else
+ echo "current state: Not ready to fadump";
+ fi
+ return 0
+ fi
+
+ if [ -e $sys_kexec_crash -a `cat $sys_kexec_crash` -eq 1 ] ; then
+ echo "current state: ready to kdump";
+ else
+ echo "current state: Not ready to kdump";
+ fi
+ echo
+ echo "kexec command:"
+ echo -n " "
+ if [ -e $kexec_cmd_file ] ; then
+ cat $kexec_cmd_file ;
+ else
+ echo "no kexec command recorded"
+ fi
+}
+
+function kdump_test()
+{
+ echo "USE_KDUMP: $USE_KDUMP"
+ echo "KDUMP_SYSCTL: $KDUMP_SYSCTL"
+ echo "KDUMP_COREDIR: $KDUMP_COREDIR"
+ echo "crashkernel addr: $IOMEM_ADDR"
+ echo "kdump kernel addr: $KDUMP_ADDR"
+ echo "kdump kernel:"
+ if [ -h "$KDUMP_KERNEL" ];then
+ echo " "$(file $KDUMP_KERNEL)
+ else
+ echo " "$KDUMP_KERNEL
+ fi
+ echo "kdump initrd: "
+ if [ -h "$KDUMP_INITRD" ];then
+ echo " "$(file $KDUMP_INITRD)
+ else
+ echo " "$KDUMP_INITRD
+ fi
+ echo "kexec command to be used:"
+ echo " $KEXEC_CMD"
+}
+
+# Check if symlinks are correctly set according to the
+# kernel version passed as argument, if $KDUMP_DIR
+# is used to store smaller initrd.img files (Ubuntu only)
+# Returns: 0/1 (success/broken,absent or wrong version)
+#
+function check_symlink()
+{
+symlink=$1
+kern_version=$2
+
+ if [ -h "$KDUMP_DIR/$symlink" ];then
+ linkedfile=$(file "$KDUMP_DIR/$symlink" | rev | cut -d" " -f1 | rev)
+ if [ -e "$linkedfile" ];then
+ version=$(basename $linkedfile)
+ if [ ${version%%-*} == "vmlinux" ];then
+ version=${version#vmlinux-}
+ else
+ version=${version#$symlink-}
+ fi
+ if [ ${version} == $kern_version ]; then
+ return 0
+ fi
+ fi
+ fi
+ return 1
+}
+
+# Create a symlink
+function create_symlink()
+{
+link=$1
+kernel_version=$2
+
+ log_action_msg "Creating symlink $KDUMP_DIR/${link}"
+ if [ $link == "vmlinuz" ];then
+ ln -fs /boot/${link%?}?-${kernel_version} $KDUMP_DIR/$link
+ else
+ ln -fs $KDUMP_DIR/${link}-${kernel_version} $KDUMP_DIR/$link
+ fi
+}
+
+# If $KDUMP_DIR is used to hold smaller initrd.img,
+# verify if the proper symlinks are in place for
+# initrd.img and vmlinuz/vmlinux.
+# If no link is found, the links are broken or pointing
+# to the wrong version, new links are created.
+# Nothing is created if DRY_RUN = true. Only reporting
+# is done.
+# Returns: none. prints warnings or exit
+# Creates: $KDUMP_DIR/vmlinuz $KDUMP_DIR/initrd.img
+function manage_symlinks()
+{
+ if [ -d "$KDUMP_DIR" ];then
+ for symlink in initrd.img vmlinuz;do
+ check_symlink $symlink $KVER
+ ret=$?
+ if [ $ret == 1 ];then
+ log_failure_msg "Invalid symlink : $KDUMP_DIR/$symlink"
+ if [ ! $DRY_RUN ];then
+ create_symlink $symlink $KVER
+ fi
+ fi
+ done
+ fi
+ return 0
+}
+
+# check_fadump_support: Other miscellaneous checks go here:
+# 1: if USE_KDUMP is 0, don't set up fadump.
+# 2: -e /sys/kernel/fadump_registered indicates that this kernel
+# thinks it supports fadump
+#
+# Returns: none. prints warnings or exit
+function check_fadump_support()
+{
+ if [ -z "$USE_KDUMP" -o "$USE_KDUMP" == "0" ] ; then
+ log_failure_msg "$KDUMP_DEFAULTS: USE_KDUMP is not set or zero"
+ [ ! $DRY_RUN ] && exit 1;
+ fi
+ if [ ! -e $sys_fadump_registered ]; then
+ log_failure_msg "fadump is not configured in this kernel."
+ log_failure_msg "Try passing \"fadump=on\" to enable fadump"
+ [ ! $DRY_RUN ] && exit 1;
+ fi
+ if [ -n "$NFS" ] && [ -n "$SSH" ];then
+ log_failure_msg "\$SSH and \$NFS cannot be defined concurrently"
+ [ ! $DRY_RUN ] && exit 1;
+ fi
+}
+
+# check_kdump_support: Other miscellaneous checks go here:
+# 1: if USE_KDUMP is 0, don't set up kdump.
+# 2: -e /sys/kernel/kexec_crash loaded indicates that this kernel
+# thinks it supports kdump
+# 3: the current kernel should have booted with a crashkernel= command
+# line parameter.
+#
+# Returns: none. prints warnings or exit
+function check_kdump_support()
+{
+ if [ -z "$USE_KDUMP" -o "$USE_KDUMP" == "0" ] ; then
+ log_failure_msg "$KDUMP_DEFAULTS: USE_KDUMP is not set or zero"
+ [ ! $DRY_RUN ] && exit 1;
+ fi
+ if [ ! -e $sys_kexec_crash ] ; then
+ log_failure_msg "kdump is not supported by this kernel"
+ [ ! $DRY_RUN ] && exit 1;
+ fi
+ CRASHKERNEL=`grep -i crashkernel= /proc/cmdline`;
+ if [ -z "$CRASHKERNEL" ] ; then
+ log_failure_msg "no crashkernel= parameter in the kernel cmdline"
+ [ ! $DRY_RUN ] && exit 1;
+ fi
+ if [ -n "$NFS" ] && [ -n "$SSH" ];then
+ log_failure_msg "\$SSH and \$NFS cannot be defined concurrently"
+ [ ! $DRY_RUN ] && exit 1;
+ fi
+}
+
+# check_relocatable: check if the given kernel config is relocatable
+# Arguments:
+# 1: the config file to check
+# Returns: 0 if the given kernel config indicates a relocatable kernel.
+# 1 otherwise.
+function check_relocatable()
+{
+ if [ "$ARCH" = "ia64" ]; then
+ # Linux is always relocatable on ia64
+ return 0
+ elif grep -q 'CONFIG_RELOCATABLE=y' $1; then
+ return 0
+ else
+ return 1
+ fi
+}
+
+function check_securelevel()
+{
+ local sl_path="/sys/kernel/security/securelevel"
+ if [ ! -f "$sl_path" ]; then
+ return 1
+ fi
+
+ if [ "$(cat "$sl_path")" = "1" ]; then
+ return 0
+ fi
+
+ return 1
+}
+
+
+function check_secure_boot()
+{
+ local sb_path sm_file sb sm
+
+ sb_path=$(find /sys/firmware/efi/efivars -name SecureBoot-* 2>/dev/null)
+ sm_path=$(find /sys/firmware/efi/efivars -name SetupMode-* 2>/dev/null)
+
+ if [ -f "$sb_path" ] && [ -f "$sm_path" ]; then
+ sb=$(hexdump -v -e '/1 "%d\ "' $sb_path|cut -d' ' -f 5)
+ sm=$(hexdump -v -e '/1 "%d\ "' $sm_path|cut -d' ' -f 5)
+
+ if [ "$sb" = "1" ] && [ "$sm" = "0" ]; then
+ return 0
+ fi
+ fi
+
+ return 1
+}
+
+# Find the kexec/kdump kernel and possibly a corresponding initrd.
+# A kdump kernel does not need to match the `uname -r` of the booted kernel.
+#
+# Use the following priorites in determining the kdump kernel:
+# 1. An explicit Kdump kernel in the defaults file overrides all
+# 2. Use the current running kernel if it is relocatable.
+# 3. Give up. Note, a kdump kernel is required.
+#
+# Returns: 0/1 (success/fail)
+# Returns: none. prints warnings or exit
+# Sets: KDUMP_KERNEL, KDUMP_INITRD
+function locate_kdump_kernel()
+{
+ # 1: User may have specified the KDUMP_KERNEL and KDUMP_INITRD
+ # explicitly. Test for existance and either use it or fail.
+ if [ -n "$KDUMP_KERNEL" ] ; then
+ if [ ! -e "$KDUMP_KERNEL" ] ; then
+ log_failure_msg "$KDUMP_DEFAULTS: KDUMP_KERNEL does not exist: $KDUMP_KERNEL"
+ [ ! $DRY_RUN ] && exit 1;
+ elif [ -n "$KDUMP_INITRD" -a ! -e "$KDUMP_INITRD" ] ; then
+ log_failure_msg "$KDUMP_DEFAULTS: KDUMP_INITRD does not exist: $KDUMP_INITRD"
+ [ ! $DRY_RUN ] && exit 1;
+ fi
+ return 0;
+ fi
+
+ # 2: The currently running kernel may be relocatable. If so, then
+ # use the currently running kernel as the crash kernel.
+ if check_relocatable /boot/config-$KVER; then
+ if [ -f /boot/vmlinuz-$KVER ]; then
+ KDUMP_KERNEL=/boot/vmlinuz-$KVER
+ elif [ -f /boot/vmlinux-$KVER ]; then
+ KDUMP_KERNEL=/boot/vmlinux-$KVER
+ else
+ KDUMP_KERNEL=
+ fi
+ if [ -f /boot/initrd.img-$KVER ]; then
+ KDUMP_INITRD=/boot/initrd.img-$KVER
+ else
+ KDUMP_INITRD=
+ fi
+ KDUMP_ADDR="relocatable"
+ return 0;
+ fi
+
+ # If the kdump kernel is not relocatable, we need to make sure it was
+ # built to start at the crashkernel= address. IOMEM_ADDR is already
+ # set...
+ if [ -z "$KDUMP_CONFIG" ] ; then return 0 ; fi
+
+ if check_relocatable $KDUMP_CONFIG; then
+ KDUMP_ADDR="relocatable"
+ else
+ KDUMP_ADDR=`grep CONFIG_PHYSICAL_START $KDUMP_CONFIG | sed "s/CONFIG_PHYSICAL_START=//"`
+ # compare the two
+ if [ "$KDUMP_ADDR" != "$IOMEM_ADDR" ] ; then
+ log_failure_msg "kdump kernel relocation address does not match crashkernel parameter"
+ [ ! $DRY_RUN ] && exit 1;
+ return 1;
+ fi
+ fi
+
+ return 0;
+}
+
+# Register firmware-assisted dump as the dump mechanism
+# Returns: none. prints warnings or exit
+function fadump_register()
+{
+ # set fadump registered sys node to `1` to register fadump
+ if [ "`cat $sys_fadump_registered`" -ne 1 ]; then
+ echo 1 > $sys_fadump_registered
+ fi
+ rc=`cat $sys_fadump_registered`
+ if [ $rc -ne 1 ] ; then
+ log_failure_msg "fadump registering failed"
+ logger -t $NAME "fadump registering failed"
+ [ ! $DRY_RUN ] && exit 1;
+ fi
+
+ log_success_msg "fadump registered successfully"
+ logger -t $NAME "fadump registered successfully"
+
+ # Last step: make sure panic_on_oops is enabled
+ PANIC_ON_OOPS=`/sbin/sysctl kernel.panic_on_oops | cut -d" " -f3`
+ if [ $PANIC_ON_OOPS != "1" ] ; then
+ sysctl -w kernel.panic_on_oops=1 >/dev/null
+ fi
+}
+
+# Returns: none. prints warnings or exit
+function fadump_unregister()
+{
+ # set fadump registered sys node to `0` to un-register fadump
+ if [ "`cat $sys_fadump_registered`" -ne 0 ]; then
+ echo 0 > $sys_fadump_registered
+ fi
+ rc=`cat $sys_fadump_registered`
+ if [ $rc -ne 0 ] ; then
+ log_failure_msg "fadump un-registering failed"
+ logger -t $NAME "fadump un-registering failed"
+ [ ! $DRY_RUN ] && exit 1;
+ fi
+
+ log_success_msg "fadump un-registered successfully"
+ logger -t $NAME "fadump un-registered successfully"
+}
+
+function kdump_create_symlinks()
+{
+kernel_version=$1
+
+ if [ -e $sys_kexec_crash -a `cat $sys_kexec_crash` -eq 1 ] ; then
+ log_failure_msg "Cannot change symbolic links when kdump is loaded"
+ exit 1
+ fi
+
+ if [ -e /boot/vmlinu[xz]-${kernel_version} ];then
+ create_symlink vmlinuz $kernel_version
+
+ if [ -f $KDUMP_DIR/initrd.img-${kernel_version} ]; then
+ create_symlink initrd.img ${kernel_version}
+ else
+ if [ -x $KDUMP_KERNEL_HOOK ];then
+ $KDUMP_KERNEL_HOOK $kernel_version
+ create_symlink initrd.img $kernel_version
+ else
+ log_failure_msg "Unable to locate kernel hook"
+ fi
+ fi
+ else
+ log_failure_msg "Invalid kernel version : $kernel_version"
+ fi
+}
+#
+# Load the already determined kdump kernel and kdump initrd using kexec
+# 1: A KDUMP_CMDLINE in the defaults file overrides all.
+# 2: Use /proc/cmdline
+# a. strip out the crashkernel= parameter.
+# b. strip out the abm= parameter.
+# c. append KDUMP_CMDLINE_APPEND from defaults file
+# Sets: KEXEC_CMD
+# Returns: none. prints warnings or exit
+function kdump_load()
+{
+ # assemble the kexec command used to load the kdump kernel
+ KEXEC_CMD="$KEXEC -p"
+
+ if check_secure_boot || check_securelevel; then
+ KEXEC_CMD="$KEXEC_CMD -s"
+ fi
+
+ # Different kernel types allow/require different options:
+ # The only special case here is that x86, x86_64 elf style
+ # binaries require the --args-linux argument.
+ if [ "$ARCH" != "ia64" ] ; then
+ ELF_TST=`file $KDUMP_KERNEL | grep ELF`
+ if [ -n "$ELF_TST" ] ; then
+ KEXEC_CMD="$KEXEC_CMD --args-linux"
+ fi
+ fi
+
+ # KDUMP_KEXEC_ARGS, if non-empty, comes from the defaults file.
+ if [ -n "$KDUMP_KEXEC_ARGS" ] ; then
+ KEXEC_CMD="$KEXEC_CMD $KDUMP_KEXEC_ARGS"
+ fi
+
+ # Assemble the --commmand-line:
+ if [ -z "$KDUMP_CMDLINE" ] ; then
+ KDUMP_CMDLINE=`cat /proc/cmdline | \
+ sed -r -e 's/(^| )crashkernel=[^ ]*//g' \
+ -e 's/(^| )hugepages=[^ ]*//g' \
+ -e 's/(^| )hugepagesz=[^ ]*//g' \
+ -e 's/(^| )abm=[^ ]*//g' \
+ -e 's/"/\\\\"/'g`
+ fi
+ KDUMP_CMDLINE="$KDUMP_CMDLINE $KDUMP_CMDLINE_APPEND"
+ KEXEC_CMD="$KEXEC_CMD --command-line=\"$KDUMP_CMDLINE\""
+
+ # Assemble the --initrd:
+ if [ -e "$KDUMP_INITRD" ] ; then
+ KEXEC_CMD="$KEXEC_CMD --initrd=$KDUMP_INITRD"
+ fi
+
+ # Finally, add the kernel:
+ KEXEC_CMD="$KEXEC_CMD $KDUMP_KERNEL"
+
+ if [ $DRY_RUN ] ; then return 0; fi
+
+ eval $KEXEC_CMD
+
+ if [ $? == 0 ]; then
+ log_success_msg "loaded kdump kernel"
+ logger -t $NAME "$KEXEC_CMD"
+ logger -t $NAME "loaded kdump kernel"
+ echo "$KEXEC_CMD" >$kexec_cmd_file
+ else
+ log_failure_msg "failed to load kdump kernel"
+ logger -t $NAME "failed to load kdump kernel"
+ [ ! $DRY_RUN ] && exit 1;
+ fi
+
+ # Last step: make sure panic_on_oops is enabled
+ PANIC_ON_OOPS=`/sbin/sysctl kernel.panic_on_oops | cut -d" " -f3`
+ if [ $PANIC_ON_OOPS != "1" ] ; then
+ sysctl -w kernel.panic_on_oops=1 >/dev/null
+ fi
+
+}
+
+# Returns: none. prints warnings or exit
+function kdump_unload()
+{
+ if check_secure_boot || check_securelevel; then
+ $KEXEC -s -p -u
+ else
+ $KEXEC -p -u
+ fi
+
+ if [ $? == 0 ]; then
+ log_success_msg "unloaded kdump kernel"
+ logger -t $NAME "unloaded kdump kernel"
+ else
+ log_failure_msg "failed to unload kdump kernel"
+ logger -t $NAME "failed to unload kdump kernel"
+ [ ! $DRY_RUN ] && exit 1;
+ fi
+}
+
+#
+# Return the name of the subdirectory to store core file.
+# Will add hostname/IP according to the value of
+# HOSTTAG if networked dump is selected
+
+function define_stampdir()
+{
+ STAMP=$1
+ HOSTTAG="${HOSTTAG:=ip}"
+
+ if [ -z "$SSH" ] && [ -z "$NFS" ]; then
+ echo "$KDUMP_COREDIR/$STAMP"
+ elif [ "$HOSTTAG" = "hostname" ];then
+ echo "$KDUMP_COREDIR/$(hostname)-$STAMP"
+ else
+ # Looping to give time to network to settle
+ typeset -i counter=0
+ while (( counter < 5));do
+ THIS_HOST="$(hostname -I)"
+ set -- $THIS_HOST
+ THIS_HOST=$1
+ if [ -z "$THIS_HOST" ]; then
+ sleep 1
+ ((counter+=1))
+ else
+ break
+ fi
+ done
+ if [ -z "$THIS_HOST" ]; then
+ # Send log msg to stderr to avoid polluting
+ # the result of the function
+ log_failure_msg "Unable to get IP from network" >&2
+ log_action_msg "Reverting to HOSTTAG=hostname" >&2
+ THIS_HOST="$(hostname)"
+ fi
+ echo "$KDUMP_COREDIR/$THIS_HOST-$STAMP"
+ fi
+}
+
+
+# Saving the vmcore:
+# Our priorities are:
+# 1. If the makedumpfile config link is valid, use that
+# 2. else if the vmlinux link is valid, use that
+# 3. else fallback to using: makedumpfile -d 1 -c
+# 4. else use cp
+#
+# Returns: 0/1 (success/fail)
+# Sets: KDUMP_STAMPDIR, KDUMP_COREFILE
+function kdump_save_core()
+{
+ KDUMP_STAMP=`date +"%Y%m%d%H%M"`
+ KDUMP_STAMPDIR=$(define_stampdir $KDUMP_STAMP)
+ KDUMP_CORETEMP="$KDUMP_STAMPDIR/dump-incomplete"
+ KDUMP_COREFILE="$KDUMP_STAMPDIR/dump.$KDUMP_STAMP"
+ KDUMP_DMESGFILE="$KDUMP_STAMPDIR/dmesg.$KDUMP_STAMP"
+
+ # If we use NFS, verify that we can mount the FS
+ #
+ if [ -n "$NFS" ];then
+ log_action_msg "Mounting NFS mountpoint $NFS ..."
+ mount -t nfs -o nolock -o tcp -o soft -o timeo=${NFS_TIMEO} -o retrans=${NFS_RETRANS} $NFS $KDUMP_COREDIR
+ ERROR=$?
+ if [ $ERROR -ne 0 ];then
+ log_failure_msg "$NAME: Unable to mount remote NFS directory $NFS. Cannot save core"
+ logger -t $NAME "Unable to mount remote NFS directory $NFS. Cannot save core"
+ return 1;
+ fi
+
+ # FS is mounted, see if we can write to it
+ #
+ mkdir -p $KDUMP_STAMPDIR
+ ERROR=$?
+
+ if [ $ERROR -ne 0 ];then
+ log_failure_msg "$NAME: Unable to write to the remote NFS directory $NFS. Cannot save core"
+ logger -t $NAME "Unable to write to the remote NFS directory $NFS. Cannot save core"
+ umount $KDUMP_COREDIR
+ UMNT_ERROR=$?
+ if [ $UMNT_ERROR -ne 0 ];then
+ log_failure_msg "$NAME: Unable to cleanly unmount the NFS file system"
+ logger -t $NAME "Unable to cleanly unmount the NFS file system"
+ fi
+ else
+ log_action_msg "Dumping to NFS mountpoint $NFS/$KDUMP_STAMP"
+ logger -t $NAME "Dumping to NFS mountpoint $NFS/$KDUMP_STAMP"
+ fi
+ else
+ mkdir -p $KDUMP_STAMPDIR
+ fi
+
+ log_action_msg "running makedumpfile $MAKEDUMP_ARGS $vmcore_file $KDUMP_CORETEMP"
+ makedumpfile $MAKEDUMP_ARGS $vmcore_file $KDUMP_CORETEMP
+ ERROR=$?
+ if [ $ERROR -ne 0 ] ; then
+ log_failure_msg "$NAME: makedumpfile failed, falling back to 'cp'"
+ logger -t $NAME "makedumpfile failed, falling back to 'cp'"
+ KDUMP_CORETEMP="$KDUMP_STAMPDIR/vmcore-incomplete"
+ KDUMP_COREFILE="$KDUMP_STAMPDIR/vmcore.$KDUMP_STAMP"
+ cp $vmcore_file $KDUMP_CORETEMP
+ ERROR=$?
+ fi
+
+ # did we succeed?
+ if [ $ERROR == 0 ]; then
+ mv $KDUMP_CORETEMP $KDUMP_COREFILE
+ log_success_msg "$NAME: saved vmcore in $KDUMP_STAMPDIR"
+ logger -t $NAME "saved vmcore in $KDUMP_STAMPDIR"
+ sync
+ else
+ log_failure_msg "$NAME: failed to save vmcore in $KDUMP_STAMPDIR"
+ logger -t $NAME "failed to save vmcore in $KDUMP_STAMPDIR"
+ fi
+
+ # dump the dmesg buffer
+ if [ "$KDUMP_DUMP_DMESG" -eq 1 ] ; then
+ log_action_msg "running makedumpfile --dump-dmesg $vmcore_file $KDUMP_DMESGFILE"
+ makedumpfile --dump-dmesg $vmcore_file $KDUMP_DMESGFILE
+ ERROR=$?
+ if [ $ERROR -ne 0 ] ; then
+ log_failure_msg "$NAME: makedumpfile --dump-dmesg failed. dmesg content will be unavailable"
+ logger -t $NAME "makedumpfile --dump-dmesg failed. dmesg content will be unavailable"
+ fi
+
+ # did we succeed?
+ if [ $ERROR == 0 ]; then
+ log_success_msg "$NAME: saved dmesg content in $KDUMP_STAMPDIR"
+ logger -t $NAME "saved dmesg content in $KDUMP_STAMPDIR"
+ sync
+ else
+ log_failure_msg "$NAME: failed to save dmesg content in $KDUMP_STAMPDIR"
+ logger -t $NAME "failed to save dmesg content in $KDUMP_STAMPDIR"
+ fi
+ fi
+
+ # limit the number of dumps kept on the local machine
+ if [ -z "${NFS}" -a $ERROR == 0 -a $KDUMP_NUM_DUMPS -gt 0 ] ; then
+ num_dumps=$(ls -1dv $KDUMP_COREDIR/2* | wc -l)
+ if [ $num_dumps -gt $KDUMP_NUM_DUMPS ] ; then
+ purge_num=$((num_dumps - KDUMP_NUM_DUMPS))
+ purge_dir=$(ls -1dv $KDUMP_COREDIR/2* | head -$purge_num | tr "\n" " ")
+ log_action_msg "Too many dumps, purging: $purge_dir"
+ logger -t $NAME "Too many dumps, purging: $purge_dir"
+ rm -rf $purge_dir
+ fi
+ fi
+
+ # If we use NFS, umount the remote FS
+ #
+ if [ -n "$NFS" ];then
+ umount $KDUMP_COREDIR
+ UMNT_ERROR=$?
+ if [ $UMNT_ERROR -ne 0 ] ; then
+ log_failure_msg "$NAME: Unable to cleanly unmount the NFS file system"
+ logger -t $NAME "Unable to cleanly unmount the NFS file system"
+ fi
+ fi
+
+ return $ERROR
+}
+
+function kdump_save_core_to_ssh()
+{
+ KDUMP_SSH_KEY="${SSH_KEY:=/root/.ssh/kdump_id_rsa}"
+ KDUMP_REMOTE_HOST="$SSH"
+
+ KDUMP_STAMP=`date +"%Y%m%d%H%M"`
+ KDUMP_STAMPDIR=$(define_stampdir $KDUMP_STAMP)
+
+ KDUMP_CORETEMP="$KDUMP_STAMPDIR/dump-incomplete"
+ KDUMP_COREFILE="$KDUMP_STAMPDIR/dump.$KDUMP_STAMP"
+ KDUMP_TMPDMESG="/tmp/dmesg.$KDUMP_STAMP"
+ KDUMP_DMESGFILE="$KDUMP_STAMPDIR/dmesg.$KDUMP_STAMP"
+ ERROR=0
+
+ ssh -i $KDUMP_SSH_KEY $KDUMP_REMOTE_HOST mkdir -p $KDUMP_STAMPDIR
+ ERROR=$?
+ # If remote connections fails, no need to continue
+ if [ $ERROR -ne 0 ] ; then
+ log_failure_msg "$NAME: Unable to reach remote server $KDUMP_REMOTE_HOST. No reason to continue"
+ logger -t $NAME "Unable to reach remote server $KDUMP_REMOTE_HOST. No reason to continue"
+ return 1
+ fi
+
+ # Add '-F' [flatten] to MAKEDUMP_ARGS, if not there:
+ [ "${MAKEDUMP_ARGS#-F*}" != "${MAKEDUMP_ARGS}" ] || MAKEDUMP_ARGS="${MAKEDUMP_ARGS} -F"
+ log_action_msg "sending makedumpfile $MAKEDUMP_ARGS $vmcore_file to $KDUMP_REMOTE_HOST : $KDUMP_CORETEMP"
+ makedumpfile $MAKEDUMP_ARGS $vmcore_file | ssh -i $KDUMP_SSH_KEY $KDUMP_REMOTE_HOST dd of=$KDUMP_CORETEMP
+ ERROR=$?
+ if [ $ERROR -ne 0 ] ; then
+ log_failure_msg "$NAME: makedumpfile failed, falling back to 'scp'"
+ logger -t $NAME "makedumpfile failed, falling back to 'scp'"
+ KDUMP_CORETEMP="$KDUMP_STAMPDIR/vmcore-incomplete"
+ KDUMP_COREFILE="$KDUMP_STAMPDIR/vmcore.$KDUMP_STAMP"
+ scp -i $KDUMP_SSH_KEY $vmcore_file $KDUMP_REMOTE_HOST:$KDUMP_CORETEMP
+ if [ $? -ne 0 ];then
+ log_failure_msg "$NAME: makedumpfile scp failed. The vmcore file will not be available"
+ logger -t $NAME "makedumpfile scp failed. The vmcore file will not be available"
+ else
+ ERROR=0
+ fi
+ else
+ ERROR=0
+ fi
+
+ # did we succeed?
+ if [ $ERROR -ne 0 ]; then
+ log_failure_msg "$NAME: failed to save vmcore in $KDUMP_REMOTE_HOST:$KDUMP_STAMPDIR"
+ logger -t $NAME "failed to save vmcore in $KDUMP_REMOTE_HOST:$KDUMP_STAMPDIR"
+ sync
+ else
+ ssh -i $KDUMP_SSH_KEY $KDUMP_REMOTE_HOST mv $KDUMP_CORETEMP $KDUMP_COREFILE
+ log_success_msg "$NAME: saved vmcore in $KDUMP_REMOTE_HOST:$KDUMP_STAMPDIR"
+ logger -t $NAME "saved vmcore in $KDUMP_REMOTE_HOST:$KDUMP_STAMPDIR"
+ fi
+
+ # dump the dmesg buffer
+ if [ "$KDUMP_DUMP_DMESG" -eq 1 ] ; then
+ log_action_msg "running makedumpfile --dump-dmesg $vmcore_file $KDUMP_TMPDMESG"
+ makedumpfile --dump-dmesg $vmcore_file $KDUMP_TMPDMESG
+ ERROR=$?
+ if [ $ERROR -ne 0 ] ; then
+ log_failure_msg "$NAME: makedumpfile --dump-dmesg failed. dmesg content will be unavailable"
+ logger -t $NAME "makedumpfile --dump-dmesg failed. dmesg content will be unavailable"
+ else
+ scp -i $KDUMP_SSH_KEY $KDUMP_TMPDMESG $KDUMP_REMOTE_HOST:$KDUMP_DMESGFILE
+ ERROR=$?
+ fi
+
+ # did we succeed?
+ if [ $ERROR == 0 ]; then
+ log_success_msg "$NAME: saved dmesg content in $KDUMP_REMOTE_HOST:$KDUMP_STAMPDIR"
+ logger -t $NAME "saved dmesg content in $KDUMP_REMOTE_HOST:$KDUMP_STAMPDIR"
+ return 0;
+ else
+ log_failure_msg "$NAME: failed to save dmesg content in $KDUMP_REMOTE_HOST:$KDUMP_STAMPDIR"
+ logger -t $NAME "failed to save dmesg content in $KDUMP_REMOTE_HOST:$KDUMP_STAMPDIR"
+ return 1;
+ fi
+ fi
+}
+
+function kdump_propagate()
+{
+ KDUMP_SSH_KEY="${SSH_KEY:=/root/.ssh/kdump_id_rsa}"
+ KDUMP_REMOTE_HOST="$SSH"
+
+ # ssh key propagation is only needed
+ # if remote ssh dump is configured
+ if [ -z "$KDUMP_REMOTE_HOST" ];then
+ log_failure_msg "$NAME: Remote ssh dump is not configured. No reason to propagate"
+ logger -t $NAME "Remote ssh dump is not configured. No reason to propagate"
+ return 1;
+ fi
+
+ # Verify if the provided key exists and create it if needed
+ if [ -f "$KDUMP_SSH_KEY" ];then
+ echo "Using existing key $KDUMP_SSH_KEY"
+ else
+ echo "Need to generate a new ssh key..."
+ /usr/bin/ssh-keygen -t rsa -f $KDUMP_SSH_KEY -N "" 2>&1 > /dev/null
+ fi
+
+ KDUMP_SSH_USER=${KDUMP_REMOTE_HOST%@*}
+ KDUMP_SSH_TARGET=${KDUMP_REMOTE_HOST#*@}
+
+ ssh-copy-id -i $KDUMP_SSH_KEY $KDUMP_SSH_USER@$KDUMP_SSH_TARGET &>/dev/null
+ ERROR=$?
+
+ if [ $ERROR -ne 0 ];then
+ log_failure_msg "$NAME: $KDUMP_SSH_KEY failed to be sent to $KDUMP_REMOTE_HOST"
+ logger -t $NAME "$KDUMP_SSH_KEY failed to be sent to $KDUMP_REMOTE_HOST"
+ return 1;
+ else
+ logger -t $NAME "propagated ssh key $KDUMP_SSH_KEY to server $KDUMP_REMOTE_HOST"
+ echo "propagated ssh key $KDUMP_SSH_KEY to server $KDUMP_REMOTE_HOST"
+ return 0;
+ fi
+
+}
+
+
+
+case "$1" in
+ test)
+ DRY_RUN="true"
+ if [ "$DUMP_MODE" == "fadump" ]; then
+ check_fadump_support
+ else
+ check_kdump_support;
+ manage_symlinks;
+ locate_kdump_kernel;
+ kdump_load;
+ kdump_test
+ fi
+ ;;
+ show)
+ DRY_RUN="true"
+ if [ "$DUMP_MODE" == "fadump" ]; then
+ check_fadump_support;
+ else
+ check_kdump_support;
+ fi
+ kdump_show
+ ;;
+ load)
+ if [ "$DUMP_MODE" == "fadump" ]; then
+ check_fadump_support;
+ fadump_register
+ else
+ check_kdump_support;
+ kdump_create_symlinks $KVER;
+ manage_symlinks;
+ locate_kdump_kernel;
+ kdump_load
+ fi
+ ;;
+ unload)
+ if [ "$DUMP_MODE" == "fadump" ]; then
+ fadump_unregister
+ else
+ kdump_unload
+ fi
+ ;;
+ status)
+ if [ "$DUMP_MODE" == "fadump" ]; then
+ check_fadump_support
+ if [ `cat $sys_fadump_registered` -eq 1 ] ; then
+ echo "current state : ready to fadump";
+ else
+ echo "current state : Not ready to fadump";
+ fi
+ else
+ DRY_RUN=true
+ check_kdump_support;
+ manage_symlinks;
+ if [ `cat $sys_kexec_crash` -eq 1 ] ; then
+ echo "current state : ready to kdump";
+ else
+ echo "current state : Not ready to kdump";
+ fi
+ fi
+ exit 0;
+ ;;
+ savecore)
+ if ! [ -z $SSH ];then
+ kdump_save_core_to_ssh
+ else
+ kdump_save_core
+ fi
+ exit $?
+ ;;
+ propagate)
+ kdump_propagate;
+ ;;
+ symlinks)
+ if [ -z $2 ];then
+ log_failure_msg "Invalid argument : missing kernel version"
+ else
+ kdump_create_symlinks $2
+ fi
+ ;;
+ help|-h*|--h*)
+ kdump_help
+ ;;
+ *)
+ echo "Usage: $0 {help|test|show|status|load|unload|savecore|propagate|symlinks kernel-version}"
+ exit 1
+ ;;
+esac
+
+exit 0