diff --git a/.kexec-tools.metadata b/.kexec-tools.metadata new file mode 100644 index 0000000..e519eef --- /dev/null +++ b/.kexec-tools.metadata @@ -0,0 +1,4 @@ +dcdb6d2488c8a31ae95563e2113860ae16256c8f SOURCES/eppic_030413.tar.gz +d903c5631b96913a4b31d4cc5df8aab4837e0e45 SOURCES/kexec-tools-po.tar.gz +f119507a92446bcda58b108fd7f61e6d9f187358 SOURCES/kexec-tools-2.0.4.tar.bz2 +077dfb8fbf2f12b5efca385eb1fda55dee2096d5 SOURCES/makedumpfile-1.5.4.tar.gz diff --git a/README.md b/README.md deleted file mode 100644 index 0e7897f..0000000 --- a/README.md +++ /dev/null @@ -1,5 +0,0 @@ -The master branch has no content - -Look at the c7 branch if you are working with CentOS-7, or the c4/c5/c6 branch for CentOS-4, 5 or 6 - -If you find this file in a distro specific branch, it means that no content has been checked in yet diff --git a/SOURCES/98-kexec.rules b/SOURCES/98-kexec.rules new file mode 100644 index 0000000..8c742dd --- /dev/null +++ b/SOURCES/98-kexec.rules @@ -0,0 +1,4 @@ +SUBSYSTEM=="cpu", ACTION=="online", PROGRAM="/bin/systemctl try-restart kdump.service" +SUBSYSTEM=="cpu", ACTION=="offline", PROGRAM="/bin/systemctl try-restart kdump.service" +SUBSYSTEM=="memory", ACTION=="add", PROGRAM="/bin/systemctl try-restart kdump.service" +SUBSYSTEM=="memory", ACTION=="remove", PROGRAM="/bin/systemctl try-restart kdump.service" diff --git a/SOURCES/dracut-kdump.sh b/SOURCES/dracut-kdump.sh new file mode 100755 index 0000000..f38891d --- /dev/null +++ b/SOURCES/dracut-kdump.sh @@ -0,0 +1,328 @@ +#!/bin/sh + +exec &> /dev/console +. /lib/dracut-lib.sh +. /lib/kdump-lib.sh + +if [ -f "$initdir/lib/dracut/no-emergency-shell" ]; then + rm -f -- $initdir/lib/dracut/no-emergency-shell +fi + +set -o pipefail +KDUMP_PATH="/var/crash" +CORE_COLLECTOR="" +DEFAULT_CORE_COLLECTOR="makedumpfile -c --message-level 1 -d 31" +DMESG_COLLECTOR="/sbin/vmcore-dmesg" +DEFAULT_ACTION="reboot -f" +DATEDIR=`date +%Y.%m.%d-%T` +HOST_IP='127.0.0.1' +DUMP_INSTRUCTION="" +SSH_KEY_LOCATION="/root/.ssh/kdump_id_rsa" +KDUMP_SCRIPT_DIR="/kdumpscripts" +DD_BLKSIZE=512 +FINAL_ACTION="reboot -f" +DUMP_RETVAL=0 +conf_file="/etc/kdump.conf" +KDUMP_PRE="" +KDUMP_POST="" +MOUNTS="" + +export PATH=$PATH:$KDUMP_SCRIPT_DIR + +do_dump() +{ + local _ret + + eval $DUMP_INSTRUCTION + _ret=$? + + if [ $_ret -ne 0 ]; then + echo "kdump: saving vmcore failed" + fi + + return $_ret +} + +do_umount() +{ + if [ -n "$MOUNTS" ]; then + for mount in $MOUNTS; do + ismounted $mount && umount -R $mount + done + fi +} + +do_final_action() +{ + do_umount + eval $FINAL_ACTION +} + +do_default_action() +{ + wait_for_loginit + eval $DEFAULT_ACTION +} + +do_kdump_pre() +{ + if [ -n "$KDUMP_PRE" ]; then + "$KDUMP_PRE" + fi +} + +do_kdump_post() +{ + if [ -n "$KDUMP_POST" ]; then + "$KDUMP_POST" "$1" + fi +} + +add_dump_code() +{ + DUMP_INSTRUCTION=$1 +} + +# dump_fs +dump_fs() +{ + local _dev=$(findmnt -k -f -n -r -o SOURCE $1) + local _mp=$(findmnt -k -f -n -r -o TARGET $1) + + echo "kdump: dump target is $_dev" + + if [ -z "$_mp" ]; then + echo "kdump: error: Dump target $_dev is not mounted." + return 1 + fi + MOUNTS="$MOUNTS $_mp" + + # Remove -F in makedumpfile case. We don't want a flat format dump here. + [[ $CORE_COLLECTOR = *makedumpfile* ]] && CORE_COLLECTOR=`echo $CORE_COLLECTOR | sed -e "s/-F//g"` + + echo "kdump: saving to $_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR/" + + mount -o remount,rw $_mp || return 1 + mkdir -p $_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR || return 1 + + save_vmcore_dmesg_fs ${DMESG_COLLECTOR} "$_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR/" + + echo "kdump: saving vmcore" + $CORE_COLLECTOR /proc/vmcore $_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR/vmcore-incomplete || return 1 + mv $_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR/vmcore-incomplete $_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR/vmcore + sync + + echo "kdump: saving vmcore complete" + return 0 +} + +dump_raw() +{ + local _raw=$1 + + [ -b "$_raw" ] || return 1 + + echo "kdump: saving to raw disk $_raw" + + if ! $(echo -n $CORE_COLLECTOR|grep -q makedumpfile); then + _src_size=`ls -l /proc/vmcore | cut -d' ' -f5` + _src_size_mb=$(($_src_size / 1048576)) + monitor_dd_progress $_src_size_mb & + fi + + echo "kdump: saving vmcore" + $CORE_COLLECTOR /proc/vmcore | dd of=$_raw bs=$DD_BLKSIZE >> /tmp/dd_progress_file 2>&1 || return 1 + sync + + echo "kdump: saving vmcore complete" + return 0 +} + +dump_ssh() +{ + local _opt="-i $1 -o BatchMode=yes -o StrictHostKeyChecking=yes" + local _dir="$KDUMP_PATH/$HOST_IP-$DATEDIR" + local _host=$2 + + echo "kdump: saving to $_host:$_dir" + + cat /var/lib/random-seed > /dev/urandom + ssh -q $_opt $_host mkdir -p $_dir || return 1 + + save_vmcore_dmesg_ssh ${DMESG_COLLECTOR} ${_dir} "${_opt}" $_host + + echo "kdump: saving vmcore" + + if [ "${CORE_COLLECTOR%%[[:blank:]]*}" = "scp" ]; then + scp -q $_opt /proc/vmcore "$_host:$_dir/vmcore-incomplete" || return 1 + ssh $_opt $_host "mv $_dir/vmcore-incomplete $_dir/vmcore" || return 1 + else + $CORE_COLLECTOR /proc/vmcore | ssh $_opt $_host "dd bs=512 of=$_dir/vmcore-incomplete" || return 1 + ssh $_opt $_host "mv $_dir/vmcore-incomplete $_dir/vmcore.flat" || return 1 + fi + + echo "kdump: saving vmcore complete" + return 0 +} + +save_vmcore_dmesg_fs() { + local _dmesg_collector=$1 + local _path=$2 + + echo "kdump: saving vmcore-dmesg.txt" + $_dmesg_collector /proc/vmcore > ${_path}/vmcore-dmesg-incomplete.txt + _exitcode=$? + if [ $_exitcode -eq 0 ]; then + mv ${_path}/vmcore-dmesg-incomplete.txt ${_path}/vmcore-dmesg.txt + echo "kdump: saving vmcore-dmesg.txt complete" + else + echo "kdump: saving vmcore-dmesg.txt failed" + fi +} + +save_vmcore_dmesg_ssh() { + local _dmesg_collector=$1 + local _path=$2 + local _opts="$3" + local _location=$4 + + echo "kdump: saving vmcore-dmesg.txt" + $_dmesg_collector /proc/vmcore | ssh $_opts $_location "dd of=$_path/vmcore-dmesg-incomplete.txt" + _exitcode=$? + + if [ $_exitcode -eq 0 ]; then + ssh -q $_opts $_location mv $_path/vmcore-dmesg-incomplete.txt $_path/vmcore-dmesg.txt + echo "kdump: saving vmcore-dmesg.txt complete" + else + echo "kdump: saving vmcore-dmesg.txt failed" + fi +} + + +get_host_ip() +{ + local _host + if is_nfs_dump_target || is_ssh_dump_target + then + kdumpnic=$(getarg kdumpnic=) + [ -z "$kdumpnic" ] && echo "kdump: failed to get kdumpnic!" && return 1 + _host=`ip addr show dev $kdumpnic|grep 'inet '` + [ $? -ne 0 ] && echo "kdump: wrong kdumpnic: $kdumpnic" && return 1 + _host="${_host##*inet }" + _host="${_host%%/*}" + [ -z "$_host" ] && echo "kdump: wrong kdumpnic: $kdumpnic" && return 1 + HOST_IP=$_host + fi + return 0 +} + +read_kdump_conf() +{ + if [ ! -f "$conf_file" ]; then + echo "kdump: $conf_file not found" + return + fi + + # first get the necessary variables + while read config_opt config_val; + do + # remove inline comments after the end of a directive. + config_val=$(strip_comments $config_val) + case "$config_opt" in + path) + KDUMP_PATH="$config_val" + ;; + core_collector) + [ -n "$config_val" ] && CORE_COLLECTOR="$config_val" + ;; + sshkey) + if [ -f "$config_val" ]; then + SSH_KEY_LOCATION=$config_val + fi + ;; + kdump_pre) + KDUMP_PRE="$config_val" + ;; + kdump_post) + KDUMP_POST="$config_val" + ;; + default) + case $config_val in + shell) + DEFAULT_ACTION="_emergency_shell kdump" + ;; + reboot) + DEFAULT_ACTION="do_umount; reboot -f" + ;; + halt) + DEFAULT_ACTION="do_umount; halt -f" + ;; + poweroff) + DEFAULT_ACTION="do_umount; poweroff -f" + ;; + dump_to_rootfs) + DEFAULT_ACTION="dump_fs $NEWROOT" + ;; + esac + ;; + esac + done < $conf_file + + # rescan for add code for dump target + while read config_opt config_val; + do + # remove inline comments after the end of a directive. + config_val=$(strip_comments $config_val) + case "$config_opt" in + ext[234]|xfs|btrfs|minix|nfs) + add_dump_code "dump_fs $config_val" + ;; + raw) + add_dump_code "dump_raw $config_val" + ;; + ssh) + add_dump_code "dump_ssh $SSH_KEY_LOCATION $config_val" + ;; + esac + done < $conf_file +} + +read_kdump_conf + +if [ -z "$CORE_COLLECTOR" ];then + CORE_COLLECTOR=$DEFAULT_CORE_COLLECTOR + if is_ssh_dump_target || is_raw_dump_target; then + CORE_COLLECTOR="$CORE_COLLECTOR -F" + fi +fi + +get_host_ip +if [ $? -ne 0 ]; then + echo "kdump: get_host_ip exited with non-zero status!" + do_default_action + do_final_action +fi + +if [ -z "$DUMP_INSTRUCTION" ]; then + add_dump_code "dump_fs $NEWROOT" +fi + +do_kdump_pre +if [ $? -ne 0 ]; then + echo "kdump: kdump_pre script exited with non-zero status!" + do_final_action +fi + +do_dump +DUMP_RETVAL=$? + +do_kdump_post $DUMP_RETVAL +if [ $? -ne 0 ]; then + echo "kdump: kdump_post script exited with non-zero status!" +fi + +if [ $DUMP_RETVAL -ne 0 ]; then + do_default_action +fi + +do_final_action diff --git a/SOURCES/dracut-module-setup.sh b/SOURCES/dracut-module-setup.sh new file mode 100755 index 0000000..c013430 --- /dev/null +++ b/SOURCES/dracut-module-setup.sh @@ -0,0 +1,420 @@ +#!/bin/bash + +. $dracutfunctions +. /lib/kdump/kdump-lib.sh + +check() { + [[ $debug ]] && set -x + #kdumpctl sets this explicitly + if [ -z "$IN_KDUMP" ] || [ ! -f /etc/kdump.conf ] + then + return 1 + fi + return 0 +} + +depends() { + local _dep="base shutdown" + + if [ -d /sys/module/drm/drivers ]; then + _dep="$_dep drm" + fi + + echo $_dep + return 0 +} + +kdump_to_udev_name() { + local dev="${1//\"/}" + + case "$dev" in + UUID=*) + dev=`blkid -U "${dev#UUID=}"` + ;; + LABEL=*) + dev=`blkid -L "${dev#LABEL=}"` + ;; + esac + echo $(get_persistent_dev "$dev") +} + +kdump_is_bridge() { + [ -d /sys/class/net/"$1"/bridge ] +} + +kdump_is_bond() { + [ -d /sys/class/net/"$1"/bonding ] +} + +kdump_is_team() { + [ -f /usr/bin/teamnl ] && teamnl $1 ports &> /dev/null +} + +kdump_is_vlan() { + [ -f /proc/net/vlan/"$1" ] +} + +# $1: netdev name +kdump_setup_dns() { + _dnsfile=${initdir}/etc/cmdline.d/42dns.conf + . /etc/sysconfig/network-scripts/ifcfg-$1 + [ -n "$DNS1" ] && echo "nameserver=$DNS1" > "$_dnsfile" + [ -n "$DNS2" ] && echo "nameserver=$DNS2" >> "$_dnsfile" +} + +#$1: netdev name +#checking /etc/sysconfig/network-scripts/ifcfg-$1, +#if it use static ip echo it, or echo null +kdump_static_ip() { + . /etc/sysconfig/network-scripts/ifcfg-$1 + if [ -n "$IPADDR" ]; then + [ -z "$NETMASK" -a -n "$PREFIX" ] && \ + NETMASK=$(ipcalc -m $IPADDR/$PREFIX | cut -d'=' -f2) + echo -n "${IPADDR}::${GATEWAY}:${NETMASK}::" + fi +} + +kdump_get_mac_addr() { + cat /sys/class/net/$1/address +} + +#Bonding or team master modifies the mac address +#of its slaves, we should use perm address +kdump_get_perm_addr() { + local addr=$(ethtool -P $1 | sed -e 's/Permanent address: //') + if [ -z "$addr" ] || [ "$addr" = "00:00:00:00:00:00" ] + then + derror "Can't get the permanent address of $1" + else + echo "$addr" + fi +} + +kdump_setup_bridge() { + local _netdev=$1 + local _brif _dev + for _dev in `ls /sys/class/net/$_netdev/brif/`; do + if kdump_is_bond "$_dev"; then + kdump_setup_bond "$_dev" + elif kdump_is_team "$_dev"; then + kdump_setup_team "$_dev" + elif kdump_is_vlan "$_dev"; then + kdump_setup_vlan "$_dev" + else + echo -n " ifname=$_dev:$(kdump_get_mac_addr $_dev)" >> ${initdir}/etc/cmdline.d/41bridge.conf + fi + _brif+="$_dev," + done + echo " bridge=$_netdev:$(echo $_brif | sed -e 's/,$//')" >> ${initdir}/etc/cmdline.d/41bridge.conf +} + +kdump_setup_bond() { + local _netdev=$1 + local _dev + for _dev in `cat /sys/class/net/$_netdev/bonding/slaves`; do + echo -n " ifname=$_dev:$(kdump_get_perm_addr $_dev)" >> ${initdir}/etc/cmdline.d/42bond.conf + done + echo -n " bond=$_netdev:$(sed -e 's/ /,/g' /sys/class/net/$_netdev/bonding/slaves)" >> ${initdir}/etc/cmdline.d/42bond.conf + # Get bond options specified in ifcfg + . /etc/sysconfig/network-scripts/ifcfg-$_netdev + bondoptions="$(echo :$BONDING_OPTS | sed 's/\s\+/,/')" + echo "$bondoptions" >> ${initdir}/etc/cmdline.d/42bond.conf +} + +kdump_setup_team() { + local _netdev=$1 + local slaves _dev + for _dev in `teamnl $_netdev ports | awk -F':' '{print $2}'`; do + echo -n " ifname=$_dev:$(kdump_get_perm_addr $_dev)" >> ${initdir}/etc/cmdline.d/44team.conf + slaves+="$_dev," + done + echo " team=$_netdev:$(echo $slaves | sed -e 's/,$//')" >> ${initdir}/etc/cmdline.d/44team.conf + #Buggy version teamdctl outputs to stderr! + #Try to use the latest version of teamd. + teamdctl "$_netdev" config dump > /tmp/$$-$_netdev.conf + if [ $? -ne 0 ] + then + derror "teamdctl failed." + exit 1 + fi + inst_dir /etc/teamd + inst_simple /tmp/$$-$_netdev.conf "/etc/teamd/$_netdev.conf" + rm -f /tmp/$$-$_netdev.conf +} + +kdump_setup_vlan() { + local _netdev=$1 + local _phydev="$(awk '/^Device:/{print $2}' /proc/net/vlan/"$_netdev")" + local _netmac="$(kdump_get_mac_addr $_phydev)" + + echo " vlan=$_netdev:$_phydev" > ${initdir}/etc/cmdline.d/43vlan.conf + + #Just support vlan over bond, it is not easy + #to support all other complex setup + if kdump_is_bridge "$_phydev"; then + derror "Vlan over bridge is not supported!" + exit 1 + elif kdump_is_team "$_phydev"; then + derror "Vlan over team is not supported!" + exit 1 + elif kdump_is_bond "$_phydev"; then + kdump_setup_bond "$_phydev" + else + echo " vlan=$_netdev:$_phydev ifname=$_phydev:$_netmac" > ${initdir}/etc/cmdline.d/43vlan.conf + fi +} + +# setup s390 znet cmdline +# $1: netdev name +kdump_setup_znet() { + local _options="" + . /etc/sysconfig/network-scripts/ifcfg-$1 + for i in $OPTIONS; do + _options=${_options},$i + done + echo rd.znet=${NETTYPE},${SUBCHANNELS}${_options} > ${initdir}/etc/cmdline.d/30znet.conf +} + +# Setup dracut to bringup a given network interface +kdump_setup_netdev() { + local _netdev=$1 + local _static _proto + + if [ "$(uname -m)" = "s390x" ]; then + kdump_setup_znet $_netdev + fi + + _netmac=$(kdump_get_mac_addr $_netdev) + _static=$(kdump_static_ip $_netdev) + if [ -n "$_static" ]; then + _proto=none + else + _proto=dhcp + fi + + echo " ip=${_static}$_netdev:${_proto}" > ${initdir}/etc/cmdline.d/40ip.conf + + if kdump_is_bridge "$_netdev"; then + kdump_setup_bridge "$_netdev" + elif kdump_is_bond "$_netdev"; then + kdump_setup_bond "$_netdev" + elif kdump_is_team "$_netdev"; then + kdump_setup_team "$_netdev" + elif kdump_is_vlan "$_netdev"; then + kdump_setup_vlan "$_netdev" + else + echo " ifname=$_netdev:$(kdump_get_mac_addr $_netdev)" >> ${initdir}/etc/cmdline.d/40ip.conf + fi + + kdump_setup_dns "$_netdev" +} + +#Function:kdump_install_net +#$1: config values of net line in kdump.conf +kdump_install_net() { + local _server _netdev + local config_val="$1" + + _server=`echo $config_val | sed 's/.*@//' | cut -d':' -f1` + + _need_dns=`echo $_server|grep "[a-zA-Z]"` + [ -n "$_need_dns" ] && _server=`getent hosts $_server|cut -d' ' -f1` + + _netdev=`/sbin/ip route get to $_server 2>&1` + [ $? != 0 ] && echo "Bad kdump location: $config_val" && exit 1 + + #the field in the ip output changes if we go to another subnet + if [ -n "`echo $_netdev | grep via`" ] + then + # we are going to a different subnet + _netdev=`echo $_netdev|awk '{print $5;}'|head -n 1` + else + # we are on the same subnet + _netdev=`echo $_netdev|awk '{print $3}'|head -n 1` + fi + + kdump_setup_netdev "${_netdev}" + #save netdev used for kdump as cmdline + echo "kdumpnic=${_netdev}" > ${initdir}/etc/cmdline.d/60kdumpnic.conf + echo "bootdev=${_netdev}" > ${initdir}/etc/cmdline.d/70bootdev.conf +} + +#install kdump.conf and what user specifies in kdump.conf +kdump_install_conf() { + sed -ne '/^#/!p' /etc/kdump.conf > /tmp/$$-kdump.conf + + while read config_opt config_val; + do + # remove inline comments after the end of a directive. + config_val=$(strip_comments $config_val) + case "$config_opt" in + ext[234]|xfs|btrfs|minix|raw) + sed -i -e "s#$config_val#$(kdump_to_udev_name $config_val)#" /tmp/$$-kdump.conf + ;; + ssh|nfs) + kdump_install_net "$config_val" + ;; + kdump_pre|kdump_post|extra_bins) + dracut_install $config_val + ;; + core_collector) + dracut_install "${config_val%%[[:blank:]]*}" + ;; + esac + done < /etc/kdump.conf + + inst "/tmp/$$-kdump.conf" "/etc/kdump.conf" + rm -f /tmp/$$-kdump.conf +} + +kdump_iscsi_get_rec_val() { + + local result + + # The open-iscsi 742 release changed to using flat files in + # /var/lib/iscsi. + + result=$(/sbin/iscsiadm --show -m session -r ${1} | grep "^${2} = ") + result=${result##* = } + echo $result +} + +kdump_get_iscsi_initiator() { + local _initiator + local initiator_conf="/etc/iscsi/initiatorname.iscsi" + + [ -f "$initiator_conf" ] || return 1 + + while read _initiator; do + [ -z "${_initiator%%#*}" ] && continue # Skip comment lines + + case $_initiator in + InitiatorName=*) + initiator=${_initiator#InitiatorName=} + echo "rd.iscsi.initiator=${initiator}" + return 0;; + *) ;; + esac + done < ${initiator_conf} + + return 1 +} + +# No ibft handling yet. +kdump_setup_iscsi_device() { + local path=$1 + local tgt_name; local tgt_ipaddr; + local username; local password; local userpwd_str; + local username_in; local password_in; local userpwd_in_str; + local netdev + local idev + local netroot_str ; local initiator_str; + local netroot_conf="${initdir}/etc/cmdline.d/50iscsi.conf" + local initiator_conf="/etc/iscsi/initiatorname.iscsi" + + dinfo "Found iscsi component $1" + + # Check once before getting explicit values, so we can output a decent + # error message. + + if ! /sbin/iscsiadm -m session -r ${path} >/dev/null ; then + derror "Unable to find iscsi record for $path" + return 1 + fi + + tgt_name=$(kdump_iscsi_get_rec_val ${path} "node.name") + tgt_ipaddr=$(kdump_iscsi_get_rec_val ${path} "node.conn\[0\].address") + + # get and set username and password details + username=$(kdump_iscsi_get_rec_val ${path} "node.session.auth.username") + [ "$username" == "" ] && username="" + password=$(kdump_iscsi_get_rec_val ${path} "node.session.auth.password") + [ "$password" == "" ] && password="" + username_in=$(kdump_iscsi_get_rec_val ${path} "node.session.auth.username_in") + [ -n "$username" ] && userpwd_str="$username:$password" + + # get and set incoming username and password details + [ "$username_in" == "" ] && username_in="" + password_in=$(kdump_iscsi_get_rec_val ${path} "node.session.auth.password_in") + [ "$password_in" == "" ] && password_in="" + + [ -n "$username_in" ] && userpwd_in_str=":$username_in:$password_in" + + netdev=$(/sbin/ip route get to ${tgt_ipaddr} | \ + sed 's|.*dev \(.*\).*|\1|g' | awk '{ print $1; exit }') + + kdump_setup_netdev $netdev + + # prepare netroot= command line + # FIXME: IPV6 addresses require explicit [] around $tgt_ipaddr + # FIXME: Do we need to parse and set other parameters like protocol, port + # iscsi_iface_name, netdev_name, LUN etc. + + netroot_str="netroot=iscsi:${userpwd_str}${userpwd_in_str}@$tgt_ipaddr::::$tgt_name" + + [[ -f $netroot_conf ]] || touch $netroot_conf + + # If netroot target does not exist already, append. + if ! grep -q $netroot_str $netroot_conf; then + echo $netroot_str >> $netroot_conf + dinfo "Appended $netroot_str to $netroot_conf" + fi + + # Setup initator + initiator_str=$(kdump_get_iscsi_initiator) + [ $? -ne "0" ] && derror "Failed to get initiator name" && return 1 + + # If initiator details do not exist already, append. + if ! grep -q "$initiator_str" $netroot_conf; then + echo "$initiator_str" >> $netroot_conf + dinfo "Appended "$initiator_str" to $netroot_conf" + fi +} + +kdump_check_iscsi_targets () { + # If our prerequisites are not met, fail anyways. + type -P iscsistart >/dev/null || return 1 + + kdump_check_setup_iscsi() ( + local _dev + _dev=$1 + + [[ -L /sys/dev/block/$_dev ]] || return + cd "$(readlink -f /sys/dev/block/$_dev)" + until [[ -d sys || -d iscsi_session ]]; do + cd .. + done + [[ -d iscsi_session ]] && kdump_setup_iscsi_device "$PWD" + ) + + [[ $hostonly ]] || [[ $mount_needs ]] && { + for_each_host_dev_and_slaves_all kdump_check_setup_iscsi + } +} + + +install() { + kdump_install_conf + >"$initdir/lib/dracut/no-emergency-shell" + + if is_ssh_dump_target; then + dracut_install /var/lib/random-seed || exit $? + fi + dracut_install -o /etc/adjtime /etc/localtime + inst "$moddir/monitor_dd_progress" "/kdumpscripts/monitor_dd_progress" + chmod +x ${initdir}/kdumpscripts/monitor_dd_progress + inst "/bin/dd" "/bin/dd" + inst "/bin/tail" "/bin/tail" + inst "/bin/date" "/bin/date" + inst "/bin/sync" "/bin/sync" + inst "/bin/cut" "/bin/cut" + inst "/sbin/makedumpfile" "/sbin/makedumpfile" + inst "/sbin/vmcore-dmesg" "/sbin/vmcore-dmesg" + inst_hook pre-pivot 9999 "$moddir/kdump.sh" + inst "/lib/kdump/kdump-lib.sh" "/lib/kdump-lib.sh" + + # Check for all the devices and if any device is iscsi, bring up iscsi + # target. Ideally all this should be pushed into dracut iscsi module + # at some point of time. + kdump_check_iscsi_targets +} diff --git a/SOURCES/dracut-monitor_dd_progress b/SOURCES/dracut-monitor_dd_progress new file mode 100644 index 0000000..e139d33 --- /dev/null +++ b/SOURCES/dracut-monitor_dd_progress @@ -0,0 +1,28 @@ +#!/bin/sh + +SRC_FILE_MB=$1 + +while true +do + DD_PID=`pidof dd` + if [ -n "$DD_PID" ]; then + break + fi +done + +while true +do + sleep 5 + if [ ! -d /proc/$DD_PID ]; then + break + fi + + kill -s USR1 $DD_PID + CURRENT_SIZE=`tail -n 1 /tmp/dd_progress_file | sed "s/[^0-9].*//g"` + [ -n "$CURRENT_SIZE" ] && { + CURRENT_MB=$(($CURRENT_SIZE / 1048576)) + echo -e "Copied $CURRENT_MB MB / $SRC_FILE_MB MB\r" + } +done + +rm -f /tmp/dd_progress_file diff --git a/SOURCES/firstboot_kdump.py b/SOURCES/firstboot_kdump.py new file mode 100755 index 0000000..2bdec5b --- /dev/null +++ b/SOURCES/firstboot_kdump.py @@ -0,0 +1,497 @@ +# +# firstboot_kdump.py - kdump configuration page for firstboot +# Copyright 2006 Red Hat, Inc. +# Author: Jarod Wilson +# Contributors: +# Neil Horman +# Dave Lehman +# +# +# 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., 675 Mass Ave, Cambridge, MA 02139, USA. + +import sys +sys.path.append('/usr/share/system-config-kdump/') + +from gtk import * +import string +import os +import os.path +import time +import gtk +import gobject +import commands +from firstboot.config import * +from firstboot.constants import * +from firstboot.functions import * +from firstboot.module import * +import gettext +_ = lambda x: gettext.ldgettext("kexec-tools", x) +N_ = lambda x: x + +class moduleClass(Module): + def __init__(self): + Module.__init__(self) + self.priority = 100 + self.sidebarTitle = N_("Kdump") + self.title = N_("Kdump") + self.reboot = False + + # runPriority determines the order in which this module runs in firstboot + runPriority = 70 + moduleName = _("Kdump") + windowName = moduleName + reboot = False + + # possible bootloaders we'll need to adjust + # bootloader : (config file, kdump offset) + bootloaders = { "grub" : (["/boot/grub/grub.conf", \ + "/boot/efi/EFI/redhat/grub.conf"], [16, 256]),\ + "grub2" : (["/boot/grub2/grub.cfg", \ + "/boot/efi/EFI/fedora/grub.cfg", \ + "/boot/efi/EFI/redhat/grub.cfg"], [16, 256]),\ + "zipl" : (["/etc/zipl.conf"], [0]),\ + "yaboot" : (["/boot/etc/yaboot.conf"], [32]) } + bootloader = None + offset = 0 + + # list of architectures without kdump support + unsupportedArches = [ "ppc", "s390", "i386", "i586" ] + + def needsReboot(self): + return self.reboot + + # toggle sensitivity of kdump config bits + def showHideReserve(self, status): + self.labelKdump.set_sensitive(status) + self.kdumpMemspin.set_sensitive(status) + self.totalMem.set_sensitive(status) + self.systemUsableMem.set_sensitive(status) + self.labelTotal.set_sensitive(status) + self.labelSys.set_sensitive(status) + + # toggle sensitivity of kdump config bits + def showHide(self, status): + show_kdumpmem = status + if self.distro == 'rhel': + show_autoreserve = self.buttonAuto.get_active() + if status == True: + if self.buttonAuto.get_active() == True: + show_kdumpmem = False + self.buttonAuto.set_active(show_autoreserve) + self.buttonManual.set_active(not show_autoreserve) + self.labelReserve.set_sensitive(status) + self.buttonAuto.set_sensitive(status) + self.buttonManual.set_sensitive(status) + self.showHideReserve(show_kdumpmem) + self.labelReserved.set_sensitive(status) + self.labelReservedMemsize.set_sensitive(status) + self.kdumpEnabled = status + self.AdvWindow.set_sensitive(status) + + def on_enableKdumpCheck_toggled(self, *args): + showHideStatus = self.enableKdumpCheck.get_active() + self.showHide(showHideStatus) + + def on_auto_toggled(self, *args): + if self.distro == 'rhel': + self.showHideReserve(not self.buttonAuto.get_active()) + + def on_manual_toggled(self, *args): + if self.distro == 'rhel': + self.showHideReserve(self.buttonManual.get_active()) + + def updateAvail(self, widget, spin): + self.reserveMem = eval(string.strip(self.kdumpMemspin.get_text())) + self.remainingMem = self.availMem - self.reserveMem + self.systemUsableMem.set_text("%s" % self.remainingMem) + + def getBootloader(self): + for (name, (conf, offset)) in self.bootloaders.items(): + i = 0 + for c in conf: + if os.access(c, os.W_OK): + self.bootloader = name + self.offset = i + return self.bootloader + i += 1 + + self.offset = None + self.bootloader = None + return None + + def createScreen(self, doDebug = None): + self.doDebug = doDebug + + if doDebug: + print "initializing kdump module" + + # What kernel are we running? + self.runningKernel = os.popen("/bin/uname -r").read().strip() + + # What arch are we running on? + self.arch = os.popen("/bin/uname -m").read().strip() + + # Check for a xen kernel, kdump doesn't work w/xen just yet... + self.xenKernel = self.runningKernel.find("xen") + + # Fedora or RHEL? + releaseFile = '/etc/redhat-release' + lines = open(releaseFile).readlines() + for line in lines: + if line.find("Fedora") != -1: + self.distro = 'fedora' + else: + self.distro = 'rhel' + + # Ascertain how much memory is in the system + memInfo = open("/proc/meminfo").readlines() + self.availMem = 0 + for line in memInfo: + if line.startswith("MemTotal:"): + self.availMem = int(line.split()[1]) / 1024 + break + + # Fix up memory calculations if kdump is already on + cmdLine = open("/proc/cmdline").read() + self.kdumpOffset = 0 + self.origCrashKernel = "" + self.kdumpEnabled = False + chkConfigStatus=commands.getoutput('/bin/systemctl is-enabled kdump.service') + if chkConfigStatus.find("enabled") > -1: + self.kdumpEnabled = True + self.kdumpMemInitial = 0 + + crashString = "" + kexec_crash_size = open("/sys/kernel/kexec_crash_size").read() + self.reservedMem = int(kexec_crash_size)/(1024*1024) + + if cmdLine.find("crashkernel") != -1: + crashString = filter(lambda t: t.startswith("crashkernel="), + cmdLine.split())[0].split("=")[1] + self.origCrashKernel = "crashkernel=%s" % (crashString) + if self.doDebug: + print "crashString is %s" % crashString + if crashString.find("@") != -1: + (self.kdumpMemInitial, self.kdumpOffset) = [int(m[:-1]) for m in crashString.split("@")] + else: + #kdumpMemInitial = -1 means auto reservation + if self.distro == 'rhel' and self.origCrashKernel == 'crashkernel=auto': + self.kdumpMemInitial=-1 + else: + self.kdumpMemInitial=int(crashString[:-1]) + self.kdumpOffset = 0 + if self.kdumpMemInitial != 0: + self.availMem += self.reservedMem + self.kdumpEnabled = True + else: + self.kdumpEnabled = False + if self.origCrashKernel.find("crashkernel=") != -1: + self.kdumpEnabled = True + + self.initialState = self.kdumpEnabled + + # Do some sanity-checking and try to present only sane options. + # + # Defaults + lowerBound = 128 + minUsable = 256 + step = 1 + self.enoughMem = True + if self.arch == 'ia64': + # ia64 usually needs at *least* 256M, page-aligned... :( + lowerBound = 256 + minUsable = 512 + step = 256 + elif self.arch == 'ppc64': + # ppc64 often fails w/128M lately, and we want at least 1G + # of RAM for normal use, due to 64k page size... :\ + lowerBound = 256 + minUsable = 1024 + + upperBound = (self.availMem - minUsable) - (self.availMem % step) + + if upperBound < lowerBound: + self.enoughMem = False + + # Set spinner to lowerBound unless already set on kernel command line + if self.kdumpMemInitial == 0 or self.kdumpMemInitial == -1: + self.kdumpMemInitial = lowerBound + else: + # round down to a multiple of step value + self.kdumpMemInitial = self.kdumpMemInitial - (self.kdumpMemInitial % step) + + # kdump enable/disable checkbox + self.enableKdumpCheck = gtk.CheckButton(_("_Enable kdump?")) + self.enableKdumpCheck.set_alignment(xalign=0, yalign=0) + + # detected total amount of system memory + self.totalMem = gtk.Label(_("%s" % self.availMem)) + self.labelTotal = gtk.Label(_("Total System Memory (MB):")) + self.labelTotal.set_alignment(0.0, 0.5) + self.labelTotal.set_width_chars(32) + + # how much ram to reserve for kdump + self.memAdjustment = gtk.Adjustment(self.kdumpMemInitial, lowerBound, upperBound, step, step, 0) + self.kdumpMemspin = gtk.SpinButton(self.memAdjustment, 0, 0) + self.kdumpMemspin.set_update_policy(gtk.UPDATE_IF_VALID) + self.kdumpMemspin.set_numeric(True) + self.memAdjustment.connect("value_changed", self.updateAvail, self.kdumpMemspin) + self.labelKdump = gtk.Label(_("Memory To Be _Reserved (MB):")) + self.labelKdump.set_use_underline(True) + self.labelKdump.set_mnemonic_widget(self.kdumpMemspin) + self.labelKdump.set_alignment(0.0, 0.5) + + # remaining usable system memory + self.reserveMem = eval(string.strip(self.kdumpMemspin.get_text())) + self.remainingMem = self.availMem - self.reserveMem + self.systemUsableMem = gtk.Label(_("%s" % self.remainingMem)) + self.labelSys = gtk.Label(_("Usable System Memory (MB):")) + self.labelSys.set_alignment(0.0, 0.5) + + self.labelReserved=gtk.Label(_("Memory Currently Reserved (MB):")) + self.labelReservedMemsize=gtk.Label(_("%s" % self.reservedMem)) + self.labelReserved.set_alignment(0.0, 0.5) + + # rhel crashkernel=auto handling + if self.distro == 'rhel': + self.labelReserve = gtk.Label(_("Kdump Memory Reservation:")) + self.buttonAuto = gtk.RadioButton(None, _("_Automatic")) + self.buttonManual = gtk.RadioButton(self.buttonAuto, _("_Manual")) + self.buttonAuto.connect("toggled", self.on_auto_toggled, None) + self.buttonManual.connect("toggled", self.on_manual_toggled, None) + self.buttonAuto.set_use_underline(True) + self.buttonManual.set_use_underline(True) + self.labelReserve.set_alignment(0.0, 0.5) + if self.origCrashKernel == 'crashkernel=auto': + self.buttonAuto.set_active(True) + self.buttonManual.set_active(False) + else: + self.buttonAuto.set_active(False) + self.buttonManual.set_active(True) + self.autoinitial = self.buttonAuto.get_active() + + + # Add an advanced kdump config text widget + inputbuf = open("/etc/kdump.conf", "r") + self.AdvConfig = gtk.TextView() + AdvBuf = gtk.TextBuffer() + AdvBuf.set_text(inputbuf.read()) + inputbuf.close() + + self.AdvConfig.set_buffer(AdvBuf) + self.AdvWindow = gtk.ScrolledWindow() + self.AdvWindow.set_shadow_type(gtk.SHADOW_IN) + self.AdvWindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) + self.AdvWindow.set_size_request(500, 300) + self.AdvWindow.add(self.AdvConfig) + + self.AdvConfLabel = gtk.Label(_("\nAdvanced kdump configuration")) + self.AdvConfLabel.set_alignment(0.0, 0.5) + + self.vbox = gtk.VBox() + self.vbox.set_size_request(400, 200) + + # title_pix = loadPixbuf("workstation.png") + + internalVBox = gtk.VBox() + internalVBox.set_border_width(10) + internalVBox.set_spacing(10) + + label = gtk.Label(_("Kdump is a kernel crash dumping mechanism. In the event of a " + "system crash, kdump will capture information from your system " + "that can be invaluable in determining the cause of the crash. " + "Note that kdump does require reserving a portion of system " + "memory that will be unavailable for other uses.")) + + label.set_line_wrap(True) + label.set_alignment(0.0, 0.5) + label.set_size_request(500, -1) + internalVBox.pack_start(label, False, True) + + if self.distro == 'rhel': + table = gtk.Table(3, 100) + table.attach(self.enableKdumpCheck, 0, 3, 0, 1, gtk.FILL, gtk.FILL, 5, 5) + table.attach(self.labelReserve, 0, 1, 1, 2, gtk.FILL) + table.attach(self.buttonAuto, 1, 2, 1, 2, gtk.FILL, gtk.FILL, 5, 5) + table.attach(self.buttonManual, 2, 3, 1, 2, gtk.FILL, gtk.FILL, 5, 5) + table.attach(self.labelReserved, 0, 1, 2, 3, gtk.FILL) + table.attach(self.labelReservedMemsize, 2, 3, 2, 3, gtk.SHRINK, gtk.FILL, 5, 5) + table.attach(self.labelKdump, 0, 1, 3, 4, gtk.FILL) + table.attach(self.kdumpMemspin, 2, 3, 3, 4, gtk.SHRINK, gtk.FILL, 5, 5) + table.attach(self.labelTotal, 0, 1, 4, 5, gtk.FILL) + table.attach(self.totalMem, 2, 3, 4, 5, gtk.SHRINK, gtk.FILL, 5, 5) + table.attach(self.labelSys, 0, 1, 5, 6, gtk.FILL) + table.attach(self.systemUsableMem, 2, 3, 5, 6, gtk.SHRINK, gtk.FILL, 5, 5) + table.attach(self.AdvConfLabel, 0, 1, 6, 7, gtk.FILL) + table.attach(self.AdvWindow, 0, 3, 7, 100, gtk.FILL, gtk.FILL, 5, 5) + else: + table = gtk.Table(2, 100) + table.attach(self.enableKdumpCheck, 0, 2, 0, 1, gtk.FILL, gtk.FILL, 5, 5) + table.attach(self.labelTotal, 0, 1, 1, 2, gtk.FILL) + table.attach(self.totalMem, 1, 2, 1, 2, gtk.SHRINK, gtk.FILL, 5, 5) + + table.attach(self.labelKdump, 0, 1, 2, 3, gtk.FILL) + table.attach(self.kdumpMemspin, 1, 2, 2, 3, gtk.SHRINK, gtk.FILL, 5, 5) + + table.attach(self.labelReserved, 0, 1, 3, 4, gtk.FILL) + table.attach(self.labelReservedMemsize, 1, 2, 3, 4, gtk.SHRINK, gtk.FILL, 5, 5) + + table.attach(self.labelSys, 0, 1, 4, 5, gtk.FILL) + table.attach(self.systemUsableMem, 1, 2, 4, 5, gtk.SHRINK, gtk.FILL, 5, 5) + + table.attach(self.AdvConfLabel, 0, 1, 6, 7, gtk.FILL) + table.attach(self.AdvWindow, 0, 2, 7, 100, gtk.FILL, gtk.FILL, 5, 5) + + # disable until user clicks check box, if not already enabled + if self.initialState is False: + self.showHide(False) + else: + self.enableKdumpCheck.set_active(True) + self.showHide(True) + + internalVBox.pack_start(table, True, 15) + + # toggle sensitivity of Mem items + self.enableKdumpCheck.connect("toggled", self.on_enableKdumpCheck_toggled) + + self.vbox.pack_start(internalVBox, False, 15) + + def grabFocus(self): + self.enableKdumpCheck.grab_focus() + + def configChanged(self): + if self.initialState == self.kdumpEnabled and self.initialState == False: + return False + if self.initialState != self.kdumpEnabled \ + or (self.distro == 'rhel' and self.autoinitial != self.buttonAuto.get_active()) \ + or (self.distro == 'rhel' and self.buttonManual.get_active() == True and self.reserveMem != self.kdumpMemInitial) \ + or (self.distro != 'rhel' and self.reserveMem != self.kdumpMemInitial): + return True + return False + + + def apply(self, *args): + if self.kdumpEnabled: + self.reserveMem = self.kdumpMemspin.get_value_as_int() + else: + self.reserveMem = self.kdumpMemInitial + self.remainingMem = self.availMem - self.reserveMem + if self.doDebug: + print "Running kernel %s on %s architecture" % (self.runningKernel, self.arch) + if self.enableKdumpCheck.get_active(): + print "System Mem: %s MB Kdump Mem: %s MB Avail Mem: %s MB" % (totalSysMem, self.reserveMem, self.remainingMem) + else: + print "Kdump will be disabled" + + # Before we do other checks we should save the users config + AdvBuf = self.AdvConfig.get_buffer() + start, end = AdvBuf.get_bounds() + outputbuf = open("/etc/kdump.conf", "rw+") + outputbuf.write(AdvBuf.get_text(start, end)) + outputbuf.close() + + # Regardless of what else happens we need to be sure to disalbe kdump if its disabled here, or + # else it will fail during startup + if (self.enableKdumpCheck.get_active() == False): + os.system("/bin/systemctl disable kdump.service") + + # If the user simply doesn't have enough memory for kdump to be viable/supportable, tell 'em + if self.enoughMem is False and self.kdumpEnabled: + self.showErrorMessage(_("Sorry, your system does not have enough memory for kdump to be viable!")) + self.enableKdumpCheck.set_active(False) + self.showHide(False) + return RESULT_FAILURE + # Alert user that we're not going to turn on kdump if they're running a xen kernel + elif self.xenKernel != -1 and self.kdumpEnabled: + self.showErrorMessage(_("Sorry, Xen kernels do not support kdump at this time!")) + self.enableKdumpCheck.set_active(False) + self.showHide(False) + return RESULT_FAILURE + # If there's no kdump support on this arch, let the user know and don't configure + elif self.arch in self.unsupportedArches: + self.showErrorMessage(_("Sorry, the %s architecture does not support kdump at this time!" % self.arch)) + self.enableKdumpCheck.set_active(False) + self.showHide(False) + return RESULT_FAILURE + + # Don't alert if nothing has changed + if self.configChanged() == True: + dlg = gtk.MessageDialog(None, 0, gtk.MESSAGE_INFO, + gtk.BUTTONS_YES_NO, + _("Changing Kdump settings requires rebooting the " + "system to reallocate memory accordingly. Would you " + "like to continue with this change and reboot the " + "system after firstboot is complete?")) + dlg.set_position(gtk.WIN_POS_CENTER) + dlg.show_all() + rc = dlg.run() + dlg.destroy() + + if rc != gtk.RESPONSE_YES: + self.reboot = False + return RESULT_SUCCESS + else: + self.reboot = True + + # Find bootloader if it exists, and update accordingly + if self.getBootloader() == None: + self.showErrorMessage(_("Error! No bootloader config file found, aborting configuration!")) + self.enableKdumpCheck.set_active(False) + self.showHide(False) + return RESULT_FAILURE + + # Are we adding or removing the crashkernel param? + if self.kdumpEnabled: + _reserves = "%iM" % (self.reserveMem) + if self.distro == 'rhel': + if self.buttonAuto.get_active() == True: + _reserves = 'auto' + + grubbyCmd = "/sbin/grubby --%s --update-kernel=ALL --args=crashkernel=%s" \ + % (self.bootloader, _reserves) + chkconfigStatus = "enable" + else: + grubbyCmd = "/sbin/grubby --%s --update-kernel=ALL --remove-args=%s" \ + % (self.bootloader, self.origCrashKernel) + chkconfigStatus = "disable" + + if self.doDebug: + print "Using %s bootloader with %iM offset" % (self.bootloader, self.offset) + print "Grubby command would be:\n %s" % grubbyCmd + print "chkconfig status is %s" % chkconfigStatus + else: + os.system(grubbyCmd) + os.system("/bin/systemctl %s kdump.service" % (chkconfigStatus)) + if self.bootloader == 'yaboot': + os.system('/sbin/ybin') + if self.bootloader == 'zipl': + os.system('/sbin/zipl') + else: + self.reboot = False + + + return RESULT_SUCCESS + + def showErrorMessage(self, text): + dlg = gtk.MessageDialog(None, 0, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, text) + dlg.set_position(gtk.WIN_POS_CENTER) + dlg.set_modal(True) + rc = dlg.run() + dlg.destroy() + return None + + def initializeUI(self): + pass + diff --git a/SOURCES/kdump-lib.sh b/SOURCES/kdump-lib.sh new file mode 100755 index 0000000..e73ac09 --- /dev/null +++ b/SOURCES/kdump-lib.sh @@ -0,0 +1,24 @@ +#!/bin/sh +# +# Kdump common functions +# + +is_ssh_dump_target() +{ + grep -q "^ssh[[:blank:]].*@" /etc/kdump.conf +} + +is_nfs_dump_target() +{ + grep -q "^nfs" /etc/kdump.conf +} + +is_raw_dump_target() +{ + grep -q "^raw" /etc/kdump.conf +} + +strip_comments() +{ + echo $@ | sed -e 's/\(.*\)#.*/\1/' +} diff --git a/SOURCES/kdump.conf b/SOURCES/kdump.conf new file mode 100644 index 0000000..c5cfb4a --- /dev/null +++ b/SOURCES/kdump.conf @@ -0,0 +1,143 @@ +# Configures where to put the kdump /proc/vmcore files +# +# This file contains a series of commands to perform (in order) when a +# kernel crash has happened and the kdump kernel has been loaded. Directives in +# this file are only applicable to the kdump initramfs, and have no effect if +# the root filesystem is mounted and the normal init scripts are processed +# +# Currently only one dump target and path may be configured at once +# if the configured dump target fails, the default action will be preformed +# the default action may be configured with the default directive below. If the +# configured dump target succedes +# +# Basics commands supported are: +# raw - Will dd /proc/vmcore into . +# Use persistent device names for partition devices, +# such as /dev/vg/. +# +# nfs - Will mount fs and copy /proc/vmcore to +# /var/crash/%HOST-%DATE/, supports DNS. +# +# ssh - Will scp /proc/vmcore to +# :/var/crash/%HOST-%DATE/, supports DNS +# NOTE: make sure user has necessary write +# permissions on server +# +# sshkey - Will use the sshkey to do ssh dump +# Specifies the path of the ssh key you want to use +# when do ssh dump, the default value is +# /root/.ssh/kdump_id_rsa. +# +# - Will mount -t /mnt and copy +# /proc/vmcore to /mnt/var/crash/%DATE/. +# NOTE: can be a device node, label or uuid. +# It's recommended to use persistent device names +# such as /dev/vg/. +# Otherwise it's suggested to use label or uuid. +# +# path - Append path to the filesystem device which you are +# dumping to. Ignored for raw device dumps. +# If unset, will default to /var/crash. +# +# core_collector +# - This allows you to specify the command to copy +# the vmcore. You could use the dump filtering +# program makedumpfile, the default one, to retrieve +# your core, which on some arches can drastically +# reduce core file size. See /sbin/makedumpfile --help +# for a list of options. Note that the -i and -g +# options are not needed here, as the initrd will +# automatically be populated with a config file +# appropriate for the running kernel. +# Default core_collector for raw/ssh dump is: +# "makedumpfile -F -c --message-level 1 -d 31". +# Default core_collector for other targets is: +# "makedumpfile -c --message-level 1 -d 31". +# For core_collector format details please refer to +# kexec-kdump-howto.txt or kdump.conf manpage. +# +# kdump_post +# - This directive allows you to run a specified +# executable just after the memory dump process +# terminates. The exit status from the dump process +# is fed to the kdump_post executable, which can be +# used to trigger different actions for success or +# failure. +# +# kdump_pre +# - works just like the kdump_post directive, but instead +# of running after the dump process, runs immediately +# before. Exit status of this binary is interpreted +# as follows: +# 0 - continue with dump process as usual +# non 0 - reboot the system +# +# extra_bins +# - This directive allows you to specify additional +# binaries or shell scripts you'd like to include in +# your kdump initrd. Generally only useful in +# conjunction with a kdump_post binary or script that +# relies on other binaries or scripts. +# +# extra_modules +# - This directive allows you to specify extra kernel +# modules that you want to be loaded in the kdump +# initrd, typically used to set up access to +# non-boot-path dump targets that might otherwise +# not be accessible in the kdump environment. Multiple +# modules can be listed, separated by a space, and any +# dependent modules will automatically be included. +# +# default +# - Action to preform in case dumping to intended target +# fails. If no default action is specified, "reboot" +# is assumed default. +# reboot: If the default action is reboot simply reboot +# the system and loose the core that you are +# trying to retrieve. +# halt: If the default action is halt, then simply +# halt the system after attempting to capture +# a vmcore, regardless of success or failure. +# poweroff: The system will be powered down +# shell: If the default action is shell, then drop to +# an shell session inside the initramfs from +# where you can try to record the core manually. +# Exiting this shell reboots the system. +# Note: kdump uses bash as the default shell. +# dump_to_rootfs: If non-root dump target is specified, +# the default action can be set as dump_to_rootfs. +# That means when dump to target fails, dump vmcore +# to rootfs from initramfs context and reboot. +# +# force_rebuild <0 | 1> +# - By default, kdump initrd only will be rebuilt when +# necessary. Specify 1 to force rebuilding kdump +# initrd every time when kdump service starts. +# +#override_resettable <0 | 1> +# - Usually a unresettable block device can't be dump target. +# Specifying 1 means though block target is unresettable, user +# understand this situation and want to try dumping. By default, +# it's set to 0, means not to try a destined failure. +# +# dracut_args +# - Pass extra dracut options when rebuilding kdump +# initrd. + +#raw /dev/vg/lv_kdump +#ext4 /dev/vg/lv_kdump +#ext4 LABEL=/boot +#ext4 UUID=03138356-5e61-4ab3-b58e-27507ac41937 +#nfs my.server.com:/export/tmp +#ssh user@my.server.com +#sshkey /root/.ssh/kdump_id_rsa +path /var/crash +#core_collector makedumpfile -c --message-level 1 -d 31 +#core_collector scp +#kdump_post /var/crash/scripts/kdump-post.sh +#kdump_pre /var/crash/scripts/kdump-pre.sh +#extra_bins /usr/bin/lftp +#extra_modules gfs2 +#default shell +#force_rebuild 1 +#dracut_args --omit-drivers "cfg80211 snd" --add-drivers "ext2 ext3" diff --git a/SOURCES/kdump.conf.5 b/SOURCES/kdump.conf.5 new file mode 100644 index 0000000..6f88370 --- /dev/null +++ b/SOURCES/kdump.conf.5 @@ -0,0 +1,316 @@ +.TH KDUMP.CONF 5 "07/23/2008" "kexec-tools" + +.SH NAME +kdump.conf \- configuration file for kdump kernel. + +.SH DESCRIPTION + +kdump.conf is a configuration file for the kdump kernel crash +collection service. + +kdump.conf provides post-kexec instructions to the kdump kernel. It is +stored in the initrd file managed by the kdump service. If you change +this file and do not want to restart before it takes effect, restart +the kdump service to rebuild to initrd. + +For most configurations, you can simply review the examples provided +in the stock /etc/kdump.conf. + +.B NOTE: +For filesystem dump the dump target must be mounted before building +kdump initramfs. + +kdump.conf only affects the behavior of the initramfs. Please read the +kdump operational flow section of kexec-kdump-howto.txt in the docs to better +understand how this configuration file affects the behavior of kdump. + +.SH OPTIONS + +.B raw +.RS +Will dd /proc/vmcore into . Use persistent device names for +partition devices, such as /dev/vg/. +.RE + +.B nfs +.RS +Will mount fs and copy /proc/vmcore to /var/crash/%HOST-%DATE/, +supports DNS. Note that a fqdn should be used as the server name in the +mount point +.RE + +.B ssh +.RS +Will scp /proc/vmcore to :/var/crash/%HOST-%DATE/, +supports DNS. NOTE: make sure user has necessary write permissions on +server and that a fqdn is used as the server name +.RE + +.B sshkey +.RS +Specifies the path of the ssh key you want to use when do ssh dump, +the default value is /root/.ssh/kdump_id_rsa. +.RE + +.B +.RS +Will mount -t /mnt and copy /proc/vmcore to +/mnt/var/crash/%DATE/. NOTE: can be a device node, label +or uuid. It's recommended to use persistent device names such as +/dev/vg/. Otherwise it's suggested to use label or uuid. +.RE + +.B path +.RS +Append path to the filesystem device which you are dumping to. +Ignored for raw device dumps. If unset, will default to /var/crash. +.RE + +.B core_collector +.RS +This allows you to specify the command to copy the vmcore. +You could use the dump filtering program makedumpfile, the default one, +to retrieve your core, which on some arches can drastically reduce +core file size. See /sbin/makedumpfile --help for a list of options. +Note that the -i and -g options are not needed here, as the initrd +will automatically be populated with a config file appropriate +for the running kernel. +.PP +Note 1: About default core collector: +Default core_collector for raw/ssh dump is: +"makedumpfile -F -c --message-level 1 -d 31". +Default core_collector for other targets is: +"makedumpfile -c --message-level 1 -d 31". +Even if core_collector option is commented out in kdump.conf, makedumpfile +is default core collector and kdump uses it internally. +If one does not want makedumpfile as default core_collector, then they +need to specify one using core_collector option to change the behavior. +.PP +Note 2: If "makedumpfile -F" is used then you will get a flattened format +vmcore.flat, you will need to use "makedumpfile -R" to rearrange the +dump data from stdard input to a normal dumpfile (readable with analysis +tools). +ie. "makedumpfile -R vmcore < vmcore.flat" + +.RE + +.B kdump_post +.RS +This directive allows you to run a specified +executable just after the memory dump process +terminates. The exit status from the dump process +is fed to the kdump_post executable, which can be +used to trigger different actions for success or +failure. +.PP +Note that scripts written for use with this +directive must use the /bin/bash interpreter +.RE + +.B kdump_pre +.RS +Works just like the kdump_post directive, but instead +of running after the dump process, runs immediately +before. Exit status of this binary is interpreted +as follows: +.PP +0 - continue with dump process as usual +.PP +non 0 - reboot the system +.PP +Note that scripts written for this directive must use +the /bin/bash interpreter +.RE + +.B extra_bins +.RS +This directive allows you to specify additional +binaries or shell scripts you'd like to include in +your kdump initrd. Generally only useful in +conjunction with a kdump_post binary or script that +relies on other binaries or scripts. +.RE + +.B extra_modules +.RS +This directive allows you to specify extra kernel +modules that you want to be loaded in the kdump +initrd, typically used to set up access to +non-boot-path dump targets that might otherwise +not be accessible in the kdump environment. Multiple +modules can be listed, separated by a space, and any +dependent modules will automatically be included. +.RE + +.B default +.RS +Action to preform in case dumping to intended target fails. If no default +action is specified, "reboot" is assumed default. +reboot: If the default action is reboot simply reboot the system (this is what +most people will want, as it returns the system to a nominal state). shell: If the default +action is shell, then drop to an shell session inside the initramfs from +where you can manually preform additional recovery actions. Exiting this shell +reboots the system. halt: bring the system to a halt, requiring manual reset +poweroff: The system will be powered down. dump_to_rootfs:If the default action +is dump_to_rootfs, specified root will be mounted and dump will be saved in "path" +directory. +Note: kdump uses bash as the default shell. +.RE + +.B force_rebuild <0 | 1> +.RS +By default, kdump initrd only will be rebuilt when necessary. +Specify 1 to force rebuilding kdump initrd every time when kdump service starts. +.RE + +.B override_resettable <0 | 1> +.RS +Usually a unresettable block device can't be dump target. Specifying 1 means +though block target is unresettable, user understand this situation and want +to try dumping. By default, it's set to 0, means not to try a destined failure. +.RE + + +.B dracut_args +.RS +Kdump uses dracut to generate initramfs for second kernel. This option +allows a user to pass arguments to dracut directly. +.RE + +.SH DEPRECATED OPTIONS + +.B net | +.RS +net option is replaced by nfs and ssh options. Use nfs or ssh options +directly. +.RE + +.B options