Skip to content

Commit 958913b

Browse files
licliucoiby
authored andcommitted
kdumpctl: update crashkernel by grub entry index instead of kernel path
When there are multiple grub entries for the same kernel, get_grub_kernel_boot_parameter() uses the first matching $_para value, which may cause inconsistent behavior in the function that calls it. Since the grub entry index is unique, the new approach is using it to update crashkernel. _get_all_kernels_from_grubby() is modified to return the grub entry index, kernel path, crashkernel and fadump value so that can provide enough information by calling grubby once. For example: 0 /boot/vmlinuz-6.12.0-102.1131_1899362502.el10.x86_64 2G-64G:256M,64G-:512M kdump 1 /boot/vmlinuz-6.12.0-55.18.2.el10_0.x86_64 2G-64G:256M,64G-:512M kdump 2 /boot/vmlinuz-6.12.0-55.18.2.el10_0.x86_64 2G-64G:256M,64G-:512M kdump Remove the get_dump_mode_by_kernel() since it is unused. This won't change the existing user experience. reset-crashkernel still accepts the --kernel=something as parameter, and all kernel paths will be converted to a list of grub entry indices by _get_all_kernels_from_grubby() — this is useful for situations when --kernel=ALL is used or there are multiple grub entries for the same kernel. Thanks to grubby's flexibility, --kernel=index also works. Signed-off-by: Lichen Liu <[email protected]>
1 parent e94ec34 commit 958913b

File tree

1 file changed

+75
-50
lines changed

1 file changed

+75
-50
lines changed

kdumpctl

Lines changed: 75 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1489,21 +1489,6 @@ get_dump_mode_by_fadump_val()
14891489
fi
14901490
}
14911491

