Compare commits
No commits in common. 'c9' and 'i8c' have entirely different histories.
@ -1,3 +1,3 @@
|
|||||||
SOURCES/eppic-e8844d3.tar.gz
|
SOURCES/1.7.2.tar.gz
|
||||||
SOURCES/kexec-tools-2.0.27.tar.xz
|
SOURCES/eppic_050615.tar.gz
|
||||||
SOURCES/makedumpfile-1.7.4.tar.gz
|
SOURCES/kexec-tools-2.0.26.tar.xz
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
80ac3f5e77d3c79883edadf14428734db4720009 SOURCES/eppic-e8844d3.tar.gz
|
24bce02cd42cdbb960ada4d9e733355582e35784 SOURCES/1.7.2.tar.gz
|
||||||
ed15f191adee22ab0721ba62af1cae67eb981670 SOURCES/kexec-tools-2.0.27.tar.xz
|
a096c8e0892b559f40b01916aae240652f75b68a SOURCES/eppic_050615.tar.gz
|
||||||
98cae2b1062871905795918c32b6d46ccd115074 SOURCES/makedumpfile-1.7.4.tar.gz
|
27cea5d032ec1e93506b8110222420abf754df2d SOURCES/kexec-tools-2.0.26.tar.xz
|
||||||
|
@ -1,31 +0,0 @@
|
|||||||
#!/usr/bin/bash
|
|
||||||
|
|
||||||
COMMAND="$1"
|
|
||||||
KERNEL_VERSION="$2"
|
|
||||||
|
|
||||||
if ! [[ ${KERNEL_INSTALL_MACHINE_ID-x} ]]; then
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Currently, fadump is supported only in environments with
|
|
||||||
# writable /boot directory.
|
|
||||||
if [[ ! -w "/boot" ]]; then
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
FADUMP_INITRD="/boot/.initramfs-${KERNEL_VERSION}.img.default"
|
|
||||||
FADUMP_INITRD_CHECKSUM="$FADUMP_INITRD.checksum"
|
|
||||||
|
|
||||||
ret=0
|
|
||||||
case "$COMMAND" in
|
|
||||||
add)
|
|
||||||
# Do nothing, fadump initramfs is strictly host only
|
|
||||||
# and managed by kdump service
|
|
||||||
;;
|
|
||||||
remove)
|
|
||||||
rm -f -- "$FADUMP_INITRD"
|
|
||||||
rm -f -- "$FADUMP_INITRD_CHECKSUM"
|
|
||||||
ret=$?
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
exit $ret
|
|
@ -1,13 +0,0 @@
|
|||||||
#!/usr/bin/bash
|
|
||||||
|
|
||||||
COMMAND="$1"
|
|
||||||
KERNEL_VERSION="$2"
|
|
||||||
KDUMP_INITRD_DIR_ABS="$3"
|
|
||||||
KERNEL_IMAGE="$4"
|
|
||||||
|
|
||||||
case "$COMMAND" in
|
|
||||||
add)
|
|
||||||
kdumpctl _reset-crashkernel-for-installed_kernel "$KERNEL_VERSION"
|
|
||||||
exit 0
|
|
||||||
;;
|
|
||||||
esac
|
|
@ -1,120 +0,0 @@
|
|||||||
Introduction
|
|
||||||
============
|
|
||||||
|
|
||||||
This document describes features the kexec-tools package provides for setting
|
|
||||||
and estimating the crashkernel value.
|
|
||||||
|
|
||||||
Kdump lives in a pre-reserved chunk of memory, and the size of the reserved
|
|
||||||
memory is specified by the `crashkernel=` kernel parameter. It's hard to
|
|
||||||
estimate an accurate `crashkernel=` value, so it's always recommended to test
|
|
||||||
kdump after you updated the `crashkernel=` value or changed the dump target.
|
|
||||||
|
|
||||||
|
|
||||||
Default crashkernel value
|
|
||||||
=========================
|
|
||||||
|
|
||||||
Latest kexec-tools provides "kdumpctl get-default-crashkernel" to retrieve
|
|
||||||
the default crashkernel value,
|
|
||||||
|
|
||||||
$ echo $(kdumpctl get-default-crashkernel)
|
|
||||||
1G-4G:192M,4G-64G:256M,64G-:512M
|
|
||||||
|
|
||||||
It will be taken as the default value of 'crashkernel=', you can use
|
|
||||||
this value as a reference for setting crashkernel value manually.
|
|
||||||
|
|
||||||
|
|
||||||
New installed system
|
|
||||||
====================
|
|
||||||
|
|
||||||
Anaconda is the OS installer which sets all the kernel boot cmdline on a newly
|
|
||||||
installed system. If kdump is enabled during Anaconda installation, Anaconda
|
|
||||||
will use the default crashkernel value as the default `crashkernel=` value on
|
|
||||||
the newly installed system.
|
|
||||||
|
|
||||||
Users can override the value during Anaconda installation manually.
|
|
||||||
|
|
||||||
|
|
||||||
Auto update of crashkernel boot parameter
|
|
||||||
=========================================
|
|
||||||
|
|
||||||
A new release of kexec-tools could update the default crashkernel value. By
|
|
||||||
default, kexec-tools would reset crashkernel to the new default value if it
|
|
||||||
detects the old default crashkernel value is used by installed kernels. If you
|
|
||||||
don't want kexec-tools to update the old default crashkernel to the new default
|
|
||||||
crashkernel, you can change auto_reset_crashkernel to no in kdump.conf.
|
|
||||||
|
|
||||||
Supported Bootloaders
|
|
||||||
---------------------
|
|
||||||
|
|
||||||
This auto update only works with GRUB2 and ZIPL, as kexec-tools heavily depends
|
|
||||||
on `grubby`. If other boot loaders are used, the user will have to update the
|
|
||||||
`crashkernel=` value manually.
|
|
||||||
|
|
||||||
|
|
||||||
Reset crashkernel to default value
|
|
||||||
==================================
|
|
||||||
|
|
||||||
kexec-tools only perform the auto update of crashkernel value when it can
|
|
||||||
confirm the boot kernel's crashkernel value is using its corresponding default
|
|
||||||
value and auto_reset_crashkernel=yes in kdump.conf. In other cases, the user
|
|
||||||
can reset the crashkernel value by themselves.
|
|
||||||
|
|
||||||
Reset using kdumpctl
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
To make it easier to reset the `crashkernel=` kernel cmdline to this default
|
|
||||||
value properly, `kdumpctl` also provides a sub-command:
|
|
||||||
|
|
||||||
`kdumpctl reset-crashkernel [--kernel=path_to_kernel] [--reboot]`
|
|
||||||
|
|
||||||
This command will reset the bootloader's kernel cmdline to the default value.
|
|
||||||
It will also update bootloader config if the bootloader has a standalone config
|
|
||||||
file. User will have to reboot the machine after this command to make it take
|
|
||||||
effect if --reboot is not specified. For more details, please refer to the
|
|
||||||
reset-crashkernel command in `man kdumpctl`.
|
|
||||||
|
|
||||||
Reset manually
|
|
||||||
--------------
|
|
||||||
|
|
||||||
To reset the crashkernel value manually, it's recommended to use utils like
|
|
||||||
`grubby`. A one liner script for resetting `crashkernel=` value of all installed
|
|
||||||
kernels to the default value is:
|
|
||||||
|
|
||||||
grubby --update-kernel ALL --args "crashkernel=$(kdumpctl get-default-crashkernel)"
|
|
||||||
|
|
||||||
NOTE: On s390x you also need to run zipl for the change to take effect.
|
|
||||||
|
|
||||||
Estimate crashkernel
|
|
||||||
====================
|
|
||||||
|
|
||||||
The best way to estimate a usable crashkernel value is by testing kdump
|
|
||||||
manually. And you can set crashkernel to a large value, then adjust the
|
|
||||||
crashkernel value to an acceptable value gradually.
|
|
||||||
|
|
||||||
`kdumpctl` also provides a sub-command for doing rough estimating without
|
|
||||||
triggering kdump:
|
|
||||||
|
|
||||||
`kdumpctl estimate`
|
|
||||||
|
|
||||||
The output will be like this:
|
|
||||||
|
|
||||||
```
|
|
||||||
Encrypted kdump target requires extra memory, assuming using the keyslot with minimum memory requirement
|
|
||||||
|
|
||||||
Reserved crashkernel: 256M
|
|
||||||
Recommended crashkernel: 655M
|
|
||||||
|
|
||||||
Kernel image size: 47M
|
|
||||||
Kernel modules size: 12M
|
|
||||||
Initramfs size: 19M
|
|
||||||
Runtime reservation: 64M
|
|
||||||
LUKS required size: 512M
|
|
||||||
Large modules:
|
|
||||||
xfs: 1892352
|
|
||||||
nouveau: 2318336
|
|
||||||
WARNING: Current crashkernel size is lower than recommended size 655M.
|
|
||||||
```
|
|
||||||
|
|
||||||
It will generate a summary report about the estimated memory consumption
|
|
||||||
of each component of kdump. The value may not be accurate enough, but
|
|
||||||
would be a good start for finding a suitable crashkernel value.
|
|
@ -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
|
@ -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
|
@ -1,618 +1,324 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
#
|
|
||||||
# The main kdump routine in capture kernel, bash may not be the
|
|
||||||
# default shell. Any code added must be POSIX compliant.
|
|
||||||
|
|
||||||
. /lib/dracut-lib.sh
|
# continue here only if we have to save dump.
|
||||||
. /lib/kdump-logger.sh
|
if [ -f /etc/fadump.initramfs ] && [ ! -f /proc/device-tree/rtas/ibm,kernel-dump ] && [ ! -f /proc/device-tree/ibm,opal/dump/mpipl-boot ]; then
|
||||||
. /lib/kdump-lib-initramfs.sh
|
exit 0
|
||||||
|
|
||||||
#initiate the kdump logger
|
|
||||||
if ! dlog_init; then
|
|
||||||
echo "failed to initiate the kdump logger."
|
|
||||||
exit 1
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
KDUMP_PATH="/var/crash"
|
. /lib/dracut-lib.sh
|
||||||
KDUMP_LOG_FILE="/run/initramfs/kexec-dmesg.log"
|
. /lib/kdump-lib-initramfs.sh
|
||||||
CORE_COLLECTOR=""
|
|
||||||
DEFAULT_CORE_COLLECTOR="makedumpfile -l --message-level 7 -d 31"
|
|
||||||
DMESG_COLLECTOR="/sbin/vmcore-dmesg"
|
|
||||||
FAILURE_ACTION="systemctl reboot -f"
|
|
||||||
DATEDIR=$(date +%Y-%m-%d-%T)
|
|
||||||
HOST_IP='127.0.0.1'
|
|
||||||
DUMP_INSTRUCTION=""
|
|
||||||
SSH_KEY_LOCATION="/root/.ssh/kdump_id_rsa"
|
|
||||||
DD_BLKSIZE=512
|
|
||||||
FINAL_ACTION="systemctl reboot -f"
|
|
||||||
KDUMP_PRE=""
|
|
||||||
KDUMP_POST=""
|
|
||||||
NEWROOT="/sysroot"
|
|
||||||
OPALCORE="/sys/firmware/opal/mpipl/core"
|
|
||||||
KDUMP_CONF_PARSED="/tmp/kdump.conf.$$"
|
|
||||||
|
|
||||||
# POSIX doesn't have pipefail, only apply when using bash
|
|
||||||
# shellcheck disable=SC3040
|
|
||||||
[ -n "$BASH" ] && set -o pipefail
|
|
||||||
|
|
||||||
|
set -o pipefail
|
||||||
DUMP_RETVAL=0
|
DUMP_RETVAL=0
|
||||||
|
|
||||||
kdump_read_conf > $KDUMP_CONF_PARSED
|
export PATH=$PATH:$KDUMP_SCRIPT_DIR
|
||||||
|
|
||||||
get_kdump_confs()
|
do_dump()
|
||||||
{
|
|
||||||
while read -r config_opt config_val; do
|
|
||||||
# remove inline comments after the end of a directive.
|
|
||||||
case "$config_opt" in
|
|
||||||
path)
|
|
||||||
KDUMP_PATH="$config_val"
|
|
||||||
;;
|
|
||||||
core_collector)
|
|
||||||
[ -n "$config_val" ] && CORE_COLLECTOR="$config_val"
|
|
||||||
;;
|
|
||||||
sshkey)
|
|
||||||
if [ -f "$config_val" ]; then
|
|
||||||
SSH_KEY_LOCATION=$config_val
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
kdump_pre)
|
|
||||||
KDUMP_PRE="$config_val"
|
|
||||||
;;
|
|
||||||
kdump_post)
|
|
||||||
KDUMP_POST="$config_val"
|
|
||||||
;;
|
|
||||||
fence_kdump_args)
|
|
||||||
FENCE_KDUMP_ARGS="$config_val"
|
|
||||||
;;
|
|
||||||
fence_kdump_nodes)
|
|
||||||
FENCE_KDUMP_NODES="$config_val"
|
|
||||||
;;
|
|
||||||
failure_action | default)
|
|
||||||
case $config_val in
|
|
||||||
shell)
|
|
||||||
FAILURE_ACTION="kdump_emergency_shell"
|
|
||||||
;;
|
|
||||||
reboot)
|
|
||||||
FAILURE_ACTION="systemctl reboot -f && exit"
|
|
||||||
;;
|
|
||||||
halt)
|
|
||||||
FAILURE_ACTION="halt && exit"
|
|
||||||
;;
|
|
||||||
poweroff)
|
|
||||||
FAILURE_ACTION="systemctl poweroff -f && exit"
|
|
||||||
;;
|
|
||||||
dump_to_rootfs)
|
|
||||||
FAILURE_ACTION="dump_to_rootfs"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
final_action)
|
|
||||||
case $config_val in
|
|
||||||
reboot)
|
|
||||||
FINAL_ACTION="systemctl reboot -f"
|
|
||||||
;;
|
|
||||||
halt)
|
|
||||||
FINAL_ACTION="halt"
|
|
||||||
;;
|
|
||||||
poweroff)
|
|
||||||
FINAL_ACTION="systemctl poweroff -f"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done < "$KDUMP_CONF_PARSED"
|
|
||||||
|
|
||||||
if [ -z "$CORE_COLLECTOR" ]; then
|
|
||||||
CORE_COLLECTOR="$DEFAULT_CORE_COLLECTOR"
|
|
||||||
if is_ssh_dump_target || is_raw_dump_target; then
|
|
||||||
CORE_COLLECTOR="$CORE_COLLECTOR -F"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# store the kexec kernel log to a file.
|
|
||||||
save_log()
|
|
||||||
{
|
|
||||||
dmesg -T > $KDUMP_LOG_FILE
|
|
||||||
|
|
||||||
if command -v journalctl > /dev/null; then
|
|
||||||
journalctl -ab >> $KDUMP_LOG_FILE
|
|
||||||
fi
|
|
||||||
chmod 600 $KDUMP_LOG_FILE
|
|
||||||
}
|
|
||||||
|
|
||||||
# $1: dump path, must be a mount point
|
|
||||||
dump_fs()
|
|
||||||
{
|
|
||||||
ddebug "dump_fs _mp=$1"
|
|
||||||
|
|
||||||
if ! is_mounted "$1"; then
|
|
||||||
dinfo "dump path '$1' is not mounted, trying to mount..."
|
|
||||||
if ! mount --target "$1"; then
|
|
||||||
derror "failed to dump to '$1', it's not a mount point!"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Remove -F in makedumpfile case. We don't want a flat format dump here.
|
|
||||||
case $CORE_COLLECTOR in
|
|
||||||
*makedumpfile*)
|
|
||||||
CORE_COLLECTOR=$(echo "$CORE_COLLECTOR" | sed -e "s/-F//g")
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
_dump_fs_path=$(echo "$1/$KDUMP_PATH/$HOST_IP-$DATEDIR/" | tr -s /)
|
|
||||||
dinfo "saving to $_dump_fs_path"
|
|
||||||
|
|
||||||
# Only remount to read-write mode if the dump target is mounted read-only.
|
|
||||||
_dump_mnt_op=$(get_mount_info OPTIONS target "$1" -f)
|
|
||||||
case $_dump_mnt_op in
|
|
||||||
ro*)
|
|
||||||
dinfo "Remounting the dump target in rw mode."
|
|
||||||
mount -o remount,rw "$1" || return 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
mkdir -p "$_dump_fs_path" || return 1
|
|
||||||
|
|
||||||
save_vmcore_dmesg_fs ${DMESG_COLLECTOR} "$_dump_fs_path"
|
|
||||||
save_opalcore_fs "$_dump_fs_path"
|
|
||||||
|
|
||||||
dinfo "saving vmcore"
|
|
||||||
$CORE_COLLECTOR /proc/vmcore "$_dump_fs_path/vmcore-incomplete"
|
|
||||||
_dump_exitcode=$?
|
|
||||||
if [ $_dump_exitcode -eq 0 ]; then
|
|
||||||
sync -f "$_dump_fs_path/vmcore-incomplete"
|
|
||||||
_sync_exitcode=$?
|
|
||||||
if [ $_sync_exitcode -eq 0 ]; then
|
|
||||||
mv "$_dump_fs_path/vmcore-incomplete" "$_dump_fs_path/vmcore"
|
|
||||||
dinfo "saving vmcore complete"
|
|
||||||
else
|
|
||||||
derror "sync vmcore failed, exitcode:$_sync_exitcode"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
derror "saving vmcore failed, exitcode:$_dump_exitcode"
|
|
||||||
fi
|
|
||||||
|
|
||||||
dinfo "saving the $KDUMP_LOG_FILE to $_dump_fs_path/"
|
|
||||||
save_log
|
|
||||||
mv "$KDUMP_LOG_FILE" "$_dump_fs_path/"
|
|
||||||
if [ $_dump_exitcode -ne 0 ]; then
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# improper kernel cmdline can cause the failure of echo, we can ignore this kind of failure
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
# $1: dmesg collector
|
|
||||||
# $2: dump path
|
|
||||||
save_vmcore_dmesg_fs()
|
|
||||||
{
|
|
||||||
dinfo "saving vmcore-dmesg.txt to $2"
|
|
||||||
if $1 /proc/vmcore > "$2/vmcore-dmesg-incomplete.txt"; then
|
|
||||||
mv "$2/vmcore-dmesg-incomplete.txt" "$2/vmcore-dmesg.txt"
|
|
||||||
chmod 600 "$2/vmcore-dmesg.txt"
|
|
||||||
|
|
||||||
# Make sure file is on disk. There have been instances where later
|
|
||||||
# saving vmcore failed and system rebooted without sync and there
|
|
||||||
# was no vmcore-dmesg.txt available.
|
|
||||||
sync
|
|
||||||
dinfo "saving vmcore-dmesg.txt complete"
|
|
||||||
else
|
|
||||||
if [ -f "$2/vmcore-dmesg-incomplete.txt" ]; then
|
|
||||||
chmod 600 "$2/vmcore-dmesg-incomplete.txt"
|
|
||||||
fi
|
|
||||||
derror "saving vmcore-dmesg.txt failed"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# $1: dump path
|
|
||||||
save_opalcore_fs()
|
|
||||||
{
|
|
||||||
if [ ! -f $OPALCORE ]; then
|
|
||||||
# Check if we are on an old kernel that uses a different path
|
|
||||||
if [ -f /sys/firmware/opal/core ]; then
|
|
||||||
OPALCORE="/sys/firmware/opal/core"
|
|
||||||
else
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
dinfo "saving opalcore:$OPALCORE to $1/opalcore"
|
|
||||||
if ! cp $OPALCORE "$1/opalcore"; then
|
|
||||||
derror "saving opalcore failed"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
sync
|
|
||||||
dinfo "saving opalcore complete"
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
dump_to_rootfs()
|
|
||||||
{
|
{
|
||||||
|
local _ret
|
||||||
|
|
||||||
if [ "$(systemctl status dracut-initqueue | sed -n "s/^\s*Active: \(\S*\)\s.*$/\1/p")" = "inactive" ]; then
|
eval $DUMP_INSTRUCTION
|
||||||
dinfo "Trying to bring up initqueue for rootfs mount"
|
_ret=$?
|
||||||
systemctl start dracut-initqueue
|
|
||||||
fi
|
|
||||||
|
|
||||||
dinfo "Clean up dead systemd services"
|
|
||||||
systemctl cancel
|
|
||||||
dinfo "Waiting for rootfs mount, will timeout after 90 seconds"
|
|
||||||
systemctl start --no-block sysroot.mount
|
|
||||||
|
|
||||||
_loop=0
|
|
||||||
while [ $_loop -lt 90 ] && ! is_mounted /sysroot; do
|
|
||||||
sleep 1
|
|
||||||
_loop=$((_loop + 1))
|
|
||||||
done
|
|
||||||
|
|
||||||
if ! is_mounted /sysroot; then
|
|
||||||
derror "Failed to mount rootfs"
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
ddebug "NEWROOT=$NEWROOT"
|
|
||||||
dump_fs $NEWROOT
|
|
||||||
}
|
|
||||||
|
|
||||||
kdump_emergency_shell()
|
if [ $_ret -ne 0 ]; then
|
||||||
{
|
derror "saving vmcore failed"
|
||||||
ddebug "Switching to kdump emergency shell..."
|
fi
|
||||||
|
|
||||||
[ -f /etc/profile ] && . /etc/profile
|
|
||||||
export PS1='kdump:${PWD}# '
|
|
||||||
|
|
||||||
. /lib/dracut-lib.sh
|
|
||||||
if [ -f /dracut-state.sh ]; then
|
|
||||||
. /dracut-state.sh 2> /dev/null
|
|
||||||
fi
|
|
||||||
|
|
||||||
source_conf /etc/conf.d
|
|
||||||
|
|
||||||
type plymouth > /dev/null 2>&1 && plymouth quit
|
|
||||||
|
|
||||||
source_hook "emergency"
|
|
||||||
while read -r _tty rest; do
|
|
||||||
(
|
|
||||||
echo
|
|
||||||
echo
|
|
||||||
echo 'Entering kdump emergency mode.'
|
|
||||||
echo 'Type "journalctl" to view system logs.'
|
|
||||||
echo 'Type "rdsosreport" to generate a sosreport, you can then'
|
|
||||||
echo 'save it elsewhere and attach it to a bug report.'
|
|
||||||
echo
|
|
||||||
echo
|
|
||||||
) > "/dev/$_tty"
|
|
||||||
done < /proc/consoles
|
|
||||||
sh -i -l
|
|
||||||
/bin/rm -f -- /.console_lock
|
|
||||||
}
|
|
||||||
|
|
||||||
do_failure_action()
|
|
||||||
{
|
|
||||||
dinfo "Executing failure action $FAILURE_ACTION"
|
|
||||||
eval $FAILURE_ACTION
|
|
||||||
}
|
|
||||||
|
|
||||||
do_final_action()
|
return $_ret
|
||||||
{
|
|
||||||
dinfo "Executing final action $FINAL_ACTION"
|
|
||||||
eval $FINAL_ACTION
|
|
||||||
}
|
}
|
||||||
|
|
||||||
do_dump()
|
do_kdump_pre()
|
||||||
{
|
{
|
||||||
eval $DUMP_INSTRUCTION
|
local _ret
|
||||||
_ret=$?
|
|
||||||
|
if [ -n "$KDUMP_PRE" ]; then
|
||||||
if [ $_ret -ne 0 ]; then
|
"$KDUMP_PRE"
|
||||||
derror "saving vmcore failed"
|
_ret=$?
|
||||||
fi
|
if [ $_ret -ne 0 ]; then
|
||||||
|
derror "$KDUMP_PRE exited with $_ret status"
|
||||||
return $_ret
|
return $_ret
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# if any script fails, it just raises warning and continues
|
||||||
|
if [ -d /etc/kdump/pre.d ]; then
|
||||||
|
for file in /etc/kdump/pre.d/*; do
|
||||||
|
"$file"
|
||||||
|
_ret=$?
|
||||||
|
if [ $_ret -ne 0 ]; then
|
||||||
|
derror "$file exited with $_ret status"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
do_kdump_pre()
|
do_kdump_post()
|
||||||
{
|
{
|
||||||
if [ -n "$KDUMP_PRE" ]; then
|
local _ret
|
||||||
"$KDUMP_PRE"
|
|
||||||
_ret=$?
|
if [ -d /etc/kdump/post.d ]; then
|
||||||
if [ $_ret -ne 0 ]; then
|
for file in /etc/kdump/post.d/*; do
|
||||||
derror "$KDUMP_PRE exited with $_ret status"
|
"$file" "$1"
|
||||||
return $_ret
|
_ret=$?
|
||||||
fi
|
if [ $_ret -ne 0 ]; then
|
||||||
fi
|
derror "$file exited with $_ret status"
|
||||||
|
fi
|
||||||
# if any script fails, it just raises warning and continues
|
done
|
||||||
if [ -d /etc/kdump/pre.d ]; then
|
fi
|
||||||
for file in /etc/kdump/pre.d/*; do
|
|
||||||
"$file"
|
if [ -n "$KDUMP_POST" ]; then
|
||||||
_ret=$?
|
"$KDUMP_POST" "$1"
|
||||||
if [ $_ret -ne 0 ]; then
|
_ret=$?
|
||||||
derror "$file exited with $_ret status"
|
if [ $_ret -ne 0 ]; then
|
||||||
fi
|
derror "$KDUMP_POST exited with $_ret status"
|
||||||
done
|
fi
|
||||||
fi
|
fi
|
||||||
return 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
do_kdump_post()
|
add_dump_code()
|
||||||
{
|
{
|
||||||
if [ -d /etc/kdump/post.d ]; then
|
DUMP_INSTRUCTION=$1
|
||||||
for file in /etc/kdump/post.d/*; do
|
|
||||||
"$file" "$1"
|
|
||||||
_ret=$?
|
|
||||||
if [ $_ret -ne 0 ]; then
|
|
||||||
derror "$file exited with $_ret status"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "$KDUMP_POST" ]; then
|
|
||||||
"$KDUMP_POST" "$1"
|
|
||||||
_ret=$?
|
|
||||||
if [ $_ret -ne 0 ]; then
|
|
||||||
derror "$KDUMP_POST exited with $_ret status"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# $1: block target, eg. /dev/sda
|
|
||||||
dump_raw()
|
dump_raw()
|
||||||
{
|
{
|
||||||
[ -b "$1" ] || return 1
|
local _raw=$1
|
||||||
|
|
||||||
dinfo "saving to raw disk $1"
|
[ -b "$_raw" ] || return 1
|
||||||
|
|
||||||
if ! echo "$CORE_COLLECTOR" | grep -q makedumpfile; then
|
dinfo "saving to raw disk $_raw"
|
||||||
_src_size=$(stat --format %s /proc/vmcore)
|
|
||||||
_src_size_mb=$((_src_size / 1048576))
|
|
||||||
/kdumpscripts/monitor_dd_progress $_src_size_mb &
|
|
||||||
fi
|
|
||||||
|
|
||||||
dinfo "saving vmcore"
|
if ! $(echo -n $CORE_COLLECTOR|grep -q makedumpfile); then
|
||||||
$CORE_COLLECTOR /proc/vmcore | dd of="$1" bs=$DD_BLKSIZE >> /tmp/dd_progress_file 2>&1 || return 1
|
_src_size=`ls -l /proc/vmcore | cut -d' ' -f5`
|
||||||
sync
|
_src_size_mb=$(($_src_size / 1048576))
|
||||||
|
monitor_dd_progress $_src_size_mb &
|
||||||
|
fi
|
||||||
|
|
||||||
dinfo "saving vmcore complete"
|
dinfo "saving vmcore"
|
||||||
return 0
|
$CORE_COLLECTOR /proc/vmcore | dd of=$_raw bs=$DD_BLKSIZE >> /tmp/dd_progress_file 2>&1 || return 1
|
||||||
}
|
sync
|
||||||
|
|
||||||
# $1: ssh key file
|
dinfo "saving vmcore complete"
|
||||||
# $2: ssh address in <user>@<host> format
|
return 0
|
||||||
dump_ssh()
|
|
||||||
{
|
|
||||||
_ret=0
|
|
||||||
_ssh_opt="-i $1 -o BatchMode=yes -o StrictHostKeyChecking=yes"
|
|
||||||
_ssh_dir="$KDUMP_PATH/$HOST_IP-$DATEDIR"
|
|
||||||
if is_ipv6_address "$2"; then
|
|
||||||
_scp_address=${2%@*}@"[${2#*@}]"
|
|
||||||
else
|
|
||||||
_scp_address=$2
|
|
||||||
fi
|
|
||||||
|
|
||||||
dinfo "saving to $2:$_ssh_dir"
|
|
||||||
|
|
||||||
cat /var/lib/random-seed > /dev/urandom
|
|
||||||
ssh -q $_ssh_opt "$2" mkdir -p "$_ssh_dir" || return 1
|
|
||||||
|
|
||||||
save_vmcore_dmesg_ssh "$DMESG_COLLECTOR" "$_ssh_dir" "$_ssh_opt" "$2"
|
|
||||||
dinfo "saving vmcore"
|
|
||||||
|
|
||||||
save_opalcore_ssh "$_ssh_dir" "$_ssh_opt" "$2" "$_scp_address"
|
|
||||||
|
|
||||||
if [ "${CORE_COLLECTOR%%[[:blank:]]*}" = "scp" ]; then
|
|
||||||
scp -q $_ssh_opt /proc/vmcore "$_scp_address:$_ssh_dir/vmcore-incomplete"
|
|
||||||
_ret=$?
|
|
||||||
_vmcore="vmcore"
|
|
||||||
else
|
|
||||||
$CORE_COLLECTOR /proc/vmcore | ssh $_ssh_opt "$2" "umask 0077 && dd bs=512 of='$_ssh_dir/vmcore-incomplete'"
|
|
||||||
_ret=$?
|
|
||||||
_vmcore="vmcore.flat"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ $_ret -eq 0 ]; then
|
|
||||||
ssh $_ssh_opt "$2" "mv '$_ssh_dir/vmcore-incomplete' '$_ssh_dir/$_vmcore'"
|
|
||||||
_ret=$?
|
|
||||||
if [ $_ret -ne 0 ]; then
|
|
||||||
derror "moving vmcore failed, exitcode:$_ret"
|
|
||||||
else
|
|
||||||
dinfo "saving vmcore complete"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
derror "saving vmcore failed, exitcode:$_ret"
|
|
||||||
fi
|
|
||||||
|
|
||||||
dinfo "saving the $KDUMP_LOG_FILE to $2:$_ssh_dir/"
|
|
||||||
save_log
|
|
||||||
if ! scp -q $_ssh_opt $KDUMP_LOG_FILE "$_scp_address:$_ssh_dir/"; then
|
|
||||||
derror "saving log file failed, _exitcode:$_ret"
|
|
||||||
fi
|
|
||||||
|
|
||||||
return $_ret
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# $1: dump path
|
dump_ssh()
|
||||||
# $2: ssh opts
|
|
||||||
# $3: ssh address in <user>@<host> format
|
|
||||||
# $4: scp address, similar with ssh address but IPv6 addresses are quoted
|
|
||||||
save_opalcore_ssh()
|
|
||||||
{
|
{
|
||||||
if [ ! -f $OPALCORE ]; then
|
local _ret=0
|
||||||
# Check if we are on an old kernel that uses a different path
|
local _exitcode=0 _exitcode2=0
|
||||||
if [ -f /sys/firmware/opal/core ]; then
|
local _opt="-i $1 -o BatchMode=yes -o StrictHostKeyChecking=yes"
|
||||||
OPALCORE="/sys/firmware/opal/core"
|
local _dir="$KDUMP_PATH/$HOST_IP-$DATEDIR"
|
||||||
else
|
local _host=$2
|
||||||
return 0
|
local _vmcore="vmcore"
|
||||||
fi
|
local _ipv6_addr="" _username=""
|
||||||
fi
|
|
||||||
|
dinfo "saving to $_host:$_dir"
|
||||||
dinfo "saving opalcore:$OPALCORE to $3:$1"
|
|
||||||
|
cat /var/lib/random-seed > /dev/urandom
|
||||||
if ! scp $2 $OPALCORE "$4:$1/opalcore-incomplete"; then
|
ssh -q $_opt $_host mkdir -p $_dir || return 1
|
||||||
derror "saving opalcore failed"
|
|
||||||
return 1
|
save_vmcore_dmesg_ssh ${DMESG_COLLECTOR} ${_dir} "${_opt}" $_host
|
||||||
fi
|
save_opalcore_ssh ${_dir} "${_opt}" $_host
|
||||||
|
|
||||||
ssh $2 "$3" mv "$1/opalcore-incomplete" "$1/opalcore"
|
dinfo "saving vmcore"
|
||||||
dinfo "saving opalcore complete"
|
|
||||||
return 0
|
if is_ipv6_address "$_host"; then
|
||||||
|
_username=${_host%@*}
|
||||||
|
_ipv6_addr="[${_host#*@}]"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "${CORE_COLLECTOR%%[[:blank:]]*}" = "scp" ]; then
|
||||||
|
if [ -n "$_username" ] && [ -n "$_ipv6_addr" ]; then
|
||||||
|
scp -q $_opt /proc/vmcore "$_username@$_ipv6_addr:$_dir/vmcore-incomplete"
|
||||||
|
else
|
||||||
|
scp -q $_opt /proc/vmcore "$_host:$_dir/vmcore-incomplete"
|
||||||
|
fi
|
||||||
|
_exitcode=$?
|
||||||
|
else
|
||||||
|
$CORE_COLLECTOR /proc/vmcore | ssh $_opt $_host "umask 0077 && dd bs=512 of=$_dir/vmcore-incomplete"
|
||||||
|
_exitcode=$?
|
||||||
|
_vmcore="vmcore.flat"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $_exitcode -eq 0 ]; then
|
||||||
|
ssh $_opt $_host "mv $_dir/vmcore-incomplete $_dir/$_vmcore"
|
||||||
|
_exitcode2=$?
|
||||||
|
if [ $_exitcode2 -ne 0 ]; then
|
||||||
|
derror "moving vmcore failed, _exitcode:$_exitcode2"
|
||||||
|
else
|
||||||
|
dinfo "saving vmcore complete"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
derror "saving vmcore failed, _exitcode:$_exitcode"
|
||||||
|
fi
|
||||||
|
|
||||||
|
dinfo "saving the $KDUMP_LOG_FILE to $_host:$_dir/"
|
||||||
|
save_log
|
||||||
|
if [ -n "$_username" ] && [ -n "$_ipv6_addr" ]; then
|
||||||
|
scp -q $_opt $KDUMP_LOG_FILE "$_username@$_ipv6_addr:$_dir/"
|
||||||
|
else
|
||||||
|
scp -q $_opt $KDUMP_LOG_FILE "$_host:$_dir/"
|
||||||
|
fi
|
||||||
|
_ret=$?
|
||||||
|
if [ $_ret -ne 0 ]; then
|
||||||
|
derror "saving log file failed, _exitcode:$_ret"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $_exitcode -ne 0 ] || [ $_exitcode2 -ne 0 ];then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
# $1: dmesg collector
|
save_opalcore_ssh() {
|
||||||
# $2: dump path
|
local _path=$1
|
||||||
# $3: ssh opts
|
local _opts="$2"
|
||||||
# $4: ssh address in <user>@<host> format
|
local _location=$3
|
||||||
save_vmcore_dmesg_ssh()
|
local _user_name="" _ipv6addr=""
|
||||||
{
|
|
||||||
dinfo "saving vmcore-dmesg.txt to $4:$2"
|
ddebug "_path=$_path _opts=$_opts _location=$_location"
|
||||||
if $1 /proc/vmcore | ssh $3 "$4" "umask 0077 && dd of='$2/vmcore-dmesg-incomplete.txt'"; then
|
|
||||||
ssh -q $3 "$4" mv "$2/vmcore-dmesg-incomplete.txt" "$2/vmcore-dmesg.txt"
|
if [ ! -f $OPALCORE ]; then
|
||||||
dinfo "saving vmcore-dmesg.txt complete"
|
# Check if we are on an old kernel that uses a different path
|
||||||
else
|
if [ -f /sys/firmware/opal/core ]; then
|
||||||
derror "saving vmcore-dmesg.txt failed"
|
OPALCORE="/sys/firmware/opal/core"
|
||||||
fi
|
else
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if is_ipv6_address "$_host"; then
|
||||||
|
_user_name=${_location%@*}
|
||||||
|
_ipv6addr="[${_location#*@}]"
|
||||||
|
fi
|
||||||
|
|
||||||
|
dinfo "saving opalcore:$OPALCORE to $_location:$_path"
|
||||||
|
|
||||||
|
if [ -n "$_user_name" ] && [ -n "$_ipv6addr" ]; then
|
||||||
|
scp $_opts $OPALCORE $_user_name@$_ipv6addr:$_path/opalcore-incomplete
|
||||||
|
else
|
||||||
|
scp $_opts $OPALCORE $_location:$_path/opalcore-incomplete
|
||||||
|
fi
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
derror "saving opalcore failed"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
ssh $_opts $_location mv $_path/opalcore-incomplete $_path/opalcore
|
||||||
|
dinfo "saving opalcore complete"
|
||||||
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
wait_online_network()
|
save_vmcore_dmesg_ssh() {
|
||||||
{
|
local _dmesg_collector=$1
|
||||||
# In some cases, network may still not be ready because nm-online is called
|
local _path=$2
|
||||||
# with "-s" which means to wait for NetworkManager startup to complete, rather
|
local _opts="$3"
|
||||||
# than waiting for network connectivity specifically. Wait 10mins more for the
|
local _location=$4
|
||||||
# network to be truely ready in these cases.
|
|
||||||
_loop=0
|
dinfo "saving vmcore-dmesg.txt to $_location:$_path"
|
||||||
while [ $_loop -lt 600 ]; do
|
$_dmesg_collector /proc/vmcore | ssh $_opts $_location "umask 0077 && dd of=$_path/vmcore-dmesg-incomplete.txt"
|
||||||
sleep 1
|
_exitcode=$?
|
||||||
_loop=$((_loop + 1))
|
|
||||||
if _route=$(kdump_get_ip_route "$1" 2> /dev/null); then
|
if [ $_exitcode -eq 0 ]; then
|
||||||
printf "%s" "$_route"
|
ssh -q $_opts $_location mv $_path/vmcore-dmesg-incomplete.txt $_path/vmcore-dmesg.txt
|
||||||
return
|
dinfo "saving vmcore-dmesg.txt complete"
|
||||||
else
|
else
|
||||||
dwarn "Waiting for network to be ready (${_loop}s / 10min)"
|
derror "saving vmcore-dmesg.txt failed"
|
||||||
fi
|
fi
|
||||||
done
|
|
||||||
|
|
||||||
derror "Oops. The network still isn't ready after waiting 10mins."
|
|
||||||
exit 1
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get_host_ip()
|
get_host_ip()
|
||||||
{
|
{
|
||||||
|
local _host
|
||||||
if ! is_nfs_dump_target && ! is_ssh_dump_target; then
|
if is_nfs_dump_target || is_ssh_dump_target
|
||||||
return 0
|
then
|
||||||
fi
|
kdumpnic=$(getarg kdumpnic=)
|
||||||
|
[ -z "$kdumpnic" ] && derror "failed to get kdumpnic!" && return 1
|
||||||
_kdump_remote_ip=$(getarg kdump_remote_ip=)
|
_host=`ip addr show dev $kdumpnic|grep '[ ]*inet'`
|
||||||
|
[ $? -ne 0 ] && derror "wrong kdumpnic: $kdumpnic" && return 1
|
||||||
if [ -z "$_kdump_remote_ip" ]; then
|
_host=`echo $_host | head -n 1 | cut -d' ' -f2`
|
||||||
derror "failed to get remote IP address!"
|
_host="${_host%%/*}"
|
||||||
return 1
|
[ -z "$_host" ] && derror "wrong kdumpnic: $kdumpnic" && return 1
|
||||||
fi
|
HOST_IP=$_host
|
||||||
|
fi
|
||||||
if ! _route=$(wait_online_network "$_kdump_remote_ip"); then
|
return 0
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
_netdev=$(kdump_get_ip_route_field "$_route" "dev")
|
|
||||||
|
|
||||||
if ! _kdumpip=$(ip addr show dev "$_netdev" | grep '[ ]*inet'); then
|
|
||||||
derror "Failed to get IP of $_netdev"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
_kdumpip=$(echo "$_kdumpip" | head -n 1 | awk '{print $2}')
|
|
||||||
_kdumpip="${_kdumpip%%/*}"
|
|
||||||
HOST_IP=$_kdumpip
|
|
||||||
}
|
}
|
||||||
|
|
||||||
read_kdump_confs()
|
read_kdump_conf()
|
||||||
{
|
{
|
||||||
if [ ! -f "$KDUMP_CONFIG_FILE" ]; then
|
if [ ! -f "$KDUMP_CONF" ]; then
|
||||||
derror "$KDUMP_CONFIG_FILE not found"
|
derror "$KDUMP_CONF not found"
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
get_kdump_confs
|
get_kdump_confs
|
||||||
|
|
||||||
# rescan for add code for dump target
|
# rescan for add code for dump target
|
||||||
while read -r config_opt config_val; do
|
while read config_opt config_val;
|
||||||
# remove inline comments after the end of a directive.
|
do
|
||||||
case "$config_opt" in
|
# remove inline comments after the end of a directive.
|
||||||
dracut_args)
|
case "$config_opt" in
|
||||||
config_val=$(get_dracut_args_target "$config_val")
|
dracut_args)
|
||||||
if [ -n "$config_val" ]; then
|
config_val=$(get_dracut_args_target "$config_val")
|
||||||
config_val=$(get_mntpoint_from_target "$config_val")
|
if [ -n "$config_val" ]; then
|
||||||
DUMP_INSTRUCTION="dump_fs $config_val"
|
config_val=$(get_mntpoint_from_target "$config_val")
|
||||||
fi
|
add_dump_code "dump_fs $config_val"
|
||||||
;;
|
fi
|
||||||
ext[234] | xfs | btrfs | minix | nfs | virtiofs)
|
;;
|
||||||
config_val=$(get_mntpoint_from_target "$config_val")
|
ext[234]|xfs|btrfs|minix|nfs)
|
||||||
DUMP_INSTRUCTION="dump_fs $config_val"
|
config_val=$(get_mntpoint_from_target "$config_val")
|
||||||
;;
|
add_dump_code "dump_fs $config_val"
|
||||||
raw)
|
;;
|
||||||
DUMP_INSTRUCTION="dump_raw $config_val"
|
raw)
|
||||||
;;
|
add_dump_code "dump_raw $config_val"
|
||||||
ssh)
|
;;
|
||||||
DUMP_INSTRUCTION="dump_ssh $SSH_KEY_LOCATION $config_val"
|
ssh)
|
||||||
;;
|
add_dump_code "dump_ssh $SSH_KEY_LOCATION $config_val"
|
||||||
esac
|
;;
|
||||||
done < "$KDUMP_CONF_PARSED"
|
esac
|
||||||
|
done <<< "$(read_strip_comments $KDUMP_CONF)"
|
||||||
}
|
}
|
||||||
|
|
||||||
fence_kdump_notify()
|
fence_kdump_notify()
|
||||||
{
|
{
|
||||||
if [ -n "$FENCE_KDUMP_NODES" ]; then
|
if [ -n "$FENCE_KDUMP_NODES" ]; then
|
||||||
# shellcheck disable=SC2086
|
$FENCE_KDUMP_SEND $FENCE_KDUMP_ARGS $FENCE_KDUMP_NODES &
|
||||||
$FENCE_KDUMP_SEND $FENCE_KDUMP_ARGS $FENCE_KDUMP_NODES &
|
fi
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if [ "$1" = "--error-handler" ]; then
|
read_kdump_conf
|
||||||
get_kdump_confs
|
|
||||||
do_failure_action
|
|
||||||
do_final_action
|
|
||||||
|
|
||||||
exit $?
|
|
||||||
fi
|
|
||||||
|
|
||||||
# continue here only if we have to save dump.
|
|
||||||
if [ -f /etc/fadump.initramfs ] && [ ! -f /proc/device-tree/rtas/ibm,kernel-dump ] && [ ! -f /proc/device-tree/ibm,opal/dump/mpipl-boot ]; then
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
read_kdump_confs
|
|
||||||
fence_kdump_notify
|
fence_kdump_notify
|
||||||
|
|
||||||
if ! get_host_ip; then
|
get_host_ip
|
||||||
derror "get_host_ip exited with non-zero status!"
|
if [ $? -ne 0 ]; then
|
||||||
exit 1
|
derror "get_host_ip exited with non-zero status!"
|
||||||
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "$DUMP_INSTRUCTION" ]; then
|
if [ -z "$DUMP_INSTRUCTION" ]; then
|
||||||
DUMP_INSTRUCTION="dump_fs $NEWROOT"
|
add_dump_code "dump_fs $NEWROOT"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! do_kdump_pre; then
|
do_kdump_pre
|
||||||
derror "kdump_pre script exited with non-zero status!"
|
if [ $? -ne 0 ]; then
|
||||||
do_final_action
|
derror "kdump_pre script exited with non-zero status!"
|
||||||
# During systemd service to reboot the machine, stop this shell script running
|
do_final_action
|
||||||
exit 1
|
# During systemd service to reboot the machine, stop this shell script running
|
||||||
|
exit 1
|
||||||
fi
|
fi
|
||||||
make_trace_mem "kdump saving vmcore" '1:shortmem' '2+:mem' '3+:slab'
|
make_trace_mem "kdump saving vmcore" '1:shortmem' '2+:mem' '3+:slab'
|
||||||
do_dump
|
do_dump
|
||||||
DUMP_RETVAL=$?
|
DUMP_RETVAL=$?
|
||||||
|
|
||||||
if ! do_kdump_post $DUMP_RETVAL; then
|
do_kdump_post $DUMP_RETVAL
|
||||||
derror "kdump_post script exited with non-zero status!"
|
if [ $? -ne 0 ]; then
|
||||||
|
derror "kdump_post script exited with non-zero status!"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ $DUMP_RETVAL -ne 0 ]; then
|
if [ $DUMP_RETVAL -ne 0 ]; then
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
do_final_action
|
do_final_action
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,177 +1,248 @@
|
|||||||
#!/bin/sh
|
# These variables and functions are useful in 2nd kernel
|
||||||
#
|
|
||||||
# The code in this file will be used in initramfs environment, bash may
|
. /lib/kdump-lib.sh
|
||||||
# not be the default shell. Any code added must be POSIX compliant.
|
. /lib/kdump-logger.sh
|
||||||
|
|
||||||
DEFAULT_PATH="/var/crash/"
|
KDUMP_PATH="/var/crash"
|
||||||
KDUMP_CONFIG_FILE="/etc/kdump.conf"
|
KDUMP_LOG_FILE="/run/initramfs/kexec-dmesg.log"
|
||||||
FENCE_KDUMP_CONFIG_FILE="/etc/sysconfig/fence_kdump"
|
CORE_COLLECTOR=""
|
||||||
FENCE_KDUMP_SEND="/usr/libexec/fence_kdump_send"
|
DEFAULT_CORE_COLLECTOR="makedumpfile -l --message-level 7 -d 31"
|
||||||
LVM_CONF="/etc/lvm/lvm.conf"
|
DMESG_COLLECTOR="/sbin/vmcore-dmesg"
|
||||||
|
FAILURE_ACTION="systemctl reboot -f"
|
||||||
# Read kdump config in well formated style
|
DATEDIR=`date +%Y-%m-%d-%T`
|
||||||
kdump_read_conf()
|
HOST_IP='127.0.0.1'
|
||||||
{
|
DUMP_INSTRUCTION=""
|
||||||
# Following steps are applied in order: strip trailing comment, strip trailing space,
|
SSH_KEY_LOCATION="/root/.ssh/kdump_id_rsa"
|
||||||
# strip heading space, match non-empty line, remove duplicated spaces between conf name and value
|
KDUMP_SCRIPT_DIR="/kdumpscripts"
|
||||||
[ -f "$KDUMP_CONFIG_FILE" ] && sed -n -e "s/#.*//;s/\s*$//;s/^\s*//;s/\(\S\+\)\s*\(.*\)/\1 \2/p" $KDUMP_CONFIG_FILE
|
DD_BLKSIZE=512
|
||||||
}
|
FINAL_ACTION="systemctl reboot -f"
|
||||||
|
KDUMP_CONF="/etc/kdump.conf"
|
||||||
# Retrieves config value defined in kdump.conf
|
KDUMP_PRE=""
|
||||||
# $1: config name, sed regexp compatible
|
KDUMP_POST=""
|
||||||
kdump_get_conf_val()
|
NEWROOT="/sysroot"
|
||||||
{
|
OPALCORE="/sys/firmware/opal/mpipl/core"
|
||||||
# For lines matching "^\s*$1\s+", remove matched part (config name including space),
|
|
||||||
# remove tailing comment, space, then store in hold space. Print out the hold buffer on last line.
|
#initiate the kdump logger
|
||||||
[ -f "$KDUMP_CONFIG_FILE" ] &&
|
dlog_init
|
||||||
sed -n -e "/^\s*\($1\)\s\+/{s/^\s*\($1\)\s\+//;s/#.*//;s/\s*$//;h};\${x;p}" $KDUMP_CONFIG_FILE
|
if [ $? -ne 0 ]; then
|
||||||
}
|
echo "failed to initiate the kdump logger."
|
||||||
|
exit 1
|
||||||
is_mounted()
|
fi
|
||||||
{
|
|
||||||
findmnt -k -n "$1" > /dev/null 2>&1
|
get_kdump_confs()
|
||||||
}
|
{
|
||||||
|
local config_opt config_val
|
||||||
# $1: info type
|
|
||||||
# $2: mount source type
|
while read config_opt config_val;
|
||||||
# $3: mount source
|
do
|
||||||
# $4: extra args
|
# remove inline comments after the end of a directive.
|
||||||
get_mount_info()
|
case "$config_opt" in
|
||||||
{
|
path)
|
||||||
__kdump_mnt=$(findmnt -k -n -r -o "$1" "--$2" "$3" $4)
|
KDUMP_PATH="$config_val"
|
||||||
|
;;
|
||||||
[ -z "$__kdump_mnt" ] && [ -e "/etc/fstab" ] && __kdump_mnt=$(findmnt -s -n -r -o "$1" "--$2" "$3" $4)
|
core_collector)
|
||||||
|
[ -n "$config_val" ] && CORE_COLLECTOR="$config_val"
|
||||||
echo "$__kdump_mnt"
|
;;
|
||||||
}
|
sshkey)
|
||||||
|
if [ -f "$config_val" ]; then
|
||||||
is_ipv6_address()
|
SSH_KEY_LOCATION=$config_val
|
||||||
{
|
fi
|
||||||
echo "$1" | grep -q ":"
|
;;
|
||||||
}
|
kdump_pre)
|
||||||
|
KDUMP_PRE="$config_val"
|
||||||
is_fs_type_nfs()
|
;;
|
||||||
{
|
kdump_post)
|
||||||
[ "$1" = "nfs" ] || [ "$1" = "nfs4" ]
|
KDUMP_POST="$config_val"
|
||||||
}
|
;;
|
||||||
|
fence_kdump_args)
|
||||||
is_fs_type_virtiofs()
|
FENCE_KDUMP_ARGS="$config_val"
|
||||||
{
|
;;
|
||||||
[ "$1" = "virtiofs" ]
|
fence_kdump_nodes)
|
||||||
}
|
FENCE_KDUMP_NODES="$config_val"
|
||||||
|
;;
|
||||||
# If $1 contains dracut_args "--mount", return <filesystem type>
|
failure_action|default)
|
||||||
get_dracut_args_fstype()
|
case $config_val in
|
||||||
{
|
shell)
|
||||||
echo $1 | grep "\-\-mount" | sed "s/.*--mount .\(.*\)/\1/" | cut -d' ' -f3
|
FAILURE_ACTION="kdump_emergency_shell"
|
||||||
}
|
;;
|
||||||
|
reboot)
|
||||||
# If $1 contains dracut_args "--mount", return <device>
|
FAILURE_ACTION="systemctl reboot -f && exit"
|
||||||
get_dracut_args_target()
|
;;
|
||||||
{
|
halt)
|
||||||
echo $1 | grep "\-\-mount" | sed "s/.*--mount .\(.*\)/\1/" | cut -d' ' -f1
|
FAILURE_ACTION="halt && exit"
|
||||||
|
;;
|
||||||
|
poweroff)
|
||||||
|
FAILURE_ACTION="systemctl poweroff -f && exit"
|
||||||
|
;;
|
||||||
|
dump_to_rootfs)
|
||||||
|
FAILURE_ACTION="dump_to_rootfs"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
final_action)
|
||||||
|
case $config_val in
|
||||||
|
reboot)
|
||||||
|
FINAL_ACTION="systemctl reboot -f"
|
||||||
|
;;
|
||||||
|
halt)
|
||||||
|
FINAL_ACTION="halt"
|
||||||
|
;;
|
||||||
|
poweroff)
|
||||||
|
FINAL_ACTION="systemctl poweroff -f"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done <<< "$(read_strip_comments $KDUMP_CONF)"
|
||||||
|
|
||||||
|
if [ -z "$CORE_COLLECTOR" ]; then
|
||||||
|
CORE_COLLECTOR="$DEFAULT_CORE_COLLECTOR"
|
||||||
|
if is_ssh_dump_target || is_raw_dump_target; then
|
||||||
|
CORE_COLLECTOR="$CORE_COLLECTOR -F"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# store the kexec kernel log to a file.
|
||||||
|
save_log()
|
||||||
|
{
|
||||||
|
dmesg -T > $KDUMP_LOG_FILE
|
||||||
|
|
||||||
|
if command -v journalctl > /dev/null; then
|
||||||
|
journalctl -ab >> $KDUMP_LOG_FILE
|
||||||
|
fi
|
||||||
|
chmod 600 $KDUMP_LOG_FILE
|
||||||
|
}
|
||||||
|
|
||||||
|
# dump_fs <mount point>
|
||||||
|
dump_fs()
|
||||||
|
{
|
||||||
|
local _exitcode
|
||||||
|
local _mp=$1
|
||||||
|
ddebug "dump_fs _mp=$_mp"
|
||||||
|
|
||||||
|
if ! is_mounted "$_mp"; then
|
||||||
|
dinfo "dump path \"$_mp\" is not mounted, trying to mount..."
|
||||||
|
mount --target $_mp
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
derror "failed to dump to \"$_mp\", it's not a mount point!"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Remove -F in makedumpfile case. We don't want a flat format dump here.
|
||||||
|
[[ $CORE_COLLECTOR = *makedumpfile* ]] && CORE_COLLECTOR=`echo $CORE_COLLECTOR | sed -e "s/-F//g"`
|
||||||
|
|
||||||
|
dinfo "saving to $_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR/"
|
||||||
|
|
||||||
|
mount -o remount,rw $_mp || return 1
|
||||||
|
mkdir -p $_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR || return 1
|
||||||
|
|
||||||
|
save_vmcore_dmesg_fs ${DMESG_COLLECTOR} "$_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR/"
|
||||||
|
save_opalcore_fs "$_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR/"
|
||||||
|
|
||||||
|
dinfo "saving vmcore"
|
||||||
|
$CORE_COLLECTOR /proc/vmcore $_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR/vmcore-incomplete
|
||||||
|
_exitcode=$?
|
||||||
|
if [ $_exitcode -eq 0 ]; then
|
||||||
|
sync -f "$_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR/vmcore-incomplete"
|
||||||
|
_sync_exitcode=$?
|
||||||
|
if [ $_sync_exitcode -eq 0 ]; then
|
||||||
|
mv "$_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR/vmcore-incomplete" "$_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR/vmcore"
|
||||||
|
dinfo "saving vmcore complete"
|
||||||
|
else
|
||||||
|
derror "sync vmcore failed, _exitcode:$_sync_exitcode"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
derror "saving vmcore failed, _exitcode:$_exitcode"
|
||||||
|
fi
|
||||||
|
|
||||||
|
dinfo "saving the $KDUMP_LOG_FILE to $_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR/"
|
||||||
|
save_log
|
||||||
|
mv $KDUMP_LOG_FILE $_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR/
|
||||||
|
if [ $_exitcode -ne 0 ]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# improper kernel cmdline can cause the failure of echo, we can ignore this kind of failure
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
save_vmcore_dmesg_fs() {
|
||||||
|
local _dmesg_collector=$1
|
||||||
|
local _path=$2
|
||||||
|
|
||||||
|
dinfo "saving vmcore-dmesg.txt to ${_path}"
|
||||||
|
$_dmesg_collector /proc/vmcore > ${_path}/vmcore-dmesg-incomplete.txt
|
||||||
|
_exitcode=$?
|
||||||
|
if [ $_exitcode -eq 0 ]; then
|
||||||
|
mv ${_path}/vmcore-dmesg-incomplete.txt ${_path}/vmcore-dmesg.txt
|
||||||
|
chmod 600 ${_path}/vmcore-dmesg.txt
|
||||||
|
|
||||||
|
# Make sure file is on disk. There have been instances where later
|
||||||
|
# saving vmcore failed and system rebooted without sync and there
|
||||||
|
# was no vmcore-dmesg.txt available.
|
||||||
|
sync
|
||||||
|
dinfo "saving vmcore-dmesg.txt complete"
|
||||||
|
else
|
||||||
|
derror "saving vmcore-dmesg.txt failed"
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
get_save_path()
|
save_opalcore_fs() {
|
||||||
{
|
local _path=$1
|
||||||
__kdump_path=$(kdump_get_conf_val path)
|
|
||||||
[ -z "$__kdump_path" ] && __kdump_path=$DEFAULT_PATH
|
|
||||||
|
|
||||||
# strip the duplicated "/"
|
if [ ! -f $OPALCORE ]; then
|
||||||
echo "$__kdump_path" | tr -s /
|
# 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
|
||||||
|
|
||||||
get_root_fs_device()
|
dinfo "saving opalcore:$OPALCORE to ${_path}/opalcore"
|
||||||
{
|
cp $OPALCORE ${_path}/opalcore
|
||||||
findmnt -k -f -n -o SOURCE /
|
if [ $? -ne 0 ]; then
|
||||||
}
|
derror "saving opalcore failed"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
# Return the current underlying device of a path, ignore bind mounts
|
sync
|
||||||
get_target_from_path()
|
dinfo "saving opalcore complete"
|
||||||
{
|
return 0
|
||||||
__kdump_target=$(df "$1" 2> /dev/null | tail -1 | awk '{print $1}')
|
|
||||||
[ "$__kdump_target" = "/dev/root" ] && [ ! -e /dev/root ] && __kdump_target=$(get_root_fs_device)
|
|
||||||
echo "$__kdump_target"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get_fs_type_from_target()
|
dump_to_rootfs()
|
||||||
{
|
{
|
||||||
get_mount_info FSTYPE source "$1" -f
|
|
||||||
}
|
|
||||||
|
|
||||||
get_mntpoint_from_target()
|
dinfo "Trying to bring up rootfs device"
|
||||||
{
|
systemctl start dracut-initqueue
|
||||||
# --source is applied to ensure non-bind mount is returned
|
dinfo "Waiting for rootfs mount, will timeout after 90 seconds"
|
||||||
get_mount_info TARGET source "$1" -f
|
systemctl start sysroot.mount
|
||||||
}
|
|
||||||
|
|
||||||
is_ssh_dump_target()
|
ddebug "NEWROOT=$NEWROOT"
|
||||||
{
|
|
||||||
kdump_get_conf_val ssh | grep -q @
|
|
||||||
}
|
|
||||||
|
|
||||||
is_raw_dump_target()
|
dump_fs $NEWROOT
|
||||||
{
|
|
||||||
[ -n "$(kdump_get_conf_val raw)" ]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
is_virtiofs_dump_target()
|
kdump_emergency_shell()
|
||||||
{
|
{
|
||||||
if [ -n "$(kdump_get_conf_val virtiofs)" ]; then
|
echo "PS1=\"kdump:\\\${PWD}# \"" >/etc/profile
|
||||||
return 0
|
ddebug "Switching to dracut emergency..."
|
||||||
fi
|
/bin/dracut-emergency
|
||||||
|
rm -f /etc/profile
|
||||||
if is_fs_type_virtiofs "$(get_dracut_args_fstype "$(kdump_get_conf_val dracut_args)")"; then
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
if is_fs_type_virtiofs "$(get_fs_type_from_target "$(get_target_from_path "$(get_save_path)")")"; then
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
is_nfs_dump_target()
|
|
||||||
{
|
|
||||||
if [ -n "$(kdump_get_conf_val nfs)" ]; then
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
if is_fs_type_nfs "$(get_dracut_args_fstype "$(kdump_get_conf_val dracut_args)")"; then
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
if is_fs_type_nfs "$(get_fs_type_from_target "$(get_target_from_path "$(get_save_path)")")"; then
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
is_fs_dump_target()
|
|
||||||
{
|
|
||||||
[ -n "$(kdump_get_conf_val "ext[234]\|xfs\|btrfs\|minix\|virtiofs")" ]
|
|
||||||
}
|
|
||||||
|
|
||||||
is_lvm2_thinp_device()
|
|
||||||
{
|
|
||||||
_device_path=$1
|
|
||||||
_lvm2_thin_device=$(lvm lvs -S 'lv_layout=sparse && lv_layout=thin' \
|
|
||||||
--nosuffix --noheadings -o vg_name,lv_name "$_device_path" 2> /dev/null)
|
|
||||||
|
|
||||||
[ -n "$_lvm2_thin_device" ]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
kdump_get_ip_route()
|
do_failure_action()
|
||||||
{
|
{
|
||||||
if ! _route=$(/sbin/ip -o route get to "$1" 2>&1); then
|
dinfo "Executing failure action $FAILURE_ACTION"
|
||||||
exit 1
|
eval $FAILURE_ACTION
|
||||||
fi
|
|
||||||
echo "$_route"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
kdump_get_ip_route_field()
|
do_final_action()
|
||||||
{
|
{
|
||||||
echo "$1" | sed -n -e "s/^.*\<$2\>\s\+\(\S\+\).*$/\1/p"
|
dinfo "Executing final action $FINAL_ACTION"
|
||||||
|
eval $FINAL_ACTION
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,72 @@
|
|||||||
|
From 58553ad03187f0cf208d6c4a0dc026c6338e5edd Mon Sep 17 00:00:00 2001
|
||||||
|
From: "Daisuke Hatayama (Fujitsu)" <d.hatayama@fujitsu.com>
|
||||||
|
Date: Wed, 29 Mar 2023 12:44:10 +0000
|
||||||
|
Subject: [PATCH] [PATCH] sadump: fix failure of reading memory when 5-level
|
||||||
|
paging is enabled
|
||||||
|
|
||||||
|
makedumpfile fails as follows for memory dumps collected by sadump
|
||||||
|
when 5-level paging is enabled on the corresponding systems:
|
||||||
|
|
||||||
|
# makedumpfile -l -d 31 -x ./vmlinux ./dump.sadump dump.sadump-ld31
|
||||||
|
__vtop4_x86_64: Can't get a valid pgd.
|
||||||
|
...snip...
|
||||||
|
__vtop4_x86_64: Can't get a valid pgd.
|
||||||
|
calc_kaslr_offset: failed to calculate kaslr_offset and phys_base; default to 0
|
||||||
|
__vtop4_x86_64: Can't get a valid pgd.
|
||||||
|
readmem: Can't convert a virtual address(ffffffff82fce960) to physical address.
|
||||||
|
readmem: type_addr: 0, addr:ffffffff82fce960, size:1024
|
||||||
|
cpu_online_mask_init: Can't read cpu_online_mask memory.
|
||||||
|
|
||||||
|
makedumpfile Failed.
|
||||||
|
|
||||||
|
This is because 5-level paging support has not been done yet for
|
||||||
|
sadump; the work of the 5-level paging support was done by the commit
|
||||||
|
30a3214a7193e94c551c0cebda5918a72a35c589 (PATCH 4/4 arch/x86_64: Add
|
||||||
|
5-level paging support) but that was focused on the core part only.
|
||||||
|
|
||||||
|
Having said that, most of things has already been finished in the
|
||||||
|
commit. What needs to be newly added for sadump is just how to check
|
||||||
|
if 5-level paging is enabled for a given memory dump.
|
||||||
|
|
||||||
|
For that purpose, let's refer to CR4.LA57, bit 12 of CR4, representing
|
||||||
|
whether 5-level paging is enabled or not. We can do this because
|
||||||
|
memory dumps collected by sadump have SMRAM as note information and
|
||||||
|
they include CR4 together with the other control registers.
|
||||||
|
|
||||||
|
Signed-off-by: HATAYAMA Daisuke <d.hatayama@fujitsu.com>
|
||||||
|
---
|
||||||
|
sadump_info.c | 4 ++++
|
||||||
|
1 file changed, 4 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/makedumpfile-1.7.2/sadump_info.c b/makedumpfile-1.7.2/sadump_info.c
|
||||||
|
index adfa8dc..2c44068 100644
|
||||||
|
--- a/makedumpfile-1.7.2/sadump_info.c
|
||||||
|
+++ b/makedumpfile-1.7.2/sadump_info.c
|
||||||
|
@@ -1362,6 +1362,7 @@ static int linux_banner_sanity_check(ulong cr3)
|
||||||
|
#define PTI_USER_PGTABLE_BIT (info->page_shift)
|
||||||
|
#define PTI_USER_PGTABLE_MASK (1 << PTI_USER_PGTABLE_BIT)
|
||||||
|
#define CR3_PCID_MASK 0xFFFull
|
||||||
|
+#define CR4_LA57 (1 << 12)
|
||||||
|
int
|
||||||
|
calc_kaslr_offset(void)
|
||||||
|
{
|
||||||
|
@@ -1397,6 +1398,8 @@ calc_kaslr_offset(void)
|
||||||
|
else
|
||||||
|
cr3 = smram.Cr3 & ~CR3_PCID_MASK;
|
||||||
|
|
||||||
|
+ NUMBER(pgtable_l5_enabled) = !!(smram.Cr4 & CR4_LA57);
|
||||||
|
+
|
||||||
|
/* Convert virtual address of IDT table to physical address */
|
||||||
|
idtr_paddr = vtop4_x86_64_pagetable(idtr, cr3);
|
||||||
|
if (idtr_paddr == NOT_PADDR) {
|
||||||
|
@@ -1417,6 +1420,7 @@ calc_kaslr_offset(void)
|
||||||
|
|
||||||
|
DEBUG_MSG("sadump: idtr=%" PRIx64 "\n", idtr);
|
||||||
|
DEBUG_MSG("sadump: cr3=%" PRIx64 "\n", cr3);
|
||||||
|
+ DEBUG_MSG("sadump: cr4=%" PRIx32 "\n", smram.Cr4);
|
||||||
|
DEBUG_MSG("sadump: idtr(phys)=%" PRIx64 "\n", idtr_paddr);
|
||||||
|
DEBUG_MSG("sadump: devide_error(vmlinux)=%lx\n",
|
||||||
|
divide_error_vmlinux);
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
@ -1,39 +0,0 @@
|
|||||||
From bd0200c47c45dd420244b39ddabcecdab1fb9a8e Mon Sep 17 00:00:00 2001
|
|
||||||
From: Hari Bathini <hbathini@linux.ibm.com>
|
|
||||||
Date: Wed, 20 Sep 2023 17:29:27 +0530
|
|
||||||
Subject: [PATCH] kexec: update manpage with explicit mention of clean kexec
|
|
||||||
|
|
||||||
While the manpage does mention about kexec boot with a clean shutdown,
|
|
||||||
it is not explicit about it. Make it explicit.
|
|
||||||
|
|
||||||
Signed-off-by: Hari Bathini <hbathini@linux.ibm.com>
|
|
||||||
Signed-off-by: Simon Horman <horms@kernel.org>
|
|
||||||
---
|
|
||||||
kexec/kexec.8 | 11 +++++++++--
|
|
||||||
1 file changed, 9 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/kexec/kexec.8 b/kexec/kexec.8
|
|
||||||
index 3a344c5..179dcf2 100644
|
|
||||||
--- a/kexec/kexec.8
|
|
||||||
+++ b/kexec/kexec.8
|
|
||||||
@@ -95,8 +95,15 @@ then you would use the following command to load the kernel:
|
|
||||||
.RB "\-\-append=" "root=/dev/hda1" "\ \-\-initrd=" /boot/initrd
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
-After this kernel is loaded, it can be booted to at any time using the
|
|
||||||
-command:
|
|
||||||
+After this kernel is loaded, assuming the user-space supports kexec-based
|
|
||||||
+rebooting, it can be booted to, with a clean shutdown, using the command:
|
|
||||||
+
|
|
||||||
+.RS
|
|
||||||
+.BR reboot
|
|
||||||
+.RE
|
|
||||||
+.PP
|
|
||||||
+Alternatively, it can also be booted to, without calling shutdown(8), with
|
|
||||||
+the command:
|
|
||||||
|
|
||||||
.RS
|
|
||||||
.BR kexec \ \-e
|
|
||||||
--
|
|
||||||
2.41.0
|
|
||||||
|
|
@ -1,44 +0,0 @@
|
|||||||
From 9d9cf8de8b2ad8273861a30476a46f34cd34871a Mon Sep 17 00:00:00 2001
|
|
||||||
From: Baoquan He <bhe@redhat.com>
|
|
||||||
Date: Tue, 14 Nov 2023 23:20:30 +0800
|
|
||||||
Subject: [PATCH] kexec_file: add kexec_file flag to support debug printing
|
|
||||||
Content-type: text/plain
|
|
||||||
|
|
||||||
This add KEXEC_FILE_DEBUG to kexec_file_flags so that it can be passed
|
|
||||||
to kernel when '-d' is added with kexec_file_load interface. With that
|
|
||||||
flag enabled, kernel can enable the debugging message printing.
|
|
||||||
|
|
||||||
Signed-off-by: Baoquan He <bhe@redhat.com>
|
|
||||||
Signed-off-by: Simon Horman <horms@kernel.org>
|
|
||||||
---
|
|
||||||
kexec/kexec-syscall.h | 1 +
|
|
||||||
kexec/kexec.c | 1 +
|
|
||||||
2 files changed, 2 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/kexec/kexec-syscall.h b/kexec/kexec-syscall.h
|
|
||||||
index 2559bffb93da..73e52543e1b0 100644
|
|
||||||
--- a/kexec/kexec-syscall.h
|
|
||||||
+++ b/kexec/kexec-syscall.h
|
|
||||||
@@ -119,6 +119,7 @@ static inline long kexec_file_load(int kernel_fd, int initrd_fd,
|
|
||||||
#define KEXEC_FILE_UNLOAD 0x00000001
|
|
||||||
#define KEXEC_FILE_ON_CRASH 0x00000002
|
|
||||||
#define KEXEC_FILE_NO_INITRAMFS 0x00000004
|
|
||||||
+#define KEXEC_FILE_DEBUG 0x00000008
|
|
||||||
|
|
||||||
/* These values match the ELF architecture values.
|
|
||||||
* Unless there is a good reason that should continue to be the case.
|
|
||||||
diff --git a/kexec/kexec.c b/kexec/kexec.c
|
|
||||||
index 9d0ec46e5657..222f79e3112e 100644
|
|
||||||
--- a/kexec/kexec.c
|
|
||||||
+++ b/kexec/kexec.c
|
|
||||||
@@ -1477,6 +1477,7 @@ int main(int argc, char *argv[])
|
|
||||||
return 0;
|
|
||||||
case OPT_DEBUG:
|
|
||||||
kexec_debug = 1;
|
|
||||||
+ kexec_file_flags |= KEXEC_FILE_DEBUG;
|
|
||||||
break;
|
|
||||||
case OPT_NOIFDOWN:
|
|
||||||
skip_ifdown = 1;
|
|
||||||
--
|
|
||||||
2.41.0
|
|
||||||
|
|
@ -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,88 @@
|
|||||||
|
From 0f632fa180e5a44219ab6bbe0879c3583f8c65cf Mon Sep 17 00:00:00 2001
|
||||||
|
From: Pingfan Liu <piliu@redhat.com>
|
||||||
|
Date: Tue, 9 Nov 2021 11:24:22 +0800
|
||||||
|
Subject: [PATCH] RHEL-only
|
||||||
|
|
||||||
|
Cope with RHEL8 kernel
|
||||||
|
|
||||||
|
Signed-off-by: Pingfan Liu <piliu@redhat.com>
|
||||||
|
---
|
||||||
|
arch/arm64.c | 14 +++++++++++++-
|
||||||
|
makedumpfile.c | 2 ++
|
||||||
|
makedumpfile.h | 1 +
|
||||||
|
3 files changed, 16 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/makedumpfile-1.7.2/arch/arm64.c b/makedumpfile-1.7.2/arch/arm64.c
|
||||||
|
index 1072178..95beae6 100644
|
||||||
|
--- a/makedumpfile-1.7.2/arch/arm64.c
|
||||||
|
+++ b/makedumpfile-1.7.2/arch/arm64.c
|
||||||
|
@@ -50,6 +50,7 @@ static int va_bits;
|
||||||
|
static int vabits_actual;
|
||||||
|
static int flipped_va;
|
||||||
|
static unsigned long kimage_voffset;
|
||||||
|
+static int max_user_va_bits;
|
||||||
|
|
||||||
|
#define SZ_4K 4096
|
||||||
|
#define SZ_16K 16384
|
||||||
|
@@ -108,7 +109,7 @@ typedef unsigned long pgdval_t;
|
||||||
|
#define PGDIR_SHIFT ARM64_HW_PGTABLE_LEVEL_SHIFT(4 - (pgtable_level))
|
||||||
|
#define PGDIR_SIZE (_AC(1, UL) << PGDIR_SHIFT)
|
||||||
|
#define PGDIR_MASK (~(PGDIR_SIZE-1))
|
||||||
|
-#define PTRS_PER_PGD (1 << ((va_bits) - PGDIR_SHIFT))
|
||||||
|
+#define PTRS_PER_PGD (1 << ((max_user_va_bits) - PGDIR_SHIFT))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Section address mask and size definitions.
|
||||||
|
@@ -449,6 +450,17 @@ get_machdep_info_arm64(void)
|
||||||
|
ERRMSG("Can't determine platform config values\n");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
+ if (NUMBER(MAX_USER_VA_BITS) != NOT_FOUND_NUMBER) {
|
||||||
|
+ max_user_va_bits = NUMBER(MAX_USER_VA_BITS);
|
||||||
|
+ DEBUG_MSG("max_user_va_bits : %d (vmcoreinfo)\n",
|
||||||
|
+ max_user_va_bits);
|
||||||
|
+ }
|
||||||
|
+ if (!max_user_va_bits) {
|
||||||
|
+ max_user_va_bits = va_bits;
|
||||||
|
+ DEBUG_MSG("max_user_va_bits : %d (default = va_bits)\n",
|
||||||
|
+ max_user_va_bits);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
|
||||||
|
kimage_voffset = NUMBER(kimage_voffset);
|
||||||
|
info->section_size_bits = SECTIONS_SIZE_BITS;
|
||||||
|
diff --git a/makedumpfile-1.7.2/makedumpfile.c b/makedumpfile-1.7.2/makedumpfile.c
|
||||||
|
index 3ad4443..018ea4c 100644
|
||||||
|
--- a/makedumpfile-1.7.2/makedumpfile.c
|
||||||
|
+++ b/makedumpfile-1.7.2/makedumpfile.c
|
||||||
|
@@ -2417,6 +2417,7 @@ write_vmcoreinfo_data(void)
|
||||||
|
|
||||||
|
WRITE_NUMBER("HUGETLB_PAGE_DTOR", HUGETLB_PAGE_DTOR);
|
||||||
|
#ifdef __aarch64__
|
||||||
|
+ WRITE_NUMBER("MAX_USER_VA_BITS", MAX_USER_VA_BITS);
|
||||||
|
WRITE_NUMBER("VA_BITS", VA_BITS);
|
||||||
|
/* WRITE_NUMBER("TCR_EL1_T1SZ", TCR_EL1_T1SZ); should not exists */
|
||||||
|
WRITE_NUMBER_UNSIGNED("PHYS_OFFSET", PHYS_OFFSET);
|
||||||
|
@@ -2863,6 +2864,7 @@ read_vmcoreinfo(void)
|
||||||
|
READ_NUMBER("phys_base", phys_base);
|
||||||
|
READ_NUMBER("KERNEL_IMAGE_SIZE", KERNEL_IMAGE_SIZE);
|
||||||
|
#ifdef __aarch64__
|
||||||
|
+ READ_NUMBER("MAX_USER_VA_BITS", MAX_USER_VA_BITS);
|
||||||
|
READ_NUMBER("VA_BITS", VA_BITS);
|
||||||
|
READ_NUMBER("TCR_EL1_T1SZ", TCR_EL1_T1SZ);
|
||||||
|
READ_NUMBER_UNSIGNED("PHYS_OFFSET", PHYS_OFFSET);
|
||||||
|
diff --git a/makedumpfile-1.7.2/makedumpfile.h b/makedumpfile-1.7.2/makedumpfile.h
|
||||||
|
index e59239d..b6236dd 100644
|
||||||
|
--- a/makedumpfile-1.7.2/makedumpfile.h
|
||||||
|
+++ b/makedumpfile-1.7.2/makedumpfile.h
|
||||||
|
@@ -2064,6 +2064,7 @@ struct number_table {
|
||||||
|
long phys_base;
|
||||||
|
long KERNEL_IMAGE_SIZE;
|
||||||
|
#ifdef __aarch64__
|
||||||
|
+ long MAX_USER_VA_BITS;
|
||||||
|
long VA_BITS;
|
||||||
|
long TCR_EL1_T1SZ;
|
||||||
|
unsigned long PHYS_OFFSET;
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in new issue