Commit 7742cc9f authored by Julius Goryavsky's avatar Julius Goryavsky

galera SST scripts: more robust port checking

parent 642195d2
...@@ -1220,26 +1220,55 @@ is_local_ip() ...@@ -1220,26 +1220,55 @@ is_local_ip()
check_sockets_utils() check_sockets_utils()
{ {
# The presence of any of these utilities is enough for us:
lsof_available=0 lsof_available=0
sockstat_available=0 sockstat_available=0
ss_available=0 ss_available=0
# The presence of any of these utilities is enough for us: socket_utility="$(commandex ss)"
if [ -n "$(commandex ss)" ]; then if [ -n "$socket_utility" ]; then
socket_uname='ss'
ss_available=1 ss_available=1
elif [ -n "$(commandex sockstat)" ]; then ss_opts='-nlp'
# Let's check that ss has an option to skip headers:
if $socket_utility -h 2>&1 | grep -qw -F -- '-H'; then
ss_available=2
ss_opts="${ss_opts}H"
fi
else
socket_utility="$(commandex sockstat)"
if [ -n "$socket_utility" ]; then
socket_uname='sockstat'
sockstat_available=1 sockstat_available=1
elif [ -n "$(commandex lsof)" ]; then sockstat_opts='-p'
if [ "$OS" = 'FreeBSD' ]; then
# sockstat in FreeBSD is different from other systems,
# let's denote it with a different value:
sockstat_available=2
fi
else
socket_utility="$(commandex lsof)"
if [ -n "$socket_utility" ]; then
socket_uname='lsof'
lsof_available=1 lsof_available=1
lsof_opts='-Pnl'
# Let's check that lsof has an option to bypass blocking: # Let's check that lsof has an option to bypass blocking:
if lsof -h 2>&1 | grep -qw -F -- '-b'; then if $socket_utility -h 2>&1 | grep -qw -F -- '-b'; then
lsof_available=2 lsof_available=2
lsof_opts="$lsof_opts -b -w"
else
lsof_opts="$lsof_opts -S 10"
fi fi
else else
wsrep_log_error "Neither lsof, nor sockstat or ss tool was found in" \ wsrep_log_error "Neither lsof, nor sockstat, nor ss tool" \
"the PATH. Make sure you have it installed." "were found in the path. Make sure you have" \
"at least one of them installed."
exit 2 # ENOENT exit 2 # ENOENT
fi fi
fi
fi
wsrep_log_info "'$socket_uname' is selected as a socket" \
"information utility."
} }
# #
...@@ -1263,26 +1292,23 @@ check_port() ...@@ -1263,26 +1292,23 @@ check_port()
local rc=1 local rc=1
if [ $ss_available -ne 0 ]; then if [ $ss_available -ne 0 ]; then
ss -nlpH "( sport = :$port )" 2>/dev/null | \ $socket_utility $ss_opts -t "( sport = :$port )" 2>/dev/null | \
grep -q -E "users:\\(.*\\(\"($utils)[^[:space:]]*\"[^)]*,pid=$pid(,[^)]*)?\\)" && rc=0 grep -q -E "[[:space:]]users:[[:space:]]?\\(.*\\(\"($utils)[^[:space:]]*\"[^)]*,pid=$pid(,[^)]*)?\\)" && rc=0
elif [ $sockstat_available -ne 0 ]; then elif [ $sockstat_available -ne 0 ]; then
local opts='-p' if [ $sockstat_available -gt 1 ]; then
if [ "$OS" = 'FreeBSD' ]; then # sockstat on FreeBSD does not return the connection
# sockstat on FreeBSD requires the "-s" option # state without special option that cancel filtering
# to display the connection state: # by the port, so we ignore the connection state for
opts='-sp' # this system:
fi $socket_utility $sockstat_opts "$port" 2>/dev/null | \
sockstat $opts "$port" 2>/dev/null | \ grep -q -E "^[^[:space:]]+[[:space:]]+($utils)[^[:space:]]*[[:space:]]+$pid([[:space:]]|\$)" && rc=0
grep -q -E "[[:space:]]+($utils)[^[:space:]]*[[:space:]]+$pid[[:space:]].*[[:space:]]LISTEN" && rc=0
elif [ $lsof_available -ne 0 ]; then
local lsof_opts='-Pnl'
if [ $lsof_available -gt 1 ]; then
lsof_opts="$lsof_opts -b -w"
else else
lsof_opts="$lsof_opts -S 15" $socket_utility $sockstat_opts "$port" 2>/dev/null | \
grep -q -E "^[^[:space:]]+[[:space:]]+($utils)[^[:space:]]*[[:space:]]+$pid([[:space:]].+)?[[:space:]]LISTEN([[:space:]]|\$)" && rc=0
fi fi
lsof $lsof_opts -i ":$port" 2>/dev/null | \ elif [ $lsof_available -ne 0 ]; then
grep -q -E "^($utils)[^[:space:]]*[[:space:]]+$pid[[:space:]].*\\(LISTEN\\)" && rc=0 $socket_utility $lsof_opts -i ":$port" 2>/dev/null | \
grep -q -E "^($utils)[^[:space:]]*[[:space:]]+$pid([[:space:]].+)?[[:space:]]\\(LISTEN\\)([[:space:]]|\$)" && rc=0
else else
wsrep_log_error "Unknown sockets utility" wsrep_log_error "Unknown sockets utility"
exit 2 # ENOENT exit 2 # ENOENT
...@@ -1553,7 +1579,7 @@ get_proc() ...@@ -1553,7 +1579,7 @@ get_proc()
if [ -z "$nproc" ]; then if [ -z "$nproc" ]; then
set +e set +e
if [ "$OS" = 'Linux' ]; then if [ "$OS" = 'Linux' ]; then
nproc=$(grep -cw -E '^processor' /proc/cpuinfo 2>/dev/null) nproc=$(grep -cw -E '^processor' /proc/cpuinfo 2>/dev/null || :)
elif [ "$OS" = 'Darwin' -o "$OS" = 'FreeBSD' ]; then elif [ "$OS" = 'Darwin' -o "$OS" = 'FreeBSD' ]; then
nproc=$(sysctl -n hw.ncpu) nproc=$(sysctl -n hw.ncpu)
fi fi
......
...@@ -751,7 +751,7 @@ setup_ports() ...@@ -751,7 +751,7 @@ setup_ports()
wait_for_listen() wait_for_listen()
{ {
for i in {1..150}; do for i in {1..150}; do
if check_port "" "$SST_PORT" 'socat|nc'; then if check_port "" "$SST_PORT" 'socat|nc|netcat'; then
break break
fi fi
sleep 0.2 sleep 0.2
......
...@@ -92,54 +92,53 @@ check_pid_and_port() ...@@ -92,54 +92,53 @@ check_pid_and_port()
local utils='rsync|stunnel' local utils='rsync|stunnel'
if ! check_port $pid "$port" "$utils"; then
local port_info local port_info
local busy=0 local final
if ! check_port $pid "$port" "$utils"; then
if [ $ss_available -ne 0 -o $sockstat_available -ne 0 ]; then if [ $ss_available -ne 0 -o $sockstat_available -ne 0 ]; then
if [ $ss_available -ne 0 ]; then if [ $ss_available -ne 0 ]; then
port_info=$(ss -nlpH "( sport = :$port )" 2>/dev/null | \ port_info=$($socket_utility $ss_opts -t "( sport = :$port )" 2>/dev/null | \
grep -F 'users:(' | grep -o -E "([^[:space:]]+[[:space:]]+){4}[^[:space:]]+") grep -E '[[:space:]]users:[[:space:]]?(' | \
grep -o -E "([^[:space:]]+[[:space:]]+){4}[^[:space:]]+" || :)
else else
local opts='-p' if [ $sockstat_available -gt 1 ]; then
local terms=4 # sockstat on FreeBSD does not return the connection
if [ "$OS" = 'FreeBSD' ]; then # state without special option that cancel filtering
# sockstat on FreeBSD requires the "-s" option # by the port, so we ignore the connection state for
# to display the connection state: # this system, also on the FreeBSD sockstat utility
opts='-sp' # produces an additional column:
# in addition, sockstat produces an additional column: port_info=$($socket_utility $sockstat_opts "$port" 2>/dev/null | \
terms=5 grep -o -E "([^[:space:]]+[[:space:]]+){5}[^[:space:]]+" || :)
fi
port_info=$(sockstat $opts "$port" 2>/dev/null | \
grep -E '[[:space:]]LISTEN' | grep -o -E "([^[:space:]]+[[:space:]]+){$terms}[^[:space:]]+")
fi
echo "$port_info" | \
grep -q -E "[[:space:]]\\[?(\\*|[[:xdigit:]]*(:[[:xdigit:]]*)+)(\\](%[^:]+)?)?:$port\$" && busy=1
else else
local lsof_opts='-Pnl' port_info=$($socket_utility $sockstat_opts "$port" 2>/dev/null | \
if [ $lsof_available -gt 1 ]; then grep -E '[[:space:]]LISTEN([[:space:]]|$)' | \
lsof_opts="$lsof_opts -b -w" grep -o -E "([^[:space:]]+[[:space:]]+){4}[^[:space:]]+" || :)
fi
fi
final='$'
else else
lsof_opts="$lsof_opts -S 15" port_info=$($socket_utility $lsof_opts -i ":$port" 2>/dev/null | \
grep -w -F '(LISTEN)' || :)
final='[[:space:]]'
fi fi
port_info=$(lsof $lsof_opts -i ":$port" 2>/dev/null | grep -F '(LISTEN)' || :)
echo "$port_info" | \ local busy=0
grep -q -E "[[:space:]]\\[?(\\*|[[:xdigit:]]*(:[[:xdigit:]]*)+)(\\](%[^:]+)?)?:$port[[:space:]]" && busy=1 if [ -n "$port_info" ]; then
local address='(\*|[0-9a-fA-F]*(:[0-9a-fA-F]*){1,7}|[0-9]+(\.[0-9]+){3})'
local filter="[[:space:]]($address|\\[$address\\])(%[^:]+)?:$port$final"
echo "$port_info" | grep -q -E "$filter" && busy=1
fi fi
if [ $busy -eq 0 ]; then if [ $busy -eq 0 ]; then
if ! echo "$port_info" | grep -qw -F "[$addr]:$port" && \
! echo "$port_info" | grep -qw -F -- "$addr:$port"
then
if ! ps -p $pid >/dev/null 2>&1; then if ! ps -p $pid >/dev/null 2>&1; then
wsrep_log_error \ wsrep_log_error \
"rsync or stunnel daemon (PID: $pid)" \ "the rsync or stunnel daemon (PID: $pid)" \
"terminated unexpectedly." "terminated unexpectedly."
exit 16 # EBUSY exit 16 # EBUSY
fi fi
return 1 return 1
fi fi
fi
if ! check_port $pid "$port" "$utils"; then if ! check_port $pid "$port" "$utils"; then
wsrep_log_error "rsync or stunnel daemon port '$port'" \ wsrep_log_error "rsync or stunnel daemon port '$port'" \
...@@ -244,7 +243,7 @@ if [ "${SSLMODE#VERIFY}" != "$SSLMODE" ]; then ...@@ -244,7 +243,7 @@ if [ "${SSLMODE#VERIFY}" != "$SSLMODE" ]; then
elif [ "$WSREP_SST_OPT_ROLE" = 'donor' ]; then elif [ "$WSREP_SST_OPT_ROLE" = 'donor' ]; then
# check if the address is an ip-address (v4 or v6): # check if the address is an ip-address (v4 or v6):
if echo "$WSREP_SST_OPT_HOST_UNESCAPED" | \ if echo "$WSREP_SST_OPT_HOST_UNESCAPED" | \
grep -q -E '^([0-9]+(\.[0-9]+){3}|[0-9a-fA-F]*(\:[0-9a-fA-F]*)+)$' grep -q -E '^([0-9]+(\.[0-9]+){3}|[0-9a-fA-F]*(:[0-9a-fA-F]*){1,7})$'
then then
CHECK_OPT="checkIP = $WSREP_SST_OPT_HOST_UNESCAPED" CHECK_OPT="checkIP = $WSREP_SST_OPT_HOST_UNESCAPED"
else else
......
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