Hi everybody,
here are a few patches before I go on Christmas vacation. I'll be back in office on Jan 9th so you don't need to hurry to review them.
Patch 3 is a little bit special as in my opinion it only highlights the problem but doesn't really fix it. For a proper fix one would need to move all functions dracut-early-kdump.sh uses from kdump-lib to kdump-lib-initramfs and make them POSIX compliant...
Thanks and see you next year Philipp
Philipp Rudo (13): kdumpctl: simplify check_failure_action_config dracut-early-kdump: fix shellcheck findings dracut-early-kdump: explicitly use bash kdumpctl: merge check_current_{kdump,fadump}_status mkfadumprd: drop unset globals from debug output kdump-lib: always specify version in is_squash_available unit tests: add tests for prepare_cmdline kdumpctl: move aws workaround to kdump-lib kdump-lib: fix prepare_cmdline kdumpctl: cleanup 'start' kdumpctl: cleanup 'stop' kdumpctl: refractor check_rebuild kdumpctl: make do_estimate more robust
.editorconfig | 2 +- dracut-early-kdump.sh | 7 +- kdump-lib.sh | 226 +++++++++++++++++--------------- kdumpctl | 287 +++++++++++++++-------------------------- mkfadumprd | 2 +- spec/kdump-lib_spec.sh | 32 +++++ 6 files changed, 266 insertions(+), 290 deletions(-) mode change 100644 => 100755 mkfadumprd
With the deprecation of the 'default' option in kdump.conf check_failure_action_config needed to track which option was used (default or failure_action). This made the function quite complex.Thus make option 'default' a true alias of 'failure_action' when parsing kdump.conf and simplify check_failure_action_config.
Do the same simplifications for check_final_action_config as both functions are basically identical.
Signed-off-by: Philipp Rudo prudo@redhat.com --- kdumpctl | 55 +++++++++++++++++-------------------------------------- 1 file changed, 17 insertions(+), 38 deletions(-)
diff --git a/kdumpctl b/kdumpctl index 3cad3dd..8a06c2e 100755 --- a/kdumpctl +++ b/kdumpctl @@ -255,7 +255,12 @@ parse_config() config_val=$DEFAULT_SSHKEY fi ;; - path | core_collector | kdump_post | kdump_pre | extra_bins | extra_modules | failure_action | default | final_action | force_rebuild | force_no_rebuild | fence_kdump_args | fence_kdump_nodes | auto_reset_crashkernel) ;; + default) + dwarn "WARNING: Option 'default' was renamed 'failure_action' and will be removed in the future." + dwarn "Please update $KDUMP_CONFIG_FILE to use option 'failure_action' instead." + _set_config failure_action "$config_val" || return 1 + ;; + path | core_collector | kdump_post | kdump_pre | extra_bins | extra_modules | failure_action | final_action | force_rebuild | force_no_rebuild | fence_kdump_args | fence_kdump_nodes | auto_reset_crashkernel) ;;
net | options | link_delay | disk_timeout | debug_mem_level | blacklist) derror "Deprecated kdump config option: $config_opt. Refer to kdump.conf manpage for alternatives." @@ -990,31 +995,12 @@ start_dump()
check_failure_action_config() { - local default_option - local failure_action - local option="failure_action" - - default_option=${OPT[default]} - failure_action=${OPT[failure_action]} - - if [[ -z $failure_action ]] && [[ -z $default_option ]]; then - return 0 - elif [[ -n $failure_action ]] && [[ -n $default_option ]]; then - derror "Cannot specify 'failure_action' and 'default' option together" - return 1 - fi - - if [[ -n $default_option ]]; then - option="default" - failure_action="$default_option" - fi - - case "$failure_action" in - reboot | halt | poweroff | shell | dump_to_rootfs) + case "${OPT[failure_action]}" in + "" | reboot | halt | poweroff | shell | dump_to_rootfs) return 0 ;; *) - dinfo $"Usage kdump.conf: $option {reboot|halt|poweroff|shell|dump_to_rootfs}" + dinfo $"Usage kdump.conf: failure_action {reboot|halt|poweroff|shell|dump_to_rootfs}" return 1 ;; esac @@ -1022,22 +1008,15 @@ check_failure_action_config()
check_final_action_config() { - local final_action - - final_action=${OPT[final_action]} - if [[ -z $final_action ]]; then + case "${OPT[final_action]}" in + "" | reboot | halt | poweroff) return 0 - else - case "$final_action" in - reboot | halt | poweroff) - return 0 - ;; - *) - dinfo $"Usage kdump.conf: final_action {reboot|halt|poweroff}" - return 1 - ;; - esac - fi + ;; + *) + dinfo $"Usage kdump.conf: final_action {reboot|halt|poweroff}" + return 1 + ;; + esac }
start()
Fix the following issues found by shellcheck
In dracut-early-kdump.sh line 9: EARLY_KDUMP_KERNELVER="" ^-------------------^ SC2034: EARLY_KDUMP_KERNELVER appears unused. Verify use (or export if used externally).
In dracut-early-kdump.sh line 61: if $KEXEC $EARLY_KEXEC_ARGS $standard_kexec_args \ ^---------------^ SC2086: Double quote to prevent globbing and word splitting.
For more information: https://www.shellcheck.net/wiki/SC2034 https://www.shellcheck.net/wiki/SC2086
Signed-off-by: Philipp Rudo prudo@redhat.com --- dracut-early-kdump.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/dracut-early-kdump.sh b/dracut-early-kdump.sh index 45ee6dc..9e55258 100755 --- a/dracut-early-kdump.sh +++ b/dracut-early-kdump.sh @@ -6,7 +6,6 @@ standard_kexec_args="-p" EARLY_KDUMP_INITRD="" EARLY_KDUMP_KERNEL="" EARLY_KDUMP_CMDLINE="" -EARLY_KDUMP_KERNELVER="" EARLY_KEXEC_ARGS=""
. /etc/sysconfig/kdump @@ -58,7 +57,7 @@ early_kdump_load() --command-line=$EARLY_KDUMP_CMDLINE --initrd=$EARLY_KDUMP_INITRD \ $EARLY_KDUMP_KERNEL"
- if $KEXEC $EARLY_KEXEC_ARGS $standard_kexec_args \ + if $KEXEC "$EARLY_KEXEC_ARGS" $standard_kexec_args \ --command-line="$EARLY_KDUMP_CMDLINE" \ --initrd=$EARLY_KDUMP_INITRD $EARLY_KDUMP_KERNEL; then dinfo "kexec: loaded early-kdump kernel"
Hi Philipp,
On Wed, Dec 21, 2022 at 04:27:14PM +0100, Philipp Rudo wrote:
Fix the following issues found by shellcheck
In dracut-early-kdump.sh line 9: EARLY_KDUMP_KERNELVER="" ^-------------------^ SC2034: EARLY_KDUMP_KERNELVER appears unused. Verify use (or export if used externally).
In dracut-early-kdump.sh line 61: if $KEXEC $EARLY_KEXEC_ARGS $standard_kexec_args \ ^---------------^ SC2086: Double quote to prevent globbing and word splitting.
For more information: https://www.shellcheck.net/wiki/SC2034 https://www.shellcheck.net/wiki/SC2086
Signed-off-by: Philipp Rudo prudo@redhat.com
dracut-early-kdump.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/dracut-early-kdump.sh b/dracut-early-kdump.sh index 45ee6dc..9e55258 100755 --- a/dracut-early-kdump.sh +++ b/dracut-early-kdump.sh @@ -6,7 +6,6 @@ standard_kexec_args="-p" EARLY_KDUMP_INITRD="" EARLY_KDUMP_KERNEL="" EARLY_KDUMP_CMDLINE="" -EARLY_KDUMP_KERNELVER="" EARLY_KEXEC_ARGS=""
. /etc/sysconfig/kdump @@ -58,7 +57,7 @@ early_kdump_load() --command-line=$EARLY_KDUMP_CMDLINE --initrd=$EARLY_KDUMP_INITRD \ $EARLY_KDUMP_KERNEL"
- if $KEXEC $EARLY_KEXEC_ARGS $standard_kexec_args \
- if $KEXEC "$EARLY_KEXEC_ARGS" $standard_kexec_args \
Since EARLY_KEXEC_ARGS could be multiple arguments, quoting it could cause a trouble for kexec. So we should simply suppress the shellcheck error instead.
--command-line="$EARLY_KDUMP_CMDLINE" \ --initrd=$EARLY_KDUMP_INITRD $EARLY_KDUMP_KERNEL; then dinfo "kexec: loaded early-kdump kernel"
-- 2.38.1 _______________________________________________ kexec mailing list -- kexec@lists.fedoraproject.org To unsubscribe send an email to kexec-leave@lists.fedoraproject.org Fedora Code of Conduct: https://docs.fedoraproject.org/en-US/project/code-of-conduct/ List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines List Archives: https://lists.fedoraproject.org/archives/list/kexec@lists.fedoraproject.org Do not reply to spam, report it: https://pagure.io/fedora-infrastructure/new_issue
On Mon, 9 Jan 2023 15:51:00 +0800 Coiby Xu coxu@redhat.com wrote:
Hi Philipp,
On Wed, Dec 21, 2022 at 04:27:14PM +0100, Philipp Rudo wrote:
Fix the following issues found by shellcheck
In dracut-early-kdump.sh line 9: EARLY_KDUMP_KERNELVER="" ^-------------------^ SC2034: EARLY_KDUMP_KERNELVER appears unused. Verify use (or export if used externally).
In dracut-early-kdump.sh line 61: if $KEXEC $EARLY_KEXEC_ARGS $standard_kexec_args \ ^---------------^ SC2086: Double quote to prevent globbing and word splitting.
For more information: https://www.shellcheck.net/wiki/SC2034 https://www.shellcheck.net/wiki/SC2086
Signed-off-by: Philipp Rudo prudo@redhat.com
dracut-early-kdump.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/dracut-early-kdump.sh b/dracut-early-kdump.sh index 45ee6dc..9e55258 100755 --- a/dracut-early-kdump.sh +++ b/dracut-early-kdump.sh @@ -6,7 +6,6 @@ standard_kexec_args="-p" EARLY_KDUMP_INITRD="" EARLY_KDUMP_KERNEL="" EARLY_KDUMP_CMDLINE="" -EARLY_KDUMP_KERNELVER="" EARLY_KEXEC_ARGS=""
. /etc/sysconfig/kdump @@ -58,7 +57,7 @@ early_kdump_load() --command-line=$EARLY_KDUMP_CMDLINE --initrd=$EARLY_KDUMP_INITRD \ $EARLY_KDUMP_KERNEL"
- if $KEXEC $EARLY_KEXEC_ARGS $standard_kexec_args \
- if $KEXEC "$EARLY_KEXEC_ARGS" $standard_kexec_args \
Since EARLY_KEXEC_ARGS could be multiple arguments, quoting it could cause a trouble for kexec. So we should simply suppress the shellcheck error instead.
true...
Thanks for the review! Philipp
--command-line="$EARLY_KDUMP_CMDLINE" \ --initrd=$EARLY_KDUMP_INITRD $EARLY_KDUMP_KERNEL; then dinfo "kexec: loaded early-kdump kernel"
-- 2.38.1 _______________________________________________ kexec mailing list -- kexec@lists.fedoraproject.org To unsubscribe send an email to kexec-leave@lists.fedoraproject.org Fedora Code of Conduct: https://docs.fedoraproject.org/en-US/project/code-of-conduct/ List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines List Archives: https://lists.fedoraproject.org/archives/list/kexec@lists.fedoraproject.org Do not reply to spam, report it: https://pagure.io/fedora-infrastructure/new_issue
Currently dracut-early-kdump.sh claims to be POSIX compliant but it sources kdump-lib.sh which uses bash-only syntax. Thus require bash for dracut-early-kdump.sh as well.
Signed-off-by: Philipp Rudo prudo@redhat.com --- .editorconfig | 2 +- dracut-early-kdump.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/.editorconfig b/.editorconfig index 87c4f98..b343f27 100644 --- a/.editorconfig +++ b/.editorconfig @@ -22,7 +22,7 @@ space_redirects = true shell_variant = bash
# Use dracut code style for *-module-setup.sh -[*-module-setup.sh] +[*-module-setup.sh,dracut-early-kdump.sh] shell_variant = bash indent_style = space indent_size = 4 diff --git a/dracut-early-kdump.sh b/dracut-early-kdump.sh index 9e55258..2954915 100755 --- a/dracut-early-kdump.sh +++ b/dracut-early-kdump.sh @@ -1,4 +1,4 @@ -#! /bin/sh +#! /bin/bash
KEXEC=/sbin/kexec standard_kexec_args="-p"
Both functions are almost identical. The only differences are (1) the sysfs node the status is read from and (2) the fact the fadump version doesn't verify if the file it's trying to read actually exists. Thus merge the two functions and get rid of the check_current_status wrapper.
While at it rename the function to is_kernel_loaded which explains better what the function does.
Finally, after moving FADUMP_REGISTER_SYS_NODE shellcheck can no longer access the definition and starts complaining about it not being quoted. Thus quote all uses of FADUMP_REGISTER_SYS_NODE.
Signed-off-by: Philipp Rudo prudo@redhat.com --- dracut-early-kdump.sh | 2 +- kdump-lib.sh | 29 +++++++++++++++++++++-------- kdumpctl | 34 ++++++++-------------------------- 3 files changed, 30 insertions(+), 35 deletions(-)
diff --git a/dracut-early-kdump.sh b/dracut-early-kdump.sh index 2954915..180837c 100755 --- a/dracut-early-kdump.sh +++ b/dracut-early-kdump.sh @@ -37,7 +37,7 @@ early_kdump_load() return 1 fi
- if check_current_kdump_status; then + if is_kernel_loaded "kdump"; then return 1 fi
diff --git a/kdump-lib.sh b/kdump-lib.sh index 400b05c..c3091c8 100755 --- a/kdump-lib.sh +++ b/kdump-lib.sh @@ -9,6 +9,7 @@ else fi
FADUMP_ENABLED_SYS_NODE="/sys/kernel/fadump_enabled" +FADUMP_REGISTER_SYS_NODE="/sys/kernel/fadump_registered"
is_fadump_capable() { @@ -494,19 +495,31 @@ check_kdump_feasibility() return $? }
-check_current_kdump_status() +is_kernel_loaded() { - if [[ ! -f /sys/kernel/kexec_crash_loaded ]]; then - derror "Perhaps CONFIG_CRASH_DUMP is not enabled in kernel" + local _sysfs _mode + + _mode=$1 + + case "$_mode" in + kdump) + _sysfs="/sys/kernel/kexec_crash_loaded" + ;; + fadump) + _sysfs="$FADUMP_REGISTER_SYS_NODE" + ;; + *) + derror "Unknown dump mode '$_mode' provided" return 1 - fi + ;; + esac
- rc=$(< /sys/kernel/kexec_crash_loaded) - if [[ $rc == 1 ]]; then - return 0 - else + if [[ ! -f $_sysfs ]]; then + derror "$_mode is not supported on this kernel" return 1 fi + + [[ $(< $_sysfs) -eq 1 ]] }
# remove_cmdline_param <kernel cmdline> <param1> [<param2>] ... [<paramN>] diff --git a/kdumpctl b/kdumpctl index 8a06c2e..71f72b5 100755 --- a/kdumpctl +++ b/kdumpctl @@ -14,7 +14,6 @@ DEFAULT_INITRD_BAK="" INITRD_CHECKSUM_LOCATION="" KDUMP_INITRD="" TARGET_INITRD="" -FADUMP_REGISTER_SYS_NODE="/sys/kernel/fadump_registered" #kdump shall be the default dump mode DEFAULT_DUMP_MODE="kdump" image_time=0 @@ -837,23 +836,6 @@ show_reserved_mem() dinfo "Reserved ${mem_mb}MB memory for crash kernel" }
-check_current_fadump_status() -{ - # Check if firmware-assisted dump has been registered. - rc=$(< $FADUMP_REGISTER_SYS_NODE) - [[ $rc -eq 1 ]] && return 0 - return 1 -} - -check_current_status() -{ - if [[ $DEFAULT_DUMP_MODE == "fadump" ]]; then - check_current_fadump_status - else - check_current_kdump_status - fi -} - save_raw() { local raw_target @@ -974,8 +956,8 @@ check_dump_feasibility()
start_fadump() { - echo 1 > $FADUMP_REGISTER_SYS_NODE - if ! check_current_fadump_status; then + echo 1 > "$FADUMP_REGISTER_SYS_NODE" + if ! is_kernel_loaded "fadump"; then derror "fadump: failed to register" return 1 fi @@ -1040,7 +1022,7 @@ start() return 1 fi
- if [[ $DEFAULT_DUMP_MODE == "kdump" ]] && check_current_kdump_status; then + if [[ $DEFAULT_DUMP_MODE == "kdump" ]] && is_kernel_loaded "kdump"; then dwarn "Kdump already running: [WARNING]" return 0 fi @@ -1065,7 +1047,7 @@ start()
reload() { - if ! check_current_status; then + if ! is_kernel_loaded "$DEFAULT_DUMP_MODE"; then dwarn "Kdump was not running: [WARNING]" fi
@@ -1096,8 +1078,8 @@ reload()
stop_fadump() { - echo 0 > $FADUMP_REGISTER_SYS_NODE - if check_current_fadump_status; then + echo 0 > "$FADUMP_REGISTER_SYS_NODE" + if is_kernel_loaded "fadump"; then derror "fadump: failed to unregister" return 1 fi @@ -1126,7 +1108,7 @@ stop_kdump()
reload_fadump() { - if echo 1 > $FADUMP_REGISTER_SYS_NODE; then + if echo 1 > "$FADUMP_REGISTER_SYS_NODE"; then dinfo "fadump: re-registered successfully" return 0 else @@ -1740,7 +1722,7 @@ main() ;; status) EXIT_CODE=0 - check_current_status + is_kernel_loaded "$DEFAULT_DUMP_MODE" case "$?" in 0) dinfo "Kdump is operational"
mkfadumprd doesn't call prepare_kdump_bootinfo from kdump-lib.sh. Thus both KDUMP_KERNELVER and DEFAULT_INITRD are always empty. Simply remove them from the debug print.
Signed-off-by: Philipp Rudo prudo@redhat.com --- mkfadumprd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) mode change 100644 => 100755 mkfadumprd
diff --git a/mkfadumprd b/mkfadumprd old mode 100644 new mode 100755 index 2fc396c..719e150 --- a/mkfadumprd +++ b/mkfadumprd @@ -37,7 +37,7 @@ FADUMP_INITRD="$MKFADUMPRD_TMPDIR/fadump.img" ### First build an initramfs with dump capture capability # this file tells the initrd is fadump enabled touch "$MKFADUMPRD_TMPDIR/fadump.initramfs" -ddebug "rebuild fadump initrd: $FADUMP_INITRD $DEFAULT_INITRD $KDUMP_KERNELVER" +ddebug "rebuild fadump initrd: $FADUMP_INITRD" # Don't use squash for capture image or default image as it negatively impacts # compression ratio and increases the size of the initramfs image. # Don't compress the capture image as uncompressed image is needed immediately.
is_squash_available is only used in dracut-module-setup.sh and mkdumprd. Neither of the two scripts calls prepare_kdump_bootinfo which determines and sets KDUMP_KERNELVER. Thus KDUMP_KERNELVER is only non-zero if it explicitly specified by the user in /etc/sysconfig/kdump (and the file gets sourced, which is not the case for drachu-module-setup.sh).
In theory this can even lead to bugs. For example consider the case when a debug kernel is running. In that case kdumpctl will try to use the non-debug version of the kernel while is_squash_available will make its decision based on the debug version. So in case the debug kernel has squash available but the non-debug kernel doesn't mkdumprd will try to add it nevertheless.
Thus factor out the kernel version detection from prepare_kdump_bootinfo and make use of the new function when checking for the availability of those kernel modules.
Signed-off-by: Philipp Rudo prudo@redhat.com --- kdump-lib.sh | 64 +++++++++++++++++++++++++--------------------------- 1 file changed, 31 insertions(+), 33 deletions(-)
diff --git a/kdump-lib.sh b/kdump-lib.sh index c3091c8..0109b95 100755 --- a/kdump-lib.sh +++ b/kdump-lib.sh @@ -24,12 +24,11 @@ is_fadump_capable()
is_squash_available() { + local _version kmodule + + _version=$(_get_kdump_kernel_version) for kmodule in squashfs overlay loop; do - if [[ -z $KDUMP_KERNELVER ]]; then - modprobe --dry-run $kmodule &> /dev/null || return 1 - else - modprobe -S "$KDUMP_KERNELVER" --dry-run $kmodule &> /dev/null || return 1 - fi + modprobe -S "$_version" --dry-run $kmodule &> /dev/null || return 1 done }
@@ -687,6 +686,31 @@ prepare_kdump_kernel() echo "$kdump_kernel" }
+_get_kdump_kernel_version() +{ + local _version _version_nondebug + + if [[ -n "$KDUMP_KERNELVER" ]]; then + echo "$KDUMP_KERNELVER" + return + fi + + _version=$(uname -r) + if [[ ! "$_version" =~ +debug$ ]]; then + echo "$_version" + return + fi + + _version_nondebug=${_version%+debug} + if [[ -f "$(prepare_kdump_kernel "$_version_nondebug")" ]]; then + dinfo "Use of debug kernel detected. Trying to use $_version_nondebug" + echo "$_version_nondebug" + else + dinfo "Use of debug kernel detected but cannot find $_version_nondebug. Falling back to $_version" + echo "$_version" + fi +} + # # Detect initrd and kernel location, results are stored in global environmental variables: # KDUMP_BOOTDIR, KDUMP_KERNELVER, KDUMP_KERNEL, DEFAULT_INITRD, and KDUMP_INITRD @@ -696,37 +720,11 @@ prepare_kdump_kernel() # prepare_kdump_bootinfo() { - local boot_initrdlist nondebug_kernelver debug_kernelver - local default_initrd_base var_target_initrd_dir - - if [[ -z $KDUMP_KERNELVER ]]; then - KDUMP_KERNELVER=$(uname -r) - - # Fadump uses the regular bootloader, unlike kdump. So, use the same version - # for default kernel and capture kernel unless specified explicitly with - # KDUMP_KERNELVER option. - if ! is_fadump_capable; then - nondebug_kernelver=$(sed -n -e 's/(.*)+debug$/\1/p' <<< "$KDUMP_KERNELVER") - fi - fi - - # Use nondebug kernel if possible, because debug kernel will consume more memory and may oom. - if [[ -n $nondebug_kernelver ]]; then - dinfo "Trying to use $nondebug_kernelver." - debug_kernelver=$KDUMP_KERNELVER - KDUMP_KERNELVER=$nondebug_kernelver - fi + local boot_initrdlist default_initrd_base var_target_initrd_dir
+ KDUMP_KERNELVER=$(_get_kdump_kernel_version) KDUMP_KERNEL=$(prepare_kdump_kernel "$KDUMP_KERNELVER")
- if ! [[ -e $KDUMP_KERNEL ]]; then - if [[ -n $debug_kernelver ]]; then - dinfo "Fallback to using debug kernel" - KDUMP_KERNELVER=$debug_kernelver - KDUMP_KERNEL=$(prepare_kdump_kernel "$KDUMP_KERNELVER") - fi - fi - if ! [[ -e $KDUMP_KERNEL ]]; then derror "Failed to detect kdump kernel location" return 1
prepare_cmdline is totally broken. For example if the remove list ($2) is empty it removes all white spaces or if a parameter has a quoted value containing a white space it only removes the first part of the parameter up to the first space. Thus add a test case that shows what the function should do in order to fix it in subsequent patches.
Signed-off-by: Philipp Rudo prudo@redhat.com --- spec/kdump-lib_spec.sh | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+)
diff --git a/spec/kdump-lib_spec.sh b/spec/kdump-lib_spec.sh index 8c91480..3d10006 100644 --- a/spec/kdump-lib_spec.sh +++ b/spec/kdump-lib_spec.sh @@ -48,4 +48,36 @@ Describe 'kdump-lib' End End
+ Describe 'prepare_cmdline()' + get_bootcpu_apicid() { + echo 1 + } + + get_watchdog_drvs() { + echo foo + } + + add="disable_cpu_apicid=1 foo.pretimeout=0" + + Parameters + #test cmdline remove add result + "#1" "a b c" "" "" "a b c" + "#2" "a b c" "b" "" "a c" + "#3" "a b=x c" "b" "" "a c" + "#4" "a b='x y' c" "b" "" "a c" + "#5" "a b='x y' c" "b=x" "" "a c" + "#6" "a b='x y' c" "b='x y'" "" "a c" + "#7" "a b c" "" "x" "a b c x" + "#8" "a b c" "" "x=1" "a b c x=1" + "#9" "a b c" "" "x='1 2'" "a b c x='1 2'" + "#10" "a b c" "a" "x='1 2'" "b c x='1 2'" + "#11" "a b c" "x" "x='1 2'" "a b c x='1 2'" + End + + It "Test $1: should generate the correct kernel command line" + When call prepare_cmdline "$2" "$3" "$4" + The output should equal "$5 $add" + End + End + End
Move the workaround for aws graviton cpus from load_kdump to prepare_cmdline. This (1) makes the workaround available also for other callers of prepare_cmdline (although not needed at the moment) and (2) makes it easier to fix the problems found by the unit test included earlier as all changes to the cmdline are done at one place now.
Signed-off-by: Philipp Rudo prudo@redhat.com --- kdump-lib.sh | 9 +++++++++ kdumpctl | 17 ----------------- 2 files changed, 9 insertions(+), 17 deletions(-)
diff --git a/kdump-lib.sh b/kdump-lib.sh index 0109b95..bea74b2 100755 --- a/kdump-lib.sh +++ b/kdump-lib.sh @@ -22,6 +22,11 @@ is_fadump_capable() return 1 }
+is_aws_aarch64() +{ + [[ "$(lscpu | grep "BIOS Model name")" =~ "AWS Graviton" ]] +} + is_squash_available() { local _version kmodule @@ -846,6 +851,10 @@ prepare_cmdline() fi done
+ # This is a workaround on AWS platform. Always remove irqpoll since it + # may cause the hot-remove of some pci hotplug device. + is_aws_aarch64 && cmdline=$(remove_cmdline_param "${cmdline}" irqpoll) + echo "$cmdline" }
diff --git a/kdumpctl b/kdumpctl index 71f72b5..de274c6 100755 --- a/kdumpctl +++ b/kdumpctl @@ -656,18 +656,6 @@ function remove_kdump_kernel_key() keyctl unlink "$KDUMP_KEY_ID" %:.ima }
-function is_aws_aarch64() -{ - local _bios_model - - _bios_model=$(lscpu | grep "BIOS Model name") - if [[ "${_bios_model}" =~ "AWS Graviton" ]]; then - return 0 - fi - - return 1 -} - # Load the kdump kernel specified in /etc/sysconfig/kdump # If none is specified, try to load a kdump kernel with the same version # as the currently running kernel. @@ -677,11 +665,6 @@ load_kdump()
KEXEC_ARGS=$(prepare_kexec_args "${KEXEC_ARGS}") KDUMP_COMMANDLINE=$(prepare_cmdline "${KDUMP_COMMANDLINE}" "${KDUMP_COMMANDLINE_REMOVE}" "${KDUMP_COMMANDLINE_APPEND}") - # This is a workaround on AWS platform, since irqpoll may cause the hot-remove of some pci hotplug device - if is_aws_aarch64; then - KDUMP_COMMANDLINE=$(remove_cmdline_param "${KDUMP_COMMANDLINE}" irqpoll) - fi - # For secureboot enabled machines, use new kexec file based syscall. # Old syscall will always fail as it does not have capability to # to kernel signature verification.
A recently added unit test found that prepare_cmdline has several problems. For example an empty remove list will remove all spaces or when the cmdline contains a parameter with quoted values containing spaces will only remove the beginning up to the first space. Furthermore the old design requires lots of subshells and pipes.
This patch rewrites prepare_cmdline in a way that makes the unit test happy and tries to use as many bash built-ins as possible.
Signed-off-by: Philipp Rudo prudo@redhat.com --- kdump-lib.sh | 128 ++++++++++++++++++++++++++------------------------- 1 file changed, 66 insertions(+), 62 deletions(-)
diff --git a/kdump-lib.sh b/kdump-lib.sh index bea74b2..6b0a83d 100755 --- a/kdump-lib.sh +++ b/kdump-lib.sh @@ -526,24 +526,6 @@ is_kernel_loaded() [[ $(< $_sysfs) -eq 1 ]] }
-# remove_cmdline_param <kernel cmdline> <param1> [<param2>] ... [<paramN>] -# Remove a list of kernel parameters from a given kernel cmdline and print the result. -# For each "arg" in the removing params list, "arg" and "arg=xxx" will be removed if exists. -remove_cmdline_param() -{ - local cmdline=$1 - shift - - for arg in "$@"; do - cmdline=$(echo "$cmdline" | - sed -e "s/\b$arg=[^ ]*//g" \ - -e "s/^$arg\b//g" \ - -e "s/[[:space:]]$arg\b//g" \ - -e "s/\s+/ /g") - done - echo "$cmdline" -} - # # This function returns the "apicid" of the boot # cpu (cpu 0) if present. @@ -558,23 +540,6 @@ get_bootcpu_apicid() /proc/cpuinfo }
-# -# append_cmdline <kernel cmdline> <parameter name> <parameter value> -# This function appends argument "$2=$3" to string ($1) if not already present. -# -append_cmdline() -{ - local cmdline=$1 - local newstr=${cmdline/$2/""} - - # unchanged str implies argument wasn't there - if [[ $cmdline == "$newstr" ]]; then - cmdline="${cmdline} ${2}=${3}" - fi - - echo "$cmdline" -} - # This function check iomem and determines if we have more than # 4GB of ram available. Returns 1 if we do, 0 if we dont need_64bit_headers() @@ -792,26 +757,46 @@ get_watchdog_drvs() echo "$_wdtdrvs" }
+_cmdline_parse() +{ + local opt val + + while read -r opt; do + if [[ $opt =~ = ]]; then + val=${opt#*=} + opt=${opt%%=*} + # ignore options like 'foo=' + [[ -z $val ]] && continue + # xargs removes quotes, add them again + [[ $val =~ [[:space:]] ]] && val=""$val"" + else + val="" + fi + + echo "$opt $val" + done <<< "$(echo "$1" | xargs -n 1 echo)" +} + # # prepare_cmdline <commandline> <commandline remove> <commandline append> # This function performs a series of edits on the command line. # Store the final result in global $KDUMP_COMMANDLINE. prepare_cmdline() { - local cmdline id arg + local in out append opt val id drv + local -A remove + + in=${1:-$(< /proc/cmdline)} + while read -r opt val; do + [[ -n "$opt" ]] || continue + remove[$opt]=1 + done <<< "$(_cmdline_parse "$2")" + append=$3
- if [[ -z $1 ]]; then - cmdline=$(< /proc/cmdline) - else - cmdline="$1" - fi
# These params should always be removed - cmdline=$(remove_cmdline_param "$cmdline" crashkernel panic_on_warn) - # These params can be removed configurably - while read -r arg; do - cmdline=$(remove_cmdline_param "$cmdline" "$arg") - done <<< "$(echo "$2" | xargs -n 1 echo)" + remove[crashkernel]=1 + remove[panic_on_warn]=1
# Always remove "root=X", as we now explicitly generate all kinds # of dump target mount information including root fs. @@ -819,43 +804,62 @@ prepare_cmdline() # We do this before KDUMP_COMMANDLINE_APPEND, if one really cares # about it(e.g. for debug purpose), then can pass "root=X" using # KDUMP_COMMANDLINE_APPEND. - cmdline=$(remove_cmdline_param "$cmdline" root) + remove[root]=1
# With the help of "--hostonly-cmdline", we can avoid some interitage. - cmdline=$(remove_cmdline_param "$cmdline" rd.lvm.lv rd.luks.uuid rd.dm.uuid rd.md.uuid fcoe) + remove[rd.lvm.lv]=1 + remove[rd.luks.uuid]=1 + remove[rd.dm.uuid]=1 + remove[rd.md.uuid]=1 + remove[fcoe]=1
# Remove netroot, rd.iscsi.initiator and iscsi_initiator since # we get duplicate entries for the same in case iscsi code adds # it as well. - cmdline=$(remove_cmdline_param "$cmdline" netroot rd.iscsi.initiator iscsi_initiator) + remove[netroot]=1 + remove[rd.iscsi.initiator]=1 + remove[iscsi_initiator]=1 + + while read -r opt val; do + [[ -n "$opt" ]] || continue + [[ -n "${remove[$opt]}" ]] && continue + + if [[ -n "$val" ]]; then + out+="$opt=$val " + else + out+="$opt " + fi + done <<< "$(_cmdline_parse "$in")"
- cmdline="${cmdline} $3" + out+="$append "
id=$(get_bootcpu_apicid) - if [[ -n ${id} ]]; then - cmdline=$(append_cmdline "$cmdline" disable_cpu_apicid "$id") + if [[ -n "${id}" ]]; then + out+="disable_cpu_apicid=$id " fi
# If any watchdog is used, set it's pretimeout to 0. pretimeout let # watchdog panic the kernel first, and reset the system after the # panic. If the system is already in kdump, panic is not helpful # and only increase the chance of watchdog failure. - for i in $(get_watchdog_drvs); do - cmdline+=" $i.pretimeout=0" - - if [[ $i == hpwdt ]]; then - # hpwdt have a special parameter kdumptimeout, is's only suppose - # to be set to non-zero in first kernel. In kdump, non-zero - # value could prevent the watchdog from resetting the system. - cmdline+=" $i.kdumptimeout=0" + for drv in $(get_watchdog_drvs); do + out+="$drv.pretimeout=0 " + + if [[ $drv == hpwdt ]]; then + # hpwdt have a special parameter kdumptimeout, it is + # only supposed to be set to non-zero in first kernel. + # In kdump, non-zero value could prevent the watchdog + # from resetting the system. + out+="$drv.kdumptimeout=0 " fi done
# This is a workaround on AWS platform. Always remove irqpoll since it # may cause the hot-remove of some pci hotplug device. - is_aws_aarch64 && cmdline=$(remove_cmdline_param "${cmdline}" irqpoll) + is_aws_aarch64 && out=$(echo "$out" | sed -e "/<irqpoll>//")
- echo "$cmdline" + # Trim unnecessary whitespaces + echo "$out" | sed -e "s/^ *//g" -e "s/ *$//g" -e "s/ +/ /g" }
PROC_IOMEM=/proc/iomem
The function has many block of the kind
if ! cmd; then derror "Starting kdump: [FAILED]" return 1 fi
This duplicates code and makes the function hard to read. Thus move the block to the calling function.
Signed-off-by: Philipp Rudo prudo@redhat.com --- kdumpctl | 44 +++++++++++++++----------------------------- 1 file changed, 15 insertions(+), 29 deletions(-)
diff --git a/kdumpctl b/kdumpctl index de274c6..77ed584 100755 --- a/kdumpctl +++ b/kdumpctl @@ -986,46 +986,26 @@ check_final_action_config()
start() { - if ! check_dump_feasibility; then - derror "Starting kdump: [FAILED]" - return 1 - fi - - if ! parse_config; then - derror "Starting kdump: [FAILED]" - return 1 - fi + check_dump_feasibility || return + parse_config || return
if sestatus 2> /dev/null | grep -q "SELinux status.*enabled"; then selinux_relabel fi
- if ! save_raw; then - derror "Starting kdump: [FAILED]" - return 1 - fi + save_raw || return
if [[ $DEFAULT_DUMP_MODE == "kdump" ]] && is_kernel_loaded "kdump"; then dwarn "Kdump already running: [WARNING]" return 0 fi
- if ! check_and_wait_network_ready; then - derror "Starting kdump: [FAILED]" - return 1 - fi - - if ! check_rebuild; then - derror "Starting kdump: [FAILED]" - return 1 - fi - - if ! start_dump; then - derror "Starting kdump: [FAILED]" - return 1 - fi + check_and_wait_network_ready || return + check_rebuild || return + start_dump || return
dinfo "Starting kdump: [OK]" + return 0 }
reload() @@ -1698,7 +1678,10 @@ main()
case "$1" in start) - start + if ! start; then + derror "Starting kdump: [FAILED]" + exit 1 + fi ;; stop) stop @@ -1723,7 +1706,10 @@ main() ;; restart) stop - start + if ! start; then + derror "Starting kdump: [FAILED]" + exit 1 + fi ;; rebuild) rebuild
Like for 'start' move the printing of the error message to the calling function. This not only makes the code more consistent to 'start' but also prevents 'kdumpctl restart' to call 'start' in case 'stop' has failed. This doesn't impact the case when 'kdumpctl restart' is run without any crash kernel being loaded as kexec will still return success in that case.
Signed-off-by: Philipp Rudo prudo@redhat.com --- kdumpctl | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/kdumpctl b/kdumpctl index 77ed584..3d3b9d4 100755 --- a/kdumpctl +++ b/kdumpctl @@ -1090,15 +1090,9 @@ reload_fadump() stop() { if [[ $DEFAULT_DUMP_MODE == "fadump" ]]; then - stop_fadump + stop_fadump || return else - stop_kdump - fi - - # shellcheck disable=SC2181 - if [[ $? != 0 ]]; then - derror "Stopping kdump: [FAILED]" - return 1 + stop_kdump || return fi
dinfo "Stopping kdump: [OK]" @@ -1684,7 +1678,10 @@ main() fi ;; stop) - stop + if ! stop; then + derror "Stopping kdump: [FAILED]" + exit 1 + fi ;; status) EXIT_CODE=0 @@ -1705,7 +1702,10 @@ main() reload ;; restart) - stop + if ! stop; then + derror "Stopping kdump: [FAILED]" + exit 1 + fi if ! start; then derror "Starting kdump: [FAILED]" exit 1
check_rebuild uses a bunch of local variables to store the result of the different checks performed. At the end of the function it then evaluates which check failed to print an appropriate info and trigger a rebuild if needed. This not only makes the function hard to read but also requires all checks to be executed even if an earlier one already determined that the initrd needs to be rebuild. Thus refractor check_rebuild such that it only checks whether the initrd needs to rebuild and trigger the rebuild by the caller (if needed). While at it rename the function to need_initrd_rebuild.
Furthermore also move setup_initrd to the caller so it is more consisted with the other users of the function.
Signed-off-by: Philipp Rudo prudo@redhat.com --- kdumpctl | 81 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 40 insertions(+), 41 deletions(-)
diff --git a/kdumpctl b/kdumpctl index 3d3b9d4..5954527 100755 --- a/kdumpctl +++ b/kdumpctl @@ -560,72 +560,58 @@ check_system_modified() return 0 }
-check_rebuild() +# need_initrd_rebuild - check whether the initrd needs to be rebuild +# Returns: +# 0 if does not need to be rebuild +# 1 if it needs to be rebuild +# 2 if an error occurred +need_initrd_rebuild() { - local capture_capable_initrd="1" local force_rebuild force_no_rebuild - local ret system_modified="0"
- setup_initrd || return 1 - - force_no_rebuild=${OPT[force_no_rebuild]} - force_no_rebuild=${force_no_rebuild:-0} + force_no_rebuild=${OPT[force_no_rebuild]:-0} if [[ $force_no_rebuild != "0" ]] && [[ $force_no_rebuild != "1" ]]; then derror "Error: force_no_rebuild value is invalid" - return 1 + return 2 fi
- force_rebuild=${OPT[force_rebuild]} - force_rebuild=${force_rebuild:-0} + force_rebuild=${OPT[force_rebuild]:-0} if [[ $force_rebuild != "0" ]] && [[ $force_rebuild != "1" ]]; then derror "Error: force_rebuild value is invalid" - return 1 + return 2 fi
if [[ $force_no_rebuild == "1" && $force_rebuild == "1" ]]; then derror "Error: force_rebuild and force_no_rebuild are enabled simultaneously in kdump.conf" - return 1 + return 2 fi
- # Will not rebuild kdump initrd if [[ $force_no_rebuild == "1" ]]; then return 0 fi
- #check to see if dependent files has been modified - #since last build of the image file - if [[ -f $TARGET_INITRD ]]; then - image_time=$(stat -c "%Y" "$TARGET_INITRD" 2> /dev/null) - - #in case of fadump mode, check whether the default/target - #initrd is already built with dump capture capability - if [[ $DEFAULT_DUMP_MODE == "fadump" ]]; then - capture_capable_initrd=$(lsinitrd -f $DRACUT_MODULES_FILE "$TARGET_INITRD" | grep -c -e ^kdumpbase$ -e ^zz-fadumpinit$) - fi + if [[ $force_rebuild == "1" ]]; then + dinfo "Force rebuild $TARGET_INITRD" + return 1 fi
- check_system_modified - ret=$? - if [[ $ret -eq 2 ]]; then + if [[ ! -f $TARGET_INITRD ]]; then + dinfo "No kdump initial ramdisk found." return 1 - elif [[ $ret -eq 1 ]]; then - system_modified="1" fi
- if [[ $image_time -eq 0 ]]; then - dinfo "No kdump initial ramdisk found." - elif [[ $capture_capable_initrd == "0" ]]; then - dinfo "Rebuild $TARGET_INITRD with dump capture support" - elif [[ $force_rebuild != "0" ]]; then - dinfo "Force rebuild $TARGET_INITRD" - elif [[ $system_modified != "0" ]]; then - : - else - return 0 + # in case of fadump mode, check whether the default/target initrd is + # already built with dump capture capability + if [[ $DEFAULT_DUMP_MODE == "fadump" ]]; then + if ! lsinitrd -f $DRACUT_MODULES_FILE "$TARGET_INITRD" | grep -q -e ^kdumpbase$ -e ^zz-fadumpinit$; then + dinfo "Rebuild $TARGET_INITRD with dump capture support" + return 1 + fi fi
- dinfo "Rebuilding $TARGET_INITRD" - rebuild_initrd + image_time=$(stat -c "%Y" "$TARGET_INITRD" 2> /dev/null) + check_system_modified + }
# On ppc64le LPARs, the keys trusted by firmware do not end up in @@ -1001,7 +987,20 @@ start() fi
check_and_wait_network_ready || return - check_rebuild || return + setup_initrd || return + need_initrd_rebuild + case "$?" in + 0) + # Nothing to do + ;; + 1) + dinfo "Rebuilding $TARGET_INITRD" + rebuild_initrd || return + ;; + *) + return + ;; + esac start_dump || return
dinfo "Starting kdump: [OK]"
At the beginning of do_estimate it currently checks whether the TARGET_INITRD exists and if not fails with an error message. This not only requires the user to manually trigger the build of the initrd but also ignores all cases where the TARGET_INITRD exists but need to be rebuild. For example when there were changes to kdump.conf or when the system switches from kdump to fadump. All these changes will impact the outcome of do_estimate. Thus properly check whether the initrd needs to be rebuild and if it does trigger the rebuild automatically.
To do so move the check whether the TARGET_INITRD has fadump enabled to is_system_modified and call this function. With this force_(no_)rebuild options in kdump.conf are ignored to avoid unnecessary rebuilds.
While at it cleanup check_system_modified and rename it to is_system_modified. Furthermore move printing the info that the initrd gets rebuild to rebuild_initrd to avoid every caller has the same line.
Signed-off-by: Philipp Rudo prudo@redhat.com --- kdumpctl | 62 ++++++++++++++++++++++++-------------------------------- 1 file changed, 27 insertions(+), 35 deletions(-)
diff --git a/kdumpctl b/kdumpctl index 5954527..d5bf408 100755 --- a/kdumpctl +++ b/kdumpctl @@ -117,6 +117,8 @@ rebuild_kdump_initrd()
rebuild_initrd() { + dinfo "Rebuilding $TARGET_INITRD" + if [[ ! -w $(dirname "$TARGET_INITRD") ]]; then derror "$(dirname "$TARGET_INITRD") does not have write permission. Cannot rebuild $TARGET_INITRD" return 1 @@ -532,32 +534,27 @@ check_fs_modified()
# returns 0 if system is not modified # returns 1 if system is modified -# returns 2 if system modification is invalid -check_system_modified() +# returns 2 if an error occurred +is_system_modified() { local ret
[[ -f $TARGET_INITRD ]] || return 1
- check_files_modified - ret=$? - if [[ $ret -ne 0 ]]; then - return $ret + # in case of fadump mode, check whether the default/target initrd is + # already built with dump capture capability + if [[ $DEFAULT_DUMP_MODE == "fadump" ]]; then + if ! lsinitrd -f $DRACUT_MODULES_FILE "$TARGET_INITRD" | grep -q -e ^kdumpbase$ -e ^zz-fadumpinit$; then + dinfo "Rebuild $TARGET_INITRD with dump capture support" + return 1 + fi fi
- check_fs_modified - ret=$? - if [[ $ret -ne 0 ]]; then - return $ret - fi + image_time=$(stat -c "%Y" "$TARGET_INITRD" 2> /dev/null)
+ check_files_modified || return + check_fs_modified || return check_drivers_modified - ret=$? - if [[ $ret -ne 0 ]]; then - return $ret - fi - - return 0 }
# need_initrd_rebuild - check whether the initrd needs to be rebuild @@ -600,18 +597,7 @@ need_initrd_rebuild() return 1 fi
- # in case of fadump mode, check whether the default/target initrd is - # already built with dump capture capability - if [[ $DEFAULT_DUMP_MODE == "fadump" ]]; then - if ! lsinitrd -f $DRACUT_MODULES_FILE "$TARGET_INITRD" | grep -q -e ^kdumpbase$ -e ^zz-fadumpinit$; then - dinfo "Rebuild $TARGET_INITRD with dump capture support" - return 1 - fi - fi - - image_time=$(stat -c "%Y" "$TARGET_INITRD" 2> /dev/null) - check_system_modified - + is_system_modified }
# On ppc64le LPARs, the keys trusted by firmware do not end up in @@ -994,7 +980,6 @@ start() # Nothing to do ;; 1) - dinfo "Rebuilding $TARGET_INITRD" rebuild_initrd || return ;; *) @@ -1105,7 +1090,6 @@ rebuild()
setup_initrd || return 1
- dinfo "Rebuilding $TARGET_INITRD" rebuild_initrd }
@@ -1118,10 +1102,18 @@ do_estimate() local size_mb=$((1024 * 1024))
setup_initrd - if [[ ! -f $TARGET_INITRD ]]; then - derror "kdumpctl estimate: kdump initramfs is not built yet." - exit 1 - fi + is_system_modified + case "$?" in + 0) + # Nothing to do + ;; + 1) + rebuild_initrd || return + ;; + *) + return + ;; + esac
kdump_mods="$(lsinitrd "$TARGET_INITRD" -f /usr/lib/dracut/hostonly-kernel-modules.txt | tr '\n' ' ')" baseline=$(kdump_get_arch_recommend_size)
Hi Philipp,
The patch looks good to me except for a small concern.
On Wed, Dec 21, 2022 at 04:27:25PM +0100, Philipp Rudo wrote:
At the beginning of do_estimate it currently checks whether the TARGET_INITRD exists and if not fails with an error message. This not only requires the user to manually trigger the build of the initrd but also ignores all cases where the TARGET_INITRD exists but need to be rebuild. For example when there were changes to kdump.conf or when the system switches from kdump to fadump. All these changes will impact the outcome of do_estimate. Thus properly check whether the initrd needs to be rebuild and if it does trigger the rebuild automatically.
To do so move the check whether the TARGET_INITRD has fadump enabled to is_system_modified and call this function. With this force_(no_)rebuild options in kdump.conf are ignored to avoid unnecessary rebuilds.
While at it cleanup check_system_modified and rename it to is_system_modified. Furthermore move printing the info that the initrd gets rebuild to rebuild_initrd to avoid every caller has the same line.
Signed-off-by: Philipp Rudo prudo@redhat.com
kdumpctl | 62 ++++++++++++++++++++++++-------------------------------- 1 file changed, 27 insertions(+), 35 deletions(-)
diff --git a/kdumpctl b/kdumpctl index 5954527..d5bf408 100755 --- a/kdumpctl +++ b/kdumpctl @@ -117,6 +117,8 @@ rebuild_kdump_initrd()
rebuild_initrd() {
- dinfo "Rebuilding $TARGET_INITRD"
- if [[ ! -w $(dirname "$TARGET_INITRD") ]]; then derror "$(dirname "$TARGET_INITRD") does not have write permission. Cannot rebuild $TARGET_INITRD" return 1
@@ -532,32 +534,27 @@ check_fs_modified()
# returns 0 if system is not modified # returns 1 if system is modified -# returns 2 if system modification is invalid -check_system_modified() +# returns 2 if an error occurred +is_system_modified() { local ret
[[ -f $TARGET_INITRD ]] || return 1
- check_files_modified
- ret=$?
- if [[ $ret -ne 0 ]]; then
return $ret
- # in case of fadump mode, check whether the default/target initrd is
- # already built with dump capture capability
- if [[ $DEFAULT_DUMP_MODE == "fadump" ]]; then
if ! lsinitrd -f $DRACUT_MODULES_FILE "$TARGET_INITRD" | grep -q -e ^kdumpbase$ -e ^zz-fadumpinit$; then
dinfo "Rebuild $TARGET_INITRD with dump capture support"
return 1
fifi
- check_fs_modified
- ret=$?
- if [[ $ret -ne 0 ]]; then
return $ret
- fi
- image_time=$(stat -c "%Y" "$TARGET_INITRD" 2> /dev/null)
Maybe it's better define/assign image_time in check_files_modified so we get rid of this global variable and make it easier for code reasoning? I just checked image_file is only used by check_files_modified and get_pcs_cluster_modified_files which is only called by check_files_modified.
- check_files_modified || return
- check_fs_modified || return check_drivers_modified
- ret=$?
- if [[ $ret -ne 0 ]]; then
return $ret
- fi
- return 0
}
# need_initrd_rebuild - check whether the initrd needs to be rebuild @@ -600,18 +597,7 @@ need_initrd_rebuild() return 1 fi
- # in case of fadump mode, check whether the default/target initrd is
- # already built with dump capture capability
- if [[ $DEFAULT_DUMP_MODE == "fadump" ]]; then
if ! lsinitrd -f $DRACUT_MODULES_FILE "$TARGET_INITRD" | grep -q -e ^kdumpbase$ -e ^zz-fadumpinit$; then
dinfo "Rebuild $TARGET_INITRD with dump capture support"
return 1
fi
- fi
- image_time=$(stat -c "%Y" "$TARGET_INITRD" 2> /dev/null)
- check_system_modified
- is_system_modified
}
# On ppc64le LPARs, the keys trusted by firmware do not end up in @@ -994,7 +980,6 @@ start() # Nothing to do ;; 1)
*)dinfo "Rebuilding $TARGET_INITRD" rebuild_initrd || return ;;
@@ -1105,7 +1090,6 @@ rebuild()
setup_initrd || return 1
- dinfo "Rebuilding $TARGET_INITRD" rebuild_initrd
}
@@ -1118,10 +1102,18 @@ do_estimate() local size_mb=$((1024 * 1024))
setup_initrd
- if [[ ! -f $TARGET_INITRD ]]; then
derror "kdumpctl estimate: kdump initramfs is not built yet."
exit 1
- fi
is_system_modified
case "$?" in
0)
# Nothing to do
;;
1)
rebuild_initrd || return
;;
*)
return
;;
esac
kdump_mods="$(lsinitrd "$TARGET_INITRD" -f /usr/lib/dracut/hostonly-kernel-modules.txt | tr '\n' ' ')" baseline=$(kdump_get_arch_recommend_size)
-- 2.38.1 _______________________________________________ kexec mailing list -- kexec@lists.fedoraproject.org To unsubscribe send an email to kexec-leave@lists.fedoraproject.org Fedora Code of Conduct: https://docs.fedoraproject.org/en-US/project/code-of-conduct/ List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines List Archives: https://lists.fedoraproject.org/archives/list/kexec@lists.fedoraproject.org Do not reply to spam, report it: https://pagure.io/fedora-infrastructure/new_issue
On Mon, 9 Jan 2023 16:39:44 +0800 Coiby Xu coxu@redhat.com wrote:
Hi Philipp,
The patch looks good to me except for a small concern.
On Wed, Dec 21, 2022 at 04:27:25PM +0100, Philipp Rudo wrote:
At the beginning of do_estimate it currently checks whether the TARGET_INITRD exists and if not fails with an error message. This not only requires the user to manually trigger the build of the initrd but also ignores all cases where the TARGET_INITRD exists but need to be rebuild. For example when there were changes to kdump.conf or when the system switches from kdump to fadump. All these changes will impact the outcome of do_estimate. Thus properly check whether the initrd needs to be rebuild and if it does trigger the rebuild automatically.
To do so move the check whether the TARGET_INITRD has fadump enabled to is_system_modified and call this function. With this force_(no_)rebuild options in kdump.conf are ignored to avoid unnecessary rebuilds.
While at it cleanup check_system_modified and rename it to is_system_modified. Furthermore move printing the info that the initrd gets rebuild to rebuild_initrd to avoid every caller has the same line.
Signed-off-by: Philipp Rudo prudo@redhat.com
kdumpctl | 62 ++++++++++++++++++++++++-------------------------------- 1 file changed, 27 insertions(+), 35 deletions(-)
diff --git a/kdumpctl b/kdumpctl index 5954527..d5bf408 100755 --- a/kdumpctl +++ b/kdumpctl @@ -117,6 +117,8 @@ rebuild_kdump_initrd()
rebuild_initrd() {
- dinfo "Rebuilding $TARGET_INITRD"
- if [[ ! -w $(dirname "$TARGET_INITRD") ]]; then derror "$(dirname "$TARGET_INITRD") does not have write permission. Cannot rebuild $TARGET_INITRD" return 1
@@ -532,32 +534,27 @@ check_fs_modified()
# returns 0 if system is not modified # returns 1 if system is modified -# returns 2 if system modification is invalid -check_system_modified() +# returns 2 if an error occurred +is_system_modified() { local ret
[[ -f $TARGET_INITRD ]] || return 1
- check_files_modified
- ret=$?
- if [[ $ret -ne 0 ]]; then
return $ret
- # in case of fadump mode, check whether the default/target initrd is
- # already built with dump capture capability
- if [[ $DEFAULT_DUMP_MODE == "fadump" ]]; then
if ! lsinitrd -f $DRACUT_MODULES_FILE "$TARGET_INITRD" | grep -q -e ^kdumpbase$ -e ^zz-fadumpinit$; then
dinfo "Rebuild $TARGET_INITRD with dump capture support"
return 1
fifi
- check_fs_modified
- ret=$?
- if [[ $ret -ne 0 ]]; then
return $ret
- fi
- image_time=$(stat -c "%Y" "$TARGET_INITRD" 2> /dev/null)
Maybe it's better define/assign image_time in check_files_modified so we get rid of this global variable and make it easier for code reasoning? I just checked image_file is only used by check_files_modified and get_pcs_cluster_modified_files which is only called by check_files_modified.
right, this will make it even better.
I'll prepare a v2 with the two changes you proposed.
Thanks Philipp
- check_files_modified || return
- check_fs_modified || return check_drivers_modified
- ret=$?
- if [[ $ret -ne 0 ]]; then
return $ret
- fi
- return 0
}
# need_initrd_rebuild - check whether the initrd needs to be rebuild @@ -600,18 +597,7 @@ need_initrd_rebuild() return 1 fi
- # in case of fadump mode, check whether the default/target initrd is
- # already built with dump capture capability
- if [[ $DEFAULT_DUMP_MODE == "fadump" ]]; then
if ! lsinitrd -f $DRACUT_MODULES_FILE "$TARGET_INITRD" | grep -q -e ^kdumpbase$ -e ^zz-fadumpinit$; then
dinfo "Rebuild $TARGET_INITRD with dump capture support"
return 1
fi
- fi
- image_time=$(stat -c "%Y" "$TARGET_INITRD" 2> /dev/null)
- check_system_modified
- is_system_modified
}
# On ppc64le LPARs, the keys trusted by firmware do not end up in @@ -994,7 +980,6 @@ start() # Nothing to do ;; 1)
*)dinfo "Rebuilding $TARGET_INITRD" rebuild_initrd || return ;;
@@ -1105,7 +1090,6 @@ rebuild()
setup_initrd || return 1
- dinfo "Rebuilding $TARGET_INITRD" rebuild_initrd
}
@@ -1118,10 +1102,18 @@ do_estimate() local size_mb=$((1024 * 1024))
setup_initrd
- if [[ ! -f $TARGET_INITRD ]]; then
derror "kdumpctl estimate: kdump initramfs is not built yet."
exit 1
- fi
is_system_modified
case "$?" in
0)
# Nothing to do
;;
1)
rebuild_initrd || return
;;
*)
return
;;
esac
kdump_mods="$(lsinitrd "$TARGET_INITRD" -f /usr/lib/dracut/hostonly-kernel-modules.txt | tr '\n' ' ')" baseline=$(kdump_get_arch_recommend_size)
-- 2.38.1 _______________________________________________ kexec mailing list -- kexec@lists.fedoraproject.org To unsubscribe send an email to kexec-leave@lists.fedoraproject.org Fedora Code of Conduct: https://docs.fedoraproject.org/en-US/project/code-of-conduct/ List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines List Archives: https://lists.fedoraproject.org/archives/list/kexec@lists.fedoraproject.org Do not reply to spam, report it: https://pagure.io/fedora-infrastructure/new_issue