Compare commits

...

No commits in common. "c8" and "c9s" have entirely different histories.
c8 ... c9s

87 changed files with 8544 additions and 5665 deletions

32
.editorconfig Normal file
View File

@ -0,0 +1,32 @@
# EditorConfig configuration for kexec-tools
# http://EditorConfig.org
# Top-most EditorConfig file
root = true
# Default code style for kexec-tools scripts
[*]
end_of_line = lf
shell_variant = posix
insert_final_newline = true
trim_trailing_whitespace = true
indent_style = tab
indent_size = 1
switch_case_indent = false
function_next_line = true
binary_next_line = false
space_redirects = true
# Some scripts will only run with bash
[{mkfadumprd,mkdumprd,kdumpctl,kdump-lib.sh}]
shell_variant = bash
# Use dracut code style for *-module-setup.sh
[*-module-setup.sh]
shell_variant = bash
indent_style = space
indent_size = 4
switch_case_indent = true
function_next_line = false
binary_next_line = true
space_redirects = true

26
.gitignore vendored
View File

@ -1,3 +1,23 @@
SOURCES/1.7.2.tar.gz
SOURCES/eppic_050615.tar.gz
SOURCES/kexec-tools-2.0.26.tar.xz
*.gz
*.xz
*.swp
*.rpm
/eppic_030413.tar.gz
/makedumpfile-1.5.7.tar.gz
/kexec-tools-2.0.8.tar.xz
/kdump-anaconda-addon-005-2-g86366ae.tar.gz
/kdump-anaconda-addon-005-5-gbf53665.tar.gz
/kdump-anaconda-addon-005-8-ge6ea581.tar.gz
/kdump-anaconda-addon-005-9-g6115ca7.tar.gz
/kexec-tools-2.0.9.tar.xz
/makedumpfile-1.5.8.tar.gz
/eppic_050615.tar.gz
/kexec-tools-2.0.10.tar.xz
/kdump-anaconda-addon-005-10-gd16915f.tar.gz
/kdump-anaconda-addon-005-11-g59f9b73.tar.gz
/kdump-anaconda-addon-005-12-g60fa4c1.tar.gz
/kdump-anaconda-addon-005-14-g563e904.tar.gz
/kdump-anaconda-addon-005-16-g586cc82.tar.gz
/kexec-tools-2.0.11.tar.xz
/makedumpfile-1.5.9.tar.gz
/kexec-tools-2.0.12.tar.xz

View File

@ -1,3 +0,0 @@
24bce02cd42cdbb960ada4d9e733355582e35784 SOURCES/1.7.2.tar.gz
a096c8e0892b559f40b01916aae240652f75b68a SOURCES/eppic_050615.tar.gz
27cea5d032ec1e93506b8110222420abf754df2d SOURCES/kexec-tools-2.0.26.tar.xz

31
60-fadump.install Executable file
View File

@ -0,0 +1,31 @@
#!/usr/bin/bash
COMMAND="$1"
KERNEL_VERSION="$2"
if ! [[ ${KERNEL_INSTALL_MACHINE_ID-x} ]]; then
exit 0
fi
# Currently, fadump is supported only in environments with
# writable /boot directory.
if [[ ! -w "/boot" ]]; then
exit 0
fi
FADUMP_INITRD="/boot/.initramfs-${KERNEL_VERSION}.img.default"
FADUMP_INITRD_CHECKSUM="$FADUMP_INITRD.checksum"
ret=0
case "$COMMAND" in
add)
# Do nothing, fadump initramfs is strictly host only
# and managed by kdump service
;;
remove)
rm -f -- "$FADUMP_INITRD"
rm -f -- "$FADUMP_INITRD_CHECKSUM"
ret=$?
;;
esac
exit $ret

13
92-crashkernel.install Executable file
View File

@ -0,0 +1,13 @@
#!/usr/bin/bash
COMMAND="$1"
KERNEL_VERSION="$2"
KDUMP_INITRD_DIR_ABS="$3"
KERNEL_IMAGE="$4"
case "$COMMAND" in
add)
kdumpctl _reset-crashkernel-for-installed_kernel "$KERNEL_VERSION"
exit 0
;;
esac

View File

@ -17,6 +17,6 @@ GOTO="kdump_reload_end"
LABEL="kdump_reload_cpu"
RUN+="/bin/sh -c '/usr/bin/systemctl is-active kdump.service || exit 0; ! test -f /sys/kernel/fadump_enabled || cat /sys/kernel/fadump_enabled | grep 0 || exit 0; /usr/bin/systemd-run --quiet --no-block /usr/lib/udev/kdump-udev-throttler'"
RUN+="/bin/sh -c '/usr/bin/systemctl is-active kdump.service || exit 0; ! test -f /sys/kernel/fadump/enabled || cat /sys/kernel/fadump/enabled | grep 0 || exit 0; /usr/bin/systemd-run --quiet --no-block /usr/lib/udev/kdump-udev-throttler'"
LABEL="kdump_reload_end"

4
99-kdump.conf Normal file
View File

@ -0,0 +1,4 @@
dracutmodules=''
add_dracutmodules=' kdumpbase '
omit_dracutmodules=' plymouth resume ifcfg earlykdump '
omit_drivers+=' nouveau amdgpu '

12
README Normal file
View File

@ -0,0 +1,12 @@
Adding a patch to kexec-tools
=============================
There is a mailing list kexec@lists.fedoraproject.org where all the dicussion
related to fedora kexec-tools happen. All the patches are posted there for
inclusion and committed to kexec-tools after review.
So if you want your patches to be included in fedora kexec-tools package,
post these to kexec@lists.fedoraproject.org.
One can subscribe to list and browse through archives here.
https://admin.fedoraproject.org/mailman/listinfo/kexec

View File

@ -1,28 +0,0 @@
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
# This service will be placed in kdump initramfs and replace both the systemd
# emergency service and dracut emergency shell. IOW, any emergency will be
# kick this service and in turn isolating to kdump error handler.
[Unit]
Description=Kdump Emergency
DefaultDependencies=no
IgnoreOnIsolate=yes
[Service]
ExecStart=/usr/bin/systemctl --no-block isolate kdump-error-handler.service
Type=oneshot
StandardInput=tty-force
StandardOutput=inherit
StandardError=inherit
KillMode=process
IgnoreSIGPIPE=no
# Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash
# terminates cleanly.
KillSignal=SIGHUP

View File

@ -1,10 +0,0 @@
#!/bin/sh
. /lib/kdump-lib-initramfs.sh
set -o pipefail
export PATH=$PATH:$KDUMP_SCRIPT_DIR
get_kdump_confs
do_failure_action
do_final_action

View File

@ -1,324 +0,0 @@
#!/bin/sh
# continue here only if we have to save dump.
if [ -f /etc/fadump.initramfs ] && [ ! -f /proc/device-tree/rtas/ibm,kernel-dump ] && [ ! -f /proc/device-tree/ibm,opal/dump/mpipl-boot ]; then
exit 0
fi
. /lib/dracut-lib.sh
. /lib/kdump-lib-initramfs.sh
set -o pipefail
DUMP_RETVAL=0
export PATH=$PATH:$KDUMP_SCRIPT_DIR
do_dump()
{
local _ret
eval $DUMP_INSTRUCTION
_ret=$?
if [ $_ret -ne 0 ]; then
derror "saving vmcore failed"
fi
return $_ret
}
do_kdump_pre()
{
local _ret
if [ -n "$KDUMP_PRE" ]; then
"$KDUMP_PRE"
_ret=$?
if [ $_ret -ne 0 ]; then
derror "$KDUMP_PRE exited with $_ret status"
return $_ret
fi
fi
# if any script fails, it just raises warning and continues
if [ -d /etc/kdump/pre.d ]; then
for file in /etc/kdump/pre.d/*; do
"$file"
_ret=$?
if [ $_ret -ne 0 ]; then
derror "$file exited with $_ret status"
fi
done
fi
return 0
}
do_kdump_post()
{
local _ret
if [ -d /etc/kdump/post.d ]; then
for file in /etc/kdump/post.d/*; do
"$file" "$1"
_ret=$?
if [ $_ret -ne 0 ]; then
derror "$file exited with $_ret status"
fi
done
fi
if [ -n "$KDUMP_POST" ]; then
"$KDUMP_POST" "$1"
_ret=$?
if [ $_ret -ne 0 ]; then
derror "$KDUMP_POST exited with $_ret status"
fi
fi
}
add_dump_code()
{
DUMP_INSTRUCTION=$1
}
dump_raw()
{
local _raw=$1
[ -b "$_raw" ] || return 1
dinfo "saving to raw disk $_raw"
if ! $(echo -n $CORE_COLLECTOR|grep -q makedumpfile); then
_src_size=`ls -l /proc/vmcore | cut -d' ' -f5`
_src_size_mb=$(($_src_size / 1048576))
monitor_dd_progress $_src_size_mb &
fi
dinfo "saving vmcore"
$CORE_COLLECTOR /proc/vmcore | dd of=$_raw bs=$DD_BLKSIZE >> /tmp/dd_progress_file 2>&1 || return 1
sync
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=""
dinfo "saving to $_host:$_dir"
cat /var/lib/random-seed > /dev/urandom
ssh -q $_opt $_host mkdir -p $_dir || return 1
save_vmcore_dmesg_ssh ${DMESG_COLLECTOR} ${_dir} "${_opt}" $_host
save_opalcore_ssh ${_dir} "${_opt}" $_host
dinfo "saving vmcore"
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 "umask 0077 && 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
return 0
}
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
if [ -f /sys/firmware/opal/core ]; then
OPALCORE="/sys/firmware/opal/core"
else
return 0
fi
fi
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
derror "saving opalcore failed"
return 1
fi
ssh $_opts $_location mv $_path/opalcore-incomplete $_path/opalcore
dinfo "saving opalcore complete"
return 0
}
save_vmcore_dmesg_ssh() {
local _dmesg_collector=$1
local _path=$2
local _opts="$3"
local _location=$4
dinfo "saving vmcore-dmesg.txt to $_location:$_path"
$_dmesg_collector /proc/vmcore | ssh $_opts $_location "umask 0077 && 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
dinfo "saving vmcore-dmesg.txt complete"
else
derror "saving vmcore-dmesg.txt failed"
fi
}
get_host_ip()
{
local _host
if is_nfs_dump_target || is_ssh_dump_target
then
kdumpnic=$(getarg kdumpnic=)
[ -z "$kdumpnic" ] && derror "failed to get kdumpnic!" && return 1
_host=`ip addr show dev $kdumpnic|grep '[ ]*inet'`
[ $? -ne 0 ] && derror "wrong kdumpnic: $kdumpnic" && return 1
_host=`echo $_host | head -n 1 | cut -d' ' -f2`
_host="${_host%%/*}"
[ -z "$_host" ] && derror "wrong kdumpnic: $kdumpnic" && return 1
HOST_IP=$_host
fi
return 0
}
read_kdump_conf()
{
if [ ! -f "$KDUMP_CONF" ]; then
derror "$KDUMP_CONF not found"
return
fi
get_kdump_confs
# rescan for add code for dump target
while read config_opt config_val;
do
# remove inline comments after the end of a directive.
case "$config_opt" in
dracut_args)
config_val=$(get_dracut_args_target "$config_val")
if [ -n "$config_val" ]; then
config_val=$(get_mntpoint_from_target "$config_val")
add_dump_code "dump_fs $config_val"
fi
;;
ext[234]|xfs|btrfs|minix|nfs)
config_val=$(get_mntpoint_from_target "$config_val")
add_dump_code "dump_fs $config_val"
;;
raw)
add_dump_code "dump_raw $config_val"
;;
ssh)
add_dump_code "dump_ssh $SSH_KEY_LOCATION $config_val"
;;
esac
done <<< "$(read_strip_comments $KDUMP_CONF)"
}
fence_kdump_notify()
{
if [ -n "$FENCE_KDUMP_NODES" ]; then
$FENCE_KDUMP_SEND $FENCE_KDUMP_ARGS $FENCE_KDUMP_NODES &
fi
}
read_kdump_conf
fence_kdump_notify
get_host_ip
if [ $? -ne 0 ]; then
derror "get_host_ip exited with non-zero status!"
exit 1
fi
if [ -z "$DUMP_INSTRUCTION" ]; then
add_dump_code "dump_fs $NEWROOT"
fi
do_kdump_pre
if [ $? -ne 0 ]; then
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
fi
make_trace_mem "kdump saving vmcore" '1:shortmem' '2+:mem' '3+:slab'
do_dump
DUMP_RETVAL=$?
do_kdump_post $DUMP_RETVAL
if [ $? -ne 0 ]; then
derror "kdump_post script exited with non-zero status!"
fi
if [ $DUMP_RETVAL -ne 0 ]; then
exit 1
fi
do_final_action

File diff suppressed because it is too large Load Diff

View File

@ -1,248 +0,0 @@
# 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 7 -d 31"
DMESG_COLLECTOR="/sbin/vmcore-dmesg"
FAILURE_ACTION="systemctl reboot -f"
DATEDIR=`date +%Y-%m-%d-%T`
HOST_IP='127.0.0.1'
DUMP_INSTRUCTION=""
SSH_KEY_LOCATION="/root/.ssh/kdump_id_rsa"
KDUMP_SCRIPT_DIR="/kdumpscripts"
DD_BLKSIZE=512
FINAL_ACTION="systemctl reboot -f"
KDUMP_CONF="/etc/kdump.conf"
KDUMP_PRE=""
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
while read config_opt config_val;
do
# remove inline comments after the end of a directive.
case "$config_opt" in
path)
KDUMP_PATH="$config_val"
;;
core_collector)
[ -n "$config_val" ] && CORE_COLLECTOR="$config_val"
;;
sshkey)
if [ -f "$config_val" ]; then
SSH_KEY_LOCATION=$config_val
fi
;;
kdump_pre)
KDUMP_PRE="$config_val"
;;
kdump_post)
KDUMP_POST="$config_val"
;;
fence_kdump_args)
FENCE_KDUMP_ARGS="$config_val"
;;
fence_kdump_nodes)
FENCE_KDUMP_NODES="$config_val"
;;
failure_action|default)
case $config_val in
shell)
FAILURE_ACTION="kdump_emergency_shell"
;;
reboot)
FAILURE_ACTION="systemctl reboot -f && exit"
;;
halt)
FAILURE_ACTION="halt && exit"
;;
poweroff)
FAILURE_ACTION="systemctl poweroff -f && exit"
;;
dump_to_rootfs)
FAILURE_ACTION="dump_to_rootfs"
;;
esac
;;
final_action)
case $config_val in
reboot)
FINAL_ACTION="systemctl reboot -f"
;;
halt)
FINAL_ACTION="halt"
;;
poweroff)
FINAL_ACTION="systemctl poweroff -f"
;;
esac
;;
esac
done <<< "$(read_strip_comments $KDUMP_CONF)"
if [ -z "$CORE_COLLECTOR" ]; then
CORE_COLLECTOR="$DEFAULT_CORE_COLLECTOR"
if is_ssh_dump_target || is_raw_dump_target; then
CORE_COLLECTOR="$CORE_COLLECTOR -F"
fi
fi
}
# 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
chmod 600 $KDUMP_LOG_FILE
}
# dump_fs <mount point>
dump_fs()
{
local _exitcode
local _mp=$1
ddebug "dump_fs _mp=$_mp"
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
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"`
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
save_vmcore_dmesg_fs ${DMESG_COLLECTOR} "$_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR/"
save_opalcore_fs "$_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR/"
dinfo "saving vmcore"
$CORE_COLLECTOR /proc/vmcore $_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR/vmcore-incomplete
_exitcode=$?
if [ $_exitcode -eq 0 ]; then
sync -f "$_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR/vmcore-incomplete"
_sync_exitcode=$?
if [ $_sync_exitcode -eq 0 ]; then
mv "$_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR/vmcore-incomplete" "$_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR/vmcore"
dinfo "saving vmcore complete"
else
derror "sync vmcore failed, _exitcode:$_sync_exitcode"
return 1
fi
else
derror "saving vmcore failed, _exitcode:$_exitcode"
fi
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
}
save_vmcore_dmesg_fs() {
local _dmesg_collector=$1
local _path=$2
dinfo "saving vmcore-dmesg.txt to ${_path}"
$_dmesg_collector /proc/vmcore > ${_path}/vmcore-dmesg-incomplete.txt
_exitcode=$?
if [ $_exitcode -eq 0 ]; then
mv ${_path}/vmcore-dmesg-incomplete.txt ${_path}/vmcore-dmesg.txt
chmod 600 ${_path}/vmcore-dmesg.txt
# Make sure file is on disk. There have been instances where later
# saving vmcore failed and system rebooted without sync and there
# was no vmcore-dmesg.txt available.
sync
dinfo "saving vmcore-dmesg.txt complete"
else
derror "saving vmcore-dmesg.txt failed"
fi
}
save_opalcore_fs() {
local _path=$1
if [ ! -f $OPALCORE ]; then
# Check if we are on an old kernel that uses a different path
if [ -f /sys/firmware/opal/core ]; then
OPALCORE="/sys/firmware/opal/core"
else
return 0
fi
fi
dinfo "saving opalcore:$OPALCORE to ${_path}/opalcore"
cp $OPALCORE ${_path}/opalcore
if [ $? -ne 0 ]; then
derror "saving opalcore failed"
return 1
fi
sync
dinfo "saving opalcore complete"
return 0
}
dump_to_rootfs()
{
dinfo "Trying to bring up rootfs device"
systemctl start dracut-initqueue
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()
{
dinfo "Executing failure action $FAILURE_ACTION"
eval $FAILURE_ACTION
}
do_final_action()
{
dinfo "Executing final action $FINAL_ACTION"
eval $FINAL_ACTION
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,55 +0,0 @@
.TH KDUMPCTL 8 2015-07-13 kexec-tools
.SH NAME
kdumpctl \- control interface for kdump
.SH SYNOPSIS
.B kdumpctl
.I COMMAND
.SH DESCRIPTION
.B kdumpctl
is used to check or control the kdump service.
In most cases, you should use
.B systemctl
to start / stop / enable kdump service instead. However,
.B kdumpctl
provides more details for debug and a helper to setup ssh key authentication.
.SH COMMANDS
.TP
.I start
Start the service.
.TP
.I stop
Stop the service.
.TP
.I status
Prints the current status of kdump service.
It returns non-zero value if kdump is not operational.
.TP
.I restart
Is equal to
.I start; stop
.TP
.I reload
reload crash kernel image and initramfs without triggering a rebuild.
.TP
.I rebuild
rebuild the crash kernel initramfs.
.TP
.I propagate
Helps to setup key authentication for ssh storage since it's
impossible to use password authentication during kdump.
.TP
.I showmem
Prints the size of reserved memory for crash kernel in megabytes.
.TP
.I estimate
Estimate a suitable crashkernel value for current machine. This is a
best-effort estimate. It will print a recommanded crashkernel value
based on current kdump setup, and list some details of memory usage.
.SH "SEE ALSO"
.BR kdump.conf (5),
.BR mkdumprd (8)

View File

@ -1,72 +0,0 @@
From 58553ad03187f0cf208d6c4a0dc026c6338e5edd Mon Sep 17 00:00:00 2001
From: "Daisuke Hatayama (Fujitsu)" <d.hatayama@fujitsu.com>
Date: Wed, 29 Mar 2023 12:44:10 +0000
Subject: [PATCH] [PATCH] sadump: fix failure of reading memory when 5-level
paging is enabled
makedumpfile fails as follows for memory dumps collected by sadump
when 5-level paging is enabled on the corresponding systems:
# makedumpfile -l -d 31 -x ./vmlinux ./dump.sadump dump.sadump-ld31
__vtop4_x86_64: Can't get a valid pgd.
...snip...
__vtop4_x86_64: Can't get a valid pgd.
calc_kaslr_offset: failed to calculate kaslr_offset and phys_base; default to 0
__vtop4_x86_64: Can't get a valid pgd.
readmem: Can't convert a virtual address(ffffffff82fce960) to physical address.
readmem: type_addr: 0, addr:ffffffff82fce960, size:1024
cpu_online_mask_init: Can't read cpu_online_mask memory.
makedumpfile Failed.
This is because 5-level paging support has not been done yet for
sadump; the work of the 5-level paging support was done by the commit
30a3214a7193e94c551c0cebda5918a72a35c589 (PATCH 4/4 arch/x86_64: Add
5-level paging support) but that was focused on the core part only.
Having said that, most of things has already been finished in the
commit. What needs to be newly added for sadump is just how to check
if 5-level paging is enabled for a given memory dump.
For that purpose, let's refer to CR4.LA57, bit 12 of CR4, representing
whether 5-level paging is enabled or not. We can do this because
memory dumps collected by sadump have SMRAM as note information and
they include CR4 together with the other control registers.
Signed-off-by: HATAYAMA Daisuke <d.hatayama@fujitsu.com>
---
sadump_info.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/makedumpfile-1.7.2/sadump_info.c b/makedumpfile-1.7.2/sadump_info.c
index adfa8dc..2c44068 100644
--- a/makedumpfile-1.7.2/sadump_info.c
+++ b/makedumpfile-1.7.2/sadump_info.c
@@ -1362,6 +1362,7 @@ static int linux_banner_sanity_check(ulong cr3)
#define PTI_USER_PGTABLE_BIT (info->page_shift)
#define PTI_USER_PGTABLE_MASK (1 << PTI_USER_PGTABLE_BIT)
#define CR3_PCID_MASK 0xFFFull
+#define CR4_LA57 (1 << 12)
int
calc_kaslr_offset(void)
{
@@ -1397,6 +1398,8 @@ calc_kaslr_offset(void)
else
cr3 = smram.Cr3 & ~CR3_PCID_MASK;
+ NUMBER(pgtable_l5_enabled) = !!(smram.Cr4 & CR4_LA57);
+
/* Convert virtual address of IDT table to physical address */
idtr_paddr = vtop4_x86_64_pagetable(idtr, cr3);
if (idtr_paddr == NOT_PADDR) {
@@ -1417,6 +1420,7 @@ calc_kaslr_offset(void)
DEBUG_MSG("sadump: idtr=%" PRIx64 "\n", idtr);
DEBUG_MSG("sadump: cr3=%" PRIx64 "\n", cr3);
+ DEBUG_MSG("sadump: cr4=%" PRIx32 "\n", smram.Cr4);
DEBUG_MSG("sadump: idtr(phys)=%" PRIx64 "\n", idtr_paddr);
DEBUG_MSG("sadump: devide_error(vmlinux)=%lx\n",
divide_error_vmlinux);
--
2.31.1

View File

@ -1,452 +0,0 @@
#!/bin/bash --norc
# New mkdumprd
#
# Copyright 2011 Red Hat, Inc.
#
# Written by Cong Wang <amwang@redhat.com>
#
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="--add kdumpbase --quiet --hostonly --hostonly-cmdline --hostonly-i18n --hostonly-mode strict --hostonly-nics '' -o \"plymouth dash resume ifcfg earlykdump\" --compress=xz"
readonly MKDUMPRD_TMPDIR="$(mktemp -d -t mkdumprd.XXXXXX)"
[ -d "$MKDUMPRD_TMPDIR" ] || perror_exit "dracut: mktemp -p -d -t dracut.XXXXXX failed."
readonly MKDUMPRD_TMPMNT="$MKDUMPRD_TMPDIR/target"
trap '
ret=$?;
is_mounted $MKDUMPRD_TMPMNT && umount -f $MKDUMPRD_TMPMNT;
[[ -d $MKDUMPRD_TMPDIR ]] && rm --one-file-system -rf -- "$MKDUMPRD_TMPDIR";
exit $ret;
' EXIT
# clean up after ourselves no matter how we die.
trap 'exit 1;' SIGINT
add_dracut_arg() {
dracut_args="$dracut_args $@"
}
add_dracut_mount() {
add_dracut_arg "--mount" "\"$1\""
}
add_dracut_sshkey() {
add_dracut_arg "--sshkey" "\"$1\""
}
# caller should ensure $1 is valid and mounted in 1st kernel
to_mount() {
local _target=$1 _fstype=$2 _options=$3 _new_mntpoint _pdev
_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}"
if [[ "$_fstype" == "nfs"* ]]; then
_pdev=$_target
_options=$(echo $_options | sed 's/,\(mount\)\?addr=[^,]*//g')
_options=$(echo $_options | sed 's/,\(mount\)\?proto=[^,]*//g')
_options=$(echo $_options | sed 's/,clientaddr=[^,]*//')
else
# for non-nfs _target converting to use udev persistent name
_pdev="$(kdump_get_persistent_dev $_target)"
if [ -z "$_pdev" ]; then
return 1
fi
fi
#mount fs target as rw in 2nd kernel
_options=$(echo $_options | sed 's/\(^\|,\)ro\($\|,\)/\1rw\2/g')
# with 'noauto' in fstab nfs and non-root disk mount will fail in 2nd
# kernel, filter it out here.
_options=$(echo $_options | sed 's/\(^\|,\)noauto\($\|,\)/\1/g')
# use both nofail and x-systemd.before to ensure systemd will try best to
# mount it before kdump starts, this is an attempt to improve robustness
_options="$_options,nofail,x-systemd.before=initrd-fs.target"
echo "$_pdev $_new_mntpoint $_fstype $_options"
}
#Function: get_ssh_size
#$1=dump target
#called from while loop and shouldn't read from stdin, so we're using "ssh -n"
get_ssh_size() {
local _opt _out _size
_opt="-i $SSH_KEY_LOCATION -o BatchMode=yes -o StrictHostKeyChecking=yes"
_out=$(ssh -q -n $_opt $1 "df -P $SAVE_PATH")
[ $? -ne 0 ] && {
perror_exit "checking remote ssh server available size failed."
}
#ssh output removed the line break, so print field NF-2
_size=$(echo -n $_out| awk '{avail=NF-2; print $avail}')
echo -n $_size
}
#mkdir if save path does not exist on ssh dump target
#$1=ssh dump target
#caller should ensure write permission on $1:$SAVE_PATH
#called from while loop and shouldn't read from stdin, so we're using "ssh -n"
mkdir_save_path_ssh()
{
local _opt _dir
_opt="-i $SSH_KEY_LOCATION -o BatchMode=yes -o StrictHostKeyChecking=yes"
ssh -qn $_opt $1 mkdir -p $SAVE_PATH 2>&1 > /dev/null
_ret=$?
if [ $_ret -ne 0 ]; then
perror_exit "mkdir failed on $1:$SAVE_PATH"
fi
#check whether user has write permission on $1:$SAVE_PATH
_dir=$(ssh -qn $_opt $1 mktemp -dqp $SAVE_PATH 2>/dev/null)
_ret=$?
if [ $_ret -ne 0 ]; then
perror_exit "Could not create temporary directory on $1:$SAVE_PATH. Make sure user has write permission on destination"
fi
ssh -qn $_opt $1 rmdir $_dir
return 0
}
#Function: get_fs_size
#$1=dump target
get_fs_size() {
local _mnt=$(get_mntpoint_from_target $1)
echo -n $(df -P "${_mnt}/$SAVE_PATH"|tail -1|awk '{print $4}')
}
#Function: get_raw_size
#$1=dump target
get_raw_size() {
echo -n $(fdisk -s "$1")
}
#Function: check_size
#$1: dump type string ('raw', 'fs', 'ssh')
#$2: dump target
check_size() {
local avail memtotal
memtotal=$(awk '/MemTotal/{print $2}' /proc/meminfo)
case "$1" in
raw)
avail=$(get_raw_size "$2")
;;
ssh)
avail=$(get_ssh_size "$2")
;;
fs)
avail=$(get_fs_size "$2")
;;
*)
return
esac
if [ $? -ne 0 ]; then
perror_exit "Check dump target size failed"
fi
if [ $avail -lt $memtotal ]; then
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
}
check_save_path_fs()
{
local _path=$1
if [ ! -d $_path ]; then
perror_exit "Dump path $_path does not exist."
fi
}
check_user_configured_target()
{
local _target=$1 _cfg_fs_type=$2 _mounted
local _mnt=$(get_mntpoint_from_target $_target)
local _opt=$(get_mntopt_from_target $_target)
local _fstype=$(get_fs_type_from_target $_target)
if [ -n "$_fstype" ]; then
# In case of nfs4, nfs should be used instead, nfs* options is deprecated in kdump.conf
[[ $_fstype = "nfs"* ]] && _fstype=nfs
if [ -n "$_cfg_fs_type" ] && [ "$_fstype" != "$_cfg_fs_type" ]; then
perror_exit "\"$_target\" have a wrong type config \"$_cfg_fs_type\", expected \"$_fstype\""
fi
else
_fstype="$_cfg_fs_type"
_fstype="$_cfg_fs_type"
fi
# For noauto mount, mount it inplace with default value.
# Else use the temporary target directory
if [ -n "$_mnt" ]; then
if ! is_mounted "$_mnt"; then
if [[ $_opt = *",noauto"* ]]; then
mount $_mnt
[ $? -ne 0 ] && perror_exit "Failed to mount $_target on $_mnt for kdump preflight check."
_mounted=$_mnt
else
perror_exit "Dump target \"$_target\" is neither mounted nor configured as \"noauto\""
fi
fi
else
_mnt=$MKDUMPRD_TMPMNT
mkdir -p $_mnt
mount $_target $_mnt -t $_fstype -o defaults
[ $? -ne 0 ] && perror_exit "Failed to mount $_target for kdump preflight check."
_mounted=$_mnt
fi
# For user configured target, use $SAVE_PATH as the dump path within the target
if [ ! -d "$_mnt/$SAVE_PATH" ]; then
perror_exit "Dump path \"$SAVE_PATH\" does not exist in dump target \"$_target\""
fi
check_size fs "$_target"
# Unmount it early, if function is interrupted and didn't reach here, the shell trap will clear it up anyway
if [ -n "$_mounted" ]; then
umount -f -- $_mounted
fi
}
# $1: core_collector config value
verify_core_collector() {
local _cmd="${1%% *}"
local _params="${1#${_cmd}}"
if [ "$_cmd" != "makedumpfile" ]; then
if is_raw_dump_target; then
dwarn "Warning: specifying a non-makedumpfile core collector, you will have to recover the vmcore manually."
fi
return
fi
if is_ssh_dump_target || is_raw_dump_target; then
if ! strstr "$_params" "-F"; then
perror_exit "The specified dump target needs makedumpfile \"-F\" option."
fi
_params="$_params vmcore"
else
_params="$_params vmcore dumpfile"
fi
if ! $_cmd --check-params $_params; then
perror_exit "makedumpfile parameter check failed."
fi
}
add_mount() {
local _mnt=$(to_mount $@)
if [ $? -ne 0 ]; then
exit 1
fi
add_dracut_mount "$_mnt"
}
#handle the case user does not specify the dump target explicitly
handle_default_dump_target()
{
local _target
local _mntpoint
is_user_configured_dump_target && return
check_save_path_fs $SAVE_PATH
_save_path=$(get_bind_mount_source $SAVE_PATH)
_target=$(get_target_from_path $_save_path)
_mntpoint=$(get_mntpoint_from_target $_target)
SAVE_PATH=${_save_path##"$_mntpoint"}
add_mount "$_target"
check_size fs $_target
}
get_override_resettable()
{
local override_resettable
override_resettable=$(grep "^override_resettable" $conf_file)
if [ -n "$override_resettable" ]; then
OVERRIDE_RESETTABLE=$(echo $override_resettable | cut -d' ' -f2)
if [ "$OVERRIDE_RESETTABLE" != "0" ] && [ "$OVERRIDE_RESETTABLE" != "1" ];then
perror_exit "override_resettable value $OVERRIDE_RESETTABLE is invalid"
fi
fi
}
# $1: function name
for_each_block_target()
{
local dev majmin
for dev in $(get_kdump_targets); do
[ -b "$dev" ] || continue
majmin=$(get_maj_min $dev)
check_block_and_slaves $1 $majmin && return 1
done
return 0
}
#judge if a specific device with $1 is unresettable
#return false if unresettable.
is_unresettable()
{
local path="/sys/$(udevadm info --query=all --path=/sys/dev/block/$1 | awk '/^P:/ {print $2}' | sed -e 's/\(cciss[0-9]\+\/\).*/\1/g' -e 's/\/block\/.*$//')/resettable"
local resettable=1
if [ -f "$path" ]
then
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}')
derror "Error: Can not save vmcore because device $device is unresettable"
return 0
}
fi
return 1
}
#check if machine is resettable.
#return true if resettable
check_resettable()
{
local _ret _target
get_override_resettable
for_each_block_target is_unresettable
_ret=$?
[ $_ret -eq 0 ] && return
return 1
}
check_crypt()
{
local _dev
for _dev in $(get_kdump_targets); do
if [[ -n $(get_luks_crypt_dev "$(get_maj_min "$_dev")") ]]; then
derror "Device $_dev is encrypted." && return 1
fi
done
}
if ! check_resettable; then
exit 1
fi
if ! check_crypt; then
dwarn "Warning: Encrypted device is in dump path. User will prompted for password during second kernel boot."
fi
# firstly get right SSH_KEY_LOCATION
keyfile=$(awk '/^sshkey/ {print $2}' $conf_file)
if [ -f "$keyfile" ]; then
# canonicalize the path
SSH_KEY_LOCATION=$(/usr/bin/readlink -m $keyfile)
fi
while read config_opt config_val;
do
# remove inline comments after the end of a directive.
case "$config_opt" in
extra_modules)
extra_modules="$extra_modules $config_val"
;;
ext[234]|xfs|btrfs|minix|nfs)
check_user_configured_target "$config_val" "$config_opt"
add_mount "$config_val" "$config_opt"
;;
raw)
# checking raw disk writable
dd if=$config_val count=1 of=/dev/null > /dev/null 2>&1 || {
perror_exit "Bad raw disk $config_val"
}
_praw=$(persistent_policy="by-id" kdump_get_persistent_dev $config_val)
if [ -z "$_praw" ]; then
exit 1
fi
add_dracut_arg "--device" "$_praw"
check_size raw $config_val
;;
ssh)
if strstr "$config_val" "@";
then
mkdir_save_path_ssh $config_val
check_size ssh $config_val
add_dracut_sshkey "$SSH_KEY_LOCATION"
else
perror_exit "Bad ssh dump target $config_val"
fi
;;
core_collector)
verify_core_collector "$config_val"
;;
dracut_args)
add_dracut_arg $config_val
;;
*)
;;
esac
done <<< "$(read_strip_comments $conf_file)"
handle_default_dump_target
if [ -n "$extra_modules" ]
then
add_dracut_arg "--add-drivers" \"$extra_modules\"
fi
# TODO: The below check is not needed anymore with the introduction of
# 'zz-fadumpinit' module, that isolates fadump's capture kernel initrd,
# but still sysroot.mount unit gets generated based on 'root=' kernel
# parameter available in fadump case. So, find a way to fix that first
# before removing this check.
if ! is_fadump_capable; then
# The 2nd rootfs mount stays behind the normal dump target mount,
# so it doesn't affect the logic of check_dump_fs_modified().
is_dump_to_rootfs && add_mount "$(to_dev_name $(get_root_fs_device))"
add_dracut_arg "--no-hostonly-default-device"
if fips-mode-setup --is-enabled 2> /dev/null; then
add_dracut_arg --add-device "$(findmnt -n -o SOURCE --target /boot)"
fi
fi
echo "$dracut_args $@" | xargs dracut

