From 0ff44ca6e8f8f0f744d9c7a0baa6a99b2c524cda Mon Sep 17 00:00:00 2001 From: Philipp Rudo Date: Mon, 3 Apr 2023 16:55:04 +0200 Subject: [PATCH] kdumpctl: fix is_dracut_mod_omitted The function is pretty broken right now. To start with the -o/--omit option allows a quoted, space separated list of modules. But using 'set' breaks quotation and thus only considers the first element in the list. Furthermore dracut uses getopt internally. This means that it is also possible to pass the list via --omit=. Fix the function by making use of getopt for parsing the dracut_args. While at it also add a test cases to cover the functions. Signed-off-by: Philipp Rudo Reviewed-by: Coiby Xu --- kdumpctl | 52 ++++++++++++++++++++++++++++------- kexec-tools.spec | 1 + spec/kdumpctl_general_spec.sh | 48 ++++++++++++++++++++++++++++++++ 3 files changed, 91 insertions(+), 10 deletions(-) diff --git a/kdumpctl b/kdumpctl index 330767b..2c647d6 100755 --- a/kdumpctl +++ b/kdumpctl @@ -45,23 +45,55 @@ if ! dlog_init; then exit 1 fi -# returns 0 when omission of a module is desired in dracut_args -# returns 1 otherwise -is_dracut_mod_omitted() +_get_dracut_arg() { - local dracut_args dracut_mod=$1 + local shortopt longopt n tmp + local -a _opt _ret - set -- $(kdump_get_conf_val dracut_args) - while [ $# -gt 0 ]; do + shortopt=$1; shift + longopt=$1; shift + n=0 + + if [[ -n $shortopt ]]; then + _opt+=(-o "${shortopt#-}:") + else + # getopt requires the -o/--option to be set. + _opt+=(-o "") + fi + [[ -n $longopt ]] && _opt+=(--long "${longopt#--}:") + + # make sure bash didn't break quoting + eval set -- "$*" + tmp=$( + unset POSIXLY_CORRECT + getopt -q "${_opt[@]}" -- "$@" + ) + eval set -- "$tmp" + while :; do case $1 in - -o | --omit) - [[ " ${2//[^[:alnum:]]/ } " == *" $dracut_mod "* ]] && return 0 - ;; + "$shortopt"|"$longopt") + _ret+=("$2"); shift + n=$((n+1)) + ;; + --|*) + break + ;; esac shift done - return 1 + echo "${_ret[@]}" + return $n +} + +is_dracut_mod_omitted() +{ + local mod omitted + + mod=$1 + omitted=$(_get_dracut_arg -o --omit "${OPT[dracut_args]}") + + [[ " $omitted " == *" $mod "* ]] } single_instance_lock() diff --git a/kexec-tools.spec b/kexec-tools.spec index 5c42af6..d2a8aca 100644 --- a/kexec-tools.spec +++ b/kexec-tools.spec @@ -65,6 +65,7 @@ Requires: dracut >= 050 Requires: dracut-network >= 050 Requires: dracut-squash >= 050 Requires: ethtool +Requires: util-linux Recommends: grubby Recommends: hostname BuildRequires: make diff --git a/spec/kdumpctl_general_spec.sh b/spec/kdumpctl_general_spec.sh index 41fbc29..bb5755c 100644 --- a/spec/kdumpctl_general_spec.sh +++ b/spec/kdumpctl_general_spec.sh @@ -107,6 +107,54 @@ Describe 'kdumpctl' End End + Describe "_get_dracut_arg" + dracut_args='-o "foo bar baz" -t 1 --test="a b c" --omit bla' + Parameters + -o --omit 2 "foo bar baz bla" + -e --empty 0 "" + -t "" 1 "1" + "" --test 1 "a b c" + "" "" 0 "" + End + It "should parse the dracut_args correctly" + When call _get_dracut_arg "$1" "$2" "$dracut_args" + The status should equal $3 + The output should equal "$4" + End + End + + Describe "is_dracut_mod_omitted()" + KDUMP_CONFIG_FILE=$(mktemp -t kdump_conf.XXXXXXXXXX) + cleanup() { + rm -f "$kdump_conf" + } + AfterAll 'cleanup' + + Parameters:dynamic + for opt in '-o ' '--omit ' '--omit='; do + for val in \ + 'foo' \ + '"foo"' \ + '"foo bar baz"' \ + '"bar foo baz"' \ + '"bar baz foo"'; do + %data success foo "$opt$val" + %data success foo "-a x $opt$val -i y" + %data failure xyz "$opt$val" + %data failure xyz "-a x $opt$val -i y" + done + done + %data success foo "-o xxx -o foo" + %data failure foo "-a x -i y" + End + It "shall return $1 for module $2 and dracut_args '$3'" + echo "dracut_args $3" > $KDUMP_CONFIG_FILE + parse_config + When call is_dracut_mod_omitted $2 + The status should be $1 + End + End + Describe '_update_kernel_arg_in_grub_etc_default()' GRUB_ETC_DEFAULT=/tmp/default_grub