Whamcloud - gitweb
LU-11268 mdc: use smaller buffers for getxattr
[fs/lustre-release.git] / contrib / scripts / pacemaker / healthLNET
1 #!/bin/sh
2 #
3 #
4 #       LNet OCF RA
5 #
6
7
8 # License:      GNU General Public License (GPL)v2
9 # Description:  Manages ZFS and Lustre on a shared storage
10 # Written by:   Gabriele Paciucci
11 # Release Date: 01 November 2016
12 # Release Version: 0.99.4
13
14 # Copyright (c) 2009 Andrew Beekhof
15 # Copyright (c) 2016, Intel Corporation
16
17
18 #
19 # This program is free software; you can redistribute it and/or modify
20 # it under the terms of version 2 of the GNU General Public License as
21 # published by the Free Software Foundation.
22 #
23 # This program is distributed in the hope that it would be useful, but
24 # WITHOUT ANY WARRANTY; without even the implied warranty of
25 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
26 #
27 # Further, this software is distributed without any warranty that it is
28 # free of the rightful claim of any third person regarding infringement
29 # or the like.  Any license provided herein, whether implied or
30 # otherwise, applies only to this software file.  Patent licenses, if
31 # any, provided herein do not apply to combinations of this program with
32 # other software, or any other product whatsoever.
33 #
34 # You should have received a copy of the GNU General Public License
35 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
36 #
37
38 #######################################################################
39 # Initialization:
40
41 : ${OCF_FUNCTIONS=${OCF_ROOT}/resource.d/heartbeat/.ocf-shellfuncs}
42 . ${OCF_FUNCTIONS}
43 : ${__OCF_ACTION=$1}
44
45 #######################################################################
46
47 meta_data() {
48         cat <<END
49 <?xml version="1.0"?>
50 <!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
51 <resource-agent name="healthLNET">
52 <version>0.99.4</version>
53
54 <longdesc lang="en">
55 Every time the monitor action is run, this resource agent records (in the CIB)
56 the current number of lctl ping nodes the host can connect to.
57 </longdesc>
58 <shortdesc lang="en">LNet connectivity</shortdesc>
59
60 <parameters>
61
62 <parameter name="pidfile" unique="0">
63 <longdesc lang="en">PID file</longdesc>
64 <shortdesc lang="en">PID file</shortdesc>
65 <content type="string" default="$HA_VARRUN/ping-${OCF_RESOURCE_INSTANCE}" />
66 </parameter>
67
68 <parameter name="dampen" unique="0">
69 <longdesc lang="en">
70 The time to wait (dampening) further changes occur
71 </longdesc>
72 <shortdesc lang="en">Dampening interval</shortdesc>
73 <content type="integer" default="5s"/>
74 </parameter>
75
76 <parameter name="name" unique="0">
77 <longdesc lang="en">
78 The name of the attributes to set.  This is the name to be used in the constraints.
79 </longdesc>
80 <shortdesc lang="en">Attribute name</shortdesc>
81 <content type="string" default="pingd"/>
82 </parameter>
83
84 <parameter name="multiplier" unique="0">
85 <longdesc lang="en">
86 The number by which to multiply the number of connected ping nodes by
87 </longdesc>
88 <shortdesc lang="en">Value multiplier</shortdesc>
89 <content type="integer" default=""/>
90 </parameter>
91
92 <parameter name="host_list" unique="0" required="1">
93 <longdesc lang="en">
94 The list of ping nodes to count.
95 </longdesc>
96 <shortdesc lang="en">Host list</shortdesc>
97 <content type="string" default=""/>
98 </parameter>
99
100 <parameter name="attempts" unique="0">
101 <longdesc lang="en">
102 Number of ping attempts, per host, before declaring it dead
103 </longdesc>
104 <shortdesc lang="en">no. of ping attempts</shortdesc>
105 <content type="integer" default="2"/>
106 </parameter>
107
108 <parameter name="timeout" unique="0">
109 <longdesc lang="en">
110 How long, in seconds, to wait before declaring a ping lost
111 </longdesc>
112 <shortdesc lang="en">ping timeout in seconds</shortdesc>
113 <content type="integer" default="2"/>
114 </parameter>
115
116 <parameter name="lctl" unique="0">
117 <longdesc lang="en">
118 Option to enable lctl ping. The default is true
119 </longdesc>
120 <shortdesc lang="en">Extra Options</shortdesc>
121 <content type="string" default="true"/>
122 </parameter>
123
124 <parameter name="device" unique="0">
125 <longdesc lang="en">
126 Device used for the LNET network. We assume the same device accross the cluster
127 </longdesc>
128 <shortdesc lang="en">LNET device</shortdesc>
129 <content type="string" default=""/>
130 </parameter>
131
132
133 <parameter name="options" unique="0">
134 <longdesc lang="en">
135 A catch all for any other options that need to be passed to ping.
136 </longdesc>
137 <shortdesc lang="en">Extra Options</shortdesc>
138 <content type="string" default=""/>
139 </parameter>
140
141 <parameter name="failure_score" unique="0">
142 <longdesc lang="en">
143 Resource is failed if the score is less than failure_score.
144 Default never fails.
145 </longdesc>
146 <shortdesc lang="en">failure_score</shortdesc>
147 <content type="integer" default=""/>
148 </parameter>
149
150 <parameter name="debug" unique="0">
151 <longdesc lang="en">
152 Enables to use default attrd_updater verbose logging on every call.
153 </longdesc>
154 <shortdesc lang="en">Verbose logging</shortdesc>
155 <content type="string" default="false"/>
156 </parameter>
157
158 </parameters>
159
160 <actions>
161 <action name="start"   timeout="300s" />
162 <action name="stop"    timeout="300s" />
163 <action name="reload"  timeout="300s" />
164 <action name="monitor" depth="0"  timeout="300s" interval="20s"/>
165 <action name="meta-data"  timeout="5" />
166 <action name="validate-all"  timeout="30" />
167 </actions>
168 </resource-agent>
169 END
170 }
171
172 #######################################################################
173
174 ping_conditional_log() {
175         level=$1; shift
176         if [ ${OCF_RESKEY_debug} = "true" ]; then
177                 ocf_log $level "$*"
178         fi
179 }
180
181 ping_usage() {
182         cat <<END
183         usage: $0 {start|stop|monitor|migrate_to|migrate_from|validate-all|meta-data}
184
185         Expects to have a fully populated OCF RA-compliant environment set.
186 END
187 }
188
189 ping_start() {
190         modprobe lustre
191         rc=$?
192         if [ $rc -ne 0 ]; then
193                 return $OCF_ERR_INSTALLED
194         fi
195         ping_monitor
196         if [ $? =  $OCF_SUCCESS ]; then
197                 return $OCF_SUCCESS
198         fi
199         touch ${OCF_RESKEY_pidfile}
200         ping_update
201 }
202
203 ping_stop() {
204         rm -f ${OCF_RESKEY_pidfile}
205         attrd_updater -D -n $OCF_RESKEY_name -d $OCF_RESKEY_dampen $attrd_options
206         return $OCF_SUCCESS
207 }
208
209 ping_monitor() {
210     if [ -f ${OCF_RESKEY_pidfile} ]; then
211         ping_update
212         if [ $? -eq 0 ]; then
213             return $OCF_SUCCESS
214         fi
215         return $OCF_ERR_GENERIC
216     fi
217     return $OCF_NOT_RUNNING
218 }
219
220 ping_validate() {
221         # Is the state directory writable?
222         state_dir=`dirname "$OCF_RESKEY_pidfile"`
223         touch "$state_dir/$$"
224         if [ $? != 0 ]; then
225                 ocf_log err "Invalid location for 'state': $state_dir is not writable"
226                 return $OCF_ERR_ARGS
227         fi
228         rm "$state_dir/$$"
229
230 # Pidfile better be an absolute path
231     case $OCF_RESKEY_pidfile in
232         /*) ;;
233         *) ocf_log warn "You should use an absolute path for pidfile not: $OCF_RESKEY_pidfile" ;;
234     esac
235
236 # Check the host list
237         if [ "x" = "x$OCF_RESKEY_host_list" ]; then
238                 ocf_log err "Empty host_list.  Please specify some nodes to ping"
239                 exit $OCF_ERR_CONFIGURED
240         fi
241
242         check_binary ping
243
244         return $OCF_SUCCESS
245 }
246
247 lctl_check() {
248         active=0
249         for host in $OCF_RESKEY_host_list; do
250             lctl_exe="lctl ping"
251
252             lctl_out=`$lctl_exe $host $OCF_RESKEY_timeout 2>&1`; rc=$?
253             # debug
254             # ocf_log info "$lctl_exe $host $OCF_RESKEY_timeout"
255
256             case $rc in
257                 0) active=`expr $active + 1`;;
258                 1) ping_conditional_log warn "$host is inactive: $lctl_out";;
259                 *) ocf_log err "Unexpected result for '$lctl_exe $host $OCF_RESKEY_timeout' $rc: $p_out";;
260         esac
261         done
262         return $active
263
264
265 }
266
267
268
269 ping_check() {
270         active=0
271         for host in $OCF_RESKEY_host_list; do
272                 p_exe=ping
273
274                 case `uname` in
275                     Linux) p_args="-n -q -W $OCF_RESKEY_timeout -c $OCF_RESKEY_attempts";;
276                     Darwin) p_args="-n -q -t $OCF_RESKEY_timeout -c $OCF_RESKEY_attempts -o";;
277                     *) ocf_log err "Unknown host type: `uname`"; exit $OCF_ERR_INSTALLED;;
278                 esac
279
280                 case $host in
281                     *:*) p_exe=ping6
282                 esac
283
284                 p_out=`$p_exe $p_args $OCF_RESKEY_options $host 2>&1`; rc=$?
285
286                 case $rc in
287                     0) active=`expr $active + 1`;;
288                     1) ping_conditional_log warn "$host is inactive: $p_out";;
289                     *) ocf_log err "Unexpected result for '$p_exe $p_args $OCF_RESKEY_options $host' $rc: $p_out";;
290                 esac
291         done
292         return $active
293 }
294
295 ping_update() {
296         # first I'm testing if I have the physical link up.
297         # If not I give up without any additional tests.
298         # but first we need to find which is the device we are using on the localhost.
299
300         CARRIER=/sys/class/net/$OCF_RESKEY_device/carrier
301         OPERSTATE=/sys/class/net/$OCF_RESKEY_device/operstate
302
303         CAR_STAT=$(cat $CARRIER)
304         OPER_STAT=$(cat $OPERSTATE)
305
306         # debug
307         # ocf_log info "$CAR_STAT - $OPER_STAT"
308
309
310         if [ "$CAR_STAT" == "1" ] && [ "$OPER_STAT" == "up" ]; then
311                 if [ ${OCF_RESKEY_lctl} = "true" ]; then
312                         lctl_check
313                         active=$?
314                 else
315                         ping_check
316                         active=$?
317                 fi
318         else
319                 active=0
320         fi
321
322         # debug
323         # ocf_log info "$active"
324
325         score=`expr $active \* $OCF_RESKEY_multiplier`
326         attrd_updater -n $OCF_RESKEY_name -v $score -d $OCF_RESKEY_dampen $attrd_options
327         rc=$?
328         case $rc in
329                 0) ping_conditional_log debug "Updated $OCF_RESKEY_name = $score" ;;
330                 *) ocf_log warn "Could not update $OCF_RESKEY_name = $score: rc=$rc";;
331         esac
332         if [ $rc -ne 0 ]; then
333             return $rc
334         fi
335         if [ $score -eq 0 ]; then
336                  ocf_log err "LNet connection failed please check"
337         fi
338         if [ -n "$OCF_RESKEY_failure_score" -a "$score" -lt "$OCF_RESKEY_failure_score" ]; then
339             ocf_log warn "$OCF_RESKEY_name is less than failure_score($OCF_RESKEY_failure_score)"
340             return 1
341         fi
342         return 0
343 }
344
345 : ${OCF_RESKEY_name:="pingd"}
346 : ${OCF_RESKEY_dampen:="5s"}
347 : ${OCF_RESKEY_attempts:="3"}
348 : ${OCF_RESKEY_multiplier:="1"}
349 : ${OCF_RESKEY_debug:="false"}
350 : ${OCF_RESKEY_lctl:="true"}
351 #: ${OCF_RESKEY_device:="eth1"}
352 : ${OCF_RESKEY_failure_score:="0"}
353
354 : ${OCF_RESKEY_CRM_meta_timeout:="20000"}
355 : ${OCF_RESKEY_CRM_meta_globally_unique:="true"}
356
357 integer=`echo ${OCF_RESKEY_timeout} | egrep -o '[0-9]*'`
358 case ${OCF_RESKEY_timeout} in
359     *[0-9]ms|*[0-9]msec) OCF_RESKEY_timeout=`expr $integer / 1000`;;
360     *[0-9]m|*[0-9]min) OCF_RESKEY_timeout=`expr $integer \* 60`;;
361     *[0-9]h|*[0-9]hr)  OCF_RESKEY_timeout=`expr $integer \* 60 \* 60`;;
362     *) OCF_RESKEY_timeout=$integer;;
363 esac
364
365 if [ -z ${OCF_RESKEY_timeout} ]; then
366         if [ x"$OCF_RESKEY_host_list" != x ]; then
367                 host_count=`echo $OCF_RESKEY_host_list | awk '{print NF}'`
368                 OCF_RESKEY_timeout=`expr $OCF_RESKEY_CRM_meta_timeout / $host_count / $OCF_RESKEY_attempts`
369                 OCF_RESKEY_timeout=`expr $OCF_RESKEY_timeout / 1100` # Convert to seconds and finish 10% early
370         else
371                 OCF_RESKEY_timeout=5
372         fi
373 fi
374
375 if [ ${OCF_RESKEY_timeout} -lt 1 ]; then
376         OCF_RESKEY_timeout=5
377         elif [ ${OCF_RESKEY_timeout} -gt 1000 ]; then
378                 # ping actually complains if this value is too high, 5 minutes is plenty
379                 OCF_RESKEY_timeout=300
380 fi
381
382 if [ ${OCF_RESKEY_CRM_meta_globally_unique} = "false" ]; then
383         : ${OCF_RESKEY_pidfile:="$HA_VARRUN/ping-${OCF_RESKEY_name}"}
384 else
385         : ${OCF_RESKEY_pidfile:="$HA_VARRUN/ping-${OCF_RESOURCE_INSTANCE}"}
386 fi
387
388 attrd_options='-q'
389 if ocf_is_true ${OCF_RESKEY_debug} ; then
390         attrd_options=''
391 fi
392
393 # Check the debug option
394 case "${OCF_RESKEY_debug}" in
395         true|True|TRUE|1)    OCF_RESKEY_debug=true;;
396         false|False|FALSE|0) OCF_RESKEY_debug=false;;
397         *)
398         ocf_log warn "Value for 'debug' is incorrect. Please specify 'true' or 'false' not: ${OCF_RESKEY_debug}"
399         OCF_RESKEY_debug=false
400         ;;
401 esac
402
403 case $__OCF_ACTION in
404 meta-data)      meta_data
405                 exit $OCF_SUCCESS
406                 ;;
407 start)          ping_start;;
408 stop)           ping_stop;;
409 monitor)        ping_monitor;;
410 reload)         ping_start;;
411 validate-all)   ping_validate;;
412 usage|help)     ping_usage
413                 exit $OCF_SUCCESS
414                 ;;
415 *)              ping_usage
416                 exit $OCF_ERR_UNIMPLEMENTED
417                 ;;
418 esac