diff --git a/dracut-kdump.sh b/dracut-kdump.sh index 80acc93..2505fc6 100755 --- a/dracut-kdump.sh +++ b/dracut-kdump.sh @@ -306,11 +306,22 @@ do_final_action() do_dump() { - eval $DUMP_INSTRUCTION + if [ -d /vmcorestatus ]; then + _vmcore_creation_status="/vmcorestatus/$VMCORE_CREATION_STATUS" + else + _vmcore_creation_status="/sysroot/$VMCORE_CREATION_STATUS" + fi + + set_vmcore_creation_status 'clear' "$_vmcore_creation_status" + + eval "$DUMP_INSTRUCTION" _ret=$? if [ $_ret -ne 0 ]; then + set_vmcore_creation_status 'fail' "$_vmcore_creation_status" derror "saving vmcore failed" + else + set_vmcore_creation_status 'success' "$_vmcore_creation_status" fi return $_ret diff --git a/dracut-module-setup.sh b/dracut-module-setup.sh index 8b67c86..7565651 100755 --- a/dracut-module-setup.sh +++ b/dracut-module-setup.sh @@ -1144,6 +1144,7 @@ install() { inst "/usr/bin/printf" "/sbin/printf" inst "/usr/bin/logger" "/sbin/logger" inst "/usr/bin/chmod" "/sbin/chmod" + inst "/usr/bin/dirname" "/sbin/dirname" 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" diff --git a/kdump-lib-initramfs.sh b/kdump-lib-initramfs.sh index 6eaec93..b3e1aa7 100755 --- a/kdump-lib-initramfs.sh +++ b/kdump-lib-initramfs.sh @@ -8,6 +8,7 @@ KDUMP_CONFIG_FILE="/etc/kdump.conf" FENCE_KDUMP_CONFIG_FILE="/etc/sysconfig/fence_kdump" FENCE_KDUMP_SEND="/usr/libexec/fence_kdump_send" LVM_CONF="/etc/lvm/lvm.conf" +VMCORE_CREATION_STATUS="/var/crash/vmcore-creation.status" # Read kdump config in well formated style kdump_read_conf() @@ -101,15 +102,8 @@ get_fs_type_from_target() get_mntpoint_from_target() { - local SOURCE TARGET - findmnt -k --pairs -o SOURCE,TARGET "$1" | while read line; do - eval "$line" - # omit sources that are bind mounts i.e. they contain a [/path/to/subpath]. - if [[ ! "$SOURCE" =~ \[ ]]; then - echo $TARGET - break - fi - done + # --source is applied to ensure non-bind mount is returned + get_mount_info TARGET source "$1" -f } is_ssh_dump_target() @@ -182,3 +176,35 @@ kdump_get_ip_route_field() { echo "$1" | sed -n -e "s/^.*\<$2\>\s\+\(\S\+\).*$/\1/p" } + +# $1: success/fail/clear +# $2: status_file +set_vmcore_creation_status() +{ + _status=$1 + _status_file=$2 + _dir=$(dirname "$_status_file") + + [[ -d "$_dir" ]] || mkdir -p "$_dir" + + _mnt_op=$(get_mount_info OPTIONS target "$_dir" -f) + case $_mnt_op in + ro*) + dinfo "remounting the vmcore status target in rw mode." + mount -o remount,rw "$(findmnt -n -o TARGET --target $_dir)" + ;; + esac + + case "$_status" in + success | fail) + dinfo "saving vmcore status file to $_status_file" + echo "$_status $(date +%s)" > "$_status_file" + ;; + clear) + rm -f "$_status_file" + ;; + *) + return + esac + sync -f "$_dir" +} diff --git a/kdump-lib.sh b/kdump-lib.sh index 28ee6c0..0ccabc0 100755 --- a/kdump-lib.sh +++ b/kdump-lib.sh @@ -213,7 +213,7 @@ get_bind_mount_source() _fsroot=${_src#${_src_nofsroot}[} _fsroot=${_fsroot%]} - _mnt=$(get_mntpoint_from_target "$_src_nofsroot") + _mnt=$(get_mount_info TARGET source "$_src_nofsroot" -f) # for btrfs, _fsroot will also contain the subvol value as well, strip it if [[ $_fstype == btrfs ]]; then diff --git a/kdump.sysconfig b/kdump.sysconfig index a185e41..1b720a9 100644 --- a/kdump.sysconfig +++ b/kdump.sysconfig @@ -36,6 +36,10 @@ KEXEC_ARGS="" #What is the image type used for kdump KDUMP_IMG="vmlinuz" +# Enable vmcore creation notification by default, disable by setting +# VMCORE_CREATION_NOTIFICATION="" +VMCORE_CREATION_NOTIFICATION="yes" + # 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) diff --git a/kdump.sysconfig.aarch64 b/kdump.sysconfig.aarch64 index df75f94..0c3bc7c 100644 --- a/kdump.sysconfig.aarch64 +++ b/kdump.sysconfig.aarch64 @@ -36,6 +36,10 @@ KEXEC_ARGS="-s" #What is the image type used for kdump KDUMP_IMG="vmlinuz" +# Enable vmcore creation notification by default, disable by setting +# VMCORE_CREATION_NOTIFICATION="" +VMCORE_CREATION_NOTIFICATION="yes" + # 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) diff --git a/kdump.sysconfig.i386 b/kdump.sysconfig.i386 index d8bf5f6..70860ea 100644 --- a/kdump.sysconfig.i386 +++ b/kdump.sysconfig.i386 @@ -39,6 +39,10 @@ KDUMP_IMG="vmlinuz" #What is the images extension. Relocatable kernels don't have one KDUMP_IMG_EXT="" +# Enable vmcore creation notification by default, disable by setting +# VMCORE_CREATION_NOTIFICATION="" +VMCORE_CREATION_NOTIFICATION="yes" + # 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) diff --git a/kdump.sysconfig.ppc64 b/kdump.sysconfig.ppc64 index b7c4e79..445ab1f 100644 --- a/kdump.sysconfig.ppc64 +++ b/kdump.sysconfig.ppc64 @@ -39,6 +39,10 @@ KDUMP_IMG="vmlinuz" #What is the images extension. Relocatable kernels don't have one KDUMP_IMG_EXT="" +# Enable vmcore creation notification by default, disable by setting +# VMCORE_CREATION_NOTIFICATION="" +VMCORE_CREATION_NOTIFICATION="yes" + #Specify the action after failure # Logging is controlled by following variables in the first kernel: diff --git a/kdump.sysconfig.ppc64le b/kdump.sysconfig.ppc64le index c1cee45..d798451 100644 --- a/kdump.sysconfig.ppc64le +++ b/kdump.sysconfig.ppc64le @@ -39,6 +39,10 @@ KDUMP_IMG="vmlinuz" #What is the images extension. Relocatable kernels don't have one KDUMP_IMG_EXT="" +# Enable vmcore creation notification by default, disable by setting +# VMCORE_CREATION_NOTIFICATION="" +VMCORE_CREATION_NOTIFICATION="yes" + #Specify the action after failure # Logging is controlled by following variables in the first kernel: diff --git a/kdump.sysconfig.s390x b/kdump.sysconfig.s390x index b823093..a7a79a9 100644 --- a/kdump.sysconfig.s390x +++ b/kdump.sysconfig.s390x @@ -42,6 +42,10 @@ KDUMP_IMG="vmlinuz" #What is the images extension. Relocatable kernels don't have one KDUMP_IMG_EXT="" +# Enable vmcore creation notification by default, disable by setting +# VMCORE_CREATION_NOTIFICATION="" +VMCORE_CREATION_NOTIFICATION="yes" + # 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) diff --git a/kdump.sysconfig.x86_64 b/kdump.sysconfig.x86_64 index 09d7350..d3a5ce4 100644 --- a/kdump.sysconfig.x86_64 +++ b/kdump.sysconfig.x86_64 @@ -39,6 +39,10 @@ KDUMP_IMG="vmlinuz" #What is the images extension. Relocatable kernels don't have one KDUMP_IMG_EXT="" +# Enable vmcore creation notification by default, disable by setting +# VMCORE_CREATION_NOTIFICATION="" +VMCORE_CREATION_NOTIFICATION="yes" + # 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) diff --git a/kdumpctl b/kdumpctl index cb20708..edf9d1b 100755 --- a/kdumpctl +++ b/kdumpctl @@ -142,6 +142,7 @@ rebuild_kdump_initrd() rebuild_initrd() { + local _ret if [[ ! -w $(dirname "$TARGET_INITRD") ]]; then derror "$(dirname "$TARGET_INITRD") does not have write permission. Cannot rebuild $TARGET_INITRD" return 1 @@ -152,6 +153,10 @@ rebuild_initrd() else rebuild_kdump_initrd fi + _ret=$? + + set_vmcore_creation_status 'clear' "$VMCORE_CREATION_STATUS" + return $_ret } #$1: the files to be checked with IFS=' ' @@ -1055,6 +1060,8 @@ start() fi dinfo "Starting kdump: [OK]" + check_vmcore_creation_status + return 0 } reload() @@ -1756,6 +1763,62 @@ if [[ ! -f $KDUMP_CONFIG_FILE ]]; then exit 1 fi +check_vmcore_creation_status() +{ + local _status _timestamp _status_date + + [[ ${VMCORE_CREATION_NOTIFICATION,,} == "yes" ]] || return + + if [[ ! -s $VMCORE_CREATION_STATUS ]]; then + dwarn "Notice: No vmcore creation test performed!" + return + fi + + read -r _status _timestamp < "$VMCORE_CREATION_STATUS" + _status_date="$(date -d "@$_timestamp")" + if [[ "$_status" == "success" ]]; then + dinfo "Notice: Last successful vmcore creation on $_status_date" + else + dwarn "Notice: Last NOT successful vmcore creation on $_status_date" + fi +} + +kdump_test() +{ + local _dir + + if ! is_kernel_loaded "$DEFAULT_DUMP_MODE"; then + derror "Kdump needs be operational before test." + exit 1 + fi + + _dir=$(dirname "$VMCORE_CREATION_STATUS") + if ! [[ -d "$_dir" ]]; then + derror "Vmcore status dir $_dir not exist." + exit 1 + fi + + if ! lsblk $(get_mount_info SOURCE target "$_dir") > /dev/null; then + derror "$VMCORE_CREATION_STATUS must on local drive" + exit 1 + fi + + if [[ ! "$1" == "--force" ]]; then + read -p "DANGER!!! Will perform a kdump test by crashing the system, proceed? (y/N): " input + case $input in + [Yy] ) + dinfo "Start kdump test..." + ;; + * ) + dinfo "Operation cancelled." + exit 0 + ;; + esac + fi + set_vmcore_creation_status 'clear' "$VMCORE_CREATION_STATUS" + echo c > /proc/sysrq-trigger +} + main() { # Determine if the dump mode is kdump or fadump @@ -1786,6 +1849,7 @@ main() EXIT_CODE=3 ;; esac + check_vmcore_creation_status exit $EXIT_CODE ;; reload) @@ -1826,8 +1890,12 @@ main() reset_crashkernel_for_installed_kernel "$2" fi ;; + test) + shift + kdump_test "$@" + ;; *) - dinfo $"Usage: $0 {estimate|start|stop|status|restart|reload|rebuild|reset-crashkernel|propagate|showmem}" + dinfo $"Usage: $0 {estimate|start|stop|status|restart|reload|rebuild|reset-crashkernel|propagate|showmem|test}" exit 1 ;; esac diff --git a/kdumpctl.8 b/kdumpctl.8 index 29a6119..f6a7070 100644 --- a/kdumpctl.8 +++ b/kdumpctl.8 @@ -70,6 +70,16 @@ Note: The memory requirements for kdump varies heavily depending on the used hardware and system configuration. Thus the recommended crashkernel might not work for your specific setup. Please test if kdump works after resetting the crashkernel value. +.TP +.I test [--force] +Test the kdump by actually trigger the system crash & dump, and check if a +vmcore can really be generated successfully based on current config and +environment. After system reboot back to normal, check the test result +by "kdumpctl status". + +If the optional parameter [--force] is provided, there will be no interact +before triggering the system crash. Dangerous though, this option is meant +for automation testing. .SH "SEE ALSO" .BR kdump.conf (5), diff --git a/kexec-tools.spec b/kexec-tools.spec index 9985fa4..57d3bf4 100644 --- a/kexec-tools.spec +++ b/kexec-tools.spec @@ -5,7 +5,7 @@ Name: kexec-tools Version: 2.0.27 -Release: 15.1%{?dist} +Release: 18.1%{?dist} License: GPLv2 Summary: The kexec/kdump userspace component @@ -417,6 +417,18 @@ fi %endif %changelog +* Wed Oct 30 2024 Davide Cavalca - 2.0.27-18.1 +- Merge upstream changes for Hyperscale + +* Mon Oct 21 2024 Tao Liu - 2.0.27-18 +- Return the correct exit code of rebuild initrd + +* Tue Oct 8 2024 Tao Liu - 2.0.27-17 +- Introduce vmcore creation notification to kdump + +* Tue Sep 10 2024 Tao Liu - 2.0.27-16 +- Revert "lib: Ensure we don't find bind mounts for device target" + * Tue Sep 03 2024 Davide Cavalca - 2.0.27-15.1 - Merge upstream changes for Hyperscale diff --git a/mkdumprd b/mkdumprd index af0006d..0126d60 100644 --- a/mkdumprd +++ b/mkdumprd @@ -61,9 +61,10 @@ add_dracut_sshkey() # caller should ensure $1 is valid and mounted in 1st kernel to_mount() { - local _target=$1 _fstype=$2 _options=$3 _sed_cmd _new_mntpoint _pdev + local _target=$1 _fstype=$2 _options=$3 _new_mntpoint=$4 + local _sed_cmd _pdev - _new_mntpoint=$(get_kdump_mntpoint_from_target "$_target") + _new_mntpoint="${_new_mntpoint:-$(get_kdump_mntpoint_from_target "$_target")}" _fstype="${_fstype:-$(get_fs_type_from_target "$_target")}" _options="${_options:-$(get_mntopt_from_target "$_target")}" _options="${_options:-defaults}" @@ -474,6 +475,17 @@ if [[ -d /sys/module/nvme ]]; then add_dracut_arg "--add-drivers" "nvme" fi +status_target=$(get_target_from_path $(dirname "$VMCORE_CREATION_STATUS")) + +if [[ $(get_root_fs_device) != "$status_target" ]]; then + new_mntpoint=$(echo /vmcorestatus/$(get_mntpoint_from_target "$status_target") \ + | tr -s "/") + add_mount "$status_target" "" "" "$new_mntpoint" +elif ! is_fadump_capable && \ + ! [[ ${dracut_args[@]} == *"$(kdump_get_persistent_dev $status_target)"* ]]; then + add_mount "$status_target" +fi + dracut "${dracut_args[@]}" "$@" _rc=$?