]> git.pld-linux.org Git - packages/ocfs2-tools.git/blob - o2cb.init
- release 2
[packages/ocfs2-tools.git] / o2cb.init
1 #!/bin/bash
2 #
3 # init fragment for O2CB.
4 #
5 # chkconfig:    2345 24 20
6 # description:  Load O2CB cluster services at system boot.
7 #
8
9 # Source function library
10 . /etc/rc.d/init.d/functions
11
12 # Try get config
13 [ -f /etc/sysconfig/o2cb ] && . /etc/sysconfig/o2cb
14
15 CLUSTERCONF=/etc/ocfs2/cluster.conf
16
17
18 # This is a tricky bit of eval work.  There are many steps involved in
19 # O2CB startup/shutdown, so we collect them here.  Each line is a line
20 # of shell code that needs to be run.  The code is run via eval as
21 # follows:
22 #
23 # start/load:
24 #    Eval of the exact lines, in order.  So, the first call is
25 #    "eval load_module configfs".
26 #
27 # status:
28 #    Eval of the lines with "check_" prepended, in order.  So the first
29 #    call is "eval check_load_module configfs".
30 #
31 # stop/unload:
32 #    Eval of the lines with "un" prepened, in reverse order.  So the
33 #    *last* call is "eval unload_module configfs".
34
35 # To provide an action, create a set of shell functions or commands
36 # "foo", "check_foo", and "unfoo".  Then add "foo arguments" to the
37 # appropriate place.  Be careful, eval requires quoting to be right.
38 #
39 LOAD_ACTIONS=("load_module configfs"
40                 "mount_fs configfs /sys/kernel/config"
41                 "load_module ocfs2_nodemanager"
42                 "load_module ocfs2_dlm"
43                 "load_module ocfs2_dlmfs"
44                 "mount_fs ocfs2_dlmfs /dlm")
45
46
47 #
48 # if_fail()
49 #
50 # Evaluates return codes.  If 0, prints "OK", if 1, prints "Failed"
51 # and exits.  If 2, status is "already done" and nothing is printed.
52 # The rest of the functions in here all honor this convention.
53 #
54 if_fail()
55 {
56     RC="$1"
57     REASON="$2"
58     if [ "$RC" = "0" ]
59     then
60         echo "OK"
61         return
62     elif [ "$RC" = "2" ]
63     then
64         return
65     fi
66     echo "Failed"
67     if [ -n "${REASON}" ]
68     then
69         echo "${REASON}" >&2
70     fi
71     exit 1
72 }
73
74 #
75 # load_module()
76 # Load a module
77 #
78 load_module()
79 {
80         _modprobe single $1
81 }
82
83 #
84 # check_heartbeat()
85 #
86 # 0 is hb not active, 1 is error, 2 is hb active
87 #
88 check_heartbeat()
89 {
90     if [ "$#" -lt "1" -o -z "$1" ]; then
91         echo "check_heartbeat(): Requires an argument" >&2
92         return 1
93     fi
94     CLUSTER="$1"
95
96     RC=0
97     if [ -d "/sys/kernel/config/cluster/${CLUSTER}/heartbeat/" ]
98     then
99         ls -1 "/sys/kernel/config/cluster/${CLUSTER}/heartbeat/" | while read HBUUID
100         do
101             if [ -d "/sys/kernel/config/cluster/${CLUSTER}/heartbeat/${HBUUID}" ]
102             then
103                 return 2;
104             fi
105         done
106         if [ $? = 2 ]
107         then
108             RC=2
109         fi
110     fi
111
112     return $RC
113 }
114
115 #
116 # clean_heartbeat()
117 # Removes the inactive heartbeat regions
118
119 clean_heartbeat() {
120     if [ "$#" -lt "1" -o -z "$1" ]; then
121         echo "clean_heartbeat(): Requires an argument" >&2
122         return 1
123     fi
124     CLUSTER="$1"
125
126     echo -n "Cleaning heartbeat on ${CLUSTER}: "
127
128     if [ ! -d "/sys/kernel/config/cluster/${CLUSTER}/heartbeat/" ]
129     then
130         echo "OK"
131         return
132     fi
133
134     ls -1 "/sys/kernel/config/cluster/${CLUSTER}/heartbeat/" | while read HBUUID
135     do
136         if [ ! -d "/sys/kernel/config/cluster/${CLUSTER}/heartbeat/${HBUUID}" ]
137         then
138             continue
139         fi
140
141         OUTPUT="`ocfs2_hb_ctl -I -u ${HBUUID} 2>&1`"
142         if [ $? != 0 ]
143         then
144             echo "Failed"
145             echo "${OUTPUT}" >&2
146             exit 1
147         fi
148
149         REF="`echo ${OUTPUT} | awk '/refs/ {print $2; exit;}' 2>&1`"
150         if [ $REF != 0 ]
151         then
152            echo "Failed"
153            echo "At least one heartbeat region still active" >&2
154            exit 1
155         else
156            OUTPUT="`ocfs2_hb_ctl -K -u ${HBUUID} 2>&1`"
157         fi
158     done
159     if [ $? = 1 ]
160     then
161         exit 1
162     fi
163     echo "OK"
164 }
165
166 #
167 # unload_module()
168 # Unload a module
169 #
170 # 0 is success, 1 is error, 2 is not loaded
171
172 unload_module() {
173     if [ "$#" -lt "1" -o -z "$1" ]; then
174         echo "unload_module(): Requires an argument" >&2
175         return 1
176     fi
177     MODNAME="$1"
178
179     MODOUT="`awk '$1 ~ /^'$MODNAME'$/{print $1,$3;exit}' < /proc/modules 2>/dev/null`"
180     if [ -z "$MODOUT" ]
181     then
182         return 2
183     fi
184     case "$MODOUT" in
185     $MODNAME\ 0)
186         ;;
187     $MODNAME\ *)
188         return 2
189         ;;
190     *)
191         echo -n "Invalid module parsing! "
192         return 1
193         ;;
194     esac
195
196     echo "Unloading module \"$MODNAME\": "
197     modprobe -rs "$MODNAME"
198     if [ "$?" != 0 ]; then
199         echo "Unable to unload module \"$MODNAME\"" >&2
200         return 1
201     fi
202
203     return 0
204 }
205
206 #
207 # check_load_module()
208 #
209 # 0 is not loaded, 1 is error, 2 is already loaded
210 #
211 check_load_module() {
212     if [ "$#" -lt "1" -o -z "$1" ]
213     then
214         echo "check_load_module(): Requires an argument" >&2
215         return 1
216     fi
217     MODNAME="$1"
218
219     echo -n "Module \"$MODNAME\": "
220     MODOUT="`awk '$1 ~ /^'$MODNAME'$/{print $1,$3;exit}' < /proc/modules 2>/dev/null`"
221     if [ -z "$MODOUT" ]
222     then
223         echo "Not loaded"
224         return 0
225     fi
226     echo "Loaded"
227     return 2
228 }
229
230
231 #
232 # mount_fs()
233 # Mount a filesystem.
234 #
235 # 0 is success, 1 is error, 2 is already mounted
236 #
237 mount_fs() {
238     TYPE=$1
239     FULL_MOUNT="$2"
240     FULL_MOUNTSEARCH="`echo "$FULL_MOUNT" | sed -e 's/\//\\\\\//g'`"
241     MOUNTOUT="`awk '$2 ~ /^'$FULL_MOUNTSEARCH'$/{print $2; exit}' < /proc/mounts 2>/dev/null`"
242
243     if [ -n "$MOUNTOUT" ]
244     then
245         return 2
246     fi
247
248         run_cmd "Mounting ${TYPE} filesystems" mount -t ${TYPE} ${TYPE} $FULL_MOUNT
249     return 0
250 }
251
252 #
253 # check_mount_fs()
254 #
255 # 0 is not mounted, 1 is error, 2 is already mounted
256 #
257 check_mount_fs() {
258     TYPE="$1"
259     FULL_MOUNT="$2"
260     FULL_MOUNTSEARCH="`echo "$FULL_MOUNT" | sed -e 's/\//\\\\\//g'`"
261     MOUNTOUT="`awk '$2 ~ /^'$FULL_MOUNTSEARCH'$/{print $2; exit}' < /proc/mounts 2>/dev/null`"
262
263     echo -n "Filesystem \"$TYPE\": "
264     if [ -n "$MOUNTOUT" ]
265     then
266         echo "Mounted"
267         return 2
268     fi
269     echo "Not mounted"
270     return 0
271 }
272
273 #
274 # unmount_fs()
275 # Unmount a filesystem
276 #
277 # 0 is success, 1 is error, 2 is not mounted
278 #
279 unmount_fs() {
280     TYPE=$1
281     FULL_MOUNT=$2
282     FULL_MOUNTSEARCH="`echo "$FULL_MOUNT" | sed -e 's/\//\\\\\//g'`"
283     MOUNTOUT="`awk '$2 ~ /^'$FULL_MOUNTSEARCH'$/{print $2; exit}' < /proc/mounts 2>/dev/null`"
284
285     if [ -z "$MOUNTOUT" ]
286     then
287         return 2
288     fi
289
290     run_cmd "Unmounting ${TYPE} filesystem" umount $FULL_MOUNT
291 }
292
293 load() {
294     for i in $(seq 0 $((${#LOAD_ACTIONS[*]} - 1)) ); do
295         eval ${LOAD_ACTIONS[i]}
296     done
297 }
298
299 load_status() {
300     for i in $(seq 0 $((${#LOAD_ACTIONS[*]} - 1)) ); do
301         eval "check_${LOAD_ACTIONS[i]}"
302     done
303     return "$?"
304 }
305
306 online() {
307     CLUSTER="${1:-${O2CB_BOOTCLUSTER}}"
308     if [ -z "$CLUSTER" ]
309     then
310         echo "Cluster not known"
311         return
312     fi
313
314     check_online $CLUSTER
315     if [ $? = 2 ]
316     then
317         echo "Cluster ${CLUSTER} already online"
318         return
319     fi
320
321     if ! [ -f ${CLUSTERCONF} ]
322     then
323         echo -n "Checking cluster configuration : "
324         if_fail 1
325     fi
326
327     echo -n "Starting cluster ${CLUSTER}: "
328     OUTPUT="`o2cb_ctl -H -n "${CLUSTER}" -t cluster -a online=yes 2>&1`"
329     if [ $? = 0 ]
330     then
331         O2CB_HEARTBEAT_THRESHOLD_FILE_OLD=/proc/fs/ocfs2_nodemanager/hb_dead_threshold
332         O2CB_HEARTBEAT_THRESHOLD_FILE=/sys/kernel/config/cluster/${CLUSTER}/heartbeat/dead_threshold
333         if [ -n "$O2CB_HEARTBEAT_THRESHOLD" ]; then
334             if [ -f "$O2CB_HEARTBEAT_THRESHOLD_FILE" ]; then
335                 echo "$O2CB_HEARTBEAT_THRESHOLD" > "$O2CB_HEARTBEAT_THRESHOLD_FILE"
336             elif [ -f "$O2CB_HEARTBEAT_THRESHOLD_FILE_OLD" ]; then 
337                 echo "$O2CB_HEARTBEAT_THRESHOLD" > "$O2CB_HEARTBEAT_THRESHOLD_FILE_OLD"
338             else
339                 echo "WARNING: Unable to set heartbeat dead threshold" >&2
340             fi
341         fi
342
343         echo "OK"
344         return
345     else
346         echo "Failed"
347         echo "$OUTPUT"
348     fi
349
350     echo -n "Stopping cluster ${CLUSTER}: "
351     OUTPUT="`o2cb_ctl -H -n "${CLUSTER}" -t cluster -a online=no 2>&1`"
352     if_fail "$?" "$OUTPUT"
353 }
354
355 #
356 # check_online()
357 #
358 # 0 is not online, 1 is error, 2 is online
359 #
360 check_online() {
361     if [ "$#" -lt "1" -o -z "$1" ]
362     then
363         echo "check_online(): Requires an argument" >&2
364         return 1
365     fi
366     CLUSTER="$1"
367
368     RC=0
369     if [ -d "/sys/kernel/config/cluster/${CLUSTER}/node/" ]
370     then
371         ls -1 "/sys/kernel/config/cluster/${CLUSTER}/node/" | while read NODE
372         do
373             LOCAL="`cat \"/sys/kernel/config/cluster/${CLUSTER}/node/${NODE}/local\"`"
374             if [ $LOCAL = 1 ]
375             then
376                 return 2
377             fi
378         done
379         if [ $? = 2 ]
380         then
381             RC=2
382         fi
383     fi
384     return $RC
385 }
386
387 offline() {
388     CLUSTER="${1:-${O2CB_BOOTCLUSTER}}"
389     if [ -z "$CLUSTER" ]
390     then
391         return
392     fi
393
394     if [ ! -e "/sys/kernel/config/cluster/${CLUSTER}" ]
395     then
396         return
397     fi
398
399     clean_heartbeat $CLUSTER
400
401     echo -n "Stopping cluster ${CLUSTER}: "
402     check_heartbeat $CLUSTER
403     if [ $? != 0 ]
404     then
405         echo "Failed"
406         echo "Unable to stop cluster as heartbeat region still active" >&2
407     fi
408
409     OUTPUT="`o2cb_ctl -H -n "${CLUSTER}" -t cluster -a online=no 2>&1`"
410     if_fail "$?" "$OUTPUT"
411
412     unload_module ocfs2
413     if_fail "$?"
414 }
415
416 start() {
417     if [ "$O2CB_ENABLED" != "true" ]
418     then
419         exit 0
420     fi
421
422     load
423     online "$1"
424 }
425
426 unload() {
427     if [ -d /sys/kernel/config/cluster/ ]; then
428         ls -1 /sys/kernel/config/cluster/ | while read CLUSTER
429         do
430             echo "Unable to unload modules as Cluster ${CLUSTER} is still online" >&2
431             exit 1
432         done
433         if [ $? = 1 ]
434         then
435             exit 1
436         fi
437     fi
438
439     for i in $(seq $((${#LOAD_ACTIONS[*]} - 1)) -1 0); do
440         eval "un${LOAD_ACTIONS[i]}"
441     done
442 }
443
444 stop() {
445     offline "$1"
446     unload
447 }
448
449 status() {
450     load_status
451     if [ $? != 2 ]
452     then
453         return 0;
454     fi
455
456     CLUSTER="${1:-${O2CB_BOOTCLUSTER}}"
457     if [ -z "$CLUSTER" ]
458     then
459         return 1;
460     fi
461
462     echo -n "Checking cluster $CLUSTER: "
463     check_online $CLUSTER
464     if [ $? = 2 ]
465     then
466        echo "Online"
467     else
468        echo "Offline"
469        return 0;
470     fi
471
472     echo -n "Checking heartbeat: "
473     check_heartbeat $CLUSTER
474     if [ $? = 2 ]
475     then
476         echo "Active"
477     else
478         echo "Not active"
479         return 0;
480     fi
481
482     return
483
484     echo -n "Checking if O2CB is loaded: "
485     RC=0
486     for MODSPEC in $MODULE_LIST
487     do
488         MODULE_NAME="`echo $MODSPEC | cut -d: -f1`"
489         FSTYPE="`echo $MODSPEC | cut -d: -f2`"
490         MOUNT_POINT="`echo $MODSPEC | cut -d: -f3`"
491
492         if grep "^${MODULE_NAME} " /proc/modules >/dev/null 2>&1
493         then
494             echo -n "${MODULE_NAME} "
495         else
496             RC=1
497             break
498         fi
499     done
500     if_fail "$RC"
501
502     echo -n "Checking O2CB mount points: "
503     for MODSPEC in $MODULE_LIST
504     do
505         MODULE_NAME="`echo $MODSPEC | cut -d: -f1`"
506         FSTYPE="`echo $MODSPEC | cut -d: -f2`"
507         MOUNT_POINT="`echo $MODSPEC | cut -d: -f3`"
508
509         if [ -z "$FSTYPE" -o -z "$MOUNT_POINT" ]
510         then
511             continue
512         fi
513
514         FULL_MOUNT="${O2CB_MANAGER}/${MOUNT_POINT}"
515         FULL_MOUNTSEARCH="`echo "$FULL_MOUNT" | sed -e 's/\//\\\\\//g'`"
516         if grep "^${FSTYPE} ${FULL_MOUNTSEARCH} ${FSTYPE}" /proc/mounts >/dev/null 2>&1
517         then
518             echo -n "${MOUNT_POINT} "
519         else
520             RC=1
521             break
522         fi
523     done
524     if_fail "$RC"
525 }
526
527
528
529 case "$1" in
530     start)
531         start "$2"
532         ;;
533
534     status)
535         status "$2"
536         ;;
537
538     stop)
539         stop "$2"
540         ;;
541
542     restart)
543         stop "$2"
544         start "$2"
545         ;;
546
547     force-reload)
548         stop "$2"
549         start "$2"
550         ;;
551
552     load)
553         load
554         ;;
555
556     online)
557         load
558         online "$2"
559         ;;
560
561     offline)
562         offline "$2"
563         ;;
564
565     unload)
566         offline "$2"
567         unload
568         ;;
569
570     *)
571         msg_usage "$0 {start|stop|restart|force-reload|load|unload|online|offline|status}"
572         exit 3
573         ;;
574 esac
575
576 exit 0
This page took 0.140208 seconds and 3 git commands to generate.