1 # Hey Emacs, this is a -*- shell-script -*- !!!
3 # utility functions for ctdb event scripts
5 if [ -z "$CTDB_BASE" ] ; then
6 echo 'CTDB_BASE unset in CTDB functions file'
10 CTDB_VARDIR="/usr/local/var/lib/ctdb"
11 ctdb_rundir="/usr/local/var/run/ctdb"
13 # Only (and always) override these variables in test code
15 if [ -z "$CTDB_SCRIPT_VARDIR" ] ; then
16 CTDB_SCRIPT_VARDIR="/usr/local/var/lib/ctdb/state"
19 if [ -z "$CTDB_SYS_ETCDIR" ] ; then
20 CTDB_SYS_ETCDIR="/etc"
23 #######################################
24 # pull in a system config file, if any
26 rewrite_ctdb_options ()
30 _opts_defaults="mode=700"
31 # Get any extra options specified after colon
32 if [ "$CTDB_DBDIR" = "tmpfs" ] ; then
35 _opts="${CTDB_DBDIR#tmpfs:}"
37 # This is an internal variable, only used by ctdbd_wrapper.
38 # It is OK to repeat mount options - last value wins
39 CTDB_DBDIR_TMPFS_OPTIONS="${_opts_defaults}${_opts:+,}${_opts}"
41 CTDB_DBDIR="${ctdb_rundir}/CTDB_DBDIR"
44 CTDB_DBDIR_TMPFS_OPTIONS=""
51 foo="${service_config:-${service_name}}"
52 if [ -n "$foo" ] ; then
58 if [ "$1" != "ctdb" ] ; then
66 if [ -f $CTDB_SYS_ETCDIR/sysconfig/$1 ]; then
67 . $CTDB_SYS_ETCDIR/sysconfig/$1
68 elif [ -f $CTDB_SYS_ETCDIR/default/$1 ]; then
69 . $CTDB_SYS_ETCDIR/default/$1
70 elif [ -f $CTDB_BASE/sysconfig/$1 ]; then
71 . $CTDB_BASE/sysconfig/$1
74 if [ "$1" = "ctdb" ] ; then
75 _config="${CTDB_BASE}/ctdbd.conf"
76 if [ -r "$_config" ] ; then
87 ##############################################################
89 # CTDB_SCRIPT_DEBUGLEVEL can be overwritten by setting it in a
93 if [ ${CTDB_SCRIPT_DEBUGLEVEL:-2} -ge 4 ] ; then
94 # If there are arguments then echo them. Otherwise expect to
95 # use stdin, which allows us to pass lots of debug using a
100 sed -e 's@^@DEBUG: @'
103 if [ -z "$1" ] ; then
118 # Log given message or stdin to either syslog or a CTDB log file
119 # $1 is the tag passed to logger if syslog is in use.
124 case "$CTDB_LOGGING" in
126 if [ -n "$CTDB_LOGGING" ] ; then
127 _file="${CTDB_LOGGING#file:}"
129 _file="/usr/local/var/log/log.ctdb"
132 if [ -n "$*" ] ; then
140 # Handle all syslog:* variants here too. There's no tool to do
141 # the lossy things, so just use logger.
142 logger -t "ctdbd: ${_tag}" $*
147 # When things are run in the background in an eventscript then logging
148 # output might get lost. This is the "solution". :-)
149 background_with_logging ()
152 "$@" 2>&1 </dev/null |
153 script_log "${script_name}&"
159 ##############################################################
160 # check number of args for different events
166 echo "ERROR: must supply interface, IP and maskbits"
172 echo "ERROR: must supply old interface, new interface, IP and maskbits"
179 ##############################################################
180 # determine on what type of system (init style) we are running
183 # only do detection if not already set:
184 [ -z "$CTDB_INIT_STYLE" ] || return
186 if [ -x /sbin/startproc ]; then
187 CTDB_INIT_STYLE="suse"
188 elif [ -x /sbin/start-stop-daemon ]; then
189 CTDB_INIT_STYLE="debian"
191 CTDB_INIT_STYLE="redhat"
195 ######################################################
196 # simulate /sbin/service on platforms that don't have it
197 # _service() makes it easier to hook the service() function for
204 # do nothing, when no service was specified
205 [ -z "$_service_name" ] && return
207 if [ -x /sbin/service ]; then
208 $_nice /sbin/service "$_service_name" "$_op"
209 elif [ -x /usr/sbin/service ]; then
210 $_nice /usr/sbin/service "$_service_name" "$_op"
211 elif [ -x $CTDB_SYS_ETCDIR/init.d/$_service_name ]; then
212 $_nice $CTDB_SYS_ETCDIR/init.d/$_service_name "$_op"
213 elif [ -x $CTDB_SYS_ETCDIR/rc.d/init.d/$_service_name ]; then
214 $_nice $CTDB_SYS_ETCDIR/rc.d/init.d/$_service_name "$_op"
224 ######################################################
225 # simulate /sbin/service (niced) on platforms that don't have it
232 ######################################################
233 # Cached retrieval of PNN from local node. This never changes so why
234 # open a client connection to the server each time this is needed?
235 # This sets $pnn - this avoid an unnecessary subprocess.
238 _pnn_file="${CTDB_SCRIPT_VARDIR}/my-pnn"
239 if [ ! -f "$_pnn_file" ] ; then
240 ctdb pnn | sed -e 's@.*:@@' >"$_pnn_file"
243 read pnn <"$_pnn_file"
246 ######################################################
247 # wrapper around /proc/ settings to allow them to be hooked
249 # 1st arg is relative path under /proc/, 2nd arg is value to set
252 echo "$2" >"/proc/$1"
257 if [ -w "/proc/$1" ] ; then
262 ######################################################
263 # wrapper around getting file contents from /proc/ to allow
264 # this to be hooked for testing
265 # 1st arg is relative path under /proc/
271 ######################################################
272 # Print up to $_max kernel stack traces for processes named $_program
273 program_stack_traces ()
279 for _pid in $(pidof "$_prog") ; do
280 [ $_count -le $_max ] || break
282 # Do this first to avoid racing with process exit
283 _stack=$(get_proc "${_pid}/stack" 2>/dev/null)
284 if [ -n "$_stack" ] ; then
285 echo "Stack trace for ${_prog}[${_pid}]:"
287 _count=$(($_count + 1))
292 ######################################################
293 # Ensure $service_name is set
294 assert_service_name ()
296 [ -n "$service_name" ] || die "INTERNAL ERROR: \$service_name not set"
299 ######################################################
300 # check a set of directories is available
301 # return 1 on a missing directory
302 # directories are read from stdin
303 ######################################################
304 ctdb_check_directories_probe()
306 while IFS="" read d ; do
312 [ -d "${d}/." ] || return 1
317 ######################################################
318 # check a set of directories is available
319 # directories are read from stdin
320 ######################################################
321 ctdb_check_directories()
323 ctdb_check_directories_probe || {
324 echo "ERROR: $service_name directory \"$d\" not available"
329 ######################################################
330 # check a set of tcp ports
331 # usage: ctdb_check_tcp_ports <ports...>
332 ######################################################
334 # This flag file is created when a service is initially started. It
335 # is deleted the first time TCP port checks for that service succeed.
336 # Until then ctdb_check_tcp_ports() prints a more subtle "error"
337 # message if a port check fails.
338 _ctdb_check_tcp_common ()
341 _d="${CTDB_SCRIPT_VARDIR}/failcount"
342 _ctdb_service_started_file="${_d}/${service_name}.started"
345 ctdb_check_tcp_init ()
347 _ctdb_check_tcp_common
348 mkdir -p "${_ctdb_service_started_file%/*}" # dirname
349 touch "$_ctdb_service_started_file"
352 # Check whether something is listening on all of the given TCP ports
353 # using the "ctdb checktcpport" command.
354 ctdb_check_tcp_ports()
356 if [ -z "$1" ] ; then
357 echo "INTERNAL ERROR: ctdb_check_tcp_ports - no ports specified"
361 for _p ; do # process each function argument (port)
362 _cmd="ctdb checktcpport $_p"
367 _ctdb_check_tcp_common
368 if [ ! -f "$_ctdb_service_started_file" ] ; then
369 echo "ERROR: $service_name tcp port $_p is not responding"
370 debug "\"ctdb checktcpport $_p\" was able to bind to port"
372 echo "INFO: $service_name tcp port $_p is not responding"
378 # Couldn't bind, something already listening, next port...
382 echo "ERROR: unexpected error running \"ctdb checktcpport\""
384 ctdb checktcpport (exited with $_ret) with output:
391 # All ports listening
392 _ctdb_check_tcp_common
393 rm -f "$_ctdb_service_started_file"
397 ######################################################
398 # check a unix socket
399 # usage: ctdb_check_unix_socket SERVICE_NAME <socket_path>
400 ######################################################
401 ctdb_check_unix_socket() {
403 [ -z "$socket_path" ] && return
405 if ! netstat --unix -a -n | grep -q "^unix.*LISTEN.*${socket_path}$"; then
406 echo "ERROR: $service_name socket $socket_path not found"
411 ######################################################
412 # check a command returns zero status
413 # usage: ctdb_check_command <command>
414 ######################################################
415 ctdb_check_command ()
417 _out=$("$@" 2>&1) || {
418 echo "ERROR: $* returned error"
424 ################################################
425 # kill off any TCP connections with the given IP
426 ################################################
427 kill_tcp_connections ()
432 if [ "$2" = "oneway" ] ; then
436 get_tcp_connections_for_ip "$_ip" | {
441 while read _dst _src; do
442 _destport="${_dst##*:}"
445 # we only do one-way killtcp for CIFS
446 139|445) __oneway=true ;;
449 echo "Killing TCP connection $_src $_dst"
450 _connections="${_connections}${_nl}${_src} ${_dst}"
451 if ! $__oneway ; then
452 _connections="${_connections}${_nl}${_dst} ${_src}"
455 _killcount=$(($_killcount + 1))
458 if [ $_killcount -eq 0 ] ; then
462 echo "$_connections" | ctdb killtcp || {
463 echo "Failed to send killtcp control"
469 _remaining=$(get_tcp_connections_for_ip $_ip | wc -l)
471 if [ $_remaining -eq 0 ] ; then
472 echo "Killed $_killcount TCP connections to released IP $_ip"
476 _count=$(($_count + 1))
477 if [ $_count -gt 3 ] ; then
478 echo "Timed out killing tcp connections for IP $_ip ($_remaining remaining)"
482 echo "Waiting for $_remaining connections to be killed for IP $_ip"
488 ##################################################################
489 # kill off the local end for any TCP connections with the given IP
490 ##################################################################
491 kill_tcp_connections_local_only ()
493 kill_tcp_connections "$1" "oneway"
496 ##################################################################
497 # tickle any TCP connections with the given IP
498 ##################################################################
499 tickle_tcp_connections ()
503 get_tcp_connections_for_ip "$_ip" |
507 while read dest src; do
508 echo "Tickle TCP connection $src $dest"
509 ctdb tickle $src $dest >/dev/null 2>&1 || _failed=true
510 echo "Tickle TCP connection $dest $src"
511 ctdb tickle $dest $src >/dev/null 2>&1 || _failed=true
515 echo "Failed to send tickle control"
520 get_tcp_connections_for_ip ()
524 netstat -tn | awk -v ip=$_ip \
525 'index($1, "tcp") == 1 && \
526 (index($4, ip ":") == 1 || index($4, "::ffff:" ip ":") == 1) \
527 && $6 == "ESTABLISHED" \
531 ########################################################
539 # Ensure interface is up
540 ip link set "$_iface" up || \
541 die "Failed to bringup interface $_iface"
543 # Only need to define broadcast for IPv4
549 ip addr add "$_ip/$_maskbits" $_bcast dev "$_iface" || {
550 echo "Failed to add $_ip/$_maskbits on dev $_iface"
554 # Wait 5 seconds for IPv6 addresses to stop being tentative...
555 if [ -z "$_bcast" ] ; then
556 for _x in $(seq 1 10) ; do
557 ip addr show to "${_ip}/128" | grep -q "tentative" || break
561 # If the address was a duplicate then it won't be on the
562 # interface so flag an error.
563 _t=$(ip addr show to "${_ip}/128")
566 echo "Failed to add $_ip/$_maskbits on dev $_iface"
569 *tentative*|*dadfailed*)
570 echo "Failed to add $_ip/$_maskbits on dev $_iface"
571 ip addr del "$_ip/$_maskbits" dev "$_iface"
578 delete_ip_from_iface()
584 # This could be set globally for all interfaces but it is probably
585 # better to avoid surprises, so limit it the interfaces where CTDB
586 # has public IP addresses. There isn't anywhere else convenient
587 # to do this so just set it each time. This is much cheaper than
588 # remembering and re-adding secondaries.
589 set_proc "sys/net/ipv4/conf/${_iface}/promote_secondaries" 1
591 ip addr del "$_ip/$_maskbits" dev "$_iface" || {
592 echo "Failed to del $_ip on dev $_iface"
597 # If the given IP is hosted then print 2 items: maskbits and iface
603 *:*) _family="inet6" ; _bits=128 ;;
604 *) _family="inet" ; _bits=32 ;;
607 ip addr show to "${_addr}/${_bits}" 2>/dev/null | \
608 awk -v family="${_family}" \
609 'NR == 1 { iface = $2; sub(":$", "", iface) ; \
610 sub("@.*", "", iface) } \
611 $1 ~ /inet/ { mask = $2; sub(".*/", "", mask); \
612 print mask, iface, family }'
617 _addr="${1%/*}" # Remove optional maskbits
619 set -- $(ip_maskbits_iface $_addr)
620 if [ -n "$1" ] ; then
623 echo "Removing public address $_addr/$_maskbits from device $_iface"
624 delete_ip_from_iface $_iface $_addr $_maskbits >/dev/null 2>&1
628 drop_all_public_ips ()
630 while read _ip _x ; do
632 done <"${CTDB_PUBLIC_ADDRESSES:-/dev/null}"
637 set_proc_maybe sys/net/ipv4/route/flush 1
638 set_proc_maybe sys/net/ipv6/route/flush 1
641 ########################################################
643 _ctdb_counter_common () {
644 _service_name="${1:-${service_name:-${script_name}}}"
645 _counter_file="${CTDB_SCRIPT_VARDIR}/failcount/${_service_name}"
646 mkdir -p "${_counter_file%/*}" # dirname
648 ctdb_counter_init () {
649 _ctdb_counter_common "$1"
653 ctdb_counter_incr () {
654 _ctdb_counter_common "$1"
657 echo -n 1 >> "$_counter_file"
659 ctdb_counter_get () {
660 _ctdb_counter_common "$1"
662 stat -c "%s" "$_counter_file" 2>/dev/null || echo 0
664 ctdb_check_counter () {
665 _msg="${1:-error}" # "error" - anything else is silent on fail
666 _op="${2:--ge}" # an integer operator supported by test
667 _limit="${3:-${service_fail_limit}}"
670 _size=$(ctdb_counter_get "$1")
673 if [ "$_op" != "%" ] ; then
674 if [ $_size $_op $_limit ] ; then
678 if [ $(($_size $_op $_limit)) -eq 0 ] ; then
683 if [ "$_msg" = "error" ] ; then
684 echo "ERROR: $_size consecutive failures for $_service_name, marking node unhealthy"
692 ########################################################
694 ctdb_setup_service_state_dir ()
696 service_state_dir="${CTDB_SCRIPT_VARDIR}/service_state/${1:-${service_name}}"
697 mkdir -p "$service_state_dir" || {
698 echo "Error creating state dir \"$service_state_dir\""
703 ########################################################
704 # Managed status history, for auto-start/stop
706 _ctdb_managed_common ()
708 _ctdb_managed_file="${CTDB_SCRIPT_VARDIR}/managed_history/${service_name}"
711 ctdb_service_managed ()
714 mkdir -p "${_ctdb_managed_file%/*}" # dirname
715 touch "$_ctdb_managed_file"
718 ctdb_service_unmanaged ()
721 rm -f "$_ctdb_managed_file"
724 is_ctdb_previously_managed_service ()
727 [ -f "$_ctdb_managed_file" ]
730 ##################################################################
731 # Reconfigure a service on demand
733 _ctdb_service_reconfigure_common ()
735 _d="${CTDB_SCRIPT_VARDIR}/service_status/${service_name}"
737 _ctdb_service_reconfigure_flag="$_d/reconfigure"
740 ctdb_service_needs_reconfigure ()
742 _ctdb_service_reconfigure_common
743 [ -e "$_ctdb_service_reconfigure_flag" ]
746 ctdb_service_set_reconfigure ()
748 _ctdb_service_reconfigure_common
749 >"$_ctdb_service_reconfigure_flag"
752 ctdb_service_unset_reconfigure ()
754 _ctdb_service_reconfigure_common
755 rm -f "$_ctdb_service_reconfigure_flag"
758 ctdb_service_reconfigure ()
760 echo "Reconfiguring service \"${service_name}\"..."
761 ctdb_service_unset_reconfigure
762 service_reconfigure || return $?
766 # Default service_reconfigure() function does nothing.
767 service_reconfigure ()
772 ctdb_reconfigure_take_lock ()
774 _ctdb_service_reconfigure_common
775 _lock="${_d}/reconfigure_lock"
776 mkdir -p "${_lock%/*}" # dirname
781 # This is overkill but will work if we need to extend this to
782 # allow certain events to run multiple times in parallel
783 # (e.g. takeip) and write multiple PIDs to the file.
785 if [ -n "$_locker_event" ] ; then
787 if [ -n "$_pid" -a "$_pid" != $$ ] && \
788 kill -0 "$_pid" 2>/dev/null ; then
794 printf "%s\n%s\n" "$event_name" $$ >"$_lock"
799 ctdb_reconfigure_release_lock ()
801 _ctdb_service_reconfigure_common
802 _lock="${_d}/reconfigure_lock"
807 ctdb_replay_monitor_status ()
809 echo "Replaying previous status for this script due to reconfigure..."
810 # Leading separator ('|') is missing in some versions...
811 _out=$(ctdb scriptstatus -X | grep -E "^\|?monitor\|${script_name}\|")
812 # Output looks like this:
813 # |monitor|60.nfs|1|ERROR|1314764004.030861|1314764004.035514|foo bar|
814 # This is the cheapest way of getting fields in the middle.
815 set -- $(IFS="|" ; echo $_out)
818 # The error output field can include colons so we'll try to
819 # preserve them. The weak checking at the beginning tries to make
820 # this work for both broken (no leading '|') and fixed output.
822 _err_out="${_out#*monitor|${script_name}|*|*|*|*|}"
824 OK) : ;; # Do nothing special.
826 # Recast this as an error, since we can't exit with the
827 # correct negative number.
829 _err_out="[Replay of TIMEDOUT scriptstatus - note incorrect return code.] ${_err_out}"
832 # Recast this as an OK, since we can't exit with the
833 # correct negative number.
835 _err_out="[Replay of DISABLED scriptstatus - note incorrect return code.] ${_err_out}"
837 *) : ;; # Must be ERROR, do nothing special.
839 if [ -n "$_err_out" ] ; then
845 ctdb_service_check_reconfigure ()
849 # We only care about some events in this function. For others we
851 case "$event_name" in
852 monitor|ipreallocated|reconfigure) : ;;
856 if ctdb_reconfigure_take_lock ; then
857 # No events covered by this function are running, so proceed
859 case "$event_name" in
861 (ctdb_service_reconfigure)
865 if ctdb_service_needs_reconfigure ; then
866 ctdb_service_reconfigure
871 ctdb_reconfigure_release_lock
873 # Somebody else is running an event we don't want to collide
874 # with. We proceed with caution.
875 case "$event_name" in
877 # Tell whoever called us to retry.
881 # Defer any scheduled reconfigure and just run the
882 # rest of the ipreallocated event, as per the
883 # eventscript. There's an assumption here that the
884 # event doesn't depend on any scheduled reconfigure.
885 # This is true in the current code.
889 # There is most likely a reconfigure in progress so
890 # the service is possibly unstable. As above, we
891 # defer any scheduled reconfigured. We also replay
892 # the previous monitor status since that's the best
893 # information we have.
894 ctdb_replay_monitor_status
900 ##################################################################
901 # Does CTDB manage this service? - and associated auto-start/stop
903 ctdb_compat_managed_service ()
905 if [ "$1" = "yes" -a "$2" = "$service_name" ] ; then
906 CTDB_MANAGED_SERVICES="$CTDB_MANAGED_SERVICES $2"
910 is_ctdb_managed_service ()
914 # $t is used just for readability and to allow better accurate
915 # matching via leading/trailing spaces
916 t=" $CTDB_MANAGED_SERVICES "
918 # Return 0 if "<space>$service_name<space>" appears in $t
919 if [ "${t#* ${service_name} }" != "${t}" ] ; then
923 # If above didn't match then update $CTDB_MANAGED_SERVICES for
924 # backward compatibility and try again.
925 ctdb_compat_managed_service "$CTDB_MANAGES_VSFTPD" "vsftpd"
926 ctdb_compat_managed_service "$CTDB_MANAGES_SAMBA" "samba"
927 ctdb_compat_managed_service "$CTDB_MANAGES_WINBIND" "winbind"
928 ctdb_compat_managed_service "$CTDB_MANAGES_HTTPD" "apache2"
929 ctdb_compat_managed_service "$CTDB_MANAGES_HTTPD" "httpd"
930 ctdb_compat_managed_service "$CTDB_MANAGES_ISCSI" "iscsi"
931 ctdb_compat_managed_service "$CTDB_MANAGES_CLAMD" "clamd"
932 ctdb_compat_managed_service "$CTDB_MANAGES_NFS" "nfs"
934 t=" $CTDB_MANAGED_SERVICES "
936 # Return 0 if "<space>$service_name<space>" appears in $t
937 [ "${t#* ${service_name} }" != "${t}" ]
940 ctdb_start_stop_service ()
944 # Allow service-start/service-stop pseudo-events to start/stop
945 # services when we're not auto-starting/stopping and we're not
947 case "$event_name" in
949 if is_ctdb_managed_service ; then
950 die 'service-start event not permitted when service is managed'
952 if [ "$CTDB_SERVICE_AUTOSTARTSTOP" = "yes" ] ; then
953 die 'service-start event not permitted with $CTDB_SERVICE_AUTOSTARTSTOP = yes'
959 if is_ctdb_managed_service ; then
960 die 'service-stop event not permitted when service is managed'
962 if [ "$CTDB_SERVICE_AUTOSTARTSTOP" = "yes" ] ; then
963 die 'service-stop event not permitted with $CTDB_SERVICE_AUTOSTARTSTOP = yes'
970 # Do nothing unless configured to...
971 [ "$CTDB_SERVICE_AUTOSTARTSTOP" = "yes" ] || return 0
973 [ "$event_name" = "monitor" ] || return 0
975 if is_ctdb_managed_service ; then
976 if ! is_ctdb_previously_managed_service ; then
977 echo "Starting service \"$service_name\" - now managed"
978 background_with_logging ctdb_service_start
982 if is_ctdb_previously_managed_service ; then
983 echo "Stopping service \"$service_name\" - no longer managed"
984 background_with_logging ctdb_service_stop
990 ctdb_service_start ()
992 # The service is marked managed if we've ever tried to start it.
995 service_start || return $?
1001 ctdb_service_stop ()
1003 ctdb_service_unmanaged
1007 # Default service_start() and service_stop() functions.
1009 # These may be overridden in an eventscript.
1012 service "$service_name" start
1017 service "$service_name" stop
1020 ##################################################################
1022 ctdb_standard_event_handler ()
1029 _family="$1" ; shift
1030 if [ "$_family" = "inet6" ] ; then
1031 _iptables_cmd="ip6tables"
1033 _iptables_cmd="iptables"
1036 # iptables doesn't like being re-entered, so flock-wrap it.
1037 flock -w 30 "${CTDB_SCRIPT_VARDIR}/iptables.flock" "$_iptables_cmd" "$@"
1040 # AIX (and perhaps others?) doesn't have mktemp
1041 if ! type mktemp >/dev/null 2>&1 ; then
1045 if [ "$1" = "-d" ] ; then
1049 _d="${TMPDIR:-/tmp}"
1050 _hex10=$(dd if=/dev/urandom count=20 2>/dev/null | \
1052 sed -e 's@\(..........\).*@\1@')
1053 _t="${_d}/tmp.${_hex10}"
1066 ########################################################
1068 ########################################################
1074 tickledir="${CTDB_SCRIPT_VARDIR}/tickles"
1075 mkdir -p "$tickledir"
1079 # What public IPs do I hold?
1080 _ips=$(ctdb -X ip | awk -F'|' -v pnn=$pnn '$3 == pnn {print $2}')
1082 # IPs as a regexp choice
1083 _ipschoice="($(echo $_ips | sed -e 's/ /|/g' -e 's/\./\\\\./g'))"
1085 # Record connections to our public IPs in a temporary file
1086 _my_connections="${tickledir}/${_port}.connections"
1087 rm -f "$_my_connections"
1089 awk -v destpat="^${_ipschoice}:${_port}\$" \
1090 '$1 == "tcp" && $6 == "ESTABLISHED" && $4 ~ destpat {print $5, $4}' |
1091 sort >"$_my_connections"
1093 # Record our current tickles in a temporary file
1094 _my_tickles="${tickledir}/${_port}.tickles"
1095 rm -f "$_my_tickles"
1096 for _i in $_ips ; do
1097 ctdb -X gettickles $_i $_port |
1098 awk -F'|' 'NR > 1 { printf "%s:%s %s:%s\n", $2, $3, $4, $5 }'
1100 sort >"$_my_tickles"
1102 # Add tickles for connections that we haven't already got tickles for
1103 comm -23 "$_my_connections" "$_my_tickles" |
1104 while read _src _dst ; do
1105 ctdb addtickle $_src $_dst
1108 # Remove tickles for connections that are no longer there
1109 comm -13 "$_my_connections" "$_my_tickles" |
1110 while read _src _dst ; do
1111 ctdb deltickle $_src $_dst
1114 rm -f "$_my_connections" "$_my_tickles"
1117 ########################################################
1118 # load a site local config file
1119 ########################################################
1121 [ -n "$CTDB_RC_LOCAL" -a -x "$CTDB_RC_LOCAL" ] && {
1125 [ -x $CTDB_BASE/rc.local ] && {
1126 . $CTDB_BASE/rc.local
1129 [ -d $CTDB_BASE/rc.local.d ] && {
1130 for i in $CTDB_BASE/rc.local.d/* ; do
1131 [ -x "$i" ] && . "$i"
1135 script_name="${0##*/}" # basename
1136 service_fail_limit=1