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