Skip to content

Commit

Permalink
MDEV-25669: SST scripts should check all server groups in config files
Browse files Browse the repository at this point in the history
1) This commit implements reading all sections from configuration
files while looking for the current value of any server variable,
which were previously only read from the [mysqld.suffix] group and
from [mysqld], but not from other groups such as [mariadb.suffix],
[mariadb] or, for example, [server].

2) This commit also fixes misrecognition of some parameters when
parsing a command line containing a special marker for the end
of the list of options ("--") or when short option names (such
as "-s", "-a" and "-h arg") chained together (like a "-sah arg").
Such parameters can be passed to the SST script in the list of
arguments after "--mysqld-args" if the server is started with a
complex set of options - this was revealed during manual testing
of changes to read configuration files.

3) The server-side preparation code for the "--mysqld-args"
option list has also been simplified to make it easier to change
in the future (if needed), and has been improved to properly
handle the special backquote ("`") character in the argument
values.
  • Loading branch information
sysprg committed May 17, 2021
1 parent 16898e7 commit f9f8e33
Show file tree
Hide file tree
Showing 4 changed files with 201 additions and 191 deletions.
159 changes: 109 additions & 50 deletions scripts/wsrep_sst_common.sh
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -240,44 +240,108 @@ case "$1" in
original_cmd=""
shift
while [ $# -gt 0 ]; do
# check if the argument is the short option
# (starting with "-" instead of "--"):
if [ "${1#--}" = "$1" -a "${1#-}" != "$1" ]; then
option="${1#-}"
value=""
# check that the option value follows the name,
# without a space:
if [ ${#option} -gt 1 ]; then
# let's separate the first character as the option name,
# and the subsequent characters consider its value:
value="${1#-?}"
option="${1%$value}"
# check that the option name consists of one letter
# and there are the following arguments:
elif [ ${#option} -eq 1 -a $# -gt 1 ]; then
# if the next argument does not start with a "-" character,
# then this is the value of the current option:
if [ "${2#-}" = "$2" ]; then
value="$2"
lname="${1#--}"
# "--" is interpreted as the end of the list of options:
if [ -z "$lname" ]; then
shift
if [ $# -gt 0 ]; then
# copy "--" to the output string:
original_cmd="$original_cmd --"
# All other arguments must be copied unchanged:
while [ $# -gt 0 ]; do
original_cmd="$original_cmd '$1'"
shift
fi
done
fi
shift
if [ "$option" = 'h' ]; then
if [ -z "$WSREP_SST_OPT_DATA" ]; then
MYSQLD_OPT_DATADIR="${value%/}"
fi
elif [ "$option" != 'u' -a \
"$option" != 'P' ]; then
if [ -z "$original_cmd" ]; then
original_cmd="'-$option$value'"
else
original_cmd="$original_cmd '-$option$value'"
break;
fi
# Make sure the argument does not start with "--", otherwise it
# is a long option, which is processed after this "if":
if [ "$lname" = "$1" ]; then
# Check if the argument is the short option or the short
# options list, starting with "-":
options="${1#-}"
if [ "$options" != "$1" -a -n "$options" ]; then
slist=""
while [ -n "$options" ]; do
# Let's separate the first character as the current
# option name:
if [ -n "$BASH_VERSION" ]; then
option="${options:0:1}"
else
# If it's not bash, then we need to use slow
# external utilities:
option=$(echo "$options" | cut -c1-1)
fi
# And the subsequent characters consider option value:
value=""
if [ ${#options} -gt 0 ]; then
value="${options#?}"
fi
# Check for options without argument:
if [ "$option" != '?' -a \
"$option" != 'a' -a \
"$option" != 's' -a \
"$option" != 'v' ]
then
# If the option value is absent, then check
# the following argument:
if [ -z "$value" -a $# -gt 1 ]; then
# if the next argument does not start with
# the "-" character, then next argument is
# the current option value:
if [ "${2#-}" = "$2" ]; then
shift
value="$1"
fi
fi
if [ $option == 'h' ]; then
if [ -z "$WSREP_SST_OPT_DATA" ]; then
MYSQLD_OPT_DATADIR="${value%/}"
fi
elif [ $option != 'u' -a \
$option != 'P' ]
then
if [ -z "$value" ]; then
slist="$slist$option"
elif [ -z "$slist" ]; then
slist="$option '$value'"
else
slist="$slist -$option '$value'"
fi
fi
break

else
slist="$slist$option"
fi
options="$value"
done
if [ -n "$slist" ]; then
original_cmd="$original_cmd -$slist"
fi
elif [ -z "$options" ]; then
# We found an equal sign without any characters after it:
original_cmd="$original_cmd -"
else
# We found a value that does not start with a minus -
# it is a positional argument or the value of previous
# option. Copy it to output string (as is):
original_cmd="$original_cmd '$1'"
fi
shift
continue;
fi
# Now we are sure that we are working with an option
# that has a "long" name, so remove all characters after
# the first equal sign:
option="${1%%=*}"
# The "--loose-" prefix should not affect the recognition
# of the option name:
if [ "${option#--loose-}" != "$option" ]; then
option="--${option#--loose-}"
fi
# Some options just need to be removed from the list:
if [ "$option" != '--defaults-file' -a \
"$option" != '--defaults-extra-file' -a \
"$option" != '--defaults-group-suffix' -a \
Expand Down Expand Up @@ -340,22 +404,17 @@ case "$1" in
;;
esac
if [ $skip_mysqld_arg -eq 0 ]; then
if [ -z "$original_cmd" ]; then
original_cmd="'$1'"
else
original_cmd="$original_cmd '$1'"
fi
original_cmd="$original_cmd '$1'"
fi
fi
shift
fi
shift
done
WSREP_SST_OPT_MYSQLD="$original_cmd"
WSREP_SST_OPT_MYSQLD="${original_cmd# *}"
break
;;
*) # must be command
# usage
# exit 1
;;
*) # Must be command usage
# exit 1
;;
esac
shift
done
Expand Down Expand Up @@ -601,9 +660,9 @@ parse_cnf()
# of the groups list (as if it were a prefix):
groups="${groups#$group}"
groups="${groups#\|}"
# if the group name is the same as the "[--]mysqld", then
# try to use it together with the group suffix:
if [ "${group#--}" = 'mysqld' -a -n "$WSREP_SST_OPT_SUFFIX_VALUE" ]; then
# If the group name is the same as the "mysqld" without "--" prefix,
# then try to use it together with the group suffix:
if [ "$group" = 'mysqld' -a -n "$WSREP_SST_OPT_SUFFIX_VALUE" ]; then
reval=$($MY_PRINT_DEFAULTS "mysqld$WSREP_SST_OPT_SUFFIX_VALUE" | awk "$pattern")
if [ -n "$reval" ]; then
break
Expand All @@ -616,7 +675,7 @@ parse_cnf()
fi
done

# use default if we haven't found a value:
# Use default if we haven't found a value:
if [ -z "$reval" ]; then
[ -n "${3:-}" ] && reval="$3"
fi
Expand Down Expand Up @@ -648,9 +707,9 @@ in_config()
# of the groups list (as if it were a prefix):
groups="${groups#$group}"
groups="${groups#\|}"
# if the group name is the same as the "[--]mysqld", then
# try to use it together with the group suffix:
if [ "${group#--}" = 'mysqld' -a -n "$WSREP_SST_OPT_SUFFIX_VALUE" ]; then
# If the group name is the same as the "mysqld" without "--" prefix,
# then try to use it together with the group suffix:
if [ "$group" = 'mysqld' -a -n "$WSREP_SST_OPT_SUFFIX_VALUE" ]; then
found=$($MY_PRINT_DEFAULTS "mysqld$WSREP_SST_OPT_SUFFIX_VALUE" | awk "$pattern")
if [ $found -ne 0 ]; then
break
Expand Down
14 changes: 6 additions & 8 deletions scripts/wsrep_sst_mariabackup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,6 @@ read_cnf()
# avoid CA verification if not set explicitly:
# nodes may happen to have different CA if self-generated
# zeroing up tcert does the trick
local mode=$(parse_cnf 'sst' 'ssl-mode')
[ "${tmode#VERIFY}" != "$tmode" ] || tcert=""
fi
fi
Expand All @@ -421,8 +420,9 @@ read_cnf()
sockopt=$(parse_cnf sst sockopt "")
progress=$(parse_cnf sst progress "")
ttime=$(parse_cnf sst time 0)
cpat=$(parse_cnf sst cpat '.*galera\.cache$\|.*sst_in_progress$\|.*\.sst$\|.*gvwstate\.dat$\|.*grastate\.dat$\|.*\.err$\|.*\.log$\|.*RPM_UPGRADE_MARKER$\|.*RPM_UPGRADE_HISTORY$')
[ $OS = 'FreeBSD' ] && cpat=$(parse_cnf sst cpat '.*galera\.cache$|.*sst_in_progress$|.*\.sst$|.*gvwstate\.dat$|.*grastate\.dat$|.*\.err$|.*\.log$|.*RPM_UPGRADE_MARKER$|.*RPM_UPGRADE_HISTORY$')
cpat='.*galera\.cache$\|.*sst_in_progress$\|.*\.sst$\|.*gvwstate\.dat$\|.*grastate\.dat$\|.*\.err$\|.*\.log$\|.*RPM_UPGRADE_MARKER$\|.*RPM_UPGRADE_HISTORY$'
[ "$OS" = 'FreeBSD' ] && cpat=$(echo "$cpat" | sed 's/\\|/|/g')
cpat=$(parse_cnf sst cpat "$cpat")
scomp=$(parse_cnf sst compressor "")
sdecomp=$(parse_cnf sst decompressor "")

Expand All @@ -445,9 +445,7 @@ read_cnf()
fi

if [ $ssyslog -ne -1 ]; then
if $MY_PRINT_DEFAULTS mysqld_safe | grep -q -- "--syslog"; then
ssyslog=1
fi
ssyslog=$(in_config 'mysqld_safe' 'syslog')
fi
}

Expand Down Expand Up @@ -771,7 +769,7 @@ monitor_process()

while true ; do
if ! ps -p "$WSREP_SST_OPT_PARENT" &>/dev/null; then
wsrep_log_error "Parent mysqld process (PID:${WSREP_SST_OPT_PARENT}) terminated unexpectedly."
wsrep_log_error "Parent mysqld process (PID: $WSREP_SST_OPT_PARENT) terminated unexpectedly."
exit 32
fi
if ! ps -p "$sst_stream_pid" &>/dev/null; then
Expand Down Expand Up @@ -1139,7 +1137,7 @@ then

if ! ps -p "$WSREP_SST_OPT_PARENT" &>/dev/null
then
wsrep_log_error "Parent mysqld process (PID:${WSREP_SST_OPT_PARENT}) terminated unexpectedly."
wsrep_log_error "Parent mysqld process (PID: $WSREP_SST_OPT_PARENT) terminated unexpectedly."
exit 32
fi

Expand Down
20 changes: 9 additions & 11 deletions scripts/wsrep_sst_rsync.sh
Original file line number Diff line number Diff line change
Expand Up @@ -218,23 +218,21 @@ SSTKEY=$(parse_cnf 'sst' 'tkey')
SSTCERT=$(parse_cnf 'sst' 'tcert')
SSTCA=$(parse_cnf 'sst' 'tca')

SST_SECTIONS="--mysqld|sst"

check_server_ssl_config()
{
local section="$1"
SSTKEY=$(parse_cnf "$section" 'ssl-key')
SSTCERT=$(parse_cnf "$section" 'ssl-cert')
SSTCA=$(parse_cnf "$section" 'ssl-ca')
SSTKEY=$(parse_cnf "$SST_SECTIONS" 'ssl-key')
SSTCERT=$(parse_cnf "$SST_SECTIONS" 'ssl-cert')
SSTCA=$(parse_cnf "$SST_SECTIONS" 'ssl-ca')
}

SSLMODE=$(parse_cnf 'sst' 'ssl-mode' | tr [:lower:] [:upper:])
SSLMODE=$(parse_cnf "$SST_SECTIONS" 'ssl-mode' | tr [:lower:] [:upper:])

# no old-style SSL config in [sst], check for new one:
if [ -z "$SSTKEY" -a -z "$SSTCERT" -a -z "$SSTCA" ]
then
# no old-style SSL config in [sst], check for new one
check_server_ssl_config 'sst'
if [ -z "$SSTKEY" -a -z "$SSTCERT" -a -z "$SSTCA" ]; then
check_server_ssl_config '--mysqld'
fi
check_server_ssl_config
fi

if [ -z "$SSLMODE" ]; then
Expand Down Expand Up @@ -602,7 +600,7 @@ EOF
if ! ps -p $MYSQLD_PID >/dev/null
then
wsrep_log_error \
"Parent mysqld process (PID:$MYSQLD_PID) terminated unexpectedly."
"Parent mysqld process (PID: $MYSQLD_PID) terminated unexpectedly."
kill -- -$MYSQLD_PID
sleep 1
exit 32
Expand Down
Loading

0 comments on commit f9f8e33

Please sign in to comment.