reset kernel crashkernel for the special case where the kernel is updated right after kexec-tools
Resolves: bz1895258
Upstream: Fedora
Conflict: None
commit 5e8c751c39
Author: Coiby Xu <coxu@redhat.com>
Date: Thu Dec 2 17:19:50 2021 +0800
reset kernel crashkernel for the special case where the kernel is updated right after kexec-tools
When kexec-tools updates the default crashkernel value, it will try to
reset the existing installed kernels including the currently running
kernel. So the running kernel could have different kernel cmdline
parameters from /proc/cmdline. When installing a kernel after updating
kexec-tools, /usr/lib/kernel/install.d/20-grub.install would be called
by kernel-install [1] which would use /proc/cmdline to set up new kernel's
cmdline. To address this special case, reset the new kernel's crashkernel
and fadump value to the value that would be used by running kernel after
rebooting by the installation hook. One side effect of this commit is it
would reset the installed kernel's crashkernel even currently running kernel
don't use the default crashkernel value after rebooting. But I think this
side effect is a benefit for the user.
The implementation depends on kernel-install which run the scripts in
/usr/lib/kernel/install.d passing the following arguments,
add KERNEL-VERSION $BOOT/MACHINE-ID/KERNEL-VERSION/ KERNEL-IMAGE [INITRD-FILE ...]
An concrete example is given as follows,
add 5.11.12-300.fc34.x86_64 /boot/e986846f63134c7295458cf36300ba5b/5.11.12-300.fc34.x86_64 /lib/modules/5.11.12-300.fc34.x86_64/vmlinuz
kernel-install could be started by the kernel package's RPM scriplet [2].
As mentioned in previous commit "try to reset kernel crashkernel when
kexec-tools updates the default crashkernel value", kdumpctl has difficulty
running in RPM scriptlet fore CoreOS. But rpm-ostree ignores all kernel hooks,
there is no need to disable the kernel hook for CoreOS/Atomic/Silverblue. But a
collaboration between rpm-ostree and kexec-tools is needed [3] to take care
of this special case.
Note the crashkernel.default support is dropped.
[1] https://www.freedesktop.org/software/systemd/man/kernel-install.html
[2] https://src.fedoraproject.org/rpms/kernel/blob/rawhide/f/kernel.spec#_2680
[3] https://github.com/coreos/rpm-ostree/issues/2894
Reviewed-by: Pingfan Liu <piliu@redhat.com>
Reviewed-by: Philipp Rudo <prudo@redhat.com>
Signed-off-by: Coiby Xu <coxu@redhat.com>
Signed-off-by: Coiby Xu <coxu@redhat.com>
This commit is contained in:
parent
224984355d
commit
2589c40c4e
@ -5,142 +5,9 @@ KERNEL_VERSION="$2"
|
||||
KDUMP_INITRD_DIR_ABS="$3"
|
||||
KERNEL_IMAGE="$4"
|
||||
|
||||
grub_etc_default="/etc/default/grub"
|
||||
|
||||
ver_lt() {
|
||||
[[ "$(echo -e "$1\n$2" | sort -V)" == $1$'\n'* ]] && [[ $1 != "$2" ]]
|
||||
}
|
||||
|
||||
# Read crashkernel= value in /etc/default/grub
|
||||
get_grub_etc_ck() {
|
||||
[[ -e $grub_etc_default ]] && \
|
||||
sed -n -e "s/^GRUB_CMDLINE_LINUX=.*\(crashkernel=[^\ \"]*\)[\ \"].*$/\1/p" $grub_etc_default
|
||||
}
|
||||
|
||||
# Read crashkernel.default value of specified kernel
|
||||
get_ck_default() {
|
||||
ck_file="/usr/lib/modules/$1/crashkernel.default"
|
||||
[[ -f "$ck_file" ]] && cat "$ck_file"
|
||||
}
|
||||
|
||||
# Iterate installed kernels, find the kernel with the highest version that has a
|
||||
# valid crashkernel.default file, exclude current installing/removing kernel
|
||||
#
|
||||
# $1: a string representing a crashkernel= cmdline. If given, will also check the
|
||||
# content of crashkernel.default, only crashkernel.default with the same value will match
|
||||
get_highest_ck_default_kver() {
|
||||
for kernel in $(find /usr/lib/modules -maxdepth 1 -mindepth 1 -printf "%f\n" | sort --version-sort -r); do
|
||||
[[ $kernel == "$KERNEL_VERSION" ]] && continue
|
||||
[[ -s "/usr/lib/modules/$kernel/crashkernel.default" ]] || continue
|
||||
|
||||
echo "$kernel"
|
||||
return 0
|
||||
done
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
set_grub_ck() {
|
||||
sed -i -e "s/^\(GRUB_CMDLINE_LINUX=.*\)crashkernel=[^\ \"]*\([\ \"].*\)$/\1$1\2/" "$grub_etc_default"
|
||||
}
|
||||
|
||||
# Set specified kernel's crashkernel cmdline value
|
||||
set_kernel_ck() {
|
||||
kernel=$1
|
||||
ck_cmdline=$2
|
||||
|
||||
entry=$(grubby --info ALL | grep "^kernel=.*$kernel")
|
||||
entry=${entry#kernel=}
|
||||
entry=${entry#\"}
|
||||
entry=${entry%\"}
|
||||
|
||||
if [[ -z "$entry" ]]; then
|
||||
echo "$0: failed to find boot entry for kernel $kernel"
|
||||
return 1
|
||||
fi
|
||||
|
||||
[[ -f /etc/zipl.conf ]] && zipl_arg="--zipl"
|
||||
grubby --args "$ck_cmdline" --update-kernel "$entry" $zipl_arg
|
||||
[[ $zipl_arg ]] && zipl > /dev/null ||:
|
||||
}
|
||||
|
||||
case "$COMMAND" in
|
||||
add)
|
||||
# - If current boot kernel is using default crashkernel value, update
|
||||
# installing kernel's crashkernel value to its default value,
|
||||
# - If intalling a higher version kernel, and /etc/default/grub's
|
||||
# crashkernel value is using default value, update it to installing
|
||||
# kernel's default value.
|
||||
inst_ck_default=$(get_ck_default "$KERNEL_VERSION")
|
||||
# If installing kernel doesn't have crashkernel.default, just exit.
|
||||
[[ -z "$inst_ck_default" ]] && exit 0
|
||||
|
||||
boot_kernel=$(uname -r)
|
||||
boot_ck_cmdline=$(sed -n -e "s/^.*\(crashkernel=\S*\).*$/\1/p" /proc/cmdline)
|
||||
highest_ck_default_kver=$(get_highest_ck_default_kver)
|
||||
highest_ck_default=$(get_ck_default "$highest_ck_default_kver")
|
||||
|
||||
# Try update /etc/default/grub if present, else grub2-mkconfig could
|
||||
# override crashkernel value.
|
||||
grub_etc_ck=$(get_grub_etc_ck)
|
||||
if [[ -n "$grub_etc_ck" ]]; then
|
||||
if [[ -z "$highest_ck_default_kver" ]]; then
|
||||
# None of installed kernel have a crashkernel.default,
|
||||
# check for 'crashkernel=auto' in case of legacy kernel
|
||||
[[ "$grub_etc_ck" == "crashkernel=auto" ]] && \
|
||||
set_grub_ck "$inst_ck_default"
|
||||
else
|
||||
# There is a valid crashkernel.default, check if installing kernel
|
||||
# have a higher version and grub config is using default value
|
||||
ver_lt "$highest_ck_default_kver" "$KERNEL_VERSION" && \
|
||||
[[ "$grub_etc_ck" == "$highest_ck_default" ]] && \
|
||||
[[ "$grub_etc_ck" != "$inst_ck_default" ]] && \
|
||||
set_grub_ck "$inst_ck_default"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Exit if crashkernel is not used in current cmdline
|
||||
[[ -z $boot_ck_cmdline ]] && exit 0
|
||||
|
||||
# Get current boot kernel's default value
|
||||
boot_ck_default=$(get_ck_default "$boot_kernel")
|
||||
if [[ $boot_ck_cmdline == "crashkernel=auto" ]]; then
|
||||
# Legacy RHEL kernel defaults to "auto"
|
||||
boot_ck_default="$boot_ck_cmdline"
|
||||
fi
|
||||
|
||||
# If boot kernel doesn't have a crashkernel.default, check
|
||||
# if it's using any installed kernel's crashkernel.default
|
||||
if [[ -z $boot_ck_default ]]; then
|
||||
[[ $(get_highest_ck_default_kver "$boot_ck_cmdline") ]] && boot_ck_default="$boot_ck_cmdline"
|
||||
fi
|
||||
|
||||
# If boot kernel is using a default crashkernel, update
|
||||
# installing kernel's crashkernel to new default value
|
||||
if [[ "$boot_ck_cmdline" != "$inst_ck_default" ]] && [[ "$boot_ck_cmdline" == "$boot_ck_default" ]]; then
|
||||
set_kernel_ck "$KERNEL_VERSION" "$inst_ck_default"
|
||||
fi
|
||||
|
||||
exit 0
|
||||
;;
|
||||
remove)
|
||||
# If grub default value is upgraded when this kernel was installed, try downgrade it
|
||||
grub_etc_ck=$(get_grub_etc_ck)
|
||||
[[ $grub_etc_ck ]] || exit 0
|
||||
|
||||
removing_ck_conf=$(get_ck_default "$KERNEL_VERSION")
|
||||
[[ $removing_ck_conf ]] || exit 0
|
||||
|
||||
highest_ck_default_kver=$(get_highest_ck_default_kver) || exit 0
|
||||
highest_ck_default=$(get_ck_default "$highest_ck_default_kver")
|
||||
[[ $highest_ck_default ]] || exit 0
|
||||
|
||||
if ver_lt "$highest_ck_default_kver" "$KERNEL_VERSION"; then
|
||||
if [[ $grub_etc_ck == "$removing_ck_conf" ]] && [[ $grub_etc_ck != "$highest_ck_default" ]]; then
|
||||
set_grub_ck "$highest_ck_default"
|
||||
fi
|
||||
fi
|
||||
|
||||
kdumpctl reset-crashkernel-for-installed_kernel "$KERNEL_VERSION"
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
|
31
kdumpctl
31
kdumpctl
@ -1602,6 +1602,32 @@ reset_crashkernel_after_update()
|
||||
done
|
||||
}
|
||||
|
||||
reset_crashkernel_for_installed_kernel()
|
||||
{
|
||||
local _installed_kernel _running_kernel _crashkernel _crashkernel_running
|
||||
local _dump_mode_running _fadump_val_running
|
||||
|
||||
if ! _installed_kernel=$(_find_kernel_path_by_release "$1"); then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! _running_kernel=$(_get_current_running_kernel_path); then
|
||||
derror "Couldn't find current running kernel"
|
||||
exit
|
||||
fi
|
||||
|
||||
_crashkernel=$(get_grub_kernel_boot_parameter "$_installed_kernel" crashkernel)
|
||||
_crashkernel_running=$(get_grub_kernel_boot_parameter "$_running_kernel" crashkernel)
|
||||
_dump_mode_running=$(get_dump_mode_by_kernel "$_running_kernel")
|
||||
_fadump_val_running=$(get_grub_kernel_boot_parameter "$_kernel" fadump)
|
||||
|
||||
if [[ $_crashkernel != "$_crashkernel_running" ]]; then
|
||||
if _update_grub "$_installed_kernel" "$_crashkernel_running" "$_dump_mode_running" "$_fadump_val_running"; then
|
||||
echo "kexec-tools has reset $_installed_kernel to use the new default crashkernel value $_crashkernel_running"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
if [[ ! -f $KDUMP_CONFIG_FILE ]]; then
|
||||
derror "Error: No kdump config file found!"
|
||||
exit 1
|
||||
@ -1672,6 +1698,11 @@ main()
|
||||
reset_crashkernel_after_update
|
||||
fi
|
||||
;;
|
||||
reset-crashkernel-for-installed_kernel)
|
||||
if [[ $(kdump_get_conf_val auto_reset_crashkernel) != no ]]; then
|
||||
reset_crashkernel_for_installed_kernel "$2"
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
dinfo $"Usage: $0 {estimate|start|stop|status|restart|reload|rebuild|reset-crashkernel|propagate|showmem}"
|
||||
exit 1
|
||||
|
Loading…
Reference in New Issue
Block a user