View File

@ -1,13 +0,0 @@
diff --git a/purgatory/Makefile b/purgatory/Makefile
index 49ce80a..97b7a03 100644
--- a/purgatory/Makefile
+++ b/purgatory/Makefile
@@ -67,7 +67,7 @@ $(PURGATORY): $(PURGATORY_OBJS)
$(MKDIR) -p $(@D)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@.sym $^
# $(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) --no-undefined -e purgatory_start -r -o $@ $(PURGATORY_OBJS) $(UTIL_LIB)
- $(STRIP) --strip-debug -o $@ $@.sym
+ $(STRIP) --strip-debug --no-merge-notes -o $@ $@.sym
echo::
@echo "PURGATORY_SRCS $(PURGATORY_SRCS)"

View File

@ -1,51 +0,0 @@
From ce720608d5933e62f77f2c2f216859cf4f06adf8 Mon Sep 17 00:00:00 2001
From: Kairui Song <kasong@redhat.com>
Date: Wed, 13 Feb 2019 00:03:51 +0800
Subject: [PATCH] Fix eppic issue with hardening flags
This is stash of two commits:
commit f98cf5fe07f390554696755f0a5843f6bb9c4716
Author: ryncsn <ryncsn@gmail.com>
Date: Tue Mar 19 13:39:25 2019 +0800
Tell gcc not to omit frame pointer
After commit 0209874, it's now possible to enable optimization above O0.
But eppic might call __builtin_return_address(1). With O1,
-fomit-frame-pointer is enabled gcc may omit frame pointer.
__builtin_return_address(1) relies on callee preserves RBP as the stack
base, which is untrue if optimization is usded. In this case it may return
wrong value or crash.
In case of any potential failure, use -fno-omit-frame-pointer globally.
Signed-off-by: Kairui Song <ryncsn@gmail.com>
commit 0209874f4b46b8af5a2d42662ba6775cf5a1dc44
Author: Kairui Song <kasong@redhat.com>
Date: Wed Feb 13 00:03:51 2019 +0800
Drop O0 CFLAGS override in Makefile
Signed-off-by: Kairui Song <kasong@redhat.com>
---
libeppic/Makefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libeppic/Makefile b/libeppic/Makefile
index bcf2edf..8b97c87 100644
--- a/eppic/libeppic/Makefile
+++ b/eppic/libeppic/Makefile
@@ -24,7 +24,7 @@ LDIRT = lex.eppic.c lex.eppicpp.c eppic.tab.c eppic.tab.h eppicpp.tab.c \
LIBDIR = /usr/lib
TARGETS = libeppic.a
-CFLAGS += -O0 -g -fPIC
+CFLAGS += -g -fno-omit-frame-pointer -fPIC
ifeq ($(TARGET), PPC64)
CFLAGS += -m64
endif
--
2.20.1

View File

