from Mathieu PARENT <math.parent@gmail.com>
[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\s*LISTEN" > /dev/null) || all_ok=0
87               elif [ -x /bin/netstat ]; then
88                   (netstat -a -n | egrep "0.0.0.0:$p\s*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 # usage: ctdb_check_directories SERVICE_NAME <directories...>
149 ######################################################
150 ctdb_check_directories() {
151   service_name="$1"
152   shift
153   wait_dirs="$*"
154   [ -z "$wait_dirs" ] && return;
155   for d in $wait_dirs; do
156       [ -d $d ] || {
157           echo "ERROR: $service_name directory $d not available"
158           exit 1
159       }
160   done
161 }
162
163 ######################################################
164 # check a set of tcp ports
165 # usage: ctdb_check_tcp_ports SERVICE_NAME <ports...>
166 ######################################################
167 ctdb_check_tcp_ports() {
168   service_name="$1"
169   shift
170   wait_ports="$*"
171   [ -z "$wait_ports" ] && return;
172   for p in $wait_ports; do
173       all_ok=1
174       if [ -x /usr/bin/netcat ]; then
175           /usr/bin/netcat -z 127.0.0.1 $p > /dev/null || all_ok=0
176       elif [ -x /usr/bin/nc ]; then
177           /usr/bin/nc -z 127.0.0.1 $p > /dev/null || all_ok=0
178       elif [ -x /usr/bin/netstat ]; then
179           (netstat -a -n | egrep "0.0.0.0:$p .*LISTEN" > /dev/null ) || all_ok=0
180       elif [ -x /bin/netstat ]; then
181           (netstat -a -n | egrep "0.0.0.0:$p .*LISTEN" > /dev/null ) || all_ok=0
182       fi
183       [ $all_ok -eq 1 ] || {
184           echo "ERROR: $service_name tcp port $p is not responding"
185           exit 1
186       }
187   done
188 }
189
190 ######################################################
191 # check a command returns zero status
192 # usage: ctdb_check_command SERVICE_NAME <command>
193 ######################################################
194 ctdb_check_command() {
195   service_name="$1"
196   wait_cmd="$2"
197   [ -z "$wait_cmd" ] && return;
198   $wait_cmd > /dev/null 2>&1 || {
199       echo "ERROR: $service_name - $wait_cmd returned error"
200       exit 1
201   }
202 }
203
204 ################################################
205 # kill off any TCP connections with the given IP
206 ################################################
207 kill_tcp_connections() {
208     _IP="$1"    
209     _failed=0
210
211     _killcount=0
212     connfile="$CTDB_BASE/state/connections.$_IP"
213     netstat -tn |egrep "^tcp.*\s+$_IP:.*ESTABLISHED" | awk '{print $4" "$5}' > $connfile
214     while read dest src; do
215         srcip=`echo $src | cut -d: -f1`
216         srcport=`echo $src | cut -d: -f2`
217         destip=`echo $dest | cut -d: -f1`
218         destport=`echo $dest | cut -d: -f2`
219         ctdb killtcp $srcip:$srcport $destip:$destport >/dev/null 2>&1 || _failed=1
220         echo "Killing TCP connection $srcip:$srcport $destip:$destport"
221         _killcount=`expr $_killcount + 1`
222     done < $connfile
223     /bin/rm -f $connfile
224     [ $_failed = 0 ] || {
225         echo "Failed to send killtcp control"
226         return;
227     }
228     [ $_killcount -gt 0 ] || {
229         return;
230     }
231     _count=0
232     while netstat -tn |egrep "^tcp.*\s+$_IP:.*ESTABLISHED" > /dev/null; do
233         sleep 1
234         _count=`expr $_count + 1`
235         [ $_count -gt 3 ] && {
236             echo "Timed out killing tcp connections for IP $_IP"
237             return;
238         }
239     done
240     echo "killed $_killcount TCP connections to released IP $_IP"
241 }
242
243 ########################################################
244 # start/stop the nfs service on different platforms
245 ########################################################
246 startstop_nfs() {
247         PLATFORM="unknown"
248         [ -x /etc/init.d/nfsserver ] && {
249                 PLATFORM="sles"
250         }
251         [ -x /etc/init.d/nfslock ] && {
252                 PLATFORM="rhel"
253         }
254
255         case $PLATFORM in
256         sles)
257                 case $1 in
258                 start)
259                         service nfsserver start
260                         ;;
261                 stop)
262                         service nfsserver stop > /dev/null 2>&1
263                         ;;
264                 esac
265                 ;;
266         rhel)
267                 case $1 in
268                 start)
269                         service nfslock start
270                         service nfs start
271                         ;;
272                 stop)
273                         service nfs stop > /dev/null 2>&1
274                         service nfslock stop > /dev/null 2>&1
275                         ;;
276                 esac
277                 ;;
278         *)
279                 echo "Unknown platform. NFS is not supported with ctdb"
280                 exit 1
281                 ;;
282         esac
283 }
284
285 ########################################################
286 # start/stop the nfs lockmanager service on different platforms
287 ########################################################
288 startstop_nfslock() {
289         PLATFORM="unknown"
290         [ -x /etc/init.d/nfsserver ] && {
291                 PLATFORM="sles"
292         }
293         [ -x /etc/init.d/nfslock ] && {
294                 PLATFORM="rhel"
295         }
296
297         case $PLATFORM in
298         sles)
299                 # for sles there is no service for lockmanager
300                 # so we instead just shutdown/restart nfs
301                 case $1 in
302                 start)
303                         service nfsserver start
304                         ;;
305                 stop)
306                         service nfsserver stop > /dev/null 2>&1
307                         ;;
308                 esac
309                 ;;
310         rhel)
311                 case $1 in
312                 start)
313                         service nfslock start
314                         ;;
315                 stop)
316                         service nfslock stop > /dev/null 2>&1
317                         ;;
318                 esac
319                 ;;
320         *)
321                 echo "Unknown platform. NFS locking is not supported with ctdb"
322                 exit 1
323                 ;;
324         esac
325 }