diff --git a/.gitignore b/.gitignore index e7cea8f..b231ca3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ +SOURCES/1.6.8.tar.gz SOURCES/eppic_050615.tar.gz SOURCES/kexec-tools-2.0.20.tar.xz -SOURCES/makedumpfile-1.6.7.tar.gz diff --git a/.kexec-tools.metadata b/.kexec-tools.metadata index 431b034..553f89d 100644 --- a/.kexec-tools.metadata +++ b/.kexec-tools.metadata @@ -1,3 +1,3 @@ +7af5b92c69df9f63b9f02ad07a76a2a2581d4660 SOURCES/1.6.8.tar.gz a096c8e0892b559f40b01916aae240652f75b68a SOURCES/eppic_050615.tar.gz 5d9acd2e741d356d4a48fe4f2d63f66ba431051d SOURCES/kexec-tools-2.0.20.tar.xz -42941a0219d57d99909616778835e5d9ba890711 SOURCES/makedumpfile-1.6.7.tar.gz diff --git a/SOURCES/60-kdump.install b/SOURCES/60-kdump.install new file mode 100755 index 0000000..0a3b40e --- /dev/null +++ b/SOURCES/60-kdump.install @@ -0,0 +1,30 @@ +#!/usr/bin/bash + +COMMAND="$1" +KERNEL_VERSION="$2" +BOOT_DIR_ABS="$3" +KERNEL_IMAGE="$4" + +if ! [[ ${KERNEL_INSTALL_MACHINE_ID-x} ]]; then + exit 0 +fi + +if [[ -d "$BOOT_DIR_ABS" ]]; then + KDUMP_INITRD="initrdkdump" +else + BOOT_DIR_ABS="/boot" + KDUMP_INITRD="initramfs-${KERNEL_VERSION}kdump.img" +fi + +ret=0 +case "$COMMAND" in + add) + # Do nothing, kdump initramfs is strictly host only + # and managed by kdump service + ;; + remove) + rm -f -- "$BOOT_DIR_ABS/$KDUMP_INITRD" + ret=$? + ;; +esac +exit $ret diff --git a/SOURCES/dracut-early-kdump-module-setup.sh b/SOURCES/dracut-early-kdump-module-setup.sh index f30bd67..b25d6b5 100755 --- a/SOURCES/dracut-early-kdump-module-setup.sh +++ b/SOURCES/dracut-early-kdump-module-setup.sh @@ -1,7 +1,6 @@ #!/bin/bash . /etc/sysconfig/kdump -. /lib/kdump/kdump-lib.sh KDUMP_KERNEL="" KDUMP_INITRD="" @@ -21,6 +20,8 @@ depends() { } prepare_kernel_initrd() { + . /lib/kdump/kdump-lib.sh + prepare_kdump_bootinfo # $kernel is a variable from dracut @@ -48,7 +49,10 @@ install() { inst_simple "/etc/sysconfig/kdump" inst_binary "/usr/sbin/kexec" inst_binary "/usr/bin/gawk" "/usr/bin/awk" + inst_binary "/usr/bin/logger" "/usr/bin/logger" + inst_binary "/usr/bin/printf" "/usr/bin/printf" inst_script "/lib/kdump/kdump-lib.sh" "/lib/kdump-lib.sh" + inst_script "/lib/kdump/kdump-logger.sh" "/lib/kdump-logger.sh" inst_hook cmdline 00 "$moddir/early-kdump.sh" inst_binary "$KDUMP_KERNEL" inst_binary "$KDUMP_INITRD" diff --git a/SOURCES/dracut-early-kdump.sh b/SOURCES/dracut-early-kdump.sh index 92913fb..129841e 100755 --- a/SOURCES/dracut-early-kdump.sh +++ b/SOURCES/dracut-early-kdump.sh @@ -12,6 +12,14 @@ EARLY_KEXEC_ARGS="" . /etc/sysconfig/kdump . /lib/dracut-lib.sh . /lib/kdump-lib.sh +. /lib/kdump-logger.sh + +#initiate the kdump logger +dlog_init +if [ $? -ne 0 ]; then + echo "failed to initiate the kdump logger." + exit 1 +fi prepare_parameters() { @@ -28,7 +36,7 @@ early_kdump_load() fi if is_fadump_capable; then - echo "WARNING: early kdump doesn't support fadump." + dwarn "WARNING: early kdump doesn't support fadump." return 1 fi @@ -42,18 +50,25 @@ early_kdump_load() EARLY_KEXEC_ARGS=$(prepare_kexec_args "${KEXEC_ARGS}") if is_secure_boot_enforced; then - echo "Secure Boot is enabled. Using kexec file based syscall." + dinfo "Secure Boot is enabled. Using kexec file based syscall." EARLY_KEXEC_ARGS="$EARLY_KEXEC_ARGS -s" fi + # Here, only output the messages, but do not save these messages + # to a file because the target disk may not be mounted yet, the + # earlykdump is too early. + ddebug "earlykdump: $KEXEC ${EARLY_KEXEC_ARGS} $standard_kexec_args \ + --command-line=$EARLY_KDUMP_CMDLINE --initrd=$EARLY_KDUMP_INITRD \ + $EARLY_KDUMP_KERNEL" + $KEXEC ${EARLY_KEXEC_ARGS} $standard_kexec_args \ --command-line="$EARLY_KDUMP_CMDLINE" \ --initrd=$EARLY_KDUMP_INITRD $EARLY_KDUMP_KERNEL if [ $? == 0 ]; then - echo "kexec: loaded early-kdump kernel" + dinfo "kexec: loaded early-kdump kernel" return 0 else - echo "kexec: failed to load early-kdump kernel" + derror "kexec: failed to load early-kdump kernel" return 1 fi } @@ -61,10 +76,10 @@ early_kdump_load() set_early_kdump() { if getargbool 0 rd.earlykdump; then - echo "early-kdump is enabled." + dinfo "early-kdump is enabled." early_kdump_load else - echo "early-kdump is disabled." + dinfo "early-kdump is disabled." fi return 0 diff --git a/SOURCES/dracut-kdump.sh b/SOURCES/dracut-kdump.sh index 6f948fc..2497218 100755 --- a/SOURCES/dracut-kdump.sh +++ b/SOURCES/dracut-kdump.sh @@ -5,7 +5,6 @@ if [ -f /etc/fadump.initramfs ] && [ ! -f /proc/device-tree/rtas/ibm,kernel-dump exit 0 fi -exec &> /dev/console . /lib/dracut-lib.sh . /lib/kdump-lib-initramfs.sh @@ -22,7 +21,7 @@ do_dump() _ret=$? if [ $_ret -ne 0 ]; then - echo "kdump: saving vmcore failed" + derror "saving vmcore failed" fi return $_ret @@ -36,7 +35,7 @@ do_kdump_pre() "$KDUMP_PRE" _ret=$? if [ $_ret -ne 0 ]; then - echo "kdump: $KDUMP_PRE exited with $_ret status" + derror "$KDUMP_PRE exited with $_ret status" return $_ret fi fi @@ -47,7 +46,7 @@ do_kdump_pre() "$file" _ret=$? if [ $_ret -ne 0 ]; then - echo "kdump: $file exited with $_ret status" + derror "$file exited with $_ret status" fi done fi @@ -63,7 +62,7 @@ do_kdump_post() "$file" "$1" _ret=$? if [ $_ret -ne 0 ]; then - echo "kdump: $file exited with $_ret status" + derror "$file exited with $_ret status" fi done fi @@ -72,7 +71,7 @@ do_kdump_post() "$KDUMP_POST" "$1" _ret=$? if [ $_ret -ne 0 ]; then - echo "kdump: $KDUMP_POST exited with $_ret status" + derror "$KDUMP_POST exited with $_ret status" fi fi } @@ -88,7 +87,7 @@ dump_raw() [ -b "$_raw" ] || return 1 - echo "kdump: saving to raw disk $_raw" + dinfo "saving to raw disk $_raw" if ! $(echo -n $CORE_COLLECTOR|grep -q makedumpfile); then _src_size=`ls -l /proc/vmcore | cut -d' ' -f5` @@ -96,21 +95,25 @@ dump_raw() monitor_dd_progress $_src_size_mb & fi - echo "kdump: saving vmcore" + dinfo "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" + dinfo "saving vmcore complete" return 0 } dump_ssh() { + local _ret=0 + local _exitcode=0 _exitcode2=0 local _opt="-i $1 -o BatchMode=yes -o StrictHostKeyChecking=yes" local _dir="$KDUMP_PATH/$HOST_IP-$DATEDIR" local _host=$2 + local _vmcore="vmcore" + local _ipv6_addr="" _username="" - echo "kdump: saving to $_host:$_dir" + dinfo "saving to $_host:$_dir" cat /var/lib/random-seed > /dev/urandom ssh -q $_opt $_host mkdir -p $_dir || return 1 @@ -118,17 +121,54 @@ dump_ssh() save_vmcore_dmesg_ssh ${DMESG_COLLECTOR} ${_dir} "${_opt}" $_host save_opalcore_ssh ${_dir} "${_opt}" $_host - echo "kdump: saving vmcore" + dinfo "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 + if is_ipv6_address "$_host"; then + _username=${_host%@*} + _ipv6_addr="[${_host#*@}]" + fi + + if [ "${CORE_COLLECTOR%%[[:blank:]]*}" = "scp" ]; then + if [ -n "$_username" ] && [ -n "$_ipv6_addr" ]; then + scp -q $_opt /proc/vmcore "$_username@$_ipv6_addr:$_dir/vmcore-incomplete" + else + scp -q $_opt /proc/vmcore "$_host:$_dir/vmcore-incomplete" + fi + _exitcode=$? + else + $CORE_COLLECTOR /proc/vmcore | ssh $_opt $_host "dd bs=512 of=$_dir/vmcore-incomplete" + _exitcode=$? + _vmcore="vmcore.flat" + fi + + if [ $_exitcode -eq 0 ]; then + ssh $_opt $_host "mv $_dir/vmcore-incomplete $_dir/$_vmcore" + _exitcode2=$? + if [ $_exitcode2 -ne 0 ]; then + derror "moving vmcore failed, _exitcode:$_exitcode2" + else + dinfo "saving vmcore complete" + fi + else + derror "saving vmcore failed, _exitcode:$_exitcode" + fi + + dinfo "saving the $KDUMP_LOG_FILE to $_host:$_dir/" + save_log + if [ -n "$_username" ] && [ -n "$_ipv6_addr" ]; then + scp -q $_opt $KDUMP_LOG_FILE "$_username@$_ipv6_addr:$_dir/" + else + scp -q $_opt $KDUMP_LOG_FILE "$_host:$_dir/" + fi + _ret=$? + if [ $_ret -ne 0 ]; then + derror "saving log file failed, _exitcode:$_ret" + fi + + if [ $_exitcode -ne 0 ] || [ $_exitcode2 -ne 0 ];then + return 1 fi - echo "kdump: saving vmcore complete" return 0 } @@ -136,6 +176,9 @@ save_opalcore_ssh() { local _path=$1 local _opts="$2" local _location=$3 + local _user_name="" _ipv6addr="" + + ddebug "_path=$_path _opts=$_opts _location=$_location" if [ ! -f $OPALCORE ]; then # Check if we are on an old kernel that uses a different path @@ -146,15 +189,25 @@ save_opalcore_ssh() { fi fi - echo "kdump: saving opalcore" - scp $_opts $OPALCORE $_location:$_path/opalcore-incomplete + if is_ipv6_address "$_host"; then + _user_name=${_location%@*} + _ipv6addr="[${_location#*@}]" + fi + + dinfo "saving opalcore:$OPALCORE to $_location:$_path" + + if [ -n "$_user_name" ] && [ -n "$_ipv6addr" ]; then + scp $_opts $OPALCORE $_user_name@$_ipv6addr:$_path/opalcore-incomplete + else + scp $_opts $OPALCORE $_location:$_path/opalcore-incomplete + fi if [ $? -ne 0 ]; then - echo "kdump: saving opalcore failed" + derror "saving opalcore failed" return 1 fi ssh $_opts $_location mv $_path/opalcore-incomplete $_path/opalcore - echo "kdump: saving opalcore complete" + dinfo "saving opalcore complete" return 0 } @@ -164,15 +217,15 @@ save_vmcore_dmesg_ssh() { local _opts="$3" local _location=$4 - echo "kdump: saving vmcore-dmesg.txt" + dinfo "saving vmcore-dmesg.txt to $_location:$_path" $_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" + dinfo "saving vmcore-dmesg.txt complete" else - echo "kdump: saving vmcore-dmesg.txt failed" + derror "saving vmcore-dmesg.txt failed" fi } @@ -182,12 +235,12 @@ get_host_ip() if is_nfs_dump_target || is_ssh_dump_target then kdumpnic=$(getarg kdumpnic=) - [ -z "$kdumpnic" ] && echo "kdump: failed to get kdumpnic!" && return 1 + [ -z "$kdumpnic" ] && derror "failed to get kdumpnic!" && return 1 _host=`ip addr show dev $kdumpnic|grep '[ ]*inet'` - [ $? -ne 0 ] && echo "kdump: wrong kdumpnic: $kdumpnic" && return 1 + [ $? -ne 0 ] && derror "wrong kdumpnic: $kdumpnic" && return 1 _host=`echo $_host | head -n 1 | cut -d' ' -f2` _host="${_host%%/*}" - [ -z "$_host" ] && echo "kdump: wrong kdumpnic: $kdumpnic" && return 1 + [ -z "$_host" ] && derror "wrong kdumpnic: $kdumpnic" && return 1 HOST_IP=$_host fi return 0 @@ -196,7 +249,7 @@ get_host_ip() read_kdump_conf() { if [ ! -f "$KDUMP_CONF" ]; then - echo "kdump: $KDUMP_CONF not found" + derror "$KDUMP_CONF not found" return fi @@ -240,7 +293,7 @@ fence_kdump_notify get_host_ip if [ $? -ne 0 ]; then - echo "kdump: get_host_ip exited with non-zero status!" + derror "get_host_ip exited with non-zero status!" exit 1 fi @@ -250,7 +303,7 @@ fi do_kdump_pre if [ $? -ne 0 ]; then - echo "kdump: kdump_pre script exited with non-zero status!" + derror "kdump_pre script exited with non-zero status!" do_final_action # During systemd service to reboot the machine, stop this shell script running exit 1 @@ -261,7 +314,7 @@ DUMP_RETVAL=$? do_kdump_post $DUMP_RETVAL if [ $? -ne 0 ]; then - echo "kdump: kdump_post script exited with non-zero status!" + derror "kdump_post script exited with non-zero status!" fi if [ $DUMP_RETVAL -ne 0 ]; then diff --git a/SOURCES/dracut-module-setup.sh b/SOURCES/dracut-module-setup.sh index 32506ad..917afed 100755 --- a/SOURCES/dracut-module-setup.sh +++ b/SOURCES/dracut-module-setup.sh @@ -1,11 +1,12 @@ #!/bin/bash -. $dracutfunctions -. /lib/kdump/kdump-lib.sh +kdump_module_init() { + if ! [[ -d "${initdir}/tmp" ]]; then + mkdir -p "${initdir}/tmp" + fi -if ! [[ -d "${initdir}/tmp" ]]; then - mkdir -p "${initdir}/tmp" -fi + . /lib/kdump/kdump-lib.sh +} check() { [[ $debug ]] && set -x @@ -20,6 +21,12 @@ check() { depends() { local _dep="base shutdown" + kdump_module_init + + add_opt_module() { + [[ " $omit_dracutmodules " != *\ $1\ * ]] && _dep="$_dep $1" + } + is_squash_available() { for kmodule in squashfs overlay loop; do if [ -z "$KDUMP_KERNELVER" ]; then @@ -31,13 +38,26 @@ depends() { } if is_squash_available && ! is_fadump_capable; then - _dep="$_dep squash" + add_opt_module squash else dwarning "Required modules to build a squashed kdump image is missing!" fi + add_opt_module watchdog-modules + if is_wdt_active; then + add_opt_module watchdog + fi + + if is_ssh_dump_target; then + _dep="$_dep ssh-client" + fi + + if [ "$(uname -m)" = "s390x" ]; then + _dep="$_dep znet" + fi + if [ -n "$( find /sys/devices -name drm )" ] || [ -d /sys/module/hyperv_fb ]; then - _dep="$_dep drm" + add_opt_module drm fi if is_generic_fence_kdump || is_pcs_fence_kdump; then @@ -45,7 +65,6 @@ depends() { fi echo $_dep - return 0 } kdump_is_bridge() { @@ -244,14 +263,10 @@ kdump_setup_vlan() { local _netmac="$(kdump_get_mac_addr $_phydev)" local _kdumpdev - #Just support vlan over bond, it is not easy - #to support all other complex setup + #Just support vlan over bond and team 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" echo " vlan=$(kdump_setup_ifname $_netdev):$_phydev" > ${initdir}/etc/cmdline.d/43vlan.conf @@ -289,7 +304,7 @@ kdump_setup_netdev() { if [ -n "$_static" ]; then _proto=none elif is_ipv6_address $_srcaddr; then - _proto=either6 + _proto=auto6 else _proto=dhcp fi @@ -759,9 +774,32 @@ remove_cpu_online_rule() { sed -i '/SUBSYSTEM=="cpu"/d' $file } +kdump_install_systemd_conf() { + local failure_action=$(get_option_value "failure_action") + + # Kdump turns out to require longer default systemd mount timeout + # than 1st kernel(90s by default), we use default 300s for kdump. + grep -r "^[[:space:]]*DefaultTimeoutStartSec=" ${initdir}/etc/systemd/system.conf* &>/dev/null + if [ $? -ne 0 ]; then + mkdir -p ${initdir}/etc/systemd/system.conf.d + echo "[Manager]" > ${initdir}/etc/systemd/system.conf.d/kdump.conf + echo "DefaultTimeoutStartSec=300s" >> ${initdir}/etc/systemd/system.conf.d/kdump.conf + fi + + # Forward logs to console directly, and don't read Kmsg, this avoids + # unneccessary memory consumption and make console output more useful. + # Only do so for non fadump image. + mkdir -p ${initdir}/etc/systemd/journald.conf.d + echo "[Journal]" > ${initdir}/etc/systemd/journald.conf.d/kdump.conf + echo "Storage=volatile" >> ${initdir}/etc/systemd/journald.conf.d/kdump.conf + echo "ReadKMsg=no" >> ${initdir}/etc/systemd/journald.conf.d/kdump.conf + echo "ForwardToConsole=yes" >> ${initdir}/etc/systemd/journald.conf.d/kdump.conf +} + install() { local arch + kdump_module_init kdump_install_conf remove_sysctl_conf @@ -789,11 +827,14 @@ install() { inst "/bin/head" "/bin/head" inst "/sbin/makedumpfile" "/sbin/makedumpfile" inst "/sbin/vmcore-dmesg" "/sbin/vmcore-dmesg" + inst "/usr/bin/printf" "/sbin/printf" + inst "/usr/bin/logger" "/sbin/logger" inst "/lib/kdump/kdump-lib.sh" "/lib/kdump-lib.sh" inst "/lib/kdump/kdump-lib-initramfs.sh" "/lib/kdump-lib-initramfs.sh" + inst "/lib/kdump/kdump-logger.sh" "/lib/kdump-logger.sh" inst "$moddir/kdump.sh" "/usr/bin/kdump.sh" inst "$moddir/kdump-capture.service" "$systemdsystemunitdir/kdump-capture.service" - ln_r "$systemdsystemunitdir/kdump-capture.service" "$systemdsystemunitdir/initrd.target.wants/kdump-capture.service" + systemctl -q --root "$initdir" add-wants initrd.target kdump-capture.service inst "$moddir/kdump-error-handler.sh" "/usr/bin/kdump-error-handler.sh" inst "$moddir/kdump-error-handler.service" "$systemdsystemunitdir/kdump-error-handler.service" # Replace existing emergency service and emergency target @@ -807,6 +848,8 @@ install() { # at some point of time. kdump_check_iscsi_targets + kdump_install_systemd_conf + # For the lvm type target under kdump, in /etc/lvm/lvm.conf we can # safely replace "reserved_memory=XXXX"(default value is 8192) with # "reserved_memory=1024" to lower memory pressure under kdump. We do @@ -816,25 +859,8 @@ install() { 's/\(^[[:space:]]*reserved_memory[[:space:]]*=\)[[:space:]]*[[:digit:]]*/\1 1024/' \ ${initdir}/etc/lvm/lvm.conf &>/dev/null - # Kdump turns out to require longer default systemd mount timeout - # than 1st kernel(90s by default), we use default 300s for kdump. - grep -r "^[[:space:]]*DefaultTimeoutStartSec=" ${initdir}/etc/systemd/system.conf* &>/dev/null - if [ $? -ne 0 ]; then - mkdir -p ${initdir}/etc/systemd/system.conf.d - echo "[Manager]" > ${initdir}/etc/systemd/system.conf.d/kdump.conf - echo "DefaultTimeoutStartSec=300s" >> ${initdir}/etc/systemd/system.conf.d/kdump.conf - fi - + # Save more memory by dropping switch root capability if ! is_fadump_capable; then - # Forward logs to console directly, this avoids unneccessary memory - # consumption and make console output more useful. - # Only do so for non fadump image. - mkdir -p ${initdir}/etc/systemd/journald.conf.d - echo "[Journal]" > ${initdir}/etc/systemd/journald.conf.d/kdump.conf - echo "Storage=none" >> ${initdir}/etc/systemd/journald.conf.d/kdump.conf - echo "ForwardToConsole=yes" >> ${initdir}/etc/systemd/journald.conf.d/kdump.conf - - # Save more memory by dropping switch root capability dracut_no_switch_root fi } diff --git a/SOURCES/fadump-howto.txt b/SOURCES/fadump-howto.txt index c891e37..5360f3d 100644 --- a/SOURCES/fadump-howto.txt +++ b/SOURCES/fadump-howto.txt @@ -104,6 +104,11 @@ For the recommended value of X, see 'FADump Memory Requirements' section. # grubby --args="fadump=on crashkernel=6G" --update-kernel=/boot/vmlinuz-`uname -r` +By default, FADump reserved memory will be initialized as CMA area to make the +memory available through CMA allocator on the production kernel. We can opt out +of this, making reserved memory unavailable to production kernel, by booting the +linux kernel with 'fadump=nocma' instead of 'fadump=on'. + The term 'boot memory' means size of the low memory chunk that is required for a kernel to boot successfully when booted with restricted memory. By default, the boot memory size will be the larger of 5% of system RAM or 256MB. @@ -326,9 +331,14 @@ the original command line completely. How to disable FADump: -Remove "fadump=on" from kernel cmdline parameters: +Remove "fadump=on"/"fadump=nocma" from kernel cmdline parameters OR replace +it with "fadump=off" kernel cmdline parameter: # grubby --update-kernel=/boot/vmlinuz-`uname -r` --remove-args="fadump=on" +or + # grubby --update-kernel=/boot/vmlinuz-`uname -r` --remove-args="fadump=nocma" +OR + # grubby --update-kernel=/boot/vmlinuz-`uname -r` --args="fadump=off" If KDump is to be used as the dump capturing mechanism, update the crashkernel parameter (Else, remove "crashkernel=" parameter too, using grubby): diff --git a/SOURCES/kdump-dep-generator.sh b/SOURCES/kdump-dep-generator.sh index b6fab2d..f48c8f6 100644 --- a/SOURCES/kdump-dep-generator.sh +++ b/SOURCES/kdump-dep-generator.sh @@ -4,6 +4,7 @@ # http://www.freedesktop.org/wiki/Software/systemd/Generators/ . /usr/lib/kdump/kdump-lib.sh +. /usr/lib/kdump/kdump-logger.sh # If invokded with no arguments for testing purpose, output to /tmp to # avoid overriding the existing. diff --git a/SOURCES/kdump-lib-initramfs.sh b/SOURCES/kdump-lib-initramfs.sh index 2a7b613..a43c7dd 100755 --- a/SOURCES/kdump-lib-initramfs.sh +++ b/SOURCES/kdump-lib-initramfs.sh @@ -1,10 +1,12 @@ # These variables and functions are useful in 2nd kernel . /lib/kdump-lib.sh +. /lib/kdump-logger.sh KDUMP_PATH="/var/crash" +KDUMP_LOG_FILE="/run/initramfs/kexec-dmesg.log" CORE_COLLECTOR="" -DEFAULT_CORE_COLLECTOR="makedumpfile -l --message-level 1 -d 31" +DEFAULT_CORE_COLLECTOR="makedumpfile -l --message-level 7 -d 31" DMESG_COLLECTOR="/sbin/vmcore-dmesg" FAILURE_ACTION="systemctl reboot -f" DATEDIR=`date +%Y-%m-%d-%T` @@ -20,6 +22,13 @@ KDUMP_POST="" NEWROOT="/sysroot" OPALCORE="/sys/firmware/opal/mpipl/core" +#initiate the kdump logger +dlog_init +if [ $? -ne 0 ]; then + echo "failed to initiate the kdump logger." + exit 1 +fi + get_kdump_confs() { local config_opt config_val @@ -94,34 +103,36 @@ get_kdump_confs() fi } +# store the kexec kernel log to a file. +save_log() +{ + dmesg -T > $KDUMP_LOG_FILE + + if command -v journalctl > /dev/null; then + journalctl -ab >> $KDUMP_LOG_FILE + fi +} + # dump_fs dump_fs() { + local _exitcode local _mp=$1 - local _dev=$(get_mount_info SOURCE target $_mp -f) - local _op=$(get_mount_info OPTIONS target $_mp -f) + ddebug "dump_fs _mp=$_mp" - # If dump path have a corresponding device entry but not mounted, mount it. - if [ -n "$_dev" ] || [ "$_dev" == "rootfs" ]; then - if ! is_mounted "$_mp"; then - echo "kdump: dump target $_dev is not mounted, trying to mount..." - mkdir -p $_mp - mount -o $_op $_dev $_mp - - if [ $? -ne 0 ]; then - echo "kdump: mounting failed (mount point: $_mp, option: $_op)" - return 1 - fi + if ! is_mounted "$_mp"; then + dinfo "dump path \"$_mp\" is not mounted, trying to mount..." + mount --target $_mp + if [ $? -ne 0 ]; then + derror "failed to dump to \"$_mp\", it's not a mount point!" + return 1 fi - else - echo "kdump: failed to dump to \"$_mp\", it's not a mount point!" - return 1 fi # 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/" + dinfo "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 @@ -129,12 +140,23 @@ dump_fs() save_vmcore_dmesg_fs ${DMESG_COLLECTOR} "$_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR/" save_opalcore_fs "$_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 + dinfo "saving vmcore" + $CORE_COLLECTOR /proc/vmcore $_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR/vmcore-incomplete + _exitcode=$? + if [ $_exitcode -eq 0 ]; then + mv $_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR/vmcore-incomplete $_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR/vmcore + sync + dinfo "saving vmcore complete" + else + derror "saving vmcore failed, _exitcode:$_exitcode" + fi - echo "kdump: saving vmcore complete" + dinfo "saving the $KDUMP_LOG_FILE to $_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR/" + save_log + mv $KDUMP_LOG_FILE $_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR/ + if [ $_exitcode -ne 0 ]; then + return 1 + fi # improper kernel cmdline can cause the failure of echo, we can ignore this kind of failure return 0 @@ -144,7 +166,7 @@ save_vmcore_dmesg_fs() { local _dmesg_collector=$1 local _path=$2 - echo "kdump: saving vmcore-dmesg.txt" + dinfo "saving vmcore-dmesg.txt to ${_path}" $_dmesg_collector /proc/vmcore > ${_path}/vmcore-dmesg-incomplete.txt _exitcode=$? if [ $_exitcode -eq 0 ]; then @@ -154,9 +176,9 @@ save_vmcore_dmesg_fs() { # saving vmcore failed and system rebooted without sync and there # was no vmcore-dmesg.txt available. sync - echo "kdump: saving vmcore-dmesg.txt complete" + dinfo "saving vmcore-dmesg.txt complete" else - echo "kdump: saving vmcore-dmesg.txt failed" + derror "saving vmcore-dmesg.txt failed" fi } @@ -172,43 +194,47 @@ save_opalcore_fs() { fi fi - echo "kdump: saving opalcore" + dinfo "saving opalcore:$OPALCORE to ${_path}/opalcore" cp $OPALCORE ${_path}/opalcore if [ $? -ne 0 ]; then - echo "kdump: saving opalcore failed" + derror "saving opalcore failed" return 1 fi sync - echo "kdump: saving opalcore complete" + dinfo "saving opalcore complete" return 0 } dump_to_rootfs() { - echo "Kdump: trying to bring up rootfs device" + dinfo "Trying to bring up rootfs device" systemctl start dracut-initqueue - echo "Kdump: waiting for rootfs mount, will timeout after 90 seconds" + dinfo "Waiting for rootfs mount, will timeout after 90 seconds" systemctl start sysroot.mount + ddebug "NEWROOT=$NEWROOT" + dump_fs $NEWROOT } kdump_emergency_shell() { echo "PS1=\"kdump:\\\${PWD}# \"" >/etc/profile + ddebug "Switching to dracut emergency..." /bin/dracut-emergency rm -f /etc/profile } do_failure_action() { - echo "Kdump: Executing failure action $FAILURE_ACTION" + dinfo "Executing failure action $FAILURE_ACTION" eval $FAILURE_ACTION } do_final_action() { + dinfo "Executing final action $FINAL_ACTION" eval $FINAL_ACTION } diff --git a/SOURCES/kdump-lib.sh b/SOURCES/kdump-lib.sh index 798fd53..1c15a3d 100755 --- a/SOURCES/kdump-lib.sh +++ b/SOURCES/kdump-lib.sh @@ -20,14 +20,10 @@ is_fadump_capable() } perror_exit() { - echo $@ >&2 + derror "$@" exit 1 } -perror() { - echo $@ >&2 -} - is_ssh_dump_target() { grep -q "^ssh[[:blank:]].*@" /etc/kdump.conf @@ -463,28 +459,33 @@ get_ifcfg_filename() { echo -n "${ifcfg_file}" } -# returns 0 when omission of watchdog module is desired in dracut_args +# returns 0 when omission of a module is desired in dracut_args # returns 1 otherwise -is_wdt_mod_omitted() { - local dracut_args - local ret=1 +is_dracut_mod_omitted() { + local dracut_args dracut_mod=$1 - dracut_args=$(grep "^dracut_args" /etc/kdump.conf) - [[ -z $dracut_args ]] && return $ret + set -- $(grep "^dracut_args" /etc/kdump.conf) + while [ $# -gt 0 ]; do + case $1 in + -o|--omit) + [[ " ${2//[^[:alnum:]]/ } " == *" $dracut_mod "* ]] && return 0 + esac + shift + done - eval set -- $dracut_args - while :; do - [[ -z $1 ]] && break - case $1 in - -o|--omit) - echo $2 | grep -qw "watchdog" - [[ $? == 0 ]] && ret=0 - break - esac - shift - done + return 1 +} - return $ret +is_wdt_active() { + local active + + [ -d /sys/class/watchdog ] || return 1 + for dir in /sys/class/watchdog/*; do + [ -f "$dir/state" ] || continue + active=$(< "$dir/state") + [ "$active" = "active" ] && return 0 + done + return 1 } # If "dracut_args" contains "--mount" information, use it @@ -513,7 +514,7 @@ check_crash_mem_reserved() mem_reserved=$(cat /sys/kernel/kexec_crash_size) if [ $mem_reserved -eq 0 ]; then - echo "No memory reserved for crash kernel" + derror "No memory reserved for crash kernel" return 1 fi @@ -523,7 +524,7 @@ check_crash_mem_reserved() check_kdump_feasibility() { if [ ! -e /sys/kernel/kexec_crash_loaded ]; then - echo "Kdump is not supported on this kernel" + derror "Kdump is not supported on this kernel" return 1 fi check_crash_mem_reserved @@ -533,7 +534,7 @@ check_kdump_feasibility() check_current_kdump_status() { if [ ! -f /sys/kernel/kexec_crash_loaded ];then - echo "Perhaps CONFIG_CRASH_DUMP is not enabled in kernel" + derror "Perhaps CONFIG_CRASH_DUMP is not enabled in kernel" return 1 fi @@ -616,11 +617,16 @@ is_secure_boot_enforced() local secure_boot_file setup_mode_file local secure_boot_byte setup_mode_byte - # On powerpc, os-secureboot-enforcing DT property indicates whether secureboot - # is enforced. Return success, if it is found. + # On powerpc, secure boot is enforced if: + # host secure boot: /ibm,secure-boot/os-secureboot-enforcing DT property exists + # guest secure boot: /ibm,secure-boot >= 2 if [ -f /proc/device-tree/ibm,secureboot/os-secureboot-enforcing ]; then return 0 fi + if [ -f /proc/device-tree/ibm,secure-boot ] && \ + [ $(lsprop /proc/device-tree/ibm,secure-boot | tail -1) -ge 2 ]; then + return 0 + fi # Detect secure boot on x86 and arm64 secure_boot_file=$(find /sys/firmware/efi/efivars -name SecureBoot-* 2>/dev/null) @@ -661,8 +667,7 @@ prepare_kexec_args() found_elf_args=`echo $kexec_args | grep elf32-core-headers` if [ -n "$found_elf_args" ] then - echo -n "Warning: elf32-core-headers overrides correct elf64 setting" - echo + dwarn "Warning: elf32-core-headers overrides correct elf64 setting" else kexec_args="$kexec_args --elf64-core-headers" fi @@ -713,7 +718,7 @@ prepare_kdump_bootinfo() done if ! [ -e "$KDUMP_KERNEL" ]; then - echo "Failed to detect kdump kernel location" + derror "Failed to detect kdump kernel location" return 1 fi @@ -741,6 +746,25 @@ prepare_kdump_bootinfo() fi } +get_watchdog_drvs() +{ + local _wdtdrvs _drv _dir + + for _dir in /sys/class/watchdog/*; do + # device/modalias will return driver of this device + [[ -f "$_dir/device/modalias" ]] || continue + _drv=$(< "$_dir/device/modalias") + _drv=$(modprobe --set-version "$KDUMP_KERNELVER" -R $_drv 2>/dev/null) + for i in $_drv; do + if ! [[ " $_wdtdrvs " == *" $i "* ]]; then + _wdtdrvs="$_wdtdrvs $i" + fi + done + done + + echo $_wdtdrvs +} + # # prepare_cmdline # This function performs a series of edits on the command line. @@ -783,12 +807,20 @@ prepare_cmdline() cmdline=$(append_cmdline "${cmdline}" disable_cpu_apicid ${id}) fi - # Disable efifb if hyperv_fb is in use, hyperv_fb will relocate the framebuffer - # but kexec_file_load always use original screen_info and in second kernel efifb - # will try to access an invalid framebuffer address - if [ -d /sys/module/hyperv_fb ]; then - cmdline=$(append_cmdline "$cmdline" "video=efifb:off") - fi + # If any watchdog is used, set it's pretimeout to 0. pretimeout let + # watchdog panic the kernel first, and reset the system after the + # panic. If the system is already in kdump, panic is not helpful + # and only increase the chance of watchdog failure. + for i in $(get_watchdog_drvs); do + cmdline+=" $i.pretimeout=0" + + if [[ $i == hpwdt ]]; then + # hpwdt have a special parameter kdumptimeout, is's only suppose + # to be set to non-zero in first kernel. In kdump, non-zero + # value could prevent the watchdog from resetting the system. + cmdline+=" $i.kdumptimeout=0" + fi + done echo ${cmdline} } diff --git a/SOURCES/kdump-logger.sh b/SOURCES/kdump-logger.sh new file mode 100755 index 0000000..370e5e8 --- /dev/null +++ b/SOURCES/kdump-logger.sh @@ -0,0 +1,348 @@ +#!/bin/bash +# +# This comes from the dracut-logger.sh +# +# The logger defined 4 logging levels: +# - ddebug (4) +# The DEBUG Level designates fine-grained informational events that are most +# useful to debug an application. +# - dinfo (3) +# The INFO level designates informational messages that highlight the +# progress of the application at coarse-grained level. +# - dwarn (2) +# The WARN level designates potentially harmful situations. +# - derror (1) +# The ERROR level designates error events that might still allow the +# application to continue running. +# +# Logging is controlled by following global variables: +# - @var kdump_stdloglvl - logging level to standard error (console output) +# - @var kdump_sysloglvl - logging level to syslog (by logger command) +# - @var kdump_kmsgloglvl - logging level to /dev/kmsg (only for boot-time) +# +# If any of the variables is not set, the function dlog_init() sets it to default: +# - In the first kernel: +# - @var kdump_stdloglvl = 3 (info) +# - @var kdump_sysloglvl = 0 (no logging) +# - @var kdump_kmsgloglvl = 0 (no logging) +# +# -In the second kernel: +# - @var kdump_stdloglvl = 0 (no logging) +# - @var kdump_sysloglvl = 3 (info) +# - @var kdump_kmsgloglvl = 0 (no logging) +# +# First of all you have to start with dlog_init() function which initializes +# required variables. Don't call any other logging function before that one! +# + +# Define vairables for the log levels in this module. +kdump_stdloglvl="" +kdump_sysloglvl="" +kdump_kmsgloglvl="" + +# The dracut-lib.sh is only available in the second kernel, and it won't +# be used in the first kernel because the dracut-lib.sh is invisible in +# the first kernel. +if [ -f /lib/dracut-lib.sh ]; then + . /lib/dracut-lib.sh +fi + +# @brief Get the log level from kernel command line. +# @retval 1 if something has gone wrong +# @retval 0 on success. +# +get_kdump_loglvl() +{ + (type -p getarg) && kdump_sysloglvl=$(getarg rd.kdumploglvl) + [ -z "$kdump_sysloglvl" ] && return 1; + + (type -p isdigit) && isdigit $kdump_sysloglvl + [ $? -ne 0 ] && return 1; + + return 0 +} + +# @brief Check the log level. +# @retval 1 if something has gone wrong +# @retval 0 on success. +# +check_loglvl() +{ + case "$1" in + 0|1|2|3|4) + return 0 + ;; + *) + return 1 + ;; + esac +} + +# @brief Initializes Logger. +# @retval 1 if something has gone wrong +# @retval 0 on success. +# +dlog_init() { + local ret=0; local errmsg + + if [ -s /proc/vmcore ];then + get_kdump_loglvl + if [ $? -ne 0 ];then + logger -t "kdump[$$]" -p warn -- "Kdump is using the default log level(3)." + kdump_sysloglvl=3 + fi + kdump_stdloglvl=0 + kdump_kmsgloglvl=0 + else + kdump_stdloglvl=$KDUMP_STDLOGLVL + kdump_sysloglvl=$KDUMP_SYSLOGLVL + kdump_kmsgloglvl=$KDUMP_KMSGLOGLVL + fi + + [ -z "$kdump_stdloglvl" ] && kdump_stdloglvl=3 + [ -z "$kdump_sysloglvl" ] && kdump_sysloglvl=0 + [ -z "$kdump_kmsgloglvl" ] && kdump_kmsgloglvl=0 + + for loglvl in "$kdump_stdloglvl" "$kdump_kmsgloglvl" "$kdump_sysloglvl"; do + check_loglvl "$loglvl" + if [ $? -ne 0 ]; then + echo "Illegal log level: $kdump_stdloglvl $kdump_kmsgloglvl $kdump_sysloglvl" + return 1 + fi + done + + # Skip initialization if it's already done. + [ -n "$kdump_maxloglvl" ] && return 0 + + if [[ $UID -ne 0 ]]; then + kdump_kmsgloglvl=0 + kdump_sysloglvl=0 + fi + + if [[ $kdump_sysloglvl -gt 0 ]]; then + if [[ -d /run/systemd/journal ]] \ + && type -P systemd-cat &>/dev/null \ + && systemctl --quiet is-active systemd-journald.socket &>/dev/null; then + readonly _systemdcatfile="/var/tmp/systemd-cat" + mkfifo "$_systemdcatfile" &>/dev/null + readonly _dlogfd=15 + systemd-cat -t 'kdump' --level-prefix=true <"$_systemdcatfile" & + exec 15>"$_systemdcatfile" + elif ! [ -S /dev/log -a -w /dev/log ] || ! command -v logger >/dev/null; then + # We cannot log to syslog, so turn this facility off. + kdump_kmsgloglvl=$kdump_sysloglvl + kdump_sysloglvl=0 + ret=1 + errmsg="No '/dev/log' or 'logger' included for syslog logging" + fi + fi + + local lvl; local maxloglvl_l=0 + for lvl in $kdump_stdloglvl $kdump_sysloglvl $kdump_kmsgloglvl; do + [[ $lvl -gt $maxloglvl_l ]] && maxloglvl_l=$lvl + done + readonly kdump_maxloglvl=$maxloglvl_l + export kdump_maxloglvl + + if [[ $kdump_stdloglvl -lt 4 ]] && [[ $kdump_kmsgloglvl -lt 4 ]] && [[ $kdump_sysloglvl -lt 4 ]]; then + unset ddebug + ddebug() { :; }; + fi + + if [[ $kdump_stdloglvl -lt 3 ]] && [[ $kdump_kmsgloglvl -lt 3 ]] && [[ $kdump_sysloglvl -lt 3 ]]; then + unset dinfo + dinfo() { :; }; + fi + + if [[ $kdump_stdloglvl -lt 2 ]] && [[ $kdump_kmsgloglvl -lt 2 ]] && [[ $kdump_sysloglvl -lt 2 ]]; then + unset dwarn + dwarn() { :; }; + unset dwarning + dwarning() { :; }; + fi + + if [[ $kdump_stdloglvl -lt 1 ]] && [[ $kdump_kmsgloglvl -lt 1 ]] && [[ $kdump_sysloglvl -lt 1 ]]; then + unset derror + derror() { :; }; + fi + + [ -n "$errmsg" ] && derror "$errmsg" + + return $ret +} + +## @brief Converts numeric level to logger priority defined by POSIX.2. +# +# @param lvl Numeric logging level in range from 1 to 4. +# @retval 1 if @a lvl is out of range. +# @retval 0 if @a lvl is correct. +# @result Echoes logger priority. +_lvl2syspri() { + case "$1" in + 1) echo error;; + 2) echo warning;; + 3) echo info;; + 4) echo debug;; + *) return 1;; + esac +} + +## @brief Converts logger numeric level to syslog log level +# +# @param lvl Numeric logging level in range from 1 to 4. +# @retval 1 if @a lvl is out of range. +# @retval 0 if @a lvl is correct. +# @result Echoes kernel console numeric log level +# +# Conversion is done as follows: +# +# +# none -> LOG_EMERG (0) +# none -> LOG_ALERT (1) +# none -> LOG_CRIT (2) +# ERROR(1) -> LOG_ERR (3) +# WARN(2) -> LOG_WARNING (4) +# none -> LOG_NOTICE (5) +# INFO(3) -> LOG_INFO (6) +# DEBUG(4) -> LOG_DEBUG (7) +# +# +# @see /usr/include/sys/syslog.h +_dlvl2syslvl() { + local lvl + + case "$1" in + 1) lvl=3;; + 2) lvl=4;; + 3) lvl=6;; + 4) lvl=7;; + *) return 1;; + esac + + # The number is constructed by multiplying the facility by 8 and then + # adding the level. + # About The Syslog Protocol, please refer to the RFC5424 for more details. + echo $((24+$lvl)) +} + +## @brief Prints to stderr, to syslog and/or /dev/kmsg given message with +# given level (priority). +# +# @param lvl Numeric logging level. +# @param msg Message. +# @retval 0 It's always returned, even if logging failed. +# +# @note This function is not supposed to be called manually. Please use +# dinfo(), ddebug(), or others instead which wrap this one. +# +# This is core logging function which logs given message to standard error +# and/or syslog (with POSIX shell command logger) and/or to /dev/kmsg. +# The format is following: +# +# X: some message +# +# where @c X is the first letter of logging level. See module description for +# details on that. +# +# Message to syslog is sent with tag @c kdump. Priorities are mapped as +# following: +# - @c ERROR to @c error +# - @c WARN to @c warning +# - @c INFO to @c info +# - @c DEBUG to @c debug +_do_dlog() { + local lvl="$1"; shift + local msg="$*" + + [[ $lvl -le $kdump_stdloglvl ]] && printf -- 'kdump: %s\n' "$msg" >&2 + + if [[ $lvl -le $kdump_sysloglvl ]]; then + if [[ "$_dlogfd" ]]; then + printf -- "<%s>%s\n" "$(($(_dlvl2syslvl $lvl) & 7))" "$msg" >&$_dlogfd + else + logger -t "kdump[$$]" -p $(_lvl2syspri $lvl) -- "$msg" + fi + fi + + [[ $lvl -le $kdump_kmsgloglvl ]] && \ + echo "<$(_dlvl2syslvl $lvl)>kdump[$$] $msg" >/dev/kmsg +} + +## @brief Internal helper function for _do_dlog() +# +# @param lvl Numeric logging level. +# @param msg Message. +# @retval 0 It's always returned, even if logging failed. +# +# @note This function is not supposed to be called manually. Please use +# dinfo(), ddebug(), or others instead which wrap this one. +# +# This function calls _do_dlog() either with parameter msg, or if +# none is given, it will read standard input and will use every line as +# a message. +# +# This enables: +# dwarn "This is a warning" +# echo "This is a warning" | dwarn +dlog() { + [ -z "$kdump_maxloglvl" ] && return 0 + [[ $1 -le $kdump_maxloglvl ]] || return 0 + + if [[ $# -gt 1 ]]; then + _do_dlog "$@" + else + while read line || [ -n "$line" ]; do + _do_dlog "$1" "$line" + done + fi +} + +## @brief Logs message at DEBUG level (4) +# +# @param msg Message. +# @retval 0 It's always returned, even if logging failed. +ddebug() { + set +x + dlog 4 "$@" + [ -n "$debug" ] && set -x || : +} + +## @brief Logs message at INFO level (3) +# +# @param msg Message. +# @retval 0 It's always returned, even if logging failed. +dinfo() { + set +x + dlog 3 "$@" + [ -n "$debug" ] && set -x || : +} + +## @brief Logs message at WARN level (2) +# +# @param msg Message. +# @retval 0 It's always returned, even if logging failed. +dwarn() { + set +x + dlog 2 "$@" + [ -n "$debug" ] && set -x || : +} + +## @brief It's an alias to dwarn() function. +# +# @param msg Message. +# @retval 0 It's always returned, even if logging failed. +dwarning() { + set +x + dwarn "$@" + [ -n "$debug" ] && set -x || : +} + +## @brief Logs message at ERROR level (1) +# +# @param msg Message. +# @retval 0 It's always returned, even if logging failed. +derror() { + set +x + dlog 1 "$@" + [ -n "$debug" ] && set -x || : +} diff --git a/SOURCES/kdump.conf b/SOURCES/kdump.conf index 76fecd4..a0af268 100644 --- a/SOURCES/kdump.conf +++ b/SOURCES/kdump.conf @@ -21,7 +21,7 @@ # //%HOST-%DATE/, supports DNS. # # ssh -# - Will scp /proc/vmcore to :/%HOST-%DATE/, +# - Will save /proc/vmcore to :/%HOST-%DATE/, # supports DNS. # NOTE: make sure the user has write permissions on the server. # @@ -62,9 +62,9 @@ # as the initrd will automatically be populated with a # config file appropriate for the running kernel. # The default core_collector for raw/ssh dump is: -# "makedumpfile -F -l --message-level 1 -d 31". +# "makedumpfile -F -l --message-level 7 -d 31". # The default core_collector for other targets is: -# "makedumpfile -l --message-level 1 -d 31". +# "makedumpfile -l --message-level 7 -d 31". # # "makedumpfile -F" will create a flattened vmcore. # You need to use "makedumpfile -R" to rearrange the dump data to @@ -166,10 +166,12 @@ #ext4 LABEL=/boot #ext4 UUID=03138356-5e61-4ab3-b58e-27507ac41937 #nfs my.server.com:/export/tmp +#nfs [2001:db8::1:2:3:4]:/export/tmp #ssh user@my.server.com +#ssh user@2001:db8::1:2:3:4 #sshkey /root/.ssh/kdump_id_rsa path /var/crash -core_collector makedumpfile -l --message-level 1 -d 31 +core_collector makedumpfile -l --message-level 7 -d 31 #core_collector scp #kdump_post /var/crash/scripts/kdump-post.sh #kdump_pre /var/crash/scripts/kdump-pre.sh diff --git a/SOURCES/kdump.conf.5 b/SOURCES/kdump.conf.5 index 4aacac8..ce23dea 100644 --- a/SOURCES/kdump.conf.5 +++ b/SOURCES/kdump.conf.5 @@ -85,9 +85,9 @@ for the running kernel. .PP Note 1: About default core collector: The default core_collector for raw/ssh dump is: -"makedumpfile -F -l --message-level 1 -d 31". +"makedumpfile -F -l --message-level 7 -d 31". The default core_collector for other targets is: -"makedumpfile -l --message-level 1 -d 31". +"makedumpfile -l --message-level 7 -d 31". Even if core_collector option is commented out in kdump.conf, makedumpfile is the default core collector and kdump uses it internally. If one does not want makedumpfile as default core_collector, then they @@ -98,6 +98,11 @@ vmcore.flat, you will need to use "makedumpfile -R" to rearrange the dump data from standard input to a normal dumpfile (readable with analysis tools). ie. "makedumpfile -R vmcore < vmcore.flat" +.PP +Note 3: If specified core_collector simply copy the vmcore file to the +dump target (eg: cp, scp), the vmcore could be significantly large. +Please make sure the dump target has enough space, at leaset larger +than the system's RAM. .RE @@ -307,11 +312,11 @@ Above will effectively be translated to: cp --sparse=always /proc/vmcore /vmcore .TP ex2. -core_collector "makedumpfile -l --message-level 1 -d 31" +core_collector "makedumpfile -l --message-level 7 -d 31" Above will effectively be translated to: -makedumpfile -l --message-level 1 -d 31 /proc/vmcore /vmcore +makedumpfile -l --message-level 7 -d 31 /proc/vmcore /vmcore .PP For dump targets like raw and ssh, in general, core collector should expect one argument (source file) and should output the processed core on standard @@ -328,11 +333,11 @@ Above will effectively be translated to. cat /proc/vmcore | dd of= .TP ex4. -core_collector "makedumpfile -F -l --message-level 1 -d 31" +core_collector "makedumpfile -F -l --message-level 7 -d 31" Above will effectively be translated to. -makedumpfile -F -l --message-level 1 -d 31 | dd of= +makedumpfile -F -l --message-level 7 -d 31 | dd of= .PP ssh dumps examples .TP @@ -344,11 +349,11 @@ Above will effectively be translated to. cat /proc/vmcore | ssh "dd of=path/vmcore" .TP ex6. -core_collector "makedumpfile -F -l --message-level 1 -d 31" +core_collector "makedumpfile -F -l --message-level 7 -d 31" Above will effectively be translated to. -makedumpfile -F -l --message-level 1 -d 31 | ssh "dd of=path/vmcore" +makedumpfile -F -l --message-level 7 -d 31 | ssh "dd of=path/vmcore" There is one exception to standard output rule for ssh dumps. And that is scp. As scp can handle ssh destinations for file transfers, one can diff --git a/SOURCES/kdump.service b/SOURCES/kdump.service index f888dd6..99feed8 100644 --- a/SOURCES/kdump.service +++ b/SOURCES/kdump.service @@ -2,6 +2,7 @@ Description=Crash recovery kernel arming After=network.target network-online.target remote-fs.target basic.target DefaultDependencies=no +ConditionKernelCommandLine=crashkernel [Service] Type=oneshot diff --git a/SOURCES/kdump.sysconfig b/SOURCES/kdump.sysconfig index 7c5641a..ae802d2 100644 --- a/SOURCES/kdump.sysconfig +++ b/SOURCES/kdump.sysconfig @@ -35,3 +35,19 @@ KEXEC_ARGS="" #What is the image type used for kdump KDUMP_IMG="vmlinuz" + +# Logging is controlled by following variables in the first kernel: +# - @var KDUMP_STDLOGLVL - logging level to standard error (console output) +# - @var KDUMP_SYSLOGLVL - logging level to syslog (by logger command) +# - @var KDUMP_KMSGLOGLVL - logging level to /dev/kmsg (only for boot-time) +# +# In the second kernel, kdump will use the rd.kdumploglvl option to set the +# log level in the above KDUMP_COMMANDLINE_APPEND. +# - @var rd.kdumploglvl - logging level to syslog (by logger command) +# - for example: add the rd.kdumploglvl=3 option to KDUMP_COMMANDLINE_APPEND +# +# Logging levels: no logging(0), error(1),warn(2),info(3),debug(4) +# +# KDUMP_STDLOGLVL=3 +# KDUMP_SYSLOGLVL=0 +# KDUMP_KMSGLOGLVL=0 diff --git a/SOURCES/kdump.sysconfig.aarch64 b/SOURCES/kdump.sysconfig.aarch64 index 6f55c03..2ab2893 100644 --- a/SOURCES/kdump.sysconfig.aarch64 +++ b/SOURCES/kdump.sysconfig.aarch64 @@ -28,10 +28,26 @@ KDUMP_COMMANDLINE_APPEND="irqpoll nr_cpus=1 reset_devices cgroup_disable=memory # # Example: # KEXEC_ARGS="--elf32-core-headers" -KEXEC_ARGS="" +KEXEC_ARGS="-s" #Where to find the boot image #KDUMP_BOOTDIR="/boot" #What is the image type used for kdump KDUMP_IMG="vmlinuz" + +# Logging is controlled by following variables in the first kernel: +# - @var KDUMP_STDLOGLVL - logging level to standard error (console output) +# - @var KDUMP_SYSLOGLVL - logging level to syslog (by logger command) +# - @var KDUMP_KMSGLOGLVL - logging level to /dev/kmsg (only for boot-time) +# +# In the second kernel, kdump will use the rd.kdumploglvl option to set the +# log level in the above KDUMP_COMMANDLINE_APPEND. +# - @var rd.kdumploglvl - logging level to syslog (by logger command) +# - for example: add the rd.kdumploglvl=3 option to KDUMP_COMMANDLINE_APPEND +# +# Logging levels: no logging(0), error(1),warn(2),info(3),debug(4) +# +# KDUMP_STDLOGLVL=3 +# KDUMP_SYSLOGLVL=0 +# KDUMP_KMSGLOGLVL=0 diff --git a/SOURCES/kdump.sysconfig.i386 b/SOURCES/kdump.sysconfig.i386 index 84f0df1..165d13a 100644 --- a/SOURCES/kdump.sysconfig.i386 +++ b/SOURCES/kdump.sysconfig.i386 @@ -38,3 +38,19 @@ KDUMP_IMG="vmlinuz" #What is the images extension. Relocatable kernels don't have one KDUMP_IMG_EXT="" + +# Logging is controlled by following variables in the first kernel: +# - @var KDUMP_STDLOGLVL - logging level to standard error (console output) +# - @var KDUMP_SYSLOGLVL - logging level to syslog (by logger command) +# - @var KDUMP_KMSGLOGLVL - logging level to /dev/kmsg (only for boot-time) +# +# In the second kernel, kdump will use the rd.kdumploglvl option to set the +# log level in the above KDUMP_COMMANDLINE_APPEND. +# - @var rd.kdumploglvl - logging level to syslog (by logger command) +# - for example: add the rd.kdumploglvl=3 option to KDUMP_COMMANDLINE_APPEND +# +# Logging levels: no logging(0), error(1),warn(2),info(3),debug(4) +# +# KDUMP_STDLOGLVL=3 +# KDUMP_SYSLOGLVL=0 +# KDUMP_KMSGLOGLVL=0 diff --git a/SOURCES/kdump.sysconfig.ppc64 b/SOURCES/kdump.sysconfig.ppc64 index 7ce41e3..00b40ff 100644 --- a/SOURCES/kdump.sysconfig.ppc64 +++ b/SOURCES/kdump.sysconfig.ppc64 @@ -40,3 +40,19 @@ KDUMP_IMG="vmlinuz" KDUMP_IMG_EXT="" #Specify the action after failure + +# Logging is controlled by following variables in the first kernel: +# - @var KDUMP_STDLOGLVL - logging level to standard error (console output) +# - @var KDUMP_SYSLOGLVL - logging level to syslog (by logger command) +# - @var KDUMP_KMSGLOGLVL - logging level to /dev/kmsg (only for boot-time) +# +# In the second kernel, kdump will use the rd.kdumploglvl option to set the +# log level in the above KDUMP_COMMANDLINE_APPEND. +# - @var rd.kdumploglvl - logging level to syslog (by logger command) +# - for example: add the rd.kdumploglvl=3 option to KDUMP_COMMANDLINE_APPEND +# +# Logging levels: no logging(0), error(1),warn(2),info(3),debug(4) +# +# KDUMP_STDLOGLVL=3 +# KDUMP_SYSLOGLVL=0 +# KDUMP_KMSGLOGLVL=0 diff --git a/SOURCES/kdump.sysconfig.ppc64le b/SOURCES/kdump.sysconfig.ppc64le index 7ce41e3..00b40ff 100644 --- a/SOURCES/kdump.sysconfig.ppc64le +++ b/SOURCES/kdump.sysconfig.ppc64le @@ -40,3 +40,19 @@ KDUMP_IMG="vmlinuz" KDUMP_IMG_EXT="" #Specify the action after failure + +# Logging is controlled by following variables in the first kernel: +# - @var KDUMP_STDLOGLVL - logging level to standard error (console output) +# - @var KDUMP_SYSLOGLVL - logging level to syslog (by logger command) +# - @var KDUMP_KMSGLOGLVL - logging level to /dev/kmsg (only for boot-time) +# +# In the second kernel, kdump will use the rd.kdumploglvl option to set the +# log level in the above KDUMP_COMMANDLINE_APPEND. +# - @var rd.kdumploglvl - logging level to syslog (by logger command) +# - for example: add the rd.kdumploglvl=3 option to KDUMP_COMMANDLINE_APPEND +# +# Logging levels: no logging(0), error(1),warn(2),info(3),debug(4) +# +# KDUMP_STDLOGLVL=3 +# KDUMP_SYSLOGLVL=0 +# KDUMP_KMSGLOGLVL=0 diff --git a/SOURCES/kdump.sysconfig.s390x b/SOURCES/kdump.sysconfig.s390x index de0ac49..3f75b76 100644 --- a/SOURCES/kdump.sysconfig.s390x +++ b/SOURCES/kdump.sysconfig.s390x @@ -31,7 +31,7 @@ MKDUMPRD_ARGS="" # # Example: # KEXEC_ARGS="--elf32-core-headers" -KEXEC_ARGS="" +KEXEC_ARGS="-s" #Where to find the boot image #KDUMP_BOOTDIR="/boot" @@ -41,3 +41,19 @@ KDUMP_IMG="vmlinuz" #What is the images extension. Relocatable kernels don't have one KDUMP_IMG_EXT="" + +# Logging is controlled by following variables in the first kernel: +# - @var KDUMP_STDLOGLVL - logging level to standard error (console output) +# - @var KDUMP_SYSLOGLVL - logging level to syslog (by logger command) +# - @var KDUMP_KMSGLOGLVL - logging level to /dev/kmsg (only for boot-time) +# +# In the second kernel, kdump will use the rd.kdumploglvl option to set the +# log level in the above KDUMP_COMMANDLINE_APPEND. +# - @var rd.kdumploglvl - logging level to syslog (by logger command) +# - for example: add the rd.kdumploglvl=3 option to KDUMP_COMMANDLINE_APPEND +# +# Logging levels: no logging(0), error(1),warn(2),info(3),debug(4) +# +# KDUMP_STDLOGLVL=3 +# KDUMP_SYSLOGLVL=0 +# KDUMP_KMSGLOGLVL=0 diff --git a/SOURCES/kdump.sysconfig.x86_64 b/SOURCES/kdump.sysconfig.x86_64 index ce4d30f..b136d0c 100644 --- a/SOURCES/kdump.sysconfig.x86_64 +++ b/SOURCES/kdump.sysconfig.x86_64 @@ -38,3 +38,19 @@ KDUMP_IMG="vmlinuz" #What is the images extension. Relocatable kernels don't have one KDUMP_IMG_EXT="" + +# Logging is controlled by following variables in the first kernel: +# - @var KDUMP_STDLOGLVL - logging level to standard error (console output) +# - @var KDUMP_SYSLOGLVL - logging level to syslog (by logger command) +# - @var KDUMP_KMSGLOGLVL - logging level to /dev/kmsg (only for boot-time) +# +# In the second kernel, kdump will use the rd.kdumploglvl option to set the +# log level in the above KDUMP_COMMANDLINE_APPEND. +# - @var rd.kdumploglvl - logging level to syslog (by logger command) +# - for example: add the rd.kdumploglvl=3 option to KDUMP_COMMANDLINE_APPEND +# +# Logging levels: no logging(0), error(1),warn(2),info(3),debug(4) +# +# KDUMP_STDLOGLVL=3 +# KDUMP_SYSLOGLVL=0 +# KDUMP_KMSGLOGLVL=0 diff --git a/SOURCES/kdumpctl b/SOURCES/kdumpctl index 2fb7404..099d5fc 100755 --- a/SOURCES/kdumpctl +++ b/SOURCES/kdumpctl @@ -6,6 +6,7 @@ KDUMP_KERNEL="" KDUMP_COMMANDLINE="" KEXEC_ARGS="" KDUMP_CONFIG_FILE="/etc/kdump.conf" +KDUMP_LOG_PATH="/var/log" MKDUMPRD="/sbin/mkdumprd -f" DRACUT_MODULES_FILE="/usr/lib/dracut/modules.txt" SAVE_PATH=/var/crash @@ -21,11 +22,7 @@ FADUMP_REGISTER_SYS_NODE="/sys/kernel/fadump_registered" DEFAULT_DUMP_MODE="kdump" image_time=0 -[[ $dracutbasedir ]] || dracutbasedir=/usr/lib/dracut -. $dracutbasedir/dracut-functions.sh -. /lib/kdump/kdump-lib.sh - -standard_kexec_args="-p" +standard_kexec_args="-d -p" # Some default values in case /etc/sysconfig/kdump doesn't include KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug" @@ -34,13 +31,25 @@ if [ -f /etc/sysconfig/kdump ]; then . /etc/sysconfig/kdump fi +[[ $dracutbasedir ]] || dracutbasedir=/usr/lib/dracut +. $dracutbasedir/dracut-functions.sh +. /lib/kdump/kdump-lib.sh +. /lib/kdump/kdump-logger.sh + +#initiate the kdump logger +dlog_init +if [ $? -ne 0 ]; then + echo "failed to initiate the kdump logger." + exit 1 +fi + single_instance_lock() { local rc timeout=5 exec 9>/var/lock/kdump if [ $? -ne 0 ]; then - echo "Create file lock failed" + derror "Create file lock failed" exit 1 fi @@ -48,7 +57,7 @@ single_instance_lock() rc=$? while [ $rc -ne 0 ]; do - echo "Another app is currently holding the kdump lock; waiting for it to exit..." + dinfo "Another app is currently holding the kdump lock; waiting for it to exit..." flock -w $timeout 9 rc=$? done @@ -59,9 +68,10 @@ determine_dump_mode() # Check if firmware-assisted dump is enabled # if yes, set the dump mode as fadump if is_fadump_capable; then - echo "Dump mode is fadump" + dinfo "Dump mode is fadump" DEFAULT_DUMP_MODE="fadump" fi + ddebug "DEFAULT_DUMP_MODE=$DEFAULT_DUMP_MODE" } save_core() @@ -69,22 +79,25 @@ save_core() coredir="/var/crash/`date +"%Y-%m-%d-%H:%M"`" mkdir -p $coredir + ddebug "cp --sparse=always /proc/vmcore $coredir/vmcore-incomplete" cp --sparse=always /proc/vmcore $coredir/vmcore-incomplete if [ $? == 0 ]; then mv $coredir/vmcore-incomplete $coredir/vmcore - echo "saved a vmcore to $coredir" + dinfo "saved a vmcore to $coredir" else - echo "failed to save a vmcore to $coredir" >&2 + derror "failed to save a vmcore to $coredir" fi # pass the dmesg to Abrt tool if exists, in order # to collect the kernel oops message. # https://fedorahosted.org/abrt/ if [ -x /usr/bin/dumpoops ]; then + ddebug "makedumpfile --dump-dmesg $coredir/vmcore $coredir/dmesg" makedumpfile --dump-dmesg $coredir/vmcore $coredir/dmesg >/dev/null 2>&1 + ddebug "dumpoops -d $coredir/dmesg" dumpoops -d $coredir/dmesg >/dev/null 2>&1 if [ $? == 0 ]; then - echo "kernel oops has been collected by abrt tool" + dinfo "kernel oops has been collected by abrt tool" fi fi } @@ -96,16 +109,18 @@ rebuild_fadump_initrd() # this file tells the initrd is fadump enabled touch /tmp/fadump.initramfs target_initrd_tmp="$TARGET_INITRD.tmp" + ddebug "rebuild fadump initrd: $target_initrd_tmp $DEFAULT_INITRD_BAK $KDUMP_KERNELVER" $MKDUMPRD $target_initrd_tmp --rebuild $DEFAULT_INITRD_BAK --kver $KDUMP_KERNELVER \ -i /tmp/fadump.initramfs /etc/fadump.initramfs if [ $? != 0 ]; then - echo "mkdumprd: failed to rebuild initrd with fadump support" >&2 + derror "mkdumprd: failed to rebuild initrd with fadump support" rm -f /tmp/fadump.initramfs return 1 fi rm -f /tmp/fadump.initramfs # updating fadump initrd + ddebug "updating fadump initrd: $target_initrd_tmp $TARGET_INITRD" mv $target_initrd_tmp $TARGET_INITRD sync @@ -120,14 +135,15 @@ check_earlykdump_is_enabled() rebuild_kdump_initrd() { + ddebug "rebuild kdump initrd: $MKDUMPRD $TARGET_INITRD $KDUMP_KERNELVER" $MKDUMPRD $TARGET_INITRD $KDUMP_KERNELVER if [ $? != 0 ]; then - echo "mkdumprd: failed to make kdump initrd" >&2 + derror "mkdumprd: failed to make kdump initrd" return 1 fi if check_earlykdump_is_enabled; then - echo "Tips: If early kdump is enabled, also require rebuilding the system initramfs to make the changes take effect for early kdump." + dwarn "Tips: If early kdump is enabled, also require rebuilding the system initramfs to make the changes take effect for early kdump." fi return 0 @@ -136,7 +152,7 @@ rebuild_kdump_initrd() rebuild_initrd() { if [[ ! -w "$KDUMP_BOOTDIR" ]];then - echo "$KDUMP_BOOTDIR does not have write permission. Can not rebuild $TARGET_INITRD" + derror "$KDUMP_BOOTDIR does not have write permission. Can not rebuild $TARGET_INITRD" return 1 fi @@ -154,7 +170,7 @@ check_exist() { for file in $1; do if [ ! -e "$file" ]; then - echo -n "Error: $file not found."; echo + derror "Error: $file not found." return 1 fi done @@ -165,7 +181,7 @@ check_executable() { for file in $1; do if [ ! -x "$file" ]; then - echo -n "Error: $file is not executable."; echo + derror "Error: $file is not executable." return 1 fi done @@ -173,17 +189,19 @@ check_executable() backup_default_initrd() { + ddebug "backup default initrd: $DEFAULT_INITRD" + if [ ! -f "$DEFAULT_INITRD" ]; then return fi if [ ! -e $DEFAULT_INITRD_BAK ]; then - echo "Backing up $DEFAULT_INITRD before rebuild." + dinfo "Backing up $DEFAULT_INITRD before rebuild." # save checksum to verify before restoring sha1sum $DEFAULT_INITRD > $INITRD_CHECKSUM_LOCATION cp $DEFAULT_INITRD $DEFAULT_INITRD_BAK if [ $? -ne 0 ]; then - echo "WARNING: failed to backup $DEFAULT_INITRD." + dwarn "WARNING: failed to backup $DEFAULT_INITRD." rm -f $DEFAULT_INITRD_BAK fi fi @@ -191,6 +209,8 @@ backup_default_initrd() restore_default_initrd() { + ddebug "restore default initrd: $DEFAULT_INITRD" + if [ ! -f "$DEFAULT_INITRD" ]; then return fi @@ -202,13 +222,12 @@ restore_default_initrd() backup_checksum=`sha1sum $DEFAULT_INITRD_BAK | awk '{ print $1 }'` default_checksum=`cat $INITRD_CHECKSUM_LOCATION | awk '{ print $1 }'` if [ "$default_checksum" != "$backup_checksum" ]; then - echo "WARNING: checksum mismatch! Can't restore original initrd.." + dwarn "WARNING: checksum mismatch! Can't restore original initrd.." else rm -f $INITRD_CHECKSUM_LOCATION mv $DEFAULT_INITRD_BAK $DEFAULT_INITRD if [[ $? -eq 0 ]]; then - echo -n "Restoring original initrd as fadump mode " - echo "is disabled." + derror "Restoring original initrd as fadump mode is disabled." sync fi fi @@ -217,55 +236,58 @@ restore_default_initrd() check_config() { - local nr - - nr=$(awk 'BEGIN{cnt=0} /^raw|^ssh[[:blank:]]|^nfs|^ext[234]|^xfs|^btrfs|^minix|^dracut_args .*\-\-mount/{cnt++} END{print cnt}' $KDUMP_CONFIG_FILE) - [ $nr -gt 1 ] && { - echo "More than one dump targets specified." - return 1 - } - - nr=$(grep "^dracut_args .*\-\-mount" $KDUMP_CONFIG_FILE | grep -o "\-\-mount" | wc -l) - [ $nr -gt 1 ] && { - echo "Multiple mount targets specified in one \"dracut_args\"." - return 1 - } - - # Check if we have any leading spaces (or tabs) before the - # variable name in the kdump conf file - if grep -E -q '^[[:blank:]]+[a-z]' $KDUMP_CONFIG_FILE; then - echo "No whitespaces are allowed before a kdump option name in $KDUMP_CONFIG_FILE" - return 1 - fi - + local -A _opt_rec while read config_opt config_val; do + if [ -z "$config_val" ]; then + derror "Invalid kdump config value for option $config_opt" + return 1 + fi + case "$config_opt" in - \#* | "") - ;; - raw|ext2|ext3|ext4|minix|btrfs|xfs|nfs|ssh|sshkey|path|core_collector|kdump_post|kdump_pre|extra_bins|extra_modules|failure_action|default|final_action|force_rebuild|force_no_rebuild|dracut_args|fence_kdump_args|fence_kdump_nodes) - # remove inline comments after the end of a directive. - [ -z "$config_val" ] && { - echo "Invalid kdump config value for option $config_opt." - return 1; - } - if [ -d "/proc/device-tree/ibm,opal/dump" ] && [ "$config_opt" == "raw" ]; then - echo "WARNING: Won't capture opalcore when 'raw' dump target is used." + dracut_args) + if [[ $config_val == *--mount* ]]; then + if [ $(echo $config_val | grep -o "\-\-mount" | wc -l) -ne 1 ]; then + derror "Multiple mount targets specified in one \"dracut_args\"." + return 1 + fi + config_opt=_target fi ;; + raw) + if [ -d "/proc/device-tree/ibm,opal/dump" ]; then + derror "WARNING: Won't capture opalcore when 'raw' dump target is used." + return 1 + fi + config_opt=_target + ;; + ext[234]|minix|btrfs|xfs|nfs|ssh) + config_opt=_target + ;; + sshkey|path|core_collector|kdump_post|kdump_pre|extra_bins|extra_modules|failure_action|default|final_action|force_rebuild|force_no_rebuild|fence_kdump_args|fence_kdump_nodes) + ;; net|options|link_delay|disk_timeout|debug_mem_level|blacklist) - echo "Deprecated kdump config option: $config_opt. Refer to kdump.conf manpage for alternatives." + derror "Deprecated kdump config option: $config_opt. Refer to kdump.conf manpage for alternatives." return 1 ;; *) - echo "Invalid kdump config option $config_opt" - return 1; + derror "Invalid kdump config option $config_opt" + return 1 ;; esac + + if [ -n "${_opt_rec[$config_opt]}" ]; then + if [ $config_opt == _target ]; then + derror "More than one dump targets specified" + else + derror "Duplicated kdump config value of option $config_opt" + fi + return 1 + fi + _opt_rec[$config_opt]="$config_val" done <<< "$(read_strip_comments $KDUMP_CONFIG_FILE)" check_failure_action_config || return 1 check_final_action_config || return 1 - check_fence_kdump_config || return 1 return 0 @@ -302,6 +324,7 @@ setup_initrd() { prepare_kdump_bootinfo if [ $? -ne 0 ]; then + derror "failed to prepare for kdump bootinfo." return 1 fi @@ -309,7 +332,7 @@ setup_initrd() if [ $DEFAULT_DUMP_MODE == "fadump" ]; then TARGET_INITRD="$DEFAULT_INITRD" if [ ! -s "$TARGET_INITRD" ]; then - echo "Error: No initrd found to rebuild!" + derror "Error: No initrd found to rebuild!" return 1 fi @@ -376,7 +399,7 @@ check_files_modified() else # If it's not a module nor builtin, give an error if ! ( modprobe --set-version "$KDUMP_KERNELVER" --dry-run "$_module" &>/dev/null ); then - echo "Module $_module not found" + dwarn "Module $_module not found" fi fi done @@ -401,27 +424,66 @@ check_files_modified() fi fi else - echo "$file doesn't exist" + dwarn "$file doesn't exist" fi done if [ -n "$modified_files" ]; then - echo "Detected change(s) in the following file(s):" - echo -n " "; echo "$modified_files" | sed 's/\s/\n /g' + dinfo "Detected change(s) in the following file(s): $modified_files" return 1 fi return 0 } -check_dump_fs_modified() +check_drivers_modified() +{ + local _target _new_drivers _old_drivers _module_name _module_filename + + # If it's dump target is on block device, detect the block driver + _target=$(get_block_dump_target) + if [[ -n "$_target" ]]; then + _record_block_drivers() { + local _drivers + _drivers=$(udevadm info -a "/dev/block/$1" | sed -n 's/\s*DRIVERS=="\(\S\+\)"/\1/p') + for _driver in $_drivers; do + if ! [[ " $_new_drivers " == *" $_driver "* ]]; then + _new_drivers="$_new_drivers $_driver" + fi + done + + ddebug "MAJ:MIN=$1 drivers='$_drivers'" + } + check_block_and_slaves_all _record_block_drivers "$(get_maj_min "$_target")" + fi + + # Include watchdog drivers if watchdog module is not omitted + is_dracut_mod_omitted watchdog || is_dracut_mod_omitted watchdog-modules || _new_drivers+=" $(get_watchdog_drvs)" + + [ -z "$_new_drivers" ] && return 0 + _old_drivers="$(lsinitrd $TARGET_INITRD -f /usr/lib/dracut/loaded-kernel-modules.txt | tr '\n' ' ')" + + ddebug "Modules required for kdump: '$_new_drivers'" + ddebug "Modules included in old initramfs: '$_old_drivers'" + for _driver in $_new_drivers; do + # Skip deprecated/invalid driver name or built-in module + _module_name=$(modinfo --set-version "$KDUMP_KERNELVER" -F name $_driver 2>/dev/null) + _module_filename=$(modinfo --set-version "$KDUMP_KERNELVER" -n $_driver 2>/dev/null) + if [ $? -ne 0 ] || [ -z "$_module_name" ] || [[ "$_module_filename" = *"(builtin)"* ]]; then + continue + fi + if ! [[ " $_old_drivers " == *" $_module_name "* ]]; then + dinfo "Detected change in block device driver, new loaded module: $_module_name" + return 1 + fi + done +} + +check_fs_modified() { local _old_dev _old_mntpoint _old_fstype local _new_dev _new_mntpoint _new_fstype - local _target _path _dracut_args - local _target_drivers _module_name _module_filename - - local _old_drivers="$(lsinitrd $TARGET_INITRD -f /usr/lib/dracut/loaded-kernel-modules.txt | tr '\n' ' ')" + local _target _dracut_args # No need to check in case of mount target specified via "dracut_args". if is_mount_in_dracut_args; then @@ -434,66 +496,24 @@ check_dump_fs_modified() return 0 fi - _target=$(get_user_configured_dump_disk) - - if [[ -n "$_target" ]]; then - _target=$(to_dev_name $_target) - _new_fstype=$(blkid $_target | awk -F"TYPE=" '{print $2}' | cut -d '"' -f 2) - else - _path=$(get_save_path) - _target=$(get_target_from_path $_path) - _target=$(to_dev_name $_target) - _new_fstype=$(get_fs_type_from_target $_target) - if [[ -z "$_target" || -z "$_new_fstype" ]];then - echo "Dump path $_path does not exist" - return 2 - fi + _target=$(get_block_dump_target) + _new_fstype=$(get_fs_type_from_target $_target) + if [[ -z "$_target" ]] || [[ -z "$_new_fstype" ]];then + derror "Dump target is invalid" + return 2 fi - _record_block_drivers() { - local _drivers - if [[ -b /dev/block/$1 ]]; then - _drivers=$(udevadm info -a "/dev/block/$1" | sed -n 's/\s*DRIVERS=="\(\S\+\)"/\1/p') - fi - if [[ -b $1 ]]; then - _drivers=$(udevadm info -a "$1" | sed -n 's/\s*DRIVERS=="\(\S\+\)"/\1/p') - fi - for _driver in $_drivers; do - if ! [[ " $_target_drivers " == *" $_driver "* ]]; then - _target_drivers="$_target_drivers $_driver" - fi - done - return 1 - } - - check_block_and_slaves_all _record_block_drivers "$(get_maj_min "$_target")" - for _driver in $_target_drivers; do - # Skip deprecated/invalid driver name or built-in module - _module_name=$(modinfo --set-version "$KDUMP_KERNELVER" -F name $_driver 2>/dev/null) - _module_filename=$(modinfo --set-version "$KDUMP_KERNELVER" -n $_driver 2>/dev/null) - if [ $? -ne 0 ] || [ -z "$_module_name" ] || [[ "$_module_filename" = *"(builtin)"* ]]; then - continue - fi - if ! [[ " $_old_drivers " == *" $_module_name "* ]]; then - echo "Detected change in block device driver, new loaded module: $_module_name" - return 1 - fi - done - - if [[ $(expr substr $_new_fstype 1 3) = "nfs" ]];then - _new_dev=$_target - else - _new_dev=$(kdump_get_persistent_dev $_target) - if [ -z "$_new_dev" ]; then - echo "Get persistent device name failed" - return 2 - fi + ddebug "_target=$_target _new_fstype=$_new_fstype" + _new_dev=$(kdump_get_persistent_dev $_target) + if [ -z "$_new_dev" ]; then + perror "Get persistent device name failed" + return 2 fi _new_mntpoint="$(get_kdump_mntpoint_from_target $_target)" _dracut_args=$(lsinitrd $TARGET_INITRD -f usr/lib/dracut/build-parameter.txt) if [[ -z "$_dracut_args" ]];then - echo "Warning: No dracut arguments found in initrd" + dwarn "Warning: No dracut arguments found in initrd" return 0 fi @@ -511,63 +531,7 @@ check_dump_fs_modified() [[ "$_target" = "$(get_root_fs_device)" ]] && return 0 fi - echo "Detected change in File System" - return 1 -} - -check_wdt_modified() -{ - local -A _drivers - local _alldrivers _active _wdtdrv _wdtppath _dir - local wd_old wd_new - - is_wdt_mod_omitted - [[ $? -eq 0 ]] && return 0 - [[ -d /sys/class/watchdog/ ]] || return 0 - - # Copied logic from dracut 04watchdog/module-setup.sh::installkernel() - for _dir in /sys/class/watchdog/*; do - [[ -d "$_dir" ]] || continue - [[ -f "$_dir/state" ]] || continue - _active=$(< "$_dir/state") - [[ "$_active" = "active" ]] || continue - # device/modalias will return driver of this device - _wdtdrv=$(< "$_dir/device/modalias") - # There can be more than one module represented by same - # modalias. Currently load all of them. - # TODO: Need to find a way to avoid any unwanted module - # represented by modalias - _wdtdrv=$(modprobe --set-version "$KDUMP_KERNELVER" -R $_wdtdrv 2>/dev/null) - if [[ $_wdtdrv ]]; then - for i in $_wdtdrv; do - _drivers[$i]=1 - done - fi - # however in some cases, we also need to check that if there is - # a specific driver for the parent bus/device. In such cases - # we also need to enable driver for parent bus/device. - _wdtppath=$(readlink -f "$_dir/device") - while [[ -d "$_wdtppath" ]] && [[ "$_wdtppath" != "/sys" ]]; do - _wdtppath=$(readlink -f "$_wdtppath/..") - [[ -f "$_wdtppath/modalias" ]] || continue - - _wdtdrv=$(< "$_wdtppath/modalias") - _wdtdrv=$(modprobe --set-version "$KDUMP_KERNELVER" -R $_wdtdrv 2>/dev/null) - if [[ $_wdtdrv ]]; then - for i in $_wdtdrv; do - _drivers[$i]=1 - done - fi - done - done - - # ensure that watchdog module is loaded as early as possible - _alldrivers="${!_drivers[*]}" - [[ $_alldrivers ]] && wd_new="rd.driver.pre=${_alldrivers// /,}" - wd_old=$(lsinitrd $TARGET_INITRD -f etc/cmdline.d/00-watchdog.conf) - - [[ "$wd_old" = "$wd_new" ]] && return 0 - + dinfo "Detected change in File System" return 1 } @@ -586,16 +550,16 @@ check_system_modified() return $ret fi - check_dump_fs_modified + check_fs_modified ret=$? if [ $ret -ne 0 ]; then return $ret fi - check_wdt_modified - if [ $? -ne 0 ]; then - echo "Detected change in watchdog state" - return 1 + check_drivers_modified + ret=$? + if [ $ret -ne 0 ]; then + return $ret fi return 0 @@ -618,7 +582,7 @@ check_rebuild() if [ $? -eq 0 ]; then force_no_rebuild=`echo $_force_no_rebuild | cut -d' ' -f2` if [ "$force_no_rebuild" != "0" ] && [ "$force_no_rebuild" != "1" ];then - echo "Error: force_no_rebuild value is invalid" + derror "Error: force_no_rebuild value is invalid" return 1 fi fi @@ -627,13 +591,13 @@ check_rebuild() if [ $? -eq 0 ]; then force_rebuild=`echo $_force_rebuild | cut -d' ' -f2` if [ "$force_rebuild" != "0" ] && [ "$force_rebuild" != "1" ];then - echo "Error: force_rebuild value is invalid" + derror "Error: force_rebuild value is invalid" return 1 fi fi if [[ "$force_no_rebuild" == "1" && "$force_rebuild" == "1" ]]; then - echo "Error: force_rebuild and force_no_rebuild are enabled simultaneously in kdump.conf" + derror "Error: force_rebuild and force_no_rebuild are enabled simultaneously in kdump.conf" return 1 fi @@ -663,27 +627,58 @@ check_rebuild() fi if [ $image_time -eq 0 ]; then - echo -n "No kdump initial ramdisk found."; echo + dinfo "No kdump initial ramdisk found." elif [ "$capture_capable_initrd" == "0" ]; then - echo -n "Rebuild $TARGET_INITRD with dump capture support"; echo + dinfo "Rebuild $TARGET_INITRD with dump capture support" elif [ "$force_rebuild" != "0" ]; then - echo -n "Force rebuild $TARGET_INITRD"; echo + dinfo "Force rebuild $TARGET_INITRD" elif [ "$system_modified" != "0" ]; then : else return 0 fi - echo "Rebuilding $TARGET_INITRD" + dinfo "Rebuilding $TARGET_INITRD" rebuild_initrd return $? } +# On ppc64le LPARs, the keys trusted by firmware do not end up in +# .builtin_trusted_keys. So instead, add the key to the .ima keyring +function load_kdump_kernel_key() +{ + # this is only called inside is_secure_boot_enforced, + # no need to retest + + # this is only required if DT /ibm,secure-boot is a file. + # if it is a dir, we are on OpenPower and don't need this. + if ! [ -f /proc/device-tree/ibm,secure-boot ]; then + return + fi + + KDUMP_KEY_ID=$(cat /usr/share/doc/kernel-keys/$KDUMP_KERNELVER/kernel-signing-ppc.cer | + keyctl padd asymmetric kernelkey-$RANDOM %:.ima) +} + +# remove a previously loaded key. There's no real security implication +# to leaving it around, we choose to do this because it makes it easier +# to be idempotent and so as to reduce the potential for confusion. +function remove_kdump_kernel_key() +{ + if [ -z "$KDUMP_KEY_ID" ]; then + return + fi + + keyctl unlink $KDUMP_KEY_ID %:.ima +} + # 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. load_kdump() { + local ret + KEXEC_ARGS=$(prepare_kexec_args "${KEXEC_ARGS}") KDUMP_COMMANDLINE=$(prepare_cmdline "${KDUMP_COMMANDLINE}" "${KDUMP_COMMANDLINE_REMOVE}" "${KDUMP_COMMANDLINE_APPEND}") @@ -691,18 +686,37 @@ load_kdump() # Old syscall will always fail as it does not have capability to # to kernel signature verification. if is_secure_boot_enforced; then - echo "Secure Boot is enabled. Using kexec file based syscall." + dinfo "Secure Boot is enabled. Using kexec file based syscall." KEXEC_ARGS="$KEXEC_ARGS -s" + load_kdump_kernel_key fi + ddebug "$KEXEC $KEXEC_ARGS $standard_kexec_args --command-line=$KDUMP_COMMANDLINE --initrd=$TARGET_INITRD $KDUMP_KERNEL" + + # The '12' represents an intermediate temporary file descriptor + # to store the standard error file descriptor '2', and later + # restore the error file descriptor with the file descriptor '12' + # and release it. + exec 12>&2 + exec 2>> $KDUMP_LOG_PATH/kdump.log + PS4='+ $(date "+%Y-%m-%d %H:%M:%S") ${BASH_SOURCE}@${LINENO}: ' + set -x + $KEXEC $KEXEC_ARGS $standard_kexec_args \ --command-line="$KDUMP_COMMANDLINE" \ --initrd=$TARGET_INITRD $KDUMP_KERNEL - if [ $? == 0 ]; then - echo "kexec: loaded kdump kernel" + + ret=$? + set +x + exec 2>&12 12>&- + + remove_kdump_kernel_key + + if [ $ret == 0 ]; then + dinfo "kexec: loaded kdump kernel" return 0 else - echo "kexec: failed to load kdump kernel" >&2 + derror "kexec: failed to load kdump kernel" return 1 fi } @@ -717,7 +731,7 @@ check_ssh_config() # canonicalize the path SSH_KEY_LOCATION=$(/usr/bin/readlink -m $config_val) else - echo "WARNING: '$config_val' doesn't exist, using default value '$SSH_KEY_LOCATION'" + dwarn "WARNING: '$config_val' doesn't exist, using default value '$SSH_KEY_LOCATION'" fi ;; path) @@ -759,22 +773,22 @@ check_and_wait_network_ready() if [ $retval -eq 0 ]; then return 0 elif [ $retval -ne 255 ]; then - echo "Could not create $DUMP_TARGET:$SAVE_PATH, you should check the privilege on server side" >&2 + derror "Could not create $DUMP_TARGET:$SAVE_PATH, you should check the privilege on server side" return 1 fi # if server removes the authorized_keys or, no /root/.ssh/kdump_id_rsa - echo $errmsg | grep -q "Permission denied\|No such file or directory\|Host key verification failed" + ddebug "$errmsg" + echo $errmsg | grep -q "Permission denied\|No such file or directory\|Host key verification failed" &> /dev/null if [ $? -eq 0 ]; then - echo "Could not create $DUMP_TARGET:$SAVE_PATH, you probably need to run \"kdumpctl propagate\"" >&2 + derror "Could not create $DUMP_TARGET:$SAVE_PATH, you probably need to run \"kdumpctl propagate\"" return 1 fi if [ $warn_once -eq 1 ]; then - echo "Network dump target is not usable, waiting for it to be ready" + dwarn "Network dump target is not usable, waiting for it to be ready..." warn_once=0 fi - echo -n . cur=$(date +%s) let "diff = $cur - $start_time" @@ -785,7 +799,7 @@ check_and_wait_network_ready() sleep 1 done - echo "Could not create $DUMP_TARGET:$SAVE_PATH, ipaddr is not ready yet. You should check network connection" >&2 + dinfo "Could not create $DUMP_TARGET:$SAVE_PATH, ipaddr is not ready yet. You should check network connection" return 1 } @@ -802,7 +816,7 @@ propagate_ssh_key() { check_ssh_config if [ $? -ne 0 ]; then - echo "No ssh config specified in $KDUMP_CONFIG_FILE. Can't propagate" >&2 + derror "No ssh config specified in $KDUMP_CONFIG_FILE. Can't propagate" exit 1 fi @@ -811,11 +825,11 @@ propagate_ssh_key() #Check to see if we already created key, if not, create it. if [ -f $KEYFILE ]; then - echo "Using existing keys..." + dinfo "Using existing keys..." else - echo -n "Generating new ssh keys... " + dinfo "Generating new ssh keys... " /usr/bin/ssh-keygen -t rsa -f $KEYFILE -N "" 2>&1 > /dev/null - echo "done." + dinfo "done." fi #now find the target ssh user and server to contact. @@ -826,10 +840,10 @@ propagate_ssh_key() ssh-copy-id -i $KEYFILE $SSH_USER@$SSH_SERVER RET=$? if [ $RET == 0 ]; then - echo $KEYFILE has been added to ~$SSH_USER/.ssh/authorized_keys on $SSH_SERVER + dinfo "$KEYFILE has been added to ~$SSH_USER/.ssh/authorized_keys on $SSH_SERVER" return 0 else - echo $errmsg, $KEYFILE failed in transfer to $SSH_SERVER >&2 + derror "$errmsg, $KEYFILE failed in transfer to $SSH_SERVER" exit 1 fi } @@ -839,7 +853,7 @@ show_reserved_mem() local mem=$(cat /sys/kernel/kexec_crash_size) local mem_mb=$(expr $mem / 1024 / 1024) - echo "Reserved "$mem_mb"MB memory for crash kernel" + dinfo "Reserved "$mem_mb"MB memory for crash kernel" } check_current_fadump_status() @@ -869,7 +883,7 @@ save_raw() raw_target=$(awk '$1 ~ /^raw$/ { print $2; }' $KDUMP_CONFIG_FILE) [ -z "$raw_target" ] && return 0 [ -b "$raw_target" ] || { - echo "raw partition $raw_target not found" + derror "raw partition $raw_target not found" return 1 } kdump_dir=`grep ^path $KDUMP_CONFIG_FILE | cut -d' ' -f2-` @@ -881,12 +895,12 @@ save_raw() mkdir -p "$coredir" [ -d "$coredir" ] || { - echo "failed to create $coredir" + derror "failed to create $coredir" return 1 } if makedumpfile -R $coredir/vmcore <$raw_target >/dev/null 2>&1; then # dump found - echo "Dump saved to $coredir/vmcore" + dinfo "Dump saved to $coredir/vmcore" # wipe makedumpfile header dd if=/dev/zero of=$raw_target bs=1b count=1 2>/dev/null else @@ -959,13 +973,13 @@ check_fence_kdump_config() for node in $nodes; do if [ "$node" = "$hostname" ]; then - echo "Option fence_kdump_nodes cannot contain $hostname" + derror "Option fence_kdump_nodes cannot contain $hostname" return 1 fi # node can be ipaddr - echo $ipaddrs | grep $node > /dev/null + echo "$ipaddrs " | grep "$node " > /dev/null if [ $? -eq 0 ]; then - echo "Option fence_kdump_nodes cannot contain $node" + derror "Option fence_kdump_nodes cannot contain $node" return 1 fi done @@ -987,11 +1001,11 @@ start_fadump() { echo 1 > $FADUMP_REGISTER_SYS_NODE if ! check_current_fadump_status; then - echo "fadump: failed to register" + derror "fadump: failed to register" return 1 fi - echo "fadump: registered successfully" + dinfo "fadump: registered successfully" return 0 } @@ -1018,7 +1032,7 @@ check_failure_action_config() if [ -z "$failure_action" -a -z "$default_option" ]; then return 0 elif [ -n "$failure_action" -a -n "$default_option" ]; then - echo "Cannot specify 'failure_action' and 'default' option together" + derror "Cannot specify 'failure_action' and 'default' option together" return 1 fi @@ -1032,7 +1046,7 @@ check_failure_action_config() return 0 ;; *) - echo $"Usage kdump.conf: $option {reboot|halt|poweroff|shell|dump_to_rootfs}" + dinfo $"Usage kdump.conf: $option {reboot|halt|poweroff|shell|dump_to_rootfs}" return 1 esac } @@ -1050,7 +1064,7 @@ check_final_action_config() return 0 ;; *) - echo $"Usage kdump.conf: final_action {reboot|halt|poweroff}" + dinfo $"Usage kdump.conf: final_action {reboot|halt|poweroff}" return 1 esac fi @@ -1060,13 +1074,13 @@ start() { check_dump_feasibility if [ $? -ne 0 ]; then - echo "Starting kdump: [FAILED]" + derror "Starting kdump: [FAILED]" return 1 fi check_config if [ $? -ne 0 ]; then - echo "Starting kdump: [FAILED]" + derror "Starting kdump: [FAILED]" return 1 fi @@ -1076,43 +1090,43 @@ start() save_raw if [ $? -ne 0 ]; then - echo "Starting kdump: [FAILED]" + derror "Starting kdump: [FAILED]" return 1 fi check_current_status if [ $? == 0 ]; then - echo "Kdump already running: [WARNING]" + dwarn "Kdump already running: [WARNING]" return 0 fi if check_ssh_config; then if ! check_ssh_target; then - echo "Starting kdump: [FAILED]" + derror "Starting kdump: [FAILED]" return 1 fi fi check_rebuild if [ $? != 0 ]; then - echo "Starting kdump: [FAILED]" + derror "Starting kdump: [FAILED]" return 1 fi start_dump if [ $? != 0 ]; then - echo "Starting kdump: [FAILED]" + derror "Starting kdump: [FAILED]" return 1 fi - echo "Starting kdump: [OK]" + dinfo "Starting kdump: [OK]" } reload() { check_current_status if [ $? -ne 0 ]; then - echo "Kdump was not running: [WARNING]" + dwarn "Kdump was not running: [WARNING]" fi if [ $DEFAULT_DUMP_MODE == "fadump" ]; then @@ -1123,36 +1137,36 @@ reload() fi if [ $? -ne 0 ]; then - echo "Stopping kdump: [FAILED]" + derror "Stopping kdump: [FAILED]" return 1 fi - echo "Stopping kdump: [OK]" + dinfo "Stopping kdump: [OK]" setup_initrd if [ $? -ne 0 ]; then - echo "Starting kdump: [FAILED]" + derror "Starting kdump: [FAILED]" return 1 fi start_dump if [ $? -ne 0 ]; then - echo "Starting kdump: [FAILED]" + derror "Starting kdump: [FAILED]" return 1 fi - echo "Starting kdump: [OK]" + dinfo "Starting kdump: [OK]" } stop_fadump() { echo 0 > $FADUMP_REGISTER_SYS_NODE if check_current_fadump_status; then - echo "fadump: failed to unregister" + derror "fadump: failed to unregister" return 1 fi - echo "fadump: unregistered successfully" + dinfo "fadump: unregistered successfully" return 0 } @@ -1165,11 +1179,11 @@ stop_kdump() fi if [ $? != 0 ]; then - echo "kexec: failed to unload kdump kernel" + derror "kexec: failed to unload kdump kernel" return 1 fi - echo "kexec: unloaded kdump kernel" + dinfo "kexec: unloaded kdump kernel" return 0 } @@ -1177,7 +1191,7 @@ reload_fadump() { echo 1 > $FADUMP_REGISTER_SYS_NODE if [ $? == 0 ]; then - echo "fadump: re-registered successfully" + dinfo "fadump: re-registered successfully" return 0 else # FADump could fail on older kernel where re-register @@ -1202,11 +1216,11 @@ stop() fi if [ $? != 0 ]; then - echo "Stopping kdump: [FAILED]" + derror "Stopping kdump: [FAILED]" return 1 fi - echo "Stopping kdump: [OK]" + dinfo "Stopping kdump: [OK]" return 0 } @@ -1227,13 +1241,13 @@ rebuild() { return 1 fi - echo "Rebuilding $TARGET_INITRD" + dinfo "Rebuilding $TARGET_INITRD" rebuild_initrd return $? } if [ ! -f "$KDUMP_CONFIG_FILE" ]; then - echo "Error: No kdump config file found!" >&2 + derror "Error: No kdump config file found!" exit 1 fi @@ -1259,11 +1273,11 @@ main () check_current_status case "$?" in 0) - echo "Kdump is operational" + dinfo "Kdump is operational" EXIT_CODE=0 ;; 1) - echo "Kdump is not operational" + dinfo "Kdump is not operational" EXIT_CODE=3 ;; esac @@ -1288,7 +1302,7 @@ main () show_reserved_mem ;; *) - echo $"Usage: $0 {start|stop|status|restart|reload|rebuild|propagate|showmem}" + dinfo $"Usage: $0 {start|stop|status|restart|reload|rebuild|propagate|showmem}" exit 1 esac } diff --git a/SOURCES/kexec-kdump-howto.txt b/SOURCES/kexec-kdump-howto.txt index 50bd316..47e11c2 100644 --- a/SOURCES/kexec-kdump-howto.txt +++ b/SOURCES/kexec-kdump-howto.txt @@ -524,17 +524,91 @@ to send over the necessary ssh key file. Restart the kdump service via Advanced Setups =============== -Kdump boot directory --------------------- +About /etc/sysconfig/kdump +------------------------------ + +Currently, there are a few options in /etc/sysconfig/kdump, which are +usually used to control the behavior of kdump kernel. Basically, all of +these options have default values, usually we do not need to change them, +but sometimes, we may modify them in order to better control the behavior +of kdump kernel such as debug, etc. + +-KDUMP_BOOTDIR Usually kdump kernel is the same as 1st kernel. So kdump will try to find kdump kernel under /boot according to /proc/cmdline. E.g we execute below command and get an output: cat /proc/cmdline BOOT_IMAGE=/xxx/vmlinuz-3.yyy.zzz root=xxxx ..... -Then kdump kernel will be /boot/xxx/vmlinuz-3.yyy.zzz. -However a variable KDUMP_BOOTDIR in /etc/sysconfig/kdump is provided to -user if kdump kernel is put in a different directory. + +Then kdump kernel will be /boot/xxx/vmlinuz-3.yyy.zzz. However, this option +is provided to user if kdump kernel is put in a different directory. + +-KDUMP_IMG + +This represents the image type used for kdump. The default value is "vmlinuz". + +-KDUMP_IMG_EXT + +This represents the images extension. Relocatable kernels don't have one. +Currently, it is a null string by default. + +-KEXEC_ARGS + +Any additional kexec arguments required. For example: +KEXEC_ARGS="--elf32-core-headers". + +In most situations, this should be left empty. But, sometimes we hope to get +additional kexec loading debugging information, we can add the '-d' option +for the debugging. + +-KDUMP_KERNELVER + +This is a kernel version string for the kdump kernel. If the version is not +specified, the init script will try to find a kdump kernel with the same +version number as the running kernel. + +-KDUMP_COMMANDLINE + +The value of 'KDUMP_COMMANDLINE' will be passed to kdump kernel as command +line parameters, this will likely match the contents of the grub kernel line. + +In general, if a command line is not specified, which means that it is a null +string such as KDUMP_COMMANDLINE="", the default will be taken automatically +from the '/proc/cmdline'. + +-KDUMP_COMMANDLINE_REMOVE + +This option allows us to remove arguments from the current kdump command line. +If we don't specify any parameters for the KDUMP_COMMANDLINE, it will inherit +all values from the '/proc/cmdline', which is not expected. As you know, some +default kernel parameters could affect kdump, furthermore, that could cause +the failure of kdump kernel boot. + +In addition, the option is also helpful to debug the kdump kernel, we can use +this option to change kdump kernel command line. + +For more kernel parameters, please refer to kernel document. + +-KDUMP_COMMANDLINE_APPEND + +This option allows us to append arguments to the current kdump command line +after processed by the KDUMP_COMMANDLINE_REMOVE. For kdump kernel, some +specific modules require to be disabled like the mce, cgroup, numa, hest_disable, +etc. Those modules may waste memory or kdump kernel doesn't need them, +furthermore, there may affect kdump kernel boot. + +Just like above option, it can be used to disable or enable some kernel +modules so that we can exclude any errors for kdump kernel, this is very +meaningful for debugging. + +-KDUMP_STDLOGLVL | KDUMP_SYSLOGLVL | KDUMP_KMSGLOGLVL + +These variables are used to control the kdump log level in the first kernel. +In the second kernel, kdump will use the rd.kdumploglvl option to set the log +level in the above KDUMP_COMMANDLINE_APPEND. + +Logging levels: no logging(0), error(1), warn(2), info(3), debug(4) Kdump Post-Capture Executable ----------------------------- @@ -613,7 +687,7 @@ is a dump filtering and compression utility provided with kexec-tools. On some architectures, it can drastically reduce the size of your vmcore files, which becomes very useful on systems with large amounts of memory. -A typical setup is 'core_collector makedumpfile -F -l --message-level 1 -d 31', +A typical setup is 'core_collector makedumpfile -F -l --message-level 7 -d 31', but check the output of '/sbin/makedumpfile --help' for a list of all available options (-i and -g don't need to be specified, they're automatically taken care of). Note that use of makedumpfile requires that the kernel-debuginfo package @@ -633,11 +707,11 @@ First one is source file and second one is target file. For ex. - ex2. - core_collector "makedumpfile -l --message-level 1 -d 31" + core_collector "makedumpfile -l --message-level 7 -d 31" Above will effectively be translated to: - makedumpfile -l --message-level 1 -d 31 /proc/vmcore /vmcore + makedumpfile -l --message-level 7 -d 31 /proc/vmcore /vmcore For dump targets like raw and ssh, in general, core collector should expect one argument (source file) and should output the processed core on standard @@ -656,11 +730,11 @@ raw dumps core_collector examples: - ex4. - core_collector "makedumpfile -F -l --message-level 1 -d 31" + core_collector "makedumpfile -F -l --message-level 7 -d 31" Above will effectively be translated to. - makedumpfile -F -l --message-level 1 -d 31 | dd of= + makedumpfile -F -l --message-level 7 -d 31 | dd of= ssh dumps core_collector examples: @@ -674,11 +748,11 @@ ssh dumps core_collector examples: - ex6. - core_collector "makedumpfile -F -l --message-level 1 -d 31" + core_collector "makedumpfile -F -l --message-level 7 -d 31" Above will effectively be translated to. - makedumpfile -F -l --message-level 1 -d 31 | ssh "dd of=path/vmcore" + makedumpfile -F -l --message-level 7 -d 31 | ssh "dd of=path/vmcore" There is one exception to standard output rule for ssh dumps. And that is scp. As scp can handle ssh destinations for file transfers, one can @@ -696,9 +770,9 @@ About default core collector ---------------------------- Default core_collector for ssh/raw dump is: -"makedumpfile -F -l --message-level 1 -d 31". +"makedumpfile -F -l --message-level 7 -d 31". Default core_collector for other targets is: -"makedumpfile -l --message-level 1 -d 31". +"makedumpfile -l --message-level 7 -d 31". Even if core_collector option is commented out in kdump.conf, makedumpfile is default core collector and kdump uses it internally. @@ -885,3 +959,83 @@ Debugging Tips minicom -C /tmp/console-logs Now minicom should be logging serial console in file console-logs. + +- Using the logger to output kdump log messages + + You can configure the kdump log level for the first kernel in the + /etc/sysconfig/kdump. For example: + + KDUMP_STDLOGLVL=3 + KDUMP_SYSLOGLVL=0 + KDUMP_KMSGLOGLVL=0 + + The above configurations indicate that kdump messages will be printed + to the console, and the KDUMP_STDLOGLVL is set to 3(info), but the + KDUMP_SYSLOGLVL and KDUMP_KMSGLOGLVL are set to 0(no logging). This + is also the current default log levels in the first kernel. + + In the second kernel, you can add the 'rd.kdumploglvl=X' option to the + KDUMP_COMMANDLINE_APPEND in the /etc/sysconfig/kdump so that you can also + set the log levels for the second kernel. The 'X' represents the logging + levels, the default log level is 3(info) in the second kernel, for example: + + # cat /etc/sysconfig/kdump |grep rd.kdumploglvl + KDUMP_COMMANDLINE_APPEND="irqpoll nr_cpus=1 reset_devices cgroup_disable=memory mce=off numa=off udev.children-max=2 panic=10 acpi_no_memhotplug transparent_hugepage=never nokaslr hest_disable novmcoredd rd.kdumploglvl=3" + + Logging levels: no logging(0), error(1),warn(2),info(3),debug(4) + + The ERROR level designates error events that might still allow the application + to continue running. + + The WARN level designates potentially harmful situations. + + The INFO level designates informational messages that highlight the progress + of the application at coarse-grained level. + + The DEBUG level designates fine-grained informational events that are most + useful to debug an application. + + Note: if you set the log level to 0, that will disable the logs at the + corresponding log level, which indicates that it has no log output. + + At present, the logger works in both the first kernel(kdump service debugging) + and the second kernel. + + In the first kernel, you can find the historical logs with the journalctl + command and check kdump service debugging information. In addition, the + 'kexec -d' debugging messages are also saved to /var/log/kdump.log in the + first kernel. For example: + + [root@ibm-z-109 ~]# ls -al /var/log/kdump.log + -rw-r--r--. 1 root root 63238 Oct 28 06:40 /var/log/kdump.log + + If you want to get the debugging information of building kdump initramfs, you + can enable the '--debug' option for the dracut_args in the /etc/kdump.conf, and + then rebuild the kdump initramfs as below: + + # systemctl restart kdump.service + + That will rebuild the kdump initramfs and gerenate some logs to journald, you + can find the dracut logs with the journalctl command. + + In the second kernel, kdump will automatically put the kexec-dmesg.log to a same + directory with the vmcore, the log file includes the debugging messages like dmesg + and journald logs. For example: + + [root@ibm-z-109 ~]# ls -al /var/crash/127.0.0.1-2020-10-28-02\:01\:23/ + drwxr-xr-x. 2 root root 67 Oct 28 02:02 . + drwxr-xr-x. 6 root root 154 Oct 28 02:01 .. + -rw-r--r--. 1 root root 21164 Oct 28 02:01 kexec-dmesg.log + -rw-------. 1 root root 74238698 Oct 28 02:01 vmcore + -rw-r--r--. 1 root root 17532 Oct 28 02:01 vmcore-dmesg.txt + + If you want to get more debugging information in the second kernel, you can add + the 'rd.debug' option to the KDUMP_COMMANDLINE_APPEND in the /etc/sysconfig/kdump, + and then reload them in order to make the changes take effect. + + In addition, you can also add the 'rd.memdebug=X' option to the KDUMP_COMMANDLINE_APPEND + in the /etc/sysconfig/kdump in order to output the additional information about + kernel module memory consumption during loading. + + For more details, please refer to the /etc/sysconfig/kdump, or the man page of + dracut.cmdline and kdump.conf. diff --git a/SOURCES/kexec-tools-2.0.20-Remove-duplicated-variable-declarations.patch b/SOURCES/kexec-tools-2.0.20-Remove-duplicated-variable-declarations.patch new file mode 100644 index 0000000..d54f45a --- /dev/null +++ b/SOURCES/kexec-tools-2.0.20-Remove-duplicated-variable-declarations.patch @@ -0,0 +1,99 @@ +From cc087b11462af9f971a2c090d07e8d780a867b50 Mon Sep 17 00:00:00 2001 +From: Kairui Song +Date: Wed, 29 Jan 2020 13:38:19 +0800 +Subject: [PATCH] kexec-tools: Remove duplicated variable declarations + +When building kexec-tools for Fedora 32, following error is observed: + +/usr/bin/ld: kexec/arch/x86_64/kexec-bzImage64.o:(.bss+0x0): multiple definition of `bzImage_support_efi_boot'; +kexec/arch/i386/kexec-bzImage.o:(.bss+0x0): first defined here + +/builddir/build/BUILD/kexec-tools-2.0.20/kexec/arch/arm/../../fs2dt.h:33: multiple definition of `my_debug'; +kexec/fs2dt.o:/builddir/build/BUILD/kexec-tools-2.0.20/kexec/fs2dt.h:33: first defined here + +/builddir/build/BUILD/kexec-tools-2.0.20/kexec/arch/arm64/kexec-arm64.h:68: multiple definition of `arm64_mem'; +kexec/fs2dt.o:/builddir/build/BUILD/kexec-tools-2.0.20/././kexec/arch/arm64/kexec-arm64.h:68: first defined here + +/builddir/build/BUILD/kexec-tools-2.0.20/kexec/arch/arm64/kexec-arm64.h:54: multiple definition of `initrd_size'; +kexec/fs2dt.o:/builddir/build/BUILD/kexec-tools-2.0.20/././kexec/arch/arm64/kexec-arm64.h:54: first defined here + +/builddir/build/BUILD/kexec-tools-2.0.20/kexec/arch/arm64/kexec-arm64.h:53: multiple definition of `initrd_base'; +kexec/fs2dt.o:/builddir/build/BUILD/kexec-tools-2.0.20/././kexec/arch/arm64/kexec-arm64.h:53: first defined here + +And apparently, these variables are wrongly declared multiple times. So +remove duplicated declaration. + +Signed-off-by: Kairui Song +Signed-off-by: Simon Horman +--- + kexec/arch/arm64/kexec-arm64.h | 6 +++--- + kexec/arch/ppc64/kexec-elf-ppc64.c | 2 -- + kexec/arch/x86_64/kexec-bzImage64.c | 1 - + kexec/fs2dt.h | 2 +- + 4 files changed, 4 insertions(+), 7 deletions(-) + +diff --git a/kexec/arch/arm64/kexec-arm64.h b/kexec/arch/arm64/kexec-arm64.h +index 628de79..ed447ac 100644 +--- a/kexec/arch/arm64/kexec-arm64.h ++++ b/kexec/arch/arm64/kexec-arm64.h +@@ -50,8 +50,8 @@ int zImage_arm64_load(int argc, char **argv, const char *kernel_buf, + void zImage_arm64_usage(void); + + +-off_t initrd_base; +-off_t initrd_size; ++extern off_t initrd_base; ++extern off_t initrd_size; + + /** + * struct arm64_mem - Memory layout info. +@@ -65,7 +65,7 @@ struct arm64_mem { + }; + + #define arm64_mem_ngv UINT64_MAX +-struct arm64_mem arm64_mem; ++extern struct arm64_mem arm64_mem; + + uint64_t get_phys_offset(void); + uint64_t get_vp_offset(void); +diff --git a/kexec/arch/ppc64/kexec-elf-ppc64.c b/kexec/arch/ppc64/kexec-elf-ppc64.c +index 3510b70..695b8b0 100644 +--- a/kexec/arch/ppc64/kexec-elf-ppc64.c ++++ b/kexec/arch/ppc64/kexec-elf-ppc64.c +@@ -44,8 +44,6 @@ + uint64_t initrd_base, initrd_size; + unsigned char reuse_initrd = 0; + const char *ramdisk; +-/* Used for enabling printing message from purgatory code */ +-int my_debug = 0; + + int elf_ppc64_probe(const char *buf, off_t len) + { +diff --git a/kexec/arch/x86_64/kexec-bzImage64.c b/kexec/arch/x86_64/kexec-bzImage64.c +index 8edb3e4..ba8dc48 100644 +--- a/kexec/arch/x86_64/kexec-bzImage64.c ++++ b/kexec/arch/x86_64/kexec-bzImage64.c +@@ -42,7 +42,6 @@ + #include + + static const int probe_debug = 0; +-int bzImage_support_efi_boot; + + int bzImage64_probe(const char *buf, off_t len) + { +diff --git a/kexec/fs2dt.h b/kexec/fs2dt.h +index 7633273..fe24931 100644 +--- a/kexec/fs2dt.h ++++ b/kexec/fs2dt.h +@@ -30,7 +30,7 @@ extern struct bootblock bb[1]; + + /* Used for enabling printing message from purgatory code + * Only has implemented for PPC64 */ +-int my_debug; ++extern int my_debug; + extern int dt_no_old_root; + + void reserve(unsigned long long where, unsigned long long length); +-- +2.7.5 + diff --git a/SOURCES/kexec-tools-2.0.20-eppic-Remove-duplicated-variable-declaration.patch b/SOURCES/kexec-tools-2.0.20-eppic-Remove-duplicated-variable-declaration.patch new file mode 100644 index 0000000..892f4fb --- /dev/null +++ b/SOURCES/kexec-tools-2.0.20-eppic-Remove-duplicated-variable-declaration.patch @@ -0,0 +1,25 @@ +From f54ad866c428ecd64a01cfdf7fc6b0a64f5e0fe5 Mon Sep 17 00:00:00 2001 +From: Pingfan Liu +Date: Tue, 15 Dec 2020 14:13:13 +0800 +Subject: [PATCH] fix + +--- + eppic/libeppic/eppic.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/eppic/libeppic/eppic.h b/eppic/libeppic/eppic.h +index 06320f2..74a3c1c 100644 +--- a/eppic/libeppic/eppic.h ++++ b/eppic/libeppic/eppic.h +@@ -467,7 +467,7 @@ type_t *eppic_addstorage(type_t *t1, type_t *t2); + type_t *eppic_getvoidstruct(int ctype); + + extern int lineno, needvar, instruct, nomacs, eppic_legacy; +-node_t *lastv; ++extern node_t *lastv; + + #define NULLNODE ((node_t*)0) + +-- +2.29.2 + diff --git a/SOURCES/kexec-tools-2.0.20-makedumpfile-PATCH-Align-PMD_SECTION_MASK-with-PHYS_MASK.patch b/SOURCES/kexec-tools-2.0.20-makedumpfile-PATCH-Align-PMD_SECTION_MASK-with-PHYS_MASK.patch deleted file mode 100644 index e165b7d..0000000 --- a/SOURCES/kexec-tools-2.0.20-makedumpfile-PATCH-Align-PMD_SECTION_MASK-with-PHYS_MASK.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 7242ae4cb5288df626f464ced0a8b60fd669100b Mon Sep 17 00:00:00 2001 -From: Michal Suchanek -Date: Mon, 16 Mar 2020 19:39:58 +0100 -Subject: [PATCH 6/7] [PATCH] Align PMD_SECTION_MASK with PHYS_MASK - -Reportedly on some arm64 systems makedumpfile loops forever exhausting -all memory when filtering kernel core. It turns out the reason is it -cannot resolve some addresses because the PMD mask is wrong. When -physical address mask allows up to 48bits pmd mask should allow the -same. -I suppose you would need a system that needs physical addresses over 1TB -to be able to reproduce this. This may be either because you have a lot -of memory or because the firmware mapped some memory above 1TB for some -reason. - -Signed-off-by: Michal Suchanek ---- - arch/arm64.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/makedumpfile-1.6.7/arch/arm64.c b/makedumpfile-1.6.7/arch/arm64.c -index 43164cc..54d60b4 100644 ---- a/makedumpfile-1.6.7/arch/arm64.c -+++ b/makedumpfile-1.6.7/arch/arm64.c -@@ -81,7 +81,7 @@ static unsigned long kimage_voffset; - * Remove the highest order bits that are not a part of the - * physical address in a section - */ --#define PMD_SECTION_MASK ((1UL << 40) - 1) -+#define PMD_SECTION_MASK ((1UL << PHYS_MASK_SHIFT) - 1) - - #define PMD_TYPE_MASK 3 - #define PMD_TYPE_SECT 1 --- -2.7.5 - diff --git a/SOURCES/kexec-tools-2.0.20-makedumpfile-PATCH-Avoid-false-positive-failure-in-mem_seciton-va.patch b/SOURCES/kexec-tools-2.0.20-makedumpfile-PATCH-Avoid-false-positive-failure-in-mem_seciton-va.patch deleted file mode 100644 index 1033494..0000000 --- a/SOURCES/kexec-tools-2.0.20-makedumpfile-PATCH-Avoid-false-positive-failure-in-mem_seciton-va.patch +++ /dev/null @@ -1,80 +0,0 @@ -From 81b79c514ff6fc881f1df4cb04ecb2d7cb22badc Mon Sep 17 00:00:00 2001 -From: Kazuhito Hagio -Date: Wed, 19 Feb 2020 12:48:13 -0500 -Subject: [PATCH] [PATCH] Avoid false-positive failure in mem_seciton - validation - -Currently in get_mem_section(), we check whether SYMBOL(mem_section) -is a pointer to the array or a pointer to the pointer to the array -for some cases. - -However, with commit e113f1c974c8 ("[PATCH] cope with not-present -mem section") relaxing the check, there was a report that the function -failed because both of two validate_mem_section() calls return TRUE. - -Avoid the false-positive failure by not calling the second one if the -first one returns TRUE. - -Reported-by: Pingfan Liu -Acked-by: Thadeu Lima de Souza Cascardo -Signed-off-by: Kazuhito Hagio ---- - makedumpfile.c | 29 ++++++----------------------- - 1 file changed, 6 insertions(+), 23 deletions(-) - -diff --git a/makedumpfile-1.6.7/makedumpfile.c b/makedumpfile-1.6.7/makedumpfile.c -index f5860a1..4c4251e 100644 ---- a/makedumpfile-1.6.7/makedumpfile.c -+++ b/makedumpfile-1.6.7/makedumpfile.c -@@ -3472,7 +3472,6 @@ static int - get_mem_section(unsigned int mem_section_size, unsigned long *mem_maps, - unsigned int num_section) - { -- unsigned long mem_section_ptr; - int ret = FALSE; - unsigned long *mem_sec = NULL; - -@@ -3484,34 +3483,18 @@ get_mem_section(unsigned int mem_section_size, unsigned long *mem_maps, - ret = validate_mem_section(mem_sec, SYMBOL(mem_section), - mem_section_size, mem_maps, num_section); - -- if (is_sparsemem_extreme()) { -- int symbol_valid = ret; -- int pointer_valid; -- int mem_maps_size = sizeof(*mem_maps) * num_section; -- unsigned long *mem_maps_ex = NULL; -+ if (!ret && is_sparsemem_extreme()) { -+ unsigned long mem_section_ptr; -+ - if (!readmem(VADDR, SYMBOL(mem_section), &mem_section_ptr, - sizeof(mem_section_ptr))) - goto out; - -- if ((mem_maps_ex = malloc(mem_maps_size)) == NULL) { -- ERRMSG("Can't allocate memory for the mem_maps. %s\n", -- strerror(errno)); -- goto out; -- } -+ ret = validate_mem_section(mem_sec, mem_section_ptr, -+ mem_section_size, mem_maps, num_section); - -- pointer_valid = validate_mem_section(mem_sec, -- mem_section_ptr, -- mem_section_size, -- mem_maps_ex, -- num_section); -- if (pointer_valid) -- memcpy(mem_maps, mem_maps_ex, mem_maps_size); -- if (mem_maps_ex) -- free(mem_maps_ex); -- ret = symbol_valid ^ pointer_valid; -- if (!ret) { -+ if (!ret) - ERRMSG("Could not validate mem_section.\n"); -- } - } - out: - if (mem_sec != NULL) --- -2.7.5 - diff --git a/SOURCES/kexec-tools-2.0.20-makedumpfile-PATCH-Fix-cd_header-offset-overflow-with-large-pfn.patch b/SOURCES/kexec-tools-2.0.20-makedumpfile-PATCH-Fix-cd_header-offset-overflow-with-large-pfn.patch deleted file mode 100644 index 85b5048..0000000 --- a/SOURCES/kexec-tools-2.0.20-makedumpfile-PATCH-Fix-cd_header-offset-overflow-with-large-pfn.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 6e4b2dfaed5e5e5c617e0e45f969c1f571c13e27 Mon Sep 17 00:00:00 2001 -From: Jialong Chen -Date: Mon, 23 Mar 2020 16:42:01 -0400 -Subject: [PATCH 7/7] [PATCH] Fix cd_header offset overflow with large pfn - -In function write_kdump_pages_and_bitmap_cyclic(), cd_header->offset is -calculated by the following formula: - - cd_header->offset - = (DISKDUMP_HEADER_BLOCKS + dh->sub_hdr_size + dh->bitmap_blocks) - * dh->block_size; - -However, the variables of the right side are only int and unsigned int, -so if dh->bitmap_blocks is very large, it causes an interger overflow. - -As a result, makedumpfile created a broken vmcore in a system with a -physical address range from 0x602770ecf000 to 0x6027ffffffff, and the -crash utility failed during session initialization, ending with the -error message "crash: vmlinux and vmcore do not match!". - -Signed-off-by: Jialong Chen -Signed-off-by: Kazuhito Hagio ---- - diskdump_mod.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/makedumpfile-1.6.7/diskdump_mod.h b/makedumpfile-1.6.7/diskdump_mod.h -index 2676817..3733953 100644 ---- a/makedumpfile-1.6.7/diskdump_mod.h -+++ b/makedumpfile-1.6.7/diskdump_mod.h -@@ -22,7 +22,7 @@ - #define DISK_DUMP_SIGNATURE "DISKDUMP" - #define KDUMP_SIGNATURE "KDUMP " - #define SIG_LEN (sizeof(DUMP_PARTITION_SIGNATURE) - 1) --#define DISKDUMP_HEADER_BLOCKS (1) -+#define DISKDUMP_HEADER_BLOCKS (1UL) - - /* - * These are all remnants of the old "diskdump" facility, --- -2.7.5 - diff --git a/SOURCES/kexec-tools-2.0.20-makedumpfile-PATCH-Introduce-check-params-option.patch b/SOURCES/kexec-tools-2.0.20-makedumpfile-PATCH-Introduce-check-params-option.patch deleted file mode 100644 index b83d083..0000000 --- a/SOURCES/kexec-tools-2.0.20-makedumpfile-PATCH-Introduce-check-params-option.patch +++ /dev/null @@ -1,255 +0,0 @@ -From 989152e113bfcb4fbfbad6f3aed6f43be4455919 Mon Sep 17 00:00:00 2001 -From: Kazuhito Hagio -Date: Tue, 25 Feb 2020 16:04:55 -0500 -Subject: [PATCH 4/7] [PATCH] Introduce --check-params option - -Currently it's difficult to check whether a makedumpfile command-line -is valid or not without an actual panic. This is inefficient and if -a wrong configuration is not tested, you will miss the vmcore when an -actual panic occurs. - -In order for kdump facilities like kexec-tools to be able to check -the specified command-line parameters in advance, introduce the ---check-params option that only checks them and exits immediately. - -Signed-off-by: Kazuhito Hagio ---- - makedumpfile.8 | 5 ++++ - makedumpfile.c | 75 +++++++++++++++++++++++++++++++++++++++++++++------------- - makedumpfile.h | 2 ++ - print_info.c | 4 ++++ - 4 files changed, 69 insertions(+), 17 deletions(-) - -diff --git a/makedumpfile-1.6.7/makedumpfile.8 b/makedumpfile-1.6.7/makedumpfile.8 -index bf156a8..c5d4806 100644 ---- a/makedumpfile-1.6.7/makedumpfile.8 -+++ b/makedumpfile-1.6.7/makedumpfile.8 -@@ -632,6 +632,11 @@ Show help message and LZO/snappy support status (enabled/disabled). - \fB\-v\fR - Show the version of makedumpfile. - -+.TP -+\fB\-\-check-params\fR -+Only check whether the command-line parameters are valid or not, and exit. -+Preferable to be given as the first parameter. -+ - .SH ENVIRONMENT VARIABLES - - .TP 8 -diff --git a/makedumpfile-1.6.7/makedumpfile.c b/makedumpfile-1.6.7/makedumpfile.c -index 607e07f..f5860a1 100644 ---- a/makedumpfile-1.6.7/makedumpfile.c -+++ b/makedumpfile-1.6.7/makedumpfile.c -@@ -10972,12 +10972,6 @@ check_param_for_creating_dumpfile(int argc, char *argv[]) - if (info->flag_generate_vmcoreinfo || info->flag_rearrange) - return FALSE; - -- if ((message_level < MIN_MSG_LEVEL) -- || (MAX_MSG_LEVEL < message_level)) { -- message_level = DEFAULT_MSG_LEVEL; -- MSG("Message_level is invalid.\n"); -- return FALSE; -- } - if ((info->flag_compress && info->flag_elf_dumpfile) - || (info->flag_read_vmcoreinfo && info->name_vmlinux) - || (info->flag_read_vmcoreinfo && info->name_xen_syms)) -@@ -11007,6 +11001,11 @@ check_param_for_creating_dumpfile(int argc, char *argv[]) - if (info->flag_partial_dmesg && !info->flag_dmesg) - return FALSE; - -+ if (info->flag_excludevm && !info->working_dir) { -+ MSG("-%c requires --work-dir\n", OPT_EXCLUDE_UNUSED_VM); -+ return FALSE; -+ } -+ - if ((argc == optind + 2) && !info->flag_flatten - && !info->flag_split - && !info->flag_sadump_diskset) { -@@ -11402,6 +11401,23 @@ int show_mem_usage(void) - return TRUE; - } - -+static int set_message_level(char *str_ml) -+{ -+ int ml; -+ -+ ml = atoi(str_ml); -+ if ((ml < MIN_MSG_LEVEL) || (MAX_MSG_LEVEL < ml)) { -+ message_level = DEFAULT_MSG_LEVEL; -+ MSG("Message_level(%d) is invalid.\n", ml); -+ return FALSE; -+ } -+ -+ if (info->flag_check_params) -+ return TRUE; -+ -+ message_level = ml; -+ return TRUE; -+} - - static struct option longopts[] = { - {"split", no_argument, NULL, OPT_SPLIT}, -@@ -11423,6 +11439,7 @@ static struct option longopts[] = { - {"splitblock-size", required_argument, NULL, OPT_SPLITBLOCK_SIZE}, - {"work-dir", required_argument, NULL, OPT_WORKING_DIR}, - {"num-threads", required_argument, NULL, OPT_NUM_THREADS}, -+ {"check-params", no_argument, NULL, OPT_CHECK_PARAMS}, - {0, 0, 0, 0} - }; - -@@ -11521,7 +11538,8 @@ main(int argc, char *argv[]) - info->flag_compress = DUMP_DH_COMPRESSED_LZO; - break; - case OPT_MESSAGE_LEVEL: -- message_level = atoi(optarg); -+ if (!set_message_level(optarg)) -+ goto out; - break; - case OPT_DUMP_DMESG: - info->flag_dmesg = 1; -@@ -11584,6 +11602,10 @@ main(int argc, char *argv[]) - case OPT_NUM_THREADS: - info->num_threads = MAX(atoi(optarg), 0); - break; -+ case OPT_CHECK_PARAMS: -+ info->flag_check_params = TRUE; -+ message_level = DEFAULT_MSG_LEVEL; -+ break; - case '?': - MSG("Commandline parameter is invalid.\n"); - MSG("Try `makedumpfile --help' for more information.\n"); -@@ -11593,11 +11615,9 @@ main(int argc, char *argv[]) - if (flag_debug) - message_level |= ML_PRINT_DEBUG_MSG; - -- if (info->flag_excludevm && !info->working_dir) { -- ERRMSG("Error: -%c requires --work-dir\n", OPT_EXCLUDE_UNUSED_VM); -- ERRMSG("Try `makedumpfile --help' for more information\n"); -- return COMPLETED; -- } -+ if (info->flag_check_params) -+ /* suppress debugging messages */ -+ message_level = DEFAULT_MSG_LEVEL; - - if (info->flag_show_usage) { - print_usage(); -@@ -11628,6 +11648,9 @@ main(int argc, char *argv[]) - MSG("Try `makedumpfile --help' for more information.\n"); - goto out; - } -+ if (info->flag_check_params) -+ goto check_ok; -+ - if (!open_files_for_generating_vmcoreinfo()) - goto out; - -@@ -11651,6 +11674,9 @@ main(int argc, char *argv[]) - MSG("Try `makedumpfile --help' for more information.\n"); - goto out; - } -+ if (info->flag_check_params) -+ goto check_ok; -+ - if (!check_dump_file(info->name_dumpfile)) - goto out; - -@@ -11671,6 +11697,9 @@ main(int argc, char *argv[]) - MSG("Try `makedumpfile --help' for more information.\n"); - goto out; - } -+ if (info->flag_check_params) -+ goto check_ok; -+ - if (!check_dump_file(info->name_dumpfile)) - goto out; - -@@ -11684,6 +11713,9 @@ main(int argc, char *argv[]) - MSG("Try `makedumpfile --help' for more information.\n"); - goto out; - } -+ if (info->flag_check_params) -+ goto check_ok; -+ - if (!check_dump_file(info->name_dumpfile)) - goto out; - if (!dump_dmesg()) -@@ -11697,6 +11729,9 @@ main(int argc, char *argv[]) - MSG("Try `makedumpfile --help' for more information.\n"); - goto out; - } -+ if (info->flag_check_params) -+ goto check_ok; -+ - if (!populate_kernel_version()) - goto out; - -@@ -11715,6 +11750,9 @@ main(int argc, char *argv[]) - MSG("Try `makedumpfile --help' for more information.\n"); - goto out; - } -+ if (info->flag_check_params) -+ goto check_ok; -+ - if (info->flag_split) { - for (i = 0; i < info->num_dumpfile; i++) { - SPLITTING_FD_BITMAP(i) = -1; -@@ -11742,13 +11780,16 @@ main(int argc, char *argv[]) - MSG("The dumpfile is saved to %s.\n", info->name_dumpfile); - } - } -+check_ok: - retcd = COMPLETED; - out: -- MSG("\n"); -- if (retcd != COMPLETED) -- MSG("makedumpfile Failed.\n"); -- else if (!info->flag_mem_usage) -- MSG("makedumpfile Completed.\n"); -+ if (!info->flag_check_params) { -+ MSG("\n"); -+ if (retcd != COMPLETED) -+ MSG("makedumpfile Failed.\n"); -+ else if (!info->flag_mem_usage) -+ MSG("makedumpfile Completed.\n"); -+ } - - free_for_parallel(); - -diff --git a/makedumpfile-1.6.7/makedumpfile.h b/makedumpfile-1.6.7/makedumpfile.h -index 7217407..03fb4ce 100644 ---- a/makedumpfile-1.6.7/makedumpfile.h -+++ b/makedumpfile-1.6.7/makedumpfile.h -@@ -1301,6 +1301,7 @@ struct DumpInfo { - int flag_read_vmcoreinfo; /* flag of reading vmcoreinfo file */ - int flag_show_usage; /* flag of showing usage */ - int flag_show_version; /* flag of showing version */ -+ int flag_check_params; /* only check parameters */ - int flag_flatten; /* flag of outputting flattened - format to a standard out */ - int flag_rearrange; /* flag of creating dumpfile from -@@ -2362,6 +2363,7 @@ struct elf_prstatus { - #define OPT_WORKING_DIR OPT_START+15 - #define OPT_NUM_THREADS OPT_START+16 - #define OPT_PARTIAL_DMESG OPT_START+17 -+#define OPT_CHECK_PARAMS OPT_START+18 - - /* - * Function Prototype. -diff --git a/makedumpfile-1.6.7/print_info.c b/makedumpfile-1.6.7/print_info.c -index 0be12ea..e0c38b4 100644 ---- a/makedumpfile-1.6.7/print_info.c -+++ b/makedumpfile-1.6.7/print_info.c -@@ -321,6 +321,10 @@ print_usage(void) - MSG(" [-v]:\n"); - MSG(" Show the version of makedumpfile.\n"); - MSG("\n"); -+ MSG(" [--check-params]:\n"); -+ MSG(" Only check whether the command-line parameters are valid or not, and exit.\n"); -+ MSG(" Preferable to be given as the first parameter.\n"); -+ MSG("\n"); - MSG(" VMLINUX:\n"); - MSG(" This is a pathname to the first kernel's vmlinux.\n"); - MSG(" This file must have the debug information of the first kernel to analyze\n"); --- -2.7.5 - diff --git a/SOURCES/kexec-tools-2.0.20-makedumpfile-PATCH-Makefile-Fix-build-errors-in-static-build.patch b/SOURCES/kexec-tools-2.0.20-makedumpfile-PATCH-Makefile-Fix-build-errors-in-static-build.patch deleted file mode 100644 index f2f2153..0000000 --- a/SOURCES/kexec-tools-2.0.20-makedumpfile-PATCH-Makefile-Fix-build-errors-in-static-build.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 12250baa02584dc713cdb1a12fb366f643fdc8b3 Mon Sep 17 00:00:00 2001 -From: Kazuhito Hagio -Date: Mon, 9 Mar 2020 17:17:31 -0400 -Subject: [PATCH 5/7] [PATCH] Makefile: Fix build errors in static build - -When building makedumpfile statically (without LINKTYPE=dynamic), -the following error is observed: - - /usr/bin/ld: /usr/lib/makedumpfile-1.6.7/gcc/x86_64-redhat-linux/9/../../../../lib64/libdw.a(lzma.o): in function `__libdw_unlzma': - (.text+0xbd): undefined reference to `lzma_auto_decoder' - /usr/bin/ld: (.text+0x23a): undefined reference to `lzma_code' - /usr/bin/ld: (.text+0x269): undefined reference to `lzma_end' - /usr/bin/ld: (.text+0x2aa): undefined reference to `lzma_end' - /usr/bin/ld: (.text+0x3ac): undefined reference to `lzma_end' - /usr/bin/ld: (.text+0x427): undefined reference to `lzma_end' - /usr/bin/ld: (.text+0x62b): undefined reference to `lzma_end' - collect2: error: ld returned 1 exit status - make: *** [Makefile:97: makedumpfile] Error 1 - -Also, when doing it with USESNAPPY=on: - - /usr/bin/ld: /usr/local/lib64/libsnappy.a(snappy.cc.o): in function `snappy::internal::WorkingMemory::WorkingMemory(unsigned long)': - snappy.cc:(.text+0x7d4): undefined reference to `std::allocator::allocator()' - /usr/bin/ld: snappy.cc:(.text+0x803): undefined reference to `std::allocator::~allocator()' - /usr/bin/ld: snappy.cc:(.text+0x853): undefined reference to `std::allocator::~allocator()' - /usr/bin/ld: /usr/local/lib64/libsnappy.a(snappy.cc.o): in function `snappy::internal::WorkingMemory::~WorkingMemory()': - snappy.cc:(.text+0x87e): undefined reference to `std::allocator::allocator()' - /usr/bin/ld: snappy.cc:(.text+0x8a8): undefined reference to `std::allocator::~allocator()' - ... - -Fix these errors by adding -llzma and -lstd++ to LIBS respectively -if LINKTYPE=dynamic is not specified. - -Reported-by: Prabhakar Kushwaha -Signed-off-by: Kazuhito Hagio ---- - Makefile | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/makedumpfile-1.6.7/Makefile b/makedumpfile-1.6.7/Makefile -index 868eea6..ef20672 100644 ---- a/makedumpfile-1.6.7/Makefile -+++ b/makedumpfile-1.6.7/Makefile -@@ -52,7 +52,7 @@ OBJ_ARCH=$(patsubst %.c,%.o,$(SRC_ARCH)) - - LIBS = -ldw -lbz2 -ldl -lelf -lz - ifneq ($(LINKTYPE), dynamic) --LIBS := -static $(LIBS) -+LIBS := -static $(LIBS) -llzma - endif - - ifeq ($(USELZO), on) -@@ -62,6 +62,9 @@ endif - - ifeq ($(USESNAPPY), on) - LIBS := -lsnappy $(LIBS) -+ifneq ($(LINKTYPE), dynamic) -+LIBS := $(LIBS) -lstdc++ -+endif - CFLAGS += -DUSESNAPPY - endif - --- -2.7.5 - diff --git a/SOURCES/kexec-tools-2.0.20-makedumpfile-PATCH-Remove-duplicated-variable-definitions.patch b/SOURCES/kexec-tools-2.0.20-makedumpfile-PATCH-Remove-duplicated-variable-definitions.patch deleted file mode 100644 index 691cd05..0000000 --- a/SOURCES/kexec-tools-2.0.20-makedumpfile-PATCH-Remove-duplicated-variable-definitions.patch +++ /dev/null @@ -1,103 +0,0 @@ -From 399f2c9a3acd5bd913e50a4dde52dee6527b297e Mon Sep 17 00:00:00 2001 -From: Kairui Song -Date: Wed, 29 Jan 2020 13:37:13 +0800 -Subject: [PATCH 2/7] [PATCH] Remove duplicated variable definitions - -When building on Fedora 32 (with GCC 10), following error is observed: - -/usr/bin/ld: erase_info.o:/tmp/makedumpfile/makedumpfile.h:2010: multiple definition of - `crash_reserved_mem_nr'; elf_info.o:/tmp/makedumpfile/makedumpfile.h:2010: first defined here -/usr/bin/ld: erase_info.o:/tmp/makedumpfile/makedumpfile.h:2009: multiple definition of - `crash_reserved_mem'; elf_info.o:/tmp/makedumpfile/makedumpfile.h:2009: first defined here -/usr/bin/ld: erase_info.o:/tmp/makedumpfile/makedumpfile.h:1278: multiple definition of - `parallel_info_t'; elf_info.o:/tmp/makedumpfile/makedumpfile.h:1278: first defined here -/usr/bin/ld: erase_info.o:/tmp/makedumpfile/makedumpfile.h:1265: multiple definition of - `splitting_info_t'; elf_info.o:/tmp/makedumpfile/makedumpfile.h:1265: first defined here -... -collect2: error: ld returned 1 exit status -make: *** [Makefile:97: makedumpfile] Error 1 - -These variables are wrongly defined multiple times. So remove the -duplicated definitions. - -Signed-off-by: Kairui Song -Signed-off-by: Kazuhito Hagio ---- - makedumpfile.c | 8 ++++---- - makedumpfile.h | 8 ++++---- - 2 files changed, 8 insertions(+), 8 deletions(-) - -diff --git a/makedumpfile-1.6.7/makedumpfile.c b/makedumpfile-1.6.7/makedumpfile.c -index e290fbd..ae7336a 100644 ---- a/makedumpfile-1.6.7/makedumpfile.c -+++ b/makedumpfile-1.6.7/makedumpfile.c -@@ -10954,7 +10954,7 @@ check_param_for_reassembling_dumpfile(int argc, char *argv[]) - return FALSE; - - if ((info->splitting_info -- = malloc(sizeof(splitting_info_t) * info->num_dumpfile)) -+ = malloc(sizeof(struct splitting_info) * info->num_dumpfile)) - == NULL) { - MSG("Can't allocate memory for splitting_info.\n"); - return FALSE; -@@ -11042,7 +11042,7 @@ check_param_for_creating_dumpfile(int argc, char *argv[]) - return FALSE; - } - if ((info->splitting_info -- = malloc(sizeof(splitting_info_t) * info->num_dumpfile)) -+ = malloc(sizeof(struct splitting_info) * info->num_dumpfile)) - == NULL) { - MSG("Can't allocate memory for splitting_info.\n"); - return FALSE; -@@ -11077,13 +11077,13 @@ check_param_for_creating_dumpfile(int argc, char *argv[]) - - if (info->num_threads) { - if ((info->parallel_info = -- malloc(sizeof(parallel_info_t) * info->num_threads)) -+ malloc(sizeof(struct parallel_info) * info->num_threads)) - == NULL) { - MSG("Can't allocate memory for parallel_info.\n"); - return FALSE; - } - -- memset(info->parallel_info, 0, sizeof(parallel_info_t) -+ memset(info->parallel_info, 0, sizeof(struct parallel_info) - * info->num_threads); - } - -diff --git a/makedumpfile-1.6.7/makedumpfile.h b/makedumpfile-1.6.7/makedumpfile.h -index 68d9691..7217407 100644 ---- a/makedumpfile-1.6.7/makedumpfile.h -+++ b/makedumpfile-1.6.7/makedumpfile.h -@@ -1262,7 +1262,7 @@ struct splitting_info { - mdf_pfn_t end_pfn; - off_t offset_eraseinfo; - unsigned long size_eraseinfo; --} splitting_info_t; -+}; - - struct parallel_info { - int fd_memory; -@@ -1275,7 +1275,7 @@ struct parallel_info { - #ifdef USELZO - lzo_bytep wrkmem; - #endif --} parallel_info_t; -+}; - - struct ppc64_vmemmap { - unsigned long phys; -@@ -2006,8 +2006,8 @@ struct memory_range { - }; - - #define CRASH_RESERVED_MEM_NR 8 --struct memory_range crash_reserved_mem[CRASH_RESERVED_MEM_NR]; --int crash_reserved_mem_nr; -+extern struct memory_range crash_reserved_mem[CRASH_RESERVED_MEM_NR]; -+extern int crash_reserved_mem_nr; - - unsigned long read_vmcoreinfo_symbol(char *str_symbol); - int readmem(int type_addr, unsigned long long addr, void *bufptr, size_t size); --- -2.7.5 - diff --git a/SOURCES/kexec-tools-2.0.20-makedumpfile-PATCH-cope-with-not-present-mem-section.patch b/SOURCES/kexec-tools-2.0.20-makedumpfile-PATCH-cope-with-not-present-mem-section.patch deleted file mode 100644 index 2e9832c..0000000 --- a/SOURCES/kexec-tools-2.0.20-makedumpfile-PATCH-cope-with-not-present-mem-section.patch +++ /dev/null @@ -1,65 +0,0 @@ -From e113f1c974c820f9633dc0073eda525d7575f365 Mon Sep 17 00:00:00 2001 -From: Pingfan Liu -Date: Mon, 20 Jan 2020 10:25:24 +0800 -Subject: [PATCH 3/7] [PATCH] cope with not-present mem section - -After kernel commit ba72b4c8cf60 ("mm/sparsemem: support sub-section -hotplug"), when hot-removed, section_mem_map is still encoded with section -start pfn, not NULL. This break the current makedumpfile. - - # makedumpfile -x vmlinux -l -d 31 vmcore vmcore.dump - get_mem_section: Could not validate mem_section. - get_mm_sparsemem: Can't get the address of mem_section. - - makedumpfile Failed. - -Whatever section_mem_map coding info after hot-removed, it is reliable -just to work on SECTION_MARKED_PRESENT bit. Fixing makedumpfile by this -way. - -[ This issue occurs on kernel 5.3 through 5.5, and should be fixed by -commit 1f503443e7df ("mm/sparse.c: reset section's mem_map when fully -deactivated") in 5.6-rc1, 5.5.3 and 5.4.19. ] - -Signed-off-by: Pingfan Liu -To: kexec@lists.infradead.org -Cc: Kazuhito Hagio -Cc: Baoquan He -Cc: David Hildenbrand -Cc: Andrew Morton -Cc: Dan Williams -Cc: Oscar Salvador -Cc: Michal Hocko -Cc: Qian Cai ---- - makedumpfile.c | 6 +----- - 1 file changed, 1 insertion(+), 5 deletions(-) - -diff --git a/makedumpfile-1.6.7/makedumpfile.c b/makedumpfile-1.6.7/makedumpfile.c -index ae7336a..607e07f 100644 ---- a/makedumpfile-1.6.7/makedumpfile.c -+++ b/makedumpfile-1.6.7/makedumpfile.c -@@ -3406,8 +3406,6 @@ section_mem_map_addr(unsigned long addr, unsigned long *map_mask) - map = ULONG(mem_section + OFFSET(mem_section.section_mem_map)); - mask = SECTION_MAP_MASK; - *map_mask = map & ~mask; -- if (map == 0x0) -- *map_mask |= SECTION_MARKED_PRESENT; - map &= mask; - free(mem_section); - -@@ -3453,10 +3451,8 @@ validate_mem_section(unsigned long *mem_sec, - mem_map = NOT_MEMMAP_ADDR; - } else { - mem_map = section_mem_map_addr(section, &map_mask); -+ /* for either no mem_map or hot-removed */ - if (!(map_mask & SECTION_MARKED_PRESENT)) { -- return FALSE; -- } -- if (mem_map == 0) { - mem_map = NOT_MEMMAP_ADDR; - } else { - mem_map = sparse_decode_mem_map(mem_map, --- -2.7.5 - diff --git a/SOURCES/kexec-tools-2.0.20-makedumpfile-PATCH-sadump-kaslr-fix-failure-of-calculating-kaslr.patch b/SOURCES/kexec-tools-2.0.20-makedumpfile-PATCH-sadump-kaslr-fix-failure-of-calculating-kaslr.patch deleted file mode 100644 index 6814649..0000000 --- a/SOURCES/kexec-tools-2.0.20-makedumpfile-PATCH-sadump-kaslr-fix-failure-of-calculating-kaslr.patch +++ /dev/null @@ -1,213 +0,0 @@ -From 3c0cf7a93cff83f1e711e241eb47fcb096a451c5 Mon Sep 17 00:00:00 2001 -From: HATAYAMA Daisuke -Date: Thu, 9 Jul 2020 18:27:49 +0900 -Subject: [PATCH] [PATCH] sadump, kaslr: fix failure of calculating - kaslr_offset due to an sadump format restriction - -We faced recently a memory dump collected by sadump where unused part -of register values are non-zero. For the crash dump, calculating -kaslr_offset fails because it is based on the assumption that unused -part of register values in the sadump format are always zero cleared. - -The problem is that used and unused part of register values are -rigorously indistinguishable in the sadump format. Although there is -kernel data structure that represents a map between logical cpu -numbers and lapic ids, they cannot be used in order to calculate -kaslr_offset. - -To fix this, we have no choice but use a trial-and-error approach: try -to use each entry of register values in order until we find a good -pair of cr3 and idtr by which we can refer to linux_banner symbol as -expected. - -Signed-off-by: HATAYAMA Daisuke ---- - sadump_info.c | 129 +++++++++++++++++++++++++++++++++++++++++----------------- - 1 file changed, 91 insertions(+), 38 deletions(-) - -diff --git a/makedumpfile-1.6.7/sadump_info.c b/makedumpfile-1.6.7/sadump_info.c -index 72a077b4f408..410c6bc2a909 100644 ---- a/makedumpfile-1.6.7/sadump_info.c -+++ b/makedumpfile-1.6.7/sadump_info.c -@@ -101,6 +101,7 @@ static int lookup_diskset(unsigned long long whole_offset, int *diskid, - unsigned long long *disk_offset); - static int max_mask_cpu(void); - static int cpu_online_mask_init(void); -+static int linux_banner_sanity_check(ulong cr3); - static int per_cpu_init(void); - static int get_data_from_elf_note_desc(const char *note_buf, uint32_t n_descsz, - char *name, uint32_t n_type, char **data); -@@ -1293,6 +1294,30 @@ finish: - return ret; - } - -+static int linux_banner_sanity_check(ulong cr3) -+{ -+ unsigned long linux_banner_paddr; -+ char buf[sizeof("Linux version")]; -+ -+ linux_banner_paddr = vtop4_x86_64_pagetable(SYMBOL(linux_banner), cr3); -+ if (linux_banner_paddr == NOT_PADDR) { -+ DEBUG_MSG("sadump: linux_banner address translation failed\n"); -+ return FALSE; -+ } -+ -+ if (!readmem(PADDR, linux_banner_paddr, &buf, sizeof(buf))) { -+ DEBUG_MSG("sadump: reading linux_banner failed\n"); -+ return FALSE; -+ } -+ -+ if (!STRNEQ(buf, "Linux version")) { -+ DEBUG_MSG("sadump: linux_banner sanity check failed\n"); -+ return FALSE; -+ } -+ -+ return TRUE; -+} -+ - /* - * Calculate kaslr_offset and phys_base - * -@@ -1370,59 +1395,85 @@ calc_kaslr_offset(void) - { - struct sadump_header *sh = si->sh_memory; - uint64_t idtr = 0, cr3 = 0, idtr_paddr; -- struct sadump_smram_cpu_state smram, zero; -+ struct sadump_smram_cpu_state smram; - int apicid; - unsigned long divide_error_vmcore, divide_error_vmlinux; - unsigned long kaslr_offset, phys_base; - unsigned long kaslr_offset_kdump, phys_base_kdump; -+ int sanity_check_passed = FALSE; - -- memset(&zero, 0, sizeof(zero)); - for (apicid = 0; apicid < sh->nr_cpus; ++apicid) { -+ -+ DEBUG_MSG("sadump: apicid: %d\n", apicid); -+ - if (!get_smram_cpu_state(apicid, &smram)) { - ERRMSG("get_smram_cpu_state error\n"); - return FALSE; - } - -- if (memcmp(&smram, &zero, sizeof(smram)) != 0) -- break; -- } -- if (apicid >= sh->nr_cpus) { -- ERRMSG("Can't get smram state\n"); -- return FALSE; -- } -+ idtr = ((uint64_t)smram.IdtUpper)<<32|(uint64_t)smram.IdtLower; - -- idtr = ((uint64_t)smram.IdtUpper)<<32 | (uint64_t)smram.IdtLower; -- if ((SYMBOL(pti_init) != NOT_FOUND_SYMBOL) || -- (SYMBOL(kaiser_init) != NOT_FOUND_SYMBOL)) -- cr3 = smram.Cr3 & ~(CR3_PCID_MASK|PTI_USER_PGTABLE_MASK); -- else -- cr3 = smram.Cr3 & ~CR3_PCID_MASK; -+ if (!smram.Cr3 || !idtr) { -+ DEBUG_MSG("sadump: cr3: %lx idt: %lx, skipped\n", -+ smram.Cr3, idtr); -+ continue; -+ } - -- /* Convert virtual address of IDT table to physical address */ -- if ((idtr_paddr = vtop4_x86_64_pagetable(idtr, cr3)) == NOT_PADDR) -- return FALSE; -+ if ((SYMBOL(pti_init) != NOT_FOUND_SYMBOL) || -+ (SYMBOL(kaiser_init) != NOT_FOUND_SYMBOL)) -+ cr3 = smram.Cr3 & ~(CR3_PCID_MASK|PTI_USER_PGTABLE_MASK); -+ else -+ cr3 = smram.Cr3 & ~CR3_PCID_MASK; - -- /* Now we can calculate kaslr_offset and phys_base */ -- divide_error_vmlinux = SYMBOL(divide_error); -- divide_error_vmcore = get_vec0_addr(idtr_paddr); -- kaslr_offset = divide_error_vmcore - divide_error_vmlinux; -- phys_base = idtr_paddr - -- (SYMBOL(idt_table) + kaslr_offset - __START_KERNEL_map); -+ /* Convert virtual address of IDT table to physical address */ -+ idtr_paddr = vtop4_x86_64_pagetable(idtr, cr3); -+ if (idtr_paddr == NOT_PADDR) { -+ DEBUG_MSG("sadump: converting IDT physical address " -+ "failed.\n"); -+ continue; -+ } - -- info->kaslr_offset = kaslr_offset; -- info->phys_base = phys_base; -+ /* Now we can calculate kaslr_offset and phys_base */ -+ divide_error_vmlinux = SYMBOL(divide_error); -+ divide_error_vmcore = get_vec0_addr(idtr_paddr); -+ kaslr_offset = divide_error_vmcore - divide_error_vmlinux; -+ phys_base = idtr_paddr - -+ (SYMBOL(idt_table)+kaslr_offset-__START_KERNEL_map); - -- DEBUG_MSG("sadump: idtr=%" PRIx64 "\n", idtr); -- DEBUG_MSG("sadump: cr3=%" PRIx64 "\n", cr3); -- DEBUG_MSG("sadump: idtr(phys)=%" PRIx64 "\n", idtr_paddr); -- DEBUG_MSG("sadump: devide_error(vmlinux)=%lx\n", -- divide_error_vmlinux); -- DEBUG_MSG("sadump: devide_error(vmcore)=%lx\n", -- divide_error_vmcore); -+ info->kaslr_offset = kaslr_offset; -+ info->phys_base = phys_base; - -- /* Reload symbol */ -- if (!get_symbol_info()) -- return FALSE; -+ DEBUG_MSG("sadump: idtr=%" PRIx64 "\n", idtr); -+ DEBUG_MSG("sadump: cr3=%" PRIx64 "\n", cr3); -+ DEBUG_MSG("sadump: idtr(phys)=%" PRIx64 "\n", idtr_paddr); -+ DEBUG_MSG("sadump: devide_error(vmlinux)=%lx\n", -+ divide_error_vmlinux); -+ DEBUG_MSG("sadump: devide_error(vmcore)=%lx\n", -+ divide_error_vmcore); -+ -+ /* Reload symbol */ -+ if (!get_symbol_info()) { -+ ERRMSG("Reading symbol table failed\n"); -+ return FALSE; -+ } -+ -+ /* Sanity check */ -+ if (linux_banner_sanity_check(cr3)) { -+ sanity_check_passed = TRUE; -+ break; -+ } -+ -+ info->kaslr_offset = 0; -+ info->phys_base = 0; -+ } -+ -+ if (!sanity_check_passed) { -+ ERRMSG("failed to calculate kaslr_offset and phys_base; " -+ "default to 0\n"); -+ info->kaslr_offset = 0; -+ info->phys_base = 0; -+ return TRUE; -+ } - - /* - * Check if current kaslr_offset/phys_base is for 1st kernel or 2nd -@@ -1430,13 +1481,15 @@ calc_kaslr_offset(void) - * from vmcoreinfo - */ - if (get_kaslr_offset_from_vmcoreinfo(cr3, &kaslr_offset_kdump, -- &phys_base_kdump)) { -+ &phys_base_kdump)) { - info->kaslr_offset = kaslr_offset_kdump; - info->phys_base = phys_base_kdump; - - /* Reload symbol */ -- if (!get_symbol_info()) -+ if (!get_symbol_info()) { -+ ERRMSG("Reading symbol table failed\n"); - return FALSE; -+ } - } - - DEBUG_MSG("sadump: kaslr_offset=%lx\n", info->kaslr_offset); --- -2.7.4 - diff --git a/SOURCES/mkdumprd b/SOURCES/mkdumprd index 8b09710..6e923fe 100644 --- a/SOURCES/mkdumprd +++ b/SOURCES/mkdumprd @@ -6,18 +6,30 @@ # Written by Cong Wang # +if [ -f /etc/sysconfig/kdump ]; then + . /etc/sysconfig/kdump +fi + [[ $dracutbasedir ]] || dracutbasedir=/usr/lib/dracut . $dracutbasedir/dracut-functions.sh . /lib/kdump/kdump-lib.sh +. /lib/kdump/kdump-logger.sh export IN_KDUMP=1 +#initiate the kdump logger +dlog_init +if [ $? -ne 0 ]; then + echo "failed to initiate the kdump logger." + exit 1 +fi + conf_file="/etc/kdump.conf" SSH_KEY_LOCATION="/root/.ssh/kdump_id_rsa" SAVE_PATH=$(get_save_path) OVERRIDE_RESETTABLE=0 extra_modules="" -dracut_args="--quiet --hostonly --hostonly-cmdline --hostonly-i18n --hostonly-mode strict -o \"plymouth dash resume ifcfg earlykdump\"" +dracut_args="--add kdumpbase --quiet --hostonly --hostonly-cmdline --hostonly-i18n --hostonly-mode strict -o \"plymouth dash resume ifcfg earlykdump\"" readonly MKDUMPRD_TMPDIR="$(mktemp -d -t mkdumprd.XXXXXX)" [ -d "$MKDUMPRD_TMPDIR" ] || perror_exit "dracut: mktemp -p -d -t dracut.XXXXXX failed." @@ -33,28 +45,10 @@ trap ' # clean up after ourselves no matter how we die. trap 'exit 1;' SIGINT -is_wdt_addition_needed() { - local active - - is_wdt_mod_omitted - [[ $? -eq 0 ]] && return 1 - [[ -d /sys/class/watchdog/ ]] || return 1 - for dir in /sys/class/watchdog/*; do - [[ -f "$dir/state" ]] || continue - active=$(< "$dir/state") - [[ "$active" = "active" ]] && return 0 - done - return 1 -} - add_dracut_arg() { dracut_args="$dracut_args $@" } -add_dracut_module() { - add_dracut_arg "--add" "\"$1\"" -} - add_dracut_mount() { add_dracut_arg "--mount" "\"$1\"" } @@ -177,8 +171,8 @@ check_size() { fi if [ $avail -lt $memtotal ]; then - echo "Warning: There might not be enough space to save a vmcore." - echo " The size of $2 should be greater than $memtotal kilo bytes." + dwarn "Warning: There might not be enough space to save a vmcore." + dwarn " The size of $2 should be greater than $memtotal kilo bytes." fi } @@ -250,7 +244,7 @@ verify_core_collector() { if [ "$_cmd" != "makedumpfile" ]; then if is_raw_dump_target; then - echo "Warning: specifying a non-makedumpfile core collector, you will have to recover the vmcore manually." + dwarn "Warning: specifying a non-makedumpfile core collector, you will have to recover the vmcore manually." fi return fi @@ -340,7 +334,7 @@ is_unresettable() resettable="$(cat $path)" [ $resettable -eq 0 -a "$OVERRIDE_RESETTABLE" -eq 0 ] && { local device=$(udevadm info --query=all --path=/sys/dev/block/$1 | awk -F= '/DEVNAME/{print $2}') - echo "Error: Can not save vmcore because device $device is unresettable" + derror "Error: Can not save vmcore because device $device is unresettable" return 0 } fi @@ -374,7 +368,7 @@ is_crypt() eval "$line" [[ "$ID_FS_TYPE" = "crypto_LUKS" ]] && { dev=$(udevadm info --query=all --path=/sys/dev/block/$majmin | awk -F= '/DEVNAME/{print $2}') - echo "Device $dev is encrypted." + derror "Device $dev is encrypted." return 0 } return 1 @@ -397,7 +391,7 @@ if ! check_resettable; then fi if ! check_crypt; then - echo "Warning: Encrypted device is in dump path. User will prompted for password during second kernel boot." + dwarn "Warning: Encrypted device is in dump path. User will prompted for password during second kernel boot." fi # firstly get right SSH_KEY_LOCATION @@ -407,14 +401,6 @@ if [ -f "$keyfile" ]; then SSH_KEY_LOCATION=$(/usr/bin/readlink -m $keyfile) fi -if [ "$(uname -m)" = "s390x" ]; then - add_dracut_module "znet" -fi - -if is_wdt_addition_needed; then - add_dracut_arg "-a" "watchdog" -fi - while read config_opt config_val; do # remove inline comments after the end of a directive. @@ -443,7 +429,6 @@ do then mkdir_save_path_ssh $config_val check_size ssh $config_val - add_dracut_module "ssh-client" add_dracut_sshkey "$SSH_KEY_LOCATION" else perror_exit "Bad ssh dump target $config_val" diff --git a/SOURCES/mkdumprd.8 b/SOURCES/mkdumprd.8 index 7faae57..2ac3d5a 100644 --- a/SOURCES/mkdumprd.8 +++ b/SOURCES/mkdumprd.8 @@ -15,7 +15,13 @@ be loaded in the initramfs (based on configuration retrieved from \fI/etc/kdump.conf)\fR \fBmkdumprd\fR add a new \fBdracut\fR module 99kdumpbase and use \fBdracut\fR -utility to generate the initramfs. +utility to generate the initramfs. When generating a kdump initramfs, \fBmkdumprd\fR +will determine how much disk space is available, if the dump target's available +space is not greater than the total system memory, \fBmkdumprd\fR will print a +warning to remind that there might not be enough space to save a vmcore. The +warning covers extreme scenarios such as the slab explodes with non-zero data or +a full vmcore, etc. Therefore, need to prevent users from having minimum disk +space for crash dump. \fBmkdumprd\fR was not intended for casual use outside of the service initialization script for the kdump utility, and should not be run manually. If diff --git a/SOURCES/rhelonly-kexec-tools-2.0.20-makedumpfile-arm64-Add-support-for-ARMv8.2-LVA-52-bi.patch b/SOURCES/rhelonly-kexec-tools-2.0.20-makedumpfile-arm64-Add-support-for-ARMv8.2-LVA-52-bi.patch new file mode 100644 index 0000000..85b5496 --- /dev/null +++ b/SOURCES/rhelonly-kexec-tools-2.0.20-makedumpfile-arm64-Add-support-for-ARMv8.2-LVA-52-bi.patch @@ -0,0 +1,85 @@ +From 16028a119c85ed73944bcf6ca310a7ee4d2e64fe Mon Sep 17 00:00:00 2001 +From: Pingfan Liu +Date: Mon, 21 Dec 2020 13:35:38 +0800 +Subject: [PATCH] RHEL-only + +--- + arch/arm64.c | 14 +++++++++++++- + makedumpfile.c | 2 ++ + makedumpfile.h | 1 + + 3 files changed, 16 insertions(+), 1 deletion(-) + +diff --git a/makedumpfile-1.6.8/arch/arm64.c b/makedumpfile-1.6.8/arch/arm64.c +index 3d7b416..c8e7f62 100644 +--- a/makedumpfile-1.6.8/arch/arm64.c ++++ b/makedumpfile-1.6.8/arch/arm64.c +@@ -48,6 +48,7 @@ static int lpa_52_bit_support_available; + static int pgtable_level; + static int va_bits; + static unsigned long kimage_voffset; ++static int max_user_va_bits; + + #define SZ_4K 4096 + #define SZ_16K 16384 +@@ -107,7 +108,7 @@ typedef unsigned long pgdval_t; + #define PGDIR_SHIFT ARM64_HW_PGTABLE_LEVEL_SHIFT(4 - (pgtable_level)) + #define PGDIR_SIZE (_AC(1, UL) << PGDIR_SHIFT) + #define PGDIR_MASK (~(PGDIR_SIZE-1)) +-#define PTRS_PER_PGD (1 << ((va_bits) - PGDIR_SHIFT)) ++#define PTRS_PER_PGD (1 << ((max_user_va_bits) - PGDIR_SHIFT)) + + /* + * Section address mask and size definitions. +@@ -366,6 +367,17 @@ get_machdep_info_arm64(void) + ERRMSG("Can't determine platform config values\n"); + return FALSE; + } ++ if (NUMBER(MAX_USER_VA_BITS) != NOT_FOUND_NUMBER) { ++ max_user_va_bits = NUMBER(MAX_USER_VA_BITS); ++ DEBUG_MSG("max_user_va_bits : %d (vmcoreinfo)\n", ++ max_user_va_bits); ++ } ++ if (!max_user_va_bits) { ++ max_user_va_bits = va_bits; ++ DEBUG_MSG("max_user_va_bits : %d (default = va_bits)\n", ++ max_user_va_bits); ++ } ++ + + kimage_voffset = NUMBER(kimage_voffset); + info->section_size_bits = SECTIONS_SIZE_BITS; +diff --git a/makedumpfile-1.6.8/makedumpfile.c b/makedumpfile-1.6.8/makedumpfile.c +index cdde040..9fd3ae9 100644 +--- a/makedumpfile-1.6.8/makedumpfile.c ++++ b/makedumpfile-1.6.8/makedumpfile.c +@@ -2322,6 +2322,7 @@ write_vmcoreinfo_data(void) + + WRITE_NUMBER("HUGETLB_PAGE_DTOR", HUGETLB_PAGE_DTOR); + #ifdef __aarch64__ ++ WRITE_NUMBER("MAX_USER_VA_BITS", MAX_USER_VA_BITS); + WRITE_NUMBER("VA_BITS", VA_BITS); + WRITE_NUMBER_UNSIGNED("PHYS_OFFSET", PHYS_OFFSET); + WRITE_NUMBER_UNSIGNED("kimage_voffset", kimage_voffset); +@@ -2728,6 +2729,7 @@ read_vmcoreinfo(void) + READ_NUMBER("phys_base", phys_base); + READ_NUMBER("KERNEL_IMAGE_SIZE", KERNEL_IMAGE_SIZE); + #ifdef __aarch64__ ++ READ_NUMBER("MAX_USER_VA_BITS", MAX_USER_VA_BITS); + READ_NUMBER("VA_BITS", VA_BITS); + READ_NUMBER_UNSIGNED("PHYS_OFFSET", PHYS_OFFSET); + READ_NUMBER_UNSIGNED("kimage_voffset", kimage_voffset); +diff --git a/makedumpfile-1.6.8/makedumpfile.h b/makedumpfile-1.6.8/makedumpfile.h +index 698c054..2763a47 100644 +--- a/makedumpfile-1.6.8/makedumpfile.h ++++ b/makedumpfile-1.6.8/makedumpfile.h +@@ -1937,6 +1937,7 @@ struct number_table { + long phys_base; + long KERNEL_IMAGE_SIZE; + #ifdef __aarch64__ ++ long MAX_USER_VA_BITS; + long VA_BITS; + unsigned long PHYS_OFFSET; + unsigned long kimage_voffset; +-- +2.21.0 + diff --git a/SOURCES/rhonly-kexec-tools-2.0.18-makedumpfile-arm64-Add-support-for-ARMv8.2-LVA-52-bi.patch b/SOURCES/rhonly-kexec-tools-2.0.18-makedumpfile-arm64-Add-support-for-ARMv8.2-LVA-52-bi.patch deleted file mode 100644 index 71bdca4..0000000 --- a/SOURCES/rhonly-kexec-tools-2.0.18-makedumpfile-arm64-Add-support-for-ARMv8.2-LVA-52-bi.patch +++ /dev/null @@ -1,235 +0,0 @@ -From: Bhupesh Sharma -Date: Wed, 6 Feb 2019 12:31:29 +0530 -Subject: [PATCH] makedumpfile/arm64: Add support for ARMv8.2-LVA (52-bit - user-space VA support) - -With ARMv8.2-LVA architecture extension availability, arm64 hardware -which supports this extension can support upto 52-bit virtual -addresses. It is specially useful for having a 52-bit user-space virtual -address space while the kernel can still retain 48-bit virtual -addresses. - -Since at the moment we enable the support of this extension in the -kernel via a CONFIG flag (CONFIG_ARM64_USER_VA_BITS_52), so there are -no clear mechanisms in user-space to determine this CONFIG -flag value and use it to determine the user-space VA address range -values. - -'makedumpfile' can instead use 'MAX_USER_VA_BITS' value to -determine the maximum virtual physical address supported by user-space. -If 'MAX_USER_VA_BITS' value is greater than 'VA_BITS' than we are -running a use-case where user-space is 52-bit and underlying kernel is -still 48-bit. The increased 'PTRS_PER_PGD' value for such cases can then -be calculated as is done by the underlying kernel (see kernel file -'arch/arm64/include/asm/pgtable-hwdef.h' for details): - - #define PTRS_PER_PGD (1 << (MAX_USER_VA_BITS - PGDIR_SHIFT)) - -I have sent a kernel patch upstream to add 'MAX_USER_VA_BITS' to -vmcoreinfo for arm64 (see [0]). - -This patch is in accordance with ARMv8 Architecture Reference Manual -version D.a - -[0]. -http://lists.infradead.org/pipermail/kexec/2019-February/022411.html - -Signed-off-by: Bhupesh Sharma - ---- - arch/arm64.c | 109 ++++++++++++++++++++++++++++++++++++++++++--------------- - makedumpfile.c | 2 ++ - makedumpfile.h | 1 + - 3 files changed, 83 insertions(+), 29 deletions(-) - -diff --git a/makedumpfile-1.6.7/arch/arm64.c b/makedumpfile-1.6.7/arch/arm64.c -index 0535193..5fcf59d 100644 ---- a/makedumpfile-1.6.7/arch/arm64.c -+++ b/makedumpfile-1.6.7/arch/arm64.c -@@ -41,6 +41,7 @@ typedef struct { - - static int pgtable_level; - static int va_bits; -+static int max_user_va_bits; - static unsigned long kimage_voffset; - - #define SZ_4K (4 * 1024) -@@ -61,7 +62,7 @@ static unsigned long kimage_voffset; - - #define PAGE_MASK (~(PAGESIZE() - 1)) - #define PGDIR_SHIFT ((PAGESHIFT() - 3) * pgtable_level + 3) --#define PTRS_PER_PGD (1 << (va_bits - PGDIR_SHIFT)) -+#define PTRS_PER_PGD (1 << ((max_user_va_bits) - PGDIR_SHIFT)) - #define PUD_SHIFT get_pud_shift_arm64() - #define PUD_SIZE (1UL << PUD_SHIFT) - #define PUD_MASK (~(PUD_SIZE - 1)) -@@ -73,6 +74,10 @@ static unsigned long kimage_voffset; - #define PTRS_PER_PMD PTRS_PER_PTE - - #define PAGE_PRESENT (1 << 0) -+ -+/* -+ * Section address mask and size definitions. -+ */ - #define SECTIONS_SIZE_BITS 30 - /* Highest possible physical address supported */ - #define PHYS_MASK_SHIFT 48 -@@ -284,14 +289,83 @@ get_stext_symbol(void) - return(found ? kallsym : FALSE); - } - -+static int -+get_va_bits_from_stext_arm64(void) -+{ -+ ulong _stext; -+ -+ _stext = get_stext_symbol(); -+ if (!_stext) { -+ ERRMSG("Can't get the symbol of _stext.\n"); -+ return FALSE; -+ } -+ -+ /* Derive va_bits as per arch/arm64/Kconfig */ -+ if ((_stext & PAGE_OFFSET_36) == PAGE_OFFSET_36) { -+ va_bits = 36; -+ } else if ((_stext & PAGE_OFFSET_39) == PAGE_OFFSET_39) { -+ va_bits = 39; -+ } else if ((_stext & PAGE_OFFSET_42) == PAGE_OFFSET_42) { -+ va_bits = 42; -+ } else if ((_stext & PAGE_OFFSET_47) == PAGE_OFFSET_47) { -+ va_bits = 47; -+ } else if ((_stext & PAGE_OFFSET_48) == PAGE_OFFSET_48) { -+ va_bits = 48; -+ } else { -+ ERRMSG("Cannot find a proper _stext for calculating VA_BITS\n"); -+ return FALSE; -+ } -+ -+ DEBUG_MSG("va_bits : %d\n", va_bits); -+ -+ return TRUE; -+} -+ -+static void -+get_page_offset_arm64(void) -+{ -+ info->page_offset = (0xffffffffffffffffUL) << (va_bits - 1); -+ -+ DEBUG_MSG("page_offset : %lx\n", info->page_offset); -+} -+ - int - get_machdep_info_arm64(void) - { - /* Check if va_bits is still not initialized. If still 0, call - * get_versiondep_info() to initialize the same. - */ -+ if (NUMBER(VA_BITS) != NOT_FOUND_NUMBER) { -+ va_bits = NUMBER(VA_BITS); -+ DEBUG_MSG("va_bits : %d (vmcoreinfo)\n", -+ va_bits); -+ } -+ -+ /* Check if va_bits is still not initialized. If still 0, call -+ * get_versiondep_info() to initialize the same from _stext -+ * symbol. -+ */ - if (!va_bits) -- get_versiondep_info_arm64(); -+ if (get_va_bits_from_stext_arm64() == ERROR) -+ return ERROR; -+ -+ get_page_offset_arm64(); -+ -+ if (NUMBER(MAX_USER_VA_BITS) != NOT_FOUND_NUMBER) { -+ max_user_va_bits = NUMBER(MAX_USER_VA_BITS); -+ DEBUG_MSG("max_user_va_bits : %d (vmcoreinfo)\n", -+ max_user_va_bits); -+ } -+ -+ /* Check if max_user_va_bits is still not initialized. -+ * If still 0, its not available in vmcoreinfo and its -+ * safe to initialize it with va_bits. -+ */ -+ if (!max_user_va_bits) { -+ max_user_va_bits = va_bits; -+ DEBUG_MSG("max_user_va_bits : %d (default = va_bits)\n", -+ max_user_va_bits); -+ } - - if (!calculate_plat_config()) { - ERRMSG("Can't determine platform config values\n"); -@@ -330,34 +404,11 @@ get_xen_info_arm64(void) - int - get_versiondep_info_arm64(void) - { -- ulong _stext; -- -- _stext = get_stext_symbol(); -- if (!_stext) { -- ERRMSG("Can't get the symbol of _stext.\n"); -- return FALSE; -- } -- -- /* Derive va_bits as per arch/arm64/Kconfig */ -- if ((_stext & PAGE_OFFSET_36) == PAGE_OFFSET_36) { -- va_bits = 36; -- } else if ((_stext & PAGE_OFFSET_39) == PAGE_OFFSET_39) { -- va_bits = 39; -- } else if ((_stext & PAGE_OFFSET_42) == PAGE_OFFSET_42) { -- va_bits = 42; -- } else if ((_stext & PAGE_OFFSET_47) == PAGE_OFFSET_47) { -- va_bits = 47; -- } else if ((_stext & PAGE_OFFSET_48) == PAGE_OFFSET_48) { -- va_bits = 48; -- } else { -- ERRMSG("Cannot find a proper _stext for calculating VA_BITS\n"); -- return FALSE; -- } -- -- info->page_offset = (0xffffffffffffffffUL) << (va_bits - 1); -+ if (!va_bits) -+ if (get_va_bits_from_stext_arm64() == ERROR) -+ return ERROR; - -- DEBUG_MSG("va_bits : %d\n", va_bits); -- DEBUG_MSG("page_offset : %lx\n", info->page_offset); -+ get_page_offset_arm64(); - - return TRUE; - } -diff --git a/makedumpfile-1.6.7/makedumpfile.c b/makedumpfile-1.6.7/makedumpfile.c -index d76a435..c8906b5 100644 ---- a/makedumpfile-1.6.7/makedumpfile.c -+++ b/makedumpfile-1.6.7/makedumpfile.c -@@ -2313,6 +2313,7 @@ write_vmcoreinfo_data(void) - - WRITE_NUMBER("HUGETLB_PAGE_DTOR", HUGETLB_PAGE_DTOR); - #ifdef __aarch64__ -+ WRITE_NUMBER("MAX_USER_VA_BITS", MAX_USER_VA_BITS); - WRITE_NUMBER("VA_BITS", VA_BITS); - WRITE_NUMBER_UNSIGNED("PHYS_OFFSET", PHYS_OFFSET); - WRITE_NUMBER_UNSIGNED("kimage_voffset", kimage_voffset); -@@ -2719,6 +2720,7 @@ read_vmcoreinfo(void) - READ_NUMBER("phys_base", phys_base); - READ_NUMBER("KERNEL_IMAGE_SIZE", KERNEL_IMAGE_SIZE); - #ifdef __aarch64__ -+ READ_NUMBER("MAX_USER_VA_BITS", MAX_USER_VA_BITS); - READ_NUMBER("VA_BITS", VA_BITS); - READ_NUMBER_UNSIGNED("PHYS_OFFSET", PHYS_OFFSET); - READ_NUMBER_UNSIGNED("kimage_voffset", kimage_voffset); -diff --git a/makedumpfile-1.6.7/makedumpfile.h b/makedumpfile-1.6.7/makedumpfile.h -index 24b2f69..cccb52a 100644 ---- a/makedumpfile-1.6.7/makedumpfile.h -+++ b/makedumpfile-1.6.7/makedumpfile.h -@@ -1937,6 +1937,7 @@ struct number_table { - long phys_base; - long KERNEL_IMAGE_SIZE; - #ifdef __aarch64__ -+ long MAX_USER_VA_BITS; - long VA_BITS; - unsigned long PHYS_OFFSET; - unsigned long kimage_voffset; --- -2.7.5 - diff --git a/SPECS/kexec-tools.spec b/SPECS/kexec-tools.spec index 2d4ff93..a01500e 100644 --- a/SPECS/kexec-tools.spec +++ b/SPECS/kexec-tools.spec @@ -1,6 +1,6 @@ Name: kexec-tools Version: 2.0.20 -Release: 34%{?dist}.2 +Release: 46%{?dist} License: GPLv2 Group: Applications/System Summary: The kexec/kdump userspace component @@ -13,7 +13,7 @@ Source4: kdump.sysconfig.i386 Source5: kdump.sysconfig.ppc64 Source7: mkdumprd Source8: kdump.conf -Source9: http://downloads.sourceforge.net/project/makedumpfile/makedumpfile/1.6.7/makedumpfile-1.6.7.tar.gz +Source9: https://github.com/makedumpfile/makedumpfile/archive/1.6.8.tar.gz Source10: kexec-kdump-howto.txt Source12: mkdumprd.8 Source13: 98-kexec.rules @@ -34,6 +34,8 @@ Source28: supported-kdump-targets.txt Source29: kdump-udev-throttler Source30: kdump.sysconfig.aarch64 Source31: fadump-howto.txt +Source32: 60-kdump.install +Source33: kdump-logger.sh ####################################### # These are sources for mkdumpramfs @@ -54,7 +56,7 @@ Requires(post): systemd-units Requires(preun): systemd-units Requires(postun): systemd-units Requires(pre): coreutils sed zlib -Requires: dracut >= 049-24 +Requires: dracut >= 049-129 Requires: dracut-network >= 049 Requires: dracut-squash >= 049 Requires: ethtool @@ -94,7 +96,7 @@ ExcludeArch: i686 # Patch601: rhelonly-kexec-tools-2.0.16-koji-build-fail-workaround.patch Patch602: rhelonly-kexec-tools-2.0.18-eppic-fix-issues-with-hardening-flags.patch -Patch603: rhonly-kexec-tools-2.0.18-makedumpfile-arm64-Add-support-for-ARMv8.2-LVA-52-bi.patch +#Patch603: rhonly-kexec-tools-2.0.18-makedumpfile-arm64-Add-support-for-ARMv8.2-LVA-52-bi.patch Patch604: kexec-tools-2.0.20-Cleanup-remove-the-read_elf_kcore.patch Patch605: kexec-tools-2.0.20-Fix-an-error-definition-about-the-variable-fname.patch Patch606: kexec-tools-2.0.20-Cleanup-move-it-back-from-util_lib-elf_info.c.patch @@ -103,16 +105,12 @@ Patch608: kexec-tools-2.0.20-vmcore-dmesg-vmcore-dmesg.c-Fix-shifting-error-repo Patch609: kexec-tools-2.0.20-kexec-add-variant-helper-functions-for-handling-memo.patch Patch610: kexec-tools-2.0.20-arm64-kexec-allocate-memory-space-avoiding-reserved-.patch Patch611: kexec-tools-2.0.20-arm64-kdump-deal-with-a-lot-of-resource-entries-in-p.patch +Patch612: kexec-tools-2.0.20-Remove-duplicated-variable-declarations.patch +Patch613: kexec-tools-2.0.20-eppic-Remove-duplicated-variable-declaration.patch + # Patches 701 onward for makedumpfile -Patch701: kexec-tools-2.0.20-makedumpfile-PATCH-Remove-duplicated-variable-definitions.patch -Patch702: kexec-tools-2.0.20-makedumpfile-PATCH-cope-with-not-present-mem-section.patch -Patch703: kexec-tools-2.0.20-makedumpfile-PATCH-Introduce-check-params-option.patch -Patch704: kexec-tools-2.0.20-makedumpfile-PATCH-Makefile-Fix-build-errors-in-static-build.patch -Patch705: kexec-tools-2.0.20-makedumpfile-PATCH-Align-PMD_SECTION_MASK-with-PHYS_MASK.patch -Patch706: kexec-tools-2.0.20-makedumpfile-PATCH-Fix-cd_header-offset-overflow-with-large-pfn.patch -Patch707: kexec-tools-2.0.20-makedumpfile-PATCH-Avoid-false-positive-failure-in-mem_seciton-va.patch -Patch708: kexec-tools-2.0.20-makedumpfile-PATCH-sadump-kaslr-fix-failure-of-calculating-kaslr.patch +Patch701: rhelonly-kexec-tools-2.0.20-makedumpfile-arm64-Add-support-for-ARMv8.2-LVA-52-bi.patch %description @@ -131,7 +129,7 @@ tar -z -x -v -f %{SOURCE19} %patch601 -p1 %patch602 -p1 -%patch603 -p1 +#%patch603 -p1 %patch604 -p1 %patch605 -p1 %patch606 -p1 @@ -140,14 +138,9 @@ tar -z -x -v -f %{SOURCE19} %patch609 -p1 %patch610 -p1 %patch611 -p1 +%patch612 -p1 +%patch613 -p1 %patch701 -p1 -%patch702 -p1 -%patch703 -p1 -%patch704 -p1 -%patch705 -p1 -%patch706 -p1 -%patch707 -p1 -%patch708 -p1 %ifarch ppc %define archdef ARCH=ppc @@ -177,8 +170,8 @@ cp %{SOURCE31} . make %ifarch %{ix86} x86_64 ppc64 s390x ppc64le aarch64 make -C eppic/libeppic -make -C makedumpfile-1.6.7 LINKTYPE=dynamic USELZO=on USESNAPPY=on -make -C makedumpfile-1.6.7 LDFLAGS="$LDFLAGS -I../eppic/libeppic -L../eppic/libeppic" eppic_makedumpfile.so +make -C makedumpfile-1.6.8 LINKTYPE=dynamic USELZO=on USESNAPPY=on +make -C makedumpfile-1.6.8 LDFLAGS="$LDFLAGS -I../eppic/libeppic -L../eppic/libeppic" eppic_makedumpfile.so %endif %install @@ -216,6 +209,7 @@ install -m 644 %{SOURCE12} $RPM_BUILD_ROOT%{_mandir}/man8/mkdumprd.8 install -m 644 %{SOURCE25} $RPM_BUILD_ROOT%{_mandir}/man8/kdumpctl.8 install -m 755 %{SOURCE20} $RPM_BUILD_ROOT%{_prefix}/lib/kdump/kdump-lib.sh install -m 755 %{SOURCE23} $RPM_BUILD_ROOT%{_prefix}/lib/kdump/kdump-lib-initramfs.sh +install -m 755 %{SOURCE33} $RPM_BUILD_ROOT%{_prefix}/lib/kdump/kdump-logger.sh %ifnarch s390x ppc64 ppc64le # For s390x the ELF header is created in the kdump kernel and therefore kexec # udev rules are not required @@ -230,15 +224,17 @@ install -m 755 %{SOURCE29} $RPM_BUILD_ROOT%{_udevrulesdir}/../kdump-udev-throttl install -m 644 %{SOURCE15} $RPM_BUILD_ROOT%{_mandir}/man5/kdump.conf.5 install -m 644 %{SOURCE16} $RPM_BUILD_ROOT%{_unitdir}/kdump.service install -m 755 -D %{SOURCE22} $RPM_BUILD_ROOT%{_prefix}/lib/systemd/system-generators/kdump-dep-generator.sh +install -m 755 -D %{SOURCE32} $RPM_BUILD_ROOT%{_prefix}/lib/kernel/install.d/60-kdump.install + %ifarch %{ix86} x86_64 ppc64 s390x ppc64le aarch64 -install -m 755 makedumpfile-1.6.7/makedumpfile $RPM_BUILD_ROOT/usr/sbin/makedumpfile -install -m 644 makedumpfile-1.6.7/makedumpfile.8.gz $RPM_BUILD_ROOT/%{_mandir}/man8/makedumpfile.8.gz -install -m 644 makedumpfile-1.6.7/makedumpfile.conf.5.gz $RPM_BUILD_ROOT/%{_mandir}/man5/makedumpfile.conf.5.gz -install -m 644 makedumpfile-1.6.7/makedumpfile.conf $RPM_BUILD_ROOT/%{_sysconfdir}/makedumpfile.conf.sample -install -m 755 makedumpfile-1.6.7/eppic_makedumpfile.so $RPM_BUILD_ROOT/%{_libdir}/eppic_makedumpfile.so +install -m 755 makedumpfile-1.6.8/makedumpfile $RPM_BUILD_ROOT/usr/sbin/makedumpfile +install -m 644 makedumpfile-1.6.8/makedumpfile.8.gz $RPM_BUILD_ROOT/%{_mandir}/man8/makedumpfile.8.gz +install -m 644 makedumpfile-1.6.8/makedumpfile.conf.5.gz $RPM_BUILD_ROOT/%{_mandir}/man5/makedumpfile.conf.5.gz +install -m 644 makedumpfile-1.6.8/makedumpfile.conf $RPM_BUILD_ROOT/%{_sysconfdir}/makedumpfile.conf.sample +install -m 755 makedumpfile-1.6.8/eppic_makedumpfile.so $RPM_BUILD_ROOT/%{_libdir}/eppic_makedumpfile.so mkdir -p $RPM_BUILD_ROOT/usr/share/makedumpfile/eppic_scripts/ -install -m 644 makedumpfile-1.6.7/eppic_scripts/* $RPM_BUILD_ROOT/usr/share/makedumpfile/eppic_scripts/ +install -m 644 makedumpfile-1.6.8/eppic_scripts/* $RPM_BUILD_ROOT/usr/share/makedumpfile/eppic_scripts/ %endif %define remove_dracut_prefix() %(echo -n %1|sed 's/.*dracut-//g') @@ -366,6 +362,7 @@ done %{_mandir}/man5/* %{_unitdir}/kdump.service %{_prefix}/lib/systemd/system-generators/kdump-dep-generator.sh +%{_prefix}/lib/kernel/install.d/60-kdump.install %doc News %license COPYING %doc TODO @@ -381,15 +378,99 @@ done %endif %changelog -* Mon Jan 11 2021 Pingfan Liu - 2.0.20-34.2 +* Thu Feb 25 2021 Pingfan Liu - 2.0.20-46 +- kdumpctl: enable secure boot on ppc64le LPARs + +* Mon Jan 25 2021 Pingfan Liu - 2.0.20-45 +- origin/rhel-8.4.0) Revert "Revert "Append both nofail and x-systemd.before to kdump mount target"" +- kdump.conf: add ipv6 example for nfs and ssh dump +- fix kdump failure of saving vmcore with the scp + ipv6 method + +* Fri Jan 22 2021 Pingfan Liu - 2.0.20-44 +- module-setup.sh: don't polute the namespace unnecessarily +- module-setup.sh: don't source $dracutfunctions +- logger: source the logger file individually +- dracut-module-setup.sh: enable ForwardToConsole=yes in fadump mode + +* Fri Jan 15 2021 Pingfan Liu - 2.0.20-43 +- Always include watchdog-modules +- mkdumprd: Ensure kdumpbase is added +- Move watchdog detect and install code to module-setup.sh +- Add a helper to omit non-mandatory dracut module +- Move some dracut module dependencies checks to module-setup.sh +- Set watchdog's pretimeout to zero in kdump kernel +- kdump-lib.sh: Use a more generic helper to detect omitted dracut module +- Fix the watchdog drivers detection code +- Add a helper for detecting watchdog drivers +- Remove a redundant nfs check +- kdumpctl: split the driver detection from fs dection function +- kdump.service: use ConditionKernelCommandLine=crashkernel +- Revert "Append both nofail and x-systemd.before to kdump mount target" +- Revert "Don's try to restart dracut-initqueue if it's already failed" +- Fix dump_fs mount point detection and fallback mount +- kdump.conf: Update doc about core_collector for ssh target +- Save the final failure information to log file if saving vmcore failed +- Doc: Improve the kdump sysconfig document +- kdumpctl: fix a variable expansion in check_fence_kdump_config() +- Fedora 33 rhpkg build bug + +* Tue Dec 22 2020 Pingfan Liu - 2.0.20-42 +- makedumpfile: add support for ARMv8.2 LVA 52 bits + +* Fri Dec 18 2020 Pingfan Liu - 2.0.20-41 +- Doc: improve mkdumprd man page + +* Tue Dec 15 2020 Pingfan Liu - 2.0.20-40 +- Rework on dracut-module-setup.sh: Use systemctl call to replace ln_r + +* Tue Dec 15 2020 Pingfan Liu - 2.0.20-39 +- dracut-module-setup.sh: Use systemctl call to replace ln_r + +* Fri Dec 11 2020 Pingfan Liu - 2.0.20-38 +- Don's try to restart dracut-initqueue if it's already failed +- fadump-howto: update about 'nocma' and 'off' options for 'fadump=' parameter +- dracut-module-setup.sh: use auto6 for ipv6 +- module-setup.sh: enable vlan on team interface +- Fix rootfs detection in dump_fs +- Remove RHEL-only patch: kexec-tools-2.0.18-makedumpfile-arm64-Add-support-for-ARMv8.2-LVA-52-bi.patch +- Rebase to makedumpfile-1.6.8 (step1) + +* Fri Nov 13 2020 Pingfan Liu - 2.0.20-37 +- Doc: improve the usage documentation of the logger +- Update the kdump sysconfig +- Capitalize the configuration name of log level +- Add the rd.kdumploglvl option to control log level in the second kernel +- Appropriately converts logger numeric level to syslog log level +- Remove unused log levels for kdump logger +- Add sanity checks for the log levels +- Add code comments to help better understanding +- Doc: add a documentation for the usage of logger +- Improve debugging in the kdump kernel +- kdumpctl: add the '-d' option to enable the kexec loading debugging messages +- kdump.sysconfig: add the kdump logger configurations +- enable the logger for kdump +- introduce the kdump logger from the dracut + +* Fri Nov 6 2020 Pingfan Liu - 2.0.20-36 +- arm64: Enable 'kexec_file_load' by default +- Fix, Add a kernel install hook to clean up kdump initramfs + +* Fri Oct 30 2020 Pingfan Liu - 2.0.20-35 +- module-setup.sh: Instead of drop journalctl log, just don't read kmsg +- s390x: enable the kexec file load by default +- increase makdumpfile default message level to 7 +- Rework check_config and warn on any duplicated option +- kdumpctl: Error out if path is set more than once. +- Don't drop journalctl content if failure action is "shell" +- dracut-module-install: Move systemd conf install code to a function - kdump-lib.sh: Remove is_atomic - Refactor kernel image and initrd detection code - early-kdump: Use consistent symbol link for kernel and initramfs - kdump-lib: strip grub device from kdump_bootdir - kdumpctl: fix driver change detection on latest Fedora - -* Wed Oct 28 2020 Pingfan Liu - 2.0.20-34.1 +- Revert "kdump-lib: disable efifb if hyperv_fb is in use" - kdump-lib.sh: detect secure boot on s390 +- Add a kernel install hook to clean up kdump initramfs * Wed Aug 19 2020 Pingfan Liu - 2.0.20-34 - kdump-lib: disable efifb if hyperv_fb is in use