@ -1,88 +0,0 @@
From 0f632fa180e5a44219ab6bbe0879c3583f8c65cf Mon Sep 17 00:00:00 2001
From: Pingfan Liu <piliu@redhat.com>
Date: Tue, 9 Nov 2021 11:24:22 +0800
Subject: [PATCH] RHEL-only
Cope with RHEL8 kernel
Signed-off-by: Pingfan Liu <piliu@redhat.com>
---
arch/arm64.c | 14 +++++++++++++-
makedumpfile.c | 2 ++
makedumpfile.h | 1 +
3 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/makedumpfile-1.7.2/arch/arm64.c b/makedumpfile-1.7.2/arch/arm64.c
index 1072178..95beae6 100644
--- a/makedumpfile-1.7.2/arch/arm64.c
+++ b/makedumpfile-1.7.2/arch/arm64.c
@@ -50,6 +50,7 @@ static int va_bits;
static int vabits_actual;
static int flipped_va;
static unsigned long kimage_voffset;
+static int max_user_va_bits;
#define SZ_4K 4096
#define SZ_16K 16384
@@ -108,7 +109,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.
@@ -449,6 +450,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.7.2/makedumpfile.c b/makedumpfile-1.7.2/makedumpfile.c
index 3ad4443..018ea4c 100644
--- a/makedumpfile-1.7.2/makedumpfile.c
+++ b/makedumpfile-1.7.2/makedumpfile.c
@@ -2417,6 +2417,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("TCR_EL1_T1SZ", TCR_EL1_T1SZ); should not exists */
WRITE_NUMBER_UNSIGNED("PHYS_OFFSET", PHYS_OFFSET);
@@ -2863,6 +2864,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("TCR_EL1_T1SZ", TCR_EL1_T1SZ);
READ_NUMBER_UNSIGNED("PHYS_OFFSET", PHYS_OFFSET);
diff --git a/makedumpfile-1.7.2/makedumpfile.h b/makedumpfile-1.7.2/makedumpfile.h
index e59239d..b6236dd 100644
--- a/makedumpfile-1.7.2/makedumpfile.h
+++ b/makedumpfile-1.7.2/makedumpfile.h
@@ -2064,6 +2064,7 @@ struct number_table {
long phys_base;
long KERNEL_IMAGE_SIZE;
#ifdef __aarch64__
+ long MAX_USER_VA_BITS;
long VA_BITS;
long TCR_EL1_T1SZ;
unsigned long PHYS_OFFSET;
--
2.31.1

120
crashkernel-howto.txt Normal file
View File

@ -0,0 +1,120 @@
Introduction
============
This document describes features the kexec-tools package provides for setting
and estimating the crashkernel value.
Kdump lives in a pre-reserved chunk of memory, and the size of the reserved
memory is specified by the `crashkernel=` kernel parameter. It's hard to
estimate an accurate `crashkernel=` value, so it's always recommended to test
kdump after you updated the `crashkernel=` value or changed the dump target.
Default crashkernel value
=========================
Latest kexec-tools provides "kdumpctl get-default-crashkernel" to retrieve
the default crashkernel value,
$ echo $(kdumpctl get-default-crashkernel)
1G-4G:192M,4G-64G:256M,64G-:512M
It will be taken as the default value of 'crashkernel=', you can use
this value as a reference for setting crashkernel value manually.
New installed system
====================
Anaconda is the OS installer which sets all the kernel boot cmdline on a newly
installed system. If kdump is enabled during Anaconda installation, Anaconda
will use the default crashkernel value as the default `crashkernel=` value on
the newly installed system.
Users can override the value during Anaconda installation manually.
Auto update of crashkernel boot parameter
=========================================
A new release of kexec-tools could update the default crashkernel value. By
default, kexec-tools would reset crashkernel to the new default value if it
detects the old default crashkernel value is used by installed kernels. If you
don't want kexec-tools to update the old default crashkernel to the new default
crashkernel, you can change auto_reset_crashkernel to no in kdump.conf.
Supported Bootloaders
---------------------
This auto update only works with GRUB2 and ZIPL, as kexec-tools heavily depends
on `grubby`. If other boot loaders are used, the user will have to update the
`crashkernel=` value manually.
Reset crashkernel to default value
==================================
kexec-tools only perform the auto update of crashkernel value when it can
confirm the boot kernel's crashkernel value is using its corresponding default
value and auto_reset_crashkernel=yes in kdump.conf. In other cases, the user
can reset the crashkernel value by themselves.
Reset using kdumpctl
--------------------
To make it easier to reset the `crashkernel=` kernel cmdline to this default
value properly, `kdumpctl` also provides a sub-command:
`kdumpctl reset-crashkernel [--kernel=path_to_kernel] [--reboot]`
This command will reset the bootloader's kernel cmdline to the default value.
It will also update bootloader config if the bootloader has a standalone config
file. User will have to reboot the machine after this command to make it take
effect if --reboot is not specified. For more details, please refer to the
reset-crashkernel command in `man kdumpctl`.
Reset manually
--------------
To reset the crashkernel value manually, it's recommended to use utils like
`grubby`. A one liner script for resetting `crashkernel=` value of all installed
kernels to the default value is:
grubby --update-kernel ALL --args "crashkernel=$(kdumpctl get-default-crashkernel)"
NOTE: On s390x you also need to run zipl for the change to take effect.
Estimate crashkernel
====================
The best way to estimate a usable crashkernel value is by testing kdump
manually. And you can set crashkernel to a large value, then adjust the
crashkernel value to an acceptable value gradually.
`kdumpctl` also provides a sub-command for doing rough estimating without
triggering kdump:
`kdumpctl estimate`
The output will be like this:
```
Encrypted kdump target requires extra memory, assuming using the keyslot with minimum memory requirement
Reserved crashkernel: 256M
Recommended crashkernel: 655M
Kernel image size: 47M
Kernel modules size: 12M
Initramfs size: 19M
Runtime reservation: 64M
LUKS required size: 512M
Large modules:
xfs: 1892352
nouveau: 2318336
WARNING: Current crashkernel size is lower than recommended size 655M.
```
It will generate a summary report about the estimated memory consumption
of each component of kdump. The value may not be accurate enough, but
would be a good start for finding a suitable crashkernel value.

View File

@ -6,9 +6,8 @@ KDUMP_KERNEL=""
KDUMP_INITRD=""
check() {
if [ ! -f /etc/sysconfig/kdump ] || [ ! -f /lib/kdump/kdump-lib.sh ]\
|| [ -n "${IN_KDUMP}" ]
then
if [[ ! -f /etc/sysconfig/kdump ]] || [[ ! -f /lib/kdump/kdump-lib.sh ]] \
|| [[ -n ${IN_KDUMP} ]]; then
return 1
fi
return 255
@ -25,7 +24,7 @@ prepare_kernel_initrd() {
prepare_kdump_bootinfo
# $kernel is a variable from dracut
if [ "$KDUMP_KERNELVER" != $kernel ]; then
if [[ $KDUMP_KERNELVER != "$kernel" ]]; then
dwarn "Using kernel version '$KDUMP_KERNELVER' for early kdump," \
"but the initramfs is generated for kernel version '$kernel'"
fi
@ -33,12 +32,12 @@ prepare_kernel_initrd() {
install() {
prepare_kernel_initrd
if [ ! -f "$KDUMP_KERNEL" ]; then
if [[ ! -f $KDUMP_KERNEL ]]; then
derror "Could not find required kernel for earlykdump," \
"earlykdump will not work!"
return 1
fi
if [ ! -f "$KDUMP_INITRD" ]; then
if [[ ! -f $KDUMP_INITRD ]]; then
derror "Could not find required kdump initramfs for earlykdump," \
"please ensure kdump initramfs is generated first," \
"earlykdump will not work!"
@ -51,7 +50,9 @@ install() {
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_binary "/usr/bin/xargs" "/usr/bin/xargs"
inst_script "/lib/kdump/kdump-lib.sh" "/lib/kdump-lib.sh"
inst_script "/lib/kdump/kdump-lib-initramfs.sh" "/lib/kdump/kdump-lib-initramfs.sh"
inst_script "/lib/kdump/kdump-logger.sh" "/lib/kdump-logger.sh"
inst_hook cmdline 00 "$moddir/early-kdump.sh"
inst_binary "$KDUMP_KERNEL"

View File

@ -14,9 +14,8 @@ EARLY_KEXEC_ARGS=""
. /lib/kdump-lib.sh
. /lib/kdump-logger.sh
#initiate the kdump logger
dlog_init
if [ $? -ne 0 ]; then
# initiate the kdump logger
if ! dlog_init; then
echo "failed to initiate the kdump logger."
exit 1
fi
@ -30,8 +29,7 @@ prepare_parameters()
early_kdump_load()
{
check_kdump_feasibility
if [ $? -ne 0 ]; then
if ! check_kdump_feasibility; then
return 1
fi
@ -40,8 +38,7 @@ early_kdump_load()
return 1
fi
check_current_kdump_status
if [ $? == 0 ]; then
if is_kernel_loaded "kdump"; then
return 1
fi
@ -56,10 +53,9 @@ early_kdump_load()
--command-line=$EARLY_KDUMP_CMDLINE --initrd=$EARLY_KDUMP_INITRD \
$EARLY_KDUMP_KERNEL"
$KEXEC ${EARLY_KEXEC_ARGS} $standard_kexec_args \
if $KEXEC $EARLY_KEXEC_ARGS $standard_kexec_args \
--command-line="$EARLY_KDUMP_CMDLINE" \
--initrd=$EARLY_KDUMP_INITRD $EARLY_KDUMP_KERNEL
if [ $? == 0 ]; then
--initrd=$EARLY_KDUMP_INITRD $EARLY_KDUMP_KERNEL; then
dinfo "kexec: loaded early-kdump kernel"
return 0
else

View File

@ -1,10 +1,3 @@
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
# This service will run the real kdump error handler code. Executing the
# failure action configured in kdump.conf
@ -13,20 +6,21 @@ Description=Kdump Error Handler
DefaultDependencies=no
After=systemd-vconsole-setup.service
Wants=systemd-vconsole-setup.service
AllowIsolate=yes
[Service]
Environment=HOME=/
Environment=DRACUT_SYSTEMD=1
Environment=NEWROOT=/sysroot
WorkingDirectory=/
ExecStart=/bin/kdump-error-handler.sh
ExecStart=/bin/kdump.sh --error-handler
ExecStopPost=-/bin/rm -f -- /.console_lock
Type=oneshot
StandardInput=tty-force
StandardOutput=inherit
StandardError=inherit
KillMode=process
IgnoreSIGPIPE=no
TasksMax=infinity
# Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash
# terminates cleanly.

674
dracut-kdump.sh Executable file
View File

@ -0,0 +1,674 @@
#!/bin/sh
#
# The main kdump routine in capture kernel, bash may not be the
# default shell. Any code added must be POSIX compliant.
. /lib/dracut-lib.sh
. /lib/kdump-logger.sh
. /lib/kdump-lib-initramfs.sh
#initiate the kdump logger
if ! dlog_init; then
echo "failed to initiate the kdump logger."
exit 1
fi
KDUMP_PATH="/var/crash"
KDUMP_LOG_FILE="/run/initramfs/kexec-dmesg.log"
KDUMP_TEST_ID=""
KDUMP_TEST_STATUS=""
CORE_COLLECTOR=""
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)
HOST_IP='127.0.0.1'
DUMP_INSTRUCTION=""
SSH_KEY_LOCATION="/root/.ssh/kdump_id_rsa"
DD_BLKSIZE=512
FINAL_ACTION="systemctl reboot -f"
KDUMP_PRE=""
KDUMP_POST=""
NEWROOT="/sysroot"
OPALCORE="/sys/firmware/opal/mpipl/core"
KDUMP_CONF_PARSED="/tmp/kdump.conf.$$"
# POSIX doesn't have pipefail, only apply when using bash
# shellcheck disable=SC3040
[ -n "$BASH" ] && set -o pipefail
DUMP_RETVAL=0
kdump_read_conf > $KDUMP_CONF_PARSED
get_kdump_confs()
{
while read -r config_opt config_val; do
# remove inline comments after the end of a directive.
case "$config_opt" in
path)
KDUMP_PATH="$config_val"
;;
core_collector)
[ -n "$config_val" ] && CORE_COLLECTOR="$config_val"
;;
sshkey)
if [ -f "$config_val" ]; then
SSH_KEY_LOCATION=$config_val
fi
;;
kdump_pre)
KDUMP_PRE="$config_val"
;;
kdump_post)
KDUMP_POST="$config_val"
;;
fence_kdump_args)
FENCE_KDUMP_ARGS="$config_val"
;;
fence_kdump_nodes)
FENCE_KDUMP_NODES="$config_val"
;;
failure_action | default)
case $config_val in
shell)
FAILURE_ACTION="kdump_emergency_shell"
;;
reboot)
FAILURE_ACTION="systemctl reboot -f && exit"
;;
halt)
FAILURE_ACTION="halt && exit"
;;
poweroff)
FAILURE_ACTION="systemctl poweroff -f && exit"
;;
dump_to_rootfs)
FAILURE_ACTION="dump_to_rootfs"
;;
esac
;;
final_action)
case $config_val in
reboot)
FINAL_ACTION="systemctl reboot -f"
;;
halt)
FINAL_ACTION="halt"
;;
poweroff)
FINAL_ACTION="systemctl poweroff -f"
;;
esac
;;
esac
done < "$KDUMP_CONF_PARSED"
if [ -z "$CORE_COLLECTOR" ]; then
CORE_COLLECTOR="$DEFAULT_CORE_COLLECTOR"
if is_ssh_dump_target || is_raw_dump_target; then
CORE_COLLECTOR="$CORE_COLLECTOR -F"
fi
fi
}
# 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
chmod 600 $KDUMP_LOG_FILE
}
# $1: dump path, must be a mount point
dump_fs()
{
ddebug "dump_fs _mp=$1"
if ! is_mounted "$1"; then
dinfo "dump path '$1' is not mounted, trying to mount..."
if ! mount --target "$1"; then
derror "failed to dump to '$1', it's not a mount point!"
return 1
fi
fi
# Remove -F in makedumpfile case. We don't want a flat format dump here.
case $CORE_COLLECTOR in
*makedumpfile*)
CORE_COLLECTOR=$(echo "$CORE_COLLECTOR" | sed -e "s/-F//g")
;;
esac
if [ -z "$KDUMP_TEST_ID" ]; then
_dump_fs_path=$(echo "$1/$KDUMP_PATH/$HOST_IP-$DATEDIR/" | tr -s /)
else
_dump_fs_path=$(echo "$1/$KDUMP_PATH/" | tr -s /)
fi
dinfo "saving to $_dump_fs_path"
# Only remount to read-write mode if the dump target is mounted read-only.
_dump_mnt_op=$(get_mount_info OPTIONS target "$1" -f)
case $_dump_mnt_op in
ro*)
dinfo "Remounting the dump target in rw mode."
mount -o remount,rw "$1" || return 1
;;
esac
mkdir -p "$_dump_fs_path" || return 1
save_vmcore_dmesg_fs ${DMESG_COLLECTOR} "$_dump_fs_path"
save_opalcore_fs "$_dump_fs_path"
dinfo "saving vmcore"
$CORE_COLLECTOR /proc/vmcore "$_dump_fs_path/vmcore-incomplete"
_dump_exitcode=$?
if [ $_dump_exitcode -eq 0 ]; then
sync -f "$_dump_fs_path/vmcore-incomplete"
_sync_exitcode=$?
if [ $_sync_exitcode -eq 0 ]; then
mv "$_dump_fs_path/vmcore-incomplete" "$_dump_fs_path/vmcore"
dinfo "saving vmcore complete"
else
derror "sync vmcore failed, exitcode:$_sync_exitcode"
return 1
fi
else
derror "saving vmcore failed, exitcode:$_dump_exitcode"
fi
dinfo "saving the $KDUMP_LOG_FILE to $_dump_fs_path/"
save_log
mv "$KDUMP_LOG_FILE" "$_dump_fs_path/"
if [ $_dump_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
}
# $1: dmesg collector
# $2: dump path
save_vmcore_dmesg_fs()
{
dinfo "saving vmcore-dmesg.txt to $2"
if $1 /proc/vmcore > "$2/vmcore-dmesg-incomplete.txt"; then
mv "$2/vmcore-dmesg-incomplete.txt" "$2/vmcore-dmesg.txt"
chmod 600 "$2/vmcore-dmesg.txt"
# Make sure file is on disk. There have been instances where later
# saving vmcore failed and system rebooted without sync and there
# was no vmcore-dmesg.txt available.
sync
dinfo "saving vmcore-dmesg.txt complete"
else
if [ -f "$2/vmcore-dmesg-incomplete.txt" ]; then
chmod 600 "$2/vmcore-dmesg-incomplete.txt"
fi
derror "saving vmcore-dmesg.txt failed"
fi
}
# $1: dump path
save_opalcore_fs()
{
if [ ! -f $OPALCORE ]; then
# Check if we are on an old kernel that uses a different path
if [ -f /sys/firmware/opal/core ]; then
OPALCORE="/sys/firmware/opal/core"
else
return 0
fi
fi
dinfo "saving opalcore:$OPALCORE to $1/opalcore"
if ! cp $OPALCORE "$1/opalcore"; then
derror "saving opalcore failed"
return 1
fi
sync
dinfo "saving opalcore complete"
return 0
}
dump_to_rootfs()
{
if [ "$(systemctl status dracut-initqueue | sed -n "s/^\s*Active: \(\S*\)\s.*$/\1/p")" = "inactive" ]; then
dinfo "Trying to bring up initqueue for rootfs mount"
systemctl start dracut-initqueue
fi
dinfo "Clean up dead systemd services"
systemctl cancel
dinfo "Waiting for rootfs mount, will timeout after 90 seconds"
systemctl start --no-block sysroot.mount
_loop=0
while [ $_loop -lt 90 ] && ! is_mounted /sysroot; do
sleep 1
_loop=$((_loop + 1))
done
if ! is_mounted /sysroot; then
derror "Failed to mount rootfs"
return
fi
ddebug "NEWROOT=$NEWROOT"
dump_fs $NEWROOT
}
kdump_emergency_shell()
{
ddebug "Switching to kdump emergency shell..."
[ -f /etc/profile ] && . /etc/profile
export PS1='kdump:${PWD}# '
. /lib/dracut-lib.sh
if [ -f /dracut-state.sh ]; then
. /dracut-state.sh 2> /dev/null
fi
source_conf /etc/conf.d
type plymouth > /dev/null 2>&1 && plymouth quit
source_hook "emergency"
while read -r _tty rest; do
(
echo
echo
echo 'Entering kdump emergency mode.'
echo 'Type "journalctl" to view system logs.'
echo 'Type "rdsosreport" to generate a sosreport, you can then'
echo 'save it elsewhere and attach it to a bug report.'
echo
echo
) > "/dev/$_tty"
done < /proc/consoles
sh -i -l
/bin/rm -f -- /.console_lock
}
do_failure_action()
{
dinfo "Executing failure action $FAILURE_ACTION"
eval $FAILURE_ACTION
}
do_final_action()
{
dinfo "Executing final action $FINAL_ACTION"
eval $FINAL_ACTION
}
do_dump()
{
eval $DUMP_INSTRUCTION
_ret=$?
if [ $_ret -ne 0 ]; then
derror "saving vmcore failed"
fi
return $_ret
}
do_kdump_pre()
{
if [ -n "$KDUMP_PRE" ]; then
"$KDUMP_PRE"
_ret=$?
if [ $_ret -ne 0 ]; then
derror "$KDUMP_PRE exited with $_ret status"
return $_ret
fi
fi
# if any script fails, it just raises warning and continues
if [ -d /etc/kdump/pre.d ]; then
for file in /etc/kdump/pre.d/*; do
"$file"
_ret=$?
if [ $_ret -ne 0 ]; then
derror "$file exited with $_ret status"
fi
done
fi
return 0
}
do_kdump_post()
{
if [ -d /etc/kdump/post.d ]; then
for file in /etc/kdump/post.d/*; do
"$file" "$1"
_ret=$?
if [ $_ret -ne 0 ]; then
derror "$file exited with $_ret status"
fi
done
fi
if [ -n "$KDUMP_POST" ]; then
"$KDUMP_POST" "$1"
_ret=$?
if [ $_ret -ne 0 ]; then
derror "$KDUMP_POST exited with $_ret status"
fi
fi
}
# $1: block target, eg. /dev/sda
dump_raw()
{
[ -b "$1" ] || return 1
dinfo "saving to raw disk $1"
if ! echo "$CORE_COLLECTOR" | grep -q makedumpfile; then
_src_size=$(stat --format %s /proc/vmcore)
_src_size_mb=$((_src_size / 1048576))
/kdumpscripts/monitor_dd_progress $_src_size_mb &
fi
dinfo "saving vmcore"
$CORE_COLLECTOR /proc/vmcore | dd of="$1" bs=$DD_BLKSIZE >> /tmp/dd_progress_file 2>&1 || return 1
sync
dinfo "saving vmcore complete"
return 0
}
# $1: ssh key file
# $2: ssh address in <user>@<host> format
dump_ssh()
{
_ret=0
_ssh_opt="-i $1 -o BatchMode=yes -o StrictHostKeyChecking=yes"
if [ -z "$KDUMP_TEST_ID" ]; then
_ssh_dir="$KDUMP_PATH/$HOST_IP-$DATEDIR"
else
_ssh_dir="$KDUMP_PATH"
fi
if is_ipv6_address "$2"; then
_scp_address=${2%@*}@"[${2#*@}]"
else
_scp_address=$2
fi
dinfo "saving to $2:$_ssh_dir"
cat /var/lib/random-seed > /dev/urandom
ssh -q $_ssh_opt "$2" mkdir -p "$_ssh_dir" || return 1
save_vmcore_dmesg_ssh "$DMESG_COLLECTOR" "$_ssh_dir" "$_ssh_opt" "$2"
dinfo "saving vmcore"
save_opalcore_ssh "$_ssh_dir" "$_ssh_opt" "$2" "$_scp_address"
if [ "${CORE_COLLECTOR%%[[:blank:]]*}" = "scp" ]; then
scp -q $_ssh_opt /proc/vmcore "$_scp_address:$_ssh_dir/vmcore-incomplete"
_ret=$?
_vmcore="vmcore"
else
$CORE_COLLECTOR /proc/vmcore | ssh $_ssh_opt "$2" "umask 0077 && dd bs=512 of='$_ssh_dir/vmcore-incomplete'"
_ret=$?
_vmcore="vmcore.flat"
fi
if [ $_ret -eq 0 ]; then
ssh $_ssh_opt "$2" "mv '$_ssh_dir/vmcore-incomplete' '$_ssh_dir/$_vmcore'"
_ret=$?
if [ $_ret -ne 0 ]; then
derror "moving vmcore failed, exitcode:$_ret"
else
dinfo "saving vmcore complete"
fi
else
derror "saving vmcore failed, exitcode:$_ret"
fi
dinfo "saving the $KDUMP_LOG_FILE to $2:$_ssh_dir/"
save_log
if ! scp -q $_ssh_opt $KDUMP_LOG_FILE "$_scp_address:$_ssh_dir/"; then
derror "saving log file failed, _exitcode:$_ret"
fi
return $_ret
}
# $1: dump path
# $2: ssh opts
# $3: ssh address in <user>@<host> format
# $4: scp address, similar with ssh address but IPv6 addresses are quoted
save_opalcore_ssh()
{
if [ ! -f $OPALCORE ]; then
# Check if we are on an old kernel that uses a different path
if [ -f /sys/firmware/opal/core ]; then
OPALCORE="/sys/firmware/opal/core"
else
return 0
fi
fi
dinfo "saving opalcore:$OPALCORE to $3:$1"
if ! scp $2 $OPALCORE "$4:$1/opalcore-incomplete"; then
derror "saving opalcore failed"
return 1
fi
ssh $2 "$3" mv "$1/opalcore-incomplete" "$1/opalcore"
dinfo "saving opalcore complete"
return 0
}
# $1: dmesg collector
# $2: dump path
# $3: ssh opts
# $4: ssh address in <user>@<host> format
save_vmcore_dmesg_ssh()
{
dinfo "saving vmcore-dmesg.txt to $4:$2"
if $1 /proc/vmcore | ssh $3 "$4" "umask 0077 && dd of='$2/vmcore-dmesg-incomplete.txt'"; then
ssh -q $3 "$4" mv "$2/vmcore-dmesg-incomplete.txt" "$2/vmcore-dmesg.txt"
dinfo "saving vmcore-dmesg.txt complete"
else
derror "saving vmcore-dmesg.txt failed"
fi
}
wait_online_network()
{
# In some cases, network may still not be ready because nm-online is called
# with "-s" which means to wait for NetworkManager startup to complete, rather
# than waiting for network connectivity specifically. Wait 10mins more for the
# network to be truely ready in these cases.
_loop=0
while [ $_loop -lt 600 ]; do
sleep 1
_loop=$((_loop + 1))
if _route=$(kdump_get_ip_route "$1" 2> /dev/null); then
printf "%s" "$_route"
return
else
dwarn "Waiting for network to be ready (${_loop}s / 10min)"
fi
done
derror "Oops. The network still isn't ready after waiting 10mins."
exit 1
}
get_host_ip()
{
if ! is_nfs_dump_target && ! is_ssh_dump_target; then
return 0
fi
_kdump_remote_ip=$(getarg kdump_remote_ip=)
if [ -z "$_kdump_remote_ip" ]; then
derror "failed to get remote IP address!"
return 1
fi
if ! _route=$(wait_online_network "$_kdump_remote_ip"); then
return 1
fi
_netdev=$(kdump_get_ip_route_field "$_route" "dev")
if ! _kdumpip=$(ip addr show dev "$_netdev" | grep '[ ]*inet'); then
derror "Failed to get IP of $_netdev"
return 1
fi
_kdumpip=$(echo "$_kdumpip" | head -n 1 | awk '{print $2}')
_kdumpip="${_kdumpip%%/*}"
HOST_IP=$_kdumpip
}
read_kdump_confs()
{
if [ ! -f "$KDUMP_CONFIG_FILE" ]; then
derror "$KDUMP_CONFIG_FILE not found"
return
fi
get_kdump_confs
# rescan for add code for dump target
while read -r config_opt config_val; do
# remove inline comments after the end of a directive.
case "$config_opt" in
dracut_args)
config_val=$(get_dracut_args_target "$config_val")
if [ -n "$config_val" ]; then
config_val=$(get_mntpoint_from_target "$config_val")
DUMP_INSTRUCTION="dump_fs $config_val"
fi
;;
ext[234] | xfs | btrfs | minix | nfs | virtiofs)
config_val=$(get_mntpoint_from_target "$config_val")
DUMP_INSTRUCTION="dump_fs $config_val"
;;
raw)
DUMP_INSTRUCTION="dump_raw $config_val"
;;
ssh)
DUMP_INSTRUCTION="dump_ssh $SSH_KEY_LOCATION $config_val"
;;
esac
done < "$KDUMP_CONF_PARSED"
}
fence_kdump_notify()
{
if [ -n "$FENCE_KDUMP_NODES" ]; then
# shellcheck disable=SC2086
$FENCE_KDUMP_SEND $FENCE_KDUMP_ARGS $FENCE_KDUMP_NODES &
fi
}
kdump_test_set_status() {
_status="$1"
[ -n "$KDUMP_TEST_STATUS" ] || return
case "$_status" in
success|fail) ;;
*)
derror "Unknown test status $_status"
return 1
;;
esac
if is_ssh_dump_target; then
_ssh_opts="-i $SSH_KEY_LOCATION -o BatchMode=yes -o StrictHostKeyChecking=yes"
_ssh_host=$(echo "$DUMP_INSTRUCTION" | awk '{print $3}')
ssh -q $_ssh_opts "$_ssh_host" "mkdir -p ${KDUMP_TEST_STATUS%/*}" \
|| return 1
ssh -q $_ssh_opts "$_ssh_host" "echo $_status kdump_test_id=$KDUMP_TEST_ID > $KDUMP_TEST_STATUS" \
|| return 1
else
_target=$(echo "$DUMP_INSTRUCTION" | awk '{print $2}')
mkdir -p "$_target/$KDUMP_PATH" || return 1
echo "$_status kdump_test_id=$KDUMP_TEST_ID" > "$_target/$KDUMP_TEST_STATUS"
sync -f "$_target/$KDUMP_TEST_STATUS"
fi
}
kdump_test_init() {
is_raw_dump_target && return
KDUMP_TEST_ID=$(getarg kdump_test_id=)
[ -z "$KDUMP_TEST_ID" ] && return
KDUMP_PATH="$KDUMP_PATH/kdump-test-$KDUMP_TEST_ID"
KDUMP_TEST_STATUS="$KDUMP_PATH/vmcore-creation.status"
kdump_test_set_status 'fail'
}
if [ "$1" = "--error-handler" ]; then
get_kdump_confs
do_failure_action
do_final_action
exit $?
fi
# continue here only if we have to save dump.
if [ -f /etc/fadump.initramfs ] && [ ! -f /proc/device-tree/rtas/ibm,kernel-dump ] && [ ! -f /proc/device-tree/ibm,opal/dump/mpipl-boot ]; then
exit 0
fi
read_kdump_confs
fence_kdump_notify
if ! get_host_ip; then
derror "get_host_ip exited with non-zero status!"
exit 1
fi
if [ -z "$DUMP_INSTRUCTION" ]; then
DUMP_INSTRUCTION="dump_fs $NEWROOT"
fi
kdump_test_init
if ! do_kdump_pre; then
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
fi
make_trace_mem "kdump saving vmcore" '1:shortmem' '2+:mem' '3+:slab'
do_dump
DUMP_RETVAL=$?
if ! do_kdump_post $DUMP_RETVAL; then
derror "kdump_post script exited with non-zero status!"
fi
if [ $DUMP_RETVAL -ne 0 ]; then
exit 1
fi
kdump_test_set_status "success"
do_final_action

1195
dracut-module-setup.sh Executable file

File diff suppressed because it is too large Load Diff

View File

@ -39,7 +39,7 @@ kernel are one and the same on ppc64.
If you're reading this document, you should already have kexec-tools
installed. If not, you install it via the following command:
# yum install kexec-tools
# dnf install kexec-tools
Fadump Operational Flow:
@ -82,7 +82,7 @@ How to configure fadump:
Again, we assume if you're reading this document, you should already have
kexec-tools installed. If not, you install it via the following command:
# yum install kexec-tools
# dnf install kexec-tools
Make the kernel to be configured with FADump as the default boot entry, if
it isn't already:
@ -94,20 +94,24 @@ anything interesting in the way of debug analysis, you'll also need to install
the kernel-debuginfo package, of the same arch as your running kernel, and the
crash utility:
# yum --enablerepo=\*debuginfo install kernel-debuginfo.$(uname -m) crash
# dnf --enablerepo=\*debuginfo install kernel-debuginfo.$(uname -m) crash
Next up, we need to modify some boot parameters to enable firmware assisted
dump. With the help of grubby, it's very easy to append "fadump=on" to the end
of your kernel boot parameters. To reserve the appropriate amount of memory
for boot memory preservation, pass 'crashkernel=X' kernel cmdline parameter.
For the recommended value of X, see 'FADump Memory Requirements' section.
Next up, we can enable firmware assisted dump and reserve the memory for boot
memory preservation as specified in in the table of 'FADump Memory Requirements'
section:
# kdumpctl reset-crashkernel --fadump=on
Alternatively, you can use grubby to reserve custom amount of memory:
# 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'.
linux kernel with 'fadump=nocma' instead of 'fadump=on':
# kdumpctl reset-crashkernel --fadump=nocma
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,
@ -133,7 +137,7 @@ Then, start up kdump as well:
# systemctl start kdump.service
This should turn on the firmware assisted functionality in kernel by
echo'ing 1 to /sys/kernel/fadump_registered, leaving the system ready
echo'ing 1 to /sys/kernel/fadump/registered, leaving the system ready
to capture a vmcore upon crashing. For journaling filesystems like XFS an
additional step is required to ensure bootloader does not pick the
older initrd (without vmcore capture scripts):
@ -315,7 +319,27 @@ Advanced Setups & Failure action:
Kdump and fadump exhibit similar behavior in terms of setup & failure action.
For fadump advanced setup related information see section "Advanced Setups" in
"kexec-kdump-howto.txt" document. Refer to "Failure action" section in "kexec-
kdump-howto.txt" document for fadump failure action related information.
kdump-howto.txt" document for fadump failure action related information. Note
that the below options from /etc/sysconfig/kdump have no relevance to fadump
owing to the way it operates:
-KDUMP_BOOTDIR
-KDUMP_IMG
-KDUMP_IMG_EXT
-KEXEC_ARGS
-KDUMP_KERNELVER
-KDUMP_COMMANDLINE
-KDUMP_COMMANDLINE_REMOVE
-KDUMP_COMMANDLINE_APPEND
Passing additional parameters to fadump capture kerenl
-FADUMP_COMMANDLINE_APPEND
If a powerpc system supports passing additional parameters, it would have the
sysfs node '/sys/kernel/fadump/bootargs_append'. FADUMP_COMMANDLINE_APPEND
allows us to append arguments to fadump capture kernel, further to parameters
passed via the bootloader.
Compression and filtering
@ -327,11 +351,7 @@ Notes on rootfs mount:
Dracut is designed to mount rootfs by default. If rootfs mounting fails it
will refuse to go on. So fadump leaves rootfs mounting to dracut currently.
We make the assumtion that proper root= cmdline is being passed to dracut
initramfs for the time being. If you need modify "KDUMP_COMMANDLINE=" in
/etc/sysconfig/kdump, you will need to make sure that appropriate root=
options are copied from /proc/cmdline. In general it is best to append
command line options using "KDUMP_COMMANDLINE_APPEND=" instead of replacing
the original command line completely.
initramfs for the time being.
How to disable FADump:
@ -344,9 +364,12 @@ or
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):
Remove "crashkernel=" from kernel cmdline parameters:
# grubby --update-kernel=/boot/vmlinuz-$kver --args="crashkernl=auto"
# grubby --update-kernel=/boot/vmlinuz-`uname -r` --remove-args="crashkernel"
If KDump is to be used as the dump capturing mechanism, reset the crashkernel parameter:
# kdumpctl reset-crashkernel --fadump=off
Reboot the system for the settings to take effect.

6
gating.yaml Normal file
View File

@ -0,0 +1,6 @@
--- !Policy
product_versions:
- rhel-9
decision_context: osci_compose_gate
rules:
- !PassingTestCaseRule {test_case_name: kernel-qe.kernel-ci.general-kdump.tier0.functional}

View File

@ -1,7 +1,6 @@
#!/bin/bash
# $1: target arch
SED_EXP=""
generate()
@ -20,6 +19,12 @@ generate()
#
# Supported options:
#
# auto_reset_crashkernel <yes|no>
# - whether to reset kernel crashkernel to new default value
# or not when kexec-tools updates the default crashkernel value and
# existing kernels using the old default kernel crashkernel value.
# The default value is yes.
#
# raw <partition>
# - Will dd /proc/vmcore into <partition>.
# Use persistent device names for partition devices,
@ -41,11 +46,12 @@ generate()
#
# <fs type> <partition>
# - Will mount -t <fs type> <partition> <mnt>, and copy
# /proc/vmcore to <mnt>/<path>/%DATE/.
# /proc/vmcore to <mnt>/<path>/%HOST_IP-%DATE/.
# NOTE: <partition> can be a device node, label or uuid.
# It's recommended to use persistent device names
# such as /dev/vg/<devname>.
# Otherwise it's suggested to use label or uuid.
# Supported fs types: ext[234], xfs, btrfs, minix, virtiofs
#
# path <path>
# - "path" represents the file system path in which vmcore
@ -174,11 +180,13 @@ generate()
#ext4 /dev/vg/lv_kdump
#ext4 LABEL=/boot
#ext4 UUID=03138356-5e61-4ab3-b58e-27507ac41937
#virtiofs myfs
#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
auto_reset_crashkernel yes
path /var/crash
core_collector makedumpfile -l --message-level 7 -d 31
#core_collector scp
@ -201,20 +209,20 @@ update_param()
}
case "$1" in
aarch64)
;;
i386)
;;
ppc64)
;;
ppc64le)
;;
aarch64) ;;
i386) ;;
ppc64) ;;
ppc64le) ;;
s390x)
update_param core_collector \
"makedumpfile -c --message-level 7 -d 31"
;;
x86_64)
;;
x86_64) ;;
*)
echo "Warning: Unknown architecture '$1', using default kdump.conf template."
;;

188
kdump-lib-initramfs.sh Executable file
View File

@ -0,0 +1,188 @@
#!/bin/sh
#
# The code in this file will be used in initramfs environment, bash may
# not be the default shell. Any code added must be POSIX compliant.
DEFAULT_PATH="/var/crash/"
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"
# Read kdump config in well formated style
kdump_read_conf()
{
# Following steps are applied in order: strip trailing comment, strip trailing space,
# strip heading space, match non-empty line, remove duplicated spaces between conf name and value
[ -f "$KDUMP_CONFIG_FILE" ] && sed -n -e "s/#.*//;s/\s*$//;s/^\s*//;s/\(\S\+\)\s*\(.*\)/\1 \2/p" $KDUMP_CONFIG_FILE
}
# Retrieves config value defined in kdump.conf
# $1: config name, sed regexp compatible
kdump_get_conf_val()
{
# For lines matching "^\s*$1\s+", remove matched part (config name including space),
# remove tailing comment, space, then store in hold space. Print out the hold buffer on last line.
[ -f "$KDUMP_CONFIG_FILE" ] &&
sed -n -e "/^\s*\($1\)\s\+/{s/^\s*\($1\)\s\+//;s/#.*//;s/\s*$//;h};\${x;p}" $KDUMP_CONFIG_FILE
}
is_mounted()
{
findmnt -k -n "$1" > /dev/null 2>&1
}
# $1: info type
# $2: mount source type
# $3: mount source
# $4: extra args
get_mount_info()
{
__kdump_mnt=$(findmnt -k -n -r -o "$1" "--$2" "$3" $4)
[ -z "$__kdump_mnt" ] && [ -e "/etc/fstab" ] && __kdump_mnt=$(findmnt -s -n -r -o "$1" "--$2" "$3" $4)
echo "$__kdump_mnt"
}
is_ipv6_address()
{
echo "$1" | grep -q ":"
}
is_fs_type_nfs()
{
[ "$1" = "nfs" ] || [ "$1" = "nfs4" ]
}
is_fs_type_virtiofs()
{
[ "$1" = "virtiofs" ]
}
# If $1 contains dracut_args "--mount", return <filesystem type>
get_dracut_args_fstype()
{
echo $1 | grep "\-\-mount" | sed "s/.*--mount .\(.*\)/\1/" | cut -d' ' -f3
}
# If $1 contains dracut_args "--mount", return <device>
get_dracut_args_target()
{
echo $1 | grep "\-\-mount" | sed "s/.*--mount .\(.*\)/\1/" | cut -d' ' -f1
}
get_save_path()
{
__kdump_path=$(kdump_get_conf_val path)
[ -z "$__kdump_path" ] && __kdump_path=$DEFAULT_PATH
# strip the duplicated "/"
echo "$__kdump_path" | tr -s /
}
get_root_fs_device()
{
findmnt -k -f -n -o SOURCE /
}
# Return the current underlying device of a path, ignore bind mounts
get_target_from_path()
{
__kdump_target=$(df "$1" 2> /dev/null | tail -1 | awk '{print $1}')
[ "$__kdump_target" = "/dev/root" ] && [ ! -e /dev/root ] && __kdump_target=$(get_root_fs_device)
echo "$__kdump_target"
}
get_fs_type_from_target()
{
get_mount_info FSTYPE source "$1" -f
}
get_mntpoint_from_target()
{
local _mntpoint
# get the first TARGET when SOURCE doesn't end with ].
# In most cases, a SOURCE ends with ] when fsroot or subvol exists.
_mntpoint=$(get_mount_info TARGET,SOURCE source "$1" | grep -v "\]$" | awk 'NR==1 { print $1 }')
# fallback to the old way when _mntpoint is empty.
[[ -n "$_mntpoint" ]] || _mntpoint=$(get_mount_info TARGET source "$1" -f )
echo $_mntpoint
}
is_ssh_dump_target()
{
kdump_get_conf_val ssh | grep -q @
}
is_raw_dump_target()
{
[ -n "$(kdump_get_conf_val raw)" ]
}
is_virtiofs_dump_target()
{
if [ -n "$(kdump_get_conf_val virtiofs)" ]; then
return 0
fi
if is_fs_type_virtiofs "$(get_dracut_args_fstype "$(kdump_get_conf_val dracut_args)")"; then
return 0
fi
if is_fs_type_virtiofs "$(get_fs_type_from_target "$(get_target_from_path "$(get_save_path)")")"; then
return 0
fi
return 1
}
is_nfs_dump_target()
{
if [ -n "$(kdump_get_conf_val nfs)" ]; then
return 0
fi
if is_fs_type_nfs "$(get_dracut_args_fstype "$(kdump_get_conf_val dracut_args)")"; then
return 0
fi
if is_fs_type_nfs "$(get_fs_type_from_target "$(get_target_from_path "$(get_save_path)")")"; then
return 0
fi
return 1
}
fs_dump_target()
{
kdump_get_conf_val "ext[234]\|xfs\|btrfs\|minix\|virtiofs"
}
is_fs_dump_target()
{
[ -n "$(fs_dump_target)" ]
}
is_lvm2_thinp_device()
{
_device_path=$1
_lvm2_thin_device=$(lvm lvs -S 'lv_layout=sparse && lv_layout=thin' \
--nosuffix --noheadings -o vg_name,lv_name "$_device_path" 2> /dev/null)
[ -n "$_lvm2_thin_device" ]
}
kdump_get_ip_route()
{
if ! _route=$(/sbin/ip -o route get to "$1" 2>&1); then
exit 1
fi
echo "$_route"
}
kdump_get_ip_route_field()
{
echo "$1" | sed -n -e "s/^.*\<$2\>\s\+\(\S\+\).*$/\1/p"
}

