try to reset kernel crashkernel when kexec-tools updates the default crashkernel value

kexec-tools could update the default crashkernel value.
When auto_reset_crashkernel=yes, reset kernel to new crashkernel
value in the following two cases,
 - crashkernel=auto is found in the kernel cmdline
 - the kernel crashkernel was previously set by kexec-tools i.e.
   the kernel is using old default crashkernel value

To tell if the user is using a custom value for the kernel crashkernel
or not, we assume the user would never use the default crashkernel value
as custom value. When kexec-tools gets updated,
 1. save the default crashkernel value of the older package to
    /tmp/crashkernel (for POWER system, /tmp/crashkernel_fadump is saved
    as well).
 2. If auto_reset_crashkernel=yes, iterate all installed kernels.
    For each kernel, compare its crashkernel value with the old
    default crashkernel and reset it if yes

The implementation makes use of two RPM scriptlets [2],
 - %pre is run before a package is installed so we can use it to save
   old default crashkernel value
 - %post is run after a package installed so we can use it to try to reset
   kernel crashkernel

There are several problems when running kdumpctl in the RPM scripts
for CoreOS/Atomic/Silverblue, for example, the lock can't be acquired by
kdumpctl, "rpm-ostree kargs" can't be run and etc.. So don't enable this
feature for CoreOS/Atomic/Silverblue.

Note latest shellcheck (0.8.0) gives false positives about the
associative array as of this commit. And Fedora's shellcheck is 0.7.2
and can't even correctly parse the shell code because of the associative
array.

[1] https://github.com/koalaman/shellcheck/issues/2399
[2] https://docs.fedoraproject.org/en-US/packaging-guidelines/Scriptlets/

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:
Coiby Xu 2021-12-01 15:33:13 +08:00
parent 73ced7f451
commit 0adb0f4a8c
2 changed files with 57 additions and 0 deletions

View File

@ -1546,6 +1546,36 @@ reset_crashkernel()
fi
}
# shellcheck disable=SC2154 # false positive when dereferencing an array
reset_crashkernel_after_update()
{
local _kernel _crashkernel _dump_mode _fadump_val _old_default_crashkernel _new_default_crashkernel
declare -A _crashkernel_vals
_crashkernel_vals[old_kdump]=$(cat /tmp/old_default_crashkernel 2> /dev/null)
_crashkernel_vals[old_fadump]=$(cat /tmp/old_default_crashkernel_fadump 2> /dev/null)
_crashkernel_vals[new_kdump]=$(get_default_crashkernel kdump)
_crashkernel_vals[new_fadump]=$(get_default_crashkernel fadump)
for _kernel in $(_get_all_kernels_from_grubby); do
_crashkernel=$(get_grub_kernel_boot_parameter "$_kernel" crashkernel)
if [[ $_crashkernel == auto ]]; then
reset_crashkernel "--kernel=$_kernel"
elif [[ -n $_crashkernel ]]; then
_dump_mode=$(get_dump_mode_by_kernel "$_kernel")
_old_default_crashkernel=${_crashkernel_vals[old_${_dump_mode}]}
_new_default_crashkernel=${_crashkernel_vals[new_${_dump_mode}]}
if [[ $_crashkernel == "$_old_default_crashkernel" ]] &&
[[ $_new_default_crashkernel != "$_old_default_crashkernel" ]]; then
_fadump_val=$(get_grub_kernel_boot_parameter "$_kernel" fadump)
if _update_grub "$_kernel" "$_new_default_crashkernel" "$_dump_mode" "$_fadump_val"; then
echo "For kernel=$_kernel, crashkernel=$_new_default_crashkernel now."
fi
fi
fi
done
}
if [[ ! -f $KDUMP_CONFIG_FILE ]]; then
derror "Error: No kdump config file found!"
exit 1
@ -1606,6 +1636,11 @@ main()
shift
reset_crashkernel "$@"
;;
reset-crashkernel-after-update)
if [[ $(kdump_get_conf_val auto_reset_crashkernel) != no ]]; then
reset_crashkernel_after_update
fi
;;
*)
dinfo $"Usage: $0 {estimate|start|stop|status|restart|reload|rebuild|reset-crashkernel|propagate|showmem}"
exit 1

View File

@ -258,6 +258,15 @@ chmod 755 $RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99zz-fadumpini
mkdir -p $RPM_BUILD_ROOT/%{dracutlibdir}/modules.d/
mv $RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/* $RPM_BUILD_ROOT/%{dracutlibdir}/modules.d/
%pre
# save the old default crashkernel values to /tmp/ when upgrading the package
if ! grep -q "ostree" /proc/cmdline && [ $1 == 2 ] && grep -q get-default-crashkernel /usr/bin/kdumpctl; then
kdumpctl get-default-crashkernel kdump > /tmp/old_default_crashkernel 2>/dev/null
%ifarch ppc64 ppc64le
kdumpctl get-default-crashkernel fadump > /tmp/old_default_crashkernel_fadump 2>/dev/null
%endif
fi
%post
# Initial installation
%systemd_post kdump.service
@ -291,6 +300,19 @@ then
mv /etc/sysconfig/kdump.new /etc/sysconfig/kdump
fi
# try to reset kernel crashkernel value to new default value when upgrading
# the package
if ! grep -q "ostree" /proc/cmdline && [ $1 == 2 ]; then
kdumpctl reset-crashkernel-after-update
rm /tmp/old_default_crashkernel 2>/dev/null
%ifarch ppc64 ppc64le
rm /tmp/old_default_crashkernel_fadump 2>/dev/null
%endif
# dnf would complain about the exit code not being 0. To keep it happy,
# always return 0
:
fi
%postun
%systemd_postun_with_restart kdump.service