Kairui Song 93ba58
#!/usr/bin/bash
Kairui Song 93ba58
Kairui Song 93ba58
COMMAND="$1"
Kairui Song 93ba58
KERNEL_VERSION="$2"
Kairui Song 93ba58
KDUMP_INITRD_DIR_ABS="$3"
Kairui Song 93ba58
KERNEL_IMAGE="$4"
Kairui Song 93ba58
Kairui Song 93ba58
grub_etc_default="/etc/default/grub"
Kairui Song 93ba58
Kairui Song 93ba58
ver_lt() {
Kairui Song 93ba58
	[[ "$(echo -e "$1\n$2" | sort -V)" == $1$'\n'* ]] && [[ $1 != "$2" ]]
Kairui Song 93ba58
}
Kairui Song 93ba58
Kairui Song 93ba58
# Read crashkernel= value in /etc/default/grub
Kairui Song 93ba58
get_grub_etc_ck() {
Kairui Song 93ba58
	[[ -e $grub_etc_default ]] && \
Kairui Song 93ba58
	sed -n -e "s/^GRUB_CMDLINE_LINUX=.*\(crashkernel=[^\ \"]*\)[\ \"].*$/\1/p" $grub_etc_default
Kairui Song 93ba58
}
Kairui Song 93ba58
Kairui Song 93ba58
# Read crashkernel.default value of specified kernel
Kairui Song 93ba58
get_ck_default() {
Kairui Song 93ba58
	ck_file="/usr/lib/modules/$1/crashkernel.default"
Kairui Song 93ba58
	[[ -f "$ck_file" ]] && cat "$ck_file"
Kairui Song 93ba58
}
Kairui Song 93ba58
Kairui Song 93ba58
# Iterate installed kernels, find the kernel with the highest version that has a
Kairui Song 93ba58
# valid crashkernel.default file, exclude current installing/removing kernel
Kairui Song 93ba58
#
Kairui Song 93ba58
# $1: a string representing a crashkernel= cmdline. If given, will also check the
Kairui Song 93ba58
# content of crashkernel.default, only crashkernel.default with the same value will match
Kairui Song 93ba58
get_highest_ck_default_kver() {
Kairui Song 93ba58
	for kernel in $(find /usr/lib/modules -maxdepth 1 -mindepth 1 -printf "%f\n" | sort --version-sort -r); do
Kairui Song 93ba58
		[[ $kernel == "$KERNEL_VERSION" ]] && continue
Kairui Song 93ba58
		[[ -s "/usr/lib/modules/$kernel/crashkernel.default" ]] || continue
Kairui Song 93ba58
Kairui Song 93ba58
		echo "$kernel"
Kairui Song 93ba58
		return 0
Kairui Song 93ba58
	done
Kairui Song 93ba58
Kairui Song 93ba58
	return 1
Kairui Song 93ba58
}
Kairui Song 93ba58
Kairui Song 93ba58
set_grub_ck() {
Kairui Song 93ba58
	sed -i -e "s/^\(GRUB_CMDLINE_LINUX=.*\)crashkernel=[^\ \"]*\([\ \"].*\)$/\1$1\2/" "$grub_etc_default"
Kairui Song 93ba58
}
Kairui Song 93ba58
Kairui Song 93ba58
# Set specified kernel's crashkernel cmdline value
Kairui Song 93ba58
set_kernel_ck() {
Kairui Song 93ba58
	kernel=$1
Kairui Song 93ba58
	ck_cmdline=$2
Kairui Song 93ba58
Kairui Song 93ba58
	entry=$(grubby --info ALL | grep "^kernel=.*$kernel")
Kairui Song 93ba58
	entry=${entry#kernel=}
Kairui Song 93ba58
	entry=${entry#\"}
Kairui Song 93ba58
	entry=${entry%\"}
Kairui Song 93ba58
Kairui Song 93ba58
	if [[ -z "$entry" ]]; then
Kairui Song 93ba58
		echo "$0: failed to find boot entry for kernel $kernel"
Kairui Song 93ba58
		return 1
Kairui Song 93ba58
	fi
Kairui Song 93ba58
Kairui Song 93ba58
	[[ -f /etc/zipl.conf ]] && zipl_arg="--zipl"
Kairui Song 93ba58
	grubby --args "$ck_cmdline" --update-kernel "$entry" $zipl_arg
b256e1
	[[ $zipl_arg ]] && zipl > /dev/null ||:
Kairui Song 93ba58
}
Kairui Song 93ba58
Kairui Song 93ba58
case "$COMMAND" in
Kairui Song 93ba58
add)
Kairui Song 93ba58
	# - If current boot kernel is using default crashkernel value, update
Kairui Song 93ba58
	#   installing kernel's crashkernel value to its default value,
Kairui Song 93ba58
	# - If intalling a higher version kernel, and /etc/default/grub's
Kairui Song 93ba58
	#   crashkernel value is using default value, update it to installing
Kairui Song 93ba58
	#   kernel's default value.
Kairui Song 93ba58
	inst_ck_default=$(get_ck_default "$KERNEL_VERSION")
Kairui Song 93ba58
	# If installing kernel doesn't have crashkernel.default, just exit.
Kairui Song 93ba58
	[[ -z "$inst_ck_default" ]] && exit 0
Kairui Song 93ba58
Kairui Song 93ba58
	boot_kernel=$(uname -r)
Kairui Song 93ba58
	boot_ck_cmdline=$(sed -n -e "s/^.*\(crashkernel=\S*\).*$/\1/p" /proc/cmdline)
Kairui Song 93ba58
	highest_ck_default_kver=$(get_highest_ck_default_kver)
Kairui Song 93ba58
	highest_ck_default=$(get_ck_default "$highest_ck_default_kver")
Kairui Song 93ba58
Kairui Song 93ba58
	# Try update /etc/default/grub if present, else grub2-mkconfig could
Kairui Song 93ba58
	# override crashkernel value.
Kairui Song 93ba58
	grub_etc_ck=$(get_grub_etc_ck)
Kairui Song 93ba58
	if [[ -n "$grub_etc_ck" ]]; then
Kairui Song 93ba58
		if [[ -z "$highest_ck_default_kver" ]]; then
Kairui Song 93ba58
			# None of installed kernel have a crashkernel.default,
Kairui Song 93ba58
			# check for 'crashkernel=auto' in case of legacy kernel
Kairui Song 93ba58
			[[ "$grub_etc_ck" == "crashkernel=auto" ]] && \
Kairui Song 93ba58
				set_grub_ck "$inst_ck_default"
Kairui Song 93ba58
		else
Kairui Song 93ba58
			# There is a valid crashkernel.default, check if installing kernel
Kairui Song 93ba58
			# have a higher version and grub config is using default value
Kairui Song 93ba58
			ver_lt "$highest_ck_default_kver" "$KERNEL_VERSION" && \
Kairui Song 93ba58
				[[ "$grub_etc_ck" == "$highest_ck_default" ]] && \
Kairui Song 93ba58
				[[ "$grub_etc_ck" != "$inst_ck_default" ]] && \
Kairui Song 93ba58
				set_grub_ck "$inst_ck_default"
Kairui Song 93ba58
		fi
Kairui Song 93ba58
	fi
Kairui Song 93ba58
Kairui Song 93ba58
	# Exit if crashkernel is not used in current cmdline
Kairui Song 93ba58
	[[ -z $boot_ck_cmdline ]] && exit 0
Kairui Song 93ba58
Kairui Song 93ba58
	# Get current boot kernel's default value
Kairui Song 93ba58
	boot_ck_default=$(get_ck_default "$boot_kernel")
Kairui Song 93ba58
	if [[ $boot_ck_cmdline == "crashkernel=auto" ]]; then
Kairui Song 93ba58
		# Legacy RHEL kernel defaults to "auto"
Kairui Song 93ba58
		boot_ck_default="$boot_ck_cmdline"
Kairui Song 93ba58
	fi
Kairui Song 93ba58
Kairui Song 93ba58
	# If boot kernel doesn't have a crashkernel.default, check
Kairui Song 93ba58
	# if it's using any installed kernel's crashkernel.default
Kairui Song 93ba58
	if [[ -z $boot_ck_default ]]; then
Kairui Song 93ba58
		[[ $(get_highest_ck_default_kver "$boot_ck_cmdline") ]] && boot_ck_default="$boot_ck_cmdline"
Kairui Song 93ba58
	fi
Kairui Song 93ba58
Kairui Song 93ba58
	# If boot kernel is using a default crashkernel, update
Kairui Song 93ba58
	# installing kernel's crashkernel to new default value
Kairui Song 93ba58
	if [[ "$boot_ck_cmdline" != "$inst_ck_default" ]] && [[ "$boot_ck_cmdline" == "$boot_ck_default" ]]; then
Kairui Song 93ba58
		set_kernel_ck "$KERNEL_VERSION" "$inst_ck_default"
Kairui Song 93ba58
	fi
Kairui Song 93ba58
5f1282
	exit 0
5f1282
	;;
Kairui Song 93ba58
remove)
Kairui Song 93ba58
	# If grub default value is upgraded when this kernel was installed, try downgrade it
Kairui Song 93ba58
	grub_etc_ck=$(get_grub_etc_ck)
Kairui Song 93ba58
	[[ $grub_etc_ck ]] || exit 0
Kairui Song 93ba58
Kairui Song 93ba58
	removing_ck_conf=$(get_ck_default "$KERNEL_VERSION")
Kairui Song 93ba58
	[[ $removing_ck_conf ]] || exit 0
Kairui Song 93ba58
Kairui Song 93ba58
	highest_ck_default_kver=$(get_highest_ck_default_kver) || exit 0
Kairui Song 93ba58
	highest_ck_default=$(get_ck_default "$highest_ck_default_kver")
Kairui Song 93ba58
	[[ $highest_ck_default ]] || exit 0
Kairui Song 93ba58
Kairui Song 93ba58
	if ver_lt "$highest_ck_default_kver" "$KERNEL_VERSION"; then
Kairui Song 93ba58
		if [[ $grub_etc_ck == "$removing_ck_conf" ]] && [[ $grub_etc_ck != "$highest_ck_default" ]]; then
Kairui Song 93ba58
			set_grub_ck "$highest_ck_default"
Kairui Song 93ba58
		fi
Kairui Song 93ba58
	fi
5f1282
5f1282
	exit 0
Kairui Song 93ba58
	;;
Kairui Song 93ba58
esac