Rev 95 | Blame | Compare with Previous | Last modification | View Log | RSS feed
#! /bin/sh### BEGIN INIT INFO# Provides: kdump# Default-Start: 3 4 5# Default-Stop: 0 1 6# Require-Start: $network $local_fs $remote_fs# Short-Description: start and stop kdump crash recovery service# 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.### END INIT INFO# Copyright 2005 Red Hat, Inc.## Author: Jeff Moyer <jmoyer@redhat.com># Source function library.. /etc/init.d/functionsKEXEC=/sbin/kexec# Will be different for ia64, for example. For now, that architecture isn't# supported. Code needs to be added here when we do.BOOTDIR="/boot"KDUMP_KERNELVER=""KDUMP_COMMANDLINE=""KDUMP_IDE_NOPROBE_COMMANDLINE=""KEXEC_ARGS=""KDUMP_CONFIG_FILE="/etc/kdump.conf"MEM_RESERVED=""MKDUMPRD_ARGS=""CLUSTER_CONFIG_FILE="/etc/cluster/cluster.conf"FENCE_KDUMP_CONFIG="/etc/sysconfig/fence_kdump"SSH_KEY_LOCATION="/root/.ssh/kdump_id_rsa"#kdump shall be the default dump modeDEFAULT_DUMP_MODE="kdump"LOGGER="/usr/bin/logger -p info -t kdump"standard_kexec_args="-p"if [ -f /etc/sysconfig/kdump ]; then. /etc/sysconfig/kdumpfifunction single_instance_lock(){exec 9>/var/lock/kdumpflock 9}determine_dump_mode(){# Check if firmware-assisted dump is enabled# if yes, set the dump mode as fadump and source# fadump related functionsfadump_enabled_sys_node="/sys/kernel/fadump_enabled"if [ -f $fadump_enabled_sys_node ]; thenrc=`cat $fadump_enabled_sys_node`if [ $rc -eq 1 ]; thenecho "kdump: dump mode is fadump"DEFAULT_DUMP_MODE="fadump". /etc/init.d/fadump-functionsfifi}# remove_cmdline_param <kernel cmdline> <param1> [<param2>] ... [<paramN>]# Remove a list of kernel parameters from a given kernel cmdline and print the result.# For each "arg" in the removing params list, "arg" and "arg=xxx" will be removed if exists.function remove_cmdline_param(){local cmdline=$1shiftfor arg in $@; docmdline=`echo $cmdline | \sed -e "s/\b$arg=[^ ]*\b//g" \-e "s/\b$arg\b//g"`doneecho $cmdline}function in_xen_pv_guest(){grep -q 'xen-percpu-virq *timer0' /proc/interrupts}function in_xen_hvm_guest(){grep -q "xen" /sys/hypervisor/type >& /dev/null && ! grep -q 'xen-percpu-virq *timer0' /proc/interrupts}function check_xen_hvm_nopv_premkdumprd(){if in_xen_hvm_guest; thenif grep -q "xen_.*front" /proc/modules; thenreturn 1fifi}function save_kernel_logs(){local _path=$1mkdir -p $_pathif [ ! -f /sbin/vmcore-dmesg ];then$LOGGER "Skipping saving vmcore-dmesg.txt. File /sbin/vmcore-dmesg is not present"return;fiecho "kdump: saving vmcore-dmesg.txt to $_path"$LOGGER "saving vmcore-dmesg.txt to $_path"/sbin/vmcore-dmesg /proc/vmcore > $_path/vmcore-dmesg-incomplete.txtif [ $? == 0 ]; thenmv $_path/vmcore-dmesg-incomplete.txt $_path/vmcore-dmesg.txtecho "kdump: saved vmcore-dmesg.txt to $_path"$LOGGER "saved vmcore-dmesg.txt to $_path"elseecho "kdump: failed to save vmcore-dmesg.txt to $_path"$LOGGER "failed to save vmcore-dmesg.txt to $_path"fi}## This function returns the "initial apicid" of the# boot cpu (cpu 0) if present.#function get_bootcpu_initial_apicid(){awk ' \BEGIN { CPU = "-1"; } \$1=="processor" && $2==":" { CPU = $NF; } \CPU=="0" && /initial apicid/ { print $NF; } \' \/proc/cpuinfo}## This function appends argument "$2=$3" to string ($1) if not already present.#function append_cmdline(){local cmdline=$1local newstr=${cmdline/$2/""}# unchanged str implies argument wasn't thereif [ "$cmdline" == "$newstr" ]; thencmdline="${cmdline} ${2}=${3}"fiecho $cmdline}# This function fix root=by-path, since we can not parse it in the 2nd kernelfunction fix_cmdline_rootdev(){local cmdline=$1local rootdevlocal rootuuidlocal is_bypathrootdev=$(echo $cmdline | sed 's/^.*root=//' | cut -d" " -f1)if [ -n "$rootdev" ]; thenis_bypath=$(echo $rootdev| grep by-path)if [ -n "$is_bypath" ]; thencmdline=`remove_cmdline_param "$cmdline" root`rootuuid=`findmnt -k -f -n -r -o UUID /`if [ -n "$rootuuid" ]; thencmdline="$cmdline root=UUID=$rootuuid"fififiecho $cmdline}# This function performs a series of edits on the command linefunction prepare_cmdline(){local cmdline;if [ -z "$KDUMP_COMMANDLINE" ]; thencmdline=`cat /proc/cmdline`elsecmdline=${KDUMP_COMMANDLINE}ficmdline=`remove_cmdline_param "$cmdline" crashkernel mem hugepages hugepagesz`cmdline=$(fix_cmdline_rootdev "$cmdline")cmdline="${cmdline} ${KDUMP_COMMANDLINE_APPEND}"avoid_cdrom_driveKDUMP_COMMANDLINE="${KDUMP_COMMANDLINE} ${KDUMP_IDE_NOPROBE_COMMANDLINE}"local id=`get_bootcpu_initial_apicid`if [ ! -z ${id} ] ; thencmdline=`append_cmdline "${cmdline}" disable_cpu_apicid ${id}`fiecho $cmdline}function save_core(){local kdump_pathkdump_path=`grep ^path $KDUMP_CONFIG_FILE | cut -d' ' -f2-`if [ -z "$kdump_path" ]; thencoredir="/var/crash/127.0.0.1-`date +"%Y-%m-%d-%H:%M"`"elsecoredir="${kdump_path}/127.0.0.1-`date +"%Y-%m-%d-%H:%M"`"fimkdir -p $coredirsave_kernel_logs "${coredir}"/usr/sbin/makedumpfile -c --message-level 1 -d 31 /proc/vmcore $coredir/vmcore-incompleteif [ $? == 0 ]; thenmv $coredir/vmcore-incomplete $coredir/vmcore$LOGGER "saved a vmcore to $coredir"else$LOGGER "failed to save a vmcore to $coredir"fi}function check_kdump_config(){local modified_files=""local force_rebuild=0MKDUMPRD="/sbin/mkdumprd -d -f $MKDUMPRD_ARGS"force_rebuild=`grep ^force_rebuild $KDUMP_CONFIG_FILE | cut -d' ' -f2`if [ -n "$force_rebuild" ] && [ "$force_rebuild" -ne 0 ]thenmodified_files="force_rebuild"fiif [ -z "$KDUMP_KERNELVER" ]; thenlocal running_kernel=`uname -r`kdump_kver=`echo $running_kernel | sed 's/smp//g'`elsekdump_kver=$KDUMP_KERNELVERfikdump_kernel="${KDUMP_BOOTDIR}/${KDUMP_IMG}-${kdump_kver}${KDUMP_IMG_EXT}"kdump_initrd="${KDUMP_BOOTDIR}/initrd-${kdump_kver}kdump.img"if [ ! -f $kdump_kernel ]; thenecho -n "No kdump kernel image found."; warning; echoecho "Tried to locate ${kdump_kernel}"return 0fiif [ ! -f $kdump_initrd ]; thenecho -n "No kdump initial ramdisk found."; warning; echoif ! check_xen_hvm_nopv_premkdumprd; thenecho "hvm guest with pv drivers is not supported."exit 1fiecho "Rebuilding $kdump_initrd"$MKDUMPRD $kdump_initrd $kdump_kverif [ $? != 0 ]; thenecho "Failed to run mkdumprd"$LOGGER "mkdumprd: failed to make kdump initrd"rm -f $kdump_initrdexit 1fireturn 0fiif [ -z "$modified_files" ]then#check to see if config file or kdump post has been modified#since last build of the image fileimage_time=`stat -c "%Y" $kdump_initrd`EXTRA_FILES=`grep ^kdump_post $KDUMP_CONFIG_FILE | cut -d\ -f2`CHECK_FILE=`grep ^kdump_pre $KDUMP_CONFIG_FILE | cut -d\ -f2`EXTRA_FILES="$EXTRA_FILES $CHECK_FILE"CHECK_FILE=`grep ^extra_modules $KDUMP_CONFIG_FILE | cut -d\ -f2-`EXTRA_FILES="$EXTRA_FILES $CHECK_FILE"CHECK_FILE=`grep ^extra_bins $KDUMP_CONFIG_FILE | cut -d\ -f2-`EXTRA_FILES="$EXTRA_FILES $CHECK_FILE"FORCE_REBUILD=`grep ^extra_modules $KDUMP_CONFIG_FILE`files="$KDUMP_CONFIG_FILE $kdump_kernel $EXTRA_FILES"# changes in CLUSTER_CONFIG_FILE should be monitored only if fence_kdump# is not configured using fence_kdump_nodes option in /etc/kdump.conf# and fence_kdump is configured in Pacemaker clusterif ! grep -q ^fence_kdump_nodes /etc/kdump.conf \&& [ -f "$CLUSTER_CONFIG_FILE" ] \&& grep -q fence_kdump "$CLUSTER_CONFIG_FILE"thenfiles="$files $CLUSTER_CONFIG_FILE"if [ -f "$FENCE_KDUMP_CONFIG" ]; thenfiles="$files $FENCE_KDUMP_CONFIG"fififor file in $files; dotime_stamp=0if [ -f "$file" ]; thentime_stamp=`stat -c "%Y" $file`elsemodified_files="$modified_files $file"continuefiif [ "$time_stamp" -gt "$image_time" ]; thenmodified_files="$modified_files $file"fidonefiif [ -n "$FORCE_REBUILD" -a "$modified_files"!=" " ]thenmodified_files="force_rebuild"fiif [ -n "$modified_files" -a "$modified_files"!=" " ]; thenif [ "$modified_files" != "force_rebuild" ]thenecho "Detected change(s) the following file(s):"echo -n " "; echo "$modified_files" | sed 's/\s/\n /g'fiif ! check_xen_hvm_nopv_premkdumprd; thenecho "hvm guest with pv drivers is not supported."exit 1fiecho "Rebuilding $kdump_initrd"$MKDUMPRD $kdump_initrd $kdump_kverif [ $? != 0 ]; thenecho "Failed to run mkdumprd"$LOGGER "mkdumprd: failed to make kdump initrd"rm -f $kdump_initrdreturn 1fifi#double check the xen_*front modules are not included for xen hvmif in_xen_hvm_guest; thenif $(lsinitrd $kdump_initrd|grep -q "xen_.*front.ko"); thenecho "Found xen pv drivers in kdump initrd"exit 1fifireturn 0}function check_config(){if [ $DEFAULT_DUMP_MODE == "fadump" ]; thencheck_fadump_configelsecheck_kdump_configfireturn $?}# This function check iomem and determines if we have more than# 4GB of ram available. Returns 1 if we do, 0 if we dontfunction need_64bit_headers(){return `tail -n 1 /proc/iomem | awk '{ split ($1, r, "-"); \print (strtonum("0x" r[2]) > strtonum("0xffffffff")); }'`}function avoid_cdrom_drive(){local DRIVE=""local MEDIA=""local IDE_DRIVES=(`echo hd{a,b,c,d}`)local COUNTER="0"for DRIVE in ${IDE_DRIVES[@]}doif ! $(echo "$KDUMP_COMMANDLINE" |grep -q "$DRIVE=");thenif [ -f /proc/ide/$DRIVE/media ];thenMEDIA=$(cat /proc/ide/$DRIVE/media)if [ x"$MEDIA" == x"cdrom" ]; thenKDUMP_IDE_NOPROBE_COMMANDLINE="$KDUMP_IDE_NOPROBE_COMMANDLINE $DRIVE=cdrom"COUNTER=$(($COUNTER+1))fifielseKDUMP_IDE_NOPROBE_COMMANDLINE="$KDUMP_IDE_NOPROBE_COMMANDLINE $DRIVE=noprobe"fidone# We don't find cdrom drive.if [ $COUNTER -eq 0 ]; thenKDUMP_IDE_NOPROBE_COMMANDLINE=""fi}function check_kernel_parameter(){if [ -z "$KDUMP_COMMANDLINE" ]thenKDUMP_COMMANDLINE=`cat /proc/cmdline`fiMEM_RESERVED=`cat /sys/kernel/kexec_crash_size`if [ $MEM_RESERVED -eq 0 ]thenreturn 1elsereturn 0fi}# Load the kdump kernel specified in /etc/sysconfig/kdump# If none is specified, try to load a kdump kernel with the same version# as the currently running kernel.function load_kdump(){ARCH=`uname -m`# Get the approx amount of ram the kernel is using in KbKMEMINUSE=`awk '/Slab:.*/ {print $2}' /proc/meminfo`# Convert the reserved ram amount to KbMEM_RESERVED=`dc -e"$MEM_RESERVED 1024 / p"`# Take 70% of the reserved value rounding up to the nearest integerMEM_RESERVED=`dc -e"$MEM_RESERVED .7 * 10 * 10 / p"`#On x86, we are using nr_cpus=1, so the following check is not necessary.if [ "$ARCH" != "i686" -a "$ARCH" != "i386" -a "$ARCH" != "x86_64" ]then#Check if the KMEMINUSE is greater than MEM_RESERVED# This indicates that the currently runnign kernel is using# 70% of the amount of memory that we have reserved for kdump# we should issue a warning here indicating that the user may# want to increase the amount of reserved ram on the systemif [ $KMEMINUSE -gt $MEM_RESERVED ]thenecho -n "Your running kernel is using more than 70% of the amount of space you reserved for kdump, you should consider increasing your crashkernel reservation"warningechofifiif [ "$ARCH" == "i686" -o "$ARCH" == "i386" ]thenneed_64bit_headersif [ $? == 1 ]thenFOUND_ELF_ARGS=`echo $KEXEC_ARGS | grep elf32-core-headers`if [ -n "$FOUND_ELF_ARGS" ]thenecho -n "Warning: elf32-core-headers overrides correct elf64 setting"warningechoelseKEXEC_ARGS="$KEXEC_ARGS --elf64-core-headers"fielseFOUND_ELF_ARGS=`echo $KEXEC_ARGS | grep elf64-core-headers`if [ -z "$FOUND_ELF_ARGS" ]thenKEXEC_ARGS="$KEXEC_ARGS --elf32-core-headers"fififiif [ -f /sys/firmware/efi/systab ]thenif grep -q '^ACPI20=' /sys/firmware/efi/systabthenacpi_addr=$(awk -F'=' '/^ACPI20=/ {print $2}' /sys/firmware/efi/systab)elseacpi_addr=$(awk -F'=' '/^ACPI=/ {print $2}' /sys/firmware/efi/systab)fiKDUMP_COMMANDLINE="$KDUMP_COMMANDLINE noefi acpi_rsdp=$acpi_addr"smbios_addr=$(awk -F'=' '/^SMBIOS=/ {print $2}' /sys/firmware/efi/systab)if [ -n "$smbios_addr" ]; thenKDUMP_COMMANDLINE="$KDUMP_COMMANDLINE efi_smbios_addr=$smbios_addr"fifiif echo "$KDUMP_COMMANDLINE_APPEND" | grep -q nr_cpus;thenver=`uname -r`maj=`echo $ver | cut -d'-' -f1`min=`echo $ver | cut -d'-' -f2`min=${min%%.*}if [ "$maj" = "2.6.32" ] && [ $min -lt 171 ]thenecho "Your kernel is old, please use maxcpus=1 instead of nr_cpus=1"return 1fifiKDUMP_COMMANDLINE=`prepare_cmdline`if ! grep -q /sys/kernel/debug /proc/mounts;thenmount -t debugfs debug /sys/kernel/debugMNTDEBUG=/sys/kernel/debugfi$KEXEC $KEXEC_ARGS $standard_kexec_args \--command-line="$KDUMP_COMMANDLINE" \--initrd=$kdump_initrd $kdump_kernel 2>/dev/nullif [ $? == 0 ]; thenumount $MNTDEBUG 2>/dev/null$LOGGER "kexec: loaded kdump kernel"return 0elseumount $MNTDEBUG 2>/dev/null$LOGGER "kexec: failed to load kdump kernel"return 1fi}function propagate_ssh_key(){while read config_opt config_val; docase "$config_opt" insshkey)SSH_KEY_LOCATION="$config_val";;*);;esacdone < $KDUMP_CONFIG_FILElocal KEYFILE=$SSH_KEY_LOCATIONlocal errmsg="Failed to propagate ssh key"#make sure they've configured kdump.conf for ssh dumpslocal SSH_TARGET=`awk '/^\ *net.*@.*$/ {print $0}' $KDUMP_CONFIG_FILE`[ -z "$SSH_TARGET" ] && SSH_TARGET=`awk '/^\ *ssh.*@.*$/ {print $0}' $KDUMP_CONFIG_FILE`if [ -z "$SSH_TARGET" ]; thenecho "No ssh config specified in $KDUMP_CONFIG_FILE. Can't propagate"$LOGGER "$errmsg, no ssh config specified in $KDUMP_CONFIG_FILE"exit 1fi#Check to see if we already created key, if not, create it.if [ -f $KEYFILE ]; thenecho "Using existing keys..."elseecho -n "Generating new ssh keys... "/usr/bin/ssh-keygen -t rsa -f $KEYFILE -N "" 2>&1 > /dev/nullecho "done."fi#now find the target ssh user and server to contact.SSH_USER=`echo $SSH_TARGET | cut -d\ -f2 | cut -d@ -f1`SSH_SERVER=`echo $SSH_TARGET | sed -e's/\(.*@\)\(.*$\)/\2/'`#now send the found key to the found serverssh-copy-id -i $KEYFILE $SSH_USER@$SSH_SERVER &>/dev/nullRET=$?if [ $RET == 0 ]; thenecho $KEYFILE has been added to ~$SSH_USER/.ssh/authorized_keys on $SSH_SERVER$LOGGER "propagated ssh key (ssh server: $SSH_SERVER)"return 0elseecho $KEYFILE failed in transfer to $SSH_SERVER$LOGGER "$errmsg, unable to transfer $KEYFILE to $SSH_SERVER"exit 1fi}function status(){if [ $DEFAULT_DUMP_MODE == "fadump" ]; thencheck_current_fadump_statusreturn $?fiif [ ! -e /sys/kernel/kexec_crash_loaded ]thenreturn 2fiif in_xen_pv_guest; thenreturn 2elif in_xen_hvm_guest && ! grep -q -e xen_emul_unplug=never -e xen_emul_unplug=unnecessary /proc/cmdline; thenecho 'kdump only supported on xen hvm guests booted with xen_emul_unplug=never or xen_emul_unplug=unnecessary'return 2firc=`cat /sys/kernel/kexec_crash_loaded`if [ $rc == 1 ]; thenreturn 0elsereturn 1fi}function save_raw(){local raw_part=$(awk '$1 ~ /^raw$/ { print $2; }' $KDUMP_CONFIG_FILE)local kdump_dirif [ "$raw_part" ]; then[ -b "$raw_part" ] || {echo "raw partition $raw_part not found"return 1}kdump_dir=`grep ^path $KDUMP_CONFIG_FILE | cut -d' ' -f2-`if [ -z "${kdump_dir}" ]; thencoredir="/var/crash/`date +"%Y-%m-%d-%H:%M"`"elsecoredir="${kdump_dir}/`date +"%Y-%m-%d-%H:%M"`"fimkdir -p "$coredir"[ -d "$coredir" ] || {echo "failed to create $coredir"return 1}if makedumpfile -R $coredir/vmcore <$raw_part >/dev/null 2>&1; then# dump foundecho "Dump saved to $coredir/vmcore"# wipe makedumpfile headerdd if=/dev/zero of=$raw_part bs=1b count=1 2>/dev/nullelserm -rf "$coredir"fifireturn 0}get_save_path() {local _save_path=$(grep "^path" /etc/kdump.conf|awk '{print $2}')if [ -z "$_save_path" ]; then_save_path="/var/crash"fiecho $_save_path}is_dump_target_configured() {local _target_target=$(egrep "^ext[234]|^xfs|^btrfs|^raw|^ssh|^nfs|^nfs4|^net" /etc/kdump.conf)[ -n "$_target" ]}local_fs_dump_target(){local _target_target=$(egrep "^ext[234]|^xfs|^btrfs" /etc/kdump.conf)if [ $? -eq 0 ]; thenecho $_target|awk '{print $2}'fi}path_to_be_relabeled() {local _path _target _mnt="/" _rmntif is_dump_target_configured; then_target=$(local_fs_dump_target)if [[ -n "$_target" ]]; then_mnt=$(findmnt -k -f -n -r -o TARGET $_target)if [ -z "$_mnt" ]; thenreturnfielsereturnfifi_path=$(get_save_path)# if $_path is masked by other mount, we will not relabel it.# one exception is ! is_dump_target_configure && "$_rmnt" != "$_mnt"# for this exception see mkdumprd code about [ -z "$USING_METHOD" ]_rmnt=$(df $_mnt/$_path 2>/dev/null | tail -1 | awk '{ print $NF }')if [[ "$_rmnt" == "$_mnt" ]] || ! is_dump_target_configured; thenecho $_mnt/$_pathfi}selinux_relabel(){local _path _i _attr_path=$(path_to_be_relabeled)if [ -z "$_path" ] || ! [ -d "$_path" ] ; thenreturnfifor _i in $(find $_path); do_attr=$(getfattr -m "security.selinux" $_i 2>/dev/null)if [ -z "$_attr" ]; thenrestorecon $_i;fidone}start_dump(){if [ $DEFAULT_DUMP_MODE == "fadump" ]; thenstart_fadumpelseload_kdumpfireturn $?}# Notes about xen support:# pv guests are not supported# hvm guests are supported only when you ensure below items:# 1. Boot guests with either xen_emul_unplug=never or# xen_emul_unplug=unnecessary.# 2. While recreating kdump initrd xen_netfront and xen_blkfront modules# are not loadedfunction start(){if sestatus 2>/dev/null | grep -q "SELinux status.*enabled"; thenselinux_relabelfisave_rawif [ $? -ne 0 ]; thenecho -n "Starting kdump:"; failure; echo$LOGGER "failed to start up"return 1fistatusrc=$?if [ $rc == 2 ]; thenecho -n "Kdump is not supported on this kernel"; failure; echoreturn 1;elseif [ $rc == 0 ]; thenecho -n "Kdump already running"; success; echoreturn 0fifi# Kernel parameter check is not required for fadump as 'fadump=on'# should have already been passed if dump mode is fadumpif [ $DEFAULT_DUMP_MODE != "fadump" ]; thencheck_kernel_parameterif [ $? != 0 ]; thenecho -n "Starting kdump:"; failure; echo$LOGGER "No crashkernel parameter specified for running kernel"return 1fificheck_configif [ $? != 0 ]; thenecho -n "Starting kdump:"; failure; echo$LOGGER "failed to start up, config file incorrect"return 1fistart_dumpif [ $? != 0 ]; thenecho -n "Starting kdump:"; failure; echo$LOGGER "failed to start up"return 1fiecho -n "Starting kdump:"; success; echo$LOGGER "started up"}stop_kdump(){$KEXEC -p -u 2>/dev/nullif [ $? != 0 ]; then$LOGGER "kexec: failed to unload kdump kernel"return 1fi$LOGGER "kexec: unloaded kdump kernel"return 0}function stop(){if [ $DEFAULT_DUMP_MODE == "fadump" ]; thenstop_fadumpelsestop_kdumpfiif [ $? != 0 ]; thenecho -n "Stopping kdump:"; failure; echo$LOGGER "failed to stop"return 1fiecho -n "Stopping kdump:"; success; echo$LOGGER "stopped"return 0}# Other kdump init instances will block in queue, until this one exits.single_instance_lock# Determine if the dump mode is kdump or fadumpdetermine_dump_modecase "$1" instart)if [ $DEFAULT_DUMP_MODE == "fadump" ] && is_fadump_save_paththen# fadump: second boot after crash, save vmcoresave_fadump_coreif [ $? -eq 0 ]; thenrebootelsesave_fadump_core_on_errorhandle_fadump_default_actionfielif [ -s /proc/vmcore ]; thensave_corerebootelsestartfi;;stop)stop;;status)EXIT_CODE=0statuscase "$?" in0)echo "Kdump is operational"EXIT_CODE=0;;1)echo "Kdump is not operational"EXIT_CODE=3;;2)echo "Kdump is unsupported on this kernel"EXIT_CODE=3;;esacexit $EXIT_CODE;;restart)stopstart;;condrestart)EXIT_CODE=1statuscase "$?" in0)stopstartEXIT_CODE=0;;esacexit $EXIT_CODE;;propagate)propagate_ssh_key;;*)echo $"Usage: $0 {start|stop|status|restart|propagate}"exit 1esacexit $?