1 # Hey Emacs, this is a -*- shell-script -*- !!!
3 # utility functions for ctdb event scripts
5 PATH=/bin:/usr/bin:/usr/sbin:/sbin:$PATH
7 [ -z "$CTDB_VARDIR" ] && {
8 export CTDB_VARDIR="/var/ctdb"
10 [ -z "$CTDB_ETCDIR" ] && {
11 export CTDB_ETCDIR="/etc"
14 #######################################
15 # pull in a system config file, if any
19 foo="${service_config:-${service_name}}"
20 if [ -n "$foo" ] ; then
23 elif [ "$1" != "ctdb" ] ; then
27 if [ -f $CTDB_ETCDIR/sysconfig/$1 ]; then
28 . $CTDB_ETCDIR/sysconfig/$1
29 elif [ -f $CTDB_ETCDIR/default/$1 ]; then
30 . $CTDB_ETCDIR/default/$1
31 elif [ -f $CTDB_BASE/sysconfig/$1 ]; then
32 . $CTDB_BASE/sysconfig/$1
40 ##############################################################
41 # determine on what type of system (init style) we are running
43 # only do detection if not already set:
44 test "x$CTDB_INIT_STYLE" != "x" && return
46 if [ -x /sbin/startproc ]; then
47 CTDB_INIT_STYLE="suse"
48 elif [ -x /sbin/start-stop-daemon ]; then
49 CTDB_INIT_STYLE="debian"
51 CTDB_INIT_STYLE="redhat"
55 ######################################################
56 # simulate /sbin/service on platforms that don't have it
57 # _service() makes it easier to hook the service() function for
64 # do nothing, when no service was specified
65 [ -z "$_service_name" ] && return
67 if [ -x /sbin/service ]; then
68 $_nice /sbin/service "$_service_name" "$_op"
69 elif [ -x $CTDB_ETCDIR/init.d/$_service_name ]; then
70 $_nice $CTDB_ETCDIR/init.d/$_service_name "$_op"
71 elif [ -x $CTDB_ETCDIR/rc.d/init.d/$_service_name ]; then
72 $_nice $CTDB_ETCDIR/rc.d/init.d/$_service_name "$_op"
82 ######################################################
83 # simulate /sbin/service (niced) on platforms that don't have it
90 ######################################################
91 # wrapper around /proc/ settings to allow them to be hooked
93 # 1st arg is relative path under /proc/, 2nd arg is value to set
99 ######################################################
100 # wrapper around getting file contents from /proc/ to allow
101 # this to be hooked for testing
102 # 1st arg is relative path under /proc/
108 ######################################################
109 # Check that an RPC service is healthy -
110 # this includes allowing a certain number of failures
111 # before marking the NFS service unhealthy.
113 # usage: nfs_check_rpc_service SERVICE_NAME [ triple ...]
115 # each triple is a set of 3 arguments: an operator, a
116 # fail count limit and an action string.
120 # nfs_check_rpc_service "lockd" \
121 # -ge 15 "verbose restart unhealthy" \
122 # -eq 10 "restart:bs"
124 # says that if lockd is down for 15 iterations then do
125 # a verbose restart of lockd and mark the node unhealthy.
126 # Before this, after 10 iterations of failure, the
127 # service is restarted silently in the background.
128 # Order is important: the number of failures need to be
129 # specified in reverse order because processing stops
130 # after the first condition that is true.
131 ######################################################
132 nfs_check_rpc_service ()
134 _prog_name="$1" ; shift
137 _rpc_prog="$_prog_name"
140 case "$_prog_name" in
144 _restart="echo 'Trying to restart NFS service'"
145 _restart="${_restart}; startstop_nfs restart"
148 _opts="${MOUNTD_PORT:+ -p }${MOUNTD_PORT}"
151 _opts="${RQUOTAD_PORT:+ -p }${RQUOTAD_PORT}"
156 _restart="echo 'Trying to restart lock manager service'"
157 _restart="${_restart}; startstop_nfs restart"
158 _restart="${_restart}; startstop_nfslock restart"
162 _opts="${STATD_HOSTNAME:+ -n }${STATD_HOSTNAME}"
163 _opts="${_opts}${STATD_PORT:+ -p }${STATD_PORT}"
164 _opts="${_opts}${STATD_OUTGOING_PORT:+ -o }${STATD_OUTGOING_PORT}"
167 echo "Internal error: unknown RPC program \"$_prog_name\"."
171 _service_name="nfs_${_prog_name}"
173 if ctdb_check_rpc "$_rpc_prog" $_version >/dev/null ; then
174 ctdb_counter_init "$_service_name"
178 ctdb_counter_incr "$_service_name"
180 while [ -n "$3" ] ; do
181 ctdb_check_counter "quiet" "$1" "$2" "$_service_name" || {
182 for _action in $3 ; do
185 echo "$ctdb_check_rpc_out"
188 # No explicit command specified, construct rpc command.
189 if [ -z "$_restart" ] ; then
190 _p="rpc.${_prog_name}"
191 _restart="echo 'Trying to restart $_prog_name [${_p}${_opts}]'"
192 _restart="${_restart}; killall -q -9 $_p"
193 _restart="${_restart}; $_p $_opts"
196 # Process restart flags...
197 _flags="${_action#restart:}"
198 # There may not have been a colon...
199 [ "$_flags" != "$_action" ] || _flags=""
200 # q=quiet - everything to /dev/null
201 if [ "${_flags#*q}" != "$_flags" ] ; then
202 _restart="{ ${_restart} ; } >/dev/null 2>&1"
204 # s=stealthy - last command to /dev/null
205 if [ "${_flags#*s}" != "$_flags" ] ; then
206 _restart="${_restart} >/dev/null 2>&1"
208 # b=background - the whole thing, easy and reliable
209 if [ "${_flags#*b}" != "$_flags" ] ; then
210 _restart="{ ${_restart} ; } &"
220 echo "Internal error: unknown action \"$_action\"."
225 # Only process the first action group.
232 ######################################################
233 # check that a rpc server is registered with portmap
234 # and responding to requests
235 # usage: ctdb_check_rpc SERVICE_NAME VERSION
236 ######################################################
242 if ! ctdb_check_rpc_out=$(rpcinfo -u localhost $progname $version 2>&1) ; then
243 ctdb_check_rpc_out="ERROR: $progname failed RPC check:
245 echo "$ctdb_check_rpc_out"
250 ######################################################
251 # check a set of directories is available
252 # return 1 on a missing directory
253 # usage: ctdb_check_directories_probe SERVICE_NAME <directories...>
254 ######################################################
255 ctdb_check_directories_probe() {
256 while IFS="" read d ; do
262 [ -d "${d}/." ] || return 1
267 ######################################################
268 # check a set of directories is available
269 # usage: ctdb_check_directories SERVICE_NAME <directories...>
270 ######################################################
271 ctdb_check_directories() {
272 n="${1:-${service_name}}"
273 ctdb_check_directories_probe || {
274 echo "ERROR: $n directory \"$d\" not available"
279 ######################################################
280 # check a set of tcp ports
281 # usage: ctdb_check_tcp_ports <ports...>
282 ######################################################
283 ctdb_check_tcp_ports() {
286 if ! netstat -a -t -n | grep -q "0\.0\.0\.0:$p .*LISTEN" ; then
287 if ! netstat -a -t -n | grep -q ":::$p .*LISTEN" ; then
288 echo "ERROR: $service_name tcp port $p is not responding"
295 ######################################################
296 # check a unix socket
297 # usage: ctdb_check_unix_socket SERVICE_NAME <socket_path>
298 ######################################################
299 ctdb_check_unix_socket() {
301 [ -z "$socket_path" ] && return
303 if ! netstat --unix -a -n | grep -q "^unix.*LISTEN.*${socket_path}$"; then
304 echo "ERROR: $service_name socket $socket_path not found"
309 ######################################################
310 # check a command returns zero status
311 # usage: ctdb_check_command SERVICE_NAME <command>
312 ######################################################
313 ctdb_check_command() {
316 [ -z "$wait_cmd" ] && return;
317 $wait_cmd > /dev/null 2>&1 || {
318 echo "ERROR: $service_name - $wait_cmd returned error"
323 ################################################
324 # kill off any TCP connections with the given IP
325 ################################################
326 kill_tcp_connections() {
331 connfile="$CTDB_VARDIR/state/connections.$_IP"
332 netstat -tn |egrep "^tcp.*[[:space:]]+$_IP:.*ESTABLISHED" | awk '{print $4" "$5}' > $connfile
333 netstat -tn |egrep "^tcp.*[[:space:]]+::ffff:$_IP:.*ESTABLISHED" | awk '{print $4" "$5}' >> $connfile
335 while read dest src; do
336 srcip=`echo $src | sed -e "s/:[^:]*$//"`
337 srcport=`echo $src | sed -e "s/^.*://"`
338 destip=`echo $dest | sed -e "s/:[^:]*$//"`
339 destport=`echo $dest | sed -e "s/^.*://"`
340 echo "Killing TCP connection $srcip:$srcport $destip:$destport"
341 ctdb killtcp $srcip:$srcport $destip:$destport >/dev/null 2>&1 || _failed=1
343 # we only do one-way killtcp for CIFS
345 # for all others we do 2-way
347 ctdb killtcp $destip:$destport $srcip:$srcport >/dev/null 2>&1 || _failed=1
350 _killcount=`expr $_killcount + 1`
354 [ $_failed = 0 ] || {
355 echo "Failed to send killtcp control"
358 [ $_killcount -gt 0 ] || {
362 while netstat -tn |egrep "^tcp.*[[:space:]]+$_IP:.*ESTABLISHED" > /dev/null; do
364 _count=`expr $_count + 1`
365 [ $_count -gt 3 ] && {
366 echo "Timed out killing tcp connections for IP $_IP"
370 echo "killed $_killcount TCP connections to released IP $_IP"
373 ##################################################################
374 # kill off the local end for any TCP connections with the given IP
375 ##################################################################
376 kill_tcp_connections_local_only() {
381 connfile="$CTDB_VARDIR/state/connections.$_IP"
382 netstat -tn |egrep "^tcp.*[[:space:]]+$_IP:.*ESTABLISHED" | awk '{print $4" "$5}' > $connfile
383 netstat -tn |egrep "^tcp.*[[:space:]]+::ffff:$_IP:.*ESTABLISHED" | awk '{print $4" "$5}' >> $connfile
385 while read dest src; do
386 srcip=`echo $src | sed -e "s/:[^:]*$//"`
387 srcport=`echo $src | sed -e "s/^.*://"`
388 destip=`echo $dest | sed -e "s/:[^:]*$//"`
389 destport=`echo $dest | sed -e "s/^.*://"`
390 echo "Killing TCP connection $srcip:$srcport $destip:$destport"
391 ctdb killtcp $srcip:$srcport $destip:$destport >/dev/null 2>&1 || _failed=1
392 _killcount=`expr $_killcount + 1`
396 [ $_failed = 0 ] || {
397 echo "Failed to send killtcp control"
400 [ $_killcount -gt 0 ] || {
404 while netstat -tn |egrep "^tcp.*[[:space:]]+$_IP:.*ESTABLISHED" > /dev/null; do
406 _count=`expr $_count + 1`
407 [ $_count -gt 3 ] && {
408 echo "Timed out killing tcp connections for IP $_IP"
412 echo "killed $_killcount TCP connections to released IP $_IP"
415 ##################################################################
416 # tickle any TCP connections with the given IP
417 ##################################################################
418 tickle_tcp_connections() {
423 connfile="$CTDB_VARDIR/state/connections.$_IP"
424 netstat -tn |egrep "^tcp.*[[:space:]]+$_IP:.*ESTABLISHED" | awk '{print $4" "$5}' > $connfile
425 netstat -tn |egrep "^tcp.*[[:space:]]+::ffff:$_IP:.*ESTABLISHED" | awk '{print $4" "$5}' >> $connfile
427 while read dest src; do
428 srcip=`echo $src | sed -e "s/:[^:]*$//"`
429 srcport=`echo $src | sed -e "s/^.*://"`
430 destip=`echo $dest | sed -e "s/:[^:]*$//"`
431 destport=`echo $dest | sed -e "s/^.*://"`
432 echo "Tickle TCP connection $srcip:$srcport $destip:$destport"
433 ctdb tickle $srcip:$srcport $destip:$destport >/dev/null 2>&1 || _failed=1
434 echo "Tickle TCP connection $destip:$destport $srcip:$srcport"
435 ctdb tickle $destip:$destport $srcip:$srcport >/dev/null 2>&1 || _failed=1
439 [ $_failed = 0 ] || {
440 echo "Failed to send tickle control"
445 ########################################################
446 # start/stop the nfs service on different platforms
447 ########################################################
450 [ -x $CTDB_ETCDIR/init.d/nfsserver ] && {
453 [ -x $CTDB_ETCDIR/init.d/nfslock ] && {
461 service nfsserver start
464 service nfsserver stop > /dev/null 2>&1
467 set_proc "fs/nfsd/threads" 0
468 service nfsserver stop > /dev/null 2>&1
470 service nfsserver start
477 service nfslock start
485 set_proc "fs/nfsd/threads" 0
486 service nfs stop > /dev/null 2>&1
487 service nfslock stop > /dev/null 2>&1
489 service nfslock start
495 echo "Unknown platform. NFS is not supported with ctdb"
501 ########################################################
502 # start/stop the nfs lockmanager service on different platforms
503 ########################################################
504 startstop_nfslock() {
506 [ -x $CTDB_ETCDIR/init.d/nfsserver ] && {
509 [ -x $CTDB_ETCDIR/init.d/nfslock ] && {
515 # for sles there is no service for lockmanager
516 # so we instead just shutdown/restart nfs
519 service nfsserver start
522 service nfsserver stop > /dev/null 2>&1
525 service nfsserver stop
526 service nfsserver start
533 service nfslock start
536 service nfslock stop > /dev/null 2>&1
540 service nfslock start
545 echo "Unknown platform. NFS locking is not supported with ctdb"
556 local _state_dir="$CTDB_VARDIR/state/interface_modify"
557 local _lockfile="$_state_dir/$_iface.flock"
558 local _readd_base="$_state_dir/$_iface.readd.d"
560 mkdir -p $_state_dir || {
562 echo "Failed to mkdir -p $_state_dir - $ret"
566 test -f $_lockfile || {
570 flock --timeout 30 $_lockfile $CTDB_BASE/interface_modify.sh add "$_iface" "$_ip" "$_maskbits" "$_readd_base"
574 delete_ip_from_iface()
579 local _state_dir="$CTDB_VARDIR/state/interface_modify"
580 local _lockfile="$_state_dir/$_iface.flock"
581 local _readd_base="$_state_dir/$_iface.readd.d"
583 mkdir -p $_state_dir || {
585 echo "Failed to mkdir -p $_state_dir - $ret"
589 test -f $_lockfile || {
593 flock --timeout 30 $_lockfile $CTDB_BASE/interface_modify.sh delete "$_iface" "$_ip" "$_maskbits" "$_readd_base"
597 setup_iface_ip_readd_script()
602 local _readd_script=$4
603 local _state_dir="$CTDB_VARDIR/state/interface_modify"
604 local _lockfile="$_state_dir/$_iface.flock"
605 local _readd_base="$_state_dir/$_iface.readd.d"
607 mkdir -p $_state_dir || {
609 echo "Failed to mkdir -p $_state_dir - $ret"
613 test -f $_lockfile || {
617 flock --timeout 30 $_lockfile $CTDB_BASE/interface_modify.sh readd_script "$_iface" "$_ip" "$_maskbits" "$_readd_base" "$_readd_script"
621 ########################################################
622 # some simple logic for counting events - per eventscript
623 # usage: ctdb_counter_init
625 # ctdb_check_counter_limit <limit>
626 # ctdb_check_counter_limit succeeds when count >= <limit>
627 ########################################################
628 _ctdb_counter_common () {
629 _service_name="${1:-${service_name}}"
630 _counter_file="$ctdb_fail_dir/$_service_name"
631 mkdir -p "${_counter_file%/*}" # dirname
633 ctdb_counter_init () {
634 _ctdb_counter_common "$1"
638 ctdb_counter_incr () {
639 _ctdb_counter_common "$1"
642 echo -n 1 >> "$_counter_file"
644 ctdb_check_counter_limit () {
647 _limit="${1:-${service_fail_limit}}"
651 _size=$(stat -c "%s" "$_counter_file" 2>/dev/null || echo 0)
652 if [ $_size -ge $_limit ] ; then
653 echo "ERROR: more than $_limit consecutive failures for $service_name, marking cluster unhealthy"
655 elif [ $_size -gt 0 -a -z "$_quiet" ] ; then
656 echo "WARNING: less than $_limit consecutive failures ($_size) for $service_name, not unhealthy yet"
659 ctdb_check_counter_equal () {
665 _size=$(stat -c "%s" "$_counter_file" 2>/dev/null || echo 0)
666 if [ $_size -eq $_limit ] ; then
671 ctdb_check_counter () {
672 _msg="${1:-error}" # "error" - anything else is silent on fail
673 _op="${2:--ge}" # an integer operator supported by test
674 _limit="${3:-${service_fail_limit}}"
676 _ctdb_counter_common "$1"
679 _size=$(stat -c "%s" "$_counter_file" 2>/dev/null || echo 0)
680 if [ $_size $_op $_limit ] ; then
681 if [ "$_msg" = "error" ] ; then
682 echo "ERROR: $_limit consecutive failures for $_service_name, marking node unhealthy"
690 ########################################################
692 ctdb_status_dir="$CTDB_VARDIR/status"
693 ctdb_fail_dir="$CTDB_VARDIR/failcount"
695 ctdb_setup_service_state_dir ()
697 service_state_dir="$CTDB_VARDIR/state/${1:-${service_name}}"
698 mkdir -p "$service_state_dir" || {
699 echo "Error creating state dir \"$service_state_dir\""
704 ########################################################
705 # Managed status history, for auto-start/stop
707 ctdb_managed_dir="$CTDB_VARDIR/managed_history"
709 _ctdb_managed_common ()
711 _service_name="${1:-${service_name}}"
712 _ctdb_managed_file="$ctdb_managed_dir/$_service_name"
715 ctdb_service_managed ()
717 _ctdb_managed_common "$@"
718 mkdir -p "$ctdb_managed_dir"
719 touch "$_ctdb_managed_file"
722 ctdb_service_unmanaged ()
724 _ctdb_managed_common "$@"
725 rm -f "$_ctdb_managed_file"
728 is_ctdb_previously_managed_service ()
730 _ctdb_managed_common "$@"
731 [ -f "$_ctdb_managed_file" ]
734 ########################################################
735 # Check and set status
739 echo "node is \"$1\", \"${script_name}\" reports problem: $(cat $2)"
744 if [ -r "$ctdb_status_dir/$script_name/unhealthy" ] ; then
745 log_status_cat "unhealthy" "$ctdb_status_dir/$script_name/unhealthy"
747 elif [ -r "$ctdb_status_dir/$script_name/banned" ] ; then
748 log_status_cat "banned" "$ctdb_status_dir/$script_name/banned"
757 d="$ctdb_status_dir/$script_name"
764 for i in "banned" "unhealthy" ; do
771 ##################################################################
772 # Reconfigure a service on demand
774 _ctdb_service_reconfigure_common ()
776 _d="$ctdb_status_dir/${1:-${service_name}}"
778 _ctdb_service_reconfigure_flag="$_d/reconfigure"
781 ctdb_service_needs_reconfigure ()
783 _ctdb_service_reconfigure_common "$@"
784 [ -e "$_ctdb_service_reconfigure_flag" ]
787 ctdb_service_set_reconfigure ()
789 _ctdb_service_reconfigure_common "$@"
790 >"$_ctdb_service_reconfigure_flag"
793 ctdb_service_unset_reconfigure ()
795 _ctdb_service_reconfigure_common "$@"
796 rm -f "$_ctdb_service_reconfigure_flag"
799 ctdb_service_reconfigure ()
801 echo "Reconfiguring service \"$service_name\"..."
802 ctdb_service_unset_reconfigure "$@"
803 service_reconfigure "$@" || return $?
804 ctdb_counter_init "$@"
807 # Default service_reconfigure() function.
808 service_reconfigure ()
810 service "${1:-$service_name}" restart
813 ctdb_service_check_reconfigure ()
815 # Only do this for certain events.
816 case "$event_name" in
817 monitor|ipreallocated) : ;;
821 if ctdb_service_needs_reconfigure "$@" ; then
822 ctdb_service_reconfigure "$@"
824 # Fall through to non-monitor events.
825 [ "$event_name" = "monitor" ] || return 0
827 # We don't want to proceed with the rest of the monitor event
828 # here, so we exit. However, if we exit 0 then, if the
829 # service was previously broken, we might return a false
830 # positive. So we simply retrieve the status of this script
831 # from the previous monitor loop and exit with that status.
832 ctdb scriptstatus | \
833 grep -q -E "^${script_name}[[:space:]]+Status:OK[[:space:]]"
838 ##################################################################
839 # Does CTDB manage this service? - and associated auto-start/stop
841 ctdb_compat_managed_service ()
843 if [ "$1" = "yes" -a "$2" = "$_service_name" ] ; then
844 CTDB_MANAGED_SERVICES="$CTDB_MANAGED_SERVICES $2"
848 is_ctdb_managed_service ()
850 _service_name="${1:-${service_name}}"
852 # $t is used just for readability and to allow better accurate
853 # matching via leading/trailing spaces
854 t=" $CTDB_MANAGED_SERVICES "
856 # Return 0 if "<space>$_service_name<space>" appears in $t
857 if [ "${t#* ${_service_name} }" != "${t}" ] ; then
861 # If above didn't match then update $CTDB_MANAGED_SERVICES for
862 # backward compatibility and try again.
863 ctdb_compat_managed_service "$CTDB_MANAGES_VSFTPD" "vsftpd"
864 ctdb_compat_managed_service "$CTDB_MANAGES_SAMBA" "samba"
865 ctdb_compat_managed_service "$CTDB_MANAGES_SCP" "scp"
866 ctdb_compat_managed_service "$CTDB_MANAGES_WINBIND" "winbind"
867 ctdb_compat_managed_service "$CTDB_MANAGES_HTTPD" "httpd"
868 ctdb_compat_managed_service "$CTDB_MANAGES_ISCSI" "iscsi"
869 ctdb_compat_managed_service "$CTDB_MANAGES_CLAMD" "clamd"
870 ctdb_compat_managed_service "$CTDB_MANAGES_NFS" "nfs"
871 ctdb_compat_managed_service "$CTDB_MANAGES_NFS" "nfs-ganesha-gpfs"
873 t=" $CTDB_MANAGED_SERVICES "
875 # Return 0 if "<space>$_service_name<space>" appears in $t
876 [ "${t#* ${_service_name} }" != "${t}" ]
879 ctdb_start_stop_service ()
881 _service_name="${1:-${service_name}}"
883 [ "$event_name" = "monitor" ] || return 0
885 if is_ctdb_managed_service "$_service_name" ; then
886 if ! is_ctdb_previously_managed_service "$_service_name" ; then
887 echo "Starting service \"$_service_name\" - now managed"
888 ctdb_service_start "$_service_name"
892 if is_ctdb_previously_managed_service "$_service_name" ; then
893 echo "Stopping service \"$_service_name\" - no longer managed"
894 ctdb_service_stop "$_service_name"
900 ctdb_service_start ()
902 # The service is marked managed if we've ever tried to start it.
903 ctdb_service_managed "$@"
905 # Here we only want $1. If no argument is passed then
906 # service_start needs to know.
907 service_start "$@" || return $?
909 ctdb_counter_init "$@"
914 ctdb_service_unmanaged "$@"
918 # Default service_start() and service_stop() functions.
920 # These may be overridden in an eventscript. When overriding, the
921 # following convention must be followed. If these functions are
922 # called with no arguments then they may use internal logic to
923 # determine whether the service is managed and, therefore, whether
924 # they should take any action. However, if the service name is
925 # specified as an argument then an attempt must be made to start or
926 # stop the service. This is because the auto-start/stop code calls
927 # them with the service name as an argument.
930 service "${1:-${service_name}}" start
935 service "${1:-${service_name}}" stop
938 ##################################################################
940 ctdb_standard_event_handler ()
955 ipv4_host_addr_to_net_addr()
960 local HOST0=$(echo $HOST | awk -F . '{print $4}')
961 local HOST1=$(echo $HOST | awk -F . '{print $3}')
962 local HOST2=$(echo $HOST | awk -F . '{print $2}')
963 local HOST3=$(echo $HOST | awk -F . '{print $1}')
965 local HOST_NUM=$(( $HOST0 + $HOST1 * 256 + $HOST2 * (256 ** 2) + $HOST3 * (256 ** 3) ))
967 local MASK_NUM=$(( ( (2**32 - 1) * (2**(32 - $MASKBITS)) ) & (2**32 - 1) ))
969 local NET_NUM=$(( $HOST_NUM & $MASK_NUM))
971 local NET0=$(( $NET_NUM & 255 ))
972 local NET1=$(( ($NET_NUM & (255 * 256)) / 256 ))
973 local NET2=$(( ($NET_NUM & (255 * 256**2)) / 256**2 ))
974 local NET3=$(( ($NET_NUM & (255 * 256**3)) / 256**3 ))
976 echo "$NET3.$NET2.$NET1.$NET0"
979 ipv4_maskbits_to_net_mask()
983 local MASK_NUM=$(( ( (2**32 - 1) * (2**(32 - $MASKBITS)) ) & (2**32 - 1) ))
985 local MASK0=$(( $MASK_NUM & 255 ))
986 local MASK1=$(( ($MASK_NUM & (255 * 256)) / 256 ))
987 local MASK2=$(( ($MASK_NUM & (255 * 256**2)) / 256**2 ))
988 local MASK3=$(( ($MASK_NUM & (255 * 256**3)) / 256**3 ))
990 echo "$MASK3.$MASK2.$MASK1.$MASK0"
998 local N=`echo $ADDR | sed -e 's/[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*//'`
999 test -n "$N" && fail=1
1001 local ADDR0=$(echo $ADDR | awk -F . '{print $4}')
1002 local ADDR1=$(echo $ADDR | awk -F . '{print $3}')
1003 local ADDR2=$(echo $ADDR | awk -F . '{print $2}')
1004 local ADDR3=$(echo $ADDR | awk -F . '{print $1}')
1006 test "$ADDR0" -gt 255 && fail=1
1007 test "$ADDR1" -gt 255 && fail=1
1008 test "$ADDR2" -gt 255 && fail=1
1009 test "$ADDR3" -gt 255 && fail=1
1011 test x"$fail" != x"0" && {
1012 #echo "IPv4: '$ADDR' is not a valid address"
1019 # iptables doesn't like being re-entered, so flock-wrap it.
1022 flock -w 30 $CTDB_VARDIR/iptables-ctdb.flock /sbin/iptables "$@"
1025 ########################################################
1027 ########################################################
1029 # Temporary directory for tickles.
1030 tickledir="$CTDB_VARDIR/state/tickles"
1031 mkdir -p "$tickledir"
1037 mkdir -p "$tickledir" # Just in case
1040 _pnn=$(ctdb pnn) ; _pnn=${_pnn#PNN:}
1042 # What public IPs do I hold?
1043 _ips=$(ctdb -Y ip | awk -F: -v pnn=$_pnn '$3 == pnn {print $2}')
1045 # IPs as a regexp choice
1046 _ipschoice="($(echo $_ips | sed -e 's/ /|/g' -e 's/\./\\\\./g'))"
1048 # Record connections to our public IPs in a temporary file
1049 _my_connections="${tickledir}/${_port}.connections"
1050 rm -f "$_my_connections"
1052 awk -v destpat="^${_ipschoice}:${_port}\$" \
1053 '$1 == "tcp" && $6 == "ESTABLISHED" && $4 ~ destpat {print $5, $4}' |
1054 sort >"$_my_connections"
1056 # Record our current tickles in a temporary file
1057 _my_tickles="${tickledir}/${_port}.tickles"
1058 rm -f "$_my_tickles"
1059 for _i in $_ips ; do
1060 ctdb -Y gettickles $_i $_port |
1061 awk -F: 'NR > 1 { printf "%s:%s %s:%s\n", $2, $3, $4, $5 }'
1063 sort >"$_my_tickles"
1065 # Add tickles for connections that we haven't already got tickles for
1066 comm -23 "$_my_connections" "$_my_tickles" |
1067 while read _src _dst ; do
1068 ctdb addtickle $_src $_dst
1071 # Remove tickles for connections that are no longer there
1072 comm -13 "$_my_connections" "$_my_tickles" |
1073 while read _src _dst ; do
1074 ctdb deltickle $_src $_dst
1077 rm -f "$_my_connections" "$_my_tickles"
1080 ########################################################
1081 # load a site local config file
1082 ########################################################
1084 [ -n "$CTDB_RC_LOCAL" -a -x "$CTDB_RC_LOCAL" ] && {
1088 [ -x $CTDB_BASE/rc.local ] && {
1089 . $CTDB_BASE/rc.local
1092 [ -d $CTDB_BASE/rc.local.d ] && {
1093 for i in $CTDB_BASE/rc.local.d/* ; do
1094 [ -x "$i" ] && . "$i"
1098 script_name="${0##*/}" # basename
1099 service_name="$script_name" # default is just the script name
1100 service_fail_limit=1