summaryrefslogtreecommitdiff
path: root/scripts/wsrep_sst_rsync.sh
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/wsrep_sst_rsync.sh')
-rw-r--r--scripts/wsrep_sst_rsync.sh250
1 files changed, 123 insertions, 127 deletions
diff --git a/scripts/wsrep_sst_rsync.sh b/scripts/wsrep_sst_rsync.sh
index 29c9cd43470..28dfed18218 100644
--- a/scripts/wsrep_sst_rsync.sh
+++ b/scripts/wsrep_sst_rsync.sh
@@ -17,7 +17,7 @@
# Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston
# MA 02110-1335 USA.
-# This is a reference script for rsync-based state snapshot tansfer
+# This is a reference script for rsync-based state snapshot transfer
RSYNC_REAL_PID=0 # rsync process id
STUNNEL_REAL_PID=0 # stunnel process id
@@ -25,9 +25,6 @@ STUNNEL_REAL_PID=0 # stunnel process id
OS="$(uname)"
[ "$OS" = 'Darwin' ] && export -n LD_LIBRARY_PATH
-# Setting the path for lsof on CentOS
-export PATH="/usr/sbin:/sbin:$PATH"
-
. $(dirname "$0")/wsrep_sst_common
wsrep_check_datadir
@@ -37,13 +34,14 @@ cleanup_joiner()
{
local failure=0
- wsrep_log_info "Joiner cleanup: rsync PID=$RSYNC_REAL_PID, stunnel PID=$STUNNEL_REAL_PID"
+ wsrep_log_info "Joiner cleanup: rsync PID=$RSYNC_REAL_PID," \
+ "stunnel PID=$STUNNEL_REAL_PID"
if [ -n "$STUNNEL" ]; then
if cleanup_pid $STUNNEL_REAL_PID "$STUNNEL_PID" "$STUNNEL_CONF"; then
if [ $RSYNC_REAL_PID -eq 0 ]; then
if [ -r "$RSYNC_PID" ]; then
- RSYNC_REAL_PID=$(cat "$RSYNC_PID" 2>/dev/null)
+ RSYNC_REAL_PID=$(cat "$RSYNC_PID" 2>/dev/null || :)
if [ -z "$RSYNC_REAL_PID" ]; then
RSYNC_REAL_PID=0
fi
@@ -81,18 +79,18 @@ check_pid_and_port()
local utils='rsync|stunnel'
- if ! check_port "$pid" "$port" "$utils"; then
+ if ! check_port $pid "$port" "$utils"; then
local port_info
local busy=0
if [ $lsof_available -ne 0 ]; then
port_info=$(lsof -Pnl -i ":$port" 2>/dev/null | \
- grep -F '(LISTEN)')
+ grep -F '(LISTEN)')
echo "$port_info" | \
grep -q -E "[[:space:]](\\*|\\[?::\\]?):$port[[:space:]]" && busy=1
else
local filter='([^[:space:]]+[[:space:]]+){4}[^[:space:]]+'
- if [ $sockstat_available -eq 1 ]; then
+ if [ $sockstat_available -ne 0 ]; then
local opts='-p'
if [ "$OS" = 'FreeBSD' ]; then
# sockstat on FreeBSD requires the "-s" option
@@ -112,19 +110,21 @@ check_pid_and_port()
fi
if [ $busy -eq 0 ]; then
- if echo "$port_info" | grep -qw -F "[$addr]:$port" || \
- echo "$port_info" | grep -qw -F -- "$addr:$port"
+ if ! echo "$port_info" | grep -qw -F "[$addr]:$port" && \
+ ! echo "$port_info" | grep -qw -F -- "$addr:$port"
then
- busy=1
+ if ! ps -p $pid >/dev/null 2>&1; then
+ wsrep_log_error \
+ "rsync or stunnel daemon (PID: $pid)" \
+ "terminated unexpectedly."
+ exit 16 # EBUSY
+ fi
+ return 1
fi
fi
- if [ $busy -eq 0 ]; then
- return 1
- fi
-
- if ! check_port "$pid" "$port" "$utils"; then
- wsrep_log_error "rsync or stunnel daemon port '$port' " \
+ if ! check_port $pid "$port" "$utils"; then
+ wsrep_log_error "rsync or stunnel daemon port '$port'" \
"has been taken by another program"
exit 16 # EBUSY
fi
@@ -199,60 +199,23 @@ INNODB_UNDO_DIR=$(pwd -P)
cd "$OLD_PWD"
-# Old filter - include everything except selected
-# FILTER=(--exclude '*.err' --exclude '*.pid' --exclude '*.sock' \
-# --exclude '*.conf' --exclude core --exclude 'galera.*' \
-# --exclude grastate.txt --exclude '*.pem' \
-# --exclude '*.[0-9][0-9][0-9][0-9][0-9][0-9]' --exclude '*.index')
+encgroups='--mysqld|sst'
-# New filter - exclude everything except dirs (schemas) and innodb files
-FILTER="-f '- /lost+found'
- -f '- /.zfs'
- -f '- /.fseventsd'
- -f '- /.Trashes'
- -f '- /.pid'
- -f '- /.conf'
- -f '+ /wsrep_sst_binlog.tar'
- -f '- $INNODB_DATA_HOME_DIR/ib_lru_dump'
- -f '- $INNODB_DATA_HOME_DIR/ibdata*'
- -f '+ $INNODB_UNDO_DIR/undo*'
- -f '+ /*/'
- -f '- /*'"
-
-# old-style SSL config
-SSTKEY=$(parse_cnf 'sst' 'tkey')
-SSTCERT=$(parse_cnf 'sst' 'tcert')
-SSTCA=$(parse_cnf 'sst' 'tca')
-
-SST_SECTIONS="--mysqld|sst"
+check_server_ssl_config
-check_server_ssl_config()
-{
- SSTKEY=$(parse_cnf "$SST_SECTIONS" 'ssl-key')
- SSTCERT=$(parse_cnf "$SST_SECTIONS" 'ssl-cert')
- SSTCA=$(parse_cnf "$SST_SECTIONS" 'ssl-ca')
-}
+SSTKEY="$tkey"
+SSTCERT="$tpem"
+SSTCA="$tcert"
+SSTCAP="$tcap"
-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
- check_server_ssl_config
-fi
-
-SSTPATH=0
-if [ -n "$SSTCA" ]; then
- SSTCA=$(trim_string "$SSTCA")
- if [ "${SSTCA%/}" != "$SSTCA" ]; then
- SSTPATH=1
- fi
-fi
+SSLMODE=$(parse_cnf "$encgroups" 'ssl-mode' | tr [:lower:] [:upper:])
if [ -z "$SSLMODE" ]; then
# Implicit verification if CA is set and the SSL mode
# is not specified by user:
- if [ -n "$SSTCA" ]; then
- if [ -n "$(command -v stunnel)" ]; then
+ if [ -n "$SSTCA$SSTCAP" ]; then
+ STUNNEL_BIN=$(commandex 'stunnel')
+ if [ -n "$STUNNEL_BIN" ]; then
SSLMODE='VERIFY_CA'
fi
# Require SSL by default if SSL key and cert are present:
@@ -261,28 +224,28 @@ if [ -z "$SSLMODE" ]; then
fi
fi
-if [ -n "$SSTCERT" -a -n "$SSTKEY" ]; then
+if [ -n "$SSTKEY" -a -n "$SSTCERT" ]; then
verify_cert_matches_key "$SSTCERT" "$SSTKEY"
fi
-if [ -n "$SSTCA" ]; then
- if [ $SSTPATH -eq 0 ]; then
+CAFILE_OPT=""
+CAPATH_OPT=""
+if [ -n "$SSTCA$SSTCAP" ]; then
+ if [ -n "$SSTCA" ]; then
CAFILE_OPT="CAfile = $SSTCA"
- else
- CAFILE_OPT="CApath = $SSTCA"
+ fi
+ if [ -n "$SSTCAP" ]; then
+ CAPATH_OPT="CApath = $SSTCAP"
fi
if [ -n "$SSTCERT" ]; then
- verify_ca_matches_cert "$SSTCA" "$SSTCERT" $SSTPATH
+ verify_ca_matches_cert "$SSTCERT" "$SSTCA" "$SSTCAP"
fi
-else
- CAFILE_OPT=""
fi
VERIFY_OPT=""
CHECK_OPT=""
CHECK_OPT_LOCAL=""
-if [ "${SSLMODE#VERIFY}" != "$SSLMODE" ]
-then
+if [ "${SSLMODE#VERIFY}" != "$SSLMODE" ]; then
case "$SSLMODE" in
'VERIFY_IDENTITY')
VERIFY_OPT='verifyPeer = yes'
@@ -295,7 +258,7 @@ then
exit 22 # EINVAL
;;
esac
- if [ -z "$SSTCA" ]; then
+ if [ -z "$SSTCA$SSTCAP" ]; then
wsrep_log_error "Can't have ssl-mode='$SSLMODE' without CA file or path"
exit 22 # EINVAL
fi
@@ -318,9 +281,12 @@ fi
STUNNEL=""
if [ -n "$SSLMODE" -a "$SSLMODE" != 'DISABLED' ]; then
- STUNNEL_BIN="$(command -v stunnel)"
+ if [ -z "${STUNNEL_BIN+x}" ]; then
+ STUNNEL_BIN=$(commandex 'stunnel')
+ fi
if [ -n "$STUNNEL_BIN" ]; then
- wsrep_log_info "Using stunnel for SSL encryption: CA: '$SSTCA', ssl-mode='$SSLMODE'"
+ wsrep_log_info "Using stunnel for SSL encryption: CA: '$SSTCA'," \
+ "CAPATH='$SSTCAP', ssl-mode='$SSLMODE'"
STUNNEL="$STUNNEL_BIN $STUNNEL_CONF"
fi
fi
@@ -340,6 +306,7 @@ then
key = $SSTKEY
cert = $SSTCERT
${CAFILE_OPT}
+${CAPATH_OPT}
foreground = yes
pid = $STUNNEL_PID
debug = warning
@@ -354,8 +321,9 @@ EOF
[ -f "$STUNNEL_CONF" ] && rm -f "$STUNNEL_CONF"
fi
- if [ $WSREP_SST_OPT_BYPASS -eq 0 ]
- then
+ RC=0
+
+ if [ $WSREP_SST_OPT_BYPASS -eq 0 ]; then
FLUSHED="$WSREP_SST_OPT_DATA/tables_flushed"
ERROR="$WSREP_SST_OPT_DATA/sst_error"
@@ -370,11 +338,11 @@ EOF
# (b) Cluster state ID & wsrep_gtid_domain_id to be written to the file, OR
# (c) ERROR file, in case flush tables operation failed.
- while [ ! -r "$FLUSHED" ] && ! grep -q -F ':' "$FLUSHED" >/dev/null 2>&1
+ while [ ! -r "$FLUSHED" ] && \
+ ! grep -q -F ':' '--' "$FLUSHED" >/dev/null 2>&1
do
# Check whether ERROR file exists.
- if [ -f "$ERROR" ]
- then
+ if [ -f "$ERROR" ]; then
# Flush tables operation failed.
rm -f "$ERROR"
exit 255
@@ -387,24 +355,22 @@ EOF
sync
- if [ -n "$WSREP_SST_OPT_BINLOG" ]
+ if [ -n "$WSREP_SST_OPT_BINLOG" -a -d "${BINLOG_DIRNAME:-}" ]
then
# Prepare binlog files
cd "$BINLOG_DIRNAME"
- binlog_files_full=$(tail -n $BINLOG_N_FILES "$WSREP_SST_OPT_BINLOG_INDEX")
-
+ binlog_files_full=$(tail -n $BINLOG_N_FILES \
+ "$WSREP_SST_OPT_BINLOG_INDEX")
binlog_files=""
- for ii in $binlog_files_full
- do
- binlog_file=$(basename "$ii")
- binlog_files="$binlog_files $binlog_file"
+ for file in $binlog_files_full; do
+ binlog_file=$(basename "$file")
+ binlog_files="$binlog_files${binlog_files:+ }'$binlog_file'"
done
- if [ -n "$binlog_files" ]
- then
+ if [ -n "$binlog_files" ]; then
wsrep_log_info "Preparing binlog files for transfer:"
- tar -cvf "$BINLOG_TAR_FILE" $binlog_files >&2
+ eval tar -cvf "'$BINLOG_TAR_FILE'" $binlog_files >&2
fi
cd "$OLD_PWD"
@@ -417,9 +383,29 @@ EOF
WHOLE_FILE_OPT="--whole-file"
fi
- # first, the normal directories, so that we can detect incompatible protocol
- RC=0
- eval rsync ${STUNNEL:+"'--rsh=$STUNNEL'"} \
+# Old filter - include everything except selected
+# FILTER=(--exclude '*.err' --exclude '*.pid' --exclude '*.sock' \
+# --exclude '*.conf' --exclude core --exclude 'galera.*' \
+# --exclude grastate.txt --exclude '*.pem' \
+# --exclude '*.[0-9][0-9][0-9][0-9][0-9][0-9]' --exclude '*.index')
+
+# New filter - exclude everything except dirs (schemas) and innodb files
+FILTER="-f '- /lost+found'
+ -f '- /.zfs'
+ -f '- /.fseventsd'
+ -f '- /.Trashes'
+ -f '- /.pid'
+ -f '- /.conf'
+ -f '+ /wsrep_sst_binlog.tar'
+ -f '- $INNODB_DATA_HOME_DIR/ib_lru_dump'
+ -f '- $INNODB_DATA_HOME_DIR/ibdata*'
+ -f '+ $INNODB_UNDO_DIR/undo*'
+ -f '+ /*/'
+ -f '- /*'"
+
+ # first, the normal directories, so that we can detect
+ # incompatible protocol:
+ eval rsync ${STUNNEL:+"--rsh='$STUNNEL'"} \
--owner --group --perms --links --specials \
--ignore-times --inplace --dirs --delete --quiet \
$WHOLE_FILE_OPT $FILTER "'$WSREP_SST_OPT_DATA/'" \
@@ -430,8 +416,9 @@ EOF
case $RC in
12) RC=71 # EPROTO
wsrep_log_error \
- "rsync server on the other end has incompatible protocol. " \
- "Make sure you have the same version of rsync on all nodes."
+ "rsync server on the other end has incompatible" \
+ "protocol. Make sure you have the same version of" \
+ "rsync on all nodes."
;;
22) RC=12 # ENOMEM
;;
@@ -472,7 +459,7 @@ EOF
cd "$WSREP_SST_OPT_DATA"
- backup_threads=$(parse_cnf "--mysqld|sst" 'backup-threads')
+ backup_threads=$(parse_cnf '--mysqld|sst' 'backup-threads')
if [ -z "$backup_threads" ]; then
get_proc
backup_threads=$nproc
@@ -481,9 +468,9 @@ EOF
find . -maxdepth 1 -mindepth 1 -type d -not -name 'lost+found' \
-not -name '.zfs' -print0 | xargs -I{} -0 -P $backup_threads \
rsync ${STUNNEL:+--rsh="$STUNNEL"} \
- --owner --group --perms --links --specials \
- --ignore-times --inplace --recursive --delete --quiet \
- $WHOLE_FILE_OPT --exclude '*/ib_logfile*' --exclude '*/aria_log.*' \
+ --owner --group --perms --links --specials --ignore-times \
+ --inplace --recursive --delete --quiet $WHOLE_FILE_OPT \
+ --exclude '*/ib_logfile*' --exclude '*/aria_log.*' \
--exclude '*/aria_log_control' "$WSREP_SST_OPT_DATA/{}/" \
"rsync://$WSREP_SST_OPT_ADDR/{}" >&2 || RC=$?
@@ -514,7 +501,13 @@ EOF
fi
rsync ${STUNNEL:+--rsh="$STUNNEL"} \
- --archive --quiet --checksum "$MAGIC_FILE" "rsync://$WSREP_SST_OPT_ADDR"
+ --archive --quiet --checksum "$MAGIC_FILE" \
+ "rsync://$WSREP_SST_OPT_ADDR" >&2 || RC=$?
+
+ if [ $RC -ne 0 ]; then
+ wsrep_log_error "rsync $MAGIC_FILE returned code $RC:"
+ exit 255 # unknown error
+ fi
echo "done $STATE"
@@ -527,12 +520,11 @@ elif [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]
then
check_sockets_utils
- SST_PID="$WSREP_SST_OPT_DATA/wsrep_rsync_sst.pid"
+ SST_PID="$WSREP_SST_OPT_DATA/wsrep_sst.pid"
# give some time for previous SST to complete:
check_round=0
- while check_pid "$SST_PID" 0
- do
+ while check_pid "$SST_PID" 0 'wsrep_sst_'; do
wsrep_log_info "previous SST is not completed, waiting for it to exit"
check_round=$(( check_round + 1 ))
if [ $check_round -eq 10 ]; then
@@ -542,11 +534,13 @@ then
sleep 1
done
+ echo $$ > "$SST_PID"
+
# give some time for stunnel from the previous SST to complete:
check_round=0
- while check_pid "$STUNNEL_PID" 1
- do
- wsrep_log_info "lingering stunnel daemon found at startup, waiting for it to exit"
+ while check_pid "$STUNNEL_PID" 1; do
+ wsrep_log_info "Lingering stunnel daemon found at startup," \
+ "waiting for it to exit"
check_round=$(( check_round + 1 ))
if [ $check_round -eq 10 ]; then
wsrep_log_error "stunnel daemon already running."
@@ -561,9 +555,9 @@ then
# give some time for rsync from the previous SST to complete:
check_round=0
- while check_pid "$RSYNC_PID" 1
- do
- wsrep_log_info "lingering rsync daemon found at startup, waiting for it to exit"
+ while check_pid "$RSYNC_PID" 1; do
+ wsrep_log_info "Lingering rsync daemon found at startup," \
+ "waiting for it to exit"
check_round=$(( check_round + 1 ))
if [ $check_round -eq 10 ]; then
wsrep_log_error "rsync daemon already running."
@@ -575,9 +569,7 @@ then
[ -f "$MAGIC_FILE" ] && rm -f "$MAGIC_FILE"
[ -f "$BINLOG_TAR_FILE" ] && rm -f "$BINLOG_TAR_FILE"
- if [ -z "$STUNNEL" ]; then
- [ -f "$STUNNEL_CONF" ] && rm -f "$STUNNEL_CONF"
- fi
+ [ -z "$STUNNEL" -a -f "$STUNNEL_CONF" ] && rm -f "$STUNNEL_CONF"
ADDR="$WSREP_SST_OPT_ADDR"
RSYNC_PORT="$WSREP_SST_OPT_PORT"
@@ -626,21 +618,21 @@ EOF
RSYNC_ADDR="*"
fi
- echo $$ > "$SST_PID"
-
- if [ -z "$STUNNEL" ]
- then
- rsync --daemon --no-detach --port "$RSYNC_PORT" --config "$RSYNC_CONF" $RSYNC_EXTRA_ARGS &
+ if [ -z "$STUNNEL" ]; then
+ rsync --daemon --no-detach --port "$RSYNC_PORT" \
+ --config "$RSYNC_CONF" $RSYNC_EXTRA_ARGS &
RSYNC_REAL_PID=$!
TRANSFER_REAL_PID=$RSYNC_REAL_PID
TRANSFER_PID="$RSYNC_PID"
else
# Let's check if the path to the config file contains a space?
+ RSYNC_BIN=$(commandex 'rsync')
if [ "${RSYNC_CONF#* }" = "$RSYNC_CONF" ]; then
cat << EOF > "$STUNNEL_CONF"
key = $SSTKEY
cert = $SSTCERT
${CAFILE_OPT}
+${CAPATH_OPT}
foreground = yes
pid = $STUNNEL_PID
debug = warning
@@ -650,17 +642,18 @@ ${CHECK_OPT}
${CHECK_OPT_LOCAL}
[rsync]
accept = $STUNNEL_ACCEPT
-exec = $(command -v rsync)
+exec = $RSYNC_BIN
execargs = rsync --server --daemon --config=$RSYNC_CONF .
EOF
else
# The path contains a space, so we will run it via
# shell with "eval" command:
- export RSYNC_CMD="eval $(command -v rsync) --server --daemon --config='$RSYNC_CONF' ."
+ export RSYNC_CMD="eval '$RSYNC_BIN' --server --daemon --config='$RSYNC_CONF' ."
cat << EOF > "$STUNNEL_CONF"
key = $SSTKEY
cert = $SSTCERT
${CAFILE_OPT}
+${CAPATH_OPT}
foreground = yes
pid = $STUNNEL_PID
debug = warning
@@ -688,7 +681,8 @@ EOF
# find out my Common Name
get_openssl
if [ -z "$OPENSSL_BINARY" ]; then
- wsrep_log_error 'openssl not found but it is required for authentication'
+ wsrep_log_error \
+ 'openssl not found but it is required for authentication'
exit 42
fi
CN=$("$OPENSSL_BINARY" x509 -noout -subject -in "$SSTCERT" | \
@@ -703,7 +697,8 @@ EOF
ADDR="$WSREP_SST_OPT_HOST"
fi
- until check_pid_and_port "$TRANSFER_PID" $TRANSFER_REAL_PID "$RSYNC_ADDR_UNESCAPED" "$RSYNC_PORT"
+ until check_pid_and_port "$TRANSFER_PID" $TRANSFER_REAL_PID \
+ "$RSYNC_ADDR_UNESCAPED" "$RSYNC_PORT"
do
sleep 0.2
done
@@ -722,7 +717,7 @@ EOF
if ! ps -p $MYSQLD_PID >/dev/null 2>&1
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
@@ -768,10 +763,11 @@ EOF
if [ -r "$MAGIC_FILE" ]; then
if [ -n "$MY_SECRET" ]; then
# check donor supplied secret
- SECRET=$(grep -F -- "$SECRET_TAG " "$MAGIC_FILE" 2>/dev/null | cut -d ' ' -f 2)
+ SECRET=$(grep -F -- "$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'"
+ wsrep_log_info "Donor: '$SECRET', my: '$MY_SECRET'"
exit 32
fi
# remove secret from the magic file, and output