When we harvest all tcp connections to kill off after a takeip/releaseip event we...
[metze/ctdb/wip.git] / config / functions
1 # utility functions for ctdb event scripts
2
3 #######################################
4 # pull in a system config file, if any
5 loadconfig() {
6     name="$1"
7     if [ -f /etc/sysconfig/$name ]; then
8         . /etc/sysconfig/$name
9     elif [ -f /etc/default/$name ]; then
10         . /etc/default/$name
11     elif [ -f $CTDB_BASE/sysconfig/$name ]; then
12         . $CTDB_BASE/sysconfig/$name
13     fi
14 }
15
16
17 ######################################################
18 # simulate /sbin/service on platforms that don't have it
19 service() { 
20   service_name="$1"
21   op="$2"
22   if [ -x /sbin/service ]; then
23       /sbin/service "$service_name" "$op"
24   elif [ -x /etc/init.d/$service_name ]; then
25       /etc/init.d/$service_name "$op"
26   elif [ -x /etc/rc.d/init.d/$service_name ]; then
27       /etc/rc.d/init.d/$service_name "$op"
28   fi
29 }
30
31 ######################################################
32 # simulate /sbin/service (niced) on platforms that don't have it
33 nice_service() { 
34   service_name="$1"
35   op="$2"
36   if [ -x /sbin/service ]; then
37       nice /sbin/service "$service_name" "$op"
38   elif [ -x /etc/init.d/$service_name ]; then
39       nice /etc/init.d/$service_name "$op"
40   elif [ -x /etc/rc.d/init.d/$service_name ]; then
41       nice /etc/rc.d/init.d/$service_name "$op"
42   fi
43 }
44
45 ######################################################
46 # wait for a command to return a zero exit status
47 # usage: ctdb_wait_command SERVICE_NAME <command>
48 ######################################################
49 ctdb_wait_command() {
50   service_name="$1"
51   wait_cmd="$2"
52   [ -z "$wait_cmd" ] && return;
53   all_ok=0
54   echo "Waiting for service $service_name to start"
55   while [ $all_ok -eq 0 ]; do
56           $wait_cmd > /dev/null 2>&1 && all_ok=1
57           ctdb status > /dev/null 2>&1 || {
58                 echo "ctdb daemon has died. Exiting wait for $service_name"
59                 exit 1
60           }
61           [ $all_ok -eq 1 ] || sleep 1
62   done
63   echo "Local service $service_name is up"
64 }
65
66
67 ######################################################
68 # wait for a set of tcp ports
69 # usage: ctdb_wait_tcp_ports SERVICE_NAME <ports...>
70 ######################################################
71 ctdb_wait_tcp_ports() {
72   service_name="$1"
73   shift
74   wait_ports="$*"
75   [ -z "$wait_ports" ] && return;
76   all_ok=0
77   echo "Waiting for tcp service $service_name to start"
78   while [ $all_ok -eq 0 ]; do
79           all_ok=1
80           for p in $wait_ports; do
81               if [ -x /usr/bin/netcat ]; then
82                   /usr/bin/netcat -z 127.0.0.1 $p > /dev/null || all_ok=0
83               elif [ -x /usr/bin/nc ]; then
84                   /usr/bin/nc -z 127.0.0.1 $p > /dev/null || all_ok=0
85               elif [ -x /usr/bin/netstat ]; then
86                   (netstat -a -n | egrep "0.0.0.0:$p[[:space:]]*LISTEN" > /dev/null) || all_ok=0
87               elif [ -x /bin/netstat ]; then
88                   (netstat -a -n | egrep "0.0.0.0:$p[[:space:]]*LISTEN" > /dev/null) || all_ok=0
89               else 
90                   echo "No tool to check tcp ports availabe. can not check in ctdb_wait_tcp_ports"
91                   return
92               fi
93           done
94           [ $all_ok -eq 1 ] || sleep 1
95           ctdb status > /dev/null 2>&1 || {
96                 echo "ctdb daemon has died. Exiting tcp wait $service_name"
97                 exit 1
98           }
99   done
100   echo "Local tcp services for $service_name are up"
101 }
102
103
104
105 ######################################################
106 # wait for a set of directories
107 # usage: ctdb_wait_directories SERVICE_NAME <directories...>
108 ######################################################
109 ctdb_wait_directories() {
110   service_name="$1"
111   shift
112   wait_dirs="$*"
113   [ -z "$wait_dirs" ] && return;
114   all_ok=0
115   echo "Waiting for local directories for $service_name"
116   while [ $all_ok -eq 0 ]; do
117           all_ok=1
118           for d in $wait_dirs; do
119               [ -d $d ] || all_ok=0
120           done
121           [ $all_ok -eq 1 ] || sleep 1
122           ctdb status > /dev/null 2>&1 || {
123                 echo "ctdb daemon has died. Exiting directory wait for $service_name"
124                 exit 1
125           }
126   done
127   echo "Local directories for $service_name are available"
128 }
129
130
131 ######################################################
132 # check that a rpc server is registered with portmap
133 # and responding to requests
134 # usage: ctdb_check_rpc SERVICE_NAME PROGNUM VERSION
135 ######################################################
136 ctdb_check_rpc() {
137     service_name="$1"
138     prognum="$2"
139     version="$3"
140     rpcinfo -u localhost $prognum $version > /dev/null || {
141             echo "ERROR: $service_name not responding to rpc requests"
142             exit 1
143     }
144 }
145
146 ######################################################
147 # check a set of directories is available
148 # return 0 on a missing directory
149 # usage: ctdb_check_directories_probe SERVICE_NAME <directories...>
150 ######################################################
151 ctdb_check_directories_probe() {
152   service_name="$1"
153   shift
154   wait_dirs="$*"
155   [ -z "$wait_dirs" ] && return;
156   for d in $wait_dirs; do
157       [ -d $d ] || return 1
158   done
159   return 0
160 }
161
162 ######################################################
163 # check a set of directories is available
164 # usage: ctdb_check_directories SERVICE_NAME <directories...>
165 ######################################################
166 ctdb_check_directories() {
167   service_name="$1"
168   shift
169   wait_dirs="$*"
170   ctdb_check_directories_probe "$service_name" $wait_dirs || {
171       echo "ERROR: $service_name directory $d not available"
172       exit 1
173   }
174 }
175
176 ######################################################
177 # check a set of tcp ports
178 # usage: ctdb_check_tcp_ports SERVICE_NAME <ports...>
179 ######################################################
180 ctdb_check_tcp_ports() {
181   service_name="$1"
182   shift
183   wait_ports="$*"
184   [ -z "$wait_ports" ] && return;
185   for p in $wait_ports; do
186       all_ok=1
187       if [ -x /usr/bin/netcat ]; then
188           /usr/bin/netcat -z 127.0.0.1 $p > /dev/null || all_ok=0
189       elif [ -x /usr/bin/nc ]; then
190           /usr/bin/nc -z 127.0.0.1 $p > /dev/null || all_ok=0
191       elif [ -x /usr/bin/netstat ]; then
192           (netstat -a -n | egrep "0.0.0.0:$p .*LISTEN" > /dev/null ) || all_ok=0
193       elif [ -x /bin/netstat ]; then
194           (netstat -a -n | egrep "0.0.0.0:$p .*LISTEN" > /dev/null ) || all_ok=0
195       fi
196       [ $all_ok -eq 1 ] || {
197           echo "ERROR: $service_name tcp port $p is not responding"
198           exit 1
199       }
200   done
201 }
202
203 ######################################################
204 # check a command returns zero status
205 # usage: ctdb_check_command SERVICE_NAME <command>
206 ######################################################
207 ctdb_check_command() {
208   service_name="$1"
209   wait_cmd="$2"
210   [ -z "$wait_cmd" ] && return;
211   $wait_cmd > /dev/null 2>&1 || {
212       echo "ERROR: $service_name - $wait_cmd returned error"
213       exit 1
214   }
215 }
216
217 ################################################
218 # kill off any TCP connections with the given IP
219 ################################################
220 kill_tcp_connections() {
221     _IP="$1"    
222     _failed=0
223
224     _killcount=0
225     connfile="$CTDB_BASE/state/connections.$_IP"
226     netstat -tn |egrep "^tcp.*[[:space:]]+$_IP:.*ESTABLISHED" | awk '{print $4" "$5}' > $connfile
227     netstat -tn |egrep "^tcp.*[[:space:]]+::ffff:$_IP:.*ESTABLISHED" | awk '{print $4" "$5}' >> $connfile
228
229     while read dest src; do
230         srcip=`echo $src | sed -e "s/:[^:]*$//"`
231         srcport=`echo $src | sed -e "s/^.*://"`
232         destip=`echo $dest | sed -e "s/:[^:]*$//"`
233         destport=`echo $dest | sed -e "s/^.*://"`
234         echo "Killing TCP connection $srcip:$srcport $destip:$destport"
235         ctdb killtcp $srcip:$srcport $destip:$destport >/dev/null 2>&1 || _failed=1
236         case $destport in
237           # we only do one-way killtcp for NFS and CIFS
238           139|445|2049) : ;;
239           # for all others we do 2-way
240           *) 
241                 ctdb killtcp $destip:$destport $srcip:$srcport >/dev/null 2>&1 || _failed=1
242                 ;;
243         esac
244         _killcount=`expr $_killcount + 1`
245      done < $connfile
246     /bin/rm -f $connfile
247
248     [ $_failed = 0 ] || {
249         echo "Failed to send killtcp control"
250         return;
251     }
252     [ $_killcount -gt 0 ] || {
253         return;
254     }
255     _count=0
256     while netstat -tn |egrep "^tcp.*[[:space:]]+$_IP:.*ESTABLISHED" > /dev/null; do
257         sleep 1
258         _count=`expr $_count + 1`
259         [ $_count -gt 3 ] && {
260             echo "Timed out killing tcp connections for IP $_IP"
261             return;
262         }
263     done
264     echo "killed $_killcount TCP connections to released IP $_IP"
265 }
266
267 ########################################################
268 # start/stop the nfs service on different platforms
269 ########################################################
270 startstop_nfs() {
271         PLATFORM="unknown"
272         [ -x /etc/init.d/nfsserver ] && {
273                 PLATFORM="sles"
274         }
275         [ -x /etc/init.d/nfslock ] && {
276                 PLATFORM="rhel"
277         }
278
279         case $PLATFORM in
280         sles)
281                 case $1 in
282                 start)
283                         service nfsserver start
284                         ;;
285                 stop)
286                         service nfsserver stop > /dev/null 2>&1
287                         ;;
288                 esac
289                 ;;
290         rhel)
291                 case $1 in
292                 start)
293                         service nfslock start
294                         service nfs start
295                         ;;
296                 stop)
297                         service nfs stop > /dev/null 2>&1
298                         service nfslock stop > /dev/null 2>&1
299                         ;;
300                 esac
301                 ;;
302         *)
303                 echo "Unknown platform. NFS is not supported with ctdb"
304                 exit 1
305                 ;;
306         esac
307 }
308
309 ########################################################
310 # start/stop the nfs lockmanager service on different platforms
311 ########################################################
312 startstop_nfslock() {
313         PLATFORM="unknown"
314         [ -x /etc/init.d/nfsserver ] && {
315                 PLATFORM="sles"
316         }
317         [ -x /etc/init.d/nfslock ] && {
318                 PLATFORM="rhel"
319         }
320
321         case $PLATFORM in
322         sles)
323                 # for sles there is no service for lockmanager
324                 # so we instead just shutdown/restart nfs
325                 case $1 in
326                 start)
327                         service nfsserver start
328                         ;;
329                 stop)
330                         service nfsserver stop > /dev/null 2>&1
331                         ;;
332                 esac
333                 ;;
334         rhel)
335                 case $1 in
336                 start)
337                         service nfslock start
338                         ;;
339                 stop)
340                         service nfslock stop > /dev/null 2>&1
341                         ;;
342                 esac
343                 ;;
344         *)
345                 echo "Unknown platform. NFS locking is not supported with ctdb"
346                 exit 1
347                 ;;
348         esac
349 }
350
351 ########################################################
352 # load a site local config file
353 ########################################################
354
355 [ -x $CTDB_BASE/rc.local ] && {
356         . $CTDB_BASE/rc.local
357 }
358