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>
This commit is contained in:
parent
0adb0f4a8c
commit
5e8c751c39
@ -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
@ -1576,6 +1576,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
|
||||
@ -1641,6 +1667,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