summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-x[-rw-r--r--]scripts/wsrep_sst_common.sh159
-rw-r--r--scripts/wsrep_sst_mariabackup.sh14
-rw-r--r--scripts/wsrep_sst_rsync.sh20
-rw-r--r--sql/wsrep_sst.cc199
4 files changed, 201 insertions, 191 deletions
diff --git a/scripts/wsrep_sst_common.sh b/scripts/wsrep_sst_common.sh
index d19a0dbfdd5..c98b388a1e2 100644..100755
--- a/scripts/wsrep_sst_common.sh
+++ b/scripts/wsrep_sst_common.sh
@@ -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 \
@@ -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
@@ -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
@@ -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
@@ -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
diff --git a/scripts/wsrep_sst_mariabackup.sh b/scripts/wsrep_sst_mariabackup.sh
index de789dc1728..899f3eb4f3c 100644
--- a/scripts/wsrep_sst_mariabackup.sh
+++ b/scripts/wsrep_sst_mariabackup.sh
@@ -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
@@ -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 "")
@@ -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
}
@@ -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
@@ -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
diff --git a/scripts/wsrep_sst_rsync.sh b/scripts/wsrep_sst_rsync.sh
index f32689a9e43..4f39835e15d 100644
--- a/scripts/wsrep_sst_rsync.sh
+++ b/scripts/wsrep_sst_rsync.sh
@@ -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
@@ -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
diff --git a/sql/wsrep_sst.cc b/sql/wsrep_sst.cc
index e8555bcfbe3..f6bc0e7c63f 100644
--- a/sql/wsrep_sst.cc
+++ b/sql/wsrep_sst.cc
@@ -729,6 +729,49 @@ static int sst_append_env_var(wsp::env& env,
return -env.error();
}
+#ifdef __WIN__
+/*
+ Space, single quote, ampersand, backquote, I/O redirection
+ characters, caret, all brackets, plus, exclamation and comma
+ characters require text to be enclosed in double quotes:
+*/
+#define IS_SPECIAL(c) \
+ (isspace(c) || c == '\'' || c == '&' || c == '`' || c == '|' || \
+ c == '>' || c == '<' || c == ';' || c == '^' || \
+ c == '[' || c == ']' || c == '{' || c == '}' || \
+ c == '(' || c == ')' || c == '+' || c == '!' || \
+ c == ',')
+/*
+ Inside values, equals character are interpreted as special
+ character and requires quotation:
+*/
+#define IS_SPECIAL_V(c) (IS_SPECIAL(c) || c == '=')
+/*
+ Double quotation mark and percent characters require escaping:
+*/
+#define IS_REQ_ESCAPING(c) (c == '""' || c == '%')
+#else
+/*
+ Space, single quote, ampersand, backquote, and I/O redirection
+ characters require text to be enclosed in double quotes. The
+ semicolon is used to separate shell commands, so it must be
+ enclosed in double quotes as well:
+*/
+#define IS_SPECIAL(c) \
+ (isspace(c) || c == '\'' || c == '&' || c == '`' || c == '|' || \
+ c == '>' || c == '<' || c == ';')
+/*
+ Inside values, characters are interpreted as in parameter names:
+*/
+#define IS_SPECIAL_V(c) IS_SPECIAL(c)
+/*
+ Double quotation mark and backslash characters require
+ backslash prefixing, the dollar symbol is used to substitute
+ a variable value, therefore it also requires escaping:
+*/
+#define IS_REQ_ESCAPING(c) (c == '"' || c == '\\' || c == '$')
+#endif
+
static size_t estimate_cmd_len (bool* extra_args)
{
/*
@@ -753,22 +796,16 @@ static size_t estimate_cmd_len (bool* extra_args)
char c;
while ((c = *arg++) != 0)
{
- /*
- Space, single quote, ampersand, and I/O redirection characters
- require text to be enclosed in double quotes:
- */
- if (isspace(c) || c == '\'' || c == '&' || c == '|' ||
-#ifdef __WIN__
- c == '>' || c == '<')
-#else
- /*
- The semicolon is used to separate shell commands, so it must be
- enclosed in double quotes as well:
- */
- c == '>' || c == '<' || c == ';')
-#endif
+ if (IS_SPECIAL(c))
+ {
+ quotation= true;
+ }
+ else if (IS_REQ_ESCAPING(c))
{
+ cmd_len++;
+#ifdef __WIN__
quotation= true;
+#endif
}
/*
If the equals symbol is encountered, then we need to separately
@@ -788,58 +825,20 @@ static size_t estimate_cmd_len (bool* extra_args)
}
while ((c = *arg++) != 0)
{
- /*
- Space, single quote, ampersand, and I/O redirection characters
- require text to be enclosed in double quotes:
- */
- if (isspace(c) || c == '\'' || c == '&' || c == '|' ||
-#ifdef __WIN__
- c == '>' || c == '<')
-#else
- /*
- The semicolon is used to separate shell commands, so it must be
- enclosed in double quotes as well:
- */
- c == '>' || c == '<' || c == ';')
-#endif
+ if (IS_SPECIAL_V(c))
{
quotation= true;
}
- /*
- Double quotation mark or backslash symbol requires backslash
- prefixing:
- */
-#ifdef __WIN__
- else if (c == '"' || c == '\\')
-#else
- /*
- The dollar symbol is used to substitute a variable, therefore
- it also requires escaping:
- */
- else if (c == '"' || c == '\\' || c == '$')
-#endif
+ else if (IS_REQ_ESCAPING(c))
{
cmd_len++;
+#ifdef __WIN__
+ quotation= true;
+#endif
}
}
break;
}
- /*
- Double quotation mark or backslash symbol requires backslash
- prefixing:
- */
-#ifdef __WIN__
- else if (c == '"' || c == '\\')
-#else
- /*
- The dollar symbol is used to substitute a variable, therefore
- it also requires escaping:
- */
- else if (c == '"' || c == '\\' || c == '$')
-#endif
- {
- cmd_len++;
- }
}
/* Perhaps we need to quote the entire argument or its right part: */
if (quotation)
@@ -882,22 +881,16 @@ static void copy_orig_argv (char* cmd_str)
char c;
while ((c = *arg_scan++) != 0)
{
- /*
- Space, single quote, ampersand, and I/O redirection characters
- require text to be enclosed in double quotes:
- */
- if (isspace(c) || c == '\'' || c == '&' || c == '|' ||
-#ifdef __WIN__
- c == '>' || c == '<')
-#else
- /*
- The semicolon is used to separate shell commands, so it must be
- enclosed in double quotes as well:
- */
- c == '>' || c == '<' || c == ';')
-#endif
+ if (IS_SPECIAL(c))
+ {
+ quotation= true;
+ }
+ else if (IS_REQ_ESCAPING(c))
{
+ plain= false;
+#ifdef __WIN__
quotation= true;
+#endif
}
/*
If the equals symbol is encountered, then we need to separately
@@ -933,13 +926,13 @@ static void copy_orig_argv (char* cmd_str)
while (m)
{
c = *arg++;
+ if (IS_REQ_ESCAPING(c))
+ {
#ifdef __WIN__
- if (c == '"' || c == '\\')
+ *cmd_str++ = c;
#else
- if (c == '"' || c == '\\' || c == '$')
-#endif
- {
*cmd_str++ = '\\';
+#endif
}
*cmd_str++ = c;
m--;
@@ -968,58 +961,20 @@ static void copy_orig_argv (char* cmd_str)
/* Let's deal with the left side of the expression: */
while ((c = *arg_scan++) != 0)
{
- /*
- Space, single quote, ampersand, and I/O redirection characters
- require text to be enclosed in double quotes:
- */
- if (isspace(c) || c == '\'' || c == '&' || c == '|' ||
-#ifdef __WIN__
- c == '>' || c == '<')
-#else
- /*
- The semicolon is used to separate shell commands, so it must be
- enclosed in double quotes as well:
- */
- c == '>' || c == '<' || c == ';')
-#endif
+ if (IS_SPECIAL_V(c))
{
quotation= true;
}
- /*
- Double quotation mark or backslash symbol requires backslash
- prefixing:
- */
-#ifdef __WIN__
- else if (c == '"' || c == '\\')
-#else
- /*
- The dollar symbol is used to substitute a variable, therefore
- it also requires escaping:
- */
- else if (c == '"' || c == '\\' || c == '$')
-#endif
+ else if (IS_REQ_ESCAPING(c))
{
plain= false;
+#ifdef __WIN__
+ quotation= true;
+#endif
}
}
break;
}
- /*
- Double quotation mark or backslash symbol requires backslash
- prefixing:
- */
-#ifdef __WIN__
- else if (c == '"' || c == '\\')
-#else
- /*
- The dollar symbol is used to substitute a variable, therefore
- it also requires escaping:
- */
- else if (c == '"' || c == '\\' || c == '$')
-#endif
- {
- plain= false;
- }
}
if (n)
{
@@ -1042,13 +997,13 @@ static void copy_orig_argv (char* cmd_str)
{
while ((c = *arg++) != 0)
{
+ if (IS_REQ_ESCAPING(c))
+ {
#ifdef __WIN__
- if (c == '"' || c == '\\')
+ *cmd_str++ = c;
#else
- if (c == '"' || c == '\\' || c == '$')
-#endif
- {
*cmd_str++ = '\\';
+#endif
}
*cmd_str++ = c;
}