1249
kdump-lib.sh Executable file

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
#!/bin/bash
#!/bin/sh
#
# This comes from the dracut-logger.sh
#
@ -34,6 +34,8 @@
# 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!
#
# The code in this file might be run in an environment without bash.
# Any code added must be POSIX compliant.
# Define vairables for the log levels in this module.
kdump_stdloglvl=""
@ -53,11 +55,12 @@ fi
#
get_kdump_loglvl()
{
(type -p getarg) && kdump_sysloglvl=$(getarg rd.kdumploglvl)
[ -f /lib/dracut-lib.sh ] && kdump_sysloglvl=$(getarg rd.kdumploglvl)
[ -z "$kdump_sysloglvl" ] && return 1;
(type -p isdigit) && isdigit $kdump_sysloglvl
[ $? -ne 0 ] && return 1;
if [ -f /lib/dracut-lib.sh ] && ! isdigit "$kdump_sysloglvl"; then
return 1
fi
return 0
}
@ -83,11 +86,10 @@ check_loglvl()
# @retval 0 on success.
#
dlog_init() {
local ret=0; local errmsg
ret=0
if [ -s /proc/vmcore ];then
get_kdump_loglvl
if [ $? -ne 0 ];then
if ! get_kdump_loglvl; then
logger -t "kdump[$$]" -p warn -- "Kdump is using the default log level(3)."
kdump_sysloglvl=3
fi
@ -104,8 +106,7 @@ dlog_init() {
[ -z "$kdump_kmsgloglvl" ] && kdump_kmsgloglvl=0
for loglvl in "$kdump_stdloglvl" "$kdump_kmsgloglvl" "$kdump_sysloglvl"; do
check_loglvl "$loglvl"
if [ $? -ne 0 ]; then
if ! check_loglvl "$loglvl"; then
echo "Illegal log level: $kdump_stdloglvl $kdump_kmsgloglvl $kdump_sysloglvl"
return 1
fi
@ -114,21 +115,21 @@ dlog_init() {
# Skip initialization if it's already done.
[ -n "$kdump_maxloglvl" ] && return 0
if [[ $UID -ne 0 ]]; then
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
if [ "$kdump_sysloglvl" -gt 0 ]; then
if [ -d /run/systemd/journal ] \
&& systemd-cat --version 1>/dev/null 2>&1 \
&& systemctl --quiet is-active systemd-journald.socket 1>/dev/null 2>&1; then
readonly _systemdcatfile="/var/tmp/systemd-cat"
mkfifo "$_systemdcatfile" &>/dev/null
mkfifo "$_systemdcatfile" 1>/dev/null 2>&1
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
elif ! [ -S /dev/log ] && [ -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
@ -137,31 +138,31 @@ dlog_init() {
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
kdump_maxloglvl=0
for _dlog_lvl in $kdump_stdloglvl $kdump_sysloglvl $kdump_kmsgloglvl; do
[ $_dlog_lvl -gt $kdump_maxloglvl ] && kdump_maxloglvl=$_dlog_lvl
done
readonly kdump_maxloglvl=$maxloglvl_l
readonly kdump_maxloglvl
export kdump_maxloglvl
if [[ $kdump_stdloglvl -lt 4 ]] && [[ $kdump_kmsgloglvl -lt 4 ]] && [[ $kdump_sysloglvl -lt 4 ]]; then
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
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
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
if [ $kdump_stdloglvl -lt 1 ] && [ $kdump_kmsgloglvl -lt 1 ] && [ $kdump_sysloglvl -lt 1 ]; then
unset derror
derror() { :; };
fi
@ -173,7 +174,7 @@ dlog_init() {
## @brief Converts numeric level to logger priority defined by POSIX.2.
#
# @param lvl Numeric logging level in range from 1 to 4.
# @param $1: 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.
@ -189,7 +190,7 @@ _lvl2syspri() {
## @brief Converts logger numeric level to syslog log level
#
# @param lvl Numeric logging level in range from 1 to 4.
# @param $1: 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
@ -209,27 +210,25 @@ _lvl2syspri() {
#
# @see /usr/include/sys/syslog.h
_dlvl2syslvl() {
local lvl
case "$1" in
1) lvl=3;;
2) lvl=4;;
3) lvl=6;;
4) lvl=7;;
1) set -- 3;;
2) set -- 4;;
3) set -- 6;;
4) set -- 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))
echo $((24 + $1))
}
## @brief Prints to stderr, to syslog and/or /dev/kmsg given message with
# given level (priority).
#
# @param lvl Numeric logging level.
# @param msg Message.
# @param $1: Numeric logging level.
# @param $2: Message.
# @retval 0 It's always returned, even if logging failed.
#
# @note This function is not supposed to be called manually. Please use
@ -251,27 +250,24 @@ _dlvl2syslvl() {
# - @c INFO to @c info
# - @c DEBUG to @c debug
_do_dlog() {
local lvl="$1"; shift
local msg="$*"
[ "$1" -le $kdump_stdloglvl ] && printf -- 'kdump: %s\n' "$2" >&2
[[ $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
if [ "$1" -le $kdump_sysloglvl ]; then
if [ "$_dlogfd" ]; then
printf -- "<%s>%s\n" "$(($(_dlvl2syslvl "$1") & 7))" "$2" 1>&$_dlogfd
else
logger -t "kdump[$$]" -p $(_lvl2syspri $lvl) -- "$msg"
logger -t "kdump[$$]" -p "$(_lvl2syspri "$1")" -- "$2"
fi
fi
[[ $lvl -le $kdump_kmsgloglvl ]] && \
echo "<$(_dlvl2syslvl $lvl)>kdump[$$] $msg" >/dev/kmsg
[ "$1" -le $kdump_kmsgloglvl ] && \
echo "<$(_dlvl2syslvl "$1")>kdump[$$] $2" >/dev/kmsg
}
## @brief Internal helper function for _do_dlog()
#
# @param lvl Numeric logging level.
# @param msg Message.
# @param $1: Numeric logging level.
# @param $2 [...]: Message.
# @retval 0 It's always returned, even if logging failed.
#
# @note This function is not supposed to be called manually. Please use
@ -286,12 +282,13 @@ _do_dlog() {
# echo "This is a warning" | dwarn
dlog() {
[ -z "$kdump_maxloglvl" ] && return 0
[[ $1 -le $kdump_maxloglvl ]] || return 0
[ "$1" -le "$kdump_maxloglvl" ] || return 0
if [[ $# -gt 1 ]]; then
_do_dlog "$@"
if [ $# -gt 1 ]; then
_dlog_lvl=$1; shift
_do_dlog "$_dlog_lvl" "$*"
else
while read line || [ -n "$line" ]; do
while read -r line || [ -n "$line" ]; do
_do_dlog "$1" "$line"
done
fi
@ -304,7 +301,9 @@ dlog() {
ddebug() {
set +x
dlog 4 "$@"
[ -n "$debug" ] && set -x || :
if [ -n "$debug" ]; then
set -x
fi
}
## @brief Logs message at INFO level (3)
@ -314,7 +313,9 @@ ddebug() {
dinfo() {
set +x
dlog 3 "$@"
[ -n "$debug" ] && set -x || :
if [ -n "$debug" ]; then
set -x
fi
}
## @brief Logs message at WARN level (2)
@ -324,7 +325,9 @@ dinfo() {
dwarn() {
set +x
dlog 2 "$@"
[ -n "$debug" ] && set -x || :
if [ -n "$debug" ]; then
set -x
fi
}
## @brief It's an alias to dwarn() function.
@ -334,7 +337,9 @@ dwarn() {
dwarning() {
set +x
dwarn "$@"
[ -n "$debug" ] && set -x || :
if [ -n "$debug" ]; then
set -x
fi
}
## @brief Logs message at ERROR level (1)
@ -344,5 +349,7 @@ dwarning() {
derror() {
set +x
dlog 1 "$@"
[ -n "$debug" ] && set -x || :
if [ -n "$debug" ]; then
set -x
fi
}

View File

@ -26,6 +26,24 @@ understand how this configuration file affects the behavior of kdump.
.SH OPTIONS
.B auto_reset_crashkernel <yes|no>
.RS
determine whether to reset kernel crashkernel parameter to the default value
or not when kexec-tools is updated or a new kernel is installed. The default
crashkernel values are different for different architectures and also take the
following factors into consideration,
- AMD Secure Memory Encryption (SME) and Secure Encrypted Virtualization (SEV)
- Mellanox 5th generation network driver
- aarch64 64k kernel
- Firmware-assisted dump (FADump)
Since the kernel crasherkernel parameter will be only reset when kexec-tools is
updated or a new kernel is installed, you need to call "kdumpctl
reset-crashkernel [--kernel=path_to_kernel]" if you want to use the default
value set after having enabled features like SME/SEV for a specific kernel. And
you should also reboot the system for the new crashkernel value to take effect.
Also see kdumpctl(8).
.B raw <partition>
.RS
Will dd /proc/vmcore into <partition>. Use persistent device names for
@ -41,7 +59,7 @@ mount point.
.B ssh <user@server>
.RS
Will scp /proc/vmcore to <user@server>:<path>/%HOST-%DATE/,
Will save /proc/vmcore through ssh pipe to <user@server>:<path>/%HOST-%DATE/,
supports DNS. NOTE: make sure user has necessary write permissions on
server and that a fqdn is used as the server name.
.RE
@ -55,7 +73,7 @@ The default value is /root/.ssh/kdump_id_rsa.
.B <fs type> <partition>
.RS
Will mount -t <fs type> <partition> <mnt>, and copy /proc/vmcore to
<mnt>/<path>/%DATE/. NOTE: <partition> can be a device node, label
<mnt>/<path>/%HOST_IP-%DATE/. NOTE: <partition> can be a device node, label
or uuid. It's recommended to use persistent device names such as
/dev/vg/<devname>. Otherwise it's suggested to use label or uuid.
.RE
@ -121,7 +139,7 @@ specified kdump_post parameter is executed.
Note that scripts written for use with this directive must use the /bin/bash
interpreter. And since these scripts run in kdump enviroment, the reference to
the storage or network device in the scripts should adhere to the section
\'Supported dump target types and requirements\' in kexec-kdump-howto.txt.
'Supported dump target types and requirements' in kexec-kdump-howto.txt.
.RE
@ -145,7 +163,7 @@ returns non 0 exit status, the processing is continued.
Note that scripts written for use with this directive must use the /bin/bash
interpreter. And since these scripts run in kdump enviroment, the reference to
the storage or network device in the scripts should adhere to the section
\'Supported dump target types and requirements\' in kexec-kdump-howto.txt.
'Supported dump target types and requirements' in kexec-kdump-howto.txt.
.RE
@ -296,7 +314,7 @@ retaining blacklist option creates more confusing behavior. It has been
deprecated.
.PP
Instead, use rd.driver.blacklist option on second kernel to blacklist
a certain module. One can edit /etc/sysconfig/kdump and edit
a certain module. One can edit /etc/sysconfig/kdump.conf and edit
KDUMP_COMMANDLINE_APPEND to pass kernel command line options. Refer
to dracut.cmdline man page for more details on module blacklist option.
.RE

View File

@ -2,15 +2,16 @@
Description=Crash recovery kernel arming
After=network.target network-online.target remote-fs.target basic.target
DefaultDependencies=no
ConditionKernelCommandLine=crashkernel
[Service]
Type=oneshot
ExecCondition=/bin/sh -c 'grep -q -e "crashkernel" -e "fadump" /proc/cmdline'
ExecStart=/usr/bin/kdumpctl start
ExecStop=/usr/bin/kdumpctl stop
ExecReload=/usr/bin/kdumpctl reload
RemainAfterExit=yes
StartLimitInterval=0
PrivateTmp=yes
[Install]
WantedBy=multi-user.target

View File

@ -17,11 +17,11 @@ KDUMP_COMMANDLINE=""
# This variable lets us remove arguments from the current kdump commandline
# as taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline
# NOTE: some arguments such as crashkernel will always be removed
KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet log_buf_len ignition.firstboot"
KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet log_buf_len swiotlb cma hugetlb_cma ignition.firstboot"
# This variable lets us append arguments to the current kdump commandline
# after processed by KDUMP_COMMANDLINE_REMOVE
KDUMP_COMMANDLINE_APPEND="irqpoll maxcpus=1 reset_devices novmcoredd"
KDUMP_COMMANDLINE_APPEND="irqpoll nr_cpus=1 reset_devices novmcoredd cma=0 hugetlb_cma=0"
# Any additional kexec arguments required. In most situations, this should
# be left empty

View File

@ -17,11 +17,11 @@ KDUMP_COMMANDLINE=""
# This variable lets us remove arguments from the current kdump commandline
# as taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline
# NOTE: some arguments such as crashkernel will always be removed
KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet log_buf_len swiotlb ignition.firstboot"
KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet log_buf_len swiotlb cma hugetlb_cma ignition.firstboot"
# This variable lets us append arguments to the current kdump commandline
# after processed by KDUMP_COMMANDLINE_REMOVE
KDUMP_COMMANDLINE_APPEND="irqpoll nr_cpus=1 reset_devices cgroup_disable=memory udev.children-max=2 panic=10 swiotlb=noforce novmcoredd"
KDUMP_COMMANDLINE_APPEND="irqpoll nr_cpus=1 reset_devices cgroup_disable=memory udev.children-max=2 panic=10 swiotlb=noforce novmcoredd cma=0 hugetlb_cma=0"
# Any additional kexec arguments required. In most situations, this should
# be left empty

View File

@ -17,11 +17,11 @@ KDUMP_COMMANDLINE=""
# This variable lets us remove arguments from the current kdump commandline
# as taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline
# NOTE: some arguments such as crashkernel will always be removed
KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet log_buf_len swiotlb ignition.firstboot"
KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet log_buf_len swiotlb cma hugetlb_cma ignition.firstboot"
# This variable lets us append arguments to the current kdump commandline
# after processed by KDUMP_COMMANDLINE_REMOVE
KDUMP_COMMANDLINE_APPEND="irqpoll nr_cpus=1 reset_devices numa=off udev.children-max=2 panic=10 rootflags=nofail transparent_hugepage=never novmcoredd"
KDUMP_COMMANDLINE_APPEND="irqpoll nr_cpus=1 reset_devices numa=off udev.children-max=2 panic=10 transparent_hugepage=never novmcoredd cma=0 hugetlb_cma=0"
# Any additional kexec arguments required. In most situations, this should
# be left empty
@ -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)

View File

@ -17,11 +17,11 @@ KDUMP_COMMANDLINE=""
# This variable lets us remove arguments from the current kdump commandline
# as taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline
# NOTE: some arguments such as crashkernel will always be removed
KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet log_buf_len swiotlb ignition.firstboot"
KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet log_buf_len swiotlb hugetlb_cma ignition.firstboot"
# This variable lets us append arguments to the current kdump commandline
# after processed by KDUMP_COMMANDLINE_REMOVE
KDUMP_COMMANDLINE_APPEND="irqpoll maxcpus=1 noirqdistrib reset_devices cgroup_disable=memory numa=off udev.children-max=2 ehea.use_mcs=0 panic=10 rootflags=nofail kvm_cma_resv_ratio=0 transparent_hugepage=never novmcoredd"
KDUMP_COMMANDLINE_APPEND="irqpoll nr_cpus=1 noirqdistrib reset_devices cgroup_disable=memory numa=off udev.children-max=2 ehea.use_mcs=0 panic=10 kvm_cma_resv_ratio=0 transparent_hugepage=never novmcoredd hugetlb_cma=0"
# Any additional kexec arguments required. In most situations, this should
# be left empty
@ -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:

View File

@ -17,18 +17,22 @@ KDUMP_COMMANDLINE=""
# This variable lets us remove arguments from the current kdump commandline
# as taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline
# NOTE: some arguments such as crashkernel will always be removed
KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet log_buf_len swiotlb ignition.firstboot"
KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet log_buf_len swiotlb hugetlb_cma ignition.firstboot"
# This variable lets us append arguments to the current kdump commandline
# after processed by KDUMP_COMMANDLINE_REMOVE
KDUMP_COMMANDLINE_APPEND="irqpoll maxcpus=1 noirqdistrib reset_devices cgroup_disable=memory numa=off udev.children-max=2 ehea.use_mcs=0 panic=10 rootflags=nofail kvm_cma_resv_ratio=0 transparent_hugepage=never novmcoredd"
KDUMP_COMMANDLINE_APPEND="irqpoll nr_cpus=1 noirqdistrib reset_devices cgroup_disable=memory numa=off udev.children-max=2 ehea.use_mcs=0 panic=10 kvm_cma_resv_ratio=0 transparent_hugepage=never novmcoredd hugetlb_cma=0"
# This variable lets us append arguments to fadump (powerpc) capture kernel,
# further to the parameters passed via the bootloader.
FADUMP_COMMANDLINE_APPEND="nr_cpus=16 numa=off cgroup_disable=memory cma=0 kvm_cma_resv_ratio=0 hugetlb_cma=0 transparent_hugepage=never novmcoredd udev.children-max=2"
# Any additional kexec arguments required. In most situations, this should
# be left empty
#
# Example:
# KEXEC_ARGS="--elf32-core-headers"
KEXEC_ARGS="--dt-no-old-root"
KEXEC_ARGS="--dt-no-old-root -s"
#Where to find the boot image
#KDUMP_BOOTDIR="/boot"
@ -39,6 +43,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:

View File

@ -17,11 +17,11 @@ KDUMP_COMMANDLINE=""
# This variable lets us remove arguments from the current kdump commandline
# as taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline
# NOTE: some arguments such as crashkernel will always be removed
KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet log_buf_len swiotlb prot_virt ignition.firstboot zfcp.allow_lun_scan"
KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet log_buf_len swiotlb vmcp_cma cma hugetlb_cma prot_virt ignition.firstboot zfcp.allow_lun_scan"
# This variable lets us append arguments to the current kdump commandline
# after processed by KDUMP_COMMANDLINE_REMOVE
KDUMP_COMMANDLINE_APPEND="nr_cpus=1 cgroup_disable=memory numa=off udev.children-max=2 panic=10 rootflags=nofail transparent_hugepage=never novmcoredd"
KDUMP_COMMANDLINE_APPEND="nr_cpus=1 cgroup_disable=memory numa=off udev.children-max=2 panic=10 transparent_hugepage=never novmcoredd vmcp_cma=0 cma=0 hugetlb_cma=0"
# Any additional /sbin/mkdumprd arguments required.
MKDUMPRD_ARGS=""
@ -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)

View File

@ -17,11 +17,11 @@ KDUMP_COMMANDLINE=""
# This variable lets us remove arguments from the current kdump commandline
# as taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline
# NOTE: some arguments such as crashkernel will always be removed
KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet log_buf_len swiotlb ignition.firstboot"
KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet log_buf_len swiotlb cma hugetlb_cma ignition.firstboot"
# This variable lets us append arguments to the current kdump commandline
# after processed by KDUMP_COMMANDLINE_REMOVE
KDUMP_COMMANDLINE_APPEND="irqpoll nr_cpus=1 reset_devices cgroup_disable=memory mce=off numa=off udev.children-max=2 panic=10 rootflags=nofail acpi_no_memhotplug transparent_hugepage=never nokaslr novmcoredd hest_disable"
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 cma=0 hugetlb_cma=0 pcie_ports=compat"
# Any additional kexec arguments required. In most situations, this should
# be left empty
@ -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)

2049
kdumpctl Executable file

File diff suppressed because it is too large Load Diff

85
kdumpctl.8 Normal file
View File

@ -0,0 +1,85 @@
.TH KDUMPCTL 8 2015-07-13 kexec-tools
.SH NAME
kdumpctl \- control interface for kdump
.SH SYNOPSIS
.B kdumpctl
.I COMMAND
.SH DESCRIPTION
.B kdumpctl
is used to check or control the kdump service.
In most cases, you should use
.B systemctl
to start / stop / enable kdump service instead. However,
.B kdumpctl
provides more details for debugging and a helper to set up ssh key authentication.
.SH COMMANDS
.TP
.I start
Start the service.
.TP
.I stop
Stop the service.
.TP
.I status
Prints the current status of kdump service.
It returns a non-zero value if kdump is not operational.
.TP
.I restart
Is equal to
.I start; stop
.TP
.I reload
reload the crash kernel image and initramfs without triggering a rebuild.
.TP
.I rebuild
rebuild the crash kernel initramfs.
.TP
.I propagate
Helps to setup key authentication for ssh storage since it's
impossible to use password authentication during kdump.
.TP
.I showmem
Prints the size of reserved memory for the crash kernel in megabytes.
.TP
.I estimate
Estimate a suitable crashkernel value for the current machine. This is a
best-effort estimate. It will print a recommended crashkernel value
based on the current kdump setup, and list some details of memory usage.
.TP
.I get-default-crashkernel
Return the default crashkernel value provided by kexec-tools.
.TP
.I reset-crashkernel [--kernel=path_to_kernel] [--reboot]
Reset crashkernel to default value recommended by kexec-tools. If no kernel
is specified, will reset KDUMP_KERNELVER if it's defined in /etc/sysconfig/kdump
or the current running kernel's crashkernel value if KDUMP_KERNELVER is empty. You can
also specify --kernel=ALL and --kernel=DEFAULT which have the same meaning as
grubby's kernel-path=ALL and kernel-path=DEFAULT. ppc64le supports FADump and
supports an additional [--fadump=[on|off|nocma]] parameter to toggle FADump
on/off.
If the optional parameter [--reboot] is provided the system will automatically
reboot for changes to take effect. If no changes were made to the kernel
command line the reboot is omitted.
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". Note, fadump is not supported.
If the optional parameter [--force] is provided, there will be no confirmation
before triggering the system crash. Dangerous though, this option is meant
for automation testing.
.SH "SEE ALSO"
.BR kdump.conf (5),
.BR mkdumprd (8)

View File

@ -44,7 +44,7 @@ ia64 and ppc64.
If you're reading this document, you should already have kexec-tools
installed. If not, you install it via the following command:
# yum install kexec-tools
# dnf install kexec-tools
Now load a kernel with kexec:
@ -66,23 +66,31 @@ How to configure kdump
Again, we assume if you're reading this document, you should already have
kexec-tools installed. If not, you install it via the following command:
# yum install kexec-tools
# dnf install kexec-tools
To be able to do much of anything interesting in the way of debug analysis,
you'll also need to install the kernel-debuginfo package, of the same arch
as your running kernel, and the crash utility:
# yum --enablerepo=\*debuginfo install kernel-debuginfo.$(uname -m) crash
# dnf --enablerepo=\*debuginfo install kernel-debuginfo.$(uname -m) crash
Next up, we need to modify some boot parameters to reserve a chunk of memory for
the capture kernel. With the help of grubby, it's very easy to append
"crashkernel=128M" to the end of your kernel boot parameters. Note that the X
values are such that X = the amount of memory to reserve for the capture kernel.
And based on arch and system configuration, one might require more than 128M to
be reserved for kdump. One need to experiment and test kdump, if 128M is not
sufficient, try reserving more memory.
Next up, we need to reserve a chunk of memory for the capture kernel. To use
the default crashkernel value, you can kdumpctl:
# grubby --args="crashkernel=128M" --update-kernel=/boot/vmlinuz-`uname -r`
# kdumpctl reset-crashkernel --kernel=/boot/vmlinuz-`uname -r`
If the default value does not work for your setup you can use
# grubby --args="crashkernel=256M" --update-kernel=/boot/vmlinuz-`uname -r`
to specify a larger value, in this case 256M. You need to experiment to
find the best value that works for your setup. To begin with
# kdumpctl estimate
gives you an estimation for the crashkernel value based on the currently
running kernel. For more details, please refer to the "Estimate crashkernel"
section in /usr/share/doc/kexec-tools/crashkernel-howto.txt.
Note that there is an alternative form in which to specify a crashkernel
memory reservation, in the event that more control is needed over the size and
@ -135,7 +143,7 @@ in /var/crash/<YYYY-MM-DD-HH:MM>/vmcore), then the system rebooted back into
your normal kernel.
Once back to your normal kernel, you can use the previously installed crash
kernel in conjunction with the previously installed kernel-debuginfo to
utility in conjunction with the previously installed kernel-debuginfo to
perform postmortem analysis:
# crash /usr/lib/debug/lib/modules/2.6.17-1.2621.el5/vmlinux
@ -187,7 +195,7 @@ on your system, with the scripts enabled as described in the section above.
Kdump can be triggered with the combination of the 'Alt','SysRq' and 'C'
keyboard keys. Please refer to the following link for more details:
https://access.redhat.com/solutions/2023
http://kbase.redhat.com/faq/FAQ_43_5559.shtm
In addition, on PowerPC boxes, Kdump can also be triggered via Hardware
Management Console(HMC) using 'Ctrl', 'O' and 'C' keyboard keys.
@ -199,7 +207,7 @@ respond to keyboard interrupts. As a result 'Alt-SysRq' keys will not help
trigger a dump. In such scenarios Nmi Watchdog feature can prove to be useful.
The following link has more details on configuring Nmi watchdog option.
https://access.redhat.com/solutions/125103
http://kbase.redhat.com/faq/FAQ_85_9129.shtm
Once this feature has been enabled in the kernel, any lockups will result in an
OOPs message to be generated, followed by Kdump being triggered.
@ -1008,12 +1016,7 @@ Debugging Tips
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
command and check kdump service debugging information.
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

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,39 @@
From bd0200c47c45dd420244b39ddabcecdab1fb9a8e Mon Sep 17 00:00:00 2001
From: Hari Bathini <hbathini@linux.ibm.com>
Date: Wed, 20 Sep 2023 17:29:27 +0530
Subject: [PATCH] kexec: update manpage with explicit mention of clean kexec
While the manpage does mention about kexec boot with a clean shutdown,
it is not explicit about it. Make it explicit.
Signed-off-by: Hari Bathini <hbathini@linux.ibm.com>
Signed-off-by: Simon Horman <horms@kernel.org>
---
kexec/kexec.8 | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/kexec/kexec.8 b/kexec/kexec.8
index 3a344c5..179dcf2 100644
--- a/kexec/kexec.8
+++ b/kexec/kexec.8
@@ -95,8 +95,15 @@ then you would use the following command to load the kernel:
.RB "\-\-append=" "root=/dev/hda1" "\ \-\-initrd=" /boot/initrd
.RE
.PP
-After this kernel is loaded, it can be booted to at any time using the
-command:
+After this kernel is loaded, assuming the user-space supports kexec-based
+rebooting, it can be booted to, with a clean shutdown, using the command:
+
+.RS
+.BR reboot
+.RE
+.PP
+Alternatively, it can also be booted to, without calling shutdown(8), with
+the command:
.RS
.BR kexec \ \-e
--
2.41.0

View File

@ -0,0 +1,44 @@
From 9d9cf8de8b2ad8273861a30476a46f34cd34871a Mon Sep 17 00:00:00 2001
From: Baoquan He <bhe@redhat.com>
Date: Tue, 14 Nov 2023 23:20:30 +0800
Subject: [PATCH] kexec_file: add kexec_file flag to support debug printing
Content-type: text/plain
This add KEXEC_FILE_DEBUG to kexec_file_flags so that it can be passed
to kernel when '-d' is added with kexec_file_load interface. With that
flag enabled, kernel can enable the debugging message printing.
Signed-off-by: Baoquan He <bhe@redhat.com>
Signed-off-by: Simon Horman <horms@kernel.org>
---
kexec/kexec-syscall.h | 1 +
kexec/kexec.c | 1 +
2 files changed, 2 insertions(+)
diff --git a/kexec/kexec-syscall.h b/kexec/kexec-syscall.h
index 2559bffb93da..73e52543e1b0 100644
--- a/kexec/kexec-syscall.h
+++ b/kexec/kexec-syscall.h
@@ -119,6 +119,7 @@ static inline long kexec_file_load(int kernel_fd, int initrd_fd,
#define KEXEC_FILE_UNLOAD 0x00000001
#define KEXEC_FILE_ON_CRASH 0x00000002
#define KEXEC_FILE_NO_INITRAMFS 0x00000004
+#define KEXEC_FILE_DEBUG 0x00000008
/* These values match the ELF architecture values.
* Unless there is a good reason that should continue to be the case.
diff --git a/kexec/kexec.c b/kexec/kexec.c
index 9d0ec46e5657..222f79e3112e 100644
--- a/kexec/kexec.c
+++ b/kexec/kexec.c
@@ -1477,6 +1477,7 @@ int main(int argc, char *argv[])
return 0;
case OPT_DEBUG:
kexec_debug = 1;
+ kexec_file_flags |= KEXEC_FILE_DEBUG;
break;
case OPT_NOIFDOWN:
skip_ifdown = 1;
--
2.41.0

490
mkdumprd Normal file
View File

@ -0,0 +1,490 @@
#!/bin/bash --norc
# New mkdumprd
#
# Copyright 2011 Red Hat, Inc.
#
# Written by Cong Wang <amwang@redhat.com>
#
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
if ! dlog_init; then
echo "failed to initiate the kdump logger."
exit 1
fi
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 --hostonly-nics '')
MKDUMPRD_TMPDIR="$(mktemp -d -t mkdumprd.XXXXXX)"
[ -d "$MKDUMPRD_TMPDIR" ] || perror_exit "dracut: mktemp -p -d -t dracut.XXXXXX failed."
MKDUMPRD_TMPMNT="$MKDUMPRD_TMPDIR/target"
trap '
ret=$?;
is_mounted $MKDUMPRD_TMPMNT && umount -f $MKDUMPRD_TMPMNT;
[[ -d $MKDUMPRD_TMPDIR ]] && rm --one-file-system -rf -- "$MKDUMPRD_TMPDIR";
exit $ret;
' EXIT
# clean up after ourselves no matter how we die.
trap 'exit 1;' SIGINT
add_dracut_arg()
{
dracut_args+=("$@")
}
add_dracut_mount()
{
add_dracut_arg "--mount" "$1"
}
add_dracut_sshkey()
{
add_dracut_arg "--sshkey" "$1"
}
# 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
_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}"
if [[ $_fstype == "nfs"* ]]; then
_pdev=$_target
_sed_cmd+='s/,\(mount\)\?addr=[^,]*//g;'
_sed_cmd+='s/,\(mount\)\?proto=[^,]*//g;'
_sed_cmd+='s/,clientaddr=[^,]*//;'
else
# for non-nfs _target converting to use udev persistent name
_pdev="$(kdump_get_persistent_dev "$_target")"
if [[ -z $_pdev ]]; then
return 1
fi
fi
# mount fs target as rw in 2nd kernel
_sed_cmd+='s/\(^\|,\)ro\($\|,\)/\1rw\2/g;'
# with 'noauto' in fstab nfs and non-root disk mount will fail in 2nd
# kernel, filter it out here.
_sed_cmd+='s/\(^\|,\)noauto\($\|,\)/\1/g;'
# drop nofail or nobootwait
_sed_cmd+='s/\(^\|,\)nofail\($\|,\)/\1/g;'
_sed_cmd+='s/\(^\|,\)nobootwait\($\|,\)/\1/g;'
_options=$(echo "$_options" | sed "$_sed_cmd")
echo "$_pdev $_new_mntpoint $_fstype $_options"
}
#Function: get_ssh_size
#$1=dump target
#called from while loop and shouldn't read from stdin, so we're using "ssh -n"
get_ssh_size()
{
local _out
local _opt=("-i" "$SSH_KEY_LOCATION" "-o" "BatchMode=yes" "-o" "StrictHostKeyChecking=yes")
if ! _out=$(ssh -q -n "${_opt[@]}" "$1" "df" "--output=avail" "$SAVE_PATH"); then
perror_exit "checking remote ssh server available size failed."
fi
echo -n "$_out" | tail -1
}
#mkdir if save path does not exist on ssh dump target
#$1=ssh dump target
#caller should ensure write permission on $1:$SAVE_PATH
#called from while loop and shouldn't read from stdin, so we're using "ssh -n"
mkdir_save_path_ssh()
{
local _opt _dir
_opt=(-i "$SSH_KEY_LOCATION" -o BatchMode=yes -o StrictHostKeyChecking=yes)
ssh -qn "${_opt[@]}" "$1" mkdir -p "$SAVE_PATH" &> /dev/null ||
perror_exit "mkdir failed on $1:$SAVE_PATH"
# check whether user has write permission on $1:$SAVE_PATH
_dir=$(ssh -qn "${_opt[@]}" "$1" mktemp -dqp "$SAVE_PATH" 2> /dev/null) ||
perror_exit "Could not create temporary directory on $1:$SAVE_PATH. Make sure user has write permission on destination"
ssh -qn "${_opt[@]}" "$1" rmdir "$_dir"
return 0
}
#Function: get_fs_size
#$1=dump target
get_fs_size()
{
df --output=avail "$(get_mntpoint_from_target "$1")/$SAVE_PATH" | tail -1
}
#Function: get_raw_size
#$1=dump target
get_raw_size()
{
fdisk -s "$1"
}
#Function: check_size
#$1: dump type string ('raw', 'fs', 'ssh')
#$2: dump target
check_size()
{
local avail memtotal
memtotal=$(awk '/MemTotal/{print $2}' /proc/meminfo)
case "$1" in
raw)
avail=$(get_raw_size "$2")
;;
ssh)
avail=$(get_ssh_size "$2")
;;
fs)
avail=$(get_fs_size "$2")
;;
*)
return
;;
esac || perror_exit "Check dump target size failed"
if [[ $avail -lt $memtotal ]]; then
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
}
check_save_path_fs()
{
local _path=$1
if [[ ! -d $_path ]]; then
perror_exit "Dump path $_path does not exist."
fi
}
mount_failure()
{
local _target=$1
local _mnt=$2
local _fstype=$3
local msg="Failed to mount $_target"
if [[ -n $_mnt ]]; then
msg="$msg on $_mnt"
fi
msg="$msg for kdump preflight check."
if [[ $_fstype == "nfs" ]]; then
msg="$msg Please make sure nfs-utils has been installed."
fi
perror_exit "$msg"
}
check_user_configured_target()
{
local _target=$1 _cfg_fs_type=$2 _mounted
local _mnt _opt _fstype
_mnt=$(get_mntpoint_from_target "$_target")
_opt=$(get_mntopt_from_target "$_target")
_fstype=$(get_fs_type_from_target "$_target")
if [[ -n $_fstype ]]; then
# In case of nfs4, nfs should be used instead, nfs* options is deprecated in kdump.conf
[[ $_fstype == "nfs"* ]] && _fstype=nfs
if [[ -n $_cfg_fs_type ]] && [[ $_fstype != "$_cfg_fs_type" ]]; then
perror_exit "\"$_target\" have a wrong type config \"$_cfg_fs_type\", expected \"$_fstype\""
fi
else
_fstype="$_cfg_fs_type"
_fstype="$_cfg_fs_type"
fi
# For noauto mount, mount it inplace with default value.
# Else use the temporary target directory
if [[ -n $_mnt ]]; then
if ! is_mounted "$_mnt"; then
if [[ $_opt == *",noauto"* ]]; then
mount "$_mnt" || mount_failure "$_target" "$_mnt" "$_fstype"
_mounted=$_mnt
else
perror_exit "Dump target \"$_target\" is neither mounted nor configured as \"noauto\""
fi
fi
else
_mnt=$MKDUMPRD_TMPMNT
mkdir -p "$_mnt"
mount "$_target" "$_mnt" -t "$_fstype" -o defaults || mount_failure "$_target" "" "$_fstype"
_mounted=$_mnt
fi
# For user configured target, use $SAVE_PATH as the dump path within the target
if [[ ! -d "$_mnt/$SAVE_PATH" ]]; then
perror_exit "Dump path \"$SAVE_PATH\" does not exist in dump target \"$_target\""
fi
check_size fs "$_target"
# Unmount it early, if function is interrupted and didn't reach here, the shell trap will clear it up anyway
if [[ -n $_mounted ]]; then
umount -f -- "$_mounted"
fi
}
# $1: core_collector config value
verify_core_collector()
{
local _cmd="${1%% *}"
local _params="${1#${_cmd}}"
if [[ $_cmd != "makedumpfile" ]]; then
if is_raw_dump_target; then
dwarn "Warning: specifying a non-makedumpfile core collector, you will have to recover the vmcore manually."
fi
return
fi
if is_ssh_dump_target || is_raw_dump_target; then
if ! strstr "$_params" "-F"; then
perror_exit 'The specified dump target needs makedumpfile "-F" option.'
fi
_params="$_params vmcore"
else
_params="$_params vmcore dumpfile"
fi
# shellcheck disable=SC2086
if ! $_cmd --check-params $_params; then
perror_exit "makedumpfile parameter check failed."
fi
}
add_mount()
{
local _mnt
_mnt=$(to_mount "$@") || exit 1
add_dracut_mount "$_mnt"
}
#handle the case user does not specify the dump target explicitly
handle_default_dump_target()
{
local _target
local _mntpoint
is_user_configured_dump_target && return
check_save_path_fs "$SAVE_PATH"
_save_path=$(get_bind_mount_source "$SAVE_PATH")
_target=$(get_target_from_path "$_save_path")
_mntpoint=$(get_mntpoint_from_target "$_target")
SAVE_PATH=${_save_path##"$_mntpoint"}
add_mount "$_target"
check_size fs "$_target"
}
# $1: function name
for_each_block_target()
{
local dev majmin
for dev in $(get_kdump_targets); do
[[ -b $dev ]] || continue
majmin=$(get_maj_min "$dev")
check_block_and_slaves "$1" "$majmin" && return 1
done
return 0
}
#judge if a specific device with $1 is unresettable
#return false if unresettable.
is_unresettable()
{
local path device resettable=1
path="/sys/$(udevadm info --query=all --path="/sys/dev/block/$1" | awk '/^P:/ {print $2}' | sed -e 's/\(cciss[0-9]\+\/\).*/\1/g' -e 's/\/block\/.*$//')/resettable"
if [[ -f $path ]]; then
resettable="$(< "$path")"
[[ $resettable -eq 0 ]] && [[ $OVERRIDE_RESETTABLE -eq 0 ]] && {
device=$(udevadm info --query=all --path="/sys/dev/block/$1" | awk -F= '/DEVNAME/{print $2}')
derror "Error: Can not save vmcore because device $device is unresettable"
return 0
}
fi
return 1
}
#check if machine is resettable.
#return true if resettable
check_resettable()
{
local _target _override_resettable
_override_resettable=$(kdump_get_conf_val override_resettable)
OVERRIDE_RESETTABLE=${_override_resettable:-$OVERRIDE_RESETTABLE}
if [ "$OVERRIDE_RESETTABLE" != "0" ] && [ "$OVERRIDE_RESETTABLE" != "1" ]; then
perror_exit "override_resettable value '$OVERRIDE_RESETTABLE' is invalid"
fi
for_each_block_target is_unresettable && return
return 1
}
check_crypt()
{
local _dev
for _dev in $(get_kdump_targets); do
if [[ -n $(get_luks_crypt_dev "$(get_maj_min "$_dev")") ]]; then
derror "Device $_dev is encrypted." && return 1
fi
done
}
if ! check_resettable; then
exit 1
fi
if ! check_crypt; then
dwarn "Warning: Encrypted device is in dump path, which is not recommended, see kexec-kdump-howto.txt for more details."
fi
# firstly get right SSH_KEY_LOCATION
keyfile=$(kdump_get_conf_val sshkey)
if [[ -f $keyfile ]]; then
# canonicalize the path
SSH_KEY_LOCATION=$(/usr/bin/readlink -m "$keyfile")
fi
while read -r config_opt config_val; do
# remove inline comments after the end of a directive.
case "$config_opt" in
extra_modules)
extra_modules="$extra_modules $config_val"
;;
ext[234] | xfs | btrfs | minix | nfs | virtiofs)
check_user_configured_target "$config_val" "$config_opt"
add_mount "$config_val" "$config_opt"
;;
raw)
# checking raw disk writable
dd if="$config_val" count=1 of=/dev/null > /dev/null 2>&1 || {
perror_exit "Bad raw disk $config_val"
}
_praw=$(persistent_policy="by-id" kdump_get_persistent_dev "$config_val")
if [[ -z $_praw ]]; then
exit 1
fi
add_dracut_arg "--device" "$_praw"
check_size raw "$config_val"
;;
ssh)
if strstr "$config_val" "@"; then
mkdir_save_path_ssh "$config_val"
check_size ssh "$config_val"
add_dracut_sshkey "$SSH_KEY_LOCATION"
else
perror_exit "Bad ssh dump target $config_val"
fi
;;
core_collector)
verify_core_collector "$config_val"
;;
dracut_args)
# When users specify nfs dumping via dracut_args, kexec-tools won't
# mount nfs fs beforehand thus nfsv4-related drivers won't be installed
# because we call dracut with --hostonly-mode strict. So manually install
# nfsv4-related drivers.
if [[ $(get_dracut_args_fstype "$config_val") == nfs* ]]; then
add_dracut_arg "--add-drivers" nfs_layout_nfsv41_files
fi
while read -r dracut_arg; do
add_dracut_arg "$dracut_arg"
done <<< "$(echo "$config_val" | xargs -n 1 echo)"
;;
*) ;;
esac
done <<< "$(kdump_read_conf)"
handle_default_dump_target
if ! have_compression_in_dracut_args; then
if is_squash_available && dracut_have_option "--squash-compressor"; then
add_dracut_arg "--squash-compressor" "zstd"
elif is_zstd_command_available; then
add_dracut_arg "--compress" "zstd"
fi
fi
if [[ -n $extra_modules ]]; then
add_dracut_arg "--add-drivers" "$extra_modules"
fi
# TODO: The below check is not needed anymore with the introduction of
# 'zz-fadumpinit' module, that isolates fadump's capture kernel initrd,
# but still sysroot.mount unit gets generated based on 'root=' kernel
# parameter available in fadump case. So, find a way to fix that first
# before removing this check.
if ! is_fadump_capable; then
# The 2nd rootfs mount stays behind the normal dump target mount,
# so it doesn't affect the logic of check_dump_fs_modified().
is_dump_to_rootfs && add_mount "$(to_dev_name "$(get_root_fs_device)")"
add_dracut_arg "--no-hostonly-default-device"
if fips-mode-setup --is-enabled 2> /dev/null; then
add_dracut_arg --add-device "$(findmnt -n -o SOURCE --target /boot)"
fi
fi
# This is RHEL-only to work around nvme problem, then real fix should go to dracut
if [[ -d /sys/module/nvme ]]; then
add_dracut_arg "--add-drivers" "nvme"
fi
# Use kdump managed dracut profile.
[[ $kdump_dracut_confdir ]] || kdump_dracut_confdir=/lib/kdump/dracut.conf.d
if [[ "$(dracut --help)" == *--add-confdir* ]] && [[ -d "$kdump_dracut_confdir" ]]; then
dracut_args+=("--add-confdir" "$kdump_dracut_confdir")
else
dracut_args+=(--add kdumpbase)
dracut_args+=(--omit "plymouth resume ifcfg earlykdump")
fi
dracut "${dracut_args[@]}" "$@"
_rc=$?
sync
exit $_rc

