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