import kexec-tools-2.0.20-34.el8_3.1
This commit is contained in:
commit
89a2b3181d
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
SOURCES/eppic_050615.tar.gz
|
||||
SOURCES/kexec-tools-2.0.20.tar.xz
|
||||
SOURCES/makedumpfile-1.6.7.tar.gz
|
3
.kexec-tools.metadata
Normal file
3
.kexec-tools.metadata
Normal file
@ -0,0 +1,3 @@
|
||||
a096c8e0892b559f40b01916aae240652f75b68a SOURCES/eppic_050615.tar.gz
|
||||
5d9acd2e741d356d4a48fe4f2d63f66ba431051d SOURCES/kexec-tools-2.0.20.tar.xz
|
||||
42941a0219d57d99909616778835e5d9ba890711 SOURCES/makedumpfile-1.6.7.tar.gz
|
16
SOURCES/98-kexec.rules
Normal file
16
SOURCES/98-kexec.rules
Normal file
@ -0,0 +1,16 @@
|
||||
SUBSYSTEM=="cpu", ACTION=="add", GOTO="kdump_reload"
|
||||
SUBSYSTEM=="cpu", ACTION=="remove", GOTO="kdump_reload"
|
||||
SUBSYSTEM=="memory", ACTION=="online", GOTO="kdump_reload"
|
||||
SUBSYSTEM=="memory", ACTION=="offline", GOTO="kdump_reload"
|
||||
|
||||
GOTO="kdump_reload_end"
|
||||
|
||||
LABEL="kdump_reload"
|
||||
|
||||
# If kdump is not loaded, calling kdump-udev-throttle will end up
|
||||
# doing nothing, but systemd-run will always generate extra logs for
|
||||
# each call, so trigger the kdump-udev-throttler only if kdump
|
||||
# service is active to avoid unnecessary logs
|
||||
RUN+="/bin/sh -c '/usr/bin/systemctl is-active kdump.service || exit 0; /usr/bin/systemd-run --quiet --no-block /usr/lib/udev/kdump-udev-throttler'"
|
||||
|
||||
LABEL="kdump_reload_end"
|
15
SOURCES/98-kexec.rules.ppc64
Normal file
15
SOURCES/98-kexec.rules.ppc64
Normal file
@ -0,0 +1,15 @@
|
||||
SUBSYSTEM=="cpu", ACTION=="online", GOTO="kdump_reload"
|
||||
SUBSYSTEM=="memory", ACTION=="online", GOTO="kdump_reload"
|
||||
SUBSYSTEM=="memory", ACTION=="offline", GOTO="kdump_reload"
|
||||
|
||||
GOTO="kdump_reload_end"
|
||||
|
||||
LABEL="kdump_reload"
|
||||
|
||||
# If kdump is not loaded, calling kdump-udev-throttle will end up
|
||||
# doing nothing, but systemd-run will always generate extra logs for
|
||||
# each call, so trigger the kdump-udev-throttler only if kdump
|
||||
# service is active to avoid unnecessary logs
|
||||
RUN+="/bin/sh -c '/usr/bin/systemctl is-active kdump.service || exit 0; /usr/bin/systemd-run --quiet --no-block /usr/lib/udev/kdump-udev-throttler'"
|
||||
|
||||
LABEL="kdump_reload_end"
|
65
SOURCES/dracut-early-kdump-module-setup.sh
Executable file
65
SOURCES/dracut-early-kdump-module-setup.sh
Executable file
@ -0,0 +1,65 @@
|
||||
#!/bin/bash
|
||||
|
||||
. /etc/sysconfig/kdump
|
||||
. /lib/kdump/kdump-lib.sh
|
||||
|
||||
KDUMP_KERNEL=""
|
||||
KDUMP_INITRD=""
|
||||
|
||||
check() {
|
||||
if [ ! -f /etc/sysconfig/kdump ] || [ ! -f /lib/kdump/kdump-lib.sh ]\
|
||||
|| [ -n "${IN_KDUMP}" ]
|
||||
then
|
||||
return 1
|
||||
fi
|
||||
return 255
|
||||
}
|
||||
|
||||
depends() {
|
||||
echo "base shutdown"
|
||||
return 0
|
||||
}
|
||||
|
||||
prepare_kernel_initrd() {
|
||||
KDUMP_BOOTDIR=$(check_boot_dir "${KDUMP_BOOTDIR}")
|
||||
if [ -z "$KDUMP_KERNELVER" ]; then
|
||||
kdump_kver=`uname -r`
|
||||
if [ "$kernel" != "$kdump_kver" ]; then
|
||||
dwarn "Using current kernel version '$kdump_kver' for early kdump," \
|
||||
"but the initramfs is generated for kernel version '$kernel'"
|
||||
fi
|
||||
else
|
||||
kdump_kver=$KDUMP_KERNELVER
|
||||
fi
|
||||
KDUMP_KERNEL="${KDUMP_BOOTDIR}/${KDUMP_IMG}-${kdump_kver}${KDUMP_IMG_EXT}"
|
||||
KDUMP_INITRD="${KDUMP_BOOTDIR}/initramfs-${kdump_kver}kdump.img"
|
||||
}
|
||||
|
||||
install() {
|
||||
prepare_kernel_initrd
|
||||
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
|
||||
derror "Could not find required kdump initramfs for earlykdump," \
|
||||
"please ensure kdump initramfs is generated first," \
|
||||
"earlykdump will not work!"
|
||||
return 1
|
||||
fi
|
||||
|
||||
inst_multiple tail find cut dirname hexdump
|
||||
inst_simple "/etc/sysconfig/kdump"
|
||||
inst_binary "/usr/sbin/kexec"
|
||||
inst_binary "/usr/bin/gawk" "/usr/bin/awk"
|
||||
inst_script "/lib/kdump/kdump-lib.sh" "/lib/kdump-lib.sh"
|
||||
inst_hook cmdline 00 "$moddir/early-kdump.sh"
|
||||
inst_binary "$KDUMP_KERNEL"
|
||||
inst_binary "$KDUMP_INITRD"
|
||||
|
||||
ln_r "$KDUMP_KERNEL" "${KDUMP_BOOTDIR}/${KDUMP_IMG}-earlykdump${KDUMP_IMG_EXT}"
|
||||
ln_r "$KDUMP_INITRD" "${KDUMP_BOOTDIR}/initramfs-earlykdump.img"
|
||||
|
||||
chmod -x "${initdir}/$KDUMP_KERNEL"
|
||||
}
|
75
SOURCES/dracut-early-kdump.sh
Executable file
75
SOURCES/dracut-early-kdump.sh
Executable file
@ -0,0 +1,75 @@
|
||||
#! /bin/sh
|
||||
|
||||
KEXEC=/sbin/kexec
|
||||
standard_kexec_args="-p"
|
||||
|
||||
EARLY_KDUMP_INITRD=""
|
||||
EARLY_KDUMP_KERNEL=""
|
||||
EARLY_KDUMP_CMDLINE=""
|
||||
EARLY_KDUMP_KERNELVER=""
|
||||
EARLY_KEXEC_ARGS=""
|
||||
|
||||
. /etc/sysconfig/kdump
|
||||
. /lib/dracut-lib.sh
|
||||
. /lib/kdump-lib.sh
|
||||
|
||||
prepare_parameters()
|
||||
{
|
||||
EARLY_KDUMP_CMDLINE=$(prepare_cmdline "${KDUMP_COMMANDLINE}" "${KDUMP_COMMANDLINE_REMOVE}" "${KDUMP_COMMANDLINE_APPEND}")
|
||||
KDUMP_BOOTDIR=$(check_boot_dir "${KDUMP_BOOTDIR}")
|
||||
|
||||
EARLY_KDUMP_KERNEL="${KDUMP_BOOTDIR}/${KDUMP_IMG}-earlykdump${KDUMP_IMG_EXT}"
|
||||
EARLY_KDUMP_INITRD="${KDUMP_BOOTDIR}/initramfs-earlykdump.img"
|
||||
}
|
||||
|
||||
early_kdump_load()
|
||||
{
|
||||
check_kdump_feasibility
|
||||
if [ $? -ne 0 ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
if is_fadump_capable; then
|
||||
echo "WARNING: early kdump doesn't support fadump."
|
||||
return 1
|
||||
fi
|
||||
|
||||
check_current_kdump_status
|
||||
if [ $? == 0 ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
prepare_parameters
|
||||
|
||||
EARLY_KEXEC_ARGS=$(prepare_kexec_args "${KEXEC_ARGS}")
|
||||
|
||||
if is_secure_boot_enforced; then
|
||||
echo "Secure Boot is enabled. Using kexec file based syscall."
|
||||
EARLY_KEXEC_ARGS="$EARLY_KEXEC_ARGS -s"
|
||||
fi
|
||||
|
||||
$KEXEC ${EARLY_KEXEC_ARGS} $standard_kexec_args \
|
||||
--command-line="$EARLY_KDUMP_CMDLINE" \
|
||||
--initrd=$EARLY_KDUMP_INITRD $EARLY_KDUMP_KERNEL
|
||||
if [ $? == 0 ]; then
|
||||
echo "kexec: loaded early-kdump kernel"
|
||||
return 0
|
||||
else
|
||||
echo "kexec: failed to load early-kdump kernel"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
set_early_kdump()
|
||||
{
|
||||
if getargbool 0 rd.earlykdump; then
|
||||
echo "early-kdump is enabled."
|
||||
early_kdump_load
|
||||
else
|
||||
echo "early-kdump is disabled."
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
set_early_kdump
|
30
SOURCES/dracut-kdump-capture.service
Normal file
30
SOURCES/dracut-kdump-capture.service
Normal file
@ -0,0 +1,30 @@
|
||||
# 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.
|
||||
|
||||
[Unit]
|
||||
Description=Kdump Vmcore Save Service
|
||||
After=initrd.target initrd-parse-etc.service sysroot.mount
|
||||
After=dracut-initqueue.service dracut-pre-mount.service dracut-mount.service dracut-pre-pivot.service
|
||||
Before=initrd-cleanup.service
|
||||
ConditionPathExists=/etc/initrd-release
|
||||
OnFailure=emergency.target
|
||||
OnFailureJobMode=isolate
|
||||
|
||||
[Service]
|
||||
Environment=DRACUT_SYSTEMD=1
|
||||
Environment=NEWROOT=/sysroot
|
||||
Type=oneshot
|
||||
ExecStart=/bin/kdump.sh
|
||||
StandardInput=null
|
||||
StandardOutput=syslog
|
||||
StandardError=syslog+console
|
||||
KillMode=process
|
||||
RemainAfterExit=yes
|
||||
|
||||
# Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash
|
||||
# terminates cleanly.
|
||||
KillSignal=SIGHUP
|
28
SOURCES/dracut-kdump-emergency.service
Normal file
28
SOURCES/dracut-kdump-emergency.service
Normal file
@ -0,0 +1,28 @@
|
||||
# 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
|
14
SOURCES/dracut-kdump-emergency.target
Normal file
14
SOURCES/dracut-kdump-emergency.target
Normal file
@ -0,0 +1,14 @@
|
||||
# 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.
|
||||
|
||||
[Unit]
|
||||
Description=Emergency Mode
|
||||
Documentation=man:systemd.special(7)
|
||||
Requires=emergency.service
|
||||
After=emergency.service
|
||||
AllowIsolate=yes
|
||||
IgnoreOnIsolate=yes
|
33
SOURCES/dracut-kdump-error-handler.service
Normal file
33
SOURCES/dracut-kdump-error-handler.service
Normal file
@ -0,0 +1,33 @@
|
||||
# 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
|
||||
|
||||
[Unit]
|
||||
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
|
||||
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
|
10
SOURCES/dracut-kdump-error-handler.sh
Executable file
10
SOURCES/dracut-kdump-error-handler.sh
Executable file
@ -0,0 +1,10 @@
|
||||
#!/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
|
271
SOURCES/dracut-kdump.sh
Executable file
271
SOURCES/dracut-kdump.sh
Executable file
@ -0,0 +1,271 @@
|
||||
#!/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
|
||||
|
||||
exec &> /dev/console
|
||||
. /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
|
||||
echo "kdump: saving vmcore failed"
|
||||
fi
|
||||
|
||||
return $_ret
|
||||
}
|
||||
|
||||
do_kdump_pre()
|
||||
{
|
||||
local _ret
|
||||
|
||||
if [ -n "$KDUMP_PRE" ]; then
|
||||
"$KDUMP_PRE"
|
||||
_ret=$?
|
||||
if [ $_ret -ne 0 ]; then
|
||||
echo "kdump: $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
|
||||
echo "kdump: $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
|
||||
echo "kdump: $file exited with $_ret status"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if [ -n "$KDUMP_POST" ]; then
|
||||
"$KDUMP_POST" "$1"
|
||||
_ret=$?
|
||||
if [ $_ret -ne 0 ]; then
|
||||
echo "kdump: $KDUMP_POST exited with $_ret status"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
add_dump_code()
|
||||
{
|
||||
DUMP_INSTRUCTION=$1
|
||||
}
|
||||
|
||||
dump_raw()
|
||||
{
|
||||
local _raw=$1
|
||||
|
||||
[ -b "$_raw" ] || return 1
|
||||
|
||||
echo "kdump: saving to raw disk $_raw"
|
||||
|
||||
if ! $(echo -n $CORE_COLLECTOR|grep -q makedumpfile); then
|
||||
_src_size=`ls -l /proc/vmcore | cut -d' ' -f5`
|
||||
_src_size_mb=$(($_src_size / 1048576))
|
||||
monitor_dd_progress $_src_size_mb &
|
||||
fi
|
||||
|
||||
echo "kdump: saving vmcore"
|
||||
$CORE_COLLECTOR /proc/vmcore | dd of=$_raw bs=$DD_BLKSIZE >> /tmp/dd_progress_file 2>&1 || return 1
|
||||
sync
|
||||
|
||||
echo "kdump: saving vmcore complete"
|
||||
return 0
|
||||
}
|
||||
|
||||
dump_ssh()
|
||||
{
|
||||
local _opt="-i $1 -o BatchMode=yes -o StrictHostKeyChecking=yes"
|
||||
local _dir="$KDUMP_PATH/$HOST_IP-$DATEDIR"
|
||||
local _host=$2
|
||||
|
||||
echo "kdump: saving to $_host:$_dir"
|
||||
|
||||
cat /var/lib/random-seed > /dev/urandom
|
||||
ssh -q $_opt $_host mkdir -p $_dir || return 1
|
||||
|
||||
save_vmcore_dmesg_ssh ${DMESG_COLLECTOR} ${_dir} "${_opt}" $_host
|
||||
save_opalcore_ssh ${_dir} "${_opt}" $_host
|
||||
|
||||
echo "kdump: saving vmcore"
|
||||
|
||||
if [ "${CORE_COLLECTOR%%[[:blank:]]*}" = "scp" ]; then
|
||||
scp -q $_opt /proc/vmcore "$_host:$_dir/vmcore-incomplete" || return 1
|
||||
ssh $_opt $_host "mv $_dir/vmcore-incomplete $_dir/vmcore" || return 1
|
||||
else
|
||||
$CORE_COLLECTOR /proc/vmcore | ssh $_opt $_host "dd bs=512 of=$_dir/vmcore-incomplete" || return 1
|
||||
ssh $_opt $_host "mv $_dir/vmcore-incomplete $_dir/vmcore.flat" || return 1
|
||||
fi
|
||||
|
||||
echo "kdump: saving vmcore complete"
|
||||
return 0
|
||||
}
|
||||
|
||||
save_opalcore_ssh() {
|
||||
local _path=$1
|
||||
local _opts="$2"
|
||||
local _location=$3
|
||||
|
||||
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
|
||||
|
||||
echo "kdump: saving opalcore"
|
||||
scp $_opts $OPALCORE $_location:$_path/opalcore-incomplete
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "kdump: saving opalcore failed"
|
||||
return 1
|
||||
fi
|
||||
|
||||
ssh $_opts $_location mv $_path/opalcore-incomplete $_path/opalcore
|
||||
echo "kdump: saving opalcore complete"
|
||||
return 0
|
||||
}
|
||||
|
||||
save_vmcore_dmesg_ssh() {
|
||||
local _dmesg_collector=$1
|
||||
local _path=$2
|
||||
local _opts="$3"
|
||||
local _location=$4
|
||||
|
||||
echo "kdump: saving vmcore-dmesg.txt"
|
||||
$_dmesg_collector /proc/vmcore | ssh $_opts $_location "dd of=$_path/vmcore-dmesg-incomplete.txt"
|
||||
_exitcode=$?
|
||||
|
||||
if [ $_exitcode -eq 0 ]; then
|
||||
ssh -q $_opts $_location mv $_path/vmcore-dmesg-incomplete.txt $_path/vmcore-dmesg.txt
|
||||
echo "kdump: saving vmcore-dmesg.txt complete"
|
||||
else
|
||||
echo "kdump: saving vmcore-dmesg.txt failed"
|
||||
fi
|
||||
}
|
||||
|
||||
get_host_ip()
|
||||
{
|
||||
local _host
|
||||
if is_nfs_dump_target || is_ssh_dump_target
|
||||
then
|
||||
kdumpnic=$(getarg kdumpnic=)
|
||||
[ -z "$kdumpnic" ] && echo "kdump: failed to get kdumpnic!" && return 1
|
||||
_host=`ip addr show dev $kdumpnic|grep '[ ]*inet'`
|
||||
[ $? -ne 0 ] && echo "kdump: wrong kdumpnic: $kdumpnic" && return 1
|
||||
_host=`echo $_host | head -n 1 | cut -d' ' -f2`
|
||||
_host="${_host%%/*}"
|
||||
[ -z "$_host" ] && echo "kdump: wrong kdumpnic: $kdumpnic" && return 1
|
||||
HOST_IP=$_host
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
read_kdump_conf()
|
||||
{
|
||||
if [ ! -f "$KDUMP_CONF" ]; then
|
||||
echo "kdump: $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
|
||||
echo "kdump: 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
|
||||
echo "kdump: 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
|
||||
echo "kdump: kdump_post script exited with non-zero status!"
|
||||
fi
|
||||
|
||||
if [ $DUMP_RETVAL -ne 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
do_final_action
|
840
SOURCES/dracut-module-setup.sh
Executable file
840
SOURCES/dracut-module-setup.sh
Executable file
@ -0,0 +1,840 @@
|
||||
#!/bin/bash
|
||||
|
||||
. $dracutfunctions
|
||||
. /lib/kdump/kdump-lib.sh
|
||||
|
||||
if ! [[ -d "${initdir}/tmp" ]]; then
|
||||
mkdir -p "${initdir}/tmp"
|
||||
fi
|
||||
|
||||
check() {
|
||||
[[ $debug ]] && set -x
|
||||
#kdumpctl sets this explicitly
|
||||
if [ -z "$IN_KDUMP" ] || [ ! -f /etc/kdump.conf ]
|
||||
then
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
depends() {
|
||||
local _dep="base shutdown"
|
||||
|
||||
is_squash_available() {
|
||||
for kmodule in squashfs overlay loop; do
|
||||
if [ -z "$KDUMP_KERNELVER" ]; then
|
||||
modprobe --dry-run $kmodule &>/dev/null || return 1
|
||||
else
|
||||
modprobe -S $KDUMP_KERNELVER --dry-run $kmodule &>/dev/null || return 1
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
if is_squash_available && ! is_fadump_capable; then
|
||||
_dep="$_dep squash"
|
||||
else
|
||||
dwarning "Required modules to build a squashed kdump image is missing!"
|
||||
fi
|
||||
|
||||
if [ -n "$( find /sys/devices -name drm )" ] || [ -d /sys/module/hyperv_fb ]; then
|
||||
_dep="$_dep drm"
|
||||
fi
|
||||
|
||||
if is_generic_fence_kdump || is_pcs_fence_kdump; then
|
||||
_dep="$_dep network"
|
||||
fi
|
||||
|
||||
echo $_dep
|
||||
return 0
|
||||
}
|
||||
|
||||
kdump_is_bridge() {
|
||||
[ -d /sys/class/net/"$1"/bridge ]
|
||||
}
|
||||
|
||||
kdump_is_bond() {
|
||||
[ -d /sys/class/net/"$1"/bonding ]
|
||||
}
|
||||
|
||||
kdump_is_team() {
|
||||
[ -f /usr/bin/teamnl ] && teamnl $1 ports &> /dev/null
|
||||
}
|
||||
|
||||
kdump_is_vlan() {
|
||||
[ -f /proc/net/vlan/"$1" ]
|
||||
}
|
||||
|
||||
# $1: netdev name
|
||||
source_ifcfg_file() {
|
||||
local ifcfg_file
|
||||
|
||||
ifcfg_file=$(get_ifcfg_filename $1)
|
||||
if [ -f "${ifcfg_file}" ]; then
|
||||
. ${ifcfg_file}
|
||||
else
|
||||
dwarning "The ifcfg file of $1 is not found!"
|
||||
fi
|
||||
}
|
||||
|
||||
# $1: netdev name
|
||||
kdump_setup_dns() {
|
||||
local _nameserver _dns
|
||||
local _dnsfile=${initdir}/etc/cmdline.d/42dns.conf
|
||||
|
||||
source_ifcfg_file $1
|
||||
|
||||
[ -n "$DNS1" ] && echo "nameserver=$DNS1" > "$_dnsfile"
|
||||
[ -n "$DNS2" ] && echo "nameserver=$DNS2" >> "$_dnsfile"
|
||||
|
||||
while read content;
|
||||
do
|
||||
_nameserver=$(echo $content | grep ^nameserver)
|
||||
[ -z "$_nameserver" ] && continue
|
||||
|
||||
_dns=$(echo $_nameserver | cut -d' ' -f2)
|
||||
[ -z "$_dns" ] && continue
|
||||
|
||||
if [ ! -f $_dnsfile ] || [ ! $(cat $_dnsfile | grep -q $_dns) ]; then
|
||||
echo "nameserver=$_dns" >> "$_dnsfile"
|
||||
fi
|
||||
done < "/etc/resolv.conf"
|
||||
}
|
||||
|
||||
#$1: netdev name
|
||||
#$2: srcaddr
|
||||
#if it use static ip echo it, or echo null
|
||||
kdump_static_ip() {
|
||||
local _netdev="$1" _srcaddr="$2" _ipv6_flag
|
||||
local _netmask _gateway _ipaddr _target _nexthop
|
||||
|
||||
_ipaddr=$(ip addr show dev $_netdev permanent | awk "/ $_srcaddr\/.* /{print \$2}")
|
||||
|
||||
if is_ipv6_address $_srcaddr; then
|
||||
_ipv6_flag="-6"
|
||||
fi
|
||||
|
||||
if [ -n "$_ipaddr" ]; then
|
||||
_gateway=$(ip $_ipv6_flag route list dev $_netdev | \
|
||||
awk '/^default /{print $3}' | head -n 1)
|
||||
|
||||
if [ "x" != "x"$_ipv6_flag ]; then
|
||||
# _ipaddr="2002::56ff:feb6:56d5/64", _netmask is the number after "/"
|
||||
_netmask=${_ipaddr#*\/}
|
||||
_srcaddr="[$_srcaddr]"
|
||||
_gateway="[$_gateway]"
|
||||
else
|
||||
_netmask=$(ipcalc -m $_ipaddr | cut -d'=' -f2)
|
||||
fi
|
||||
echo -n "${_srcaddr}::${_gateway}:${_netmask}::"
|
||||
fi
|
||||
|
||||
/sbin/ip $_ipv6_flag route show | grep -v default | grep ".*via.* $_netdev " |\
|
||||
while read _route; do
|
||||
_target=`echo $_route | cut -d ' ' -f1`
|
||||
_nexthop=`echo $_route | cut -d ' ' -f3`
|
||||
if [ "x" != "x"$_ipv6_flag ]; then
|
||||
_target="[$_target]"
|
||||
_nexthop="[$_nexthop]"
|
||||
fi
|
||||
echo "rd.route=$_target:$_nexthop:$_netdev"
|
||||
done >> ${initdir}/etc/cmdline.d/45route-static.conf
|
||||
}
|
||||
|
||||
kdump_get_mac_addr() {
|
||||
cat /sys/class/net/$1/address
|
||||
}
|
||||
|
||||
#Bonding or team master modifies the mac address
|
||||
#of its slaves, we should use perm address
|
||||
kdump_get_perm_addr() {
|
||||
local addr=$(ethtool -P $1 | sed -e 's/Permanent address: //')
|
||||
if [ -z "$addr" ] || [ "$addr" = "00:00:00:00:00:00" ]
|
||||
then
|
||||
derror "Can't get the permanent address of $1"
|
||||
else
|
||||
echo "$addr"
|
||||
fi
|
||||
}
|
||||
|
||||
# Prefix kernel assigned names with "kdump-". EX: eth0 -> kdump-eth0
|
||||
# Because kernel assigned names are not persistent between 1st and 2nd
|
||||
# kernel. We could probably end up with eth0 being eth1, eth0 being
|
||||
# eth1, and naming conflict happens.
|
||||
kdump_setup_ifname() {
|
||||
local _ifname
|
||||
|
||||
# If ifname already has 'kdump-' prefix, we must be switching from
|
||||
# fadump to kdump. Skip prefixing 'kdump-' in this case as adding
|
||||
# another prefix may truncate the ifname. Since an ifname with
|
||||
# 'kdump-' is already persistent, this should be fine.
|
||||
if [[ $1 =~ eth* ]] && [[ ! $1 =~ ^kdump-* ]]; then
|
||||
_ifname="kdump-$1"
|
||||
else
|
||||
_ifname="$1"
|
||||
fi
|
||||
|
||||
echo "$_ifname"
|
||||
}
|
||||
|
||||
kdump_setup_bridge() {
|
||||
local _netdev=$1
|
||||
local _brif _dev _mac _kdumpdev
|
||||
for _dev in `ls /sys/class/net/$_netdev/brif/`; do
|
||||
_kdumpdev=$_dev
|
||||
if kdump_is_bond "$_dev"; then
|
||||
kdump_setup_bond "$_dev"
|
||||
elif kdump_is_team "$_dev"; then
|
||||
kdump_setup_team "$_dev"
|
||||
elif kdump_is_vlan "$_dev"; then
|
||||
kdump_setup_vlan "$_dev"
|
||||
else
|
||||
_mac=$(kdump_get_mac_addr $_dev)
|
||||
_kdumpdev=$(kdump_setup_ifname $_dev)
|
||||
echo -n " ifname=$_kdumpdev:$_mac" >> ${initdir}/etc/cmdline.d/41bridge.conf
|
||||
fi
|
||||
_brif+="$_kdumpdev,"
|
||||
done
|
||||
echo " bridge=$_netdev:$(echo $_brif | sed -e 's/,$//')" >> ${initdir}/etc/cmdline.d/41bridge.conf
|
||||
}
|
||||
|
||||
kdump_setup_bond() {
|
||||
local _netdev=$1
|
||||
local _dev _mac _slaves _kdumpdev
|
||||
for _dev in `cat /sys/class/net/$_netdev/bonding/slaves`; do
|
||||
_mac=$(kdump_get_perm_addr $_dev)
|
||||
_kdumpdev=$(kdump_setup_ifname $_dev)
|
||||
echo -n " ifname=$_kdumpdev:$_mac" >> ${initdir}/etc/cmdline.d/42bond.conf
|
||||
_slaves+="$_kdumpdev,"
|
||||
done
|
||||
echo -n " bond=$_netdev:$(echo $_slaves | sed 's/,$//')" >> ${initdir}/etc/cmdline.d/42bond.conf
|
||||
# Get bond options specified in ifcfg
|
||||
|
||||
source_ifcfg_file $_netdev
|
||||
|
||||
bondoptions=":$(echo $BONDING_OPTS | xargs echo | tr " " ",")"
|
||||
echo "$bondoptions" >> ${initdir}/etc/cmdline.d/42bond.conf
|
||||
}
|
||||
|
||||
kdump_setup_team() {
|
||||
local _netdev=$1
|
||||
local _dev _mac _slaves _kdumpdev
|
||||
for _dev in `teamnl $_netdev ports | awk -F':' '{print $2}'`; do
|
||||
_mac=$(kdump_get_perm_addr $_dev)
|
||||
_kdumpdev=$(kdump_setup_ifname $_dev)
|
||||
echo -n " ifname=$_kdumpdev:$_mac" >> ${initdir}/etc/cmdline.d/44team.conf
|
||||
_slaves+="$_kdumpdev,"
|
||||
done
|
||||
echo " team=$_netdev:$(echo $_slaves | sed -e 's/,$//')" >> ${initdir}/etc/cmdline.d/44team.conf
|
||||
#Buggy version teamdctl outputs to stderr!
|
||||
#Try to use the latest version of teamd.
|
||||
teamdctl "$_netdev" config dump > ${initdir}/tmp/$$-$_netdev.conf
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
derror "teamdctl failed."
|
||||
exit 1
|
||||
fi
|
||||
inst_dir /etc/teamd
|
||||
inst_simple ${initdir}/tmp/$$-$_netdev.conf "/etc/teamd/$_netdev.conf"
|
||||
rm -f ${initdir}/tmp/$$-$_netdev.conf
|
||||
}
|
||||
|
||||
kdump_setup_vlan() {
|
||||
local _netdev=$1
|
||||
local _phydev="$(awk '/^Device:/{print $2}' /proc/net/vlan/"$_netdev")"
|
||||
local _netmac="$(kdump_get_mac_addr $_phydev)"
|
||||
local _kdumpdev
|
||||
|
||||
#Just support vlan over bond, it is not easy
|
||||
#to support all other complex setup
|
||||
if kdump_is_bridge "$_phydev"; then
|
||||
derror "Vlan over bridge is not supported!"
|
||||
exit 1
|
||||
elif kdump_is_team "$_phydev"; then
|
||||
derror "Vlan over team is not supported!"
|
||||
exit 1
|
||||
elif kdump_is_bond "$_phydev"; then
|
||||
kdump_setup_bond "$_phydev"
|
||||
echo " vlan=$(kdump_setup_ifname $_netdev):$_phydev" > ${initdir}/etc/cmdline.d/43vlan.conf
|
||||
else
|
||||
_kdumpdev="$(kdump_setup_ifname $_phydev)"
|
||||
echo " vlan=$(kdump_setup_ifname $_netdev):$_kdumpdev ifname=$_kdumpdev:$_netmac" > ${initdir}/etc/cmdline.d/43vlan.conf
|
||||
fi
|
||||
}
|
||||
|
||||
# setup s390 znet cmdline
|
||||
# $1: netdev name
|
||||
kdump_setup_znet() {
|
||||
local _options=""
|
||||
local _netdev=$1
|
||||
|
||||
source_ifcfg_file $_netdev
|
||||
|
||||
for i in $OPTIONS; do
|
||||
_options=${_options},$i
|
||||
done
|
||||
echo rd.znet=${NETTYPE},${SUBCHANNELS}${_options} rd.znet_ifname=$_netdev:${SUBCHANNELS} > ${initdir}/etc/cmdline.d/30znet.conf
|
||||
}
|
||||
|
||||
# Setup dracut to bringup a given network interface
|
||||
kdump_setup_netdev() {
|
||||
local _netdev=$1 _srcaddr=$2
|
||||
local _static _proto _ip_conf _ip_opts _ifname_opts
|
||||
local _netmac=$(kdump_get_mac_addr $_netdev)
|
||||
|
||||
if [ "$(uname -m)" = "s390x" ]; then
|
||||
kdump_setup_znet $_netdev
|
||||
fi
|
||||
|
||||
_static=$(kdump_static_ip $_netdev $_srcaddr)
|
||||
if [ -n "$_static" ]; then
|
||||
_proto=none
|
||||
elif is_ipv6_address $_srcaddr; then
|
||||
_proto=either6
|
||||
else
|
||||
_proto=dhcp
|
||||
fi
|
||||
|
||||
_ip_conf="${initdir}/etc/cmdline.d/40ip.conf"
|
||||
_ip_opts=" ip=${_static}$(kdump_setup_ifname $_netdev):${_proto}"
|
||||
|
||||
# dracut doesn't allow duplicated configuration for same NIC, even they're exactly the same.
|
||||
# so we have to avoid adding duplicates
|
||||
# We should also check /proc/cmdline for existing ip=xx arg.
|
||||
# For example, iscsi boot will specify ip=xxx arg in cmdline.
|
||||
if [ ! -f $_ip_conf ] || ! grep -q $_ip_opts $_ip_conf &&\
|
||||
! grep -q "ip=[^[:space:]]*$_netdev" /proc/cmdline; then
|
||||
echo "$_ip_opts" >> $_ip_conf
|
||||
fi
|
||||
|
||||
if kdump_is_bridge "$_netdev"; then
|
||||
kdump_setup_bridge "$_netdev"
|
||||
elif kdump_is_bond "$_netdev"; then
|
||||
kdump_setup_bond "$_netdev"
|
||||
elif kdump_is_team "$_netdev"; then
|
||||
kdump_setup_team "$_netdev"
|
||||
elif kdump_is_vlan "$_netdev"; then
|
||||
kdump_setup_vlan "$_netdev"
|
||||
else
|
||||
_ifname_opts=" ifname=$(kdump_setup_ifname $_netdev):$_netmac"
|
||||
echo "$_ifname_opts" >> $_ip_conf
|
||||
fi
|
||||
|
||||
kdump_setup_dns "$_netdev"
|
||||
|
||||
if [ ! -f ${initdir}/etc/cmdline.d/50neednet.conf ]; then
|
||||
# network-manager module needs this parameter
|
||||
echo "rd.neednet" >> ${initdir}/etc/cmdline.d/50neednet.conf
|
||||
fi
|
||||
}
|
||||
|
||||
get_ip_route_field()
|
||||
{
|
||||
if `echo $1 | grep -q $2`; then
|
||||
echo ${1##*$2} | cut -d ' ' -f1
|
||||
fi
|
||||
}
|
||||
|
||||
#Function:kdump_install_net
|
||||
#$1: config values of net line in kdump.conf
|
||||
#$2: srcaddr of network device
|
||||
kdump_install_net() {
|
||||
local _server _netdev _srcaddr _route _serv_tmp
|
||||
local config_val="$1"
|
||||
|
||||
_server=$(get_remote_host $config_val)
|
||||
|
||||
if is_hostname $_server; then
|
||||
_serv_tmp=`getent ahosts $_server | grep -v : | head -n 1`
|
||||
if [ -z "$_serv_tmp" ]; then
|
||||
_serv_tmp=`getent ahosts $_server | head -n 1`
|
||||
fi
|
||||
_server=`echo $_serv_tmp | cut -d' ' -f1`
|
||||
fi
|
||||
|
||||
_route=`/sbin/ip -o route get to $_server 2>&1`
|
||||
[ $? != 0 ] && echo "Bad kdump location: $config_val" && exit 1
|
||||
|
||||
#the field in the ip output changes if we go to another subnet
|
||||
_srcaddr=$(get_ip_route_field "$_route" "src")
|
||||
_netdev=$(get_ip_route_field "$_route" "dev")
|
||||
|
||||
kdump_setup_netdev "${_netdev}" "${_srcaddr}"
|
||||
|
||||
#save netdev used for kdump as cmdline
|
||||
# Whoever calling kdump_install_net() is setting up the default gateway,
|
||||
# ie. bootdev/kdumpnic. So don't override the setting if calling
|
||||
# kdump_install_net() for another time. For example, after setting eth0 as
|
||||
# the default gate way for network dump, eth1 in the fence kdump path will
|
||||
# call kdump_install_net again and we don't want eth1 to be the default
|
||||
# gateway.
|
||||
if [ ! -f ${initdir}/etc/cmdline.d/60kdumpnic.conf ] &&
|
||||
[ ! -f ${initdir}/etc/cmdline.d/70bootdev.conf ]; then
|
||||
echo "kdumpnic=$(kdump_setup_ifname $_netdev)" > ${initdir}/etc/cmdline.d/60kdumpnic.conf
|
||||
echo "bootdev=$(kdump_setup_ifname $_netdev)" > ${initdir}/etc/cmdline.d/70bootdev.conf
|
||||
fi
|
||||
}
|
||||
|
||||
# install etc/kdump/pre.d and /etc/kdump/post.d
|
||||
kdump_install_pre_post_conf() {
|
||||
if [ -d /etc/kdump/pre.d ]; then
|
||||
for file in /etc/kdump/pre.d/*; do
|
||||
if [ -x "$file" ]; then
|
||||
dracut_install $file
|
||||
elif [ $file != "/etc/kdump/pre.d/*" ]; then
|
||||
echo "$file is not executable"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if [ -d /etc/kdump/post.d ]; then
|
||||
for file in /etc/kdump/post.d/*; do
|
||||
if [ -x "$file" ]; then
|
||||
dracut_install $file
|
||||
elif [ $file != "/etc/kdump/post.d/*" ]; then
|
||||
echo "$file is not executable"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
default_dump_target_install_conf()
|
||||
{
|
||||
local _target _fstype
|
||||
local _mntpoint _save_path
|
||||
|
||||
is_user_configured_dump_target && return
|
||||
|
||||
_save_path=$(get_bind_mount_source $(get_save_path))
|
||||
_target=$(get_target_from_path $_save_path)
|
||||
_mntpoint=$(get_mntpoint_from_target $_target)
|
||||
|
||||
_fstype=$(get_fs_type_from_target $_target)
|
||||
if is_fs_type_nfs $_fstype; then
|
||||
kdump_install_net "$_target"
|
||||
_fstype="nfs"
|
||||
else
|
||||
_target=$(kdump_get_persistent_dev $_target)
|
||||
fi
|
||||
|
||||
echo "$_fstype $_target" >> ${initdir}/tmp/$$-kdump.conf
|
||||
|
||||
# don't touch the path under root mount
|
||||
if [ "$_mntpoint" != "/" ]; then
|
||||
_save_path=${_save_path##"$_mntpoint"}
|
||||
fi
|
||||
|
||||
#erase the old path line, then insert the parsed path
|
||||
sed -i "/^path/d" ${initdir}/tmp/$$-kdump.conf
|
||||
echo "path $_save_path" >> ${initdir}/tmp/$$-kdump.conf
|
||||
}
|
||||
|
||||
#install kdump.conf and what user specifies in kdump.conf
|
||||
kdump_install_conf() {
|
||||
local _opt _val _pdev
|
||||
sed -ne '/^#/!p' /etc/kdump.conf > ${initdir}/tmp/$$-kdump.conf
|
||||
|
||||
while read _opt _val;
|
||||
do
|
||||
# remove inline comments after the end of a directive.
|
||||
case "$_opt" in
|
||||
raw)
|
||||
_pdev=$(persistent_policy="by-id" kdump_get_persistent_dev $_val)
|
||||
sed -i -e "s#^$_opt[[:space:]]\+$_val#$_opt $_pdev#" ${initdir}/tmp/$$-kdump.conf
|
||||
;;
|
||||
ext[234]|xfs|btrfs|minix)
|
||||
_pdev=$(kdump_get_persistent_dev $_val)
|
||||
sed -i -e "s#^$_opt[[:space:]]\+$_val#$_opt $_pdev#" ${initdir}/tmp/$$-kdump.conf
|
||||
;;
|
||||
ssh|nfs)
|
||||
kdump_install_net "$_val"
|
||||
;;
|
||||
dracut_args)
|
||||
if [[ $(get_dracut_args_fstype "$_val") = nfs* ]] ; then
|
||||
kdump_install_net "$(get_dracut_args_target "$_val")"
|
||||
fi
|
||||
;;
|
||||
kdump_pre|kdump_post|extra_bins)
|
||||
dracut_install $_val
|
||||
;;
|
||||
core_collector)
|
||||
dracut_install "${_val%%[[:blank:]]*}"
|
||||
;;
|
||||
esac
|
||||
done <<< "$(read_strip_comments /etc/kdump.conf)"
|
||||
|
||||
kdump_install_pre_post_conf
|
||||
|
||||
default_dump_target_install_conf
|
||||
|
||||
kdump_configure_fence_kdump "${initdir}/tmp/$$-kdump.conf"
|
||||
inst "${initdir}/tmp/$$-kdump.conf" "/etc/kdump.conf"
|
||||
rm -f ${initdir}/tmp/$$-kdump.conf
|
||||
}
|
||||
|
||||
# Default sysctl parameters should suffice for kdump kernel.
|
||||
# Remove custom configurations sysctl.conf & sysctl.d/*
|
||||
remove_sysctl_conf() {
|
||||
|
||||
# As custom configurations like vm.min_free_kbytes can lead
|
||||
# to OOM issues in kdump kernel, avoid them
|
||||
rm -f "${initdir}/etc/sysctl.conf"
|
||||
rm -rf "${initdir}/etc/sysctl.d"
|
||||
rm -rf "${initdir}/run/sysctl.d"
|
||||
rm -rf "${initdir}/usr/lib/sysctl.d"
|
||||
}
|
||||
|
||||
kdump_iscsi_get_rec_val() {
|
||||
|
||||
local result
|
||||
|
||||
# The open-iscsi 742 release changed to using flat files in
|
||||
# /var/lib/iscsi.
|
||||
|
||||
result=$(/sbin/iscsiadm --show -m session -r ${1} | grep "^${2} = ")
|
||||
result=${result##* = }
|
||||
echo $result
|
||||
}
|
||||
|
||||
kdump_get_iscsi_initiator() {
|
||||
local _initiator
|
||||
local initiator_conf="/etc/iscsi/initiatorname.iscsi"
|
||||
|
||||
[ -f "$initiator_conf" ] || return 1
|
||||
|
||||
while read _initiator; do
|
||||
[ -z "${_initiator%%#*}" ] && continue # Skip comment lines
|
||||
|
||||
case $_initiator in
|
||||
InitiatorName=*)
|
||||
initiator=${_initiator#InitiatorName=}
|
||||
echo "rd.iscsi.initiator=${initiator}"
|
||||
return 0;;
|
||||
*) ;;
|
||||
esac
|
||||
done < ${initiator_conf}
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
# Figure out iBFT session according to session type
|
||||
is_ibft() {
|
||||
[ "$(kdump_iscsi_get_rec_val $1 "node.discovery_type")" = fw ]
|
||||
}
|
||||
|
||||
kdump_setup_iscsi_device() {
|
||||
local path=$1
|
||||
local tgt_name; local tgt_ipaddr;
|
||||
local username; local password; local userpwd_str;
|
||||
local username_in; local password_in; local userpwd_in_str;
|
||||
local netdev
|
||||
local srcaddr
|
||||
local idev
|
||||
local netroot_str ; local initiator_str;
|
||||
local netroot_conf="${initdir}/etc/cmdline.d/50iscsi.conf"
|
||||
local initiator_conf="/etc/iscsi/initiatorname.iscsi"
|
||||
|
||||
dinfo "Found iscsi component $1"
|
||||
|
||||
# Check once before getting explicit values, so we can bail out early,
|
||||
# e.g. in case of pure-hardware(all-offload) iscsi.
|
||||
if ! /sbin/iscsiadm -m session -r ${path} &>/dev/null ; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
if is_ibft ${path}; then
|
||||
return
|
||||
fi
|
||||
|
||||
# Remove software iscsi cmdline generated by 95iscsi,
|
||||
# and let kdump regenerate here.
|
||||
rm -f ${initdir}/etc/cmdline.d/95iscsi.conf
|
||||
|
||||
tgt_name=$(kdump_iscsi_get_rec_val ${path} "node.name")
|
||||
tgt_ipaddr=$(kdump_iscsi_get_rec_val ${path} "node.conn\[0\].address")
|
||||
|
||||
# get and set username and password details
|
||||
username=$(kdump_iscsi_get_rec_val ${path} "node.session.auth.username")
|
||||
[ "$username" == "<empty>" ] && username=""
|
||||
password=$(kdump_iscsi_get_rec_val ${path} "node.session.auth.password")
|
||||
[ "$password" == "<empty>" ] && password=""
|
||||
username_in=$(kdump_iscsi_get_rec_val ${path} "node.session.auth.username_in")
|
||||
[ -n "$username" ] && userpwd_str="$username:$password"
|
||||
|
||||
# get and set incoming username and password details
|
||||
[ "$username_in" == "<empty>" ] && username_in=""
|
||||
password_in=$(kdump_iscsi_get_rec_val ${path} "node.session.auth.password_in")
|
||||
[ "$password_in" == "<empty>" ] && password_in=""
|
||||
|
||||
[ -n "$username_in" ] && userpwd_in_str=":$username_in:$password_in"
|
||||
|
||||
netdev=$(/sbin/ip route get to ${tgt_ipaddr} | \
|
||||
sed 's|.*dev \(.*\).*|\1|g')
|
||||
srcaddr=$(echo $netdev | awk '{ print $3; exit }')
|
||||
netdev=$(echo $netdev | awk '{ print $1; exit }')
|
||||
|
||||
kdump_setup_netdev $netdev $srcaddr
|
||||
|
||||
# prepare netroot= command line
|
||||
# FIXME: Do we need to parse and set other parameters like protocol, port
|
||||
# iscsi_iface_name, netdev_name, LUN etc.
|
||||
|
||||
if is_ipv6_address $tgt_ipaddr; then
|
||||
tgt_ipaddr="[$tgt_ipaddr]"
|
||||
fi
|
||||
netroot_str="netroot=iscsi:${userpwd_str}${userpwd_in_str}@$tgt_ipaddr::::$tgt_name"
|
||||
|
||||
[[ -f $netroot_conf ]] || touch $netroot_conf
|
||||
|
||||
# If netroot target does not exist already, append.
|
||||
if ! grep -q $netroot_str $netroot_conf; then
|
||||
echo $netroot_str >> $netroot_conf
|
||||
dinfo "Appended $netroot_str to $netroot_conf"
|
||||
fi
|
||||
|
||||
# Setup initator
|
||||
initiator_str=$(kdump_get_iscsi_initiator)
|
||||
[ $? -ne "0" ] && derror "Failed to get initiator name" && return 1
|
||||
|
||||
# If initiator details do not exist already, append.
|
||||
if ! grep -q "$initiator_str" $netroot_conf; then
|
||||
echo "$initiator_str" >> $netroot_conf
|
||||
dinfo "Appended "$initiator_str" to $netroot_conf"
|
||||
fi
|
||||
}
|
||||
|
||||
kdump_check_iscsi_targets () {
|
||||
# If our prerequisites are not met, fail anyways.
|
||||
type -P iscsistart >/dev/null || return 1
|
||||
|
||||
kdump_check_setup_iscsi() (
|
||||
local _dev
|
||||
_dev=$1
|
||||
|
||||
[[ -L /sys/dev/block/$_dev ]] || return
|
||||
cd "$(readlink -f /sys/dev/block/$_dev)"
|
||||
until [[ -d sys || -d iscsi_session ]]; do
|
||||
cd ..
|
||||
done
|
||||
[[ -d iscsi_session ]] && kdump_setup_iscsi_device "$PWD"
|
||||
)
|
||||
|
||||
[[ $hostonly ]] || [[ $mount_needs ]] && {
|
||||
for_each_host_dev_and_slaves_all kdump_check_setup_iscsi
|
||||
}
|
||||
}
|
||||
|
||||
# hostname -a is deprecated, do it by ourself
|
||||
get_alias() {
|
||||
local ips
|
||||
local entries
|
||||
local alias_set
|
||||
|
||||
ips=$(hostname -I)
|
||||
for ip in $ips
|
||||
do
|
||||
# in /etc/hosts, alias can come at the 2nd column
|
||||
entries=$(grep $ip /etc/hosts | awk '{ $1=""; print $0 }')
|
||||
if [ $? -eq 0 ]; then
|
||||
alias_set="$alias_set $entries"
|
||||
fi
|
||||
done
|
||||
|
||||
echo $alias_set
|
||||
}
|
||||
|
||||
is_localhost() {
|
||||
local hostnames=$(hostname -A)
|
||||
local shortnames=$(hostname -A -s)
|
||||
local aliasname=$(get_alias)
|
||||
local nodename=$1
|
||||
|
||||
hostnames="$hostnames $shortnames $aliasname"
|
||||
|
||||
for name in ${hostnames}; do
|
||||
if [ "$name" == "$nodename" ]; then
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
# retrieves fence_kdump nodes from Pacemaker cluster configuration
|
||||
get_pcs_fence_kdump_nodes() {
|
||||
local nodes
|
||||
|
||||
# get cluster nodes from cluster cib, get interface and ip address
|
||||
nodelist=`pcs cluster cib | xmllint --xpath "/cib/status/node_state/@uname" -`
|
||||
|
||||
# nodelist is formed as 'uname="node1" uname="node2" ... uname="nodeX"'
|
||||
# we need to convert each to node1, node2 ... nodeX in each iteration
|
||||
for node in ${nodelist}; do
|
||||
# convert $node from 'uname="nodeX"' to 'nodeX'
|
||||
eval $node
|
||||
nodename=$uname
|
||||
# Skip its own node name
|
||||
if [ "$nodename" = `hostname` -o "$nodename" = `hostname -s` ]; then
|
||||
continue
|
||||
fi
|
||||
nodes="$nodes $nodename"
|
||||
done
|
||||
|
||||
echo $nodes
|
||||
}
|
||||
|
||||
# retrieves fence_kdump args from config file
|
||||
get_pcs_fence_kdump_args() {
|
||||
if [ -f $FENCE_KDUMP_CONFIG_FILE ]; then
|
||||
. $FENCE_KDUMP_CONFIG_FILE
|
||||
echo $FENCE_KDUMP_OPTS
|
||||
fi
|
||||
}
|
||||
|
||||
get_generic_fence_kdump_nodes() {
|
||||
local filtered
|
||||
local nodes
|
||||
|
||||
nodes=$(get_option_value "fence_kdump_nodes")
|
||||
for node in ${nodes}; do
|
||||
# Skip its own node name
|
||||
if is_localhost $node; then
|
||||
continue
|
||||
fi
|
||||
filtered="$filtered $node"
|
||||
done
|
||||
echo $filtered
|
||||
}
|
||||
|
||||
# setup fence_kdump in cluster
|
||||
# setup proper network and install needed files
|
||||
kdump_configure_fence_kdump () {
|
||||
local kdump_cfg_file=$1
|
||||
local nodes
|
||||
local args
|
||||
|
||||
if is_generic_fence_kdump; then
|
||||
nodes=$(get_generic_fence_kdump_nodes)
|
||||
|
||||
elif is_pcs_fence_kdump; then
|
||||
nodes=$(get_pcs_fence_kdump_nodes)
|
||||
|
||||
# set appropriate options in kdump.conf
|
||||
echo "fence_kdump_nodes $nodes" >> ${kdump_cfg_file}
|
||||
|
||||
args=$(get_pcs_fence_kdump_args)
|
||||
if [ -n "$args" ]; then
|
||||
echo "fence_kdump_args $args" >> ${kdump_cfg_file}
|
||||
fi
|
||||
|
||||
else
|
||||
# fence_kdump not configured
|
||||
return 1
|
||||
fi
|
||||
|
||||
# setup network for each node
|
||||
for node in ${nodes}; do
|
||||
kdump_install_net $node
|
||||
done
|
||||
|
||||
dracut_install /etc/hosts
|
||||
dracut_install /etc/nsswitch.conf
|
||||
dracut_install $FENCE_KDUMP_SEND
|
||||
}
|
||||
|
||||
# Install a random seed used to feed /dev/urandom
|
||||
# By the time kdump service starts, /dev/uramdom is already fed by systemd
|
||||
kdump_install_random_seed() {
|
||||
local poolsize=`cat /proc/sys/kernel/random/poolsize`
|
||||
|
||||
if [ ! -d ${initdir}/var/lib/ ]; then
|
||||
mkdir -p ${initdir}/var/lib/
|
||||
fi
|
||||
|
||||
dd if=/dev/urandom of=${initdir}/var/lib/random-seed \
|
||||
bs=$poolsize count=1 2> /dev/null
|
||||
}
|
||||
|
||||
remove_cpu_online_rule() {
|
||||
local file=${initdir}/usr/lib/udev/rules.d/40-redhat.rules
|
||||
|
||||
sed -i '/SUBSYSTEM=="cpu"/d' $file
|
||||
}
|
||||
|
||||
install() {
|
||||
local arch
|
||||
|
||||
kdump_install_conf
|
||||
remove_sysctl_conf
|
||||
|
||||
# Onlining secondary cpus breaks kdump completely on KVM on Power hosts
|
||||
# Though we use maxcpus=1 by default but 40-redhat.rules will bring up all
|
||||
# possible cpus by default. (rhbz1270174 rhbz1266322)
|
||||
# Thus before we get the kernel fix and the systemd rule fix let's remove
|
||||
# the cpu online rule in kdump initramfs.
|
||||
arch=$(uname -m)
|
||||
if [[ "$arch" = "ppc64le" ]] || [[ "$arch" = "ppc64" ]]; then
|
||||
remove_cpu_online_rule
|
||||
fi
|
||||
|
||||
if is_ssh_dump_target; then
|
||||
kdump_install_random_seed
|
||||
fi
|
||||
dracut_install -o /etc/adjtime /etc/localtime
|
||||
inst "$moddir/monitor_dd_progress" "/kdumpscripts/monitor_dd_progress"
|
||||
chmod +x ${initdir}/kdumpscripts/monitor_dd_progress
|
||||
inst "/bin/dd" "/bin/dd"
|
||||
inst "/bin/tail" "/bin/tail"
|
||||
inst "/bin/date" "/bin/date"
|
||||
inst "/bin/sync" "/bin/sync"
|
||||
inst "/bin/cut" "/bin/cut"
|
||||
inst "/bin/head" "/bin/head"
|
||||
inst "/sbin/makedumpfile" "/sbin/makedumpfile"
|
||||
inst "/sbin/vmcore-dmesg" "/sbin/vmcore-dmesg"
|
||||
inst "/lib/kdump/kdump-lib.sh" "/lib/kdump-lib.sh"
|
||||
inst "/lib/kdump/kdump-lib-initramfs.sh" "/lib/kdump-lib-initramfs.sh"
|
||||
inst "$moddir/kdump.sh" "/usr/bin/kdump.sh"
|
||||
inst "$moddir/kdump-capture.service" "$systemdsystemunitdir/kdump-capture.service"
|
||||
ln_r "$systemdsystemunitdir/kdump-capture.service" "$systemdsystemunitdir/initrd.target.wants/kdump-capture.service"
|
||||
inst "$moddir/kdump-error-handler.sh" "/usr/bin/kdump-error-handler.sh"
|
||||
inst "$moddir/kdump-error-handler.service" "$systemdsystemunitdir/kdump-error-handler.service"
|
||||
# Replace existing emergency service and emergency target
|
||||
cp "$moddir/kdump-emergency.service" "$initdir/$systemdsystemunitdir/emergency.service"
|
||||
cp "$moddir/kdump-emergency.target" "$initdir/$systemdsystemunitdir/emergency.target"
|
||||
# Also redirect dracut-emergency to kdump error handler
|
||||
ln_r "$systemdsystemunitdir/emergency.service" "$systemdsystemunitdir/dracut-emergency.service"
|
||||
|
||||
# Check for all the devices and if any device is iscsi, bring up iscsi
|
||||
# target. Ideally all this should be pushed into dracut iscsi module
|
||||
# at some point of time.
|
||||
kdump_check_iscsi_targets
|
||||
|
||||
# For the lvm type target under kdump, in /etc/lvm/lvm.conf we can
|
||||
# safely replace "reserved_memory=XXXX"(default value is 8192) with
|
||||
# "reserved_memory=1024" to lower memory pressure under kdump. We do
|
||||
# it unconditionally here, if "/etc/lvm/lvm.conf" doesn't exist, it
|
||||
# actually does nothing.
|
||||
sed -i -e \
|
||||
's/\(^[[:space:]]*reserved_memory[[:space:]]*=\)[[:space:]]*[[:digit:]]*/\1 1024/' \
|
||||
${initdir}/etc/lvm/lvm.conf &>/dev/null
|
||||
|
||||
# Kdump turns out to require longer default systemd mount timeout
|
||||
# than 1st kernel(90s by default), we use default 300s for kdump.
|
||||
grep -r "^[[:space:]]*DefaultTimeoutStartSec=" ${initdir}/etc/systemd/system.conf* &>/dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
mkdir -p ${initdir}/etc/systemd/system.conf.d
|
||||
echo "[Manager]" > ${initdir}/etc/systemd/system.conf.d/kdump.conf
|
||||
echo "DefaultTimeoutStartSec=300s" >> ${initdir}/etc/systemd/system.conf.d/kdump.conf
|
||||
fi
|
||||
|
||||
if ! is_fadump_capable; then
|
||||
# Forward logs to console directly, this avoids unneccessary memory
|
||||
# consumption and make console output more useful.
|
||||
# Only do so for non fadump image.
|
||||
mkdir -p ${initdir}/etc/systemd/journald.conf.d
|
||||
echo "[Journal]" > ${initdir}/etc/systemd/journald.conf.d/kdump.conf
|
||||
echo "Storage=none" >> ${initdir}/etc/systemd/journald.conf.d/kdump.conf
|
||||
echo "ForwardToConsole=yes" >> ${initdir}/etc/systemd/journald.conf.d/kdump.conf
|
||||
|
||||
# Save more memory by dropping switch root capability
|
||||
dracut_no_switch_root
|
||||
fi
|
||||
}
|
28
SOURCES/dracut-monitor_dd_progress
Normal file
28
SOURCES/dracut-monitor_dd_progress
Normal file
@ -0,0 +1,28 @@
|
||||
#!/bin/sh
|
||||
|
||||
SRC_FILE_MB=$1
|
||||
|
||||
while true
|
||||
do
|
||||
DD_PID=`pidof dd`
|
||||
if [ -n "$DD_PID" ]; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
while true
|
||||
do
|
||||
sleep 5
|
||||
if [ ! -d /proc/$DD_PID ]; then
|
||||
break
|
||||
fi
|
||||
|
||||
kill -s USR1 $DD_PID
|
||||
CURRENT_SIZE=`tail -n 1 /tmp/dd_progress_file | sed "s/[^0-9].*//g"`
|
||||
[ -n "$CURRENT_SIZE" ] && {
|
||||
CURRENT_MB=$(($CURRENT_SIZE / 1048576))
|
||||
echo -e "Copied $CURRENT_MB MB / $SRC_FILE_MB MB\r"
|
||||
}
|
||||
done
|
||||
|
||||
rm -f /tmp/dd_progress_file
|
95
SOURCES/early-kdump-howto.txt
Normal file
95
SOURCES/early-kdump-howto.txt
Normal file
@ -0,0 +1,95 @@
|
||||
Early Kdump HOWTO
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
Early kdump is a mechanism to make kdump operational earlier than normal kdump
|
||||
service. The kdump service starts early enough for general crash cases, but
|
||||
there are some cases where it has no chance to make kdump operational in boot
|
||||
sequence, such as detecting devices and starting early services. If you hit
|
||||
such a case, early kdump may allow you to get more information of it.
|
||||
|
||||
Early kdump is implemented as a dracut module. It adds a kernel (vmlinuz) and
|
||||
initramfs for kdump to your system's initramfs in order to load them as early
|
||||
as possible. After that, if you provide "rd.earlykdump" in kernel command line,
|
||||
then in the initramfs, early kdump will load those files like the normal kdump
|
||||
service. This is disabled by default.
|
||||
|
||||
For the normal kdump service, it can check whether the early kdump has loaded
|
||||
the crash kernel and initramfs. It has no conflict with the early kdump.
|
||||
|
||||
How to configure early kdump
|
||||
----------------------------
|
||||
|
||||
We assume if you're reading this document, you should already have kexec-tools
|
||||
installed.
|
||||
|
||||
You can rebuild the initramfs with earlykdump support with below steps:
|
||||
|
||||
1. start kdump service to make sure kdump initramfs is created.
|
||||
|
||||
# systemctl start kdump
|
||||
|
||||
NOTE: If a crash occurs during boot process, early kdump captures a vmcore
|
||||
and reboot the system by default, so the system might go into crash loop.
|
||||
You can avoid such a crash loop by adding the following settings, which
|
||||
power off the system after dump capturing, to kdump.conf in advance:
|
||||
|
||||
final_action poweroff
|
||||
failure_action poweroff
|
||||
|
||||
For the failure_action, you can choose anything other than "reboot".
|
||||
|
||||
2. rebuild system initramfs with earlykdump support.
|
||||
|
||||
# dracut --force --add earlykdump
|
||||
|
||||
NOTE: Recommend to backup the original system initramfs before performing
|
||||
this step to put it back if something happens during boot-up.
|
||||
|
||||
3. add rd.earlykdump in grub kernel command line.
|
||||
|
||||
After making said changes, reboot your system to take effect. Of course, if you
|
||||
want to disable early kdump, you can simply remove "rd.earlykdump" from kernel
|
||||
boot parameters in grub, and reboot system like above.
|
||||
|
||||
Once the boot is completed, you can check the status of the early kdump support
|
||||
on the command prompt:
|
||||
|
||||
# journalctl -b | grep early-kdump
|
||||
|
||||
Then, you will see some useful logs, for example:
|
||||
|
||||
- if early kdump is successful.
|
||||
|
||||
Mar 09 09:57:56 localhost dracut-cmdline[190]: early-kdump is enabled.
|
||||
Mar 09 09:57:56 localhost dracut-cmdline[190]: kexec: loaded early-kdump kernel
|
||||
|
||||
- if early kdump is disabled.
|
||||
|
||||
Mar 09 10:02:47 localhost dracut-cmdline[189]: early-kdump is disabled.
|
||||
|
||||
Notes
|
||||
-----
|
||||
|
||||
- The size of early kdump initramfs will be large because it includes vmlinuz
|
||||
and kdump initramfs.
|
||||
|
||||
- Early kdump inherits the settings of normal kdump, so any changes that
|
||||
caused normal kdump rebuilding also require rebuilding the system initramfs
|
||||
to make sure that the changes take effect for early kdump. Therefore, after
|
||||
the rebuilding of kdump initramfs is completed, provide a prompt message to
|
||||
tell the fact.
|
||||
|
||||
- If you install an updated kernel and reboot the system with it, the early
|
||||
kdump will be disabled by default. To enable it with the new kernel, you
|
||||
need to take the above steps again.
|
||||
|
||||
Limitation
|
||||
----------
|
||||
|
||||
- At present, early kdump doesn't support fadump.
|
||||
|
||||
- Early kdump loads a crash kernel and initramfs at the beginning of the
|
||||
process in system's initramfs, so a crash at earlier than that (e.g. in
|
||||
kernel initialization) cannot be captured even with the early kdump.
|
338
SOURCES/fadump-howto.txt
Normal file
338
SOURCES/fadump-howto.txt
Normal file
@ -0,0 +1,338 @@
|
||||
Firmware assisted dump (fadump) HOWTO
|
||||
|
||||
Introduction
|
||||
|
||||
Firmware assisted dump is a new feature in the 3.4 mainline kernel supported
|
||||
only on powerpc architecture. The goal of firmware-assisted dump is to enable
|
||||
the dump of a crashed system, and to do so from a fully-reset system, and to
|
||||
minimize the total elapsed time until the system is back in production use. A
|
||||
complete documentation on implementation can be found at
|
||||
Documentation/powerpc/firmware-assisted-dump.txt in upstream linux kernel tree
|
||||
from 3.4 version and above.
|
||||
|
||||
Please note that the firmware-assisted dump feature is only available on Power6
|
||||
and above systems with recent firmware versions.
|
||||
|
||||
Overview
|
||||
|
||||
Fadump
|
||||
|
||||
Fadump is a robust kernel crash dumping mechanism to get reliable kernel crash
|
||||
dump with assistance from firmware. This approach does not use kexec, instead
|
||||
firmware assists in booting the kdump kernel while preserving memory contents.
|
||||
Unlike kdump, the system is fully reset, and loaded with a fresh copy of the
|
||||
kernel. In particular, PCI and I/O devices are reinitialized and are in a
|
||||
clean, consistent state. This second kernel, often called a capture kernel,
|
||||
boots with very little memory and captures the dump image.
|
||||
|
||||
The first kernel registers the sections of memory with the Power firmware for
|
||||
dump preservation during OS initialization. These registered sections of memory
|
||||
are reserved by the first kernel during early boot. When a system crashes, the
|
||||
Power firmware fully resets the system, preserves all the system memory
|
||||
contents, save the low memory (boot memory of size larger of 5% of system
|
||||
RAM or 256MB) of RAM to the previous registered region. It will also save
|
||||
system registers, and hardware PTE's.
|
||||
|
||||
Fadump is supported only on ppc64 platform. The standard kernel and capture
|
||||
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
|
||||
|
||||
Fadump Operational Flow:
|
||||
|
||||
Like kdump, fadump also exports the ELF formatted kernel crash dump through
|
||||
/proc/vmcore. Hence existing kdump infrastructure can be used to capture fadump
|
||||
vmcore. The idea is to keep the functionality transparent to end user. From
|
||||
user perspective there is no change in the way kdump init script works.
|
||||
|
||||
However, unlike kdump, fadump does not pre-load kdump kernel and initrd into
|
||||
reserved memory, instead it always uses default OS initrd during second boot
|
||||
after crash. Hence, for fadump, we rebuild the new kdump initrd and replace it
|
||||
with default initrd. Before replacing existing default initrd we take a backup
|
||||
of original default initrd for user's reference. The dracut package has been
|
||||
enhanced to rebuild the default initrd with vmcore capture steps. The initrd
|
||||
image is rebuilt as per the configuration in /etc/kdump.conf file.
|
||||
|
||||
The control flow of fadump works as follows:
|
||||
01. System panics.
|
||||
02. At the crash, kernel informs power firmware that kernel has crashed.
|
||||
03. Firmware takes the control and reboots the entire system preserving
|
||||
only the memory (resets all other devices).
|
||||
04. The reboot follows the normal booting process (non-kexec).
|
||||
05. The boot loader loads the default kernel and initrd from /boot
|
||||
06. The default initrd loads and runs /init
|
||||
07. dracut-kdump.sh script present in fadump aware default initrd checks if
|
||||
'/proc/device-tree/rtas/ibm,kernel-dump' file exists before executing
|
||||
steps to capture vmcore.
|
||||
(This check will help to bypass the vmcore capture steps during normal boot
|
||||
process.)
|
||||
09. Captures dump according to /etc/kdump.conf
|
||||
10. Is dump capture successful (yes goto 12, no goto 11)
|
||||
11. Perform the failure action specified in /etc/kdump.conf
|
||||
(The default failure action is reboot, if unspecified)
|
||||
12. Perform the final action specified in /etc/kdump.conf
|
||||
(The default final action is reboot, if unspecified)
|
||||
|
||||
|
||||
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
|
||||
|
||||
Make the kernel to be configured with FADump as the default boot entry, if
|
||||
it isn't already:
|
||||
|
||||
# grubby --set-default=/boot/vmlinuz-<kver>
|
||||
|
||||
Boot into the kernel to be configured for FADump. 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
|
||||
|
||||
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.
|
||||
|
||||
# grubby --args="fadump=on crashkernel=6G" --update-kernel=/boot/vmlinuz-`uname -r`
|
||||
|
||||
The term 'boot memory' means size of the low memory chunk that is required for
|
||||
a kernel to boot successfully when booted with restricted memory. By default,
|
||||
the boot memory size will be the larger of 5% of system RAM or 256MB.
|
||||
Alternatively, user can also specify boot memory size through boot parameter
|
||||
'fadump_reserve_mem=' which will override the default calculated size. Use this
|
||||
option if default boot memory size is not sufficient for second kernel to boot
|
||||
successfully.
|
||||
|
||||
After making said changes, reboot your system, so that the specified memory is
|
||||
reserved and left untouched by the normal system. Take note that the output of
|
||||
'free -m' will show X MB less memory than without this parameter, which is
|
||||
expected. If you see OOM (Out Of Memory) error messages while loading capture
|
||||
kernel, then you should bump up the memory reservation size.
|
||||
|
||||
Now that you've got that reserved memory region set up, you want to turn on
|
||||
the kdump init script:
|
||||
|
||||
# systemctl enable kdump.service
|
||||
|
||||
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
|
||||
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):
|
||||
|
||||
* If /boot is a separate partition, run the below commands as the root user,
|
||||
or as a user with CAP_SYS_ADMIN rights:
|
||||
|
||||
# fsfreeze -f
|
||||
# fsfreeze -u
|
||||
|
||||
* If /boot is not a separate partition, reboot the system.
|
||||
|
||||
After reboot check if the kdump service is up and running with:
|
||||
|
||||
# systemctl status kdump.service
|
||||
|
||||
To test out whether FADump is configured properly, you can force-crash your
|
||||
system by echo'ing a 'c' into /proc/sysrq-trigger:
|
||||
|
||||
# echo c > /proc/sysrq-trigger
|
||||
|
||||
You should see some panic output, followed by the system reset and booting into
|
||||
fresh copy of kernel. When default initrd loads and runs /init, vmcore should
|
||||
be copied out to disk (by default, in /var/crash/<YYYY.MM.DD-HH:MM:SS>/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
|
||||
perform postmortem analysis:
|
||||
|
||||
# crash /usr/lib/debug/lib/modules/2.6.17-1.2621.el5/vmlinux
|
||||
/var/crash/2006-08-23-15:34/vmcore
|
||||
|
||||
crash> bt
|
||||
|
||||
and so on...
|
||||
|
||||
Saving vmcore-dmesg.txt
|
||||
-----------------------
|
||||
Kernel log bufferes are one of the most important information available
|
||||
in vmcore. Now before saving vmcore, kernel log bufferes are extracted
|
||||
from /proc/vmcore and saved into a file vmcore-dmesg.txt. After
|
||||
vmcore-dmesg.txt, vmcore is saved. Destination disk and directory for
|
||||
vmcore-dmesg.txt is same as vmcore. Note that kernel log buffers will
|
||||
not be available if dump target is raw device.
|
||||
|
||||
FADump Memory Requirements:
|
||||
|
||||
System Memory Recommended memory
|
||||
--------------------- ----------------------
|
||||
4 GB - 16 GB : 768 MB
|
||||
16 GB - 64 GB : 1024 MB
|
||||
64 GB - 128 GB : 2 GB
|
||||
128 GB - 1 TB : 4 GB
|
||||
1 TB - 2 TB : 6 GB
|
||||
2 TB - 4 TB : 12 GB
|
||||
4 TB - 8 TB : 20 GB
|
||||
8 TB - 16 TB : 36 GB
|
||||
16 TB - 32 TB : 64 GB
|
||||
32 TB - 64 TB : 128 GB
|
||||
64 TB & above : 180 GB
|
||||
|
||||
Things to remember:
|
||||
|
||||
1) The memory required to boot capture Kernel is a moving target that depends
|
||||
on many factors like hardware attached to the system, kernel and modules in
|
||||
use, packages installed and services enabled, there is no one-size-fits-all.
|
||||
But the above recommendations are based on system memory. So, the above
|
||||
recommendations for FADump come with a few assumptions, based on available
|
||||
system memory, about the resources the system could have. So, please take
|
||||
the recommendations with a pinch of salt and remember to try capturing dump
|
||||
a few times to confirm that the system is configured successfully with dump
|
||||
capturing support.
|
||||
|
||||
2) Though the memory requirements for FADump seem high, this memory is not
|
||||
completely set aside but made available for userspace applications to use,
|
||||
through the CMA allocator.
|
||||
|
||||
3) As the same initrd is used for booting production kernel as well as capture
|
||||
kernel and with dump being captured in a restricted memory environment, few
|
||||
optimizations (like not inclding network dracut module, disabling multipath
|
||||
and such) are applied while building the initrd. In case, the production
|
||||
environment needs these optimizations to be avoided, dracut_args option in
|
||||
/etc/kdump.conf file could be leveraged. For example, if a user wishes for
|
||||
network module to be included in the initrd, adding the below entry in
|
||||
/etc/kdump.conf file and restarting kdump service would take care of it.
|
||||
|
||||
dracut_args --add "network"
|
||||
|
||||
4) If FADump is configured to capture vmcore to a remote dump target using SSH
|
||||
or NFS protocol, the network interface is renamed to kdump-<interface-name>
|
||||
if <interface-name> is generic, for example, *eth#, or net#. This problem
|
||||
occurs because the vmcore capture scripts in the initial RAM disk (initrd)
|
||||
add the kdump- prefix to the network interface name to secure persistent
|
||||
naming. As the same initrd is used for production kernel boot, the interface
|
||||
name is changed for the production kernel too.
|
||||
|
||||
Dump Triggering methods:
|
||||
|
||||
This section talks about the various ways, other than a Kernel Panic, in which
|
||||
fadump can be triggered. The following methods assume that fadump is configured
|
||||
on your system, with the scripts enabled as described in the section above.
|
||||
|
||||
1) AltSysRq C
|
||||
|
||||
FAdump can be triggered with the combination of the 'Alt','SysRq' and 'C'
|
||||
keyboard keys. Please refer to the following link for more details:
|
||||
|
||||
https://fedoraproject.org/wiki/QA/Sysrq
|
||||
|
||||
In addition, on PowerPC boxes, fadump can also be triggered via Hardware
|
||||
Management Console(HMC) using 'Ctrl', 'O' and 'C' keyboard keys.
|
||||
|
||||
2) Kernel OOPs
|
||||
|
||||
If we want to generate a dump everytime the Kernel OOPses, we can achieve this
|
||||
by setting the 'Panic On OOPs' option as follows:
|
||||
|
||||
# echo 1 > /proc/sys/kernel/panic_on_oops
|
||||
|
||||
3) PowerPC specific methods:
|
||||
|
||||
On IBM PowerPC machines, issuing a soft reset invokes the XMON debugger(if
|
||||
XMON is configured). To configure XMON one needs to compile the kernel with
|
||||
the CONFIG_XMON and CONFIG_XMON_DEFAULT options, or by compiling with
|
||||
CONFIG_XMON and booting the kernel with xmon=on option.
|
||||
|
||||
Following are the ways to remotely issue a soft reset on PowerPC boxes, which
|
||||
would drop you to XMON. Pressing a 'X' (capital alphabet X) followed by an
|
||||
'Enter' here will trigger the dump.
|
||||
|
||||
3.1) HMC
|
||||
|
||||
Hardware Management Console(HMC) available on Power4 and Power5 machines allow
|
||||
partitions to be reset remotely. This is specially useful in hang situations
|
||||
where the system is not accepting any keyboard inputs.
|
||||
|
||||
Once you have HMC configured, the following steps will enable you to trigger
|
||||
fadump via a soft reset:
|
||||
|
||||
On Power4
|
||||
Using GUI
|
||||
|
||||
* In the right pane, right click on the partition you wish to dump.
|
||||
* Select "Operating System->Reset".
|
||||
* Select "Soft Reset".
|
||||
* Select "Yes".
|
||||
|
||||
Using HMC Commandline
|
||||
|
||||
# reset_partition -m <machine> -p <partition> -t soft
|
||||
|
||||
On Power5
|
||||
Using GUI
|
||||
|
||||
* In the right pane, right click on the partition you wish to dump.
|
||||
* Select "Restart Partition".
|
||||
* Select "Dump".
|
||||
* Select "OK".
|
||||
|
||||
Using HMC Commandline
|
||||
|
||||
# chsysstate -m <managed system name> -n <lpar name> -o dumprestart -r lpar
|
||||
|
||||
3.2) Blade Management Console for Blade Center
|
||||
|
||||
To initiate a dump operation, go to Power/Restart option under "Blade Tasks" in
|
||||
the Blade Management Console. Select the corresponding blade for which you want
|
||||
to initate the dump and then click "Restart blade with NMI". This issues a
|
||||
system reset and invokes xmon debugger.
|
||||
|
||||
|
||||
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.
|
||||
|
||||
Compression and filtering
|
||||
|
||||
Refer "Compression and filtering" section in "kexec-kdump-howto.txt" document.
|
||||
Compression and filtering are same for kdump & fadump.
|
||||
|
||||
|
||||
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.
|
||||
|
||||
How to disable FADump:
|
||||
|
||||
Remove "fadump=on" from kernel cmdline parameters:
|
||||
|
||||
# grubby --update-kernel=/boot/vmlinuz-`uname -r` --remove-args="fadump=on"
|
||||
|
||||
If KDump is to be used as the dump capturing mechanism, update the crashkernel
|
||||
parameter (Else, remove "crashkernel=" parameter too, using grubby):
|
||||
|
||||
# grubby --update-kernel=/boot/vmlinuz-$kver --args="crashkernl=auto"
|
||||
|
||||
Reboot the system for the settings to take effect.
|
22
SOURCES/kdump-dep-generator.sh
Normal file
22
SOURCES/kdump-dep-generator.sh
Normal file
@ -0,0 +1,22 @@
|
||||
#!/bin/sh
|
||||
|
||||
# More details about systemd generator:
|
||||
# http://www.freedesktop.org/wiki/Software/systemd/Generators/
|
||||
|
||||
. /usr/lib/kdump/kdump-lib.sh
|
||||
|
||||
# If invokded with no arguments for testing purpose, output to /tmp to
|
||||
# avoid overriding the existing.
|
||||
dest_dir="/tmp"
|
||||
|
||||
if [ -n "$1" ]; then
|
||||
dest_dir=$1
|
||||
fi
|
||||
|
||||
systemd_dir=/usr/lib/systemd/system
|
||||
kdump_wants=$dest_dir/kdump.service.wants
|
||||
|
||||
if is_ssh_dump_target; then
|
||||
mkdir -p $kdump_wants
|
||||
ln -sf $systemd_dir/network-online.target $kdump_wants/
|
||||
fi
|
91
SOURCES/kdump-in-cluster-environment.txt
Normal file
91
SOURCES/kdump-in-cluster-environment.txt
Normal file
@ -0,0 +1,91 @@
|
||||
Kdump-in-cluster-environment HOWTO
|
||||
|
||||
Introduction
|
||||
|
||||
Kdump is a kexec based crash dumping mechansim for Linux. This docuement
|
||||
illustrate how to configure kdump in cluster environment to allow the kdump
|
||||
crash recovery service complete without being preempted by traditional power
|
||||
fencing methods.
|
||||
|
||||
Overview
|
||||
|
||||
Kexec/Kdump
|
||||
|
||||
Details about Kexec/Kdump are available in Kexec-Kdump-howto file and will not
|
||||
be described here.
|
||||
|
||||
fence_kdump
|
||||
|
||||
fence_kdump is an I/O fencing agent to be used with the kdump crash recovery
|
||||
service. When the fence_kdump agent is invoked, it will listen for a message
|
||||
from the failed node that acknowledges that the failed node is executing the
|
||||
kdump crash kernel. Note that fence_kdump is not a replacement for traditional
|
||||
fencing methods. The fence_kdump agent can only detect that a node has entered
|
||||
the kdump crash recovery service. This allows the kdump crash recovery service
|
||||
complete without being preempted by traditional power fencing methods.
|
||||
|
||||
fence_kdump_send
|
||||
|
||||
fence_kdump_send is a utility used to send messages that acknowledge that the
|
||||
node itself has entered the kdump crash recovery service. The fence_kdump_send
|
||||
utility is typically run in the kdump kernel after a cluster node has
|
||||
encountered a kernel panic. Once the cluster node has entered the kdump crash
|
||||
recovery service, fence_kdump_send will periodically send messages to all
|
||||
cluster nodes. When the fence_kdump agent receives a valid message from the
|
||||
failed nodes, fencing is complete.
|
||||
|
||||
How to configure Pacemaker cluster environment:
|
||||
|
||||
If we want to use kdump in Pacemaker cluster environment, fence-agents-kdump
|
||||
should be installed in every nodes in the cluster. You can achieve this via
|
||||
the following command:
|
||||
|
||||
# yum install -y fence-agents-kdump
|
||||
|
||||
Next is to add kdump_fence to the cluster. Assuming that the cluster consists
|
||||
of three nodes, they are node1, node2 and node3, and use Pacemaker to perform
|
||||
resource management and pcs as cli configuration tool.
|
||||
|
||||
With pcs it is easy to add a stonith resource to the cluster. For example, add
|
||||
a stonith resource named mykdumpfence with fence type of fence_kdump via the
|
||||
following commands:
|
||||
|
||||
# pcs stonith create mykdumpfence fence_kdump \
|
||||
pcmk_host_check=static-list pcmk_host_list="node1 node2 node3"
|
||||
# pcs stonith update mykdumpfence pcmk_monitor_action=metadata --force
|
||||
# pcs stonith update mykdumpfence pcmk_status_action=metadata --force
|
||||
# pcs stonith update mykdumpfence pcmk_reboot_action=off --force
|
||||
|
||||
Then enable stonith
|
||||
# pcs property set stonith-enabled=true
|
||||
|
||||
How to configure kdump:
|
||||
|
||||
Actually there are two ways how to configure fence_kdump support:
|
||||
|
||||
1) Pacemaker based clusters
|
||||
If you have successfully configured fence_kdump in Pacemaker, there is
|
||||
no need to add some special configuration in kdump. So please refer to
|
||||
Kexec-Kdump-howto file for more information.
|
||||
|
||||
2) Generic clusters
|
||||
For other types of clusters there are two configuration options in
|
||||
kdump.conf which enables fence_kdump support:
|
||||
|
||||
fence_kdump_nodes <node(s)>
|
||||
Contains list of cluster node(s) separated by space to send
|
||||
fence_kdump notification to (this option is mandatory to enable
|
||||
fence_kdump)
|
||||
|
||||
fence_kdump_args <arg(s)>
|
||||
Command line arguments for fence_kdump_send (it can contain
|
||||
all valid arguments except hosts to send notification to)
|
||||
|
||||
These options will most probably be configured by your cluster software,
|
||||
so please refer to your cluster documentation how to enable fence_kdump
|
||||
support.
|
||||
|
||||
Please be aware that these two ways cannot be combined and 2) has precedence
|
||||
over 1). It means that if fence_kdump is configured using fence_kdump_nodes
|
||||
and fence_kdump_args options in kdump.conf, Pacemaker configuration is not
|
||||
used even if it exists.
|
214
SOURCES/kdump-lib-initramfs.sh
Executable file
214
SOURCES/kdump-lib-initramfs.sh
Executable file
@ -0,0 +1,214 @@
|
||||
# These variables and functions are useful in 2nd kernel
|
||||
|
||||
. /lib/kdump-lib.sh
|
||||
|
||||
KDUMP_PATH="/var/crash"
|
||||
CORE_COLLECTOR=""
|
||||
DEFAULT_CORE_COLLECTOR="makedumpfile -l --message-level 1 -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"
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
# dump_fs <mount point>
|
||||
dump_fs()
|
||||
{
|
||||
local _mp=$1
|
||||
local _dev=$(get_mount_info SOURCE target $_mp -f)
|
||||
local _op=$(get_mount_info OPTIONS target $_mp -f)
|
||||
|
||||
# If dump path have a corresponding device entry but not mounted, mount it.
|
||||
if [ -n "$_dev" ] || [ "$_dev" == "rootfs" ]; then
|
||||
if ! is_mounted "$_mp"; then
|
||||
echo "kdump: dump target $_dev is not mounted, trying to mount..."
|
||||
mkdir -p $_mp
|
||||
mount -o $_op $_dev $_mp
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "kdump: mounting failed (mount point: $_mp, option: $_op)"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
else
|
||||
echo "kdump: failed to dump to \"$_mp\", it's not a mount point!"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Remove -F in makedumpfile case. We don't want a flat format dump here.
|
||||
[[ $CORE_COLLECTOR = *makedumpfile* ]] && CORE_COLLECTOR=`echo $CORE_COLLECTOR | sed -e "s/-F//g"`
|
||||
|
||||
echo "kdump: saving to $_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR/"
|
||||
|
||||
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/"
|
||||
|
||||
echo "kdump: saving vmcore"
|
||||
$CORE_COLLECTOR /proc/vmcore $_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR/vmcore-incomplete || return 1
|
||||
mv $_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR/vmcore-incomplete $_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR/vmcore
|
||||
sync
|
||||
|
||||
echo "kdump: saving vmcore complete"
|
||||
|
||||
# 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
|
||||
|
||||
echo "kdump: saving vmcore-dmesg.txt"
|
||||
$_dmesg_collector /proc/vmcore > ${_path}/vmcore-dmesg-incomplete.txt
|
||||
_exitcode=$?
|
||||
if [ $_exitcode -eq 0 ]; then
|
||||
mv ${_path}/vmcore-dmesg-incomplete.txt ${_path}/vmcore-dmesg.txt
|
||||
|
||||
# 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
|
||||
echo "kdump: saving vmcore-dmesg.txt complete"
|
||||
else
|
||||
echo "kdump: 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
|
||||
|
||||
echo "kdump: saving opalcore"
|
||||
cp $OPALCORE ${_path}/opalcore
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "kdump: saving opalcore failed"
|
||||
return 1
|
||||
fi
|
||||
|
||||
sync
|
||||
echo "kdump: saving opalcore complete"
|
||||
return 0
|
||||
}
|
||||
|
||||
dump_to_rootfs()
|
||||
{
|
||||
|
||||
echo "Kdump: trying to bring up rootfs device"
|
||||
systemctl start dracut-initqueue
|
||||
echo "Kdump: waiting for rootfs mount, will timeout after 90 seconds"
|
||||
systemctl start sysroot.mount
|
||||
|
||||
dump_fs $NEWROOT
|
||||
}
|
||||
|
||||
kdump_emergency_shell()
|
||||
{
|
||||
echo "PS1=\"kdump:\\\${PWD}# \"" >/etc/profile
|
||||
/bin/dracut-emergency
|
||||
rm -f /etc/profile
|
||||
}
|
||||
|
||||
do_failure_action()
|
||||
{
|
||||
echo "Kdump: Executing failure action $FAILURE_ACTION"
|
||||
eval $FAILURE_ACTION
|
||||
}
|
||||
|
||||
do_final_action()
|
||||
{
|
||||
eval $FINAL_ACTION
|
||||
}
|
745
SOURCES/kdump-lib.sh
Executable file
745
SOURCES/kdump-lib.sh
Executable file
@ -0,0 +1,745 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Kdump common variables and functions
|
||||
#
|
||||
|
||||
DEFAULT_PATH="/var/crash/"
|
||||
FENCE_KDUMP_CONFIG_FILE="/etc/sysconfig/fence_kdump"
|
||||
FENCE_KDUMP_SEND="/usr/libexec/fence_kdump_send"
|
||||
FADUMP_ENABLED_SYS_NODE="/sys/kernel/fadump_enabled"
|
||||
|
||||
is_fadump_capable()
|
||||
{
|
||||
# Check if firmware-assisted dump is enabled
|
||||
# if no, fallback to kdump check
|
||||
if [ -f $FADUMP_ENABLED_SYS_NODE ]; then
|
||||
rc=`cat $FADUMP_ENABLED_SYS_NODE`
|
||||
[ $rc -eq 1 ] && return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
perror_exit() {
|
||||
echo $@ >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
perror() {
|
||||
echo $@ >&2
|
||||
}
|
||||
|
||||
is_ssh_dump_target()
|
||||
{
|
||||
grep -q "^ssh[[:blank:]].*@" /etc/kdump.conf
|
||||
}
|
||||
|
||||
is_nfs_dump_target()
|
||||
{
|
||||
grep -q "^nfs" /etc/kdump.conf || \
|
||||
[[ $(get_dracut_args_fstype "$(grep "^dracut_args .*\-\-mount" /etc/kdump.conf)") = nfs* ]]
|
||||
}
|
||||
|
||||
is_raw_dump_target()
|
||||
{
|
||||
grep -q "^raw" /etc/kdump.conf
|
||||
}
|
||||
|
||||
is_fs_type_nfs()
|
||||
{
|
||||
local _fstype=$1
|
||||
[ $_fstype = "nfs" ] || [ $_fstype = "nfs4" ] && return 0
|
||||
return 1
|
||||
}
|
||||
|
||||
is_fs_dump_target()
|
||||
{
|
||||
egrep -q "^ext[234]|^xfs|^btrfs|^minix" /etc/kdump.conf
|
||||
}
|
||||
|
||||
strip_comments()
|
||||
{
|
||||
echo $@ | sed -e 's/\(.*\)#.*/\1/'
|
||||
}
|
||||
|
||||
# Read from kdump config file stripping all comments
|
||||
read_strip_comments()
|
||||
{
|
||||
# strip heading spaces, and print any content starting with
|
||||
# neither space or #, and strip everything after #
|
||||
sed -n -e "s/^\s*\([^# \t][^#]\+\).*/\1/gp" $1
|
||||
}
|
||||
|
||||
# Check if fence kdump is configured in Pacemaker cluster
|
||||
is_pcs_fence_kdump()
|
||||
{
|
||||
# no pcs or fence_kdump_send executables installed?
|
||||
type -P pcs > /dev/null || return 1
|
||||
[ -x $FENCE_KDUMP_SEND ] || return 1
|
||||
|
||||
# fence kdump not configured?
|
||||
(pcs cluster cib | grep 'type="fence_kdump"') &> /dev/null || return 1
|
||||
}
|
||||
|
||||
# Check if fence_kdump is configured using kdump options
|
||||
is_generic_fence_kdump()
|
||||
{
|
||||
[ -x $FENCE_KDUMP_SEND ] || return 1
|
||||
|
||||
grep -q "^fence_kdump_nodes" /etc/kdump.conf
|
||||
}
|
||||
|
||||
to_dev_name() {
|
||||
local dev="${1//\"/}"
|
||||
|
||||
case "$dev" in
|
||||
UUID=*)
|
||||
dev=`blkid -U "${dev#UUID=}"`
|
||||
;;
|
||||
LABEL=*)
|
||||
dev=`blkid -L "${dev#LABEL=}"`
|
||||
;;
|
||||
esac
|
||||
echo $dev
|
||||
}
|
||||
|
||||
is_user_configured_dump_target()
|
||||
{
|
||||
return $(is_mount_in_dracut_args || is_ssh_dump_target || is_nfs_dump_target || \
|
||||
is_raw_dump_target || is_fs_dump_target)
|
||||
}
|
||||
|
||||
get_user_configured_dump_disk()
|
||||
{
|
||||
local _target
|
||||
|
||||
_target=$(egrep "^ext[234]|^xfs|^btrfs|^minix|^raw" /etc/kdump.conf 2>/dev/null |awk '{print $2}')
|
||||
[ -n "$_target" ] && echo $_target && return
|
||||
|
||||
_target=$(get_dracut_args_target "$(grep "^dracut_args .*\-\-mount" /etc/kdump.conf)")
|
||||
[ -b "$_target" ] && echo $_target
|
||||
}
|
||||
|
||||
get_root_fs_device()
|
||||
{
|
||||
findmnt -k -f -n -o SOURCE /
|
||||
}
|
||||
|
||||
get_save_path()
|
||||
{
|
||||
local _save_path=$(awk '$1 == "path" {print $2}' /etc/kdump.conf)
|
||||
[ -z "$_save_path" ] && _save_path=$DEFAULT_PATH
|
||||
|
||||
# strip the duplicated "/"
|
||||
echo $_save_path | tr -s /
|
||||
}
|
||||
|
||||
get_block_dump_target()
|
||||
{
|
||||
local _target _path
|
||||
|
||||
if is_ssh_dump_target || is_nfs_dump_target; then
|
||||
return
|
||||
fi
|
||||
|
||||
_target=$(get_user_configured_dump_disk)
|
||||
[ -n "$_target" ] && echo $(to_dev_name $_target) && return
|
||||
|
||||
# Get block device name from local save path
|
||||
_path=$(get_save_path)
|
||||
_target=$(get_target_from_path $_path)
|
||||
[ -b "$_target" ] && echo $(to_dev_name $_target)
|
||||
}
|
||||
|
||||
is_dump_to_rootfs()
|
||||
{
|
||||
grep -E "^(failure_action|default)[[:space:]]dump_to_rootfs" /etc/kdump.conf >/dev/null
|
||||
}
|
||||
|
||||
get_failure_action_target()
|
||||
{
|
||||
local _target
|
||||
|
||||
if is_dump_to_rootfs; then
|
||||
# Get rootfs device name
|
||||
_target=$(get_root_fs_device)
|
||||
[ -b "$_target" ] && echo $(to_dev_name $_target) && return
|
||||
# Then, must be nfs root
|
||||
echo "nfs"
|
||||
fi
|
||||
}
|
||||
|
||||
# Get kdump targets(including root in case of dump_to_rootfs).
|
||||
get_kdump_targets()
|
||||
{
|
||||
local _target _root
|
||||
local kdump_targets
|
||||
|
||||
_target=$(get_block_dump_target)
|
||||
if [ -n "$_target" ]; then
|
||||
kdump_targets=$_target
|
||||
elif is_ssh_dump_target; then
|
||||
kdump_targets="ssh"
|
||||
else
|
||||
kdump_targets="nfs"
|
||||
fi
|
||||
|
||||
# Add the root device if dump_to_rootfs is specified.
|
||||
_root=$(get_failure_action_target)
|
||||
if [ -n "$_root" -a "$kdump_targets" != "$_root" ]; then
|
||||
kdump_targets="$kdump_targets $_root"
|
||||
fi
|
||||
|
||||
echo "$kdump_targets"
|
||||
}
|
||||
|
||||
# Return the bind mount source path, return the path itself if it's not bind mounted
|
||||
# Eg. if /path/to/src is bind mounted to /mnt/bind, then:
|
||||
# /mnt/bind -> /path/to/src, /mnt/bind/dump -> /path/to/src/dump
|
||||
#
|
||||
# findmnt uses the option "-v, --nofsroot" to exclusive the [/dir]
|
||||
# in the SOURCE column for bind-mounts, then if $_mntpoint equals to
|
||||
# $_mntpoint_nofsroot, the mountpoint is not bind mounted directory.
|
||||
#
|
||||
# Below is just an example for mount info
|
||||
# /dev/mapper/atomicos-root[/ostree/deploy/rhel-atomic-host/var], if the
|
||||
# directory is bind mounted. The former part represents the device path, rest
|
||||
# part is the bind mounted directory which quotes by bracket "[]".
|
||||
get_bind_mount_source()
|
||||
{
|
||||
local _path=$1
|
||||
# In case it's a sub path in a mount point, get the mount point first
|
||||
local _mnt_top=$(df $_path | tail -1 | awk '{print $NF}')
|
||||
local _mntpoint=$(findmnt $_mnt_top | tail -n 1 | awk '{print $2}')
|
||||
local _mntpoint_nofsroot=$(findmnt -v $_mnt_top | tail -n 1 | awk '{print $2}')
|
||||
|
||||
if [[ "$_mntpoint" = $_mntpoint_nofsroot ]]; then
|
||||
echo $_path && return
|
||||
fi
|
||||
|
||||
_mntpoint=${_mntpoint#*$_mntpoint_nofsroot}
|
||||
_mntpoint=${_mntpoint#[}
|
||||
_mntpoint=${_mntpoint%]}
|
||||
_path=${_path#$_mnt_top}
|
||||
|
||||
echo $_mntpoint$_path
|
||||
}
|
||||
|
||||
# Return the current underlaying device of a path, ignore bind mounts
|
||||
get_target_from_path()
|
||||
{
|
||||
local _target
|
||||
|
||||
_target=$(df $1 2>/dev/null | tail -1 | awk '{print $1}')
|
||||
[[ "$_target" == "/dev/root" ]] && [[ ! -e /dev/root ]] && _target=$(get_root_fs_device)
|
||||
echo $_target
|
||||
}
|
||||
|
||||
is_mounted()
|
||||
{
|
||||
findmnt -k -n $1 &>/dev/null
|
||||
}
|
||||
|
||||
get_mount_info()
|
||||
{
|
||||
local _info_type=$1 _src_type=$2 _src=$3; shift 3
|
||||
local _info=$(findmnt -k -n -r -o $_info_type --$_src_type $_src $@)
|
||||
|
||||
[ -z "$_info" ] && [ -e "/etc/fstab" ] && _info=$(findmnt -s -n -r -o $_info_type --$_src_type $_src $@)
|
||||
|
||||
echo $_info
|
||||
}
|
||||
|
||||
get_fs_type_from_target()
|
||||
{
|
||||
get_mount_info FSTYPE source $1 -f
|
||||
}
|
||||
|
||||
get_mntopt_from_target()
|
||||
{
|
||||
get_mount_info OPTIONS source $1 -f
|
||||
}
|
||||
# Find the general mount point of a dump target, not the bind mount point
|
||||
get_mntpoint_from_target()
|
||||
{
|
||||
# Expcilitly specify --source to findmnt could ensure non-bind mount is returned
|
||||
get_mount_info TARGET source $1 -f
|
||||
}
|
||||
|
||||
# Get the path where the target will be mounted in kdump kernel
|
||||
# $1: kdump target device
|
||||
get_kdump_mntpoint_from_target()
|
||||
{
|
||||
local _mntpoint=$(get_mntpoint_from_target $1)
|
||||
|
||||
# mount under /sysroot if dump to root disk or mount under
|
||||
# mount under /kdumproot if dump target is not mounted in first kernel
|
||||
# mount under /kdumproot/$_mntpoint in other cases in 2nd kernel.
|
||||
# systemd will be in charge to umount it.
|
||||
if [ -z "$_mntpoint" ];then
|
||||
_mntpoint="/kdumproot"
|
||||
else
|
||||
if [ "$_mntpoint" = "/" ];then
|
||||
_mntpoint="/sysroot"
|
||||
else
|
||||
_mntpoint="/kdumproot/$_mntpoint"
|
||||
fi
|
||||
fi
|
||||
|
||||
# strip duplicated "/"
|
||||
echo $_mntpoint | tr -s "/"
|
||||
}
|
||||
|
||||
# get_option_value <option_name>
|
||||
# retrieves value of option defined in kdump.conf
|
||||
get_option_value() {
|
||||
strip_comments `grep "^$1[[:space:]]\+" /etc/kdump.conf | tail -1 | cut -d\ -f2-`
|
||||
}
|
||||
|
||||
kdump_get_persistent_dev() {
|
||||
local dev="${1//\"/}"
|
||||
|
||||
case "$dev" in
|
||||
UUID=*)
|
||||
dev=`blkid -U "${dev#UUID=}"`
|
||||
;;
|
||||
LABEL=*)
|
||||
dev=`blkid -L "${dev#LABEL=}"`
|
||||
;;
|
||||
esac
|
||||
echo $(get_persistent_dev "$dev")
|
||||
}
|
||||
|
||||
is_atomic()
|
||||
{
|
||||
grep -q "ostree" /proc/cmdline
|
||||
}
|
||||
|
||||
# fixme, try the best to decide whether the ipv6 addr is allocated by slaac or dhcp6
|
||||
is_ipv6_auto()
|
||||
{
|
||||
local _netdev=$1
|
||||
local _auto=$(cat /proc/sys/net/ipv6/conf/$_netdev/autoconf)
|
||||
if [ $_auto -eq 1 ]; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
is_ipv6_address()
|
||||
{
|
||||
echo $1 | grep -q ":"
|
||||
}
|
||||
|
||||
# get ip address or hostname from nfs/ssh config value
|
||||
get_remote_host()
|
||||
{
|
||||
local _config_val=$1
|
||||
|
||||
# ipv6 address in kdump.conf is around with "[]",
|
||||
# factor out the ipv6 address
|
||||
_config_val=${_config_val#*@}
|
||||
_config_val=${_config_val%:/*}
|
||||
_config_val=${_config_val#[}
|
||||
_config_val=${_config_val%]}
|
||||
echo $_config_val
|
||||
}
|
||||
|
||||
is_hostname()
|
||||
{
|
||||
local _hostname=`echo $1 | grep ":"`
|
||||
|
||||
if [ -n "$_hostname" ]; then
|
||||
return 1
|
||||
fi
|
||||
echo $1 | grep -q "[a-zA-Z]"
|
||||
}
|
||||
|
||||
# Copied from "/etc/sysconfig/network-scripts/network-functions"
|
||||
get_hwaddr()
|
||||
{
|
||||
if [ -f "/sys/class/net/${1}/address" ]; then
|
||||
awk '{ print toupper($0) }' < /sys/class/net/${1}/address
|
||||
elif [ -d "/sys/class/net/${1}" ]; then
|
||||
LC_ALL= LANG= ip -o link show ${1} 2>/dev/null | \
|
||||
awk '{ print toupper(gensub(/.*link\/[^ ]* ([[:alnum:]:]*).*/,
|
||||
"\\1", 1)); }'
|
||||
fi
|
||||
}
|
||||
|
||||
get_ifcfg_by_device()
|
||||
{
|
||||
grep -E -i -l "^[[:space:]]*DEVICE=\"*${1}\"*[[:space:]]*$" \
|
||||
/etc/sysconfig/network-scripts/ifcfg-* 2>/dev/null | head -1
|
||||
}
|
||||
|
||||
get_ifcfg_by_hwaddr()
|
||||
{
|
||||
grep -E -i -l "^[[:space:]]*HWADDR=\"*${1}\"*[[:space:]]*$" \
|
||||
/etc/sysconfig/network-scripts/ifcfg-* 2>/dev/null | head -1
|
||||
}
|
||||
|
||||
get_ifcfg_by_uuid()
|
||||
{
|
||||
grep -E -i -l "^[[:space:]]*UUID=\"*${1}\"*[[:space:]]*$" \
|
||||
/etc/sysconfig/network-scripts/ifcfg-* 2>/dev/null | head -1
|
||||
}
|
||||
|
||||
get_ifcfg_by_name()
|
||||
{
|
||||
grep -E -i -l "^[[:space:]]*NAME=\"*${1}\"*[[:space:]]*$" \
|
||||
/etc/sysconfig/network-scripts/ifcfg-* 2>/dev/null | head -1
|
||||
}
|
||||
|
||||
is_nm_running()
|
||||
{
|
||||
[ "$(LANG=C nmcli -t --fields running general status 2>/dev/null)" = "running" ]
|
||||
}
|
||||
|
||||
is_nm_handling()
|
||||
{
|
||||
LANG=C nmcli -t --fields device,state dev status 2>/dev/null \
|
||||
| grep -q "^\(${1}:connected\)\|\(${1}:connecting.*\)$"
|
||||
}
|
||||
|
||||
# $1: netdev name
|
||||
get_ifcfg_nmcli()
|
||||
{
|
||||
local nm_uuid nm_name
|
||||
local ifcfg_file
|
||||
|
||||
# Get the active nmcli config name of $1
|
||||
if is_nm_running && is_nm_handling "${1}" ; then
|
||||
# The configuration "uuid" and "name" generated by nm is wrote to
|
||||
# the ifcfg file as "UUID=<nm_uuid>" and "NAME=<nm_name>".
|
||||
nm_uuid=$(LANG=C nmcli -t --fields uuid,device c show --active 2>/dev/null \
|
||||
| grep "${1}" | head -1 | cut -d':' -f1)
|
||||
nm_name=$(LANG=C nmcli -t --fields name,device c show --active 2>/dev/null \
|
||||
| grep "${1}" | head -1 | cut -d':' -f1)
|
||||
ifcfg_file=$(get_ifcfg_by_uuid "${nm_uuid}")
|
||||
[ -z "${ifcfg_file}" ] && ifcfg_file=$(get_ifcfg_by_name "${nm_name}")
|
||||
fi
|
||||
|
||||
echo -n "${ifcfg_file}"
|
||||
}
|
||||
|
||||
# $1: netdev name
|
||||
get_ifcfg_legacy()
|
||||
{
|
||||
local ifcfg_file
|
||||
|
||||
ifcfg_file="/etc/sysconfig/network-scripts/ifcfg-${1}"
|
||||
[ -f "${ifcfg_file}" ] && echo -n "${ifcfg_file}" && return
|
||||
|
||||
ifcfg_file=$(get_ifcfg_by_name "${1}")
|
||||
[ -f "${ifcfg_file}" ] && echo -n "${ifcfg_file}" && return
|
||||
|
||||
local hwaddr=$(get_hwaddr "${1}")
|
||||
if [ -n "$hwaddr" ]; then
|
||||
ifcfg_file=$(get_ifcfg_by_hwaddr "${hwaddr}")
|
||||
[ -f "${ifcfg_file}" ] && echo -n "${ifcfg_file}" && return
|
||||
fi
|
||||
|
||||
ifcfg_file=$(get_ifcfg_by_device "${1}")
|
||||
|
||||
echo -n "${ifcfg_file}"
|
||||
}
|
||||
|
||||
# $1: netdev name
|
||||
# Return the ifcfg file whole name(including the path) of $1 if any.
|
||||
get_ifcfg_filename() {
|
||||
local ifcfg_file
|
||||
|
||||
ifcfg_file=$(get_ifcfg_nmcli "${1}")
|
||||
if [ -z "${ifcfg_file}" ]; then
|
||||
ifcfg_file=$(get_ifcfg_legacy "${1}")
|
||||
fi
|
||||
|
||||
echo -n "${ifcfg_file}"
|
||||
}
|
||||
|
||||
# returns 0 when omission of watchdog module is desired in dracut_args
|
||||
# returns 1 otherwise
|
||||
is_wdt_mod_omitted() {
|
||||
local dracut_args
|
||||
local ret=1
|
||||
|
||||
dracut_args=$(grep "^dracut_args" /etc/kdump.conf)
|
||||
[[ -z $dracut_args ]] && return $ret
|
||||
|
||||
eval set -- $dracut_args
|
||||
while :; do
|
||||
[[ -z $1 ]] && break
|
||||
case $1 in
|
||||
-o|--omit)
|
||||
echo $2 | grep -qw "watchdog"
|
||||
[[ $? == 0 ]] && ret=0
|
||||
break
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
return $ret
|
||||
}
|
||||
|
||||
# If "dracut_args" contains "--mount" information, use it
|
||||
# directly without any check(users are expected to ensure
|
||||
# its correctness).
|
||||
is_mount_in_dracut_args()
|
||||
{
|
||||
grep -q "^dracut_args .*\-\-mount" /etc/kdump.conf
|
||||
}
|
||||
|
||||
# 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
|
||||
}
|
||||
|
||||
check_crash_mem_reserved()
|
||||
{
|
||||
local mem_reserved
|
||||
|
||||
mem_reserved=$(cat /sys/kernel/kexec_crash_size)
|
||||
if [ $mem_reserved -eq 0 ]; then
|
||||
echo "No memory reserved for crash kernel"
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
check_kdump_feasibility()
|
||||
{
|
||||
if [ ! -e /sys/kernel/kexec_crash_loaded ]; then
|
||||
echo "Kdump is not supported on this kernel"
|
||||
return 1
|
||||
fi
|
||||
check_crash_mem_reserved
|
||||
return $?
|
||||
}
|
||||
|
||||
check_current_kdump_status()
|
||||
{
|
||||
if [ ! -f /sys/kernel/kexec_crash_loaded ];then
|
||||
echo "Perhaps CONFIG_CRASH_DUMP is not enabled in kernel"
|
||||
return 1
|
||||
fi
|
||||
|
||||
rc=`cat /sys/kernel/kexec_crash_loaded`
|
||||
if [ $rc == 1 ]; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# remove_cmdline_param <kernel cmdline> <param1> [<param2>] ... [<paramN>]
|
||||
# Remove a list of kernel parameters from a given kernel cmdline and print the result.
|
||||
# For each "arg" in the removing params list, "arg" and "arg=xxx" will be removed if exists.
|
||||
remove_cmdline_param()
|
||||
{
|
||||
local cmdline=$1
|
||||
shift
|
||||
|
||||
for arg in $@; do
|
||||
cmdline=`echo $cmdline | \
|
||||
sed -e "s/\b$arg=[^ ]*//g" \
|
||||
-e "s/^$arg\b//g" \
|
||||
-e "s/[[:space:]]$arg\b//g" \
|
||||
-e "s/\s\+/ /g"`
|
||||
done
|
||||
echo $cmdline
|
||||
}
|
||||
|
||||
#
|
||||
# This function returns the "apicid" of the boot
|
||||
# cpu (cpu 0) if present.
|
||||
#
|
||||
get_bootcpu_apicid()
|
||||
{
|
||||
awk ' \
|
||||
BEGIN { CPU = "-1"; } \
|
||||
$1=="processor" && $2==":" { CPU = $NF; } \
|
||||
CPU=="0" && /^apicid/ { print $NF; } \
|
||||
' \
|
||||
/proc/cpuinfo
|
||||
}
|
||||
|
||||
#
|
||||
# append_cmdline <kernel cmdline> <parameter name> <parameter value>
|
||||
# This function appends argument "$2=$3" to string ($1) if not already present.
|
||||
#
|
||||
append_cmdline()
|
||||
{
|
||||
local cmdline=$1
|
||||
local newstr=${cmdline/$2/""}
|
||||
|
||||
# unchanged str implies argument wasn't there
|
||||
if [ "$cmdline" == "$newstr" ]; then
|
||||
cmdline="${cmdline} ${2}=${3}"
|
||||
fi
|
||||
|
||||
echo $cmdline
|
||||
}
|
||||
|
||||
# This function check iomem and determines if we have more than
|
||||
# 4GB of ram available. Returns 1 if we do, 0 if we dont
|
||||
need_64bit_headers()
|
||||
{
|
||||
return `tail -n 1 /proc/iomem | awk '{ split ($1, r, "-"); \
|
||||
print (strtonum("0x" r[2]) > strtonum("0xffffffff")); }'`
|
||||
}
|
||||
|
||||
# Check if secure boot is being enforced.
|
||||
#
|
||||
# Per Peter Jones, we need check efivar SecureBoot-$(the UUID) and
|
||||
# SetupMode-$(the UUID), they are both 5 bytes binary data. The first four
|
||||
# bytes are the attributes associated with the variable and can safely be
|
||||
# ignored, the last bytes are one-byte true-or-false variables. If SecureBoot
|
||||
# is 1 and SetupMode is 0, then secure boot is being enforced.
|
||||
#
|
||||
# Assume efivars is mounted at /sys/firmware/efi/efivars.
|
||||
is_secure_boot_enforced()
|
||||
{
|
||||
local secure_boot_file setup_mode_file
|
||||
local secure_boot_byte setup_mode_byte
|
||||
|
||||
# On powerpc, os-secureboot-enforcing DT property indicates whether secureboot
|
||||
# is enforced. Return success, if it is found.
|
||||
if [ -f /proc/device-tree/ibm,secureboot/os-secureboot-enforcing ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Detect secure boot on x86 and arm64
|
||||
secure_boot_file=$(find /sys/firmware/efi/efivars -name SecureBoot-* 2>/dev/null)
|
||||
setup_mode_file=$(find /sys/firmware/efi/efivars -name SetupMode-* 2>/dev/null)
|
||||
|
||||
if [ -f "$secure_boot_file" ] && [ -f "$setup_mode_file" ]; then
|
||||
secure_boot_byte=$(hexdump -v -e '/1 "%d\ "' $secure_boot_file|cut -d' ' -f 5)
|
||||
setup_mode_byte=$(hexdump -v -e '/1 "%d\ "' $setup_mode_file|cut -d' ' -f 5)
|
||||
|
||||
if [ "$secure_boot_byte" = "1" ] && [ "$setup_mode_byte" = "0" ]; then
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
|
||||
# Detect secure boot on s390x
|
||||
if [[ -e "/sys/firmware/ipl/secure" && "$(cat /sys/firmware/ipl/secure)" == "1" ]]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
#
|
||||
# prepare_kexec_args <kexec args>
|
||||
# This function prepares kexec argument.
|
||||
#
|
||||
prepare_kexec_args()
|
||||
{
|
||||
local kexec_args=$1
|
||||
local found_elf_args
|
||||
|
||||
ARCH=`uname -m`
|
||||
if [ "$ARCH" == "i686" -o "$ARCH" == "i386" ]
|
||||
then
|
||||
need_64bit_headers
|
||||
if [ $? == 1 ]
|
||||
then
|
||||
found_elf_args=`echo $kexec_args | grep elf32-core-headers`
|
||||
if [ -n "$found_elf_args" ]
|
||||
then
|
||||
echo -n "Warning: elf32-core-headers overrides correct elf64 setting"
|
||||
echo
|
||||
else
|
||||
kexec_args="$kexec_args --elf64-core-headers"
|
||||
fi
|
||||
else
|
||||
found_elf_args=`echo $kexec_args | grep elf64-core-headers`
|
||||
if [ -z "$found_elf_args" ]
|
||||
then
|
||||
kexec_args="$kexec_args --elf32-core-headers"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
echo $kexec_args
|
||||
}
|
||||
|
||||
check_boot_dir()
|
||||
{
|
||||
local kdump_bootdir=$1
|
||||
#If user specify a boot dir for kdump kernel, let's use it. Otherwise
|
||||
#check whether it's a atomic host. If yes parse the subdirectory under
|
||||
#/boot; If not just find it under /boot.
|
||||
if [ -n "$kdump_bootdir" ]; then
|
||||
echo "$kdump_bootdir"
|
||||
return
|
||||
fi
|
||||
|
||||
if ! is_atomic || [ "$(uname -m)" = "s390x" ]; then
|
||||
kdump_bootdir="/boot"
|
||||
else
|
||||
eval $(cat /proc/cmdline| grep "BOOT_IMAGE" | cut -d' ' -f1)
|
||||
kdump_bootdir="/boot"$(dirname $BOOT_IMAGE)
|
||||
fi
|
||||
echo $kdump_bootdir
|
||||
}
|
||||
|
||||
#
|
||||
# prepare_cmdline <commandline> <commandline remove> <commandline append>
|
||||
# This function performs a series of edits on the command line.
|
||||
# Store the final result in global $KDUMP_COMMANDLINE.
|
||||
prepare_cmdline()
|
||||
{
|
||||
local cmdline id
|
||||
|
||||
if [ -z "$1" ]; then
|
||||
cmdline=$(cat /proc/cmdline)
|
||||
else
|
||||
cmdline="$1"
|
||||
fi
|
||||
|
||||
# These params should always be removed
|
||||
cmdline=$(remove_cmdline_param "$cmdline" crashkernel panic_on_warn)
|
||||
# These params can be removed configurably
|
||||
cmdline=$(remove_cmdline_param "$cmdline" "$2")
|
||||
|
||||
# Always remove "root=X", as we now explicitly generate all kinds
|
||||
# of dump target mount information including root fs.
|
||||
#
|
||||
# We do this before KDUMP_COMMANDLINE_APPEND, if one really cares
|
||||
# about it(e.g. for debug purpose), then can pass "root=X" using
|
||||
# KDUMP_COMMANDLINE_APPEND.
|
||||
cmdline=$(remove_cmdline_param "$cmdline" root)
|
||||
|
||||
# With the help of "--hostonly-cmdline", we can avoid some interitage.
|
||||
cmdline=$(remove_cmdline_param "$cmdline" rd.lvm.lv rd.luks.uuid rd.dm.uuid rd.md.uuid fcoe)
|
||||
|
||||
# Remove netroot, rd.iscsi.initiator and iscsi_initiator since
|
||||
# we get duplicate entries for the same in case iscsi code adds
|
||||
# it as well.
|
||||
cmdline=$(remove_cmdline_param "$cmdline" netroot rd.iscsi.initiator iscsi_initiator)
|
||||
|
||||
cmdline="${cmdline} $3"
|
||||
|
||||
id=$(get_bootcpu_apicid)
|
||||
if [ ! -z ${id} ] ; then
|
||||
cmdline=$(append_cmdline "${cmdline}" disable_cpu_apicid ${id})
|
||||
fi
|
||||
|
||||
# Disable efifb if hyperv_fb is in use, hyperv_fb will relocate the framebuffer
|
||||
# but kexec_file_load always use original screen_info and in second kernel efifb
|
||||
# will try to access an invalid framebuffer address
|
||||
if [ -d /sys/module/hyperv_fb ]; then
|
||||
cmdline=$(append_cmdline "$cmdline" "video=efifb:off")
|
||||
fi
|
||||
|
||||
echo ${cmdline}
|
||||
}
|
42
SOURCES/kdump-udev-throttler
Executable file
42
SOURCES/kdump-udev-throttler
Executable file
@ -0,0 +1,42 @@
|
||||
#!/bin/bash
|
||||
# This util helps to reduce the workload of kdump service restarting
|
||||
# on udev event. When hotplugging memory / CPU, multiple udev
|
||||
# events may be triggered concurrently, and obviously, we don't want
|
||||
# to restart kdump service for each event.
|
||||
|
||||
# This script will be called by udev, and make sure kdump service is
|
||||
# restart after all events we are watching are settled.
|
||||
|
||||
# On each call, this script will update try to aquire the $throttle_lock
|
||||
# The first instance acquired the file lock will keep waiting for events
|
||||
# to settle and then reload kdump. Other instances will just exit
|
||||
# In this way, we can make sure kdump service is restarted immediately
|
||||
# and for exactly once after udev events are settled.
|
||||
|
||||
throttle_lock="/var/lock/kdump-udev-throttle"
|
||||
|
||||
exec 9>$throttle_lock
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Failed to create the lock file! Fallback to non-throttled kdump service restart"
|
||||
/bin/kdumpctl reload
|
||||
exit 1
|
||||
fi
|
||||
|
||||
flock -n 9
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Throttling kdump restart for concurrent udev event"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Wait for at least 1 second, at most 4 seconds for udev to settle
|
||||
# Idealy we will have a less than 1 second lag between udev events settle
|
||||
# and kdump reload
|
||||
sleep 1 && udevadm settle --timeout 3
|
||||
|
||||
# Release the lock, /bin/kdumpctl will block and make the process
|
||||
# holding two locks at the same time and we might miss some events
|
||||
exec 9>&-
|
||||
|
||||
/bin/kdumpctl reload
|
||||
|
||||
exit 0
|
183
SOURCES/kdump.conf
Normal file
183
SOURCES/kdump.conf
Normal file
@ -0,0 +1,183 @@
|
||||
# This file contains a series of commands to perform (in order) in the kdump
|
||||
# kernel after a kernel crash in the crash kernel(1st kernel) has happened.
|
||||
#
|
||||
# Directives in this file are only applicable to the kdump initramfs, and have
|
||||
# no effect once the root filesystem is mounted and the normal init scripts are
|
||||
# processed.
|
||||
#
|
||||
# Currently, only one dump target and path can be specified. If the dumping to
|
||||
# the configured target fails, the failure action which can be configured via
|
||||
# the "failure_action" directive will be performed.
|
||||
#
|
||||
# Supported options:
|
||||
#
|
||||
# raw <partition>
|
||||
# - Will dd /proc/vmcore into <partition>.
|
||||
# Use persistent device names for partition devices,
|
||||
# such as /dev/vg/<devname>.
|
||||
#
|
||||
# nfs <nfs mount>
|
||||
# - Will mount nfs to <mnt>, and copy /proc/vmcore to
|
||||
# <mnt>/<path>/%HOST-%DATE/, supports DNS.
|
||||
#
|
||||
# ssh <user@server>
|
||||
# - Will scp /proc/vmcore to <user@server>:<path>/%HOST-%DATE/,
|
||||
# supports DNS.
|
||||
# NOTE: make sure the user has write permissions on the server.
|
||||
#
|
||||
# sshkey <path>
|
||||
# - Will use the sshkey to do ssh dump.
|
||||
# Specify the path of the ssh key to use when dumping
|
||||
# via ssh. The default value is /root/.ssh/kdump_id_rsa.
|
||||
#
|
||||
# <fs type> <partition>
|
||||
# - Will mount -t <fs type> <partition> <mnt>, and copy
|
||||
# /proc/vmcore to <mnt>/<path>/%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.
|
||||
#
|
||||
# path <path>
|
||||
# - "path" represents the file system path in which vmcore
|
||||
# will be saved. If a dump target is specified in
|
||||
# kdump.conf, then "path" is relative to the specified
|
||||
# dump target.
|
||||
#
|
||||
# Interpretation of "path" changes a bit if the user didn't
|
||||
# specify any dump target explicitly in kdump.conf. In this
|
||||
# case, "path" represents the absolute path from root. The
|
||||
# dump target and adjusted path are arrived at automatically
|
||||
# depending on what's mounted in the current system.
|
||||
#
|
||||
# Ignored for raw device dumps. If unset, will use the default
|
||||
# "/var/crash".
|
||||
#
|
||||
# core_collector <command> <options>
|
||||
# - This allows you to specify the command to copy
|
||||
# the vmcore. The default is makedumpfile, which on
|
||||
# some architectures can drastically reduce vmcore size.
|
||||
# See /sbin/makedumpfile --help for a list of options.
|
||||
# Note that the -i and -g options are not needed here,
|
||||
# as the initrd will automatically be populated with a
|
||||
# config file appropriate for the running kernel.
|
||||
# The default core_collector for raw/ssh dump is:
|
||||
# "makedumpfile -F -l --message-level 1 -d 31".
|
||||
# The default core_collector for other targets is:
|
||||
# "makedumpfile -l --message-level 1 -d 31".
|
||||
#
|
||||
# "makedumpfile -F" will create a flattened vmcore.
|
||||
# You need to use "makedumpfile -R" to rearrange the dump data to
|
||||
# a normal dumpfile readable with analysis tools. For example:
|
||||
# "makedumpfile -R vmcore < vmcore.flat".
|
||||
#
|
||||
# For core_collector format details, you can refer to
|
||||
# kexec-kdump-howto.txt or kdump.conf manpage.
|
||||
#
|
||||
# kdump_post <binary | script>
|
||||
# - This directive allows you to run a executable binary
|
||||
# or script after the vmcore dump process terminates.
|
||||
# The exit status of the current dump process is fed to
|
||||
# the executable binary or script as its first argument.
|
||||
# All files under /etc/kdump/post.d are collectively sorted
|
||||
# and executed in lexical order, before binary or script
|
||||
# specified kdump_post parameter is executed.
|
||||
#
|
||||
# kdump_pre <binary | script>
|
||||
# - Works like the "kdump_post" directive, but instead of running
|
||||
# after the dump process, runs immediately before it.
|
||||
# Exit status of this binary is interpreted as follows:
|
||||
# 0 - continue with dump process as usual
|
||||
# non 0 - run the final action (reboot/poweroff/halt)
|
||||
# All files under /etc/kdump/pre.d are collectively sorted and
|
||||
# executed in lexical order, after binary or script specified
|
||||
# kdump_pre parameter is executed.
|
||||
# Even if the binary or script in /etc/kdump/pre.d directory
|
||||
# returns non 0 exit status, the processing is continued.
|
||||
#
|
||||
# extra_bins <binaries | shell scripts>
|
||||
# - This directive allows you to specify additional binaries or
|
||||
# shell scripts to be included in the kdump initrd.
|
||||
# Generally they are useful in conjunction with a kdump_post
|
||||
# or kdump_pre binary or script which depends on these extra_bins.
|
||||
#
|
||||
# extra_modules <module(s)>
|
||||
# - This directive allows you to specify extra kernel modules
|
||||
# that you want to be loaded in the kdump initrd.
|
||||
# Multiple modules can be listed, separated by spaces, and any
|
||||
# dependent modules will automatically be included.
|
||||
#
|
||||
# failure_action <reboot | halt | poweroff | shell | dump_to_rootfs>
|
||||
# - Action to perform in case dumping fails.
|
||||
# reboot: Reboot the system.
|
||||
# halt: Halt the system.
|
||||
# poweroff: Power down the system.
|
||||
# shell: Drop to a bash shell.
|
||||
# Exiting the shell reboots the system by default,
|
||||
# or perform "final_action".
|
||||
# dump_to_rootfs: Dump vmcore to rootfs from initramfs context and
|
||||
# reboot by default or perform "final_action".
|
||||
# Useful when non-root dump target is specified.
|
||||
# The default option is "reboot".
|
||||
#
|
||||
# default <reboot | halt | poweroff | shell | dump_to_rootfs>
|
||||
# - Same as the "failure_action" directive above, but this directive
|
||||
# is obsolete and will be removed in the future.
|
||||
#
|
||||
# final_action <reboot | halt | poweroff>
|
||||
# - Action to perform in case dumping succeeds. Also performed
|
||||
# when "shell" or "dump_to_rootfs" failure action finishes.
|
||||
# Each action is same as the "failure_action" directive above.
|
||||
# The default is "reboot".
|
||||
#
|
||||
# force_rebuild <0 | 1>
|
||||
# - By default, kdump initrd will only be rebuilt when necessary.
|
||||
# Specify 1 to force rebuilding kdump initrd every time when kdump
|
||||
# service starts.
|
||||
#
|
||||
# force_no_rebuild <0 | 1>
|
||||
# - By default, kdump initrd will be rebuilt when necessary.
|
||||
# Specify 1 to bypass rebuilding of kdump initrd.
|
||||
#
|
||||
# force_no_rebuild and force_rebuild options are mutually
|
||||
# exclusive and they should not be set to 1 simultaneously.
|
||||
#
|
||||
# override_resettable <0 | 1>
|
||||
# - Usually an unresettable block device can't be a dump target.
|
||||
# Specifying 1 when you want to dump even though the block
|
||||
# target is unresettable
|
||||
# By default, it is 0, which will not try dumping destined to fail.
|
||||
#
|
||||
# dracut_args <arg(s)>
|
||||
# - Pass extra dracut options when rebuilding kdump initrd.
|
||||
#
|
||||
# fence_kdump_args <arg(s)>
|
||||
# - Command line arguments for fence_kdump_send (it can contain
|
||||
# all valid arguments except hosts to send notification to).
|
||||
#
|
||||
# fence_kdump_nodes <node(s)>
|
||||
# - List of cluster node(s) except localhost, separated by spaces,
|
||||
# to send fence_kdump notifications to.
|
||||
# (this option is mandatory to enable fence_kdump).
|
||||
#
|
||||
|
||||
#raw /dev/vg/lv_kdump
|
||||
#ext4 /dev/vg/lv_kdump
|
||||
#ext4 LABEL=/boot
|
||||
#ext4 UUID=03138356-5e61-4ab3-b58e-27507ac41937
|
||||
#nfs my.server.com:/export/tmp
|
||||
#ssh user@my.server.com
|
||||
#sshkey /root/.ssh/kdump_id_rsa
|
||||
path /var/crash
|
||||
core_collector makedumpfile -l --message-level 1 -d 31
|
||||
#core_collector scp
|
||||
#kdump_post /var/crash/scripts/kdump-post.sh
|
||||
#kdump_pre /var/crash/scripts/kdump-pre.sh
|
||||
#extra_bins /usr/bin/lftp
|
||||
#extra_modules gfs2
|
||||
#failure_action shell
|
||||
#force_rebuild 1
|
||||
#force_no_rebuild 1
|
||||
#dracut_args --omit-drivers "cfg80211 snd" --add-drivers "ext2 ext3"
|
||||
#fence_kdump_args -p 7410 -f auto -c 0 -i 10
|
||||
#fence_kdump_nodes node1 node2
|
370
SOURCES/kdump.conf.5
Normal file
370
SOURCES/kdump.conf.5
Normal file
@ -0,0 +1,370 @@
|
||||
.TH KDUMP.CONF 5 "07/23/2008" "kexec-tools"
|
||||
|
||||
.SH NAME
|
||||
kdump.conf \- configuration file for kdump kernel.
|
||||
|
||||
.SH DESCRIPTION
|
||||
|
||||
kdump.conf is a configuration file for the kdump kernel crash
|
||||
collection service.
|
||||
|
||||
kdump.conf provides post-kexec instructions to the kdump kernel. It is
|
||||
stored in the initrd file managed by the kdump service. If you change
|
||||
this file and do not want to reboot in order for the changes to take
|
||||
effect, restart the kdump service to rebuild the initrd.
|
||||
|
||||
For most configurations, you can simply review the examples provided
|
||||
in the stock /etc/kdump.conf.
|
||||
|
||||
.B NOTE:
|
||||
For filesystem dumps the dump target must be mounted before building
|
||||
kdump initramfs.
|
||||
|
||||
kdump.conf only affects the behavior of the initramfs. Please read the
|
||||
kdump operational flow section of kexec-kdump-howto.txt in the docs to better
|
||||
understand how this configuration file affects the behavior of kdump.
|
||||
|
||||
.SH OPTIONS
|
||||
|
||||
.B raw <partition>
|
||||
.RS
|
||||
Will dd /proc/vmcore into <partition>. Use persistent device names for
|
||||
partition devices, such as /dev/vg/<devname>.
|
||||
.RE
|
||||
|
||||
.B nfs <nfs mount>
|
||||
.RS
|
||||
Will mount nfs to <mnt>, and copy /proc/vmcore to <mnt>/<path>/%HOST-%DATE/,
|
||||
supports DNS. Note that a fqdn should be used as the server name in the
|
||||
mount point.
|
||||
.RE
|
||||
|
||||
.B ssh <user@server>
|
||||
.RS
|
||||
Will scp /proc/vmcore 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
|
||||
|
||||
.B sshkey <path>
|
||||
.RS
|
||||
Specify the path of the ssh key to use when dumping via ssh.
|
||||
The default value is /root/.ssh/kdump_id_rsa.
|
||||
.RE
|
||||
|
||||
.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
|
||||
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
|
||||
|
||||
.B path <path>
|
||||
.RS
|
||||
"path" represents the file system path in which vmcore will be saved.
|
||||
If a dump target is specified in kdump.conf, then "path" is relative to the
|
||||
specified dump target.
|
||||
.PP
|
||||
Interpretation of "path" changes a bit if the user didn't specify any dump
|
||||
target explicitly in kdump.conf. In this case, "path" represents the
|
||||
absolute path from root. The dump target and adjusted path are arrived
|
||||
at automatically depending on what's mounted in the current system.
|
||||
.PP
|
||||
Ignored for raw device dumps. If unset, will use the default "/var/crash".
|
||||
.RE
|
||||
|
||||
.B core_collector <command> <options>
|
||||
.RS
|
||||
This allows you to specify the command to copy the vmcore.
|
||||
The default is makedumpfile, which on some architectures can drastically reduce
|
||||
core file size. See /sbin/makedumpfile --help for a list of options.
|
||||
Note that the -i and -g options are not needed here, as the initrd
|
||||
will automatically be populated with a config file appropriate
|
||||
for the running kernel.
|
||||
.PP
|
||||
Note 1: About default core collector:
|
||||
The default core_collector for raw/ssh dump is:
|
||||
"makedumpfile -F -l --message-level 1 -d 31".
|
||||
The default core_collector for other targets is:
|
||||
"makedumpfile -l --message-level 1 -d 31".
|
||||
Even if core_collector option is commented out in kdump.conf, makedumpfile
|
||||
is the default core collector and kdump uses it internally.
|
||||
If one does not want makedumpfile as default core_collector, then they
|
||||
need to specify one using core_collector option to change the behavior.
|
||||
.PP
|
||||
Note 2: If "makedumpfile -F" is used then you will get a flattened format
|
||||
vmcore.flat, you will need to use "makedumpfile -R" to rearrange the
|
||||
dump data from standard input to a normal dumpfile (readable with analysis
|
||||
tools).
|
||||
ie. "makedumpfile -R vmcore < vmcore.flat"
|
||||
|
||||
.RE
|
||||
|
||||
.B kdump_post <binary | script>
|
||||
.RS
|
||||
This directive allows you to run a specified executable
|
||||
just after the vmcore dump process terminates. The exit
|
||||
status of the current dump process is fed to the kdump_post
|
||||
executable as its first argument($1). Executable can modify
|
||||
it to indicate the new exit status of succeeding dump process,
|
||||
.PP
|
||||
All files under /etc/kdump/post.d are collectively sorted
|
||||
and executed in lexical order, before binary or script
|
||||
specified kdump_post parameter is executed.
|
||||
.PP
|
||||
Note that scripts written for use with this directive must use
|
||||
the /bin/bash interpreter.
|
||||
.RE
|
||||
|
||||
.B kdump_pre <binary | script>
|
||||
.RS
|
||||
Works just like the "kdump_post" directive, but instead
|
||||
of running after the dump process, runs immediately
|
||||
before. Exit status of this binary is interpreted
|
||||
as follows:
|
||||
.PP
|
||||
0 - continue with dump process as usual
|
||||
.PP
|
||||
non 0 - run the final action (reboot/poweroff/halt)
|
||||
.PP
|
||||
All files under /etc/kdump/pre.d are collectively sorted and
|
||||
executed in lexical order, after binary or script specified
|
||||
kdump_pre parameter is executed.
|
||||
Even if the binary or script in /etc/kdump/pre.d directory
|
||||
returns non 0 exit status, the processing is continued.
|
||||
.PP
|
||||
Note that scripts written for this directive must use
|
||||
the /bin/bash interpreter.
|
||||
.RE
|
||||
|
||||
.B extra_bins <binaries | shell scripts>
|
||||
.RS
|
||||
This directive allows you to specify additional
|
||||
binaries or shell scripts you'd like to include in
|
||||
your kdump initrd. Generally only useful in
|
||||
conjunction with a kdump_post binary or script that
|
||||
relies on other binaries or scripts.
|
||||
.RE
|
||||
|
||||
.B extra_modules <module(s)>
|
||||
.RS
|
||||
This directive allows you to specify extra kernel
|
||||
modules that you want to be loaded in the kdump
|
||||
initrd, typically used to set up access to
|
||||
non-boot-path dump targets that might otherwise
|
||||
not be accessible in the kdump environment. Multiple
|
||||
modules can be listed, separated by spaces, and any
|
||||
dependent modules will automatically be included.
|
||||
.RE
|
||||
|
||||
.B failure_action <reboot | halt | poweroff | shell | dump_to_rootfs>
|
||||
.RS
|
||||
Action to perform in case dumping to the intended target fails. The default is "reboot".
|
||||
reboot: Reboot the system (this is what most people will want, as it returns the system
|
||||
to a normal state). halt: Halt the system and lose the vmcore. poweroff: The system
|
||||
will be powered down. shell: Drop to a shell session inside the initramfs, from which
|
||||
you can manually perform additional recovery actions. Exiting this shell reboots the
|
||||
system by default or performs "final_action".
|
||||
Note: kdump uses bash as the default shell. dump_to_rootfs: If non-root dump
|
||||
target is specified, the failure action can be set as dump_to_rootfs. That means when
|
||||
dumping to target fails, dump vmcore to rootfs from initramfs context and reboot
|
||||
by default or perform "final_action".
|
||||
.RE
|
||||
|
||||
.B default <reboot | halt | poweroff | shell | dump_to_rootfs>
|
||||
.RS
|
||||
Same as the "failure_action" directive above, but this directive is obsolete
|
||||
and will be removed in the future.
|
||||
.RE
|
||||
|
||||
.B final_action <reboot | halt | poweroff>
|
||||
.RS
|
||||
Action to perform in case dumping to the intended target succeeds.
|
||||
Also performed when "shell" or "dump_to_rootfs" failure action finishes.
|
||||
Each action is same as the "failure_action" directive above.
|
||||
The default is "reboot".
|
||||
.RE
|
||||
|
||||
.B force_rebuild <0 | 1>
|
||||
.RS
|
||||
By default, kdump initrd will only be rebuilt when necessary.
|
||||
Specify 1 to force rebuilding kdump initrd every time when kdump service starts.
|
||||
.RE
|
||||
|
||||
.B force_no_rebuild <0 | 1>
|
||||
.RS
|
||||
By default, kdump initrd will be rebuilt when necessary.
|
||||
Specify 1 to bypass rebuilding of kdump initrd.
|
||||
|
||||
.PP
|
||||
force_no_rebuild and force_rebuild options are mutually exclusive and
|
||||
they should not be set to 1 simultaneously.
|
||||
.RE
|
||||
|
||||
.B override_resettable <0 | 1>
|
||||
.RS
|
||||
Usually an unresettable block device can't be a dump target. Specifying 1 means
|
||||
that even though the block target is unresettable, the user wants to try dumping anyway.
|
||||
By default, it's set to 0, which will not try something destined to fail.
|
||||
.RE
|
||||
|
||||
|
||||
.B dracut_args <arg(s)>
|
||||
.RS
|
||||
Kdump uses dracut to generate initramfs for second kernel. This option
|
||||
allows a user to pass arguments to dracut directly.
|
||||
.RE
|
||||
|
||||
|
||||
.B fence_kdump_args <arg(s)>
|
||||
.RS
|
||||
Command line arguments for fence_kdump_send (it can contain all valid
|
||||
arguments except hosts to send notification to).
|
||||
.RE
|
||||
|
||||
|
||||
.B fence_kdump_nodes <node(s)>
|
||||
.RS
|
||||
List of cluster node(s) except localhost, separated by spaces, to send fence_kdump notification
|
||||
to (this option is mandatory to enable fence_kdump).
|
||||
.RE
|
||||
|
||||
|
||||
.SH DEPRECATED OPTIONS
|
||||
|
||||
.B net <nfs mount>|<user@server>
|
||||
.RS
|
||||
net option is replaced by nfs and ssh options. Use nfs or ssh options
|
||||
directly.
|
||||
.RE
|
||||
|
||||
.B options <module> <option list>
|
||||
.RS
|
||||
Use KDUMP_COMMANDLINE_APPEND in /etc/sysconfig/kdump to add module options as
|
||||
kernel command line parameters. For example, specify 'loop.max_loop=1' to limit
|
||||
maximum loop devices to 1.
|
||||
.RE
|
||||
|
||||
.B link_delay <seconds>
|
||||
.RS
|
||||
link_delay was used to wait for a network device to initialize before using it.
|
||||
Now dracut network module takes care of this issue automatically.
|
||||
.RE
|
||||
|
||||
.B disk_timeout <seconds>
|
||||
.RS
|
||||
Similar to link_delay, dracut ensures disks are ready before kdump uses them.
|
||||
.RE
|
||||
|
||||
.B debug_mem_level <0-3>
|
||||
.RS
|
||||
Turn on verbose debug output of kdump scripts regarding free/used memory at
|
||||
various points of execution. This feature has been
|
||||
moved to dracut now.
|
||||
Use KDUMP_COMMANDLINE_APPEND in /etc/sysconfig/kdump and
|
||||
append dracut cmdline param rd.memdebug=[0-3] to enable the debug output.
|
||||
|
||||
Higher level means more debugging output.
|
||||
.PP
|
||||
0 - no output
|
||||
.PP
|
||||
1 - partial /proc/meminfo
|
||||
.PP
|
||||
2 - /proc/meminfo
|
||||
.PP
|
||||
3 - /proc/meminfo + /proc/slabinfo
|
||||
.RE
|
||||
|
||||
.B blacklist <list of kernel modules>
|
||||
.RS
|
||||
blacklist option was recently being used to prevent loading modules in
|
||||
initramfs. General terminology for blacklist has been that module is
|
||||
present in initramfs but it is not actually loaded in kernel. Hence
|
||||
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
|
||||
KDUMP_COMMANDLINE_APPEND to pass kernel command line options. Refer
|
||||
to dracut.cmdline man page for more details on module blacklist option.
|
||||
.RE
|
||||
|
||||
.RE
|
||||
|
||||
.SH EXAMPLES
|
||||
Here are some examples for core_collector option:
|
||||
.PP
|
||||
Core collector command format depends on dump target type. Typically for
|
||||
filesystem (local/remote), core_collector should accept two arguments.
|
||||
First one is source file and second one is target file. For ex.
|
||||
.TP
|
||||
ex1.
|
||||
core_collector "cp --sparse=always"
|
||||
|
||||
Above will effectively be translated to:
|
||||
|
||||
cp --sparse=always /proc/vmcore <dest-path>/vmcore
|
||||
.TP
|
||||
ex2.
|
||||
core_collector "makedumpfile -l --message-level 1 -d 31"
|
||||
|
||||
Above will effectively be translated to:
|
||||
|
||||
makedumpfile -l --message-level 1 -d 31 /proc/vmcore <dest-path>/vmcore
|
||||
.PP
|
||||
For dump targets like raw and ssh, in general, core collector should expect
|
||||
one argument (source file) and should output the processed core on standard
|
||||
output (There is one exception of "scp", discussed later). This standard
|
||||
output will be saved to destination using appropriate commands.
|
||||
|
||||
raw dumps examples:
|
||||
.TP
|
||||
ex3.
|
||||
core_collector "cat"
|
||||
|
||||
Above will effectively be translated to.
|
||||
|
||||
cat /proc/vmcore | dd of=<target-device>
|
||||
.TP
|
||||
ex4.
|
||||
core_collector "makedumpfile -F -l --message-level 1 -d 31"
|
||||
|
||||
Above will effectively be translated to.
|
||||
|
||||
makedumpfile -F -l --message-level 1 -d 31 | dd of=<target-device>
|
||||
.PP
|
||||
ssh dumps examples
|
||||
.TP
|
||||
ex5.
|
||||
core_collector "cat"
|
||||
|
||||
Above will effectively be translated to.
|
||||
|
||||
cat /proc/vmcore | ssh <options> <remote-location> "dd of=path/vmcore"
|
||||
.TP
|
||||
ex6.
|
||||
core_collector "makedumpfile -F -l --message-level 1 -d 31"
|
||||
|
||||
Above will effectively be translated to.
|
||||
|
||||
makedumpfile -F -l --message-level 1 -d 31 | ssh <options> <remote-location> "dd of=path/vmcore"
|
||||
|
||||
There is one exception to standard output rule for ssh dumps. And that is
|
||||
scp. As scp can handle ssh destinations for file transfers, one can
|
||||
specify "scp" as core collector for ssh targets (no output on stdout).
|
||||
.TP
|
||||
ex7.
|
||||
core_collector "scp"
|
||||
|
||||
Above will effectively be translated to.
|
||||
|
||||
scp /proc/vmcore <user@host>:path/vmcore
|
||||
|
||||
.PP
|
||||
examples for other options please see
|
||||
.I /etc/kdump.conf
|
||||
|
||||
.SH SEE ALSO
|
||||
|
||||
kexec(8) mkdumprd(8) dracut.cmdline(7)
|
15
SOURCES/kdump.service
Normal file
15
SOURCES/kdump.service
Normal file
@ -0,0 +1,15 @@
|
||||
[Unit]
|
||||
Description=Crash recovery kernel arming
|
||||
After=network.target network-online.target remote-fs.target basic.target
|
||||
DefaultDependencies=no
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/bin/kdumpctl start
|
||||
ExecStop=/usr/bin/kdumpctl stop
|
||||
ExecReload=/usr/bin/kdumpctl reload
|
||||
RemainAfterExit=yes
|
||||
StartLimitInterval=0
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
37
SOURCES/kdump.sysconfig
Normal file
37
SOURCES/kdump.sysconfig
Normal file
@ -0,0 +1,37 @@
|
||||
# Kernel Version string for the -kdump kernel, such as 2.6.13-1544.FC5kdump
|
||||
# If no version is specified, then the init script will try to find a
|
||||
# kdump kernel with the same version number as the running kernel.
|
||||
KDUMP_KERNELVER=""
|
||||
|
||||
# The kdump commandline is the command line that needs to be passed off to
|
||||
# the kdump kernel. This will likely match the contents of the grub kernel
|
||||
# line. For example:
|
||||
# KDUMP_COMMANDLINE="ro root=LABEL=/"
|
||||
# Dracut depends on proper root= options, so please 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=".
|
||||
# If a command line is not specified, the default will be taken from
|
||||
# /proc/cmdline
|
||||
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"
|
||||
|
||||
# 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"
|
||||
|
||||
# Any additional kexec arguments required. In most situations, this should
|
||||
# be left empty
|
||||
#
|
||||
# Example:
|
||||
# KEXEC_ARGS="--elf32-core-headers"
|
||||
KEXEC_ARGS=""
|
||||
|
||||
#Where to find the boot image
|
||||
#KDUMP_BOOTDIR="/boot"
|
||||
|
||||
#What is the image type used for kdump
|
||||
KDUMP_IMG="vmlinuz"
|
37
SOURCES/kdump.sysconfig.aarch64
Normal file
37
SOURCES/kdump.sysconfig.aarch64
Normal file
@ -0,0 +1,37 @@
|
||||
# Kernel Version string for the -kdump kernel, such as 2.6.13-1544.FC5kdump
|
||||
# If no version is specified, then the init script will try to find a
|
||||
# kdump kernel with the same version number as the running kernel.
|
||||
KDUMP_KERNELVER=""
|
||||
|
||||
# The kdump commandline is the command line that needs to be passed off to
|
||||
# the kdump kernel. This will likely match the contents of the grub kernel
|
||||
# line. For example:
|
||||
# KDUMP_COMMANDLINE="ro root=LABEL=/"
|
||||
# Dracut depends on proper root= options, so please 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=".
|
||||
# If a command line is not specified, the default will be taken from
|
||||
# /proc/cmdline
|
||||
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"
|
||||
|
||||
# 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"
|
||||
|
||||
# Any additional kexec arguments required. In most situations, this should
|
||||
# be left empty
|
||||
#
|
||||
# Example:
|
||||
# KEXEC_ARGS="--elf32-core-headers"
|
||||
KEXEC_ARGS=""
|
||||
|
||||
#Where to find the boot image
|
||||
#KDUMP_BOOTDIR="/boot"
|
||||
|
||||
#What is the image type used for kdump
|
||||
KDUMP_IMG="vmlinuz"
|
40
SOURCES/kdump.sysconfig.i386
Normal file
40
SOURCES/kdump.sysconfig.i386
Normal file
@ -0,0 +1,40 @@
|
||||
# Kernel Version string for the -kdump kernel, such as 2.6.13-1544.FC5kdump
|
||||
# If no version is specified, then the init script will try to find a
|
||||
# kdump kernel with the same version number as the running kernel.
|
||||
KDUMP_KERNELVER=""
|
||||
|
||||
# The kdump commandline is the command line that needs to be passed off to
|
||||
# the kdump kernel. This will likely match the contents of the grub kernel
|
||||
# line. For example:
|
||||
# KDUMP_COMMANDLINE="ro root=LABEL=/"
|
||||
# Dracut depends on proper root= options, so please 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=".
|
||||
# If a command line is not specified, the default will be taken from
|
||||
# /proc/cmdline
|
||||
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"
|
||||
|
||||
# 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"
|
||||
|
||||
# Any additional kexec arguments required. In most situations, this should
|
||||
# be left empty
|
||||
#
|
||||
# Example:
|
||||
# KEXEC_ARGS="--elf32-core-headers"
|
||||
KEXEC_ARGS=""
|
||||
|
||||
#Where to find the boot image
|
||||
#KDUMP_BOOTDIR="/boot"
|
||||
|
||||
#What is the image type used for kdump
|
||||
KDUMP_IMG="vmlinuz"
|
||||
|
||||
#What is the images extension. Relocatable kernels don't have one
|
||||
KDUMP_IMG_EXT=""
|
42
SOURCES/kdump.sysconfig.ppc64
Normal file
42
SOURCES/kdump.sysconfig.ppc64
Normal file
@ -0,0 +1,42 @@
|
||||
# Kernel Version string for the -kdump kernel, such as 2.6.13-1544.FC5kdump
|
||||
# If no version is specified, then the init script will try to find a
|
||||
# kdump kernel with the same version number as the running kernel.
|
||||
KDUMP_KERNELVER=""
|
||||
|
||||
# The kdump commandline is the command line that needs to be passed off to
|
||||
# the kdump kernel. This will likely match the contents of the grub kernel
|
||||
# line. For example:
|
||||
# KDUMP_COMMANDLINE="ro root=LABEL=/"
|
||||
# Dracut depends on proper root= options, so please 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=".
|
||||
# If a command line is not specified, the default will be taken from
|
||||
# /proc/cmdline
|
||||
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"
|
||||
|
||||
# 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"
|
||||
|
||||
# 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"
|
||||
|
||||
#Where to find the boot image
|
||||
#KDUMP_BOOTDIR="/boot"
|
||||
|
||||
#What is the image type used for kdump
|
||||
KDUMP_IMG="vmlinuz"
|
||||
|
||||
#What is the images extension. Relocatable kernels don't have one
|
||||
KDUMP_IMG_EXT=""
|
||||
|
||||
#Specify the action after failure
|
42
SOURCES/kdump.sysconfig.ppc64le
Normal file
42
SOURCES/kdump.sysconfig.ppc64le
Normal file
@ -0,0 +1,42 @@
|
||||
# Kernel Version string for the -kdump kernel, such as 2.6.13-1544.FC5kdump
|
||||
# If no version is specified, then the init script will try to find a
|
||||
# kdump kernel with the same version number as the running kernel.
|
||||
KDUMP_KERNELVER=""
|
||||
|
||||
# The kdump commandline is the command line that needs to be passed off to
|
||||
# the kdump kernel. This will likely match the contents of the grub kernel
|
||||
# line. For example:
|
||||
# KDUMP_COMMANDLINE="ro root=LABEL=/"
|
||||
# Dracut depends on proper root= options, so please 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=".
|
||||
# If a command line is not specified, the default will be taken from
|
||||
# /proc/cmdline
|
||||
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"
|
||||
|
||||
# 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"
|
||||
|
||||
# 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"
|
||||
|
||||
#Where to find the boot image
|
||||
#KDUMP_BOOTDIR="/boot"
|
||||
|
||||
#What is the image type used for kdump
|
||||
KDUMP_IMG="vmlinuz"
|
||||
|
||||
#What is the images extension. Relocatable kernels don't have one
|
||||
KDUMP_IMG_EXT=""
|
||||
|
||||
#Specify the action after failure
|
43
SOURCES/kdump.sysconfig.s390x
Normal file
43
SOURCES/kdump.sysconfig.s390x
Normal file
@ -0,0 +1,43 @@
|
||||
# Kernel Version string for the -kdump kernel, such as 2.6.13-1544.FC5kdump
|
||||
# If no version is specified, then the init script will try to find a
|
||||
# kdump kernel with the same version number as the running kernel.
|
||||
KDUMP_KERNELVER=""
|
||||
|
||||
# The kdump commandline is the command line that needs to be passed off to
|
||||
# the kdump kernel. This will likely match the contents of the grub kernel
|
||||
# line. For example:
|
||||
# KDUMP_COMMANDLINE="ro root=LABEL=/"
|
||||
# Dracut depends on proper root= options, so please 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=".
|
||||
# If a command line is not specified, the default will be taken from
|
||||
# /proc/cmdline
|
||||
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"
|
||||
|
||||
# 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"
|
||||
|
||||
# Any additional /sbin/mkdumprd arguments required.
|
||||
MKDUMPRD_ARGS=""
|
||||
|
||||
# Any additional kexec arguments required. In most situations, this should
|
||||
# be left empty
|
||||
#
|
||||
# Example:
|
||||
# KEXEC_ARGS="--elf32-core-headers"
|
||||
KEXEC_ARGS=""
|
||||
|
||||
#Where to find the boot image
|
||||
#KDUMP_BOOTDIR="/boot"
|
||||
|
||||
#What is the image type used for kdump
|
||||
KDUMP_IMG="vmlinuz"
|
||||
|
||||
#What is the images extension. Relocatable kernels don't have one
|
||||
KDUMP_IMG_EXT=""
|
40
SOURCES/kdump.sysconfig.x86_64
Normal file
40
SOURCES/kdump.sysconfig.x86_64
Normal file
@ -0,0 +1,40 @@
|
||||
# Kernel Version string for the -kdump kernel, such as 2.6.13-1544.FC5kdump
|
||||
# If no version is specified, then the init script will try to find a
|
||||
# kdump kernel with the same version number as the running kernel.
|
||||
KDUMP_KERNELVER=""
|
||||
|
||||
# The kdump commandline is the command line that needs to be passed off to
|
||||
# the kdump kernel. This will likely match the contents of the grub kernel
|
||||
# line. For example:
|
||||
# KDUMP_COMMANDLINE="ro root=LABEL=/"
|
||||
# Dracut depends on proper root= options, so please 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=".
|
||||
# If a command line is not specified, the default will be taken from
|
||||
# /proc/cmdline
|
||||
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"
|
||||
|
||||
# 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"
|
||||
|
||||
# Any additional kexec arguments required. In most situations, this should
|
||||
# be left empty
|
||||
#
|
||||
# Example:
|
||||
# KEXEC_ARGS="--elf32-core-headers"
|
||||
KEXEC_ARGS="-s"
|
||||
|
||||
#Where to find the boot image
|
||||
#KDUMP_BOOTDIR="/boot"
|
||||
|
||||
#What is the image type used for kdump
|
||||
KDUMP_IMG="vmlinuz"
|
||||
|
||||
#What is the images extension. Relocatable kernels don't have one
|
||||
KDUMP_IMG_EXT=""
|
1303
SOURCES/kdumpctl
Executable file
1303
SOURCES/kdumpctl
Executable file
File diff suppressed because it is too large
Load Diff
50
SOURCES/kdumpctl.8
Normal file
50
SOURCES/kdumpctl.8
Normal file
@ -0,0 +1,50 @@
|
||||
.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.
|
||||
|
||||
.SH "SEE ALSO"
|
||||
.BR kdump.conf (5),
|
||||
.BR mkdumprd (8)
|
887
SOURCES/kexec-kdump-howto.txt
Normal file
887
SOURCES/kexec-kdump-howto.txt
Normal file
@ -0,0 +1,887 @@
|
||||
=================
|
||||
Kexec/Kdump HOWTO
|
||||
=================
|
||||
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
Kexec and kdump are new features in the 2.6 mainstream kernel. These features
|
||||
are included in Red Hat Enterprise Linux 5. The purpose of these features
|
||||
is to ensure faster boot up and creation of reliable kernel vmcores for
|
||||
diagnostic purposes.
|
||||
|
||||
|
||||
Overview
|
||||
========
|
||||
|
||||
Kexec
|
||||
-----
|
||||
|
||||
Kexec is a fastboot mechanism which allows booting a Linux kernel from the
|
||||
context of already running kernel without going through BIOS. BIOS can be very
|
||||
time consuming especially on the big servers with lots of peripherals. This can
|
||||
save a lot of time for developers who end up booting a machine numerous times.
|
||||
|
||||
Kdump
|
||||
-----
|
||||
|
||||
Kdump is a new kernel crash dumping mechanism and is very reliable because
|
||||
the crash dump is captured from the context of a freshly booted kernel and
|
||||
not from the context of the crashed kernel. Kdump uses kexec to boot into
|
||||
a second kernel whenever system crashes. This second kernel, often called
|
||||
a capture kernel, boots with very little memory and captures the dump image.
|
||||
|
||||
The first kernel reserves a section of memory that the second kernel uses
|
||||
to boot. Kexec enables booting the capture kernel without going through BIOS
|
||||
hence contents of first kernel's memory are preserved, which is essentially
|
||||
the kernel crash dump.
|
||||
|
||||
Kdump is supported on the i686, x86_64, ia64 and ppc64 platforms. The
|
||||
standard kernel and capture kernel are one in the same on i686, x86_64,
|
||||
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
|
||||
|
||||
Now load a kernel with kexec:
|
||||
|
||||
# kver=`uname -r` # kexec -l /boot/vmlinuz-$kver
|
||||
--initrd=/boot/initrd-$kver.img \
|
||||
--command-line="`cat /proc/cmdline`"
|
||||
|
||||
NOTE: The above will boot you back into the kernel you're currently running,
|
||||
if you want to load a different kernel, substitute it in place of `uname -r`.
|
||||
|
||||
Now reboot your system, taking note that it should bypass the BIOS:
|
||||
|
||||
# reboot
|
||||
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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.
|
||||
|
||||
# grubby --args="crashkernel=128M" --update-kernel=/boot/vmlinuz-`uname -r`
|
||||
|
||||
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
|
||||
placement of the reserved memory. The format is:
|
||||
|
||||
crashkernel=range1:size1[,range2:size2,...][@offset]
|
||||
|
||||
Where range<n> specifies a range of values that are matched against the amount
|
||||
of physical RAM present in the system, and the corresponding size<n> value
|
||||
specifies the amount of kexec memory to reserve. For example:
|
||||
|
||||
crashkernel=512M-2G:64M,2G-:128M
|
||||
|
||||
This line tells kexec to reserve 64M of ram if the system contains between
|
||||
512M and 2G of physical memory. If the system contains 2G or more of physical
|
||||
memory, 128M should be reserved.
|
||||
|
||||
Besides, since kdump needs to access /proc/kallsyms during a kernel
|
||||
loading if KASLR is enabled, check /proc/sys/kernel/kptr_restrict to
|
||||
make sure that the content of /proc/kallsyms is exposed correctly.
|
||||
We recommend to set the value of kptr_restrict to '1'. Otherwise
|
||||
capture kernel loading could fail.
|
||||
|
||||
After making said changes, reboot your system, so that the X MB of memory is
|
||||
left untouched by the normal system, reserved for the capture kernel. Take note
|
||||
that the output of 'free -m' will show X MB less memory than without this
|
||||
parameter, which is expected. You may be able to get by with less than 128M, but
|
||||
testing with only 64M has proven unreliable of late. On ia64, as much as 512M
|
||||
may be required.
|
||||
|
||||
Now that you've got that reserved memory region set up, you want to turn on
|
||||
the kdump init script:
|
||||
|
||||
# chkconfig kdump on
|
||||
|
||||
Then, start up kdump as well:
|
||||
|
||||
# systemctl start kdump.service
|
||||
|
||||
This should load your kernel-kdump image via kexec, leaving the system ready
|
||||
to capture a vmcore upon crashing. To test this out, you can force-crash
|
||||
your system by echo'ing a c into /proc/sysrq-trigger:
|
||||
|
||||
# echo c > /proc/sysrq-trigger
|
||||
|
||||
You should see some panic output, followed by the system restarting into
|
||||
the kdump kernel. When the boot process gets to the point where it starts
|
||||
the kdump service, your vmcore should be copied out to disk (by default,
|
||||
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
|
||||
perform postmortem analysis:
|
||||
|
||||
# crash /usr/lib/debug/lib/modules/2.6.17-1.2621.el5/vmlinux
|
||||
/var/crash/2006-08-23-15:34/vmcore
|
||||
|
||||
crash> bt
|
||||
|
||||
and so on...
|
||||
|
||||
|
||||
Notes on kdump
|
||||
==============
|
||||
|
||||
When kdump starts, the kdump kernel is loaded together with the kdump
|
||||
initramfs. To save memory usage and disk space, the kdump initramfs is
|
||||
generated strictly against the system it will run on, and contains the
|
||||
minimum set of kernel modules and utilities to boot the machine to a stage
|
||||
where the dump target could be mounted.
|
||||
|
||||
With kdump service enabled, kdumpctl will try to detect possible system
|
||||
change and rebuild the kdump initramfs if needed. But it can not guarantee
|
||||
to cover every possible case. So after a hardware change, disk migration,
|
||||
storage setup update or any similar system level changes, it's highly
|
||||
recommended to rebuild the initramfs manually with following command:
|
||||
|
||||
# kdumpctl rebuild
|
||||
|
||||
|
||||
Saving vmcore-dmesg.txt
|
||||
=======================
|
||||
|
||||
Kernel log bufferes are one of the most important information available
|
||||
in vmcore. Now before saving vmcore, kernel log bufferes are extracted
|
||||
from /proc/vmcore and saved into a file vmcore-dmesg.txt. After
|
||||
vmcore-dmesg.txt, vmcore is saved. Destination disk and directory for
|
||||
vmcore-dmesg.txt is same as vmcore. Note that kernel log buffers will
|
||||
not be available if dump target is raw device.
|
||||
|
||||
|
||||
Dump Triggering methods
|
||||
=======================
|
||||
|
||||
This section talks about the various ways, other than a Kernel Panic, in which
|
||||
Kdump can be triggered. The following methods assume that Kdump is configured
|
||||
on your system, with the scripts enabled as described in the section above.
|
||||
|
||||
1) AltSysRq C
|
||||
|
||||
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
|
||||
|
||||
In addition, on PowerPC boxes, Kdump can also be triggered via Hardware
|
||||
Management Console(HMC) using 'Ctrl', 'O' and 'C' keyboard keys.
|
||||
|
||||
2) NMI_WATCHDOG
|
||||
|
||||
In case a machine has a hard hang, it is quite possible that it does not
|
||||
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
|
||||
|
||||
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.
|
||||
|
||||
3) Kernel OOPs
|
||||
|
||||
If we want to generate a dump everytime the Kernel OOPses, we can achieve this
|
||||
by setting the 'Panic On OOPs' option as follows:
|
||||
|
||||
# echo 1 > /proc/sys/kernel/panic_on_oops
|
||||
|
||||
This is enabled by default on RHEL5.
|
||||
|
||||
4) NMI(Non maskable interrupt) button
|
||||
|
||||
In cases where the system is in a hung state, and is not accepting keyboard
|
||||
interrupts, using NMI button for triggering Kdump can be very useful. NMI
|
||||
button is present on most of the newer x86 and x86_64 machines. Please refer
|
||||
to the User guides/manuals to locate the button, though in most occasions it
|
||||
is not very well documented. In most cases it is hidden behind a small hole
|
||||
on the front or back panel of the machine. You could use a toothpick or some
|
||||
other non-conducting probe to press the button.
|
||||
|
||||
For example, on the IBM X series 366 machine, the NMI button is located behind
|
||||
a small hole on the bottom center of the rear panel.
|
||||
|
||||
To enable this method of dump triggering using NMI button, you will need to set
|
||||
the 'unknown_nmi_panic' option as follows:
|
||||
|
||||
# echo 1 > /proc/sys/kernel/unknown_nmi_panic
|
||||
|
||||
5) PowerPC specific methods:
|
||||
|
||||
On IBM PowerPC machines, issuing a soft reset invokes the XMON debugger(if
|
||||
XMON is configured). To configure XMON one needs to compile the kernel with
|
||||
the CONFIG_XMON and CONFIG_XMON_DEFAULT options, or by compiling with
|
||||
CONFIG_XMON and booting the kernel with xmon=on option.
|
||||
|
||||
Following are the ways to remotely issue a soft reset on PowerPC boxes, which
|
||||
would drop you to XMON. Pressing a 'X' (capital alphabet X) followed by an
|
||||
'Enter' here will trigger the dump.
|
||||
|
||||
5.1) HMC
|
||||
|
||||
Hardware Management Console(HMC) available on Power4 and Power5 machines allow
|
||||
partitions to be reset remotely. This is specially useful in hang situations
|
||||
where the system is not accepting any keyboard inputs.
|
||||
|
||||
Once you have HMC configured, the following steps will enable you to trigger
|
||||
Kdump via a soft reset:
|
||||
|
||||
On Power4
|
||||
Using GUI
|
||||
|
||||
* In the right pane, right click on the partition you wish to dump.
|
||||
* Select "Operating System->Reset".
|
||||
* Select "Soft Reset".
|
||||
* Select "Yes".
|
||||
|
||||
Using HMC Commandline
|
||||
|
||||
# reset_partition -m <machine> -p <partition> -t soft
|
||||
|
||||
On Power5
|
||||
Using GUI
|
||||
|
||||
* In the right pane, right click on the partition you wish to dump.
|
||||
* Select "Restart Partition".
|
||||
* Select "Dump".
|
||||
* Select "OK".
|
||||
|
||||
Using HMC Commandline
|
||||
|
||||
# chsysstate -m <managed system name> -n <lpar name> -o dumprestart -r lpar
|
||||
|
||||
5.2) Blade Management Console for Blade Center
|
||||
|
||||
To initiate a dump operation, go to Power/Restart option under "Blade Tasks" in
|
||||
the Blade Management Console. Select the corresponding blade for which you want
|
||||
to initate the dump and then click "Restart blade with NMI". This issues a
|
||||
system reset and invokes xmon debugger.
|
||||
|
||||
|
||||
Dump targets
|
||||
============
|
||||
|
||||
In addition to being able to capture a vmcore to your system's local file
|
||||
system, kdump can be configured to capture a vmcore to a number of other
|
||||
locations, including a raw disk partition, a dedicated file system, an NFS
|
||||
mounted file system, or a remote system via ssh/scp. Additional options
|
||||
exist for specifying the relative path under which the dump is captured,
|
||||
what to do if the capture fails, and for compressing and filtering the dump
|
||||
(so as to produce smaller, more manageable, vmcore files, see "Advanced Setups"
|
||||
for more detail on these options).
|
||||
|
||||
In theory, dumping to a location other than the local file system should be
|
||||
safer than kdump's default setup, as its possible the default setup will try
|
||||
dumping to a file system that has become corrupted. The raw disk partition and
|
||||
dedicated file system options allow you to still dump to the local system,
|
||||
but without having to remount your possibly corrupted file system(s),
|
||||
thereby decreasing the chance a vmcore won't be captured. Dumping to an
|
||||
NFS server or remote system via ssh/scp also has this advantage, as well
|
||||
as allowing for the centralization of vmcore files, should you have several
|
||||
systems from which you'd like to obtain vmcore files. Of course, note that
|
||||
these configurations could present problems if your network is unreliable.
|
||||
|
||||
Kdump target and advanced setups are configured via modifications to
|
||||
/etc/kdump.conf, which out of the box, is fairly well documented itself.
|
||||
Any alterations to /etc/kdump.conf should be followed by a restart of the
|
||||
kdump service, so the changes can be incorporated in the kdump initrd.
|
||||
Restarting the kdump service is as simple as '/sbin/systemctl restart kdump.service'.
|
||||
|
||||
There are two ways to config the dump target, config dump target only
|
||||
using "path", and config dump target explicitly. Interpretation of "path"
|
||||
also differs in two config styles.
|
||||
|
||||
Config dump target only using "path"
|
||||
------------------------------------
|
||||
|
||||
You can change the dump target by setting "path" to a mount point where
|
||||
dump target is mounted. When there is no explicitly configured dump target,
|
||||
"path" in kdump.conf represents the current file system path in which vmcore
|
||||
will be saved. Kdump will automatically detect the underlying device of
|
||||
"path" and use that as the dump target.
|
||||
|
||||
In fact, upon dump, kdump creates a directory $hostip-$date with-in "path"
|
||||
and saves vmcore there. So practically dump is saved in $path/$hostip-$date/.
|
||||
|
||||
Kdump will only check current mount status for mount entry corresponding to
|
||||
"path". So please ensure the dump target is mounted on "path" before kdump
|
||||
service starts.
|
||||
|
||||
NOTES:
|
||||
|
||||
- It's strongly recommanded to put an mount entry for "path" in /etc/fstab
|
||||
and have it auto mounted on boot. This make sure the dump target is
|
||||
reachable from the machine and kdump's configuration is stable.
|
||||
|
||||
EXAMPLES:
|
||||
|
||||
- path /var/crash/
|
||||
|
||||
This is the default configuration. Assuming there is no disk mounted
|
||||
on /var/ or on /var/crash, dump will be saved on disk backing rootfs
|
||||
in directory /var/crash.
|
||||
|
||||
- path /var/crash/ (A separate disk mounted on /var/crash)
|
||||
|
||||
Say a disk /dev/sdb is mounted on /var. In this case dump target will
|
||||
become /dev/sdb and path will become "/" and dump will be saved
|
||||
on "sdb:/var/crash/" directory.
|
||||
|
||||
- path /var/crash/ (NFS mounted on /var)
|
||||
|
||||
Say foo.com:/export/tmp is mounted on /var. In this case dump target is
|
||||
nfs server and path will be adjusted to "/crash" and dump will be saved to
|
||||
foo.com:/export/tmp/crash/ directory.
|
||||
|
||||
Config dump target explicitely
|
||||
------------------------------
|
||||
|
||||
You can set the dump target explicitly in kdump.conf, and "path" will be
|
||||
the relative path in the specified dump target. For example, if dump
|
||||
target is "ext4 /dev/sda", then dump will be saved in "path" directory
|
||||
on /dev/sda.
|
||||
|
||||
Same is the case for nfs dump. If user specified "nfs foo.com:/export/tmp/"
|
||||
as dump target, then dump will effectively be saved in
|
||||
"foo.com:/export/tmp/var/crash/" directory.
|
||||
|
||||
If the dump target is "raw", then "path" is ignored.
|
||||
|
||||
If it's a filesystem target, kdump will need to know the right mount option.
|
||||
Kdump will check current mount status, and then /etc/fstab for mount options
|
||||
corresponding to the specified dump target and use it. If there are
|
||||
special mount option required for the dump target, it could be set by put
|
||||
an entry in fstab.
|
||||
|
||||
If there are no related mount entry, mount option is set to "defaults".
|
||||
|
||||
NOTES:
|
||||
|
||||
- It's recommended to put an entry for the dump target in /etc/fstab
|
||||
and have it auto mounted on boot. This make sure the dump target is
|
||||
reachable from the machine and kdump won't fail.
|
||||
|
||||
- Kdump ignores some mount options, including "noauto", "ro". This
|
||||
make it possible to keep the dump target unmounted or read-only
|
||||
when not used.
|
||||
|
||||
EXAMPLES:
|
||||
|
||||
- ext4 /dev/sda (mounted)
|
||||
path /var/crash/
|
||||
|
||||
In this case dump target is set to /dev/sdb, path is the absolute path
|
||||
"/var/crash" in /dev/sda, vmcore path will saved on
|
||||
"sda:/var/crash" directory.
|
||||
|
||||
- nfs foo.com:/export/tmp (mounted)
|
||||
path /var/crash/
|
||||
|
||||
In this case dump target is nfs server, path is the absolute path
|
||||
"/var/crash", vmcore path will saved on "foo.com:/export/tmp/crash/" directory.
|
||||
|
||||
- nfs foo.com:/export/tmp (not mounted)
|
||||
path /var/crash/
|
||||
|
||||
Same with above case, kdump will use "defaults" as the mount option
|
||||
for the dump target.
|
||||
|
||||
- nfs foo.com:/export/tmp (not mounted, entry with option "noauto,nolock" exists in /etc/fstab)
|
||||
path /var/crash/
|
||||
|
||||
In this case dump target is nfs server, vmcore path will saved on
|
||||
"foo.com:/export/tmp/crash/" directory, and kdump will inherit "nolock" option.
|
||||
|
||||
Dump target and mkdumprd
|
||||
------------------------
|
||||
|
||||
MKdumprd is the tool used to create kdump initramfs, and it may change
|
||||
the mount status of the dump target in some condition.
|
||||
|
||||
Usually the dump target should be used only for kdump. If you worry about
|
||||
someone uses the filesystem for something else other than dumping vmcore
|
||||
you can mount it as read-only or make it a noauto mount. Mkdumprd will
|
||||
mount/remount it as read-write for creating dump directory and will
|
||||
move it back to it's original state afterwards.
|
||||
|
||||
Supported dump target types and requirements
|
||||
--------------------------------------------
|
||||
|
||||
1) Raw partition
|
||||
|
||||
Raw partition dumping requires that a disk partition in the system, at least
|
||||
as large as the amount of memory in the system, be left unformatted. Assuming
|
||||
/dev/vg/lv_kdump is left unformatted, kdump.conf can be configured with
|
||||
'raw /dev/vg/lv_kdump', and the vmcore file will be copied via dd directly
|
||||
onto partition /dev/vg/lv_kdump. Restart the kdump service via
|
||||
'/sbin/systemctl restart kdump.service' to commit this change to your kdump
|
||||
initrd. Dump target should be persistent device name, such as lvm or device
|
||||
mapper canonical name.
|
||||
|
||||
2) Dedicated file system
|
||||
|
||||
Similar to raw partition dumping, you can format a partition with the file
|
||||
system of your choice, Again, it should be at least as large as the amount
|
||||
of memory in the system. Assuming it should be at least as large as the
|
||||
amount of memory in the system. Assuming /dev/vg/lv_kdump has been
|
||||
formatted ext4, specify 'ext4 /dev/vg/lv_kdump' in kdump.conf, and a
|
||||
vmcore file will be copied onto the file system after it has been mounted.
|
||||
Dumping to a dedicated partition has the advantage that you can dump multiple
|
||||
vmcores to the file system, space permitting, without overwriting previous ones,
|
||||
as would be the case in a raw partition setup. Restart the kdump service via
|
||||
'/sbin/systemctl restart kdump.service' to commit this change to
|
||||
your kdump initrd. Note that for local file systems ext4 and ext2 are
|
||||
supported as dumpable targets. Kdump will not prevent you from specifying
|
||||
other filesystems, and they will most likely work, but their operation
|
||||
cannot be guaranteed. for instance specifying a vfat filesystem or msdos
|
||||
filesystem will result in a successful load of the kdump service, but during
|
||||
crash recovery, the dump will fail if the system has more than 2GB of memory
|
||||
(since vfat and msdos filesystems do not support more than 2GB files).
|
||||
Be careful of your filesystem selection when using this target.
|
||||
|
||||
It is recommended to use persistent device names or UUID/LABEL for file system
|
||||
dumps. One example of persistent device is /dev/vg/<devname>.
|
||||
|
||||
3) NFS mount
|
||||
|
||||
Dumping over NFS requires an NFS server configured to export a file system
|
||||
with full read/write access for the root user. All operations done within
|
||||
the kdump initial ramdisk are done as root, and to write out a vmcore file,
|
||||
we obviously must be able to write to the NFS mount. Configuring an NFS
|
||||
server is outside the scope of this document, but either the no_root_squash
|
||||
or anonuid options on the NFS server side are likely of interest to permit
|
||||
the kdump initrd operations write to the NFS mount as root.
|
||||
|
||||
Assuming your're exporting /dump on the machine nfs-server.example.com,
|
||||
once the mount is properly configured, specify it in kdump.conf, via
|
||||
'nfs nfs-server.example.com:/dump'. The server portion can be specified either
|
||||
by host name or IP address. Following a system crash, the kdump initrd will
|
||||
mount the NFS mount and copy out the vmcore to your NFS server. Restart the
|
||||
kdump service via '/sbin/systemctl restart kdump.service' to commit this change
|
||||
to your kdump initrd.
|
||||
|
||||
4) Special mount via "dracut_args"
|
||||
|
||||
You can utilize "dracut_args" to pass "--mount" to kdump, see dracut manpage
|
||||
about the format of "--mount" for details. If there is any "--mount" specified
|
||||
via "dracut_args", kdump will build it as the mount target without doing any
|
||||
validation (mounting or checking like mount options, fs size, save path, etc),
|
||||
so you must test it to ensure all the correctness. You cannot use other targets
|
||||
in /etc/kdump.conf if you use "--mount" in "dracut_args". You also cannot specify
|
||||
mutliple "--mount" targets via "dracut_args".
|
||||
|
||||
One use case of "--mount" in "dracut_args" is you do not want to mount dump target
|
||||
before kdump service startup, for example, to reduce the burden of the shared nfs
|
||||
server. Such as the example below:
|
||||
dracut_args --mount "192.168.1.1:/share /mnt/test nfs4 defaults"
|
||||
|
||||
NOTE:
|
||||
- <mountpoint> must be specified as an absolute path.
|
||||
|
||||
5) Remote system via ssh/scp
|
||||
|
||||
Dumping over ssh/scp requires setting up passwordless ssh keys for every
|
||||
machine you wish to have dump via this method. First up, configure kdump.conf
|
||||
for ssh/scp dumping, adding a config line of 'ssh user@server', where 'user'
|
||||
can be any user on the target system you choose, and 'server' is the host
|
||||
name or IP address of the target system. Using a dedicated, restricted user
|
||||
account on the target system is recommended, as there will be keyless ssh
|
||||
access to this account.
|
||||
|
||||
Once kdump.conf is appropriately configured, issue the command
|
||||
'kdumpctl propagate' to automatically set up the ssh host keys and transmit
|
||||
the necessary bits to the target server. You'll have to type in 'yes'
|
||||
to accept the host key for your targer server if this is the first time
|
||||
you've connected to it, and then input the target system user's password
|
||||
to send over the necessary ssh key file. Restart the kdump service via
|
||||
'/sbin/systemctl restart kdump.service' to commit this change to your kdump initrd.
|
||||
|
||||
Advanced Setups
|
||||
===============
|
||||
|
||||
Kdump boot directory
|
||||
--------------------
|
||||
|
||||
Usually kdump kernel is the same as 1st kernel. So kdump will try to find
|
||||
kdump kernel under /boot according to /proc/cmdline. E.g we execute below
|
||||
command and get an output:
|
||||
cat /proc/cmdline
|
||||
BOOT_IMAGE=/xxx/vmlinuz-3.yyy.zzz root=xxxx .....
|
||||
Then kdump kernel will be /boot/xxx/vmlinuz-3.yyy.zzz.
|
||||
However a variable KDUMP_BOOTDIR in /etc/sysconfig/kdump is provided to
|
||||
user if kdump kernel is put in a different directory.
|
||||
|
||||
Kdump Post-Capture Executable
|
||||
-----------------------------
|
||||
|
||||
It is possible to specify a custom script or binary you wish to run following
|
||||
an attempt to capture a vmcore. The executable is passed an exit code from
|
||||
the capture process, which can be used to trigger different actions from
|
||||
within your post-capture executable.
|
||||
If /etc/kdump/post.d directory exist, All files in the directory are
|
||||
collectively sorted and executed in lexical order, before binary or script
|
||||
specified kdump_post parameter is executed.
|
||||
|
||||
Kdump Pre-Capture Executable
|
||||
----------------------------
|
||||
|
||||
It is possible to specify a custom script or binary you wish to run before
|
||||
capturing a vmcore. Exit status of this binary is interpreted:
|
||||
0 - continue with dump process as usual
|
||||
non 0 - run the final action (reboot/poweroff/halt)
|
||||
If /etc/kdump/pre.d directory exists, all files in the directory are collectively
|
||||
sorted and executed in lexical order, after binary or script specified
|
||||
kdump_pre parameter is executed.
|
||||
Even if the binary or script in /etc/kdump/pre.d directory returns non 0
|
||||
exit status, the processing is continued.
|
||||
|
||||
Extra Binaries
|
||||
--------------
|
||||
|
||||
If you have specific binaries or scripts you want to have made available
|
||||
within your kdump initrd, you can specify them by their full path, and they
|
||||
will be included in your kdump initrd, along with all dependent libraries.
|
||||
This may be particularly useful for those running post-capture scripts that
|
||||
rely on other binaries.
|
||||
|
||||
Extra Modules
|
||||
-------------
|
||||
|
||||
By default, only the bare minimum of kernel modules will be included in your
|
||||
kdump initrd. Should you wish to capture your vmcore files to a non-boot-path
|
||||
storage device, such as an iscsi target disk or clustered file system, you may
|
||||
need to manually specify additional kernel modules to load into your kdump
|
||||
initrd.
|
||||
|
||||
Failure action
|
||||
--------------
|
||||
|
||||
Failure action specifies what to do when dump to configured dump target
|
||||
fails. By default, failure action is "reboot" and that is system reboots
|
||||
if attempt to save dump to dump target fails.
|
||||
|
||||
There are other failure actions available though.
|
||||
|
||||
- dump_to_rootfs
|
||||
This option tries to mount root and save dump on root filesystem
|
||||
in a path specified by "path". This option will generally make
|
||||
sense when dump target is not root filesystem. For example, if
|
||||
dump is being saved over network using "ssh" then one can specify
|
||||
failure action to "dump_to_rootfs" to try saving dump to root
|
||||
filesystem if dump over network fails.
|
||||
|
||||
- shell
|
||||
Drop into a shell session inside initramfs.
|
||||
|
||||
- halt
|
||||
Halt system after failure
|
||||
|
||||
- poweroff
|
||||
Poweroff system after failure.
|
||||
|
||||
Compression and filtering
|
||||
-------------------------
|
||||
|
||||
The 'core_collector' parameter in kdump.conf allows you to specify a custom
|
||||
dump capture method. The most common alternate method is makedumpfile, which
|
||||
is a dump filtering and compression utility provided with kexec-tools. On
|
||||
some architectures, it can drastically reduce the size of your vmcore files,
|
||||
which becomes very useful on systems with large amounts of memory.
|
||||
|
||||
A typical setup is 'core_collector makedumpfile -F -l --message-level 1 -d 31',
|
||||
but check the output of '/sbin/makedumpfile --help' for a list of all available
|
||||
options (-i and -g don't need to be specified, they're automatically taken care
|
||||
of). Note that use of makedumpfile requires that the kernel-debuginfo package
|
||||
corresponding with your running kernel be installed.
|
||||
|
||||
Core collector command format depends on dump target type. Typically for
|
||||
filesystem (local/remote), core_collector should accept two arguments.
|
||||
First one is source file and second one is target file. For ex.
|
||||
|
||||
- ex1.
|
||||
|
||||
core_collector "cp --sparse=always"
|
||||
|
||||
Above will effectively be translated to:
|
||||
|
||||
cp --sparse=always /proc/vmcore <dest-path>/vmcore
|
||||
|
||||
- ex2.
|
||||
|
||||
core_collector "makedumpfile -l --message-level 1 -d 31"
|
||||
|
||||
Above will effectively be translated to:
|
||||
|
||||
makedumpfile -l --message-level 1 -d 31 /proc/vmcore <dest-path>/vmcore
|
||||
|
||||
For dump targets like raw and ssh, in general, core collector should expect
|
||||
one argument (source file) and should output the processed core on standard
|
||||
output (There is one exception of "scp", discussed later). This standard
|
||||
output will be saved to destination using appropriate commands.
|
||||
|
||||
raw dumps core_collector examples:
|
||||
|
||||
- ex3.
|
||||
|
||||
core_collector "cat"
|
||||
|
||||
Above will effectively be translated to.
|
||||
|
||||
cat /proc/vmcore | dd of=<target-device>
|
||||
|
||||
- ex4.
|
||||
|
||||
core_collector "makedumpfile -F -l --message-level 1 -d 31"
|
||||
|
||||
Above will effectively be translated to.
|
||||
|
||||
makedumpfile -F -l --message-level 1 -d 31 | dd of=<target-device>
|
||||
|
||||
ssh dumps core_collector examples:
|
||||
|
||||
- ex5.
|
||||
|
||||
core_collector "cat"
|
||||
|
||||
Above will effectively be translated to.
|
||||
|
||||
cat /proc/vmcore | ssh <options> <remote-location> "dd of=path/vmcore"
|
||||
|
||||
- ex6.
|
||||
|
||||
core_collector "makedumpfile -F -l --message-level 1 -d 31"
|
||||
|
||||
Above will effectively be translated to.
|
||||
|
||||
makedumpfile -F -l --message-level 1 -d 31 | ssh <options> <remote-location> "dd of=path/vmcore"
|
||||
|
||||
There is one exception to standard output rule for ssh dumps. And that is
|
||||
scp. As scp can handle ssh destinations for file transfers, one can
|
||||
specify "scp" as core collector for ssh targets (no output on stdout).
|
||||
|
||||
- ex7.
|
||||
|
||||
core_collector "scp"
|
||||
|
||||
Above will effectively be translated to.
|
||||
|
||||
scp /proc/vmcore <user@host>:path/vmcore
|
||||
|
||||
About default core collector
|
||||
----------------------------
|
||||
|
||||
Default core_collector for ssh/raw dump is:
|
||||
"makedumpfile -F -l --message-level 1 -d 31".
|
||||
Default core_collector for other targets is:
|
||||
"makedumpfile -l --message-level 1 -d 31".
|
||||
|
||||
Even if core_collector option is commented out in kdump.conf, makedumpfile
|
||||
is default core collector and kdump uses it internally.
|
||||
|
||||
If one does not want makedumpfile as default core_collector, then they
|
||||
need to specify one using core_collector option to change the behavior.
|
||||
|
||||
Note: If "makedumpfile -F" is used then you will get a flattened format
|
||||
vmcore.flat, you will need to use "makedumpfile -R" to rearrange the
|
||||
dump data from stdard input to a normal dumpfile (readable with analysis
|
||||
tools).
|
||||
For example: "makedumpfile -R vmcore < vmcore.flat"
|
||||
|
||||
|
||||
Caveats
|
||||
=======
|
||||
|
||||
Console frame-buffers and X are not properly supported. If you typically run
|
||||
with something along the lines of "vga=791" in your kernel config line or
|
||||
have X running, console video will be garbled when a kernel is booted via
|
||||
kexec. Note that the kdump kernel should still be able to create a dump,
|
||||
and when the system reboots, video should be restored to normal.
|
||||
|
||||
|
||||
Notes
|
||||
=====
|
||||
|
||||
Notes on resetting video:
|
||||
-------------------------
|
||||
|
||||
Video is a notoriously difficult issue with kexec. Video cards contain ROM code
|
||||
that controls their initial configuration and setup. This code is nominally
|
||||
accessed and executed from the Bios, and otherwise not safely executable. Since
|
||||
the purpose of kexec is to reboot the system without re-executing the Bios, it
|
||||
is rather difficult if not impossible to reset video cards with kexec. The
|
||||
result is, that if a system crashes while running in a graphical mode (i.e.
|
||||
running X), the screen may appear to become 'frozen' while the dump capture is
|
||||
taking place. A serial console will of course reveal that the system is
|
||||
operating and capturing a vmcore image, but a casual observer will see the
|
||||
system as hung until the dump completes and a true reboot is executed.
|
||||
|
||||
There are two possiblilties to work around this issue. One is by adding
|
||||
--reset-vga to the kexec command line options in /etc/sysconfig/kdump. This
|
||||
tells kdump to write some reasonable default values to the video card register
|
||||
file, in the hopes of returning it to a text mode such that boot messages are
|
||||
visible on the screen. It does not work with all video cards however.
|
||||
Secondly, it may be worth trying to add vga15fb.ko to the extra_modules list in
|
||||
/etc/kdump.conf. This will attempt to use the video card in framebuffer mode,
|
||||
which can blank the screen prior to the start of a dump capture.
|
||||
|
||||
Notes on rootfs mount
|
||||
---------------------
|
||||
|
||||
Dracut is designed to mount rootfs by default. If rootfs mounting fails it
|
||||
will refuse to go on. So kdump 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.
|
||||
|
||||
Notes on watchdog module handling
|
||||
---------------------------------
|
||||
|
||||
If a watchdog is active in first kernel then, we must have it's module
|
||||
loaded in crash kernel, so that either watchdog is deactivated or started
|
||||
being kicked in second kernel. Otherwise, we might face watchdog reboot
|
||||
when vmcore is being saved. When dracut watchdog module is enabled, it
|
||||
installs kernel watchdog module of active watchdog device in initrd.
|
||||
kexec-tools always add "-a watchdog" to the dracut_args if there exists at
|
||||
least one active watchdog and user has not added specifically "-o watchdog"
|
||||
in dracut_args of kdump.conf. If a watchdog module (such as hp_wdt) has
|
||||
not been written in watchdog-core framework then this option will not have
|
||||
any effect and module will not be added. Please note that only systemd
|
||||
watchdog daemon is supported as watchdog kick application.
|
||||
|
||||
Notes for disk images
|
||||
---------------------
|
||||
|
||||
Kdump initramfs is a critical component for capturing the crash dump.
|
||||
But it's strictly generated for the machine it will run on, and have
|
||||
no generality. If you install a new machine with a previous disk image
|
||||
(eg. VMs created with disk image or snapshot), kdump could be broken
|
||||
easily due to hardware changes or disk ID changes. So it's strongly
|
||||
recommended to not include the kdump initramfs in the disk image in the
|
||||
first place, this helps to save space, and kdumpctl will build the
|
||||
initramfs automatically if it's missing. If you have already installed
|
||||
a machine with a disk image which have kdump initramfs embedded, you
|
||||
should rebuild the initramfs using "kdumpctl rebuild" command manually,
|
||||
or else kdump may not work as expeceted.
|
||||
|
||||
Notes on encrypted dump target
|
||||
------------------------------
|
||||
|
||||
Currently, kdump is not working well with encrypted dump target.
|
||||
First, user have to give the password manually in capture kernel,
|
||||
so a working interactive terminal is required in the capture kernel.
|
||||
And another major issue is that an OOM problem will occur with certain
|
||||
encryption setup. For example, the default setup for LUKS2 will use a
|
||||
memory hard key derivation function to mitigate brute force attach,
|
||||
it's impossible to reduce the memory usage for mounting the encrypted
|
||||
target. In such case, you have to either reserved enough memory for
|
||||
crash kernel according, or update your encryption setup.
|
||||
It's recommanded to use a non-encrypted target (eg. remote target)
|
||||
instead.
|
||||
|
||||
Notes on device dump
|
||||
--------------------
|
||||
|
||||
Device dump allows drivers to append dump data to vmcore, so you can
|
||||
collect driver specified debug info. The drivers could append the
|
||||
data without any limit, and the data is stored in memory, this may
|
||||
bring a significant memory stress. So device dump is disabled by default
|
||||
by passing "novmcoredd" command line option to the kdump capture kernel.
|
||||
If you want to collect debug data with device dump, you need to modify
|
||||
"KDUMP_COMMANDLINE_APPEND=" value in /etc/sysconfig/kdump and remove the
|
||||
"novmcoredd" option. You also need to increase the "crashkernel=" value
|
||||
accordingly in case of OOM issue.
|
||||
Besides, kdump initramfs won't automatically include the device drivers
|
||||
which support device dump, only device drivers that are required for
|
||||
the dump target setup will be included. To ensure the device dump data
|
||||
will be included in the vmcore, you need to force include related
|
||||
device drivers by using "extra_modules" option in /etc/kdump.conf
|
||||
|
||||
|
||||
Parallel Dumping Operation
|
||||
==========================
|
||||
|
||||
Kexec allows kdump using multiple cpus. So parallel feature can accelerate
|
||||
dumping substantially, especially in executing compression and filter.
|
||||
For example:
|
||||
|
||||
1."makedumpfile -c --num-threads [THREAD_NUM] /proc/vmcore dumpfile"
|
||||
2."makedumpfile -c /proc/vmcore dumpfile",
|
||||
|
||||
1 has better performance than 2, if THREAD_NUM is larger than two
|
||||
and the usable cpus number is larger than THREAD_NUM.
|
||||
|
||||
Notes on how to use multiple cpus on a capture kernel on x86 system:
|
||||
|
||||
Make sure that you are using a kernel that supports disable_cpu_apicid
|
||||
kernel option as a capture kernel, which is needed to avoid x86 specific
|
||||
hardware issue (*). The disable_cpu_apicid kernel option is automatically
|
||||
appended by kdumpctl script and is ignored if the kernel doesn't support it.
|
||||
|
||||
You need to specify how many cpus to be used in a capture kernel by specifying
|
||||
the number of cpus in nr_cpus kernel option in /etc/sysconfig/kdump. nr_cpus
|
||||
is 1 at default.
|
||||
|
||||
You should use necessary and sufficient number of cpus on a capture kernel.
|
||||
Warning: Don't use too many cpus on a capture kernel, or the capture kernel
|
||||
may lead to panic due to Out Of Memory.
|
||||
|
||||
(*) Without disable_cpu_apicid kernel option, capture kernel may lead to
|
||||
hang, system reset or power-off at boot, depending on your system and runtime
|
||||
situation at the time of crash.
|
||||
|
||||
|
||||
Debugging Tips
|
||||
==============
|
||||
|
||||
- One can drop into a shell before/after saving vmcore with the help of
|
||||
using kdump_pre/kdump_post hooks. Use following in one of the pre/post
|
||||
scripts to drop into a shell.
|
||||
|
||||
#!/bin/bash
|
||||
_ctty=/dev/ttyS0
|
||||
setsid /bin/sh -i -l 0<>$_ctty 1<>$_ctty 2<>$_ctty
|
||||
|
||||
One might have to change the terminal depending on what they are using.
|
||||
|
||||
- Serial console logging for virtual machines
|
||||
|
||||
I generally use "virsh console <domain-name>" to get to serial console.
|
||||
I noticed after dump saving system reboots and when grub menu shows up
|
||||
some of the previously logged messages are no more there. That means
|
||||
any important debugging info at the end will be lost.
|
||||
|
||||
One can log serial console as follows to make sure messages are not lost.
|
||||
|
||||
virsh ttyconsole <domain-name>
|
||||
ln -s <name-of-tty> /dev/modem
|
||||
minicom -C /tmp/console-logs
|
||||
|
||||
Now minicom should be logging serial console in file console-logs.
|
@ -0,0 +1,181 @@
|
||||
From a7c4cb8e998571cb3dd62e907935a1e052b15d6c Mon Sep 17 00:00:00 2001
|
||||
From: Lianbo Jiang <lijiang@redhat.com>
|
||||
Date: Fri, 23 Aug 2019 20:05:38 +0800
|
||||
Subject: [PATCH 3/5] Cleanup: move it back from util_lib/elf_info.c
|
||||
|
||||
Some code related to vmcore-dmesg.c is put into the util_lib, which
|
||||
is not very reasonable, so lets move it back and tidy up those code.
|
||||
|
||||
In addition, that will also help to limit the size of vmcore-dmesg.txt
|
||||
in vmcore-dmesg.c instead of elf_info.c.
|
||||
|
||||
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||
Signed-off-by: Simon Horman <horms@verge.net.au>
|
||||
---
|
||||
util_lib/elf_info.c | 48 +++++++++----------------------------
|
||||
util_lib/include/elf_info.h | 2 +-
|
||||
vmcore-dmesg/vmcore-dmesg.c | 30 ++++++++++++++++++++++-
|
||||
3 files changed, 41 insertions(+), 39 deletions(-)
|
||||
|
||||
diff --git a/util_lib/elf_info.c b/util_lib/elf_info.c
|
||||
index 5d0efaafab53..2bce5cb1713c 100644
|
||||
--- a/util_lib/elf_info.c
|
||||
+++ b/util_lib/elf_info.c
|
||||
@@ -531,19 +531,7 @@ static int32_t read_file_s32(int fd, uint64_t addr)
|
||||
return read_file_u32(fd, addr);
|
||||
}
|
||||
|
||||
-static void write_to_stdout(char *buf, unsigned int nr)
|
||||
-{
|
||||
- ssize_t ret;
|
||||
-
|
||||
- ret = write(STDOUT_FILENO, buf, nr);
|
||||
- if (ret != nr) {
|
||||
- fprintf(stderr, "Failed to write out the dmesg log buffer!:"
|
||||
- " %s\n", strerror(errno));
|
||||
- exit(54);
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-static void dump_dmesg_legacy(int fd)
|
||||
+static void dump_dmesg_legacy(int fd, void (*handler)(char*, unsigned int))
|
||||
{
|
||||
uint64_t log_buf, log_buf_offset;
|
||||
unsigned log_end, logged_chars, log_end_wrapped;
|
||||
@@ -604,7 +592,8 @@ static void dump_dmesg_legacy(int fd)
|
||||
*/
|
||||
logged_chars = log_end < log_buf_len ? log_end : log_buf_len;
|
||||
|
||||
- write_to_stdout(buf + (log_buf_len - logged_chars), logged_chars);
|
||||
+ if (handler)
|
||||
+ handler(buf + (log_buf_len - logged_chars), logged_chars);
|
||||
}
|
||||
|
||||
static inline uint16_t struct_val_u16(char *ptr, unsigned int offset)
|
||||
@@ -623,7 +612,7 @@ static inline uint64_t struct_val_u64(char *ptr, unsigned int offset)
|
||||
}
|
||||
|
||||
/* Read headers of log records and dump accordingly */
|
||||
-static void dump_dmesg_structured(int fd)
|
||||
+static void dump_dmesg_structured(int fd, void (*handler)(char*, unsigned int))
|
||||
{
|
||||
#define OUT_BUF_SIZE 4096
|
||||
uint64_t log_buf, log_buf_offset, ts_nsec;
|
||||
@@ -733,7 +722,8 @@ static void dump_dmesg_structured(int fd)
|
||||
out_buf[len++] = c;
|
||||
|
||||
if (len >= OUT_BUF_SIZE - 64) {
|
||||
- write_to_stdout(out_buf, len);
|
||||
+ if (handler)
|
||||
+ handler(out_buf, len);
|
||||
len = 0;
|
||||
}
|
||||
}
|
||||
@@ -752,16 +742,16 @@ static void dump_dmesg_structured(int fd)
|
||||
current_idx += loglen;
|
||||
}
|
||||
free(buf);
|
||||
- if (len)
|
||||
- write_to_stdout(out_buf, len);
|
||||
+ if (len && handler)
|
||||
+ handler(out_buf, len);
|
||||
}
|
||||
|
||||
-static void dump_dmesg(int fd)
|
||||
+void dump_dmesg(int fd, void (*handler)(char*, unsigned int))
|
||||
{
|
||||
if (log_first_idx_vaddr)
|
||||
- dump_dmesg_structured(fd);
|
||||
+ dump_dmesg_structured(fd, handler);
|
||||
else
|
||||
- dump_dmesg_legacy(fd);
|
||||
+ dump_dmesg_legacy(fd, handler);
|
||||
}
|
||||
|
||||
int read_elf(int fd)
|
||||
@@ -808,22 +798,6 @@ int read_elf(int fd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-int read_elf_vmcore(int fd)
|
||||
-{
|
||||
- int ret;
|
||||
-
|
||||
- ret = read_elf(fd);
|
||||
- if (ret > 0) {
|
||||
- fprintf(stderr, "Unable to read ELF information"
|
||||
- " from vmcore\n");
|
||||
- return ret;
|
||||
- }
|
||||
-
|
||||
- dump_dmesg(fd);
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
int read_phys_offset_elf_kcore(int fd, unsigned long *phys_off)
|
||||
{
|
||||
int ret;
|
||||
diff --git a/util_lib/include/elf_info.h b/util_lib/include/elf_info.h
|
||||
index c328a1b0ecf2..4bc9279ba603 100644
|
||||
--- a/util_lib/include/elf_info.h
|
||||
+++ b/util_lib/include/elf_info.h
|
||||
@@ -30,6 +30,6 @@ int get_pt_load(int idx,
|
||||
unsigned long long *virt_end);
|
||||
int read_phys_offset_elf_kcore(int fd, unsigned long *phys_off);
|
||||
int read_elf(int fd);
|
||||
-int read_elf_vmcore(int fd);
|
||||
+void dump_dmesg(int fd, void (*handler)(char*, unsigned int));
|
||||
|
||||
#endif /* ELF_INFO_H */
|
||||
diff --git a/vmcore-dmesg/vmcore-dmesg.c b/vmcore-dmesg/vmcore-dmesg.c
|
||||
index bebc348a657e..fe7df8ec372c 100644
|
||||
--- a/vmcore-dmesg/vmcore-dmesg.c
|
||||
+++ b/vmcore-dmesg/vmcore-dmesg.c
|
||||
@@ -5,6 +5,34 @@ typedef Elf32_Nhdr Elf_Nhdr;
|
||||
|
||||
extern const char *fname;
|
||||
|
||||
+static void write_to_stdout(char *buf, unsigned int nr)
|
||||
+{
|
||||
+ ssize_t ret;
|
||||
+
|
||||
+ ret = write(STDOUT_FILENO, buf, nr);
|
||||
+ if (ret != nr) {
|
||||
+ fprintf(stderr, "Failed to write out the dmesg log buffer!:"
|
||||
+ " %s\n", strerror(errno));
|
||||
+ exit(54);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int read_vmcore_dmesg(int fd, void (*handler)(char*, unsigned int))
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = read_elf(fd);
|
||||
+ if (ret > 0) {
|
||||
+ fprintf(stderr, "Unable to read ELF information"
|
||||
+ " from vmcore\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ dump_dmesg(fd, handler);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
ssize_t ret;
|
||||
@@ -23,7 +51,7 @@ int main(int argc, char **argv)
|
||||
return 2;
|
||||
}
|
||||
|
||||
- ret = read_elf_vmcore(fd);
|
||||
+ ret = read_vmcore_dmesg(fd, write_to_stdout);
|
||||
|
||||
close(fd);
|
||||
|
||||
--
|
||||
2.17.1
|
||||
|
@ -0,0 +1,84 @@
|
||||
From 545c811050a375f79e0fa0e107cb35b9ae3a1599 Mon Sep 17 00:00:00 2001
|
||||
From: Lianbo Jiang <lijiang@redhat.com>
|
||||
Date: Fri, 23 Aug 2019 20:05:36 +0800
|
||||
Subject: [PATCH 1/5] Cleanup: remove the read_elf_kcore()
|
||||
|
||||
Here, no need to wrap the read_elf() again, lets invoke it directly.
|
||||
So remove the read_elf_kcore() and clean up redundant code.
|
||||
|
||||
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||
Signed-off-by: Simon Horman <horms@verge.net.au>
|
||||
---
|
||||
kexec/arch/arm64/kexec-arm64.c | 2 +-
|
||||
util_lib/elf_info.c | 15 ++-------------
|
||||
util_lib/include/elf_info.h | 2 +-
|
||||
3 files changed, 4 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c
|
||||
index eb3a3a37307c..6ad3b0a134b3 100644
|
||||
--- a/kexec/arch/arm64/kexec-arm64.c
|
||||
+++ b/kexec/arch/arm64/kexec-arm64.c
|
||||
@@ -889,7 +889,7 @@ int get_phys_base_from_pt_load(unsigned long *phys_offset)
|
||||
return EFAILED;
|
||||
}
|
||||
|
||||
- read_elf_kcore(fd);
|
||||
+ read_elf(fd);
|
||||
|
||||
for (i = 0; get_pt_load(i,
|
||||
&phys_start, NULL, &virt_start, NULL);
|
||||
diff --git a/util_lib/elf_info.c b/util_lib/elf_info.c
|
||||
index 90a3b21662e7..d9397ecd8626 100644
|
||||
--- a/util_lib/elf_info.c
|
||||
+++ b/util_lib/elf_info.c
|
||||
@@ -764,7 +764,7 @@ static void dump_dmesg(int fd)
|
||||
dump_dmesg_legacy(fd);
|
||||
}
|
||||
|
||||
-static int read_elf(int fd)
|
||||
+int read_elf(int fd)
|
||||
{
|
||||
int ret;
|
||||
|
||||
@@ -824,24 +824,13 @@ int read_elf_vmcore(int fd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-int read_elf_kcore(int fd)
|
||||
-{
|
||||
- int ret;
|
||||
-
|
||||
- ret = read_elf(fd);
|
||||
- if (ret != 0)
|
||||
- return ret;
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
int read_phys_offset_elf_kcore(int fd, unsigned long *phys_off)
|
||||
{
|
||||
int ret;
|
||||
|
||||
*phys_off = UINT64_MAX;
|
||||
|
||||
- ret = read_elf_kcore(fd);
|
||||
+ ret = read_elf(fd);
|
||||
if (!ret) {
|
||||
/* If we have a valid 'PHYS_OFFSET' by now,
|
||||
* return it to the caller now.
|
||||
diff --git a/util_lib/include/elf_info.h b/util_lib/include/elf_info.h
|
||||
index 1a4debd2d4ba..c328a1b0ecf2 100644
|
||||
--- a/util_lib/include/elf_info.h
|
||||
+++ b/util_lib/include/elf_info.h
|
||||
@@ -29,7 +29,7 @@ int get_pt_load(int idx,
|
||||
unsigned long long *virt_start,
|
||||
unsigned long long *virt_end);
|
||||
int read_phys_offset_elf_kcore(int fd, unsigned long *phys_off);
|
||||
-int read_elf_kcore(int fd);
|
||||
+int read_elf(int fd);
|
||||
int read_elf_vmcore(int fd);
|
||||
|
||||
#endif /* ELF_INFO_H */
|
||||
--
|
||||
2.17.1
|
||||
|
@ -0,0 +1,47 @@
|
||||
From 14ad054e7baa788a6629385ffe5e0f1996b7de02 Mon Sep 17 00:00:00 2001
|
||||
From: Lianbo Jiang <lijiang@redhat.com>
|
||||
Date: Fri, 23 Aug 2019 20:05:37 +0800
|
||||
Subject: [PATCH 2/5] Fix an error definition about the variable 'fname'
|
||||
|
||||
The variable 'fname' is mistakenly defined two twice, the first definition
|
||||
is in the vmcore-dmesg.c, and the second definition is in the elf_info.c.
|
||||
That is confused and incorrect although it's a static type, because the
|
||||
value of variable 'fname' is not assigned(set) in elf_info.c. Anyway, its
|
||||
value will be always 'null' when printing an error information.
|
||||
|
||||
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||
Signed-off-by: Simon Horman <horms@verge.net.au>
|
||||
---
|
||||
util_lib/elf_info.c | 2 +-
|
||||
vmcore-dmesg/vmcore-dmesg.c | 2 +-
|
||||
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/util_lib/elf_info.c b/util_lib/elf_info.c
|
||||
index d9397ecd8626..5d0efaafab53 100644
|
||||
--- a/util_lib/elf_info.c
|
||||
+++ b/util_lib/elf_info.c
|
||||
@@ -20,7 +20,7 @@
|
||||
/* The 32bit and 64bit note headers make it clear we don't care */
|
||||
typedef Elf32_Nhdr Elf_Nhdr;
|
||||
|
||||
-static const char *fname;
|
||||
+const char *fname;
|
||||
static Elf64_Ehdr ehdr;
|
||||
static Elf64_Phdr *phdr;
|
||||
static int num_pt_loads;
|
||||
diff --git a/vmcore-dmesg/vmcore-dmesg.c b/vmcore-dmesg/vmcore-dmesg.c
|
||||
index 7a386b380291..bebc348a657e 100644
|
||||
--- a/vmcore-dmesg/vmcore-dmesg.c
|
||||
+++ b/vmcore-dmesg/vmcore-dmesg.c
|
||||
@@ -3,7 +3,7 @@
|
||||
/* The 32bit and 64bit note headers make it clear we don't care */
|
||||
typedef Elf32_Nhdr Elf_Nhdr;
|
||||
|
||||
-static const char *fname;
|
||||
+extern const char *fname;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
--
|
||||
2.17.1
|
||||
|
@ -0,0 +1,55 @@
|
||||
From fa3f0ed47f3e6dbee485722d13713ad495571b7e Mon Sep 17 00:00:00 2001
|
||||
From: Lianbo Jiang <lijiang@redhat.com>
|
||||
Date: Fri, 23 Aug 2019 20:05:39 +0800
|
||||
Subject: [PATCH 4/5] Limit the size of vmcore-dmesg.txt to 2G
|
||||
|
||||
With some corrupted vmcore files, the vmcore-dmesg.txt file may grow
|
||||
forever till the kdump disk becomes full, and also probably causes
|
||||
the disk error messages as follow:
|
||||
...
|
||||
sd 0:0:0:0: [sda] tag#6 FAILED Result: hostbyte=DID_BAD_TARGET driverbyte=DRIVER_OK
|
||||
sd 0:0:0:0: [sda] tag#6 CDB: Read(10) 28 00 08 06 4c 98 00 00 08 00
|
||||
blk_update_request: I/O error, dev sda, sector 134630552
|
||||
sd 0:0:0:0: [sda] tag#7 FAILED Result: hostbyte=DID_BAD_TARGET driverbyte=DRIVER_OK
|
||||
sd 0:0:0:0: [sda] tag#7 CDB: Read(10) 28 00 08 06 4c 98 00 00 08 00
|
||||
blk_update_request: I/O error, dev sda, sector 134630552
|
||||
...
|
||||
|
||||
If vmcore-dmesg.txt occupies the whole disk, the vmcore can not be
|
||||
saved, this is also a problem.
|
||||
|
||||
Lets limit the size of vmcore-dmesg.txt to avoid such problems.
|
||||
|
||||
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||
Signed-off-by: Simon Horman <horms@verge.net.au>
|
||||
---
|
||||
vmcore-dmesg/vmcore-dmesg.c | 10 ++++++++++
|
||||
1 file changed, 10 insertions(+)
|
||||
|
||||
diff --git a/vmcore-dmesg/vmcore-dmesg.c b/vmcore-dmesg/vmcore-dmesg.c
|
||||
index fe7df8ec372c..81c2a58c9d86 100644
|
||||
--- a/vmcore-dmesg/vmcore-dmesg.c
|
||||
+++ b/vmcore-dmesg/vmcore-dmesg.c
|
||||
@@ -5,9 +5,19 @@ typedef Elf32_Nhdr Elf_Nhdr;
|
||||
|
||||
extern const char *fname;
|
||||
|
||||
+/* stole this macro from kernel printk.c */
|
||||
+#define LOG_BUF_LEN_MAX (uint32_t)(1 << 31)
|
||||
+
|
||||
static void write_to_stdout(char *buf, unsigned int nr)
|
||||
{
|
||||
ssize_t ret;
|
||||
+ static uint32_t n_bytes = 0;
|
||||
+
|
||||
+ n_bytes += nr;
|
||||
+ if (n_bytes > LOG_BUF_LEN_MAX) {
|
||||
+ fprintf(stderr, "The vmcore-dmesg.txt over 2G in size is not supported.\n");
|
||||
+ exit(53);
|
||||
+ }
|
||||
|
||||
ret = write(STDOUT_FILENO, buf, nr);
|
||||
if (ret != nr) {
|
||||
--
|
||||
2.17.1
|
||||
|
@ -0,0 +1,82 @@
|
||||
From 2572b8d702e452624bdb8d7b7c39f458e7dcf2ce Mon Sep 17 00:00:00 2001
|
||||
From: AKASHI Takahiro <takahiro.akashi@linaro.org>
|
||||
Date: Wed, 18 Dec 2019 11:42:32 -0500
|
||||
Subject: [PATCH 3/3] arm64: kdump: deal with a lot of resource entries in
|
||||
/proc/iomem
|
||||
|
||||
As described in the commit ("arm64: kexec: allocate memory space avoiding
|
||||
reserved regions"), /proc/iomem now has a lot of "reserved" entries, and
|
||||
it's not just enough to have a fixed size of memory range array.
|
||||
|
||||
With this patch, kdump is allowed to handle arbitrary number of memory
|
||||
ranges, using mem_regions_alloc_and_xxx() functions.
|
||||
|
||||
Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
|
||||
Tested-by: Bhupesh Sharma <bhsharma@redhat.com>
|
||||
Tested-by: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
|
||||
Signed-off-by: Simon Horman <horms@verge.net.au>
|
||||
---
|
||||
kexec/arch/arm64/crashdump-arm64.c | 25 ++++++++++---------------
|
||||
1 file changed, 10 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/kexec/arch/arm64/crashdump-arm64.c b/kexec/arch/arm64/crashdump-arm64.c
|
||||
index 4fd7aa8fd43c..38d1a0f3000d 100644
|
||||
--- a/kexec/arch/arm64/crashdump-arm64.c
|
||||
+++ b/kexec/arch/arm64/crashdump-arm64.c
|
||||
@@ -23,13 +23,8 @@
|
||||
#include "kexec-elf.h"
|
||||
#include "mem_regions.h"
|
||||
|
||||
-/* memory ranges on crashed kernel */
|
||||
-static struct memory_range system_memory_ranges[CRASH_MAX_MEMORY_RANGES];
|
||||
-static struct memory_ranges system_memory_rgns = {
|
||||
- .size = 0,
|
||||
- .max_size = CRASH_MAX_MEMORY_RANGES,
|
||||
- .ranges = system_memory_ranges,
|
||||
-};
|
||||
+/* memory ranges of crashed kernel */
|
||||
+static struct memory_ranges system_memory_rgns;
|
||||
|
||||
/* memory range reserved for crashkernel */
|
||||
struct memory_range crash_reserved_mem;
|
||||
@@ -82,7 +77,7 @@ static uint64_t get_kernel_page_offset(void)
|
||||
*
|
||||
* This function is called once for each memory region found in /proc/iomem.
|
||||
* It locates system RAM and crashkernel reserved memory and places these to
|
||||
- * variables, respectively, system_memory_ranges and crash_reserved_mem.
|
||||
+ * variables, respectively, system_memory_rgns and usablemem_rgns.
|
||||
*/
|
||||
|
||||
static int iomem_range_callback(void *UNUSED(data), int UNUSED(nr),
|
||||
@@ -90,11 +85,11 @@ static int iomem_range_callback(void *UNUSED(data), int UNUSED(nr),
|
||||
unsigned long long length)
|
||||
{
|
||||
if (strncmp(str, CRASH_KERNEL, strlen(CRASH_KERNEL)) == 0)
|
||||
- return mem_regions_add(&usablemem_rgns,
|
||||
- base, length, RANGE_RAM);
|
||||
+ return mem_regions_alloc_and_add(&usablemem_rgns,
|
||||
+ base, length, RANGE_RAM);
|
||||
else if (strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM)) == 0)
|
||||
- return mem_regions_add(&system_memory_rgns,
|
||||
- base, length, RANGE_RAM);
|
||||
+ return mem_regions_alloc_and_add(&system_memory_rgns,
|
||||
+ base, length, RANGE_RAM);
|
||||
else if (strncmp(str, KERNEL_CODE, strlen(KERNEL_CODE)) == 0)
|
||||
elf_info.kern_paddr_start = base;
|
||||
else if (strncmp(str, KERNEL_DATA, strlen(KERNEL_DATA)) == 0)
|
||||
@@ -135,9 +130,9 @@ static int crash_get_memory_ranges(void)
|
||||
|
||||
dbgprint_mem_range("Reserved memory range", &crash_reserved_mem, 1);
|
||||
|
||||
- if (mem_regions_exclude(&system_memory_rgns, &crash_reserved_mem)) {
|
||||
- fprintf(stderr,
|
||||
- "Error: Number of crash memory ranges excedeed the max limit\n");
|
||||
+ if (mem_regions_alloc_and_exclude(&system_memory_rgns,
|
||||
+ &crash_reserved_mem)) {
|
||||
+ fprintf(stderr, "Cannot allocate memory for ranges\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
--
|
||||
2.7.4
|
||||
|
@ -0,0 +1,248 @@
|
||||
From f736104f533290b4ce6fbfbca74abde9ffd3888c Mon Sep 17 00:00:00 2001
|
||||
From: AKASHI Takahiro <takahiro.akashi@linaro.org>
|
||||
Date: Wed, 18 Dec 2019 11:42:31 -0500
|
||||
Subject: [PATCH 2/3] arm64: kexec: allocate memory space avoiding reserved
|
||||
regions
|
||||
|
||||
On UEFI/ACPI-only system, some memory regions, including but not limited
|
||||
to UEFI memory map and ACPI tables, must be preserved across kexec'ing.
|
||||
Otherwise, they can be corrupted and result in early failure in booting
|
||||
a new kernel.
|
||||
|
||||
In recent kernels, /proc/iomem now has an extended file format like:
|
||||
|
||||
40000000-5871ffff : System RAM
|
||||
41800000-426affff : Kernel code
|
||||
426b0000-42aaffff : reserved
|
||||
42ab0000-42c64fff : Kernel data
|
||||
54400000-583fffff : Crash kernel
|
||||
58590000-585effff : reserved
|
||||
58700000-5871ffff : reserved
|
||||
58720000-58b5ffff : reserved
|
||||
58b60000-5be3ffff : System RAM
|
||||
58b61000-58b61fff : reserved
|
||||
|
||||
where the "reserved" entries at the top level or under System RAM (and
|
||||
its descendant resources) are ones of such kind and should not be regarded
|
||||
as usable memory ranges where several free spaces for loading kexec data
|
||||
will be allocated.
|
||||
|
||||
With this patch, get_memory_ranges() will handle this format of file
|
||||
correctly. Note that, for safety, unknown regions, in addition to
|
||||
"reserved" ones, will also be excluded.
|
||||
|
||||
Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
|
||||
Tested-by: Bhupesh Sharma <bhsharma@redhat.com>
|
||||
Tested-by: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
|
||||
Signed-off-by: Simon Horman <horms@verge.net.au>
|
||||
---
|
||||
kexec/arch/arm64/kexec-arm64.c | 153 +++++++++++++++++++++++++----------------
|
||||
1 file changed, 94 insertions(+), 59 deletions(-)
|
||||
|
||||
diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c
|
||||
index 6ad3b0a134b3..45ebc54a9b6f 100644
|
||||
--- a/kexec/arch/arm64/kexec-arm64.c
|
||||
+++ b/kexec/arch/arm64/kexec-arm64.c
|
||||
@@ -10,7 +10,9 @@
|
||||
#include <inttypes.h>
|
||||
#include <libfdt.h>
|
||||
#include <limits.h>
|
||||
+#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <linux/elf-em.h>
|
||||
#include <elf.h>
|
||||
@@ -29,6 +31,7 @@
|
||||
#include "fs2dt.h"
|
||||
#include "iomem.h"
|
||||
#include "kexec-syscall.h"
|
||||
+#include "mem_regions.h"
|
||||
#include "arch/options.h"
|
||||
|
||||
#define ROOT_NODE_ADDR_CELLS_DEFAULT 1
|
||||
@@ -905,19 +908,33 @@ int get_phys_base_from_pt_load(unsigned long *phys_offset)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static bool to_be_excluded(char *str)
|
||||
+{
|
||||
+ if (!strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM)) ||
|
||||
+ !strncmp(str, KERNEL_CODE, strlen(KERNEL_CODE)) ||
|
||||
+ !strncmp(str, KERNEL_DATA, strlen(KERNEL_DATA)) ||
|
||||
+ !strncmp(str, CRASH_KERNEL, strlen(CRASH_KERNEL)))
|
||||
+ return false;
|
||||
+ else
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
- * get_memory_ranges_iomem_cb - Helper for get_memory_ranges_iomem.
|
||||
+ * get_memory_ranges - Try to get the memory ranges from
|
||||
+ * /proc/iomem.
|
||||
*/
|
||||
-
|
||||
-static int get_memory_ranges_iomem_cb(void *data, int nr, char *str,
|
||||
- unsigned long long base, unsigned long long length)
|
||||
+int get_memory_ranges(struct memory_range **range, int *ranges,
|
||||
+ unsigned long kexec_flags)
|
||||
{
|
||||
- int ret;
|
||||
unsigned long phys_offset = UINT64_MAX;
|
||||
- struct memory_range *r;
|
||||
-
|
||||
- if (nr >= KEXEC_SEGMENT_MAX)
|
||||
- return -1;
|
||||
+ FILE *fp;
|
||||
+ const char *iomem = proc_iomem();
|
||||
+ char line[MAX_LINE], *str;
|
||||
+ unsigned long long start, end;
|
||||
+ int n, consumed;
|
||||
+ struct memory_ranges memranges;
|
||||
+ struct memory_range *last, excl_range;
|
||||
+ int ret;
|
||||
|
||||
if (!try_read_phys_offset_from_kcore) {
|
||||
/* Since kernel version 4.19, 'kcore' contains
|
||||
@@ -951,17 +968,72 @@ static int get_memory_ranges_iomem_cb(void *data, int nr, char *str,
|
||||
try_read_phys_offset_from_kcore = true;
|
||||
}
|
||||
|
||||
- r = (struct memory_range *)data + nr;
|
||||
+ fp = fopen(iomem, "r");
|
||||
+ if (!fp)
|
||||
+ die("Cannot open %s\n", iomem);
|
||||
+
|
||||
+ memranges.ranges = NULL;
|
||||
+ memranges.size = memranges.max_size = 0;
|
||||
+
|
||||
+ while (fgets(line, sizeof(line), fp) != 0) {
|
||||
+ n = sscanf(line, "%llx-%llx : %n", &start, &end, &consumed);
|
||||
+ if (n != 2)
|
||||
+ continue;
|
||||
+ str = line + consumed;
|
||||
+
|
||||
+ if (!strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM))) {
|
||||
+ ret = mem_regions_alloc_and_add(&memranges,
|
||||
+ start, end - start + 1, RANGE_RAM);
|
||||
+ if (ret) {
|
||||
+ fprintf(stderr,
|
||||
+ "Cannot allocate memory for ranges\n");
|
||||
+ fclose(fp);
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
|
||||
- if (!strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM)))
|
||||
- r->type = RANGE_RAM;
|
||||
- else if (!strncmp(str, IOMEM_RESERVED, strlen(IOMEM_RESERVED)))
|
||||
- r->type = RANGE_RESERVED;
|
||||
- else
|
||||
- return 1;
|
||||
+ dbgprintf("%s:+[%d] %016llx - %016llx\n", __func__,
|
||||
+ memranges.size - 1,
|
||||
+ memranges.ranges[memranges.size - 1].start,
|
||||
+ memranges.ranges[memranges.size - 1].end);
|
||||
+ } else if (to_be_excluded(str)) {
|
||||
+ if (!memranges.size)
|
||||
+ continue;
|
||||
+
|
||||
+ /*
|
||||
+ * Note: mem_regions_exclude() doesn't guarantee
|
||||
+ * that the ranges are sorted out, but as long as
|
||||
+ * we cope with /proc/iomem, we only operate on
|
||||
+ * the last entry and so it is safe.
|
||||
+ */
|
||||
|
||||
- r->start = base;
|
||||
- r->end = base + length - 1;
|
||||
+ /* The last System RAM range */
|
||||
+ last = &memranges.ranges[memranges.size - 1];
|
||||
+
|
||||
+ if (last->end < start)
|
||||
+ /* New resource outside of System RAM */
|
||||
+ continue;
|
||||
+ if (end < last->start)
|
||||
+ /* Already excluded by parent resource */
|
||||
+ continue;
|
||||
+
|
||||
+ excl_range.start = start;
|
||||
+ excl_range.end = end;
|
||||
+ ret = mem_regions_alloc_and_exclude(&memranges, &excl_range);
|
||||
+ if (ret) {
|
||||
+ fprintf(stderr,
|
||||
+ "Cannot allocate memory for ranges (exclude)\n");
|
||||
+ fclose(fp);
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+ dbgprintf("%s:- %016llx - %016llx\n",
|
||||
+ __func__, start, end);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ fclose(fp);
|
||||
+
|
||||
+ *range = memranges.ranges;
|
||||
+ *ranges = memranges.size;
|
||||
|
||||
/* As a fallback option, we can try determining the PHYS_OFFSET
|
||||
* value from the '/proc/iomem' entries as well.
|
||||
@@ -982,52 +1054,15 @@ static int get_memory_ranges_iomem_cb(void *data, int nr, char *str,
|
||||
* between the user-space and kernel space 'PHYS_OFFSET'
|
||||
* value.
|
||||
*/
|
||||
- set_phys_offset(r->start, "iomem");
|
||||
-
|
||||
- dbgprintf("%s: %016llx - %016llx : %s", __func__, r->start,
|
||||
- r->end, str);
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-/**
|
||||
- * get_memory_ranges_iomem - Try to get the memory ranges from
|
||||
- * /proc/iomem.
|
||||
- */
|
||||
+ if (memranges.size)
|
||||
+ set_phys_offset(memranges.ranges[0].start, "iomem");
|
||||
|
||||
-static int get_memory_ranges_iomem(struct memory_range *array,
|
||||
- unsigned int *count)
|
||||
-{
|
||||
- *count = kexec_iomem_for_each_line(NULL,
|
||||
- get_memory_ranges_iomem_cb, array);
|
||||
-
|
||||
- if (!*count) {
|
||||
- dbgprintf("%s: failed: No RAM found.\n", __func__);
|
||||
- return EFAILED;
|
||||
- }
|
||||
+ dbgprint_mem_range("System RAM ranges;",
|
||||
+ memranges.ranges, memranges.size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
-/**
|
||||
- * get_memory_ranges - Try to get the memory ranges some how.
|
||||
- */
|
||||
-
|
||||
-int get_memory_ranges(struct memory_range **range, int *ranges,
|
||||
- unsigned long kexec_flags)
|
||||
-{
|
||||
- static struct memory_range array[KEXEC_SEGMENT_MAX];
|
||||
- unsigned int count;
|
||||
- int result;
|
||||
-
|
||||
- result = get_memory_ranges_iomem(array, &count);
|
||||
-
|
||||
- *range = result ? NULL : array;
|
||||
- *ranges = result ? 0 : count;
|
||||
-
|
||||
- return result;
|
||||
-}
|
||||
-
|
||||
int arch_compat_trampoline(struct kexec_info *info)
|
||||
{
|
||||
return 0;
|
||||
--
|
||||
2.7.4
|
||||
|
@ -0,0 +1,89 @@
|
||||
From cf977b1af9ec67fabcc6a625589c49c52d07b11d Mon Sep 17 00:00:00 2001
|
||||
From: AKASHI Takahiro <takahiro.akashi@linaro.org>
|
||||
Date: Wed, 18 Dec 2019 11:42:30 -0500
|
||||
Subject: [PATCH 1/3] kexec: add variant helper functions for handling memory
|
||||
regions
|
||||
|
||||
mem_regions_alloc_and_add() and mem_regions_alloc_and_exclude() are
|
||||
functionally equivalent to, respectively, mem_regions_add() and
|
||||
mem_regions_exclude() except the formers will re-allocate memory
|
||||
dynamically when no more entries are available in 'ranges' array.
|
||||
|
||||
Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
|
||||
Tested-by: Bhupesh Sharma <bhsharma@redhat.com>
|
||||
Tested-by: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
|
||||
Signed-off-by: Simon Horman <horms@verge.net.au>
|
||||
---
|
||||
kexec/mem_regions.c | 42 ++++++++++++++++++++++++++++++++++++++++++
|
||||
kexec/mem_regions.h | 7 +++++++
|
||||
2 files changed, 49 insertions(+)
|
||||
|
||||
diff --git a/kexec/mem_regions.c b/kexec/mem_regions.c
|
||||
index 50c8abccb93a..ad7d3f13fd84 100644
|
||||
--- a/kexec/mem_regions.c
|
||||
+++ b/kexec/mem_regions.c
|
||||
@@ -125,3 +125,45 @@ int mem_regions_exclude(struct memory_ranges *ranges,
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
+
|
||||
+#define KEXEC_MEMORY_RANGES 16
|
||||
+
|
||||
+int mem_regions_alloc_and_add(struct memory_ranges *ranges,
|
||||
+ unsigned long long base,
|
||||
+ unsigned long long length, int type)
|
||||
+{
|
||||
+ void *new_ranges;
|
||||
+
|
||||
+ if (ranges->size >= ranges->max_size) {
|
||||
+ new_ranges = realloc(ranges->ranges,
|
||||
+ sizeof(struct memory_range) *
|
||||
+ (ranges->max_size + KEXEC_MEMORY_RANGES));
|
||||
+ if (!new_ranges)
|
||||
+ return -1;
|
||||
+
|
||||
+ ranges->ranges = new_ranges;
|
||||
+ ranges->max_size += KEXEC_MEMORY_RANGES;
|
||||
+ }
|
||||
+
|
||||
+ return mem_regions_add(ranges, base, length, type);
|
||||
+}
|
||||
+
|
||||
+int mem_regions_alloc_and_exclude(struct memory_ranges *ranges,
|
||||
+ const struct memory_range *range)
|
||||
+{
|
||||
+ void *new_ranges;
|
||||
+
|
||||
+ /* for safety, we should have at least one free entry in ranges */
|
||||
+ if (ranges->size >= ranges->max_size) {
|
||||
+ new_ranges = realloc(ranges->ranges,
|
||||
+ sizeof(struct memory_range) *
|
||||
+ (ranges->max_size + KEXEC_MEMORY_RANGES));
|
||||
+ if (!new_ranges)
|
||||
+ return -1;
|
||||
+
|
||||
+ ranges->ranges = new_ranges;
|
||||
+ ranges->max_size += KEXEC_MEMORY_RANGES;
|
||||
+ }
|
||||
+
|
||||
+ return mem_regions_exclude(ranges, range);
|
||||
+}
|
||||
diff --git a/kexec/mem_regions.h b/kexec/mem_regions.h
|
||||
index ae9e972b0206..e306d67e3261 100644
|
||||
--- a/kexec/mem_regions.h
|
||||
+++ b/kexec/mem_regions.h
|
||||
@@ -12,4 +12,11 @@ int mem_regions_exclude(struct memory_ranges *ranges,
|
||||
int mem_regions_add(struct memory_ranges *ranges, unsigned long long base,
|
||||
unsigned long long length, int type);
|
||||
|
||||
+int mem_regions_alloc_and_exclude(struct memory_ranges *ranges,
|
||||
+ const struct memory_range *range);
|
||||
+
|
||||
+int mem_regions_alloc_and_add(struct memory_ranges *ranges,
|
||||
+ unsigned long long base,
|
||||
+ unsigned long long length, int type);
|
||||
+
|
||||
#endif
|
||||
--
|
||||
2.7.4
|
||||
|
@ -0,0 +1,36 @@
|
||||
From 7242ae4cb5288df626f464ced0a8b60fd669100b Mon Sep 17 00:00:00 2001
|
||||
From: Michal Suchanek <msuchanek@suse.de>
|
||||
Date: Mon, 16 Mar 2020 19:39:58 +0100
|
||||
Subject: [PATCH 6/7] [PATCH] Align PMD_SECTION_MASK with PHYS_MASK
|
||||
|
||||
Reportedly on some arm64 systems makedumpfile loops forever exhausting
|
||||
all memory when filtering kernel core. It turns out the reason is it
|
||||
cannot resolve some addresses because the PMD mask is wrong. When
|
||||
physical address mask allows up to 48bits pmd mask should allow the
|
||||
same.
|
||||
I suppose you would need a system that needs physical addresses over 1TB
|
||||
to be able to reproduce this. This may be either because you have a lot
|
||||
of memory or because the firmware mapped some memory above 1TB for some
|
||||
reason.
|
||||
|
||||
Signed-off-by: Michal Suchanek <msuchanek@suse.de>
|
||||
---
|
||||
arch/arm64.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/makedumpfile-1.6.7/arch/arm64.c b/makedumpfile-1.6.7/arch/arm64.c
|
||||
index 43164cc..54d60b4 100644
|
||||
--- a/makedumpfile-1.6.7/arch/arm64.c
|
||||
+++ b/makedumpfile-1.6.7/arch/arm64.c
|
||||
@@ -81,7 +81,7 @@ static unsigned long kimage_voffset;
|
||||
* Remove the highest order bits that are not a part of the
|
||||
* physical address in a section
|
||||
*/
|
||||
-#define PMD_SECTION_MASK ((1UL << 40) - 1)
|
||||
+#define PMD_SECTION_MASK ((1UL << PHYS_MASK_SHIFT) - 1)
|
||||
|
||||
#define PMD_TYPE_MASK 3
|
||||
#define PMD_TYPE_SECT 1
|
||||
--
|
||||
2.7.5
|
||||
|
@ -0,0 +1,80 @@
|
||||
From 81b79c514ff6fc881f1df4cb04ecb2d7cb22badc Mon Sep 17 00:00:00 2001
|
||||
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||
Date: Wed, 19 Feb 2020 12:48:13 -0500
|
||||
Subject: [PATCH] [PATCH] Avoid false-positive failure in mem_seciton
|
||||
validation
|
||||
|
||||
Currently in get_mem_section(), we check whether SYMBOL(mem_section)
|
||||
is a pointer to the array or a pointer to the pointer to the array
|
||||
for some cases.
|
||||
|
||||
However, with commit e113f1c974c8 ("[PATCH] cope with not-present
|
||||
mem section") relaxing the check, there was a report that the function
|
||||
failed because both of two validate_mem_section() calls return TRUE.
|
||||
|
||||
Avoid the false-positive failure by not calling the second one if the
|
||||
first one returns TRUE.
|
||||
|
||||
Reported-by: Pingfan Liu <piliu@redhat.com>
|
||||
Acked-by: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
|
||||
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||
---
|
||||
makedumpfile.c | 29 ++++++-----------------------
|
||||
1 file changed, 6 insertions(+), 23 deletions(-)
|
||||
|
||||
diff --git a/makedumpfile-1.6.7/makedumpfile.c b/makedumpfile-1.6.7/makedumpfile.c
|
||||
index f5860a1..4c4251e 100644
|
||||
--- a/makedumpfile-1.6.7/makedumpfile.c
|
||||
+++ b/makedumpfile-1.6.7/makedumpfile.c
|
||||
@@ -3472,7 +3472,6 @@ static int
|
||||
get_mem_section(unsigned int mem_section_size, unsigned long *mem_maps,
|
||||
unsigned int num_section)
|
||||
{
|
||||
- unsigned long mem_section_ptr;
|
||||
int ret = FALSE;
|
||||
unsigned long *mem_sec = NULL;
|
||||
|
||||
@@ -3484,34 +3483,18 @@ get_mem_section(unsigned int mem_section_size, unsigned long *mem_maps,
|
||||
ret = validate_mem_section(mem_sec, SYMBOL(mem_section),
|
||||
mem_section_size, mem_maps, num_section);
|
||||
|
||||
- if (is_sparsemem_extreme()) {
|
||||
- int symbol_valid = ret;
|
||||
- int pointer_valid;
|
||||
- int mem_maps_size = sizeof(*mem_maps) * num_section;
|
||||
- unsigned long *mem_maps_ex = NULL;
|
||||
+ if (!ret && is_sparsemem_extreme()) {
|
||||
+ unsigned long mem_section_ptr;
|
||||
+
|
||||
if (!readmem(VADDR, SYMBOL(mem_section), &mem_section_ptr,
|
||||
sizeof(mem_section_ptr)))
|
||||
goto out;
|
||||
|
||||
- if ((mem_maps_ex = malloc(mem_maps_size)) == NULL) {
|
||||
- ERRMSG("Can't allocate memory for the mem_maps. %s\n",
|
||||
- strerror(errno));
|
||||
- goto out;
|
||||
- }
|
||||
+ ret = validate_mem_section(mem_sec, mem_section_ptr,
|
||||
+ mem_section_size, mem_maps, num_section);
|
||||
|
||||
- pointer_valid = validate_mem_section(mem_sec,
|
||||
- mem_section_ptr,
|
||||
- mem_section_size,
|
||||
- mem_maps_ex,
|
||||
- num_section);
|
||||
- if (pointer_valid)
|
||||
- memcpy(mem_maps, mem_maps_ex, mem_maps_size);
|
||||
- if (mem_maps_ex)
|
||||
- free(mem_maps_ex);
|
||||
- ret = symbol_valid ^ pointer_valid;
|
||||
- if (!ret) {
|
||||
+ if (!ret)
|
||||
ERRMSG("Could not validate mem_section.\n");
|
||||
- }
|
||||
}
|
||||
out:
|
||||
if (mem_sec != NULL)
|
||||
--
|
||||
2.7.5
|
||||
|
@ -0,0 +1,42 @@
|
||||
From 6e4b2dfaed5e5e5c617e0e45f969c1f571c13e27 Mon Sep 17 00:00:00 2001
|
||||
From: Jialong Chen <chenjialong@huawei.com>
|
||||
Date: Mon, 23 Mar 2020 16:42:01 -0400
|
||||
Subject: [PATCH 7/7] [PATCH] Fix cd_header offset overflow with large pfn
|
||||
|
||||
In function write_kdump_pages_and_bitmap_cyclic(), cd_header->offset is
|
||||
calculated by the following formula:
|
||||
|
||||
cd_header->offset
|
||||
= (DISKDUMP_HEADER_BLOCKS + dh->sub_hdr_size + dh->bitmap_blocks)
|
||||
* dh->block_size;
|
||||
|
||||
However, the variables of the right side are only int and unsigned int,
|
||||
so if dh->bitmap_blocks is very large, it causes an interger overflow.
|
||||
|
||||
As a result, makedumpfile created a broken vmcore in a system with a
|
||||
physical address range from 0x602770ecf000 to 0x6027ffffffff, and the
|
||||
crash utility failed during session initialization, ending with the
|
||||
error message "crash: vmlinux and vmcore do not match!".
|
||||
|
||||
Signed-off-by: Jialong Chen <chenjialong@huawei.com>
|
||||
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||
---
|
||||
diskdump_mod.h | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/makedumpfile-1.6.7/diskdump_mod.h b/makedumpfile-1.6.7/diskdump_mod.h
|
||||
index 2676817..3733953 100644
|
||||
--- a/makedumpfile-1.6.7/diskdump_mod.h
|
||||
+++ b/makedumpfile-1.6.7/diskdump_mod.h
|
||||
@@ -22,7 +22,7 @@
|
||||
#define DISK_DUMP_SIGNATURE "DISKDUMP"
|
||||
#define KDUMP_SIGNATURE "KDUMP "
|
||||
#define SIG_LEN (sizeof(DUMP_PARTITION_SIGNATURE) - 1)
|
||||
-#define DISKDUMP_HEADER_BLOCKS (1)
|
||||
+#define DISKDUMP_HEADER_BLOCKS (1UL)
|
||||
|
||||
/*
|
||||
* These are all remnants of the old "diskdump" facility,
|
||||
--
|
||||
2.7.5
|
||||
|
@ -0,0 +1,255 @@
|
||||
From 989152e113bfcb4fbfbad6f3aed6f43be4455919 Mon Sep 17 00:00:00 2001
|
||||
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||
Date: Tue, 25 Feb 2020 16:04:55 -0500
|
||||
Subject: [PATCH 4/7] [PATCH] Introduce --check-params option
|
||||
|
||||
Currently it's difficult to check whether a makedumpfile command-line
|
||||
is valid or not without an actual panic. This is inefficient and if
|
||||
a wrong configuration is not tested, you will miss the vmcore when an
|
||||
actual panic occurs.
|
||||
|
||||
In order for kdump facilities like kexec-tools to be able to check
|
||||
the specified command-line parameters in advance, introduce the
|
||||
--check-params option that only checks them and exits immediately.
|
||||
|
||||
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||
---
|
||||
makedumpfile.8 | 5 ++++
|
||||
makedumpfile.c | 75 +++++++++++++++++++++++++++++++++++++++++++++-------------
|
||||
makedumpfile.h | 2 ++
|
||||
print_info.c | 4 ++++
|
||||
4 files changed, 69 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/makedumpfile-1.6.7/makedumpfile.8 b/makedumpfile-1.6.7/makedumpfile.8
|
||||
index bf156a8..c5d4806 100644
|
||||
--- a/makedumpfile-1.6.7/makedumpfile.8
|
||||
+++ b/makedumpfile-1.6.7/makedumpfile.8
|
||||
@@ -632,6 +632,11 @@ Show help message and LZO/snappy support status (enabled/disabled).
|
||||
\fB\-v\fR
|
||||
Show the version of makedumpfile.
|
||||
|
||||
+.TP
|
||||
+\fB\-\-check-params\fR
|
||||
+Only check whether the command-line parameters are valid or not, and exit.
|
||||
+Preferable to be given as the first parameter.
|
||||
+
|
||||
.SH ENVIRONMENT VARIABLES
|
||||
|
||||
.TP 8
|
||||
diff --git a/makedumpfile-1.6.7/makedumpfile.c b/makedumpfile-1.6.7/makedumpfile.c
|
||||
index 607e07f..f5860a1 100644
|
||||
--- a/makedumpfile-1.6.7/makedumpfile.c
|
||||
+++ b/makedumpfile-1.6.7/makedumpfile.c
|
||||
@@ -10972,12 +10972,6 @@ check_param_for_creating_dumpfile(int argc, char *argv[])
|
||||
if (info->flag_generate_vmcoreinfo || info->flag_rearrange)
|
||||
return FALSE;
|
||||
|
||||
- if ((message_level < MIN_MSG_LEVEL)
|
||||
- || (MAX_MSG_LEVEL < message_level)) {
|
||||
- message_level = DEFAULT_MSG_LEVEL;
|
||||
- MSG("Message_level is invalid.\n");
|
||||
- return FALSE;
|
||||
- }
|
||||
if ((info->flag_compress && info->flag_elf_dumpfile)
|
||||
|| (info->flag_read_vmcoreinfo && info->name_vmlinux)
|
||||
|| (info->flag_read_vmcoreinfo && info->name_xen_syms))
|
||||
@@ -11007,6 +11001,11 @@ check_param_for_creating_dumpfile(int argc, char *argv[])
|
||||
if (info->flag_partial_dmesg && !info->flag_dmesg)
|
||||
return FALSE;
|
||||
|
||||
+ if (info->flag_excludevm && !info->working_dir) {
|
||||
+ MSG("-%c requires --work-dir\n", OPT_EXCLUDE_UNUSED_VM);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
if ((argc == optind + 2) && !info->flag_flatten
|
||||
&& !info->flag_split
|
||||
&& !info->flag_sadump_diskset) {
|
||||
@@ -11402,6 +11401,23 @@ int show_mem_usage(void)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
+static int set_message_level(char *str_ml)
|
||||
+{
|
||||
+ int ml;
|
||||
+
|
||||
+ ml = atoi(str_ml);
|
||||
+ if ((ml < MIN_MSG_LEVEL) || (MAX_MSG_LEVEL < ml)) {
|
||||
+ message_level = DEFAULT_MSG_LEVEL;
|
||||
+ MSG("Message_level(%d) is invalid.\n", ml);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ if (info->flag_check_params)
|
||||
+ return TRUE;
|
||||
+
|
||||
+ message_level = ml;
|
||||
+ return TRUE;
|
||||
+}
|
||||
|
||||
static struct option longopts[] = {
|
||||
{"split", no_argument, NULL, OPT_SPLIT},
|
||||
@@ -11423,6 +11439,7 @@ static struct option longopts[] = {
|
||||
{"splitblock-size", required_argument, NULL, OPT_SPLITBLOCK_SIZE},
|
||||
{"work-dir", required_argument, NULL, OPT_WORKING_DIR},
|
||||
{"num-threads", required_argument, NULL, OPT_NUM_THREADS},
|
||||
+ {"check-params", no_argument, NULL, OPT_CHECK_PARAMS},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
@@ -11521,7 +11538,8 @@ main(int argc, char *argv[])
|
||||
info->flag_compress = DUMP_DH_COMPRESSED_LZO;
|
||||
break;
|
||||
case OPT_MESSAGE_LEVEL:
|
||||
- message_level = atoi(optarg);
|
||||
+ if (!set_message_level(optarg))
|
||||
+ goto out;
|
||||
break;
|
||||
case OPT_DUMP_DMESG:
|
||||
info->flag_dmesg = 1;
|
||||
@@ -11584,6 +11602,10 @@ main(int argc, char *argv[])
|
||||
case OPT_NUM_THREADS:
|
||||
info->num_threads = MAX(atoi(optarg), 0);
|
||||
break;
|
||||
+ case OPT_CHECK_PARAMS:
|
||||
+ info->flag_check_params = TRUE;
|
||||
+ message_level = DEFAULT_MSG_LEVEL;
|
||||
+ break;
|
||||
case '?':
|
||||
MSG("Commandline parameter is invalid.\n");
|
||||
MSG("Try `makedumpfile --help' for more information.\n");
|
||||
@@ -11593,11 +11615,9 @@ main(int argc, char *argv[])
|
||||
if (flag_debug)
|
||||
message_level |= ML_PRINT_DEBUG_MSG;
|
||||
|
||||
- if (info->flag_excludevm && !info->working_dir) {
|
||||
- ERRMSG("Error: -%c requires --work-dir\n", OPT_EXCLUDE_UNUSED_VM);
|
||||
- ERRMSG("Try `makedumpfile --help' for more information\n");
|
||||
- return COMPLETED;
|
||||
- }
|
||||
+ if (info->flag_check_params)
|
||||
+ /* suppress debugging messages */
|
||||
+ message_level = DEFAULT_MSG_LEVEL;
|
||||
|
||||
if (info->flag_show_usage) {
|
||||
print_usage();
|
||||
@@ -11628,6 +11648,9 @@ main(int argc, char *argv[])
|
||||
MSG("Try `makedumpfile --help' for more information.\n");
|
||||
goto out;
|
||||
}
|
||||
+ if (info->flag_check_params)
|
||||
+ goto check_ok;
|
||||
+
|
||||
if (!open_files_for_generating_vmcoreinfo())
|
||||
goto out;
|
||||
|
||||
@@ -11651,6 +11674,9 @@ main(int argc, char *argv[])
|
||||
MSG("Try `makedumpfile --help' for more information.\n");
|
||||
goto out;
|
||||
}
|
||||
+ if (info->flag_check_params)
|
||||
+ goto check_ok;
|
||||
+
|
||||
if (!check_dump_file(info->name_dumpfile))
|
||||
goto out;
|
||||
|
||||
@@ -11671,6 +11697,9 @@ main(int argc, char *argv[])
|
||||
MSG("Try `makedumpfile --help' for more information.\n");
|
||||
goto out;
|
||||
}
|
||||
+ if (info->flag_check_params)
|
||||
+ goto check_ok;
|
||||
+
|
||||
if (!check_dump_file(info->name_dumpfile))
|
||||
goto out;
|
||||
|
||||
@@ -11684,6 +11713,9 @@ main(int argc, char *argv[])
|
||||
MSG("Try `makedumpfile --help' for more information.\n");
|
||||
goto out;
|
||||
}
|
||||
+ if (info->flag_check_params)
|
||||
+ goto check_ok;
|
||||
+
|
||||
if (!check_dump_file(info->name_dumpfile))
|
||||
goto out;
|
||||
if (!dump_dmesg())
|
||||
@@ -11697,6 +11729,9 @@ main(int argc, char *argv[])
|
||||
MSG("Try `makedumpfile --help' for more information.\n");
|
||||
goto out;
|
||||
}
|
||||
+ if (info->flag_check_params)
|
||||
+ goto check_ok;
|
||||
+
|
||||
if (!populate_kernel_version())
|
||||
goto out;
|
||||
|
||||
@@ -11715,6 +11750,9 @@ main(int argc, char *argv[])
|
||||
MSG("Try `makedumpfile --help' for more information.\n");
|
||||
goto out;
|
||||
}
|
||||
+ if (info->flag_check_params)
|
||||
+ goto check_ok;
|
||||
+
|
||||
if (info->flag_split) {
|
||||
for (i = 0; i < info->num_dumpfile; i++) {
|
||||
SPLITTING_FD_BITMAP(i) = -1;
|
||||
@@ -11742,13 +11780,16 @@ main(int argc, char *argv[])
|
||||
MSG("The dumpfile is saved to %s.\n", info->name_dumpfile);
|
||||
}
|
||||
}
|
||||
+check_ok:
|
||||
retcd = COMPLETED;
|
||||
out:
|
||||
- MSG("\n");
|
||||
- if (retcd != COMPLETED)
|
||||
- MSG("makedumpfile Failed.\n");
|
||||
- else if (!info->flag_mem_usage)
|
||||
- MSG("makedumpfile Completed.\n");
|
||||
+ if (!info->flag_check_params) {
|
||||
+ MSG("\n");
|
||||
+ if (retcd != COMPLETED)
|
||||
+ MSG("makedumpfile Failed.\n");
|
||||
+ else if (!info->flag_mem_usage)
|
||||
+ MSG("makedumpfile Completed.\n");
|
||||
+ }
|
||||
|
||||
free_for_parallel();
|
||||
|
||||
diff --git a/makedumpfile-1.6.7/makedumpfile.h b/makedumpfile-1.6.7/makedumpfile.h
|
||||
index 7217407..03fb4ce 100644
|
||||
--- a/makedumpfile-1.6.7/makedumpfile.h
|
||||
+++ b/makedumpfile-1.6.7/makedumpfile.h
|
||||
@@ -1301,6 +1301,7 @@ struct DumpInfo {
|
||||
int flag_read_vmcoreinfo; /* flag of reading vmcoreinfo file */
|
||||
int flag_show_usage; /* flag of showing usage */
|
||||
int flag_show_version; /* flag of showing version */
|
||||
+ int flag_check_params; /* only check parameters */
|
||||
int flag_flatten; /* flag of outputting flattened
|
||||
format to a standard out */
|
||||
int flag_rearrange; /* flag of creating dumpfile from
|
||||
@@ -2362,6 +2363,7 @@ struct elf_prstatus {
|
||||
#define OPT_WORKING_DIR OPT_START+15
|
||||
#define OPT_NUM_THREADS OPT_START+16
|
||||
#define OPT_PARTIAL_DMESG OPT_START+17
|
||||
+#define OPT_CHECK_PARAMS OPT_START+18
|
||||
|
||||
/*
|
||||
* Function Prototype.
|
||||
diff --git a/makedumpfile-1.6.7/print_info.c b/makedumpfile-1.6.7/print_info.c
|
||||
index 0be12ea..e0c38b4 100644
|
||||
--- a/makedumpfile-1.6.7/print_info.c
|
||||
+++ b/makedumpfile-1.6.7/print_info.c
|
||||
@@ -321,6 +321,10 @@ print_usage(void)
|
||||
MSG(" [-v]:\n");
|
||||
MSG(" Show the version of makedumpfile.\n");
|
||||
MSG("\n");
|
||||
+ MSG(" [--check-params]:\n");
|
||||
+ MSG(" Only check whether the command-line parameters are valid or not, and exit.\n");
|
||||
+ MSG(" Preferable to be given as the first parameter.\n");
|
||||
+ MSG("\n");
|
||||
MSG(" VMLINUX:\n");
|
||||
MSG(" This is a pathname to the first kernel's vmlinux.\n");
|
||||
MSG(" This file must have the debug information of the first kernel to analyze\n");
|
||||
--
|
||||
2.7.5
|
||||
|
@ -0,0 +1,65 @@
|
||||
From 12250baa02584dc713cdb1a12fb366f643fdc8b3 Mon Sep 17 00:00:00 2001
|
||||
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||
Date: Mon, 9 Mar 2020 17:17:31 -0400
|
||||
Subject: [PATCH 5/7] [PATCH] Makefile: Fix build errors in static build
|
||||
|
||||
When building makedumpfile statically (without LINKTYPE=dynamic),
|
||||
the following error is observed:
|
||||
|
||||
/usr/bin/ld: /usr/lib/makedumpfile-1.6.7/gcc/x86_64-redhat-linux/9/../../../../lib64/libdw.a(lzma.o): in function `__libdw_unlzma':
|
||||
(.text+0xbd): undefined reference to `lzma_auto_decoder'
|
||||
/usr/bin/ld: (.text+0x23a): undefined reference to `lzma_code'
|
||||
/usr/bin/ld: (.text+0x269): undefined reference to `lzma_end'
|
||||
/usr/bin/ld: (.text+0x2aa): undefined reference to `lzma_end'
|
||||
/usr/bin/ld: (.text+0x3ac): undefined reference to `lzma_end'
|
||||
/usr/bin/ld: (.text+0x427): undefined reference to `lzma_end'
|
||||
/usr/bin/ld: (.text+0x62b): undefined reference to `lzma_end'
|
||||
collect2: error: ld returned 1 exit status
|
||||
make: *** [Makefile:97: makedumpfile] Error 1
|
||||
|
||||
Also, when doing it with USESNAPPY=on:
|
||||
|
||||
/usr/bin/ld: /usr/local/lib64/libsnappy.a(snappy.cc.o): in function `snappy::internal::WorkingMemory::WorkingMemory(unsigned long)':
|
||||
snappy.cc:(.text+0x7d4): undefined reference to `std::allocator<char>::allocator()'
|
||||
/usr/bin/ld: snappy.cc:(.text+0x803): undefined reference to `std::allocator<char>::~allocator()'
|
||||
/usr/bin/ld: snappy.cc:(.text+0x853): undefined reference to `std::allocator<char>::~allocator()'
|
||||
/usr/bin/ld: /usr/local/lib64/libsnappy.a(snappy.cc.o): in function `snappy::internal::WorkingMemory::~WorkingMemory()':
|
||||
snappy.cc:(.text+0x87e): undefined reference to `std::allocator<char>::allocator()'
|
||||
/usr/bin/ld: snappy.cc:(.text+0x8a8): undefined reference to `std::allocator<char>::~allocator()'
|
||||
...
|
||||
|
||||
Fix these errors by adding -llzma and -lstd++ to LIBS respectively
|
||||
if LINKTYPE=dynamic is not specified.
|
||||
|
||||
Reported-by: Prabhakar Kushwaha <prabhakar.pkin@gmail.com>
|
||||
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||
---
|
||||
Makefile | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/makedumpfile-1.6.7/Makefile b/makedumpfile-1.6.7/Makefile
|
||||
index 868eea6..ef20672 100644
|
||||
--- a/makedumpfile-1.6.7/Makefile
|
||||
+++ b/makedumpfile-1.6.7/Makefile
|
||||
@@ -52,7 +52,7 @@ OBJ_ARCH=$(patsubst %.c,%.o,$(SRC_ARCH))
|
||||
|
||||
LIBS = -ldw -lbz2 -ldl -lelf -lz
|
||||
ifneq ($(LINKTYPE), dynamic)
|
||||
-LIBS := -static $(LIBS)
|
||||
+LIBS := -static $(LIBS) -llzma
|
||||
endif
|
||||
|
||||
ifeq ($(USELZO), on)
|
||||
@@ -62,6 +62,9 @@ endif
|
||||
|
||||
ifeq ($(USESNAPPY), on)
|
||||
LIBS := -lsnappy $(LIBS)
|
||||
+ifneq ($(LINKTYPE), dynamic)
|
||||
+LIBS := $(LIBS) -lstdc++
|
||||
+endif
|
||||
CFLAGS += -DUSESNAPPY
|
||||
endif
|
||||
|
||||
--
|
||||
2.7.5
|
||||
|
@ -0,0 +1,103 @@
|
||||
From 399f2c9a3acd5bd913e50a4dde52dee6527b297e Mon Sep 17 00:00:00 2001
|
||||
From: Kairui Song <kasong@redhat.com>
|
||||
Date: Wed, 29 Jan 2020 13:37:13 +0800
|
||||
Subject: [PATCH 2/7] [PATCH] Remove duplicated variable definitions
|
||||
|
||||
When building on Fedora 32 (with GCC 10), following error is observed:
|
||||
|
||||
/usr/bin/ld: erase_info.o:/tmp/makedumpfile/makedumpfile.h:2010: multiple definition of
|
||||
`crash_reserved_mem_nr'; elf_info.o:/tmp/makedumpfile/makedumpfile.h:2010: first defined here
|
||||
/usr/bin/ld: erase_info.o:/tmp/makedumpfile/makedumpfile.h:2009: multiple definition of
|
||||
`crash_reserved_mem'; elf_info.o:/tmp/makedumpfile/makedumpfile.h:2009: first defined here
|
||||
/usr/bin/ld: erase_info.o:/tmp/makedumpfile/makedumpfile.h:1278: multiple definition of
|
||||
`parallel_info_t'; elf_info.o:/tmp/makedumpfile/makedumpfile.h:1278: first defined here
|
||||
/usr/bin/ld: erase_info.o:/tmp/makedumpfile/makedumpfile.h:1265: multiple definition of
|
||||
`splitting_info_t'; elf_info.o:/tmp/makedumpfile/makedumpfile.h:1265: first defined here
|
||||
...
|
||||
collect2: error: ld returned 1 exit status
|
||||
make: *** [Makefile:97: makedumpfile] Error 1
|
||||
|
||||
These variables are wrongly defined multiple times. So remove the
|
||||
duplicated definitions.
|
||||
|
||||
Signed-off-by: Kairui Song <kasong@redhat.com>
|
||||
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||
---
|
||||
makedumpfile.c | 8 ++++----
|
||||
makedumpfile.h | 8 ++++----
|
||||
2 files changed, 8 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/makedumpfile-1.6.7/makedumpfile.c b/makedumpfile-1.6.7/makedumpfile.c
|
||||
index e290fbd..ae7336a 100644
|
||||
--- a/makedumpfile-1.6.7/makedumpfile.c
|
||||
+++ b/makedumpfile-1.6.7/makedumpfile.c
|
||||
@@ -10954,7 +10954,7 @@ check_param_for_reassembling_dumpfile(int argc, char *argv[])
|
||||
return FALSE;
|
||||
|
||||
if ((info->splitting_info
|
||||
- = malloc(sizeof(splitting_info_t) * info->num_dumpfile))
|
||||
+ = malloc(sizeof(struct splitting_info) * info->num_dumpfile))
|
||||
== NULL) {
|
||||
MSG("Can't allocate memory for splitting_info.\n");
|
||||
return FALSE;
|
||||
@@ -11042,7 +11042,7 @@ check_param_for_creating_dumpfile(int argc, char *argv[])
|
||||
return FALSE;
|
||||
}
|
||||
if ((info->splitting_info
|
||||
- = malloc(sizeof(splitting_info_t) * info->num_dumpfile))
|
||||
+ = malloc(sizeof(struct splitting_info) * info->num_dumpfile))
|
||||
== NULL) {
|
||||
MSG("Can't allocate memory for splitting_info.\n");
|
||||
return FALSE;
|
||||
@@ -11077,13 +11077,13 @@ check_param_for_creating_dumpfile(int argc, char *argv[])
|
||||
|
||||
if (info->num_threads) {
|
||||
if ((info->parallel_info =
|
||||
- malloc(sizeof(parallel_info_t) * info->num_threads))
|
||||
+ malloc(sizeof(struct parallel_info) * info->num_threads))
|
||||
== NULL) {
|
||||
MSG("Can't allocate memory for parallel_info.\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
- memset(info->parallel_info, 0, sizeof(parallel_info_t)
|
||||
+ memset(info->parallel_info, 0, sizeof(struct parallel_info)
|
||||
* info->num_threads);
|
||||
}
|
||||
|
||||
diff --git a/makedumpfile-1.6.7/makedumpfile.h b/makedumpfile-1.6.7/makedumpfile.h
|
||||
index 68d9691..7217407 100644
|
||||
--- a/makedumpfile-1.6.7/makedumpfile.h
|
||||
+++ b/makedumpfile-1.6.7/makedumpfile.h
|
||||
@@ -1262,7 +1262,7 @@ struct splitting_info {
|
||||
mdf_pfn_t end_pfn;
|
||||
off_t offset_eraseinfo;
|
||||
unsigned long size_eraseinfo;
|
||||
-} splitting_info_t;
|
||||
+};
|
||||
|
||||
struct parallel_info {
|
||||
int fd_memory;
|
||||
@@ -1275,7 +1275,7 @@ struct parallel_info {
|
||||
#ifdef USELZO
|
||||
lzo_bytep wrkmem;
|
||||
#endif
|
||||
-} parallel_info_t;
|
||||
+};
|
||||
|
||||
struct ppc64_vmemmap {
|
||||
unsigned long phys;
|
||||
@@ -2006,8 +2006,8 @@ struct memory_range {
|
||||
};
|
||||
|
||||
#define CRASH_RESERVED_MEM_NR 8
|
||||
-struct memory_range crash_reserved_mem[CRASH_RESERVED_MEM_NR];
|
||||
-int crash_reserved_mem_nr;
|
||||
+extern struct memory_range crash_reserved_mem[CRASH_RESERVED_MEM_NR];
|
||||
+extern int crash_reserved_mem_nr;
|
||||
|
||||
unsigned long read_vmcoreinfo_symbol(char *str_symbol);
|
||||
int readmem(int type_addr, unsigned long long addr, void *bufptr, size_t size);
|
||||
--
|
||||
2.7.5
|
||||
|
@ -0,0 +1,65 @@
|
||||
From e113f1c974c820f9633dc0073eda525d7575f365 Mon Sep 17 00:00:00 2001
|
||||
From: Pingfan Liu <piliu@redhat.com>
|
||||
Date: Mon, 20 Jan 2020 10:25:24 +0800
|
||||
Subject: [PATCH 3/7] [PATCH] cope with not-present mem section
|
||||
|
||||
After kernel commit ba72b4c8cf60 ("mm/sparsemem: support sub-section
|
||||
hotplug"), when hot-removed, section_mem_map is still encoded with section
|
||||
start pfn, not NULL. This break the current makedumpfile.
|
||||
|
||||
# makedumpfile -x vmlinux -l -d 31 vmcore vmcore.dump
|
||||
get_mem_section: Could not validate mem_section.
|
||||
get_mm_sparsemem: Can't get the address of mem_section.
|
||||
|
||||
makedumpfile Failed.
|
||||
|
||||
Whatever section_mem_map coding info after hot-removed, it is reliable
|
||||
just to work on SECTION_MARKED_PRESENT bit. Fixing makedumpfile by this
|
||||
way.
|
||||
|
||||
[ This issue occurs on kernel 5.3 through 5.5, and should be fixed by
|
||||
commit 1f503443e7df ("mm/sparse.c: reset section's mem_map when fully
|
||||
deactivated") in 5.6-rc1, 5.5.3 and 5.4.19. ]
|
||||
|
||||
Signed-off-by: Pingfan Liu <piliu@redhat.com>
|
||||
To: kexec@lists.infradead.org
|
||||
Cc: Kazuhito Hagio <k-hagio@ab.jp.nec.com>
|
||||
Cc: Baoquan He <bhe@redhat.com>
|
||||
Cc: David Hildenbrand <david@redhat.com>
|
||||
Cc: Andrew Morton <akpm@linux-foundation.org>
|
||||
Cc: Dan Williams <dan.j.williams@intel.com>
|
||||
Cc: Oscar Salvador <osalvador@suse.de>
|
||||
Cc: Michal Hocko <mhocko@kernel.org>
|
||||
Cc: Qian Cai <cai@lca.pw>
|
||||
---
|
||||
makedumpfile.c | 6 +-----
|
||||
1 file changed, 1 insertion(+), 5 deletions(-)
|
||||
|
||||
diff --git a/makedumpfile-1.6.7/makedumpfile.c b/makedumpfile-1.6.7/makedumpfile.c
|
||||
index ae7336a..607e07f 100644
|
||||
--- a/makedumpfile-1.6.7/makedumpfile.c
|
||||
+++ b/makedumpfile-1.6.7/makedumpfile.c
|
||||
@@ -3406,8 +3406,6 @@ section_mem_map_addr(unsigned long addr, unsigned long *map_mask)
|
||||
map = ULONG(mem_section + OFFSET(mem_section.section_mem_map));
|
||||
mask = SECTION_MAP_MASK;
|
||||
*map_mask = map & ~mask;
|
||||
- if (map == 0x0)
|
||||
- *map_mask |= SECTION_MARKED_PRESENT;
|
||||
map &= mask;
|
||||
free(mem_section);
|
||||
|
||||
@@ -3453,10 +3451,8 @@ validate_mem_section(unsigned long *mem_sec,
|
||||
mem_map = NOT_MEMMAP_ADDR;
|
||||
} else {
|
||||
mem_map = section_mem_map_addr(section, &map_mask);
|
||||
+ /* for either no mem_map or hot-removed */
|
||||
if (!(map_mask & SECTION_MARKED_PRESENT)) {
|
||||
- return FALSE;
|
||||
- }
|
||||
- if (mem_map == 0) {
|
||||
mem_map = NOT_MEMMAP_ADDR;
|
||||
} else {
|
||||
mem_map = sparse_decode_mem_map(mem_map,
|
||||
--
|
||||
2.7.5
|
||||
|
@ -0,0 +1,213 @@
|
||||
From 3c0cf7a93cff83f1e711e241eb47fcb096a451c5 Mon Sep 17 00:00:00 2001
|
||||
From: HATAYAMA Daisuke <d.hatayama@fujitsu.com>
|
||||
Date: Thu, 9 Jul 2020 18:27:49 +0900
|
||||
Subject: [PATCH] [PATCH] sadump, kaslr: fix failure of calculating
|
||||
kaslr_offset due to an sadump format restriction
|
||||
|
||||
We faced recently a memory dump collected by sadump where unused part
|
||||
of register values are non-zero. For the crash dump, calculating
|
||||
kaslr_offset fails because it is based on the assumption that unused
|
||||
part of register values in the sadump format are always zero cleared.
|
||||
|
||||
The problem is that used and unused part of register values are
|
||||
rigorously indistinguishable in the sadump format. Although there is
|
||||
kernel data structure that represents a map between logical cpu
|
||||
numbers and lapic ids, they cannot be used in order to calculate
|
||||
kaslr_offset.
|
||||
|
||||
To fix this, we have no choice but use a trial-and-error approach: try
|
||||
to use each entry of register values in order until we find a good
|
||||
pair of cr3 and idtr by which we can refer to linux_banner symbol as
|
||||
expected.
|
||||
|
||||
Signed-off-by: HATAYAMA Daisuke <d.hatayama@fujitsu.com>
|
||||
---
|
||||
sadump_info.c | 129 +++++++++++++++++++++++++++++++++++++++++-----------------
|
||||
1 file changed, 91 insertions(+), 38 deletions(-)
|
||||
|
||||
diff --git a/makedumpfile-1.6.7/sadump_info.c b/makedumpfile-1.6.7/sadump_info.c
|
||||
index 72a077b4f408..410c6bc2a909 100644
|
||||
--- a/makedumpfile-1.6.7/sadump_info.c
|
||||
+++ b/makedumpfile-1.6.7/sadump_info.c
|
||||
@@ -101,6 +101,7 @@ static int lookup_diskset(unsigned long long whole_offset, int *diskid,
|
||||
unsigned long long *disk_offset);
|
||||
static int max_mask_cpu(void);
|
||||
static int cpu_online_mask_init(void);
|
||||
+static int linux_banner_sanity_check(ulong cr3);
|
||||
static int per_cpu_init(void);
|
||||
static int get_data_from_elf_note_desc(const char *note_buf, uint32_t n_descsz,
|
||||
char *name, uint32_t n_type, char **data);
|
||||
@@ -1293,6 +1294,30 @@ finish:
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static int linux_banner_sanity_check(ulong cr3)
|
||||
+{
|
||||
+ unsigned long linux_banner_paddr;
|
||||
+ char buf[sizeof("Linux version")];
|
||||
+
|
||||
+ linux_banner_paddr = vtop4_x86_64_pagetable(SYMBOL(linux_banner), cr3);
|
||||
+ if (linux_banner_paddr == NOT_PADDR) {
|
||||
+ DEBUG_MSG("sadump: linux_banner address translation failed\n");
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ if (!readmem(PADDR, linux_banner_paddr, &buf, sizeof(buf))) {
|
||||
+ DEBUG_MSG("sadump: reading linux_banner failed\n");
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ if (!STRNEQ(buf, "Linux version")) {
|
||||
+ DEBUG_MSG("sadump: linux_banner sanity check failed\n");
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ return TRUE;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Calculate kaslr_offset and phys_base
|
||||
*
|
||||
@@ -1370,59 +1395,85 @@ calc_kaslr_offset(void)
|
||||
{
|
||||
struct sadump_header *sh = si->sh_memory;
|
||||
uint64_t idtr = 0, cr3 = 0, idtr_paddr;
|
||||
- struct sadump_smram_cpu_state smram, zero;
|
||||
+ struct sadump_smram_cpu_state smram;
|
||||
int apicid;
|
||||
unsigned long divide_error_vmcore, divide_error_vmlinux;
|
||||
unsigned long kaslr_offset, phys_base;
|
||||
unsigned long kaslr_offset_kdump, phys_base_kdump;
|
||||
+ int sanity_check_passed = FALSE;
|
||||
|
||||
- memset(&zero, 0, sizeof(zero));
|
||||
for (apicid = 0; apicid < sh->nr_cpus; ++apicid) {
|
||||
+
|
||||
+ DEBUG_MSG("sadump: apicid: %d\n", apicid);
|
||||
+
|
||||
if (!get_smram_cpu_state(apicid, &smram)) {
|
||||
ERRMSG("get_smram_cpu_state error\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
- if (memcmp(&smram, &zero, sizeof(smram)) != 0)
|
||||
- break;
|
||||
- }
|
||||
- if (apicid >= sh->nr_cpus) {
|
||||
- ERRMSG("Can't get smram state\n");
|
||||
- return FALSE;
|
||||
- }
|
||||
+ idtr = ((uint64_t)smram.IdtUpper)<<32|(uint64_t)smram.IdtLower;
|
||||
|
||||
- idtr = ((uint64_t)smram.IdtUpper)<<32 | (uint64_t)smram.IdtLower;
|
||||
- if ((SYMBOL(pti_init) != NOT_FOUND_SYMBOL) ||
|
||||
- (SYMBOL(kaiser_init) != NOT_FOUND_SYMBOL))
|
||||
- cr3 = smram.Cr3 & ~(CR3_PCID_MASK|PTI_USER_PGTABLE_MASK);
|
||||
- else
|
||||
- cr3 = smram.Cr3 & ~CR3_PCID_MASK;
|
||||
+ if (!smram.Cr3 || !idtr) {
|
||||
+ DEBUG_MSG("sadump: cr3: %lx idt: %lx, skipped\n",
|
||||
+ smram.Cr3, idtr);
|
||||
+ continue;
|
||||
+ }
|
||||
|
||||
- /* Convert virtual address of IDT table to physical address */
|
||||
- if ((idtr_paddr = vtop4_x86_64_pagetable(idtr, cr3)) == NOT_PADDR)
|
||||
- return FALSE;
|
||||
+ if ((SYMBOL(pti_init) != NOT_FOUND_SYMBOL) ||
|
||||
+ (SYMBOL(kaiser_init) != NOT_FOUND_SYMBOL))
|
||||
+ cr3 = smram.Cr3 & ~(CR3_PCID_MASK|PTI_USER_PGTABLE_MASK);
|
||||
+ else
|
||||
+ cr3 = smram.Cr3 & ~CR3_PCID_MASK;
|
||||
|
||||
- /* Now we can calculate kaslr_offset and phys_base */
|
||||
- divide_error_vmlinux = SYMBOL(divide_error);
|
||||
- divide_error_vmcore = get_vec0_addr(idtr_paddr);
|
||||
- kaslr_offset = divide_error_vmcore - divide_error_vmlinux;
|
||||
- phys_base = idtr_paddr -
|
||||
- (SYMBOL(idt_table) + kaslr_offset - __START_KERNEL_map);
|
||||
+ /* Convert virtual address of IDT table to physical address */
|
||||
+ idtr_paddr = vtop4_x86_64_pagetable(idtr, cr3);
|
||||
+ if (idtr_paddr == NOT_PADDR) {
|
||||
+ DEBUG_MSG("sadump: converting IDT physical address "
|
||||
+ "failed.\n");
|
||||
+ continue;
|
||||
+ }
|
||||
|
||||
- info->kaslr_offset = kaslr_offset;
|
||||
- info->phys_base = phys_base;
|
||||
+ /* Now we can calculate kaslr_offset and phys_base */
|
||||
+ divide_error_vmlinux = SYMBOL(divide_error);
|
||||
+ divide_error_vmcore = get_vec0_addr(idtr_paddr);
|
||||
+ kaslr_offset = divide_error_vmcore - divide_error_vmlinux;
|
||||
+ phys_base = idtr_paddr -
|
||||
+ (SYMBOL(idt_table)+kaslr_offset-__START_KERNEL_map);
|
||||
|
||||
- DEBUG_MSG("sadump: idtr=%" PRIx64 "\n", idtr);
|
||||
- DEBUG_MSG("sadump: cr3=%" PRIx64 "\n", cr3);
|
||||
- DEBUG_MSG("sadump: idtr(phys)=%" PRIx64 "\n", idtr_paddr);
|
||||
- DEBUG_MSG("sadump: devide_error(vmlinux)=%lx\n",
|
||||
- divide_error_vmlinux);
|
||||
- DEBUG_MSG("sadump: devide_error(vmcore)=%lx\n",
|
||||
- divide_error_vmcore);
|
||||
+ info->kaslr_offset = kaslr_offset;
|
||||
+ info->phys_base = phys_base;
|
||||
|
||||
- /* Reload symbol */
|
||||
- if (!get_symbol_info())
|
||||
- return FALSE;
|
||||
+ DEBUG_MSG("sadump: idtr=%" PRIx64 "\n", idtr);
|
||||
+ DEBUG_MSG("sadump: cr3=%" PRIx64 "\n", cr3);
|
||||
+ DEBUG_MSG("sadump: idtr(phys)=%" PRIx64 "\n", idtr_paddr);
|
||||
+ DEBUG_MSG("sadump: devide_error(vmlinux)=%lx\n",
|
||||
+ divide_error_vmlinux);
|
||||
+ DEBUG_MSG("sadump: devide_error(vmcore)=%lx\n",
|
||||
+ divide_error_vmcore);
|
||||
+
|
||||
+ /* Reload symbol */
|
||||
+ if (!get_symbol_info()) {
|
||||
+ ERRMSG("Reading symbol table failed\n");
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ /* Sanity check */
|
||||
+ if (linux_banner_sanity_check(cr3)) {
|
||||
+ sanity_check_passed = TRUE;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ info->kaslr_offset = 0;
|
||||
+ info->phys_base = 0;
|
||||
+ }
|
||||
+
|
||||
+ if (!sanity_check_passed) {
|
||||
+ ERRMSG("failed to calculate kaslr_offset and phys_base; "
|
||||
+ "default to 0\n");
|
||||
+ info->kaslr_offset = 0;
|
||||
+ info->phys_base = 0;
|
||||
+ return TRUE;
|
||||
+ }
|
||||
|
||||
/*
|
||||
* Check if current kaslr_offset/phys_base is for 1st kernel or 2nd
|
||||
@@ -1430,13 +1481,15 @@ calc_kaslr_offset(void)
|
||||
* from vmcoreinfo
|
||||
*/
|
||||
if (get_kaslr_offset_from_vmcoreinfo(cr3, &kaslr_offset_kdump,
|
||||
- &phys_base_kdump)) {
|
||||
+ &phys_base_kdump)) {
|
||||
info->kaslr_offset = kaslr_offset_kdump;
|
||||
info->phys_base = phys_base_kdump;
|
||||
|
||||
/* Reload symbol */
|
||||
- if (!get_symbol_info())
|
||||
+ if (!get_symbol_info()) {
|
||||
+ ERRMSG("Reading symbol table failed\n");
|
||||
return FALSE;
|
||||
+ }
|
||||
}
|
||||
|
||||
DEBUG_MSG("sadump: kaslr_offset=%lx\n", info->kaslr_offset);
|
||||
--
|
||||
2.7.4
|
||||
|
@ -0,0 +1,38 @@
|
||||
From a46c686f615a86933134c0924c3391ba598a02b8 Mon Sep 17 00:00:00 2001
|
||||
From: Bhupesh Sharma <bhsharma@redhat.com>
|
||||
Date: Tue, 10 Sep 2019 15:51:49 +0530
|
||||
Subject: [PATCH 5/5] vmcore-dmesg/vmcore-dmesg.c: Fix shifting error reported
|
||||
by cppcheck
|
||||
|
||||
Running 'cppcheck' static code analyzer (see cppcheck(1))
|
||||
on 'vmcore-dmesg/vmcore-dmesg.c' shows the following
|
||||
shifting error:
|
||||
|
||||
$ cppcheck --enable=all vmcore-dmesg/vmcore-dmesg.c
|
||||
Checking vmcore-dmesg/vmcore-dmesg.c ...
|
||||
[vmcore-dmesg/vmcore-dmesg.c:17]: (error) Shifting signed 32-bit value by 31 bits is undefined behaviour
|
||||
|
||||
Fix the same via this patch.
|
||||
|
||||
Signed-off-by: Bhupesh Sharma <bhsharma@redhat.com>
|
||||
Signed-off-by: Simon Horman <horms@verge.net.au>
|
||||
---
|
||||
vmcore-dmesg/vmcore-dmesg.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/vmcore-dmesg/vmcore-dmesg.c b/vmcore-dmesg/vmcore-dmesg.c
|
||||
index 81c2a58c9d86..122e53672e01 100644
|
||||
--- a/vmcore-dmesg/vmcore-dmesg.c
|
||||
+++ b/vmcore-dmesg/vmcore-dmesg.c
|
||||
@@ -6,7 +6,7 @@ typedef Elf32_Nhdr Elf_Nhdr;
|
||||
extern const char *fname;
|
||||
|
||||
/* stole this macro from kernel printk.c */
|
||||
-#define LOG_BUF_LEN_MAX (uint32_t)(1 << 31)
|
||||
+#define LOG_BUF_LEN_MAX (uint32_t)(1U << 31)
|
||||
|
||||
static void write_to_stdout(char *buf, unsigned int nr)
|
||||
{
|
||||
--
|
||||
2.17.1
|
||||
|
25
SOURCES/live-image-kdump-howto.txt
Normal file
25
SOURCES/live-image-kdump-howto.txt
Normal file
@ -0,0 +1,25 @@
|
||||
Kdump now works on live images with some manual configurations. Here is the step
|
||||
by step guide.
|
||||
|
||||
1. Enable crashkernel reservation
|
||||
|
||||
Since there isn't any config file that can be used to configure kernel
|
||||
parameters for live images before booting them, we have to append 'crashkernel'
|
||||
argument in boot menu every time we boot a live image.
|
||||
|
||||
2. Change dump target in /etc/kdump.conf
|
||||
|
||||
When kdump kernel boots in a live environment, the default target /var/crash is
|
||||
in RAM so you need to change the dump target to an external disk or a network
|
||||
dump target.
|
||||
|
||||
Besides, make sure that "default dump_to_rootfs" is not specified.
|
||||
|
||||
3. Start kdump service
|
||||
|
||||
$ kdumpctl start
|
||||
|
||||
4. Trigger a kdump test
|
||||
|
||||
$ echo 1 > /proc/sys/kernel/sysrq
|
||||
$ echo c > /proc/sysrq-trigger
|
482
SOURCES/mkdumprd
Normal file
482
SOURCES/mkdumprd
Normal file
@ -0,0 +1,482 @@
|
||||
#!/bin/bash --norc
|
||||
# New mkdumprd
|
||||
#
|
||||
# Copyright 2011 Red Hat, Inc.
|
||||
#
|
||||
# Written by Cong Wang <amwang@redhat.com>
|
||||
#
|
||||
|
||||
[[ $dracutbasedir ]] || dracutbasedir=/usr/lib/dracut
|
||||
. $dracutbasedir/dracut-functions.sh
|
||||
. /lib/kdump/kdump-lib.sh
|
||||
export IN_KDUMP=1
|
||||
|
||||
conf_file="/etc/kdump.conf"
|
||||
SSH_KEY_LOCATION="/root/.ssh/kdump_id_rsa"
|
||||
SAVE_PATH=$(get_save_path)
|
||||
OVERRIDE_RESETTABLE=0
|
||||
|
||||
extra_modules=""
|
||||
dracut_args="--quiet --hostonly --hostonly-cmdline --hostonly-i18n --hostonly-mode strict -o \"plymouth dash resume ifcfg earlykdump\""
|
||||
|
||||
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
|
||||
|
||||
is_wdt_addition_needed() {
|
||||
local active
|
||||
|
||||
is_wdt_mod_omitted
|
||||
[[ $? -eq 0 ]] && return 1
|
||||
[[ -d /sys/class/watchdog/ ]] || return 1
|
||||
for dir in /sys/class/watchdog/*; do
|
||||
[[ -f "$dir/state" ]] || continue
|
||||
active=$(< "$dir/state")
|
||||
[[ "$active" = "active" ]] && return 0
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
add_dracut_arg() {
|
||||
dracut_args="$dracut_args $@"
|
||||
}
|
||||
|
||||
add_dracut_module() {
|
||||
add_dracut_arg "--add" "\"$1\""
|
||||
}
|
||||
|
||||
add_dracut_mount() {
|
||||
add_dracut_arg "--mount" "\"$1\""
|
||||
}
|
||||
|
||||
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/,addr=[^,]*//')
|
||||
_options=$(echo $_options | sed 's/,proto=[^,]*//')
|
||||
_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
|
||||
echo "Warning: There might not be enough space to save a vmcore."
|
||||
echo " 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#* }"
|
||||
|
||||
if [ "$_cmd" != "makedumpfile" ]; then
|
||||
if is_raw_dump_target; then
|
||||
echo "Warning: specifying a non-makedumpfile core collector, you will have to recover the vmcore manually."
|
||||
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}')
|
||||
echo "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
|
||||
}
|
||||
|
||||
# $1: maj:min
|
||||
is_crypt()
|
||||
{
|
||||
local majmin=$1 dev line ID_FS_TYPE=""
|
||||
|
||||
line=$(udevadm info --query=property --path=/sys/dev/block/$majmin \
|
||||
| grep "^ID_FS_TYPE")
|
||||
eval "$line"
|
||||
[[ "$ID_FS_TYPE" = "crypto_LUKS" ]] && {
|
||||
dev=$(udevadm info --query=all --path=/sys/dev/block/$majmin | awk -F= '/DEVNAME/{print $2}')
|
||||
echo "Device $dev is encrypted."
|
||||
return 0
|
||||
}
|
||||
return 1
|
||||
}
|
||||
|
||||
check_crypt()
|
||||
{
|
||||
local _ret _target
|
||||
|
||||
for_each_block_target is_crypt
|
||||
_ret=$?
|
||||
|
||||
[ $_ret -eq 0 ] && return
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
if ! check_resettable; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! check_crypt; then
|
||||
echo "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
|
||||
|
||||
if [ "$(uname -m)" = "s390x" ]; then
|
||||
add_dracut_module "znet"
|
||||
fi
|
||||
|
||||
if is_wdt_addition_needed; then
|
||||
add_dracut_arg "-a" "watchdog"
|
||||
fi
|
||||
|
||||
while read config_opt config_val;
|
||||
do
|
||||
# remove inline comments after the end of a directive.
|
||||
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_module "ssh-client"
|
||||
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
|
||||
|
||||
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"
|
||||
fi
|
||||
|
||||
echo "$dracut_args $@" | xargs dracut
|
||||
|
||||
_rc=$?
|
||||
sync
|
||||
exit $_rc
|
33
SOURCES/mkdumprd.8
Normal file
33
SOURCES/mkdumprd.8
Normal file
@ -0,0 +1,33 @@
|
||||
.TH MKDUMRD 8 "Fri Feb 9 2007"
|
||||
.SH NAME
|
||||
mkdumprd \- creates initial ramdisk images for kdump crash recovery
|
||||
.SH SYNOPSIS
|
||||
\fBmkdumprd\fR [OPTION]
|
||||
|
||||
.SH DESCRIPTION
|
||||
\fBmkdumprd\fR creates an initial ram file system for use in conjunction with
|
||||
the booting of a kernel within the kdump framework for crash recovery.
|
||||
\fBmkdumprds\fR purpose is to create an initial ram filesystem capable of copying
|
||||
the crashed systems vmcore image to a location specified in \fI/etc/kdump.conf
|
||||
|
||||
\fBmkdumprd\fR interrogates the running system to understand what modules need to
|
||||
be loaded in the initramfs (based on configuration retrieved from
|
||||
\fI/etc/kdump.conf)\fR
|
||||
|
||||
\fBmkdumprd\fR add a new \fBdracut\fR module 99kdumpbase and use \fBdracut\fR
|
||||
utility to generate the initramfs.
|
||||
|
||||
\fBmkdumprd\fR was not intended for casual use outside of the service
|
||||
initialization script for the kdump utility, and should not be run manually. If
|
||||
you require a custom kdump initramfs image, it is suggested that you use the
|
||||
kdump service infrastructure to create one, and then manually unpack, modify and
|
||||
repack the image.
|
||||
|
||||
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
All options here are passed to dracut directly, please refer \fBdracut\fR docs
|
||||
for the info.
|
||||
|
||||
.SH "SEE ALSO"
|
||||
.BR dracut (8)
|
@ -0,0 +1,13 @@
|
||||
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)"
|
@ -0,0 +1,51 @@
|
||||
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
|
||||
|
@ -0,0 +1,235 @@
|
||||
From: Bhupesh Sharma <bhsharma@redhat.com>
|
||||
Date: Wed, 6 Feb 2019 12:31:29 +0530
|
||||
Subject: [PATCH] makedumpfile/arm64: Add support for ARMv8.2-LVA (52-bit
|
||||
user-space VA support)
|
||||
|
||||
With ARMv8.2-LVA architecture extension availability, arm64 hardware
|
||||
which supports this extension can support upto 52-bit virtual
|
||||
addresses. It is specially useful for having a 52-bit user-space virtual
|
||||
address space while the kernel can still retain 48-bit virtual
|
||||
addresses.
|
||||
|
||||
Since at the moment we enable the support of this extension in the
|
||||
kernel via a CONFIG flag (CONFIG_ARM64_USER_VA_BITS_52), so there are
|
||||
no clear mechanisms in user-space to determine this CONFIG
|
||||
flag value and use it to determine the user-space VA address range
|
||||
values.
|
||||
|
||||
'makedumpfile' can instead use 'MAX_USER_VA_BITS' value to
|
||||
determine the maximum virtual physical address supported by user-space.
|
||||
If 'MAX_USER_VA_BITS' value is greater than 'VA_BITS' than we are
|
||||
running a use-case where user-space is 52-bit and underlying kernel is
|
||||
still 48-bit. The increased 'PTRS_PER_PGD' value for such cases can then
|
||||
be calculated as is done by the underlying kernel (see kernel file
|
||||
'arch/arm64/include/asm/pgtable-hwdef.h' for details):
|
||||
|
||||
#define PTRS_PER_PGD (1 << (MAX_USER_VA_BITS - PGDIR_SHIFT))
|
||||
|
||||
I have sent a kernel patch upstream to add 'MAX_USER_VA_BITS' to
|
||||
vmcoreinfo for arm64 (see [0]).
|
||||
|
||||
This patch is in accordance with ARMv8 Architecture Reference Manual
|
||||
version D.a
|
||||
|
||||
[0].
|
||||
http://lists.infradead.org/pipermail/kexec/2019-February/022411.html
|
||||
|
||||
Signed-off-by: Bhupesh Sharma <bhsharma@redhat.com>
|
||||
|
||||
---
|
||||
arch/arm64.c | 109 ++++++++++++++++++++++++++++++++++++++++++---------------
|
||||
makedumpfile.c | 2 ++
|
||||
makedumpfile.h | 1 +
|
||||
3 files changed, 83 insertions(+), 29 deletions(-)
|
||||
|
||||
diff --git a/makedumpfile-1.6.7/arch/arm64.c b/makedumpfile-1.6.7/arch/arm64.c
|
||||
index 0535193..5fcf59d 100644
|
||||
--- a/makedumpfile-1.6.7/arch/arm64.c
|
||||
+++ b/makedumpfile-1.6.7/arch/arm64.c
|
||||
@@ -41,6 +41,7 @@ typedef struct {
|
||||
|
||||
static int pgtable_level;
|
||||
static int va_bits;
|
||||
+static int max_user_va_bits;
|
||||
static unsigned long kimage_voffset;
|
||||
|
||||
#define SZ_4K (4 * 1024)
|
||||
@@ -61,7 +62,7 @@ static unsigned long kimage_voffset;
|
||||
|
||||
#define PAGE_MASK (~(PAGESIZE() - 1))
|
||||
#define PGDIR_SHIFT ((PAGESHIFT() - 3) * pgtable_level + 3)
|
||||
-#define PTRS_PER_PGD (1 << (va_bits - PGDIR_SHIFT))
|
||||
+#define PTRS_PER_PGD (1 << ((max_user_va_bits) - PGDIR_SHIFT))
|
||||
#define PUD_SHIFT get_pud_shift_arm64()
|
||||
#define PUD_SIZE (1UL << PUD_SHIFT)
|
||||
#define PUD_MASK (~(PUD_SIZE - 1))
|
||||
@@ -73,6 +74,10 @@ static unsigned long kimage_voffset;
|
||||
#define PTRS_PER_PMD PTRS_PER_PTE
|
||||
|
||||
#define PAGE_PRESENT (1 << 0)
|
||||
+
|
||||
+/*
|
||||
+ * Section address mask and size definitions.
|
||||
+ */
|
||||
#define SECTIONS_SIZE_BITS 30
|
||||
/* Highest possible physical address supported */
|
||||
#define PHYS_MASK_SHIFT 48
|
||||
@@ -284,14 +289,83 @@ get_stext_symbol(void)
|
||||
return(found ? kallsym : FALSE);
|
||||
}
|
||||
|
||||
+static int
|
||||
+get_va_bits_from_stext_arm64(void)
|
||||
+{
|
||||
+ ulong _stext;
|
||||
+
|
||||
+ _stext = get_stext_symbol();
|
||||
+ if (!_stext) {
|
||||
+ ERRMSG("Can't get the symbol of _stext.\n");
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ /* Derive va_bits as per arch/arm64/Kconfig */
|
||||
+ if ((_stext & PAGE_OFFSET_36) == PAGE_OFFSET_36) {
|
||||
+ va_bits = 36;
|
||||
+ } else if ((_stext & PAGE_OFFSET_39) == PAGE_OFFSET_39) {
|
||||
+ va_bits = 39;
|
||||
+ } else if ((_stext & PAGE_OFFSET_42) == PAGE_OFFSET_42) {
|
||||
+ va_bits = 42;
|
||||
+ } else if ((_stext & PAGE_OFFSET_47) == PAGE_OFFSET_47) {
|
||||
+ va_bits = 47;
|
||||
+ } else if ((_stext & PAGE_OFFSET_48) == PAGE_OFFSET_48) {
|
||||
+ va_bits = 48;
|
||||
+ } else {
|
||||
+ ERRMSG("Cannot find a proper _stext for calculating VA_BITS\n");
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ DEBUG_MSG("va_bits : %d\n", va_bits);
|
||||
+
|
||||
+ return TRUE;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+get_page_offset_arm64(void)
|
||||
+{
|
||||
+ info->page_offset = (0xffffffffffffffffUL) << (va_bits - 1);
|
||||
+
|
||||
+ DEBUG_MSG("page_offset : %lx\n", info->page_offset);
|
||||
+}
|
||||
+
|
||||
int
|
||||
get_machdep_info_arm64(void)
|
||||
{
|
||||
/* Check if va_bits is still not initialized. If still 0, call
|
||||
* get_versiondep_info() to initialize the same.
|
||||
*/
|
||||
+ if (NUMBER(VA_BITS) != NOT_FOUND_NUMBER) {
|
||||
+ va_bits = NUMBER(VA_BITS);
|
||||
+ DEBUG_MSG("va_bits : %d (vmcoreinfo)\n",
|
||||
+ va_bits);
|
||||
+ }
|
||||
+
|
||||
+ /* Check if va_bits is still not initialized. If still 0, call
|
||||
+ * get_versiondep_info() to initialize the same from _stext
|
||||
+ * symbol.
|
||||
+ */
|
||||
if (!va_bits)
|
||||
- get_versiondep_info_arm64();
|
||||
+ if (get_va_bits_from_stext_arm64() == ERROR)
|
||||
+ return ERROR;
|
||||
+
|
||||
+ get_page_offset_arm64();
|
||||
+
|
||||
+ if (NUMBER(MAX_USER_VA_BITS) != NOT_FOUND_NUMBER) {
|
||||
+ max_user_va_bits = NUMBER(MAX_USER_VA_BITS);
|
||||
+ DEBUG_MSG("max_user_va_bits : %d (vmcoreinfo)\n",
|
||||
+ max_user_va_bits);
|
||||
+ }
|
||||
+
|
||||
+ /* Check if max_user_va_bits is still not initialized.
|
||||
+ * If still 0, its not available in vmcoreinfo and its
|
||||
+ * safe to initialize it with va_bits.
|
||||
+ */
|
||||
+ if (!max_user_va_bits) {
|
||||
+ max_user_va_bits = va_bits;
|
||||
+ DEBUG_MSG("max_user_va_bits : %d (default = va_bits)\n",
|
||||
+ max_user_va_bits);
|
||||
+ }
|
||||
|
||||
if (!calculate_plat_config()) {
|
||||
ERRMSG("Can't determine platform config values\n");
|
||||
@@ -330,34 +404,11 @@ get_xen_info_arm64(void)
|
||||
int
|
||||
get_versiondep_info_arm64(void)
|
||||
{
|
||||
- ulong _stext;
|
||||
-
|
||||
- _stext = get_stext_symbol();
|
||||
- if (!_stext) {
|
||||
- ERRMSG("Can't get the symbol of _stext.\n");
|
||||
- return FALSE;
|
||||
- }
|
||||
-
|
||||
- /* Derive va_bits as per arch/arm64/Kconfig */
|
||||
- if ((_stext & PAGE_OFFSET_36) == PAGE_OFFSET_36) {
|
||||
- va_bits = 36;
|
||||
- } else if ((_stext & PAGE_OFFSET_39) == PAGE_OFFSET_39) {
|
||||
- va_bits = 39;
|
||||
- } else if ((_stext & PAGE_OFFSET_42) == PAGE_OFFSET_42) {
|
||||
- va_bits = 42;
|
||||
- } else if ((_stext & PAGE_OFFSET_47) == PAGE_OFFSET_47) {
|
||||
- va_bits = 47;
|
||||
- } else if ((_stext & PAGE_OFFSET_48) == PAGE_OFFSET_48) {
|
||||
- va_bits = 48;
|
||||
- } else {
|
||||
- ERRMSG("Cannot find a proper _stext for calculating VA_BITS\n");
|
||||
- return FALSE;
|
||||
- }
|
||||
-
|
||||
- info->page_offset = (0xffffffffffffffffUL) << (va_bits - 1);
|
||||
+ if (!va_bits)
|
||||
+ if (get_va_bits_from_stext_arm64() == ERROR)
|
||||
+ return ERROR;
|
||||
|
||||
- DEBUG_MSG("va_bits : %d\n", va_bits);
|
||||
- DEBUG_MSG("page_offset : %lx\n", info->page_offset);
|
||||
+ get_page_offset_arm64();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
diff --git a/makedumpfile-1.6.7/makedumpfile.c b/makedumpfile-1.6.7/makedumpfile.c
|
||||
index d76a435..c8906b5 100644
|
||||
--- a/makedumpfile-1.6.7/makedumpfile.c
|
||||
+++ b/makedumpfile-1.6.7/makedumpfile.c
|
||||
@@ -2313,6 +2313,7 @@ write_vmcoreinfo_data(void)
|
||||
|
||||
WRITE_NUMBER("HUGETLB_PAGE_DTOR", HUGETLB_PAGE_DTOR);
|
||||
#ifdef __aarch64__
|
||||
+ WRITE_NUMBER("MAX_USER_VA_BITS", MAX_USER_VA_BITS);
|
||||
WRITE_NUMBER("VA_BITS", VA_BITS);
|
||||
WRITE_NUMBER_UNSIGNED("PHYS_OFFSET", PHYS_OFFSET);
|
||||
WRITE_NUMBER_UNSIGNED("kimage_voffset", kimage_voffset);
|
||||
@@ -2719,6 +2720,7 @@ read_vmcoreinfo(void)
|
||||
READ_NUMBER("phys_base", phys_base);
|
||||
READ_NUMBER("KERNEL_IMAGE_SIZE", KERNEL_IMAGE_SIZE);
|
||||
#ifdef __aarch64__
|
||||
+ READ_NUMBER("MAX_USER_VA_BITS", MAX_USER_VA_BITS);
|
||||
READ_NUMBER("VA_BITS", VA_BITS);
|
||||
READ_NUMBER_UNSIGNED("PHYS_OFFSET", PHYS_OFFSET);
|
||||
READ_NUMBER_UNSIGNED("kimage_voffset", kimage_voffset);
|
||||
diff --git a/makedumpfile-1.6.7/makedumpfile.h b/makedumpfile-1.6.7/makedumpfile.h
|
||||
index 24b2f69..cccb52a 100644
|
||||
--- a/makedumpfile-1.6.7/makedumpfile.h
|
||||
+++ b/makedumpfile-1.6.7/makedumpfile.h
|
||||
@@ -1937,6 +1937,7 @@ struct number_table {
|
||||
long phys_base;
|
||||
long KERNEL_IMAGE_SIZE;
|
||||
#ifdef __aarch64__
|
||||
+ long MAX_USER_VA_BITS;
|
||||
long VA_BITS;
|
||||
unsigned long PHYS_OFFSET;
|
||||
unsigned long kimage_voffset;
|
||||
--
|
||||
2.7.5
|
||||
|
128
SOURCES/supported-kdump-targets.txt
Normal file
128
SOURCES/supported-kdump-targets.txt
Normal file
@ -0,0 +1,128 @@
|
||||
Supported Kdump Targets
|
||||
|
||||
This document try to list all supported kdump targets, and those supported
|
||||
or unknown/tech-preview targets, this can help users to decide whether a dump
|
||||
solution is available.
|
||||
|
||||
Dump Target support status
|
||||
==========================
|
||||
This section tries to come up with some kind of guidelines in terms of
|
||||
what dump targets are supported/not supported. Whatever is listed here
|
||||
is not binding in any manner. It is just sharing of current understanding
|
||||
and if something is not right, this section needs to be edited.
|
||||
|
||||
Following are 3 lists. First one contains supported targets. These are
|
||||
generic configurations which should work and some configuration most
|
||||
likely has worked in testing. Second list is known unsupported targets.
|
||||
These targets we know either don't work or we don't support. And third
|
||||
list is unknown/tech-preview. We either don't yet know the status of kdump
|
||||
on these targets or these are under tech-preview.
|
||||
|
||||
Note, these lists are not set in stone and can be changed at any point of
|
||||
time. Also these lists might not be complete. We will add/remove items to
|
||||
it as we get more testing information. Also, there are many corner cases
|
||||
which can't possibly be listed. For example in general we might be
|
||||
supporting software iscsi but there might be some configurations of it
|
||||
which don't work.
|
||||
|
||||
So if any target is listed in supported section, it does not mean it works
|
||||
in all possible configurations. It just means that in common configurations
|
||||
it should work but there can be issues with particular configurations which
|
||||
are not supported. As we come to know of particular issues, we will keep on
|
||||
updating lists accordingly.
|
||||
|
||||
|
||||
Supported Dump targets
|
||||
----------------------
|
||||
storage:
|
||||
LVM volume (no thinp)
|
||||
FC disks (qla2xxx, lpfc, bnx2fc, bfa)
|
||||
software initiator based iSCSI
|
||||
software RAID (mdraid)
|
||||
hardware RAID (cciss, hpsa, megaraid_sas, mpt2sas, aacraid)
|
||||
SCSI/SATA disks
|
||||
iSCSI HBA (all offload)
|
||||
hardware FCoE (qla2xxx, lpfc)
|
||||
software FCoE (bnx2fc) (Extra configuration required,
|
||||
please read "Note on FCoE" section below)
|
||||
|
||||
network:
|
||||
Hardware using kernel modules: (tg3, igb, ixgbe, sfc, e1000e, bna,
|
||||
cnic, netxen_nic, qlge, bnx2x, bnx, qlcnic, be2net, enic,
|
||||
virtio-net, ixgbevf, igbvf)
|
||||
protocol: ipv4
|
||||
bonding
|
||||
vlan
|
||||
bridge
|
||||
team
|
||||
vlan tagged bonding
|
||||
bridge over bond/team/vlan
|
||||
|
||||
hypervisor:
|
||||
kvm
|
||||
xen (Supported in select configurations only)
|
||||
|
||||
filesystem:
|
||||
ext[234]
|
||||
xfs
|
||||
nfs
|
||||
|
||||
firmware:
|
||||
BIOS
|
||||
UEFI
|
||||
|
||||
hypervisor:
|
||||
VMWare ESXi 4.1 and 5.1
|
||||
Hyper-V 2012 R2 (RHEL Gen1 UP Guest only)
|
||||
|
||||
Unsupported Dump targets
|
||||
------------------------
|
||||
storage:
|
||||
BIOS RAID
|
||||
Thin provisioning volume
|
||||
Software iSCSI with iBFT (bnx2i, cxgb3i, cxgb4i)
|
||||
Software iSCSI with hybrid (be2iscsi)
|
||||
FCoE
|
||||
legacy IDE
|
||||
glusterfs
|
||||
gfs2/clvm/halvm
|
||||
|
||||
network:
|
||||
hardware using kernel modules: (sfc SRIOV, cxgb4vf, pch_gbe)
|
||||
protocol: ipv6
|
||||
wireless
|
||||
Infiniband (IB)
|
||||
vlan over bridge/team
|
||||
|
||||
filesystem:
|
||||
btrfs
|
||||
|
||||
Unknown/tech-preview
|
||||
--------------------
|
||||
storage:
|
||||
PCI Express based SSDs
|
||||
|
||||
hypervisor:
|
||||
Hyper-V 2008
|
||||
Hyper-V 2012
|
||||
|
||||
|
||||
Note on FCoE
|
||||
=====================
|
||||
If you are trying to dump to a software FCoE target, you may encounter OOM
|
||||
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)
|
2088
SPECS/kexec-tools.spec
Normal file
2088
SPECS/kexec-tools.spec
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user