View File

@ -2,7 +2,7 @@
# Generate an initramfs image that isolates dump capture capability within
# the default initramfs using zz-fadumpinit dracut module.
if [ -f /etc/sysconfig/kdump ]; then
if [[ -f /etc/sysconfig/kdump ]]; then
. /etc/sysconfig/kdump
fi
@ -17,7 +17,7 @@ if ! dlog_init; then
exit 1
fi
readonly MKFADUMPRD_TMPDIR="$(mktemp -d -t mkfadumprd.XXXXXX)"
MKFADUMPRD_TMPDIR="$(mktemp -d -t mkfadumprd.XXXXXX)"
[ -d "$MKFADUMPRD_TMPDIR" ] || perror_exit "mkfadumprd: mktemp -d -t mkfadumprd.XXXXXX failed."
trap '
ret=$?;
@ -38,27 +38,37 @@ FADUMP_INITRD="$MKFADUMPRD_TMPDIR/fadump.img"
# this file tells the initrd is fadump enabled
touch "$MKFADUMPRD_TMPDIR/fadump.initramfs"
ddebug "rebuild fadump initrd: $FADUMP_INITRD $DEFAULT_INITRD $KDUMP_KERNELVER"
if ! $MKDUMPRD "$FADUMP_INITRD" -i "$MKFADUMPRD_TMPDIR/fadump.initramfs" /etc/fadump.initramfs; then
# Don't use squash for capture image or default image as it negatively impacts
# compression ratio and increases the size of the initramfs image.
# Don't compress the capture image as uncompressed image is needed immediately.
# Also, early microcode would not be needed here.
if ! $MKDUMPRD "$FADUMP_INITRD" -i "$MKFADUMPRD_TMPDIR/fadump.initramfs" /etc/fadump.initramfs --omit squash --no-compress --no-early-microcode; then
perror_exit "mkfadumprd: failed to build image with dump capture support"
fi
### Unpack the initramfs having dump capture capability
### Unpack the initramfs having dump capture capability retaining previous file modification time.
# This helps in saving space by hardlinking identical files.
mkdir -p "$MKFADUMPRD_TMPDIR/fadumproot"
if ! (pushd "$MKFADUMPRD_TMPDIR/fadumproot" > /dev/null && lsinitrd --unpack "$FADUMP_INITRD" && \
popd > /dev/null); then
if ! cpio -id --preserve-modification-time --quiet -D "$MKFADUMPRD_TMPDIR/fadumproot" < "$FADUMP_INITRD"; then
derror "mkfadumprd: failed to unpack '$MKFADUMPRD_TMPDIR'"
exit 1
fi
### Pack it into the normal boot initramfs with zz-fadumpinit module
_dracut_isolate_args="--rebuild $REBUILD_INITRD --add zz-fadumpinit \
-i $MKFADUMPRD_TMPDIR/fadumproot /fadumproot \
-i $MKFADUMPRD_TMPDIR/fadumproot/usr/lib/dracut/loaded-kernel-modules.txt
/usr/lib/dracut/fadump-kernel-modules.txt"
_dracut_isolate_args=(
--rebuild "$REBUILD_INITRD" --add zz-fadumpinit
-i "$MKFADUMPRD_TMPDIR/fadumproot" /fadumproot
-i "$MKFADUMPRD_TMPDIR/fadumproot/usr/lib/dracut/hostonly-kernel-modules.txt"
/usr/lib/dracut/fadump-kernel-modules.txt
)
if is_squash_available; then
_dracut_isolate_args="$_dracut_isolate_args --add squash"
# Use zstd compression method, if available
if ! have_compression_in_dracut_args; then
if is_zstd_command_available; then
_dracut_isolate_args+=(--compress zstd)
fi
fi
if ! dracut --force --quiet $_dracut_isolate_args $@ "$TARGET_INITRD"; then
if ! dracut --force --quiet "${_dracut_isolate_args[@]}" "$@" "$TARGET_INITRD"; then
perror_exit "mkfadumprd: failed to setup '$TARGET_INITRD' with dump capture capability"
fi

