Hi Coiby,
On Tue, 4 Jan 2022 13:51:19 +0800
Coiby Xu <coxu(a)redhat.com> wrote:
Rewrite kdumpctl reset-crashkernel KERNEL_PATH as
kdumpctl reset-crashkernel [--fadump=[on|off|nocma]] [--kernel=path_to_kernel]
[--reboot]
This interface would reset a specific kernel to the default crashkernel value
given the kernel path. And it also supports grubby's syntax so there are the
following special cases,
- if --kernel not specified,
- use KDUMP_KERNELVER if it's defined in /etc/sysconfig/kdump
- otherwise use current running kernel, i.e. `uname -r`
- if --kernel=DEFAULT, the default boot kernel is chosen
- if --kernel=ALL, all kernels would have its crashkernel reset to the
default value and the /etc/default/grub is updated as well
--fadump=[on|off|nocma] toggles fadump on/off for the kernel provided
in KERNEL_PATH. If --fadump is omitted, the dump mode is determined by
parsing the kernel command line for the kernel(s) to update.
CoreOS/Atomic/Silverblue needs to be treated as a special case because,
- "rpm-ostree kargs" is used to manage kernel command line parameters
so --kernel doesn't make sense and there is no need to find current
running kernel
- "rpm-ostree kargs" itself would prompt the user to reboot the system
after modify the kernel command line parameter
- POWER is not supported so we can assume the dump mode is always kdump
This interface will also be called by kexec-tools RPM scriptlets [1]
to reset crashkernel.
Note the support of crashkenrel.default is dropped.
[1]
https://docs.fedoraproject.org/en-US/packaging-guidelines/Scriptlets/
Reviewed-by: Pingfan Liu <piliu(a)redhat.com>
Signed-off-by: Coiby Xu <coxu(a)redhat.com>
---
kdumpctl | 201 +++++++++++++++++++++++++++++++++++++++++++++++------
kdumpctl.8 | 19 +++--
2 files changed, 191 insertions(+), 29 deletions(-)
diff --git a/kdumpctl b/kdumpctl
index dd87693..1518e5c 100755
--- a/kdumpctl
+++ b/kdumpctl
@@ -1355,38 +1355,194 @@ _get_current_running_kernel_path()
fi
}
-reset_crashkernel()
+_update_grub()
{
- local kernel=$1 entry crashkernel_default
- local grub_etc_default="/etc/default/grub"
+ local _kernel_path=$1 _crashkernel=$2 _dump_mode=$3 _fadump_val=$4
- [[ -z $kernel ]] && kernel=$(uname -r)
- crashkernel_default=$(cat "/usr/lib/modules/$kernel/crashkernel.default"
2> /dev/null)
+ if is_atomic; then
+ if rpm-ostree kargs | grep -q "crashkernel="; then
+ rpm-ostree kargs --replace="crashkernel=$_crashkernel"
+ else
+ rpm-ostree kargs --append="crashkernel=$_crashkernel"
+ fi
+ else
+ [[ -f /etc/zipl.conf ]] && zipl_arg="--zipl"
+ grubby --args "crashkernel=$_crashkernel" --update-kernel
"$_kernel_path" $zipl_arg
+ if [[ $_dump_mode == kdump ]]; then
+ grubby --remove-args="fadump" --update-kernel "$_kernel_path"
+ else
+ grubby --args="fadump=$_fadump_val" --update-kernel
"$_kernel_path"
+ fi
+ fi
+ [[ $zipl_arg ]] && zipl > /dev/null
+}
- if [[ -z $crashkernel_default ]]; then
- derror "$kernel doesn't have a crashkernel.default"
- exit 1
+_valid_grubby_kernel_path()
+{
+ [[ -n "$1" ]] && grubby --info="$1" > /dev/null
2>&1
+}
+
+_get_all_kernels_from_grubby()
+{
+ local _kernels _line _kernel_path _grubby_kernel_path=$1
+
+ for _line in $(grubby --info "$_grubby_kernel_path" | grep
"^kernel="); do
+ _kernel_path=$(_filter_grubby_kernel_str "$_line")
+ _kernels="$_kernels $_kernel_path"
+ done
+ echo -n "$_kernels"
+}
+
+GRUB_ETC_DEFAULT="/etc/default/grub"
+# modify the kernel command line parameter in default grub conf
+#
+# $1: the name of the kernel command line parameter
+# $2: new value. If empty, the parameter would be removed
+_update_kernel_cmdline_in_grub_etc_default()
+{
+ local _para=$1 _val=$2 _para_val _regex
+
+ if [[ -n $_val ]]; then
+ _para_val="$_para=$_val"
fi
+ _regex='^(GRUB_CMDLINE_LINUX=.*)([[:space:]"])'"$_para"'=[^[:space:]"]*(.*)$'
+ if grep -q -E "$_regex" "$GRUB_ETC_DEFAULT"; then
+ sed -i -E
's/'"$_regex"'/\1\2'"$_para_val"'\3/'
"$GRUB_ETC_DEFAULT"
+ elif [[ -n $_para_val ]]; then
+ # If the kernel parameter doesn't exist, put it in the first
+ sed -i -E 's/^(GRUB_CMDLINE_LINUX=")/\1'"$_para_val"'
/' "$GRUB_ETC_DEFAULT"
+ fi
+}
+
+reset_crashkernel()
+{
+ local _opt _val _dump_mode _fadump_val _reboot _grubby_kernel_path _kernel _kernels
+ local _old_crashkernel _new_crashkernel _new_dump_mode _crashkernel_changed
+ local _new_fadump_val _old_fadump_val _what_is_updated
+
+ for _opt in "$@"; do
+ case "$_opt" in
+ --fadump=*)
+ _val=${_opt#*=}
+ if _dump_mode=$(get_dump_mode_by_fadump_val $_val); then
+ _fadump_val=$_val
+ else
+ derror "failed to determine dump mode"
+ exit
+ fi
+ ;;
+ --kernel=*)
+ _val=${_opt#*=}
+ if ! _valid_grubby_kernel_path $_val; then
+ derror "Invalid $_opt, please specify a valid kernel path, ALL or
DEFAULT"
+ exit
+ fi
+ _grubby_kernel_path=$_val
+ ;;
+ --reboot)
+ _reboot=yes
+ ;;
+ *)
+ derror "$_opt not recognized"
+ exit 1
+ ;;
+ esac
+ done
+
+ # 1. CoreOS uses "rpm-ostree kargs" instead of grubby to manage kernel
command
+ # line. --kernel=ALL doesn't make sense for CoreOS.
+ # 2. CoreOS doesn't support POWER so the dump mode is always kdump.
+ # 3. "rpm-ostree kargs" would prompt the user to reboot the system after
+ # modifying the kernel command line so there is no need for kexec-tools
+ # to repeat it.
if is_atomic; then
- if rpm-ostree kargs | grep -q "crashkernel="; then
- rpm-ostree kargs --replace="crashkernel=$crashkernel_default"
- else
- rpm-ostree kargs --append="crashkernel=$crashkernel_default"
+ _old_crashkernel=$(rpm-ostree kargs | sed -n -E
's/.*(^|\s)crashkernel=(\S*).*/\2/p')
+ _new_dump_mode=kdump
+ _new_crashkernel=$(kdump_get_arch_recommend_crashkernel "$_new_dump_mode")
+ if [[ $_old_crashkernel != "$_new_crashkernel" ]]; then
+ _update_grub "" "$_new_crashkernel" "$_new_dump_mode"
""
+ if [[ $_reboot == yes ]]; then
+ systemctl reboot
+ fi
fi
+ return
+ fi
+
+ # For non-ppc64le systems, the dump mode is always kdump since only ppc64le
+ # has FADump.
+ if [[ -z $_dump_mode && $(uname -m) != ppc64le ]]; then
+ _dump_mode=kdump
+ _fadump_val=off
+ fi
I still think that this could be cleaned up but I don't have a better
suggestion at the moment. So lets get it merged. We can still clean it
up later.
My main problem is that $dump_mode has two different meanings
1) if [[ -n $dump_mode ]] the actual dump mode, i.e. kdump or fadump
2) if [[ -z $dump_mode ]] a flag that no --fadump option was provided
on ppc and thus that the dump mode and fadump value needs to be read
from the config file.
At least for me that is quite confusing. But as said I don't have a
better suggestion.
[...]
diff --git a/kdumpctl.8 b/kdumpctl.8
index 74be062..f948709 100644
--- a/kdumpctl.8
+++ b/kdumpctl.8
@@ -50,14 +50,19 @@ Estimate a suitable crashkernel value for current machine. This is a
best-effort estimate. It will print a recommanded crashkernel value
based on current kdump setup, and list some details of memory usage.
.TP
-.I reset-crashkernel [KERNEL]
-Reset crashkernel value to default value. kdumpctl will try to read
-from /usr/lib/modules/<KERNEL>/crashkernel.default and reset specified
-kernel's crashkernel cmdline value. If no kernel is
-specified, will reset current running kernel's crashkernel value.
-If /usr/lib/modules/<KERNEL>/crashkernel.default doesn't exist, will
-simply exit return 1.
+.I reset-crashkernel [--kernel=path_to_kernel] [--reboot]
+Reset crashkernel to default value recommended by kexec-tools. If no kernel
+is specified, will reset KDUMP_KERNELVER if it's defined in /etc/sysconfig/kdump
trailing white space
+or current running kernel's crashkernel value if KDUMP_KERNELVER
is empty. You can
+also specify --kernel=ALL and --kernel=DEFAULT which have the same meaning as
+grubby's kernel-path=ALL and kernel-path=DEFAULT. ppc64le supports FADump and
+supports an additonal [--fadump=[on|off|nocma]] parameter to toggle FADump
+on/off.
trailing white space
Thanks
Philipp
+Note: The memory requirements for kdump varies heavily depending on the
+used hardware and system configuration. Thus the recommended
+crashkernel might not work for your specific setup. Please test if
+kdump works after resetting the crashkernel value.
.SH "SEE ALSO"
.BR kdump.conf (5),