1492-
# get dump mode of a specific kernel
1493-
# based on its fadump kernel cmdline parameter
1494-
get_dump_mode_by_kernel()
1495-
{
1496-
local _kernel_path=$1 _fadump_val _dump_mode
1497-
1498-
_fadump_val=$(get_grub_kernel_boot_parameter "$_kernel_path" fadump)
1499-
if _dump_mode=$(get_dump_mode_by_fadump_val "$_fadump_val"); then
1500-
echo -n "$_dump_mode"
1501-
else
1502-
derror "failed to get dump mode for kernel $_kernel_path"
1503-
return 1
1504-
fi
1505-
}
1506-
15071492
_filter_grubby_kernel_str()
15081493
{
15091494
local _grubby_kernel_str=$1
@@ -1527,9 +1512,9 @@ _find_kernel_path_by_release()
15271512

15281513
_update_kernel_cmdline()
15291514
{
1530-
local _kernel _param _old _new
1515+
local _grub_entry_index _param _old _new
15311516

1532-
_kernel="$1"
1517+
_grub_entry_index="$1"
15331518
_param="$2"
15341519
_old="$3"
15351520
_new="$4"
@@ -1547,9 +1532,9 @@ _update_kernel_cmdline()
15471532
fi
15481533
elif has_command grubby; then
15491534
if [[ -n $_new ]]; then
1550-
grubby --update-kernel "$_kernel" --args "$_param=$_new"
1535+
grubby --update-kernel "$_grub_entry_index" --args "$_param=$_new"
15511536
else
1552-
grubby --update-kernel "$_kernel" --remove-args "$_param"
1537+
grubby --update-kernel "$_grub_entry_index" --remove-args "$_param"
15531538
fi
15541539
else
15551540
derror "Unable to update kernel command line"
@@ -1567,20 +1552,53 @@ _valid_grubby_kernel_path()
15671552
[[ -n $1 ]] && grubby --info="$1" > /dev/null 2>&1
15681553
}
15691554

1570-
# return all the kernel paths given a grubby kernel-path
1555+
# return all the grub entries given a grubby kernel-path
15711556
#
15721557
# $1: kernel path accepted by grubby, e.g. DEFAULT, ALL,
15731558
# /boot/vmlinuz-`uname -r`
1574-
# return: kernel paths separated by space
1559+
# return: grub entry index, kernel path, crashkernel and fadump value separated by \t.
1560+
# For example:
1561+
# 0 /boot/vmlinuz-6.12.0-102.1131_1899362502.el10.x86_64 2G-64G:256M,64G-:512M kdump
1562+
# 1 /boot/vmlinuz-6.12.0-55.18.2.el10_0.x86_64 2G-64G:256M,64G-:512M kdump
1563+
# 2 /boot/vmlinuz-6.12.0-55.18.2.el10_0.x86_64 2G-64G:256M,64G-:512M kdump
15751564
_get_all_kernels_from_grubby()
15761565
{
1577-
local _kernels _line _kernel_path _grubby_kernel_path=$1
1578-
1579-
for _line in $(grubby --info "$_grubby_kernel_path" | grep "^kernel="); do
1580-
_kernel_path=$(_filter_grubby_kernel_str "$_line")
1581-
_kernels="$_kernels $_kernel_path"
1582-
done
1583-
echo -n "$_kernels"
1566+
local _grubby_kernel_path=$1
1567+
1568+
grubby --info "$_grubby_kernel_path" |
1569+
awk -F'=' '
1570+
BEGIN { OFS = "\t" }
1571+
1572+
/^index=/ {
1573+
if (knl) {
1574+
print idx, knl, crash, kdump
1575+
}
1576+
idx = $2
1577+
knl = ""
1578+
crash = ""
1579+
kdump = ""
1580+
}
1581+
1582+
/^kernel=/ {
1583+
knl = $2
1584+
gsub(/"/, "", knl)
1585+
}
1586+
1587+
/^args=/ {
1588+
if (match($0, /crashkernel=([^ "]+)/, arr_crash)) {
1589+
crash = arr_crash[1]
1590+
}
1591+
if (match($0, /fadump=([^ "]+)/, arr_fadump)) {
1592+
kdump = arr_fadump[1]
1593+
}
1594+
}
1595+
1596+
END {
1597+
if (knl) {
1598+
print idx, knl, crash, kdump
1599+
}
1600+
}
1601+
'
15841602
}
15851603

15861604
check_mem_requirement()
@@ -1602,7 +1620,7 @@ check_mem_requirement()
16021620

16031621
reset_crashkernel()
16041622
{
1605-
local _opt _val _reboot _grubby_kernel_path _kernel _kernels
1623+
local _opt _val _reboot _grubby_kernel_path _grub_entries _grub_entry_index
16061624
local _dump_mode
16071625
local _has_changed _needs_reboot
16081626
local _old_ck _new_ck
@@ -1663,31 +1681,29 @@ reset_crashkernel()
16631681
# - use current running kernel
16641682
if [[ -z $_grubby_kernel_path ]]; then
16651683
[[ -n $KDUMP_KERNELVER ]] || KDUMP_KERNELVER=$(uname -r)
1666-
if ! _kernels=$(_find_kernel_path_by_release "$KDUMP_KERNELVER"); then
1684+
if ! _grubby_kernel_path=$(_find_kernel_path_by_release "$KDUMP_KERNELVER"); then
16671685
derror "no kernel for version $KDUMP_KERNELVER found"
16681686
exit 1
16691687
fi
1670-
else
1671-
_kernels=$(_get_all_kernels_from_grubby "$_grubby_kernel_path")
16721688
fi
1689+
_grub_entries=$(_get_all_kernels_from_grubby "$_grubby_kernel_path")
16731690

1674-
for _kernel in $_kernels; do
1691+
while IFS=$'\t' read -r _grub_entry_index _kernel _old_ck _old_fadump; do
16751692
_has_changed=""
16761693
if [[ $(uname -m) == ppc64le ]]; then
16771694
if [[ -n $_opt_fadump ]]; then
16781695
_new_ck=$(kdump_get_arch_recommend_crashkernel "$_dump_mode")
1679-
_old_fadump=$(get_grub_kernel_boot_parameter "$_kernel" fadump)
16801696
_new_fadump="$_opt_fadump"
16811697
[[ $_new_fadump == off ]] && _new_fadump=""
1682-
if _update_kernel_cmdline "$_kernel" fadump "$_old_fadump" "$_new_fadump"; then
1698+
if _update_kernel_cmdline "$_grub_entry_index" fadump "$_old_fadump" "$_new_fadump"; then
16831699
if [[ -n $_new_fadump ]]; then
16841700
_has_changed="Updated fadump=$_new_fadump"
16851701
else
16861702
_has_changed="Removed fadump"
16871703
fi
16881704
fi
16891705
else
1690-
if ! _dump_mode="$(get_dump_mode_by_kernel "$_kernel")"; then
1706+
if ! _dump_mode="$(get_dump_mode_by_fadump_val "$_old_fadump")"; then
16911707
exit 1
16921708
fi
16931709
_new_ck=$(kdump_get_arch_recommend_crashkernel "$_dump_mode")
@@ -1696,16 +1712,15 @@ reset_crashkernel()
16961712
_new_ck=$(kdump_get_arch_recommend_crashkernel kdump)
16971713
fi
16981714

1699-
_old_ck=$(get_grub_kernel_boot_parameter "$_kernel" crashkernel)
1700-
if _update_kernel_cmdline "$_kernel" crashkernel "$_old_ck" "$_new_ck"; then
1715+
if _update_kernel_cmdline "$_grub_entry_index" crashkernel "$_old_ck" "$_new_ck"; then
17011716
_has_changed="Updated crashkernel=$_new_ck"
17021717
fi
17031718
if [[ -n $_has_changed ]]; then
17041719
check_mem_requirement "$_dump_mode"
17051720
_needs_reboot=1
1706-
dwarn "$_has_changed for kernel=$_kernel. Please reboot the system for the change to take effect."
1721+
dwarn "$_has_changed for kernel=$_kernel, grub entry index=$_grub_entry_index. Please reboot the system for the change to take effect."
17071722
fi
1708-
done
1723+
done <<< "$_grub_entries"
17091724

17101725
if [[ $_reboot == yes && $_needs_reboot == 1 ]]; then
17111726
systemctl reboot
@@ -1722,20 +1737,28 @@ _is_bootloader_installed()
17221737
fi
17231738
}
17241739

1740+
# update a grub entry's "crashkernel=" parameter.
1741+
# $1: index of the grub entry.
1742+
# $2: kernel path
1743+
# $3: old crashkernel
1744+
# $4: old fadump value
17251745
_update_crashkernel()
17261746
{
1727-
local _kernel _kver _dump_mode _msg
1747+
local _grub_entry_index _kernel _kver _old_fadump _dump_mode _msg
17281748
local _old_ck _new_ck
17291749

1730-
_kernel=$1
1731-
if ! _dump_mode=$(get_dump_mode_by_kernel "$_kernel"); then
1750+
_grub_entry_index=$1
1751+
_kernel=$2
1752+
_old_ck=$3
1753+
_old_fadump=$4
1754+
1755+
if ! _dump_mode=$(get_dump_mode_by_fadump_val "$_old_fadump"); then
17321756
exit 1
17331757
fi
1734-
_old_ck=$(get_grub_kernel_boot_parameter "$_kernel" crashkernel)
17351758
_kver=$(parse_kver_from_path "$_kernel")
17361759
# The second argument is for the case of aarch64, where installing a 64k variant on a 4k kernel, or vice versa
17371760
_new_ck=$(kdump_get_arch_recommend_crashkernel "$_dump_mode" "$_kver")
1738-
if _update_kernel_cmdline "$_kernel" crashkernel "$_old_ck" "$_new_ck"; then
1761+
if _update_kernel_cmdline "$_grub_entry_index" crashkernel "$_old_ck" "$_new_ck"; then
17391762
_msg="For kernel=$_kernel, crashkernel=$_new_ck now. Please reboot the system for the change to take effect."
17401763
_msg+=" Note if you don't want kdump-utils to manage the crashkernel kernel parameter, please set auto_reset_crashkernel=no in /etc/kdump.conf."
17411764
dinfo "$_msg"
@@ -1745,14 +1768,14 @@ _update_crashkernel()
17451768
# shellcheck disable=SC2154 # false positive when dereferencing an array
17461769
reset_crashkernel_after_update()
17471770
{
1748-
local _kernel
1771+
local _grub_entry_index _kernel _old_ck _old_fadump
17491772

17501773
if ! _is_bootloader_installed; then
17511774
return
17521775
fi
17531776

1754-
for _kernel in $(_get_all_kernels_from_grubby ALL); do
1755-
_update_crashkernel "$_kernel"
1777+
_get_all_kernels_from_grubby ALL | while IFS=$'\t' read -r _grub_entry_index _kernel _old_ck _old_fadump; do
1778+
_update_crashkernel "$_grub_entry_index" "$_kernel" "$_old_ck" "$_old_fadump"
17561779
done
17571780
}
17581781

@@ -1777,7 +1800,7 @@ _is_osbuild()
17771800

17781801
reset_crashkernel_for_installed_kernel()
17791802
{
1780-
local _installed_kernel
1803+
local _installed_kernel _grub_entry_index _kernel _old_ck _old_fadump
17811804

17821805
# During package install, only try to reset crashkernel for osbuild
17831806
# thus to avoid calling grubby when installing os via anaconda
@@ -1796,7 +1819,9 @@ reset_crashkernel_for_installed_kernel()
17961819
return
17971820
fi
17981821

1799-
_update_crashkernel "$_installed_kernel"
1822+
_get_all_kernels_from_grubby "$_installed_kernel" | while IFS=$'\t' read -r _grub_entry_index _kernel _old_ck _old_fadump; do
1823+
_update_crashkernel "$_grub_entry_index" "$_kernel" "$_old_ck" "$_old_fadump"
1824+
done
18001825
}
18011826

18021827
_should_reset_crashkernel()

0 commit comments

Comments
 (0)