]> git.pld-linux.org Git - packages/ocfs2-tools.git/blob - o2cb.init
- added, needs PLDification
[packages/ocfs2-tools.git] / o2cb.init
1 #!/bin/sh
2 # init fragment for O2CB.
3 #
4 # chkconfig: 2345 24 20
5 # description: Load O2CB cluster services at system boot.
6 #
7 ### BEGIN INIT INFO
8 # Provides: o2cb
9 # Required-Start: $network
10 # Should-Start:
11 # Required-Stop:
12 # Default-Start: 2 3 5
13 # Default-Stop:
14 # Description: Load O2CB cluster services at system boot.
15 ### END INIT INFO
16
17 # Force LC_ALL=C
18 export LC_ALL=C
19
20 CLUSTERCONF=/etc/ocfs2/cluster.conf
21
22 if [ -f /etc/sysconfig/o2cb ]
23 then
24     # Red Hat and Novell
25     CONFIGURATION=/etc/sysconfig/o2cb
26 elif [ -f /etc/default/o2cb ]
27 then
28     # Debian
29     CONFIGURATION=/etc/default/o2cb
30 elif [ -d /etc/sysconfig ]
31 then
32     CONFIGURATION=/etc/sysconfig/o2cb
33 else
34     CONFIGURATION=/etc/default/o2cb
35 fi
36
37 # Source configuration, 
38 [ -f "${CONFIGURATION}" ] && . "${CONFIGURATION}"
39
40 configfs_path()
41 {
42     # Note that this is only valid *after* configfs is loaded
43     if [ -d /sys/kernel/config ]
44     then
45         echo /sys/kernel/config
46     else
47         echo /config
48     fi
49 }
50
51
52 # This is a tricky bit of eval work.  There are many steps involved in
53 # O2CB startup/shutdown, so we collect them here.  Each line is a line
54 # of shell code that needs to be run.  The code is run via eval as
55 # follows:
56 #
57 # start/load:
58 #    Eval of the exact lines, in order.  So, the first call is
59 #    "eval load_module configfs".
60 #
61 # status:
62 #    Eval of the lines with "check_" prepended, in order.  So the first
63 #    call is "eval check_load_module configfs".
64 #
65 # stop/unload:
66 #    Eval of the lines with "un" prepened, in reverse order.  So the
67 #    *last* call is "eval unload_module configfs".
68
69 # To provide an action, create a set of shell functions or commands
70 # "foo", "check_foo", and "unfoo".  Then add "foo arguments" to the
71 # appropriate place.  Be careful, eval requires quoting to be right.
72 #
73 LOAD_ACTIONS=("load_module configfs"
74                 "mount_fs configfs "'$(configfs_path)'
75                 "load_module ocfs2_nodemanager"
76                 "load_module ocfs2_dlm"
77                 "load_module ocfs2_dlmfs"
78                 "mount_fs ocfs2_dlmfs /dlm")
79
80
81 #
82 # if_fail()
83 #
84 # Evaluates return codes.  If 0, prints "OK", if 1, prints "Failed"
85 # and exits.  If 2, status is "already done" and nothing is printed.
86 # The rest of the functions in here all honor this convention.
87 #
88 if_fail()
89 {
90     RC="$1"
91     REASON="$2"
92     if [ "$RC" = "0" ]
93     then
94         echo "OK"
95         return
96     elif [ "$RC" = "2" ]
97     then
98         return
99     fi
100     echo "Failed"
101     if [ -n "${REASON}" ]
102     then
103         echo "${REASON}" >&2
104     fi
105     exit 1
106 }
107
108
109 #
110 # write_sysconfig()
111 #
112 # Writes the system configuration out
113 #
114 write_sysconfig()
115 {
116     echo -n "Writing O2CB configuration: "
117     cat >"${CONFIGURATION}" <<EOF
118 #
119 # This is a configuration file for automatic startup of the O2CB
120 # driver.  It is generated by running /etc/init.d/o2cb configure.
121 # Please use that method to modify this file
122 #
123
124 # O2CB_ENABELED: 'true' means to load the driver on boot.
125 O2CB_ENABLED=${O2CB_ENABLED:-false}
126
127 # O2CB_BOOTCLUSTER: If not empty, the name of a cluster to start.
128 O2CB_BOOTCLUSTER=${O2CB_BOOTCLUSTER}
129
130 # O2CB_HEARTBEAT_THRESHOLD: Iterations before a node is considered dead.
131 O2CB_HEARTBEAT_THRESHOLD=${O2CB_HEARTBEAT_THRESHOLD}
132
133 EOF
134
135     if [ $? != 0 ]
136     then
137         return 1
138     fi
139     return 0
140 }
141
142 #
143 # configure_ask()
144 #
145 # Ask configuration questions, setting the shell vars.
146 #
147 configure_ask()
148 {
149     cat <<EOF
150 Configuring the O2CB driver.
151
152 This will configure the on-boot properties of the O2CB driver.
153 The following questions will determine whether the driver is loaded on
154 boot.  The current values will be shown in brackets ('[]').  Hitting
155 <ENTER> without typing an answer will keep that current value.  Ctrl-C
156 will abort.
157
158 EOF
159
160     while :
161     do
162         if [ "$O2CB_ENABLED" = "true" ]
163         then
164             CUR=y
165         else
166             CUR=n
167         fi
168         echo -n "Load O2CB driver on boot (y/n) [$CUR]: "
169         read LINE
170         case "$LINE" in
171         "")
172             break
173             ;;
174         y|Y)
175             O2CB_ENABLED=true
176             break
177             ;;
178         n|N)
179             O2CB_ENABLED=false
180             break
181             ;;
182         *)
183             echo "Invalid answer: $LINE" >&2
184             ;;
185         esac
186     done
187
188     while :
189     do
190         echo -n "Cluster to start on boot (Enter \"none\" to clear) [$O2CB_BOOTCLUSTER]: "
191         read LINE
192         case "$LINE" in
193         "")
194             break
195             ;;
196         none)
197             O2CB_BOOTCLUSTER=
198             break
199             ;;
200
201         *[^a-zA-Z0-9]*)
202             echo "Invalid cluster name: $LINE" >&2
203             ;;
204         *)
205             O2CB_BOOTCLUSTER="$LINE"
206             break
207             ;;
208         esac
209     done
210
211         # XXX ask about mount point base
212 }
213
214
215 #
216 # make_dir()
217 #
218 # Create $1
219 # Returns 0 on success, 1 on error, 2 if it already exists.
220 #
221 make_dir()
222 {
223     if [ "$#" -lt "1" -o -z "$1" ]
224     then
225         echo "make_dir(): Requires an argument" >&2
226         return 1
227     fi
228     DIR="$1"
229     if [ -e "$DIR" ]
230     then
231         if [ -d "$DIR" ]
232         then
233             return 2
234         fi
235         echo "make_dir(): File $DIR is not a directory" >&2
236         return 1
237     fi
238
239     echo -n "Creating directory '$DIR': "
240     mkdir -p "$DIR" 2>/dev/null
241     if [ $? != 0 ]
242     then
243         echo "Unable to create directory '$DIR'" >&2
244         return 1
245     fi
246     return 0
247 }
248
249
250 #
251 # load_module()
252 # Load a module
253 #
254 # 0 is success, 1 is error, 2 is already loaded
255
256 load_module()
257 {
258     if [ "$#" -lt "1" -o -z "$1" ]
259     then
260         echo "load_module(): Requires an argument" >&2
261         return 1
262     fi
263     MODNAME="$1"
264
265     MODOUT="`awk '$1 ~ /^'$MODNAME'$/{print $1;exit}' < /proc/modules 2>/dev/null`"
266     if [ -n "$MODOUT" ]
267     then
268         return 2
269     fi
270
271     echo -n "Loading module \"$MODNAME\": "
272     modprobe -s "$MODNAME"
273     if [ "$?" != 0 ]
274     then
275         echo "Unable to load module \"$MODNAME\"" >&2
276         return 1
277     fi
278
279     return 0
280 }
281
282 #
283 # check_heartbeat()
284 #
285 # 0 is hb not active, 1 is error, 2 is hb active
286 #
287 check_heartbeat()
288 {
289     if [ "$#" -lt "1" -o -z "$1" ]
290     then
291         echo "check_heartbeat(): Requires an argument" >&2
292         return 1
293     fi
294     CLUSTER="$1"
295
296     RC=0
297     if [ -d "$(configfs_path)/cluster/${CLUSTER}/heartbeat/" ]
298     then
299         ls -1 "$(configfs_path)/cluster/${CLUSTER}/heartbeat/" | while read HBUUID
300         do
301             if [ -d "$(configfs_path)/cluster/${CLUSTER}/heartbeat/${HBUUID}" ]
302             then
303                 return 2;
304             fi
305         done
306         if [ $? = 2 ]
307         then
308             RC=2
309         fi
310     fi
311
312     return $RC
313 }
314
315 #
316 # clean_heartbeat()
317 # Removes the inactive heartbeat regions
318
319 clean_heartbeat()
320 {
321     if [ "$#" -lt "1" -o -z "$1" ]
322     then
323         echo "clean_heartbeat(): Requires an argument" >&2
324         return 1
325     fi
326     CLUSTER="$1"
327
328     echo -n "Cleaning heartbeat on ${CLUSTER}: "
329
330     if [ ! -d "$(configfs_path)/cluster/${CLUSTER}/heartbeat/" ]
331     then
332         echo "OK"
333         return
334     fi
335
336     ls -1 "$(configfs_path)/cluster/${CLUSTER}/heartbeat/" | while read HBUUID
337     do
338         if [ ! -d "$(configfs_path)/cluster/${CLUSTER}/heartbeat/${HBUUID}" ]
339         then
340             continue
341         fi
342
343         OUTPUT="`ocfs2_hb_ctl -I -u ${HBUUID} 2>&1`"
344         if [ $? != 0 ]
345         then
346             echo "Failed"
347             echo "${OUTPUT}" >&2
348             exit 1
349         fi
350
351         REF="`echo ${OUTPUT} | awk '/refs/ {print $2; exit;}' 2>&1`"
352         if [ $REF != 0 ]
353         then
354            echo "Failed"
355            echo "At least one heartbeat region still active" >&2
356            exit 1
357         else
358            OUTPUT="`ocfs2_hb_ctl -K -u ${HBUUID} 2>&1`"
359         fi
360     done
361     if [ $? = 1 ]
362     then
363         exit 1
364     fi
365     echo "OK"
366 }
367
368 #
369 # unload_module()
370 # Unload a module
371 #
372 # 0 is success, 1 is error, 2 is not loaded
373
374 unload_module()
375 {
376     if [ "$#" -lt "1" -o -z "$1" ]
377     then
378         echo "unload_module(): Requires an argument" >&2
379         return 1
380     fi
381     MODNAME="$1"
382
383     MODOUT="`awk '$1 ~ /^'$MODNAME'$/{print $1,$3;exit}' < /proc/modules 2>/dev/null`"
384     if [ -z "$MODOUT" ]
385     then
386         return 2
387     fi
388     case "$MODOUT" in
389     $MODNAME\ 0)
390         ;;
391     $MODNAME\ *)
392         return 2
393         ;;
394     *)
395         echo -n "Invalid module parsing! "
396         return 1
397         ;;
398     esac
399
400     echo -n "Unloading module \"$MODNAME\": "
401     modprobe -rs "$MODNAME"
402     if [ "$?" != 0 ]
403     then
404         echo "Unable to unload module \"$MODNAME\"" >&2
405         return 1
406     fi
407
408     return 0
409 }
410
411 #
412 # check_load_module()
413 #
414 # 0 is not loaded, 1 is error, 2 is already loaded
415 #
416 check_load_module()
417 {
418     if [ "$#" -lt "1" -o -z "$1" ]
419     then
420         echo "check_load_module(): Requires an argument" >&2
421         return 1
422     fi
423     MODNAME="$1"
424
425     echo -n "Module \"$MODNAME\": "
426     MODOUT="`awk '$1 ~ /^'$MODNAME'$/{print $1,$3;exit}' < /proc/modules 2>/dev/null`"
427     if [ -z "$MODOUT" ]
428     then
429         echo "Not loaded"
430         return 0
431     fi
432     echo "Loaded"
433     return 2
434 }
435
436
437 #
438 # mount_fs()
439 # Mount a filesystem.
440 #
441 # 0 is success, 1 is error, 2 is already mounted
442 #
443 mount_fs()
444 {
445     TYPE="$1"
446     FULL_MOUNT="$2"
447     FULL_MOUNTSEARCH="`echo "$FULL_MOUNT" | sed -e 's/\//\\\\\//g'`"
448     MOUNTOUT="`awk '$2 ~ /^'$FULL_MOUNTSEARCH'$/{print $2; exit}' < /proc/mounts 2>/dev/null`"
449
450     if [ -n "$MOUNTOUT" ]
451     then
452         return 2
453     fi
454
455     # XXX some policy?
456     if [ ! -e "$FULL_MOUNT" ]; then
457         make_dir $FULL_MOUNT
458         if_fail "$?"
459     fi
460
461     echo -n "Mounting ${TYPE} filesystem at $FULL_MOUNT: "
462     mount -t ${TYPE} ${TYPE} $FULL_MOUNT
463     if [ $? != 0 ]
464     then
465         echo "Unable to mount ${TYPE} filesystem" >&2
466         return 1
467     fi
468
469     return 0
470 }
471
472 #
473 # check_mount_fs()
474 #
475 # 0 is not mounted, 1 is error, 2 is already mounted
476 #
477 check_mount_fs()
478 {
479     TYPE="$1"
480     FULL_MOUNT="$2"
481     FULL_MOUNTSEARCH="`echo "$FULL_MOUNT" | sed -e 's/\//\\\\\//g'`"
482     MOUNTOUT="`awk '$2 ~ /^'$FULL_MOUNTSEARCH'$/{print $2; exit}' < /proc/mounts 2>/dev/null`"
483
484     echo -n "Filesystem \"$TYPE\": "
485     if [ -n "$MOUNTOUT" ]
486     then
487         echo "Mounted"
488         return 2
489     fi
490     echo "Not mounted"
491     return 0
492 }
493
494 #
495 # unmount_fs()
496 # Unmount a filesystem
497 #
498 # 0 is success, 1 is error, 2 is not mounted
499 #
500 unmount_fs()
501 {
502     TYPE="$1"
503     FULL_MOUNT="$2"
504     FULL_MOUNTSEARCH="`echo "$FULL_MOUNT" | sed -e 's/\//\\\\\//g'`"
505     MOUNTOUT="`awk '$2 ~ /^'$FULL_MOUNTSEARCH'$/{print $2; exit}' < /proc/mounts 2>/dev/null`"
506
507     if [ -z "$MOUNTOUT" ]
508     then
509         return 2
510     fi
511
512     echo -n "Unmounting ${TYPE} filesystem: "
513     umount $FULL_MOUNT
514     if [ $? != 0 ]
515     then
516         echo "Unable to unmount ${TYPE} filesystem" >&2
517         return 1
518     fi
519
520     return 0
521 }
522
523 load()
524 {
525     for i in $(seq 0 $((${#LOAD_ACTIONS[*]} - 1)) ); do
526         eval ${LOAD_ACTIONS[i]}
527         if_fail "$?"
528     done
529 }
530
531 load_status()
532 {
533     for i in $(seq 0 $((${#LOAD_ACTIONS[*]} - 1)) ); do
534         eval "check_${LOAD_ACTIONS[i]}"
535     done
536     return "$?"
537 }
538
539 online()
540 {
541     CLUSTER="${1:-${O2CB_BOOTCLUSTER}}"
542     if [ -z "$CLUSTER" ]
543     then
544         echo "Cluster not known"
545         return
546     fi
547
548     check_online $CLUSTER
549     if [ $? = 2 ]
550     then
551         echo "Cluster ${CLUSTER} already online"
552         return
553     fi
554
555     if ! [ -f ${CLUSTERCONF} ]
556     then
557         echo -n "Checking cluster configuration : "
558         if_fail 1
559     fi
560
561     echo -n "Starting cluster ${CLUSTER}: "
562     OUTPUT="`o2cb_ctl -H -n "${CLUSTER}" -t cluster -a online=yes 2>&1`"
563     if [ $? = 0 ]
564     then
565         O2CB_HEARTBEAT_THRESHOLD_FILE_OLD=/proc/fs/ocfs2_nodemanager/hb_dead_threshold
566         O2CB_HEARTBEAT_THRESHOLD_FILE=$(configfs_path)/cluster/${CLUSTER}/heartbeat/dead_threshold
567         if [ -n "$O2CB_HEARTBEAT_THRESHOLD" ]; then
568             if [ -f "$O2CB_HEARTBEAT_THRESHOLD_FILE" ]; then
569                 echo "$O2CB_HEARTBEAT_THRESHOLD" > "$O2CB_HEARTBEAT_THRESHOLD_FILE"
570             elif [ -f "$O2CB_HEARTBEAT_THRESHOLD_FILE_OLD" ]; then 
571                 echo "$O2CB_HEARTBEAT_THRESHOLD" > "$O2CB_HEARTBEAT_THRESHOLD_FILE_OLD"
572             else
573                 echo "WARNING: Unable to set heartbeat dead threshold" >&2
574             fi
575         fi
576
577         echo "OK"
578         return
579     else
580         echo "Failed"
581         echo "$OUTPUT"
582     fi
583
584     echo -n "Stopping cluster ${CLUSTER}: "
585     OUTPUT="`o2cb_ctl -H -n "${CLUSTER}" -t cluster -a online=no 2>&1`"
586     if_fail "$?" "$OUTPUT"
587 }
588
589 #
590 # check_online()
591 #
592 # 0 is not online, 1 is error, 2 is online
593 #
594 check_online()
595 {
596     if [ "$#" -lt "1" -o -z "$1" ]
597     then
598         echo "check_online(): Requires an argument" >&2
599         return 1
600     fi
601     CLUSTER="$1"
602
603     RC=0
604     if [ -d "$(configfs_path)/cluster/${CLUSTER}/node/" ]
605     then
606         ls -1 "$(configfs_path)/cluster/${CLUSTER}/node/" | while read NODE
607         do
608             LOCAL="`cat \"$(configfs_path)/cluster/${CLUSTER}/node/${NODE}/local\"`"
609             if [ $LOCAL = 1 ]
610             then
611                 return 2
612             fi
613         done
614         if [ $? = 2 ]
615         then
616             RC=2
617         fi
618     fi
619     return $RC
620 }
621
622 offline()
623 {
624     CLUSTER="${1:-${O2CB_BOOTCLUSTER}}"
625     if [ -z "$CLUSTER" ]
626     then
627         return
628     fi
629
630     if [ ! -e "$(configfs_path)/cluster/${CLUSTER}" ]
631     then
632         return
633     fi
634
635     clean_heartbeat $CLUSTER
636
637     echo -n "Stopping cluster ${CLUSTER}: "
638     check_heartbeat $CLUSTER
639     if [ $? != 0 ]
640     then
641         echo "Failed"
642         echo "Unable to stop cluster as heartbeat region still active" >&2
643     fi
644
645     OUTPUT="`o2cb_ctl -H -n "${CLUSTER}" -t cluster -a online=no 2>&1`"
646     if_fail "$?" "$OUTPUT"
647
648     unload_module ocfs2
649     if_fail "$?"
650 }
651
652 start()
653 {
654     if [ "$O2CB_ENABLED" != "true" ]
655     then
656         exit 0
657     fi
658
659     load
660     online "$1"
661 }
662
663 unload()
664 {
665     if [ -d "$(configfs_path)/cluster/" ]
666     then
667         ls -1 $(configfs_path)/cluster/ | while read CLUSTER
668         do
669             echo "Unable to unload modules as Cluster ${CLUSTER} is still online" >&2
670             exit 1
671         done
672         if [ $? = 1 ]
673         then
674             exit 1
675         fi
676     fi
677
678     for i in $(seq $((${#LOAD_ACTIONS[*]} - 1)) -1 0); do
679         eval "un${LOAD_ACTIONS[i]}"
680         if_fail "$?"
681     done
682 }
683
684 stop()
685 {
686     offline "$1"
687     unload
688 }
689
690 configure()
691 {
692     configure_ask
693     write_sysconfig
694     if_fail "$?" "Unable to write the driver configuration"
695 }
696
697 status()
698 {
699     load_status
700     if [ $? != 2 ]
701     then
702         return 0;
703     fi
704
705     CLUSTER="${1:-${O2CB_BOOTCLUSTER}}"
706     if [ -z "$CLUSTER" ]
707     then
708         return 1;
709     fi
710
711     echo -n "Checking cluster $CLUSTER: "
712     check_online $CLUSTER
713     if [ $? = 2 ]
714     then
715        echo "Online"
716     else
717        echo "Offline"
718        return 0;
719     fi
720
721     echo -n "Checking heartbeat: "
722     check_heartbeat $CLUSTER
723     if [ $? = 2 ]
724     then
725         echo "Active"
726     else
727         echo "Not active"
728         return 0;
729     fi
730
731     return
732
733     echo -n "Checking if O2CB is loaded: "
734     RC=0
735     for MODSPEC in $MODULE_LIST
736     do
737         MODULE_NAME="`echo $MODSPEC | cut -d: -f1`"
738         FSTYPE="`echo $MODSPEC | cut -d: -f2`"
739         MOUNT_POINT="`echo $MODSPEC | cut -d: -f3`"
740
741         if grep "^${MODULE_NAME} " /proc/modules >/dev/null 2>&1
742         then
743             echo -n "${MODULE_NAME} "
744         else
745             RC=1
746             break
747         fi
748     done
749     if_fail "$RC"
750
751     echo -n "Checking O2CB mount points: "
752     for MODSPEC in $MODULE_LIST
753     do
754         MODULE_NAME="`echo $MODSPEC | cut -d: -f1`"
755         FSTYPE="`echo $MODSPEC | cut -d: -f2`"
756         MOUNT_POINT="`echo $MODSPEC | cut -d: -f3`"
757
758         if [ -z "$FSTYPE" -o -z "$MOUNT_POINT" ]
759         then
760             continue
761         fi
762
763         FULL_MOUNT="${O2CB_MANAGER}/${MOUNT_POINT}"
764         FULL_MOUNTSEARCH="`echo "$FULL_MOUNT" | sed -e 's/\//\\\\\//g'`"
765         if grep "^${FSTYPE} ${FULL_MOUNTSEARCH} ${FSTYPE}" /proc/mounts >/dev/null 2>&1
766         then
767             echo -n "${MOUNT_POINT} "
768         else
769             RC=1
770             break
771         fi
772     done
773     if_fail "$RC"
774 }
775
776
777
778 case "$1" in
779     start)
780         start "$2"
781         ;;
782
783     status)
784         status "$2"
785         ;;
786
787     stop)
788         stop "$2"
789         ;;
790
791     restart)
792         stop "$2"
793         start "$2"
794         ;;
795
796     force-reload)
797         stop "$2"
798         start "$2"
799         ;;
800
801     load)
802         load
803         ;;
804
805     online)
806         load
807         online "$2"
808         ;;
809
810     offline)
811         offline "$2"
812         ;;
813
814     unload)
815         offline "$2"
816         unload
817         ;;
818
819     configure)
820         configure
821         if [ "$O2CB_ENABLED" = "true" ]
822         then
823             start
824         else
825             stop
826         fi
827         ;;
828
829     enable)
830         O2CB_ENABLED=true
831         write_sysconfig
832         if_fail "$?" "Unable to write the driver configuration"
833         start
834         ;;
835
836     disable)
837         O2CB_ENABLED=false
838         write_sysconfig
839         if_fail "$?" "Unable to write the driver configuration"
840         stop
841         ;;
842
843     *)
844         echo "Usage: $0 {start|stop|restart|force-reload|enable|disable|configure|load|unload|online|offline|status}"
845         exit 1
846         ;;
847 esac
848
849 exit 0
This page took 0.204116 seconds and 3 git commands to generate.