Merge commit 'origin/master' into martins
[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       ( echo $d | grep -q '%' ) && continue
158       [ -d $d ] || return 1
159   done
160   return 0
161 }
162
163 ######################################################
164 # check a set of directories is available
165 # usage: ctdb_check_directories SERVICE_NAME <directories...>
166 ######################################################
167 ctdb_check_directories() {
168   service_name="$1"
169   shift
170   wait_dirs="$*"
171   ctdb_check_directories_probe "$service_name" $wait_dirs || {
172       echo "ERROR: $service_name directory $d not available"
173       exit 1
174   }
175 }
176
177 ######################################################
178 # check a set of tcp ports
179 # usage: ctdb_check_tcp_ports SERVICE_NAME <ports...>
180 ######################################################
181 ctdb_check_tcp_ports() {
182   service_name="$1"
183   shift
184   wait_ports="$*"
185   [ -z "$wait_ports" ] && return;
186   for p in $wait_ports; do
187       all_ok=1
188       if [ -x /usr/bin/netcat ]; then
189           /usr/bin/netcat -z 127.0.0.1 $p > /dev/null || all_ok=0
190       elif [ -x /usr/bin/nc ]; then
191           /usr/bin/nc -z 127.0.0.1 $p > /dev/null || all_ok=0
192       elif [ -x /usr/bin/netstat ]; then
193           (netstat -a -n | egrep "0.0.0.0:$p .*LISTEN" > /dev/null ) || all_ok=0
194       elif [ -x /bin/netstat ]; then
195           (netstat -a -n | egrep "0.0.0.0:$p .*LISTEN" > /dev/null ) || all_ok=0
196       fi
197       [ $all_ok -eq 1 ] || {
198           echo "ERROR: $service_name tcp port $p is not responding"
199           exit 1
200       }
201   done
202 }
203
204 ######################################################
205 # check a command returns zero status
206 # usage: ctdb_check_command SERVICE_NAME <command>
207 ######################################################
208 ctdb_check_command() {
209   service_name="$1"
210   wait_cmd="$2"
211   [ -z "$wait_cmd" ] && return;
212   $wait_cmd > /dev/null 2>&1 || {
213       echo "ERROR: $service_name - $wait_cmd returned error"
214       exit 1
215   }
216 }
217
218 ################################################
219 # kill off any TCP connections with the given IP
220 ################################################
221 kill_tcp_connections() {
222     _IP="$1"    
223     _failed=0
224
225     _killcount=0
226     connfile="$CTDB_BASE/state/connections.$_IP"
227     netstat -tn |egrep "^tcp.*[[:space:]]+$_IP:.*ESTABLISHED" | awk '{print $4" "$5}' > $connfile
228     netstat -tn |egrep "^tcp.*[[:space:]]+::ffff:$_IP:.*ESTABLISHED" | awk '{print $4" "$5}' >> $connfile
229
230     while read dest src; do
231         srcip=`echo $src | sed -e "s/:[^:]*$//"`
232         srcport=`echo $src | sed -e "s/^.*://"`
233         destip=`echo $dest | sed -e "s/:[^:]*$//"`
234         destport=`echo $dest | sed -e "s/^.*://"`
235         echo "Killing TCP connection $srcip:$srcport $destip:$destport"
236         ctdb killtcp $srcip:$srcport $destip:$destport >/dev/null 2>&1 || _failed=1
237         case $destport in
238           # we only do one-way killtcp for NFS and CIFS
239           139|445|2049) : ;;
240           # for all others we do 2-way
241           *) 
242                 ctdb killtcp $destip:$destport $srcip:$srcport >/dev/null 2>&1 || _failed=1
243                 ;;
244         esac
245         _killcount=`expr $_killcount + 1`
246      done < $connfile
247     /bin/rm -f $connfile
248
249     [ $_failed = 0 ] || {
250         echo "Failed to send killtcp control"
251         return;
252     }
253     [ $_killcount -gt 0 ] || {
254         return;
255     }
256     _count=0
257     while netstat -tn |egrep "^tcp.*[[:space:]]+$_IP:.*ESTABLISHED" > /dev/null; do
258         sleep 1
259         _count=`expr $_count + 1`
260         [ $_count -gt 3 ] && {
261             echo "Timed out killing tcp connections for IP $_IP"
262             return;
263         }
264     done
265     echo "killed $_killcount TCP connections to released IP $_IP"
266 }
267
268 ########################################################
269 # start/stop the nfs service on different platforms
270 ########################################################
271 startstop_nfs() {
272         PLATFORM="unknown"
273         [ -x /etc/init.d/nfsserver ] && {
274                 PLATFORM="sles"
275         }
276         [ -x /etc/init.d/nfslock ] && {
277                 PLATFORM="rhel"
278         }
279
280         case $PLATFORM in
281         sles)
282                 case $1 in
283                 start)
284                         service nfsserver start
285                         ;;
286                 stop)
287                         service nfsserver stop > /dev/null 2>&1
288                         ;;
289                 esac
290                 ;;
291         rhel)
292                 case $1 in
293                 start)
294                         service nfslock start
295                         service nfs start
296                         ;;
297                 stop)
298                         service nfs stop > /dev/null 2>&1
299                         service nfslock stop > /dev/null 2>&1
300                         ;;
301                 esac
302                 ;;
303         *)
304                 echo "Unknown platform. NFS is not supported with ctdb"
305                 exit 1
306                 ;;
307         esac
308 }
309
310 ########################################################
311 # start/stop the nfs lockmanager service on different platforms
312 ########################################################
313 startstop_nfslock() {
314         PLATFORM="unknown"
315         [ -x /etc/init.d/nfsserver ] && {
316                 PLATFORM="sles"
317         }
318         [ -x /etc/init.d/nfslock ] && {
319                 PLATFORM="rhel"
320         }
321
322         case $PLATFORM in
323         sles)
324                 # for sles there is no service for lockmanager
325                 # so we instead just shutdown/restart nfs
326                 case $1 in
327                 start)
328                         service nfsserver start
329                         ;;
330                 stop)
331                         service nfsserver stop > /dev/null 2>&1
332                         ;;
333                 esac
334                 ;;
335         rhel)
336                 case $1 in
337                 start)
338                         service nfslock start
339                         ;;
340                 stop)
341                         service nfslock stop > /dev/null 2>&1
342                         ;;
343                 esac
344                 ;;
345         *)
346                 echo "Unknown platform. NFS locking is not supported with ctdb"
347                 exit 1
348                 ;;
349         esac
350 }
351
352 ########################################################
353 # load a site local config file
354 ########################################################
355
356 [ -x $CTDB_BASE/rc.local ] && {
357         . $CTDB_BASE/rc.local
358 }
359