summaryrefslogtreecommitdiff
path: root/sql/wsrep_sst.cc
diff options
context:
space:
mode:
authorJulius Goryavsky <julius.goryavsky@mariadb.com>2021-05-14 12:51:36 +0200
committerJulius Goryavsky <julius.goryavsky@mariadb.com>2021-05-17 15:08:40 +0200
commitf92cd0c56b81690c1e8df3b32be690e3d92877e8 (patch)
tree28c959c9f3b453c7e3113b1f7d828d2a4a45a05a /sql/wsrep_sst.cc
parent16437e5e25ce4223ac9f8a8609220d5f80b0a62a (diff)
downloadmariadb-git-f92cd0c56b81690c1e8df3b32be690e3d92877e8.tar.gz
MDEV-25669: SST scripts should check all server groups in config files
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.
Diffstat (limited to 'sql/wsrep_sst.cc')
-rw-r--r--sql/wsrep_sst.cc205
1 files changed, 80 insertions, 125 deletions
diff --git a/sql/wsrep_sst.cc b/sql/wsrep_sst.cc
index eac5093ae2a..b18315dd160 100644
--- a/sql/wsrep_sst.cc
+++ b/sql/wsrep_sst.cc
@@ -658,6 +658,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)
{
/*
@@ -682,22 +725,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
@@ -717,58 +754,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)
@@ -811,22 +810,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
@@ -862,13 +855,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--;
@@ -897,58 +890,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)
{
@@ -971,13 +926,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;
}
@@ -1355,7 +1310,7 @@ static int sst_donate_mysqldump (const char* addr,
WSREP_SST_OPT_GTID " '%s:%lld' "
WSREP_SST_OPT_GTID_DOMAIN_ID " '%d'"
"%s",
- addr, port, mysqld_port, mysqld_unix_port,
+ addr, port, mysqld_port, mysqld_unix_port,
wsrep_defaults_file, uuid_str,
(long long)seqno, wsrep_gtid_domain_id,
bypass ? " " WSREP_SST_OPT_BYPASS : "");
@@ -1479,7 +1434,7 @@ static int sst_flush_tables(THD* thd)
WSREP_WARN("Current client character set is non-supported parser character set: %s", current_charset->csname);
thd->variables.character_set_client = &my_charset_latin1;
WSREP_WARN("For SST temporally setting character set to : %s",
- my_charset_latin1.csname);
+ my_charset_latin1.csname);
}
if (run_sql_command(thd, "FLUSH TABLES WITH READ LOCK"))
@@ -1547,7 +1502,7 @@ static void sst_disallow_writes (THD* thd, bool yes)
WSREP_WARN("Current client character set is non-supported parser character set: %s", current_charset->csname);
thd->variables.character_set_client = &my_charset_latin1;
WSREP_WARN("For SST temporally setting character set to : %s",
- my_charset_latin1.csname);
+ my_charset_latin1.csname);
}
snprintf (query_str, query_max, "SET GLOBAL innodb_disallow_writes=%d",