_loadconfig "$@"
}
+##############################################################
+# check number of args for different events
+ctdb_check_args ()
+{
+ case "$1" in
+ takeip|releaseip)
+ if [ $# != 4 ]; then
+ echo "ERROR: must supply interface, IP and maskbits"
+ exit 1
+ fi
+ ;;
+ updateip)
+ if [ $# != 5 ]; then
+ echo "ERROR: must supply old interface, new interface, IP and maskbits"
+ exit 1
+ fi
+ ;;
+ esac
+}
+
##############################################################
# determine on what type of system (init style) we are running
detect_init_style() {
}
+######################################################
+# wrapper around /proc/ settings to allow them to be hooked
+# for testing
+# 1st arg is relative path under /proc/, 2nd arg is value to set
+set_proc ()
+{
+ echo "$2" >"/proc/$1"
+}
+
+######################################################
+# wrapper around getting file contents from /proc/ to allow
+# this to be hooked for testing
+# 1st arg is relative path under /proc/
+get_proc ()
+{
+ cat "/proc/$1"
+}
+
######################################################
# check that a rpc server is registered with portmap
# and responding to requests
# If any of these defaults are unsupported then this variable can
# be overridden in /etc/sysconfig/ctdb or via a file in
# /etc/ctdb/rc.local.d/.
- : ${CTDB_TCP_PORT_CHECKERS:=nmap netstat}
+ : ${CTDB_TCP_PORT_CHECKERS:=ctdb nmap netstat}
for _c in $CTDB_TCP_PORT_CHECKERS ; do
ctdb_check_tcp_ports_$_c "$@"
case "$?" in
0)
+ _ctdb_check_tcp_common
rm -f "$_ctdb_service_started_file"
return 0
;;
return 0
}
+# Use the new "ctdb checktcpport" command to check the port.
+# This is very cheap.
+ctdb_check_tcp_ports_ctdb ()
+{
+ for _p ; do # process each function argument (port)
+ _cmd="ctdb checktcpport $_p"
+ _out=$($_cmd 2>&1)
+ _ret=$?
+ case "$_ret" in
+ 0)
+ ctdb_check_tcp_ports_debug="\"$_cmd\" was able to bind to port"
+ return 1
+ ;;
+ 98)
+ # Couldn't bind, something already listening, next port...
+ continue
+ ;;
+ *)
+ ctdb_check_tcp_ports_debug="$_cmd (exited with $_ret) with output:
+$_out"
+ # assume not implemented
+ return 127
+ esac
+ done
+
+ return 0
+}
+
######################################################
# check a unix socket
# usage: ctdb_check_unix_socket SERVICE_NAME <socket_path>
echo 0 >/proc/fs/nfsd/threads
service nfsserver stop > /dev/null 2>&1
pkill -9 nfsd
+ nfs_dump_some_threads
service nfsserver start
;;
esac
service nfs stop > /dev/null 2>&1
service nfslock stop > /dev/null 2>&1
pkill -9 nfsd
+ nfs_dump_some_threads
service nfslock start
service nfs start
;;
esac
}
+# Dump up to the configured number of nfsd thread backtraces.
+nfs_dump_some_threads ()
+{
+ [ -n "$CTDB_NFS_DUMP_STUCK_THREADS" ] || return 0
+
+ # Optimisation to avoid running an unnecessary pidof
+ [ $CTDB_NFS_DUMP_STUCK_THREADS -gt 0 ] || return 0
+
+ _count=0
+ for _pid in $(pidof nfsd) ; do
+ [ $_count -le $CTDB_NFS_DUMP_STUCK_THREADS ] || break
+
+ # Do this first to avoid racing with thread exit
+ _stack=$(get_proc "${_pid}/stack" 2>/dev/null)
+ if [ -n "$_stack" ] ; then
+ echo "Stack trace for stuck nfsd thread [${_pid}]:"
+ echo "$_stack"
+ _count=$(($_count + 1))
+ fi
+ done
+}
+
########################################################
# start/stop the nfs lockmanager service on different platforms
########################################################
# ctdb_check_counter_limit succeeds when count >= <limit>
########################################################
_ctdb_counter_common () {
- _counter_file="$ctdb_fail_dir/$service_name"
+ _service_name="${1:-${service_name}}"
+ _counter_file="$ctdb_fail_dir/$_service_name"
mkdir -p "${_counter_file%/*}" # dirname
}
ctdb_counter_init () {
- _ctdb_counter_common
+ _ctdb_counter_common "$1"
>"$_counter_file"
}
ctdb_counter_incr () {
- _ctdb_counter_common
+ _ctdb_counter_common "$1"
# unary counting!
echo -n 1 >> "$_counter_file"
# unary counting!
_size=$(stat -c "%s" "$_counter_file" 2>/dev/null || echo 0)
if [ $_size -ge $_limit ] ; then
- echo "ERROR: more than $_limit consecutive failures for $service_name, marking cluster unhealthy"
+ echo "ERROR: more than $_limit consecutive failures for $_service_name, marking cluster unhealthy"
exit 1
elif [ $_size -gt 0 -a -z "$_quiet" ] ; then
- echo "WARNING: less than $_limit consecutive failures ($_size) for $service_name, not unhealthy yet"
+ echo "WARNING: less than $_limit consecutive failures ($_size) for $_service_name, not unhealthy yet"
fi
}
ctdb_check_counter_equal () {
else
if [ -e "$_active" ] ; then
echo "Stopping service $_service_name"
+ CTDB_AUTOSTOPPING="$_service_name"
ctdb_service_stop || exit $?
rm -f "$_active"
exit 0
esac
}
-ipv4_host_addr_to_net_addr()
-{
- local HOST=$1
- local MASKBITS=$2
-
- local HOST0=$(echo $HOST | awk -F . '{print $4}')
- local HOST1=$(echo $HOST | awk -F . '{print $3}')
- local HOST2=$(echo $HOST | awk -F . '{print $2}')
- local HOST3=$(echo $HOST | awk -F . '{print $1}')
-
- local HOST_NUM=$(( $HOST0 + $HOST1 * 256 + $HOST2 * (256 ** 2) + $HOST3 * (256 ** 3) ))
-
- local MASK_NUM=$(( ( (2**32 - 1) * (2**(32 - $MASKBITS)) ) & (2**32 - 1) ))
-
- local NET_NUM=$(( $HOST_NUM & $MASK_NUM))
-
- local NET0=$(( $NET_NUM & 255 ))
- local NET1=$(( ($NET_NUM & (255 * 256)) / 256 ))
- local NET2=$(( ($NET_NUM & (255 * 256**2)) / 256**2 ))
- local NET3=$(( ($NET_NUM & (255 * 256**3)) / 256**3 ))
-
- echo "$NET3.$NET2.$NET1.$NET0"
-}
-
-ipv4_maskbits_to_net_mask()
-{
- local MASKBITS=$1
-
- local MASK_NUM=$(( ( (2**32 - 1) * (2**(32 - $MASKBITS)) ) & (2**32 - 1) ))
-
- local MASK0=$(( $MASK_NUM & 255 ))
- local MASK1=$(( ($MASK_NUM & (255 * 256)) / 256 ))
- local MASK2=$(( ($MASK_NUM & (255 * 256**2)) / 256**2 ))
- local MASK3=$(( ($MASK_NUM & (255 * 256**3)) / 256**3 ))
-
- echo "$MASK3.$MASK2.$MASK1.$MASK0"
-}
-
-ipv4_is_valid_addr()
-{
- local ADDR=$1
- local fail=0
-
- local N=`echo $ADDR | sed -e 's/[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*//'`
- test -n "$N" && fail=1
-
- local ADDR0=$(echo $ADDR | awk -F . '{print $4}')
- local ADDR1=$(echo $ADDR | awk -F . '{print $3}')
- local ADDR2=$(echo $ADDR | awk -F . '{print $2}')
- local ADDR3=$(echo $ADDR | awk -F . '{print $1}')
-
- test "$ADDR0" -gt 255 && fail=1
- test "$ADDR1" -gt 255 && fail=1
- test "$ADDR2" -gt 255 && fail=1
- test "$ADDR3" -gt 255 && fail=1
-
- test x"$fail" != x"0" && {
- #echo "IPv4: '$ADDR' is not a valid address"
- return 1;
- }
-
- return 0;
-}
-
# iptables doesn't like being re-entered, so flock-wrap it.
iptables()
{