Add a new hook: 92-crashkernel.install

To track and manage kernel's crashkernel usage by kernel version,
each kernel package will include a crashkernel.default containing the
default `crashkernel=` value of that kernel. So we can use a hook to
update the kernel cmdline of new installed kernel accordingly.

Put it after all other grub boot loader setup hooks, so it can simply
call grubby to modify the kernel cmdline.

Signed-off-by: Kairui Song <kasong@redhat.com>
Acked-by: Baoquan He <bhe@redhat.com>
This commit is contained in:
Kairui Song 2021-06-10 13:06:23 +08:00
parent 86130ec10f
commit 6463641935
2 changed files with 147 additions and 0 deletions

143
92-crashkernel.install Executable file
View File

@ -0,0 +1,143 @@
#!/usr/bin/bash
COMMAND="$1"
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
;;
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
;;
esac

View File

@ -40,6 +40,7 @@ Source29: kdump.sysconfig.aarch64
Source30: 60-kdump.install
Source31: kdump-logger.sh
Source32: mkfadumprd
Source33: 92-crashkernel.install
#######################################
# These are sources for mkdumpramfs
@ -66,6 +67,7 @@ Requires: dracut >= 050
Requires: dracut-network >= 050
Requires: dracut-squash >= 050
Requires: ethtool
Requires: grubby
BuildRequires: make
BuildRequires: zlib-devel elfutils-devel glib2-devel bzip2-devel ncurses-devel bison flex lzo-devel snappy-devel
BuildRequires: pkgconfig intltool gettext
@ -210,6 +212,7 @@ install -m 644 %{SOURCE15} $RPM_BUILD_ROOT%{_mandir}/man5/kdump.conf.5
install -m 644 %{SOURCE16} $RPM_BUILD_ROOT%{_unitdir}/kdump.service
install -m 755 -D %{SOURCE22} $RPM_BUILD_ROOT%{_prefix}/lib/systemd/system-generators/kdump-dep-generator.sh
install -m 755 -D %{SOURCE30} $RPM_BUILD_ROOT%{_prefix}/lib/kernel/install.d/60-kdump.install
install -m 755 -D %{SOURCE33} $RPM_BUILD_ROOT%{_prefix}/lib/kernel/install.d/92-crashkernel.install
%ifarch %{ix86} x86_64 ppc64 s390x ppc64le aarch64
install -m 755 makedumpfile-%{mkdf_ver}/makedumpfile $RPM_BUILD_ROOT/usr/sbin/makedumpfile
@ -360,6 +363,7 @@ done
%{_unitdir}/kdump.service
%{_prefix}/lib/systemd/system-generators/kdump-dep-generator.sh
%{_prefix}/lib/kernel/install.d/60-kdump.install
%{_prefix}/lib/kernel/install.d/92-crashkernel.install
%doc News
%license COPYING
%doc TODO