3
sources Normal file
View File

@ -0,0 +1,3 @@
SHA512 (eppic-e8844d3.tar.gz) = d86b9f90c57e694107272d8f71b87f66a30743b9530480fb6f665026bbada4c6b0205a83e40b5383663a945681cfbfcf1ee79469fc219ddf679473c4b2290763
SHA512 (kexec-tools-2.0.29.tar.xz) = 4c9e0b3df47b240f0eac2c31e8b515465f626ce043f64daa32b0b032d7132e54dada5d70875dab256345f66cf94a25dc3c160a9009ba60addd8dcb1e5205f5ca
SHA512 (makedumpfile-1.7.6.tar.gz) = 2436bbc5ced82e95e1c528cc63c6d71b5a386f34623f2f3cf6050019d21e6e81a15ddb5aa50cbec33b86228d2ba622f3ff37989b7cbeb6e66c94380380518f60

View File

@ -40,24 +40,24 @@ storage:
FC disks (qla2xxx, lpfc, bnx2fc, bfa)
software initiator based iSCSI
software RAID (mdraid)
hardware RAID (cciss, hpsa, megaraid_sas, mpt2sas, aacraid)
hardware RAID (smartpqi, hpsa, megaraid, mpt3sas, aacraid, mpi3mr)
SCSI/SATA disks
iSCSI HBA (all offload)
hardware FCoE (qla2xxx, lpfc)
software FCoE (bnx2fc) (Extra configuration required,
please read "Note on FCoE" section below)
NVMe-FC (qla2xxx, lpfc)
network:
Hardware using kernel modules: (tg3, igb, ixgbe, sfc, e1000e, bna,
cnic, netxen_nic, qlge, bnx2x, bnx, qlcnic, be2net, enic,
virtio-net, ixgbevf, igbvf)
Hardware using kernel modules: (igb, ixgbe, ice, i40e, e1000e, igc,
tg3, bnx2x, bnxt_en, qede, cxgb4, be2net, enic, sfc, mlx4_en,
mlx5_core, r8169, atlantic, nfp, ionic; nicvf (aarch64 only))
protocol: ipv4
bonding
vlan
bridge
team
vlan tagged bonding
bridge over bond/team/vlan
bridge over bond/vlan
hypervisor:
kvm
@ -67,14 +67,17 @@ filesystem:
ext[234]
xfs
nfs
virtiofs
firmware:
BIOS
UEFI
hypervisor:
VMWare ESXi 4.1 and 5.1
Hyper-V 2012 R2 (RHEL Gen1 UP Guest only)
VMWare ESXi 4.x 5.x would not be tested/supported any more.
only support ESXi 6.6, 6.7, 7.0
Hyper-V 2012 R2 (RHEL Gen1 UP Guest only), later version will
also be tested/supported
Unsupported Dump targets
------------------------
@ -114,15 +117,5 @@ issue, because some software FCoE requires more memory to work. In such case,
you may need to increase the kdump reserved memory size in "crashkernel="
kernel parameter.
By default, RHEL systems have "crashkernel=auto" in kernel boot arguments.
The auto reserved memory size is designed to balance the coverage of use cases
and an acceptable memory overhead, so not every use case could fit in, software
FCoE is one of the case.
For hardware FCoE, kdump should work naturally as firmware will do the
initialization job. The capture kernel and kdump tools will run just fine.
Useful Links
============
[1] RHEL6: Enabling kdump for full-virt (HVM) Xen DomU
(https://access.redhat.com/knowledge/solutions/92943)

88
tests/Makefile Normal file
View File

@ -0,0 +1,88 @@
TEST_CASE ?=
BASE_IMAGE ?=
TEST_ROOT := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
BUILD_ROOT := $(TEST_ROOT)/build
REPO = $(shell realpath $(TEST_ROOT)/../)
ARCH ?= $(shell arch)
SPEC = kexec-tools.spec
DIST ?= fedora
DIST_ABR ?= f
DIST_ABRL ?= fc
DIST_UNSET ?= rhel
RELEASE ?= 33
DEFAULT_BASE_IMAGE_VER ?= 1.2
DEFAULT_BASE_IMAGE ?= Fedora-Cloud-Base-$(RELEASE)-$(DEFAULT_BASE_IMAGE_VER).$(ARCH).raw.xz
DEFAULT_BASE_IMAGE_URL ?= https://dl.fedoraproject.org/pub/fedora/linux/releases/$(RELEASE)/Cloud/$(ARCH)/images/$(DEFAULT_BASE_IMAGE)
BUILD_ROOT = $(TEST_ROOT)/build
RPMDEFINE = --define '_sourcedir $(REPO)'\
--define '_specdir $(REPO)'\
--define '_builddir $(BUILD_ROOT)'\
--define '_srcrpmdir $(BUILD_ROOT)'\
--define '_rpmdir $(BUILD_ROOT)'\
--define 'dist %{?distprefix}.$(DIST_ABRL)$(RELEASE)'\
--define '$(DIST) $(RELEASE)'\
--eval '%undefine $(DIST_UNSET)'\
--define '$(DIST_ABRL)$(RELEASE) 1'\
KEXEC_TOOLS_SRC = $(filter-out $(REPO)/tests,$(wildcard $(REPO)/*))
KEXEC_TOOLS_TEST_SRC = $(wildcard $(REPO)/tests/scripts/**/*)
KEXEC_TOOLS_NVR = $(shell rpm $(RPMDEFINE) -q --specfile $(REPO)/$(SPEC) 2>/dev/null | grep -m 1 .)
KEXEC_TOOLS_RPM = $(BUILD_ROOT)/$(ARCH)/$(KEXEC_TOOLS_NVR).rpm
all: $(TEST_ROOT)/output/test-base-image
# Use either:
# fedpkg --release $(DIST_ABR)$(RELEASE) --path ../../ local
# or
# rpmbuild $(RPMDEFINE) -ba $(REPO)/$(SPEC)
# to rebuild the rpm, currently use rpmbuild to have better control over the rpm building process
#
$(KEXEC_TOOLS_RPM): $(KEXEC_TOOLS_SRC)
sh -c "cd .. && fedpkg sources"
@echo Rebuilding RPM due to modification of sources: $?
rpmbuild $(RPMDEFINE) -ba $(REPO)/$(SPEC)
$(BUILD_ROOT)/base-image:
mkdir -p $(BUILD_ROOT)
ifeq ($(strip $(BASE_IMAGE)),)
wget $(DEFAULT_BASE_IMAGE_URL) -O $(BUILD_ROOT)/$(DEFAULT_BASE_IMAGE)
$(TEST_ROOT)/scripts/build-image.sh \
$(BUILD_ROOT)/$(DEFAULT_BASE_IMAGE)\
$(BUILD_ROOT)/base-image
else
$(TEST_ROOT)/scripts/build-image.sh \
$(BASE_IMAGE)\
$(BUILD_ROOT)/base-image
endif
$(BUILD_ROOT)/inst-base-image: $(BUILD_ROOT)/base-image
@echo "Building installation base image"
echo $(KEXEC_TOOLS_NVR)
$(TEST_ROOT)/scripts/build-image.sh \
$(BUILD_ROOT)/base-image \
$(BUILD_ROOT)/inst-base-image \
$(TEST_ROOT)/scripts/build-scripts/base-image.sh
$(TEST_ROOT)/output/test-base-image: $(BUILD_ROOT)/inst-base-image $(KEXEC_TOOLS_RPM) $(KEXEC_TOOLS_TEST_SRC)
@echo "Building test base image"
mkdir -p $(TEST_ROOT)/output
$(TEST_ROOT)/scripts/build-image.sh \
$(BUILD_ROOT)/inst-base-image \
$(TEST_ROOT)/output/test-base-image \
$(TEST_ROOT)/scripts/build-scripts/test-base-image.sh \
$(KEXEC_TOOLS_RPM)
test-run: $(TEST_ROOT)/output/test-base-image
ifeq ($(strip $(TEST_CASE)),)
$(TEST_ROOT)/scripts/run-test.sh
else
$(TEST_ROOT)/scripts/run-test.sh --console $(TEST_CASE)
endif
clean:
rm -rf $(TEST_ROOT)/build
rm -rf $(TEST_ROOT)/output

65
tests/README Normal file
View File

@ -0,0 +1,65 @@
=====================
Kexec Kdump Self-test
=====================
Introduction
============
The self-tests here are useful for quick sanity tests for new patches, and also helpful for debugging issues.
How it works
============
All tests are run within VMs using qemu. By default, VM images are based on Fedora Cloud image, and the image for each test run is a layered qcow2 snapshot on top of the base image.
Test images are managed by Makefile, so if there are any code change in the kexec-tools repository, `make` command will detect that and only rebuild the top image layer. This makes the test runs boot fast and each test run is clean.
Basic usage
===========
Before you start, you can make the self-tests use your own base image by running following command:
`make clean && make BASE_IMAGE=<path/to/your/image>`
This is helpful if you have a slow network, else self-test will try to download the cloud image from Fedora's official website using `wget`.
- Use the following command to run all tests:
$ make test-run
All available tests will be executed.
Test artifacts are stored in output/<testcase>
- For easier debugging, you can run only on test with the following command:
$ make TEST_CASE=<testcase> test-run
This way, VM's console is directly connected to stdin/out so debugging will be easier.
If there are multiple VMs used in a test case, the VM performing actual kdump/kexec operation will be connected to stdin/out.
Test Cases
==========
Each test case is a folder under scripts/testcases/, a test case folder will contain at least one executable shell script, and each script should contain two functions: "on_build" and "on_test".
"on_build" is called when building the test image, which can instruct the self-test framework to install packages or create files, etc.
"on_test" is called when VM finished booting, which can get the boot count by calling "get_test_boot_count" and determine what to do. It should call "test_passed" on success, and call "test_failed" on failure. "test_aborted" is called when unexpected behavior occurs.
When there are multiple scripts in a single test case folder, they will spawn VMs in lexical order, and the last VM is considered the VM performing the actual test. Other VMs could be hosting test required service. This is useful for the network dump test. However, "test_passed" or "test_failed" or "test_aborted" could be called in any of these VMs, so during network kdump test, the dump target can also terminate the test and mark it passed when a valid vmcore is detected.
Debugging
=========
- When the test VM boots, you can append "no_test" to kernel args in grub, which tells the test services to quit early.
- You can launch the VMs manually or inspect the image after ran a test.
Test images are located as:
output/<testcase>/<vm-name>.img
Test images' corresponding qemu command are located as:
output/<testcase>/<vm-name>.qemu_cmd
To repeat/debug a test manually, you should launch all VMs in output/<testcase> menu in lexical order, and append 'no_test' in the last VM's grub cmdline, then VM will hang on login prompt, login with root/fedora. Test script is located as /kexec-kdump-test/test.sh
- If you just want to inspect the images file content, you can also use scripts/spawn-image-shell.sh <test-image> to spawn a shell in the image quickly.

57
tests/scripts/build-image.sh Executable file
View File

@ -0,0 +1,57 @@
#!/usr/bin/env bash
if [ $# -lt 2 ]; then
echo "Usage: $(basename $0) <base-image> <output-image> <build-script> [<build-script-args>]
Build a new <output-image> on top of <base-image>, and install
contents defined in <build-script>. <args> are directly passed
to <build-script>.
If <base-image> is raw, will copy it and create <output-image>
in qcow2 format.
If <base-image> is qcow2, will create <output-image> as a snapshot
on top of <base-image>"
exit 1
fi
BASEDIR=$(realpath $(dirname "$0"))
. $BASEDIR/image-init-lib.sh
# Base image to build from
BASE_IMAGE=$1 && shift
if [[ ! -e $BASE_IMAGE ]]; then
perror_exit "Base image '$BASE_IMAGE' not found"
else
BASE_IMAGE=$(realpath "$BASE_IMAGE")
fi
OUTPUT_IMAGE=$1 && shift
if [[ ! -d $(dirname $OUTPUT_IMAGE) ]]; then
perror_exit "Path '$(dirname $OUTPUT_IMAGE)' doesn't exists"
fi
INST_SCRIPT=$1 && shift
create_image_from_base_image $BASE_IMAGE $OUTPUT_IMAGE.building
mount_image $OUTPUT_IMAGE.building
img_inst() {
inst_in_image $OUTPUT_IMAGE.building $@
}
img_inst_pkg() {
inst_pkg_in_image $OUTPUT_IMAGE.building $@
}
img_run_cmd() {
run_in_image $OUTPUT_IMAGE.building "$@"
}
img_add_qemu_cmd() {
QEMU_CMD+="$@"
}
[ -e "$INST_SCRIPT" ] && source $INST_SCRIPT
mv $OUTPUT_IMAGE.building $OUTPUT_IMAGE

View File

@ -0,0 +1,10 @@
#!/bin/sh
img_inst_pkg grubby\
dnsmasq\
openssh openssh-server\
dracut-network dracut-squash squashfs-tools ethtool snappy
img_run_cmd "grubby --args systemd.journald.forward_to_console=1 systemd.log_target=console --update-kernel ALL"
img_run_cmd "grubby --args selinux=0 --update-kernel ALL"
img_run_cmd "grubby --args crashkernel=224M --update-kernel ALL"

View File

@ -0,0 +1,21 @@
#!/bin/sh
# Test RPMs to be installed
TEST_RPMS=
for _rpm in $@; do
if [[ ! -e $_rpm ]]; then
perror_exit "'$_rpm' not found"
else
TEST_RPMS=$(realpath "$_rpm")
fi
done
img_run_cmd "mkdir -p /kexec-kdump-test"
img_inst $TESTDIR/scripts/kexec-kdump-test/init.sh /kexec-kdump-test/init.sh
img_inst $TESTDIR/scripts/kexec-kdump-test/test.sh /kexec-kdump-test/test.sh
img_inst $TESTDIR/scripts/kexec-kdump-test/kexec-kdump-test.service /etc/systemd/system/kexec-kdump-test.service
img_run_cmd "systemctl enable kexec-kdump-test.service"
img_inst_pkg $TEST_RPMS
# Test script should start kdump manually to save time
img_run_cmd "systemctl disable kdump.service"

View File

@ -0,0 +1,21 @@
#!/usr/bin/env bash
. $TESTDIR/scripts/test-lib.sh
TEST_SCRIPT=$1
QEMU_CMD="$DEFAULT_QEMU_CMD \
-serial stdio \
-serial file:$(get_test_output_file $TEST_SCRIPT) \
-monitor none \
-hda $OUTPUT_IMAGE"
img_add_qemu_cmd() {
QEMU_CMD+=" $@"
}
source $TEST_SCRIPT
on_build
img_inst $TEST_SCRIPT /kexec-kdump-test/test.sh
echo $QEMU_CMD > $(get_test_qemu_cmd_file $TEST_SCRIPT)

View File

@ -0,0 +1,25 @@
#!/usr/bin/env bash
BASEDIR=$(realpath $(dirname "$0"))
. $BASEDIR/image-init-lib.sh
# Base image to copy from
BOOT_IMAGE=$1 && shift
if [ ! -e "$BOOT_IMAGE" ]; then
perror_exit "Image '$BOOT_IMAGE' not found"
else
BOOT_IMAGE=$(realpath "$BOOT_IMAGE")
fi
mount_image $BOOT_IMAGE
IMAGE_MNT=$(get_image_mount_root $BOOT_IMAGE)
SRC=
while [ $# -gt 1 ]; do
SRC="$SRC $IMAGE_MNT/$1"
shift
done
DST=$1
cp -rv $SRC $DST

View File

@ -0,0 +1,256 @@
#!/usr/bin/env bash
[ -z "$TESTDIR" ] && TESTDIR=$(realpath $(dirname "$0")/../)
SUDO="sudo"
declare -A MNTS=()
declare -A DEVS=()
perror() {
echo $@>&2
}
perror_exit() {
echo $@>&2
exit 1
}
is_mounted()
{
findmnt -k -n $1 &>/dev/null
}
clean_up()
{
for _mnt in ${MNTS[@]}; do
is_mounted $_mnt && $SUDO umount -f $_mnt
done
for _dev in ${DEVS[@]}; do
[ ! -e "$_dev" ] && continue
[[ "$_dev" == "/dev/loop"* ]] && $SUDO losetup -d "$_dev"
[[ "$_dev" == "/dev/nbd"* ]] && $SUDO qemu-nbd --disconnect "$_dev"
done
[ -d "$TMPDIR" ] && $SUDO rm --one-file-system -rf -- "$TMPDIR";
sync
}
trap '
ret=$?;
clean_up
exit $ret;
' EXIT
# clean up after ourselves no matter how we die.
trap 'exit 1;' SIGINT
readonly TMPDIR="$(mktemp -d -t kexec-kdump-test.XXXXXX)"
[ -d "$TMPDIR" ] || perror_exit "mktemp failed."
get_image_fmt() {
local image=$1 fmt
[ ! -e "$image" ] && perror "image: $image doesn't exist" && return 1
fmt=$(qemu-img info $image | sed -n "s/file format:\s*\(.*\)/\1/p")
[ $? -eq 0 ] && echo $fmt && return 0
return 1
}
fmt_is_qcow2() {
[ "$1" == "qcow2" ] || [ "$1" == "qcow2 backing qcow2" ]
}
# If it's partitioned, return the mountable partition, else return the dev
get_mountable_dev() {
local dev=$1 parts
$SUDO partprobe $dev && sync
parts="$(ls -1 ${dev}p*)"
if [ -n "$parts" ]; then
if [ $(echo "$parts" | wc -l) -gt 1 ]; then
perror "It's a image with multiple partitions, using last partition as main partition"
fi
echo "$parts" | tail -1
else
echo "$dev"
fi
}
prepare_loop() {
[ -n "$(lsmod | grep "^loop")" ] && return
$SUDO modprobe loop
[ ! -e "/dev/loop-control" ] && perror_exit "failed to load loop driver"
}
prepare_nbd() {
[ -n "$(lsmod | grep "^nbd")" ] && return
$SUDO modprobe nbd max_part=4
[ ! -e "/dev/nbd0" ] && perror_exit "failed to load nbd driver"
}
mount_nbd() {
local image=$1 size dev
for _dev in /sys/class/block/nbd* ; do
size=$(cat $_dev/size)
if [ "$size" -eq 0 ] ; then
dev=/dev/${_dev##*/}
$SUDO qemu-nbd --connect=$dev $image 1>&2
[ $? -eq 0 ] && echo $dev && break
fi
done
return 1
}
image_lock()
{
local image=$1 timeout=5 fd
eval "exec {fd}>$image.lock"
if [ $? -ne 0 ]; then
perror_exit "failed acquiring image lock"
exit 1
fi
flock -n $fd
rc=$?
while [ $rc -ne 0 ]; do
echo "Another instance is holding the image lock ..."
flock -w $timeout $fd
rc=$?
done
}
# Mount a device, will umount it automatially when shell exits
mount_image() {
local image=$1 fmt
local dev mnt mnt_dev
# Lock the image just in case user run this script in parrel
image_lock $image
fmt=$(get_image_fmt $image)
[ $? -ne 0 ] || [ -z "$fmt" ] && perror_exit "failed to detect image format"
if [ "$fmt" == "raw" ]; then
prepare_loop
dev="$($SUDO losetup --show -f $image)"
[ $? -ne 0 ] || [ -z "$dev" ] && perror_exit "failed to setup loop device"
elif fmt_is_qcow2 "$fmt"; then
prepare_nbd
dev=$(mount_nbd $image)
[ $? -ne 0 ] || [ -z "$dev" ] perror_exit "failed to connect qemu to nbd device '$dev'"
else
perror_exit "Unrecognized image format '$fmt'"
fi
DEVS[$image]="$dev"
mnt="$(mktemp -d -p $TMPDIR -t mount.XXXXXX)"
[ $? -ne 0 ] || [ -z "$mnt" ] && perror_exit "failed to create tmp mount dir"
MNTS[$image]="$mnt"
mnt_dev=$(get_mountable_dev "$dev")
[ $? -ne 0 ] || [ -z "$mnt_dev" ] && perror_exit "failed to setup loop device"
$SUDO mount $mnt_dev $mnt
[ $? -ne 0 ] && perror_exit "failed to mount device '$mnt_dev'"
}
get_image_mount_root() {
local image=$1
local root=${MNTS[$image]}
echo $root
if [ -z "$root" ]; then
return 1
fi
}
shell_in_image() {
local root=$(get_image_mount_root $1) && shift
pushd $root
$SHELL
popd
}
inst_pkg_in_image() {
local root=$(get_image_mount_root $1) && shift
# LSB not available
# release_info=$($SUDO chroot $root /bin/bash -c "lsb_release -a")
# release=$(echo "$release_info" | sed -n "s/Release:\s*\(.*\)/\1/p")
# distro=$(echo "$release_info" | sed -n "s/Distributor ID:\s*\(.*\)/\1/p")
# if [ "$distro" != "Fedora" ]; then
# perror_exit "only Fedora image is supported"
# fi
release=$(cat $root/etc/fedora-release | sed -n "s/.*[Rr]elease\s*\([0-9]*\).*/\1/p")
[ $? -ne 0 ] || [ -z "$release" ] && perror_exit "only Fedora image is supported"
$SUDO dnf --releasever=$release --installroot=$root install -y $@
}
run_in_image() {
local root=$(get_image_mount_root $1) && shift
$SUDO chroot $root /bin/bash -c "$@"
}
inst_in_image() {
local image=$1 src=$2 dst=$3
local root=${MNTS[$image]}
$SUDO cp $src $root/$dst
}
# If source image is qcow2, create a snapshot
# If source image is raw, convert to raw
# If source image is xz, decompress then repeat the above logic
#
# Won't touch source image
create_image_from_base_image() {
local image=$1
local output=$2
local decompressed_image
local ext="${image##*.}"
if [[ "$ext" == 'xz' ]]; then
echo "Decompressing base image..."
xz -d -k $image
decompressed_image=${image%.xz}
image=$decompressed_image
fi
local image_fmt=$(get_image_fmt $image)
if [ "$image_fmt" != "raw" ]; then
if fmt_is_qcow2 "$image_fmt"; then
echo "Source image is qcow2, using snapshot..."
qemu-img create -f qcow2 -b $image $output
else
perror_exit "Unrecognized base image format '$image_mnt'"
fi
else
echo "Source image is raw, converting to qcow2..."
qemu-img convert -f raw -O qcow2 $image $output
fi
# Clean up decompress temp image
if [ -n "$decompressed_image" ]; then
rm $decompressed_image
fi
}

View File

@ -0,0 +1,122 @@
#!/usr/bin/env sh
BOOT_ARG="test_boot_count"
_YELLOW='\033[1;33m'
_GREEN='\033[0;32m'
_RED='\033[0;31m'
_NC='\033[0m' # No Color
if [ -n "$(cat /proc/cmdline | grep "\bno_test\b")" ]; then
exit 0
fi
get_test_boot_count() {
local boot_count=$(cat /proc/cmdline | sed -n "s/.*$BOOT_ARG=\([0-9]*\).*/\1/p")
if [ -z "$boot_count" ]; then
boot_count=1
fi
echo $boot_count
}
test_output() {
echo $@ > /dev/ttyS1
echo $@ > /dev/ttyS0
sync
}
test_passed() {
echo -e "${_GREEN}TEST PASSED${_NC}" > /dev/ttyS1
echo -e "${_GREEN}kexec-kdump-test: TEST PASSED${_NC}" > /dev/ttyS0
echo $@ > /dev/ttyS1
echo $@ > /dev/ttyS0
sync
shutdown -h 0
exit 0
}
test_failed() {
echo -e "${_RED}TEST FAILED${_NC}" > /dev/ttyS1
echo -e "${_RED}kexec-kdump-test: TEST FAILED${_NC}" > /dev/ttyS0
echo $@ > /dev/ttyS1
echo $@ > /dev/ttyS0
sync
shutdown -h 0
exit 1
}
test_abort() {
echo -e "${_YELLOW}TEST ABORTED${_NC}" > /dev/ttyS1
echo -e "${_YELLOW}kexec-kdump-test: TEST ABORTED${_NC}" > /dev/ttyS0
echo $@ > /dev/ttyS1
echo $@ > /dev/ttyS0
sync
shutdown -h 0
exit 2
}
has_valid_vmcore_dir() {
local path=$1
local vmcore_dir=$path/$(ls -1 $path | tail -n 1)
local vmcore="<invalid>"
test_output "Found a vmcore dir \"$vmcore_dir\":"
# Checking with `crash` is slow and consume a lot of memory/disk,
# just do a sanity check by check if log are available.
if [ -e $vmcore_dir/vmcore ]; then
vmcore=$vmcore_dir/vmcore
makedumpfile --dump-dmesg $vmcore $vmcore_dir/vmcore-dmesg.txt.2 || {
test_output "Failed to retrive dmesg from vmcore!"
return 1
}
elif [ -e $vmcore_dir/vmcore.flat ]; then
vmcore=$vmcore_dir/vmcore.flat
makedumpfile -R $vmcore_dir/vmcore < $vmcore || return 1
makedumpfile --dump-dmesg $vmcore_dir/vmcore $vmcore_dir/vmcore-dmesg.txt.2 || {
test_output "Failed to retrive dmesg from vmcore!"
return 1
}
rm $vmcore_dir/vmcore
else
test_output "The vmcore dir is empty!"
return 1
fi
if ! diff $vmcore_dir/vmcore-dmesg.txt.2 $vmcore_dir/vmcore-dmesg.txt; then
test_output "Dmesg retrived from vmcore is different from dump version!"
return 1
fi
test_output "VMCORE: $vmcore"
test_output "KERNEL VERSION: $(rpm -q kernel-core)"
return 0
}
BOOT_COUNT=$(get_test_boot_count)
test_output "Kexec-Kdump-Test Boot #$BOOT_COUNT"
echo 'fedora' | passwd --stdin root
test_output "Updating kernel cmdline"
grubby --update-kernel ALL --args $BOOT_ARG=$(expr $BOOT_COUNT + 1) && sync
test_output "Executing test hook"
source /kexec-kdump-test/test.sh
on_test;
test_output "Test exited, system hang for inspect"

View File

@ -0,0 +1,9 @@
[Unit]
Description=Kexec Kdump Test Service
[Service]
ExecStart=/kexec-kdump-test/init.sh
Type=idle
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,15 @@
#!/usr/bin/env sh
# A test example that do nothing
# Executed before VM starts
on_build() {
:
}
# Executed when VM boots
on_test() {
:
# call get_test_boot_count to get boot cound
# call test_passed if test passed
# call test_failed if test passed
}

148
tests/scripts/run-test.sh Executable file
View File

@ -0,0 +1,148 @@
#!/bin/bash
_kill_all_jobs() {
local _jobs=$(jobs -r -p)
[ -n "$_jobs" ] && kill $_jobs
}
trap '
ret=$?;
_kill_all_jobs
exit $ret;
' EXIT
trap 'exit 1;' SIGINT
BASEDIR=$(realpath $(dirname "$0"))
. $BASEDIR/test-lib.sh
TESTCASEDIR="$BASEDIR/testcases"
console=0
testcases=""
while [ $# -gt 0 ]; do
case $1 in
'')
break
;;
--console )
console=1
;;
-*)
echo "Invalid option $1"
;;
*)
testcases+=" $1"
;;
esac
shift;
done
if [ -z "$testcases" ]; then
echo "==== Starting all tests: ===="
testcases=$(ls -1 $TESTCASEDIR)
else
echo "==== Starting specified tests: ===="
fi
echo ${testcases##*/}
echo
declare -A results
ret=0
for test_case in $testcases; do
echo "======== Running Test Case $test_case ========"
results[$test_case]="<Test Skipped>"
testdir=$TESTCASEDIR/$test_case
script_num=$(ls -1 $testdir | wc -l)
scripts=$(ls -r -1 $testdir | tr '\n' ' ')
test_outputs=""
read main_script aux_script <<< "$scripts"
if [ -z "$main_script" ]; then
echo "ERROR: Empty testcase dir $testdir"
continue
fi
for script in $scripts; do
echo "---- Building image for: $script ----"
echo "-------- Output image is: $(get_test_image $testdir/$script)"
echo "-------- Building log is: $(get_test_image $testdir/$script).log"
mkdir -p $(dirname $(get_test_image $testdir/$script))
build_test_image $testdir/$script &> $(get_test_image $testdir/$script).log
if [ $? -ne 0 ]; then
echo "Failing building image!"
continue 2
fi
done
for script in $aux_script; do
echo "---- Starting VM: $script ----"
script="$testdir/$script"
echo "-------- Qemu cmdline: $(get_test_qemu_cmd_file $script)"
echo "-------- Console log: $(get_test_console_file $script)"
echo "-------- Test log: $(get_test_output_file $script)"
test_outputs+="$(get_test_output_file $script) "
rm -f $(get_test_console_file $script)
rm -f $(get_test_output_file $script)
$(run_test_sync $script > $(get_test_console_file $script)) &
sleep 5
done
script="$main_script"
echo "---- Starting test VM: $(basename $script) ----"
script="$testdir/$script"
echo "-------- Qemu cmdline: $(get_test_qemu_cmd_file $script)"
echo "-------- Console log: $(get_test_console_file $script)"
echo "-------- Test log: $(get_test_output_file $script)"
test_outputs+="$(get_test_output_file $script) "
rm -f $(get_test_console_file $script)
rm -f $(get_test_output_file $script)
if [ $console -eq 1 ]; then
run_test_sync $script | tee $(get_test_console_file $script)
[ -n "$(jobs -p)" ] && kill $(jobs -p)
else
$(run_test_sync $script > $(get_test_console_file $script)) &
watch_test_outputs $test_outputs
fi
res="$(gather_test_result $test_outputs)"
[ $? -ne 0 ] && ret=$(expr $ret + 1)
results[$test_case]="$res"
echo -e "-------- Test finished: $test_case $res --------"
for script in $scripts; do
script="$testdir/$script"
output="$(get_test_output_file $script) "
image="$(get_test_image $script)"
vmcore="$(sed -n 's/^VMCORE: \(\S*\).*/\1/p' $output)"
kernel="$(sed -n 's/^KERNEL VERSION: \(\S*\).*/\1/p' $output)"
if [ -n "$vmcore" ]; then
echo "You can retrive the verify the vmcore file using following command:"
echo "./scripts/copy-from-image.sh \\"
echo " $image \\"
echo " $vmcore ./"
echo "Kernel package verion is: $kernel"
fi
done
done
echo "======== Test results ========"
for i in ${!results[@]}; do
echo "----------------"
echo -e "$i:\t\t${results[$i]}"
done
exit $ret

View File

@ -0,0 +1,16 @@
#!/usr/bin/env bash
BASEDIR=$(realpath $(dirname "$0"))
. $BASEDIR/image-init-lib.sh
# Base image to build from
BOOT_IMAGE=$1
if [[ ! -e $BOOT_IMAGE ]]; then
perror_exit "Image '$BOOT_IMAGE' not found"
else
BOOT_IMAGE=$(realpath "$BOOT_IMAGE")
fi
mount_image $BOOT_IMAGE
shell_in_image $BOOT_IMAGE

177
tests/scripts/test-lib.sh Normal file
View File

@ -0,0 +1,177 @@
#!/usr/bin/env sh
[ -z "$BASEDIR" ] && BASEDIR=$(realpath $(dirname "$0"))
[ -z "$TESTDIR" ] && TESTDIR=$(realpath $BASEDIR/../)
[ -z "$TEST_BASE_IMAGE" ] && TEST_BASE_IMAGE=$TESTDIR/output/test-base-image
[[ ! -e $TEST_BASE_IMAGE ]] && echo "Test base image not found." && exit 1
DEFAULT_QEMU_CMD="-nodefaults \
-nographic \
-smp 2 \
-m 768M \
-monitor none"
_YELLOW='\033[1;33m'
_GREEN='\033[0;32m'
_RED='\033[0;31m'
_NC='\033[0m' # No Color
get_test_path() {
local script=$1
local testname=$(basename $(dirname $script))
local output=$TESTDIR/output/$testname
echo $output
}
get_test_entry_name() {
echo $(basename ${1%.*})
}
get_test_image() {
local script=$1
local testout=$(get_test_path $script)
local entry=$(get_test_entry_name $script)
echo $testout/$entry.img
}
get_test_qemu_cmd_file() {
local script=$1
local testout=$(get_test_path $script)
local entry=$(get_test_entry_name $script)
echo $testout/$entry.qemu_cmd
}
get_test_qemu_cmd() {
cat $(get_test_qemu_cmd_file $1)
}
get_test_output_file() {
local script=$1
local testout=$(get_test_path $script)
local entry=$(get_test_entry_name $script)
echo $testout/$entry.output
}
get_test_console_file() {
local script=$1
local testout=$(get_test_path $script)
local entry=$(get_test_entry_name $script)
echo $testout/$entry.console
}
get_test_output() {
local output=$(get_test_output_file $1)
if [ -e "$output" ]; then
cat $(get_test_output_file $1)
else
echo "<No Output>"
fi
}
build_test_image() {
local script=$1
local test_image=$(get_test_image $script)
mkdir -p $(dirname $test_image)
$BASEDIR/build-image.sh \
$TEST_BASE_IMAGE \
$test_image \
$BASEDIR/build-scripts/test-image.sh \
$script
}
run_test_sync() {
local qemu_cmd=$(get_test_qemu_cmd $1)
if [ -n "$qemu_cmd" ]; then
timeout --foreground 10m qemu-kvm $(get_test_qemu_cmd $1)
else
echo "error: test qemu command line is not configured" > /dev/stderr
return 1
fi
}
_check_test_result() {
grep "TEST PASSED" $1 2>/dev/null
[ $? -eq 0 ] && return 0
grep "TEST FAILED" $1 2>/dev/null
[ $? -eq 0 ] && return 1
grep "TEST ABORTED" $1 2>/dev/null
[ $? -eq 0 ] && return 2
return 255
}
# Print test result and return below value:
# 0: Test passed
# 1: Test failed
# 2: Test aborted, test scripts errored out
# 3: Test exited unexpectely, VM got killed early, or time out
gather_test_result() {
local ret=255
local res=""
for i in $@; do
res=$(_check_test_result $i)
ret=$?
if [ $ret -ne 255 ]; then
echo $res
return $ret
fi
done
echo "${_RED}TEST RESULT NOT FOUND!${_NC}"
return 3
}
# Wait and watch for test result
watch_test_outputs() {
local ret=255
local res=""
# If VMs are still running, check for test result, if
# test finished, kill remaining VMs
while true; do
if [ -n "$(jobs -r)" ]; then
# VMs still running
for i in $@; do
res=$(_check_test_result $i)
ret=$?
if [ $ret -ne 255 ]; then
# Test finished, kill VMs
kill $(jobs -p)
break 2
fi
done
else
# VMs exited
ret=255
for i in $@; do
res=$(_check_test_result $i)
ret=$?
if [ $ret -ne 255 ]; then
break 2
fi
done
if [ $ret -eq 255 ]; then
ret=3
break
fi
fi
sleep 1
done
return $ret
}

View File

@ -0,0 +1,32 @@
on_build() {
:
}
on_test() {
local boot_count=$(get_test_boot_count)
if [ $boot_count -eq 1 ]; then
cat << EOF > /etc/kdump.conf
path /var/crash
core_collector makedumpfile -l --message-level 7 -d 31
EOF
kdumpctl start || test_failed "Failed to start kdump"
sync
echo 1 > /proc/sys/kernel/sysrq
echo c > /proc/sysrq-trigger
elif [ $boot_count -eq 2 ]; then
if has_valid_vmcore_dir /var/crash; then
test_passed
else
test_failed "Vmcore missing"
fi
shutdown -h 0
else
test_failed "Unexpected reboot"
fi
}

View File

@ -0,0 +1,41 @@
#!/usr/bin/env sh
# Executed before VM starts
on_build() {
img_inst_pkg "nfs-utils dnsmasq"
img_run_cmd "mkdir -p /srv/nfs/var/crash"
img_run_cmd "echo /srv/nfs 192.168.77.1/24\(rw,async,insecure,no_root_squash\) > /etc/exports"
img_run_cmd "systemctl enable nfs-server"
img_run_cmd "touch /etc/systemd/resolved.conf"
img_run_cmd "echo DNSStubListener=no >> /etc/systemd/resolved.conf"
img_run_cmd "echo interface=eth0 > /etc/dnsmasq.conf"
img_run_cmd "echo dhcp-authoritative >> /etc/dnsmasq.conf"
img_run_cmd "echo dhcp-range=192.168.77.50,192.168.77.100,255.255.255.0,12h >> /etc/dnsmasq.conf"
img_run_cmd "systemctl enable dnsmasq"
img_run_cmd 'echo DEVICE="eth0" > /etc/sysconfig/network-scripts/ifcfg-eth0'
img_run_cmd 'echo BOOTPROTO="none >> /etc/sysconfig/network-scripts/ifcfg-eth0"'
img_run_cmd 'echo ONBOOT="yes" >> /etc/sysconfig/network-scripts/ifcfg-eth0'
img_run_cmd 'echo PREFIX="24" >> /etc/sysconfig/network-scripts/ifcfg-eth0'
img_run_cmd 'echo IPADDR="192.168.77.1" >> /etc/sysconfig/network-scripts/ifcfg-eth0'
img_run_cmd 'echo TYPE="Ethernet" >> /etc/sysconfig/network-scripts/ifcfg-eth0'
img_add_qemu_cmd "-nic socket,listen=:8010,mac=52:54:00:12:34:56"
}
# Executed when VM boots
on_test() {
while true; do
if has_valid_vmcore_dir /srv/nfs/var/crash; then
# Wait a few seconds so client finish it's work to generate a full log
sleep 5
test_passed
fi
sleep 1
done
}

View File

@ -0,0 +1,30 @@
# Executed before VM starts
on_build() {
img_inst_pkg "nfs-utils"
img_add_qemu_cmd "-nic socket,connect=127.0.0.1:8010,mac=52:54:00:12:34:57"
}
on_test() {
local boot_count=$(get_test_boot_count)
local nfs_server=192.168.77.1
if [ "$boot_count" -eq 1 ]; then
cat << EOF > /etc/kdump.conf
nfs $nfs_server:/srv/nfs
core_collector makedumpfile -l --message-level 7 -d 31
EOF
while ! ping -c 1 $nfs_server -W 1; do
sleep 1
done
kdumpctl start || test_failed "Failed to start kdump"
sync
echo 1 > /proc/sys/kernel/sysrq
echo c > /proc/sysrq-trigger
else
shutdown -h 0
fi
}

View File

@ -0,0 +1,37 @@
#!/usr/bin/env sh
# Executed before VM starts
on_build() {
img_add_qemu_cmd "-nic socket,listen=:8010,mac=52:54:00:12:34:56"
img_run_cmd "echo root:fedora | chpasswd"
img_run_cmd 'sed -i "s/^.*PasswordAuthentication .*\$/PasswordAuthentication yes/" /etc/ssh/sshd_config'
img_run_cmd 'sed -i "s/^.*PermitRootLogin .*\$/PermitRootLogin yes/" /etc/ssh/sshd_config'
img_run_cmd "systemctl enable sshd"
img_run_cmd "touch /etc/systemd/resolved.conf"
img_run_cmd "echo DNSStubListener=no >> /etc/systemd/resolved.conf"
img_run_cmd "echo interface=eth0 > /etc/dnsmasq.conf"
img_run_cmd "echo dhcp-authoritative >> /etc/dnsmasq.conf"
img_run_cmd "echo dhcp-range=192.168.77.50,192.168.77.100,255.255.255.0,12h >> /etc/dnsmasq.conf"
img_run_cmd "systemctl enable dnsmasq"
img_run_cmd 'echo DEVICE="eth0" > /etc/sysconfig/network-scripts/ifcfg-eth0'
img_run_cmd 'echo BOOTPROTO="none >> /etc/sysconfig/network-scripts/ifcfg-eth0"'
img_run_cmd 'echo ONBOOT="yes" >> /etc/sysconfig/network-scripts/ifcfg-eth0'
img_run_cmd 'echo PREFIX="24" >> /etc/sysconfig/network-scripts/ifcfg-eth0'
img_run_cmd 'echo IPADDR="192.168.77.1" >> /etc/sysconfig/network-scripts/ifcfg-eth0'
img_run_cmd 'echo TYPE="Ethernet" >> /etc/sysconfig/network-scripts/ifcfg-eth0'
}
# Executed when VM boots
on_test() {
while true; do
if has_valid_vmcore_dir /var/crash; then
test_passed
fi
sleep 1
done
}

View File

@ -0,0 +1,42 @@
# Executed before VM starts
on_build() {
img_inst_pkg "sshpass"
img_add_qemu_cmd "-nic socket,connect=127.0.0.1:8010,mac=52:54:00:12:34:57"
}
on_test() {
local boot_count=$(get_test_boot_count)
local ssh_server=192.168.77.1
if [ "$boot_count" -eq 1 ]; then
cat << EOF > /etc/kdump.conf
ssh root@192.168.77.1
core_collector makedumpfile -l --message-level 7 -d 31 -F
EOF
ssh-keygen -q -t rsa -N '' -f /root/.ssh/id_rsa <<< y
while ! ping -c 1 $ssh_server -W 1; do
sleep 1
done
while [ -z "$(cat /root/.ssh/known_hosts)" ]; do
ssh-keyscan -H 192.168.77.1 > /root/.ssh/known_hosts
done
sshpass -p fedora ssh $ssh_server "mkdir /root/.ssh"
cat /root/.ssh/id_rsa.pub | sshpass -p fedora ssh $ssh_server "cat >> /root/.ssh/authorized_keys"
sshpass -p fedora kdumpctl propagate
cat /root/.ssh/kdump_id_rsa.pub | sshpass -p fedora ssh $ssh_server "cat >> /root/.ssh/authorized_keys"
kdumpctl start || test_failed "Failed to start kdump"
sync
echo 1 > /proc/sys/kernel/sysrq
echo c > /proc/sysrq-trigger
else
shutdown -h 0
fi
}

79
zanata-notes.txt Normal file
View File

@ -0,0 +1,79 @@
Zanata is a web-based system for managing localisation projects.
For kexec-tools firstboot module, I created a zanata project with name of
"kexec-tools": https://translate.zanata.org/zanata/project/view/kexec-tools
There's several clients available for zanata translation management, such as
python client and Maven client. It's suggested to use maven client for latest
zanata issues
Firstly you need install mvn rpms, just do below for fedora 16 and beyond:
yum install maven
create zanata.ini in your home dir:
>~/.config/zanata.ini
There should be something need to change like below:
translate_zanata_org.url=https://translate.zanata.org/zanata/
translate_zanata_org.username=
translate_zanata_org.key=
Change username to your zanata username
Change the key to the "API key" of zanata which can be generate from
zanata web page.
Open user profile page of zanata.org, click "Generate API Key" to create it.
zanata is a plugin of maven, to activate it, you need do below configurations:
1. cd kexec-tools/po, (assume kexec-tools is the git repo)
2. add a pom.xml like below: (note: version 2.0.0 is better than 1.7.5
for performance improvement)
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.zanata</groupId>
<artifactId>zanata-maven-plugin</artifactId>
<version>1.7.5</version>
</plugin>
</plugins>
</build>
...
</project>
3. add zanata.xml for your project with content like below:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<config xmlns="http://zanata.org/namespace/config/">
<url>https://translate.zanata.org/zanata/</url>
<project>kexec-tools</project>
<project-version>F18</project-version>
<project-type>gettext</project-type>
<locales>
<locale>ar</locale>
...
</config>
You can get mostly-complete zanata.xml from the project version page on zanata
Things need to be modified is:
a) project-type, please use gettext
b) for locales which are diffrent between local name and zanata server name,
for example for kexec-tools we have bn_IN but zanata server accept bn-IN,
so we need to add below line:
<locale map-from="bn_IN">bn-IN</locale>
The first running of "mvn zanata:help" will download and activate the new
version of zanata plugin for you.
I use below command to upload both pot file and translated po files:
mvn zanata:push -Dzanata.pushType=both
If you only need to upload po files, you can use:
mvn zanata:push -Dzanata.pushType=trans
You can use mvn zanata:help to lookup the detail help content of param names
The other thing to be careful is specifying the correct source and
translation directories.
They are relative path. You can also put the pom.xml and zanata.xml under toplevel directory and run:
mvn zanata:push -Dzanata.pushType=both -Dzanata.srcDir=po -Dzanata.transDir=po
--
[1] https://github.com/zanata/zanata/wiki/Zanata-Maven-Integration
[2] https://github.com/zanata/zanata/wiki/client-configuration