Commit 32d884c9 authored by Julius Goryavsky's avatar Julius Goryavsky

Merge branch 'sst-ssl-fixes-10.2' of...

Merge branch 'sst-ssl-fixes-10.2' of https://github.com/codership/mariadb-server into codership-sst-ssl-fixes-10.2
parents 7345d371 2dce82f1
SELECT 1; SELECT 1;
1 1
1 1
include/assert_grep.inc [Using openssl based encryption with socat]
SELECT 1;
1
1
include/assert_grep.inc [Using openssl based encryption with socat]
# #
# This test checks that key and cert encryption options can be passed to mariabackup via the my.cnf file # This test checks that key and cert encryption options can be passed to
# Initial SST happens via mariabackup, so there is not much to do in the body of the test # mariabackup via the my.cnf file
# Initial SST happens via mariabackup, so there is not much to do in the body
# of the test
# #
--source include/big_test.inc --source include/big_test.inc
...@@ -12,3 +14,11 @@ SELECT 1; ...@@ -12,3 +14,11 @@ SELECT 1;
--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; --let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
--source include/wait_condition.inc --source include/wait_condition.inc
# Confirm that transfer was SSL-encrypted
--let $assert_text = Using openssl based encryption with socat
--let $assert_select = Using openssl based encryption with socat: with key and crt
--let $assert_count = 1
--let $assert_file = $MYSQLTEST_VARDIR/log/mysqld.1.err
--let $assert_only_after = CURRENT_TEST
--source include/assert_grep.inc
!include ../galera_2nodes.cnf
[mysqld]
wsrep_sst_method=mariabackup
wsrep_sst_auth="root:"
wsrep_debug=ON
ssl-cert=@ENV.MYSQL_TEST_DIR/std_data/client-cert.pem
ssl-key=@ENV.MYSQL_TEST_DIR/std_data/client-key.pem
ssl-ca=@ENV.MYSQL_TEST_DIR/std_data/cacert.pem
[sst]
ssl-mode=VERIFY_CA
\ No newline at end of file
#
# This test checks that if SST SSL is not explicitly donfigured mariabackup SST
# uses server SSL configuration if present.
# Initial SST happens via mariabackup, so there is not much to do in the body
# of the test
#
--source include/big_test.inc
--source include/galera_cluster.inc
--source include/have_innodb.inc
--source include/have_mariabackup.inc
--source include/have_ssl_communication.inc
SELECT 1;
--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
--source include/wait_condition.inc
# Confirm that transfer was SSL-encrypted
--let $assert_text = Using openssl based encryption with socat
--let $assert_select = Using openssl based encryption with socat: with key and c
--let $assert_count = 1
--let $assert_file = $MYSQLTEST_VARDIR/log/mysqld.1.err
--let $assert_only_after = CURRENT_TEST
--source include/assert_grep.inc
...@@ -25,6 +25,7 @@ WSREP_SST_OPT_DATA="" ...@@ -25,6 +25,7 @@ WSREP_SST_OPT_DATA=""
WSREP_SST_OPT_AUTH=${WSREP_SST_OPT_AUTH:-} WSREP_SST_OPT_AUTH=${WSREP_SST_OPT_AUTH:-}
WSREP_SST_OPT_USER=${WSREP_SST_OPT_USER:-} WSREP_SST_OPT_USER=${WSREP_SST_OPT_USER:-}
WSREP_SST_OPT_PSWD=${WSREP_SST_OPT_PSWD:-} WSREP_SST_OPT_PSWD=${WSREP_SST_OPT_PSWD:-}
WSREP_SST_OPT_REMOTE_AUTH=${WSREP_SST_OPT_REMOTE_AUTH:-}
WSREP_SST_OPT_DEFAULT="" WSREP_SST_OPT_DEFAULT=""
WSREP_SST_OPT_EXTRA_DEFAULT="" WSREP_SST_OPT_EXTRA_DEFAULT=""
WSREP_SST_OPT_SUFFIX_DEFAULT="" WSREP_SST_OPT_SUFFIX_DEFAULT=""
...@@ -34,6 +35,7 @@ INNODB_DATA_HOME_DIR_ARG="" ...@@ -34,6 +35,7 @@ INNODB_DATA_HOME_DIR_ARG=""
INNODB_LOG_GROUP_HOME_ARG="" INNODB_LOG_GROUP_HOME_ARG=""
INNODB_UNDO_DIR_ARG="" INNODB_UNDO_DIR_ARG=""
LOG_BIN_ARG="" LOG_BIN_ARG=""
readonly WSREP_SST_OPT_REMOTE_AUTH
while [ $# -gt 0 ]; do while [ $# -gt 0 ]; do
case "$1" in case "$1" in
...@@ -121,7 +123,8 @@ case "$1" in ...@@ -121,7 +123,8 @@ case "$1" in
WSREP_SST_OPT_BYPASS=1 WSREP_SST_OPT_BYPASS=1
;; ;;
'--datadir') '--datadir')
readonly WSREP_SST_OPT_DATA="$2" # strip trailing '/'
readonly WSREP_SST_OPT_DATA="${2%/}"
shift shift
;; ;;
'--innodb-data-home-dir') '--innodb-data-home-dir')
...@@ -320,12 +323,22 @@ readonly WSREP_SST_OPT_AUTH ...@@ -320,12 +323,22 @@ readonly WSREP_SST_OPT_AUTH
# Splitting AUTH into potential user:password pair # Splitting AUTH into potential user:password pair
if ! wsrep_auth_not_set if ! wsrep_auth_not_set
then then
WSREP_SST_OPT_USER="${WSREP_SST_OPT_AUTH%%:*}" WSREP_SST_OPT_USER="${WSREP_SST_OPT_AUTH%:*}"
WSREP_SST_OPT_PSWD="${WSREP_SST_OPT_AUTH##*:}" WSREP_SST_OPT_PSWD="${WSREP_SST_OPT_AUTH##*:}"
fi fi
readonly WSREP_SST_OPT_USER readonly WSREP_SST_OPT_USER
readonly WSREP_SST_OPT_PSWD readonly WSREP_SST_OPT_PSWD
if [ -n "$WSREP_SST_OPT_REMOTE_AUTH" ]
then
# Split auth string at the last ':'
readonly WSREP_SST_OPT_REMOTE_USER="${WSREP_SST_OPT_REMOTE_AUTH%:*}"
readonly WSREP_SST_OPT_REMOTE_PSWD="${WSREP_SST_OPT_REMOTE_AUTH##*:}"
else
readonly WSREP_SST_OPT_REMOTE_USER=
readonly WSREP_SST_OPT_REMOTE_PSWD=
fi
if [ -n "${WSREP_SST_OPT_DATA:-}" ] if [ -n "${WSREP_SST_OPT_DATA:-}" ]
then then
SST_PROGRESS_FILE="$WSREP_SST_OPT_DATA/sst_in_progress" SST_PROGRESS_FILE="$WSREP_SST_OPT_DATA/sst_in_progress"
...@@ -385,6 +398,19 @@ wsrep_check_programs() ...@@ -385,6 +398,19 @@ wsrep_check_programs()
return $ret return $ret
} }
# Generate a string equivalent to 16 random bytes
wsrep_gen_secret()
{
if [ -x /usr/bin/openssl ]
then
echo `/usr/bin/openssl rand -hex 16`
else
printf "%04x%04x%04x%04x%04x%04x%04x%04x" \
$RANDOM $RANDOM $RANDOM $RANDOM \
$RANDOM $RANDOM $RANDOM $RANDOM
fi
}
# #
# user can specify mariabackup specific settings that will be used during sst # user can specify mariabackup specific settings that will be used during sst
# process like encryption, etc..... # process like encryption, etc.....
...@@ -396,14 +422,22 @@ wsrep_check_programs() ...@@ -396,14 +422,22 @@ wsrep_check_programs()
parse_cnf() parse_cnf()
{ {
local group=$1 local group=$1
local var=$2 local var=${2//_/-} # normalize variable name by replacing all '_' with '-'
local reval="" local reval=""
# normalize the variable names specified in cnf file (user can use _ or - for example log-bin or log_bin) # first normalize output variable names specified in cnf file:
# user can use _ or - (for example log-bin or log_bin) and/or prefix
# variable with --loose-
# then search for needed variable # then search for needed variable
# finally get the variable value (if variables has been specified multiple time use the last value only) # finally get the variable value (if variables has been specified multiple time use the last value only)
reval=$($MY_PRINT_DEFAULTS "${group}" | awk -v var="${var}" 'BEGIN { OFS=FS="=" } { gsub(/_/,"-",$1); if ( $1=="--"var) lastval=substr($0,length($1)+2) } END { print lastval}') reval=$($MY_PRINT_DEFAULTS "${group}" | \
awk -v var="${var}" 'BEGIN { OFS=FS="=" } \
{ sub(/^--loose/,"-",$0); \
gsub(/_/,"-",$1); \
if ( $1=="--"var) \
lastval=substr($0,length($1)+2) } \
END { print lastval}')
# use default if we haven't found a value # use default if we haven't found a value
if [ -z "$reval" ]; then if [ -z "$reval" ]; then
......
...@@ -37,6 +37,7 @@ REMOTEIP="" ...@@ -37,6 +37,7 @@ REMOTEIP=""
tcert="" tcert=""
tpem="" tpem=""
tkey="" tkey=""
tmode="DISABLED"
sockopt="" sockopt=""
progress="" progress=""
ttime=0 ttime=0
...@@ -72,6 +73,8 @@ xtmpdir="" ...@@ -72,6 +73,8 @@ xtmpdir=""
scomp="" scomp=""
sdecomp="" sdecomp=""
readonly SECRET_TAG="secret"
# Required for backup locks # Required for backup locks
# For backup locks it is 1 sent by joiner # For backup locks it is 1 sent by joiner
# 5.6.21 PXC and later can't donate to an older joiner # 5.6.21 PXC and later can't donate to an older joiner
...@@ -264,24 +267,30 @@ get_transfer() ...@@ -264,24 +267,30 @@ get_transfer()
exit 22 exit 22
fi fi
stagemsg+="-OpenSSL-Encrypted-3" stagemsg+="-OpenSSL-Encrypted-3"
if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then if [[ -z $tcert ]];then
if [[ -z $tcert ]];then # no verification
if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then
wsrep_log_info "Decrypting with cert=${tpem}, key=${tkey}, verify=0" wsrep_log_info "Decrypting with cert=${tpem}, key=${tkey}, verify=0"
tcmd="socat -u openssl-listen:${TSST_PORT},reuseaddr,cert=${tpem},key=${tkey},verify=0${sockopt} stdio" tcmd="socat -u openssl-listen:${TSST_PORT},reuseaddr,cert=${tpem},key=${tkey},verify=0${sockopt} stdio"
else else
wsrep_log_info "Decrypting with cert=${tpem}, key=${tkey}, cafile=${tcert}"
tcmd="socat -u openssl-listen:${TSST_PORT},reuseaddr,cert=${tpem},key=${tkey},cafile=${tcert}${sockopt} stdio"
fi
else
if [[ -z $tcert ]];then
wsrep_log_info "Encrypting with cert=${tpem}, key=${tkey}, verify=0" wsrep_log_info "Encrypting with cert=${tpem}, key=${tkey}, verify=0"
tcmd="socat -u stdio openssl-connect:${REMOTEIP}:${TSST_PORT},cert=${tpem},key=${tkey},verify=0${sockopt}" tcmd="socat -u stdio openssl-connect:${REMOTEIP}:${TSST_PORT},cert=${tpem},key=${tkey},verify=0${sockopt}"
fi
else
# CA verification
if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then
wsrep_log_info "Decrypting with cert=${tpem}, key=${tkey}, cafile=${tcert}"
tcmd="socat -u openssl-listen:${TSST_PORT},reuseaddr,cert=${tpem},key=${tkey},cafile=${tcert}${sockopt} stdio"
else else
if [ -n "$WSREP_SST_OPT_REMOTE_USER" ]; then
CN_option=",commonname=$WSREP_SST_OPT_REMOTE_USER"
else
CN_option=""
fi
wsrep_log_info "Encrypting with cert=${tpem}, key=${tkey}, cafile=${tcert}" wsrep_log_info "Encrypting with cert=${tpem}, key=${tkey}, cafile=${tcert}"
tcmd="socat -u stdio openssl-connect:${REMOTEIP}:${TSST_PORT},cert=${tpem},key=${tkey},cafile=${tcert}${sockopt}" tcmd="socat -u stdio openssl-connect:${REMOTEIP}:${TSST_PORT},cert=${tpem},key=${tkey},cafile=${tcert}${CN_option}${sockopt}"
fi fi
fi fi
else else
if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then
tcmd="socat -u TCP-LISTEN:${TSST_PORT},reuseaddr${sockopt} stdio" tcmd="socat -u TCP-LISTEN:${TSST_PORT},reuseaddr${sockopt} stdio"
...@@ -290,7 +299,6 @@ get_transfer() ...@@ -290,7 +299,6 @@ get_transfer()
fi fi
fi fi
fi fi
} }
parse_cnf() parse_cnf()
...@@ -298,10 +306,17 @@ parse_cnf() ...@@ -298,10 +306,17 @@ parse_cnf()
local group=$1 local group=$1
local var=$2 local var=$2
# print the default settings for given group using my_print_default. # print the default settings for given group using my_print_default.
# remove possible 'loose' variable name prefix
# normalize the variable names specified in cnf file (user can use _ or - for example log-bin or log_bin) # normalize the variable names specified in cnf file (user can use _ or - for example log-bin or log_bin)
# then grep for needed variable # then grep for needed variable
# finally get the variable value (if variables has been specified multiple time use the last value only) # finally get the variable value (if variables has been specified multiple time use the last value only)
reval=$($MY_PRINT_DEFAULTS $group | awk -F= '{if ($1 ~ /_/) { gsub(/_/,"-",$1); print $1"="$2 } else { print $0 }}' | grep -- "--$var=" | cut -d= -f2- | tail -1) reval=$($MY_PRINT_DEFAULTS $group | \
awk -F= '{ sub(/^--loose/,"-",$0); \
if ($1 ~ /_/) \
{ gsub(/_/,"-",$1); print $1"="$2 } \
else \
{ print $0 }}' | \
grep -- "--$var=" | cut -d= -f2- | tail -1)
if [[ -z $reval ]];then if [[ -z $reval ]];then
[[ -n $3 ]] && reval=$3 [[ -n $3 ]] && reval=$3
fi fi
...@@ -351,6 +366,24 @@ adjust_progress() ...@@ -351,6 +366,24 @@ adjust_progress()
fi fi
} }
check_server_ssl_config()
{
local section=$1
tcert=$(parse_cnf $section ssl-ca "")
tpem=$(parse_cnf $section ssl-cert "")
tkey=$(parse_cnf $section ssl-key "")
if [ 0 -eq $encrypt -a -n "$tpem" -a -n "$tkey" ]
then
encrypt=3 # enable cert/key SSL encyption
# 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* ]] || tcert=""
fi
}
read_cnf() read_cnf()
{ {
sfmt=$(parse_cnf sst streamfmt "xbstream") sfmt=$(parse_cnf sst streamfmt "xbstream")
...@@ -359,6 +392,26 @@ read_cnf() ...@@ -359,6 +392,26 @@ read_cnf()
tpem=$(parse_cnf sst tcert "") tpem=$(parse_cnf sst tcert "")
tkey=$(parse_cnf sst tkey "") tkey=$(parse_cnf sst tkey "")
encrypt=$(parse_cnf sst encrypt 0) encrypt=$(parse_cnf sst encrypt 0)
tmode=$(parse_cnf sst ssl-mode "DISABLED" | tr [:lower:] [:upper:])
if [ -z "$tpem" -a -z "$tkey" -a -z "$tcert" ]
then # no old-style SSL config in [sst]
if [ "$tmode" != "DISABLED" ]
then # backward-incompatible behavior
check_server_ssl_config "sst"
if [ -z "$tpem" -a -z "$tkey" -a -z "$tcert" ]
then # no new-stype SSL config in [sst], try server-wide SSL config
check_server_ssl_config "mysqld.$WSREP_SST_OPT_SUFFIX_VALUE"
if [ -z "$tpem" -a -z "$tkey" -a -z "$tcert" ]
then
check_server_ssl_config "mysqld"
fi
fi
fi
fi
wsrep_log_info "SSL configuration: CA='"$tcert"', CERT='"$tpem"'," \
"KEY='"$tkey"', MODE='"$tmode"', encrypt="$encrypt
sockopt=$(parse_cnf sst sockopt "") sockopt=$(parse_cnf sst sockopt "")
progress=$(parse_cnf sst progress "") progress=$(parse_cnf sst progress "")
rebuild=$(parse_cnf sst rebuild 0) rebuild=$(parse_cnf sst rebuild 0)
...@@ -404,7 +457,7 @@ read_cnf() ...@@ -404,7 +457,7 @@ read_cnf()
if [[ $encrypt -eq 1 ]]; then if [[ $encrypt -eq 1 ]]; then
wsrep_log_error "Xtrabackup-based encryption is currently not" \ wsrep_log_error "Xtrabackup-based encryption is currently not" \
"supported with MariaBackup" "supported with MariaBackup"
exit 2 exit 2
fi fi
} }
...@@ -631,8 +684,8 @@ recv_joiner() ...@@ -631,8 +684,8 @@ recv_joiner()
popd 1>/dev/null popd 1>/dev/null
if [[ ${RC[0]} -eq 124 ]];then if [[ ${RC[0]} -eq 124 ]];then
wsrep_log_error "Possible timeout in receiving first data from " wsrep_log_error "Possible timeout in receiving first data from " \
"donor in gtid stage: exit codes: ${RC[@]}" "donor in gtid stage: exit codes: ${RC[@]}"
exit 32 exit 32
fi fi
...@@ -644,12 +697,27 @@ recv_joiner() ...@@ -644,12 +697,27 @@ recv_joiner()
fi fi
done done
if [[ $checkf -eq 1 && ! -r "${MAGIC_FILE}" ]];then if [[ $checkf -eq 1 ]]; then
# this message should cause joiner to abort if [[ ! -r "${MAGIC_FILE}" ]];then
wsrep_log_error "xtrabackup process ended without creating '${MAGIC_FILE}'" # this message should cause joiner to abort
wsrep_log_info "Contents of datadir" wsrep_log_error "receiving process ended without creating " \
wsrep_log_info "$(ls -l ${dir}/*)" "'${MAGIC_FILE}'"
exit 32 wsrep_log_info "Contents of datadir"
wsrep_log_info "$(ls -l ${dir}/*)"
exit 32
fi
# check donor supplied secret
SECRET=$(grep "$SECRET_TAG " ${MAGIC_FILE} 2>/dev/null | cut -d ' ' -f 2)
if [[ $SECRET != $MY_SECRET ]]; then
wsrep_log_error "Donor does not know my secret!"
wsrep_log_info "Donor:'$SECRET', my:'$MY_SECRET'"
exit 32
fi
# remove secret from magic file
grep -v "$SECRET_TAG " ${MAGIC_FILE} > ${MAGIC_FILE}.new
mv ${MAGIC_FILE}.new ${MAGIC_FILE}
fi fi
} }
...@@ -665,10 +733,9 @@ send_donor() ...@@ -665,10 +733,9 @@ send_donor()
set -e set -e
popd 1>/dev/null popd 1>/dev/null
for ecode in "${RC[@]}";do for ecode in "${RC[@]}";do
if [[ $ecode -ne 0 ]];then if [[ $ecode -ne 0 ]];then
wsrep_log_error "Error while getting data from donor node: " \ wsrep_log_error "Error while sending data to joiner node: " \
"exit codes: ${RC[@]}" "exit codes: ${RC[@]}"
exit 32 exit 32
fi fi
...@@ -891,6 +958,11 @@ then ...@@ -891,6 +958,11 @@ then
# (separated by a space). # (separated by a space).
echo "${WSREP_SST_OPT_GTID} ${WSREP_SST_OPT_GTID_DOMAIN_ID}" > "${MAGIC_FILE}" echo "${WSREP_SST_OPT_GTID} ${WSREP_SST_OPT_GTID_DOMAIN_ID}" > "${MAGIC_FILE}"
if [[ -n ${WSREP_SST_OPT_REMOTE_PSWD} ]]; then
# Let joiner know that we know its secret
echo "$SECRET_TAG ${WSREP_SST_OPT_REMOTE_PSWD}" >> ${MAGIC_FILE}
fi
ttcmd="$tcmd" ttcmd="$tcmd"
if [[ $encrypt -eq 1 ]];then if [[ $encrypt -eq 1 ]];then
...@@ -1003,7 +1075,6 @@ then ...@@ -1003,7 +1075,6 @@ then
stagemsg="Joiner-Recv" stagemsg="Joiner-Recv"
sencrypted=1 sencrypted=1
nthreads=1 nthreads=1
...@@ -1025,7 +1096,26 @@ then ...@@ -1025,7 +1096,26 @@ then
fi fi
fi fi
wait_for_listen ${SST_PORT} ${ADDR} ${MODULE} & if [[ "$tmode" = *"VERIFY"* ]]
then # backward-incompatible behavior
if [ -n "$tpem" ]
then
# find out my Common Name
wsrep_check_programs openssl
CN=$(openssl x509 -noout -subject -in $tpem | \
tr "," "\n" | grep "CN =" | cut -d= -f2 | sed s/^\ // | \
sed s/\ %//)
else
CN=""
fi
MY_SECRET=$(wsrep_gen_secret)
# Add authentication data to address
ADDR="$CN:$MY_SECRET@$ADDR"
else
MY_SECRET="" # for check down in recv_joiner()
fi # tmode == *VERIFY*
wait_for_listen ${SST_PORT} "${ADDR}" ${MODULE} &
trap sig_joiner_cleanup HUP PIPE INT TERM trap sig_joiner_cleanup HUP PIPE INT TERM
trap cleanup_joiner EXIT trap cleanup_joiner EXIT
......
...@@ -637,49 +637,30 @@ static void* sst_joiner_thread (void* a) ...@@ -637,49 +637,30 @@ static void* sst_joiner_thread (void* a)
return NULL; return NULL;
} }
#define WSREP_SST_AUTH_ENV "WSREP_SST_OPT_AUTH" #define WSREP_SST_AUTH_ENV "WSREP_SST_OPT_AUTH"
#define WSREP_SST_REMOTE_AUTH_ENV "WSREP_SST_OPT_REMOTE_AUTH"
#define DATA_HOME_DIR_ENV "INNODB_DATA_HOME_DIR"
static int sst_append_auth_env(wsp::env& env, const char* sst_auth) static int sst_append_env_var(wsp::env& env,
const char* const var,
const char* const val)
{ {
int const sst_auth_size= strlen(WSREP_SST_AUTH_ENV) + 1 /* = */ int const env_str_size= strlen(var) + 1 /* = */
+ (sst_auth ? strlen(sst_auth) : 0) + 1 /* \0 */; + (val ? strlen(val) : 0) + 1 /* \0 */;
wsp::string sst_auth_str(sst_auth_size); // for automatic cleanup on return wsp::string env_str(env_str_size); // for automatic cleanup on return
if (!sst_auth_str()) return -ENOMEM; if (!env_str()) return -ENOMEM;
int ret= snprintf(sst_auth_str(), sst_auth_size, "%s=%s", int ret= snprintf(env_str(), env_str_size, "%s=%s", var, val ? val : "");
WSREP_SST_AUTH_ENV, sst_auth ? sst_auth : "");
if (ret < 0 || ret >= sst_auth_size) if (ret < 0 || ret >= env_str_size)
{ {
WSREP_ERROR("sst_append_auth_env(): snprintf() failed: %d", ret); WSREP_ERROR("sst_append_env_var(): snprintf(%s=%s) failed: %d",
var, val, ret);
return (ret < 0 ? ret : -EMSGSIZE); return (ret < 0 ? ret : -EMSGSIZE);
} }
env.append(sst_auth_str()); env.append(env_str());
return -env.error();
}
#define DATA_HOME_DIR_ENV "INNODB_DATA_HOME_DIR"
static int sst_append_data_dir(wsp::env& env, const char* data_dir)
{
int const data_dir_size= strlen(DATA_HOME_DIR_ENV) + 1 /* = */
+ (data_dir ? strlen(data_dir) : 0) + 1 /* \0 */;
wsp::string data_dir_str(data_dir_size); // for automatic cleanup on return
if (!data_dir_str()) return -ENOMEM;
int ret= snprintf(data_dir_str(), data_dir_size, "%s=%s",
DATA_HOME_DIR_ENV, data_dir ? data_dir : "");
if (ret < 0 || ret >= data_dir_size)
{
WSREP_ERROR("sst_append_data_dir(): snprintf() failed: %d", ret);
return (ret < 0 ? ret : -EMSGSIZE);
}
env.append(data_dir_str());
return -env.error(); return -env.error();
} }
...@@ -1090,7 +1071,7 @@ static ssize_t sst_prepare_other (const char* method, ...@@ -1090,7 +1071,7 @@ static ssize_t sst_prepare_other (const char* method,
return -env.error(); return -env.error();
} }
if ((ret= sst_append_auth_env(env, sst_auth))) if ((ret= sst_append_env_var(env, WSREP_SST_AUTH_ENV, sst_auth)))
{ {
WSREP_ERROR("sst_prepare_other(): appending auth failed: %d", ret); WSREP_ERROR("sst_prepare_other(): appending auth failed: %d", ret);
return ret; return ret;
...@@ -1098,7 +1079,7 @@ static ssize_t sst_prepare_other (const char* method, ...@@ -1098,7 +1079,7 @@ static ssize_t sst_prepare_other (const char* method,
if (data_home_dir) if (data_home_dir)
{ {
if ((ret= sst_append_data_dir(env, data_home_dir))) if ((ret= sst_append_env_var(env, DATA_HOME_DIR_ENV, data_home_dir)))
{ {
WSREP_ERROR("sst_prepare_other(): appending data " WSREP_ERROR("sst_prepare_other(): appending data "
"directory failed: %d", ret); "directory failed: %d", ret);
...@@ -1275,12 +1256,12 @@ ssize_t wsrep_sst_prepare (void** msg) ...@@ -1275,12 +1256,12 @@ ssize_t wsrep_sst_prepare (void** msg)
*msg = malloc (msg_len); *msg = malloc (msg_len);
if (NULL != *msg) { if (NULL != *msg) {
char* const method_ptr(reinterpret_cast<char*>(*msg)); char* const method_ptr(static_cast<char*>(*msg));
strcpy (method_ptr, wsrep_sst_method); strcpy (method_ptr, wsrep_sst_method);
char* const addr_ptr(method_ptr + method_len + 1); char* const addr_ptr(method_ptr + method_len + 1);
strcpy (addr_ptr, addr_out); strcpy (addr_ptr, addr_out);
WSREP_INFO ("Prepared SST request: %s|%s", method_ptr, addr_ptr); WSREP_DEBUG("Prepared SST request: %s|%s", method_ptr, addr_ptr);
} }
else { else {
WSREP_ERROR("Failed to allocate SST request of size %zu. Can't continue.", WSREP_ERROR("Failed to allocate SST request of size %zu. Can't continue.",
...@@ -1733,6 +1714,7 @@ static int sst_donate_other (const char* method, ...@@ -1733,6 +1714,7 @@ static int sst_donate_other (const char* method,
"wsrep_sst_%s " "wsrep_sst_%s "
WSREP_SST_OPT_ROLE " 'donor' " WSREP_SST_OPT_ROLE " 'donor' "
WSREP_SST_OPT_ADDR " '%s' " WSREP_SST_OPT_ADDR " '%s' "
WSREP_SST_OPT_LPORT " '%u' "
WSREP_SST_OPT_SOCKET " '%s' " WSREP_SST_OPT_SOCKET " '%s' "
WSREP_SST_OPT_DATA " '%s' " WSREP_SST_OPT_DATA " '%s' "
"%s" "%s"
...@@ -1740,7 +1722,8 @@ static int sst_donate_other (const char* method, ...@@ -1740,7 +1722,8 @@ static int sst_donate_other (const char* method,
WSREP_SST_OPT_GTID_DOMAIN_ID " '%d'" WSREP_SST_OPT_GTID_DOMAIN_ID " '%d'"
"%s" "%s"
"%s", "%s",
method, addr, mysqld_unix_port, mysql_real_data_home, method, addr, mysqld_port, mysqld_unix_port,
mysql_real_data_home,
wsrep_defaults_file, wsrep_defaults_file,
uuid, (long long) seqno, wsrep_gtid_domain_id, uuid, (long long) seqno, wsrep_gtid_domain_id,
binlog_opt_val, binlog_opt_val,
...@@ -1820,7 +1803,21 @@ wsrep_cb_status_t wsrep_sst_donate_cb (void* app_ctx, void* recv_ctx, ...@@ -1820,7 +1803,21 @@ wsrep_cb_status_t wsrep_sst_donate_cb (void* app_ctx, void* recv_ctx,
const char* data = method + method_len + 1; const char* data = method + method_len + 1;
if (check_request_str(data, address_char)) /* check for auth@addr separator */
const char* addr= strrchr(data, '@');
wsp::string remote_auth;
if (addr)
{
remote_auth.set(strndup(data, addr - data));
addr++;
}
else
{
// no auth part
addr= data;
}
if (check_request_str(addr, address_char))
{ {
WSREP_ERROR("Bad SST address string. SST canceled."); WSREP_ERROR("Bad SST address string. SST canceled.");
return WSREP_CB_FAILURE; return WSREP_CB_FAILURE;
...@@ -1841,15 +1838,25 @@ wsrep_cb_status_t wsrep_sst_donate_cb (void* app_ctx, void* recv_ctx, ...@@ -1841,15 +1838,25 @@ wsrep_cb_status_t wsrep_sst_donate_cb (void* app_ctx, void* recv_ctx,
} }
int ret; int ret;
if ((ret= sst_append_auth_env(env, sst_auth_real))) if ((ret= sst_append_env_var(env, WSREP_SST_AUTH_ENV, sst_auth_real)))
{ {
WSREP_ERROR("wsrep_sst_donate_cb(): appending auth env failed: %d", ret); WSREP_ERROR("wsrep_sst_donate_cb(): appending auth env failed: %d", ret);
return WSREP_CB_FAILURE; return WSREP_CB_FAILURE;
} }
if (remote_auth())
{
if ((ret= sst_append_env_var(env, WSREP_SST_REMOTE_AUTH_ENV,remote_auth())))
{
WSREP_ERROR("wsrep_sst_donate_cb(): appending remote auth env failed: "
"%d", ret);
return WSREP_CB_FAILURE;
}
}
if (data_home_dir) if (data_home_dir)
{ {
if ((ret= sst_append_data_dir(env, data_home_dir))) if ((ret= sst_append_env_var(env, DATA_HOME_DIR_ENV, data_home_dir)))
{ {
WSREP_ERROR("wsrep_sst_donate_cb(): appending data " WSREP_ERROR("wsrep_sst_donate_cb(): appending data "
"directory failed: %d", ret); "directory failed: %d", ret);
...@@ -1859,12 +1866,12 @@ wsrep_cb_status_t wsrep_sst_donate_cb (void* app_ctx, void* recv_ctx, ...@@ -1859,12 +1866,12 @@ wsrep_cb_status_t wsrep_sst_donate_cb (void* app_ctx, void* recv_ctx,
if (!strcmp (WSREP_SST_MYSQLDUMP, method)) if (!strcmp (WSREP_SST_MYSQLDUMP, method))
{ {
ret = sst_donate_mysqldump(data, &current_gtid->uuid, uuid_str, ret = sst_donate_mysqldump(addr, &current_gtid->uuid, uuid_str,
current_gtid->seqno, bypass, env()); current_gtid->seqno, bypass, env());
} }
else else
{ {
ret = sst_donate_other(method, data, uuid_str, ret = sst_donate_other(method, addr, uuid_str,
current_gtid->seqno, bypass, env()); current_gtid->seqno, bypass, env());
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment