Compare commits
No commits in common. "c8" and "c9s" have entirely different histories.
32
.editorconfig
Normal file
32
.editorconfig
Normal 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
26
.gitignore
vendored
@ -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
|
||||
|
@ -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
31
60-fadump.install
Executable 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
13
92-crashkernel.install
Executable 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
|
@ -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
4
99-kdump.conf
Normal file
@ -0,0 +1,4 @@
|
||||
dracutmodules=''
|
||||
add_dracutmodules=' kdumpbase '
|
||||
omit_dracutmodules=' plymouth resume ifcfg earlykdump '
|
||||
omit_drivers+=' nouveau amdgpu '
|
12
README
Normal file
12
README
Normal 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
|
@ -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
|
@ -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
|
@ -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
@ -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
|
||||
}
|
1113
SOURCES/kdump-lib.sh
1113
SOURCES/kdump-lib.sh
File diff suppressed because it is too large
Load Diff
1385
SOURCES/kdumpctl
1385
SOURCES/kdumpctl
File diff suppressed because it is too large
Load Diff
@ -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)
|
@ -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
|
||||
|
452
SOURCES/mkdumprd
452
SOURCES/mkdumprd
@ -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
|
@ -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)"
|
@ -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
|
||||
|
@ -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
120
crashkernel-howto.txt
Normal 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.
|
@ -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"
|
@ -15,8 +15,7 @@ EARLY_KEXEC_ARGS=""
|
||||
. /lib/kdump-logger.sh
|
||||
|
||||
# initiate the kdump logger
|
||||
dlog_init
|
||||
if [ $? -ne 0 ]; then
|
||||
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
|
@ -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
674
dracut-kdump.sh
Executable 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
1195
dracut-module-setup.sh
Executable file
File diff suppressed because it is too large
Load Diff
@ -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
6
gating.yaml
Normal 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}
|
@ -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
188
kdump-lib-initramfs.sh
Executable 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
1249
kdump-lib.sh
Executable file
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
}
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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)
|
@ -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:
|
@ -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:
|
@ -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)
|
@ -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)
|
85
kdumpctl.8
Normal file
85
kdumpctl.8
Normal 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)
|
@ -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
39
kexec-update-manpage-with-explicit-mention-of-clean-.patch
Normal file
39
kexec-update-manpage-with-explicit-mention-of-clean-.patch
Normal 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
|
||||
|
44
kexec_file-add-kexec_file-flag-to-support-debug-prin.patch
Normal file
44
kexec_file-add-kexec_file-flag-to-support-debug-prin.patch
Normal 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
490
mkdumprd
Normal 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
|
@ -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
|
||||
if ! dracut --force --quiet $_dracut_isolate_args $@ "$TARGET_INITRD"; then
|
||||
fi
|
||||
|
||||
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
3
sources
Normal 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
|
@ -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
88
tests/Makefile
Normal 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
65
tests/README
Normal 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
57
tests/scripts/build-image.sh
Executable 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
|
10
tests/scripts/build-scripts/base-image.sh
Executable file
10
tests/scripts/build-scripts/base-image.sh
Executable 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"
|
21
tests/scripts/build-scripts/test-base-image.sh
Executable file
21
tests/scripts/build-scripts/test-base-image.sh
Executable 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"
|
21
tests/scripts/build-scripts/test-image.sh
Executable file
21
tests/scripts/build-scripts/test-image.sh
Executable 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)
|
25
tests/scripts/copy-from-image.sh
Executable file
25
tests/scripts/copy-from-image.sh
Executable 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
|
256
tests/scripts/image-init-lib.sh
Normal file
256
tests/scripts/image-init-lib.sh
Normal 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
|
||||
}
|
122
tests/scripts/kexec-kdump-test/init.sh
Executable file
122
tests/scripts/kexec-kdump-test/init.sh
Executable 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"
|
9
tests/scripts/kexec-kdump-test/kexec-kdump-test.service
Normal file
9
tests/scripts/kexec-kdump-test/kexec-kdump-test.service
Normal 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
|
15
tests/scripts/kexec-kdump-test/test.sh
Executable file
15
tests/scripts/kexec-kdump-test/test.sh
Executable 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
148
tests/scripts/run-test.sh
Executable 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
|
16
tests/scripts/spawn-image-shell.sh
Executable file
16
tests/scripts/spawn-image-shell.sh
Executable 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
177
tests/scripts/test-lib.sh
Normal 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
|
||||
}
|
32
tests/scripts/testcases/local-kdump/0-local.sh
Executable file
32
tests/scripts/testcases/local-kdump/0-local.sh
Executable 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
|
||||
}
|
41
tests/scripts/testcases/nfs-kdump/0-server.sh
Executable file
41
tests/scripts/testcases/nfs-kdump/0-server.sh
Executable 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
|
||||
}
|
30
tests/scripts/testcases/nfs-kdump/1-client.sh
Executable file
30
tests/scripts/testcases/nfs-kdump/1-client.sh
Executable 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
|
||||
}
|
37
tests/scripts/testcases/ssh-kdump/0-server.sh
Executable file
37
tests/scripts/testcases/ssh-kdump/0-server.sh
Executable 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
|
||||
}
|
42
tests/scripts/testcases/ssh-kdump/1-client.sh
Executable file
42
tests/scripts/testcases/ssh-kdump/1-client.sh
Executable 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
79
zanata-notes.txt
Normal 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
|
Loading…
Reference in New Issue
Block a user