kdump-lib-initramfs: Fix performance regression in kdump_get_conf_val
Resolves: RHEL-115464
Upstream: kdump-utils
Conflict: None
commit b43908c20f5a028c60b0096006a26a6e52a01279
Author: Philipp Rudo <prudo@redhat.com>
Date: Wed Jan 14 15:54:25 2026 +0100
kdump-lib-initramfs: Fix performance regression in kdump_get_conf_val
Rewriting kdump_get_conf_val in Bash lead to a massive performance
regression. On my test system starting the kdump service took
$ time kdumpctl start
real 0m13.134s
user 0m8.828s
sys 0m7.450s
which is ~20 times slower compared to kdump-utils-1.0.59-1.fc44 with
$ time kdumpctl start
real 0m0.641s
user 0m0.208s
sys 0m0.538s
Looking at the traces shows that this is caused because Bash now has to
handle the whole kdump.conf, including the extensive comment at the
start, every time kdump_get_conf_val is called. This is done multiple
times when starting the kdump service and is often cloaked by other
functions, e.g. is_ssh_dump_target() or get_save_path().
To fix the issue remove comments and empty lines in a regex again so
that the Bash code only has to handle valid config entries. With this
change alone the performance is almost as good as the original version
with
$ time kdumpctl start
real 0m0.780s
user 0m0.330s
sys 0m0.604s
In the long run it would make sense to also reduce the number of calls
to kdump_get_conf_val.
This patch also fixes the issue that subsequent blanks are replaced by a
single space. Usually this is not an issue but there are corner cases,
e.g. in printf-like format strings passed as an argument, where the new
behaviour is undesirable.
Fixes: d81109c ("kdump-lib-initramfs: rewrite kdump_get_conf_val")
Signed-off-by: Philipp Rudo <prudo@redhat.com>
Signed-off-by: Lichen Liu <lichliu@redhat.com>
This commit is contained in:
parent
d2709ce157
commit
065d73a90a
@ -27,38 +27,40 @@ kdump_get_conf_val()
|
||||
_found=""
|
||||
|
||||
[ -f "$KDUMP_CONFIG_FILE" ] || return
|
||||
while read -r _line; do
|
||||
_line="$(echo "$_line" | tr -s "[:blank:]" " ")"
|
||||
case "$_line" in
|
||||
"" | \#*)
|
||||
continue
|
||||
;;
|
||||
*\#*)
|
||||
_line="${_line%%\#*}"
|
||||
_line="${_line% }"
|
||||
;;
|
||||
esac
|
||||
|
||||
_opt=${_line%% *}
|
||||
_val=${_line#* }
|
||||
# On lines that are _not_ comments or empty remove...
|
||||
# Note: The additional braces {} are required as piping into a while
|
||||
# loop creates a sub-shell. So without the braces $_found would only be
|
||||
# set inside the loop but empty outside of it.
|
||||
grep -Ev -e '^\s*#' -e '^\s*$' "$KDUMP_CONFIG_FILE" | {
|
||||
while read -r _opt _val; do
|
||||
# ...trailing comments...
|
||||
case "$_val" in
|
||||
*\#*)
|
||||
_val="${_val%%#*}"
|
||||
_val="${_val%"${_val##*[![:space:]]}"}"
|
||||
;;
|
||||
esac
|
||||
|
||||
case "$_val" in
|
||||
\"*\")
|
||||
# Remove quotes
|
||||
_val="${_val#\"}"
|
||||
_val="${_val%\"}"
|
||||
;;
|
||||
esac
|
||||
# ...quotes
|
||||
case "$_val" in
|
||||
\"*\")
|
||||
_val="${_val#\"}"
|
||||
_val="${_val%\"}"
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -z "$_to_find" ]; then
|
||||
echo "$_opt $_val"
|
||||
elif echo "$_opt" | grep -q -E "^($_to_find)$"; then
|
||||
# make sure to only return the last match to mirror the
|
||||
# old behavior
|
||||
_found="$_val"
|
||||
fi
|
||||
done < "$KDUMP_CONFIG_FILE"
|
||||
[ -n "$_found" ] && echo "$_found"
|
||||
if [ -z "$_to_find" ]; then
|
||||
echo "$_opt $_val"
|
||||
elif echo "$_opt" | grep -q -E "^($_to_find)$"; then
|
||||
# make sure to only return the last match to
|
||||
# mirror the old behavior
|
||||
_found="$_val"
|
||||
fi
|
||||
done
|
||||
|
||||
[ -n "$_found" ] && echo "$_found"
|
||||
}
|
||||
|
||||
# make sure we return 0 even when a option isn't set
|
||||
return 0
|
||||
|
||||
Loading…
Reference in New Issue
Block a user