]> git.pld-linux.org Git - packages/ocfs2-tools.git/blame - o2cb.init
- o2cb.sysconfig added; BRs revisited; proper %service; more files
[packages/ocfs2-tools.git] / o2cb.init
CommitLineData
c566897e 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
18export LC_ALL=C
19
20CLUSTERCONF=/etc/ocfs2/cluster.conf
21
22if [ -f /etc/sysconfig/o2cb ]
23then
24 # Red Hat and Novell
25 CONFIGURATION=/etc/sysconfig/o2cb
26elif [ -f /etc/default/o2cb ]
27then
28 # Debian
29 CONFIGURATION=/etc/default/o2cb
30elif [ -d /etc/sysconfig ]
31then
32 CONFIGURATION=/etc/sysconfig/o2cb
33else
34 CONFIGURATION=/etc/default/o2cb
35fi
36
37# Source configuration,
38[ -f "${CONFIGURATION}" ] && . "${CONFIGURATION}"
39
40configfs_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#
73LOAD_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#
88if_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#
114write_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.
125O2CB_ENABLED=${O2CB_ENABLED:-false}
126
127# O2CB_BOOTCLUSTER: If not empty, the name of a cluster to start.
128O2CB_BOOTCLUSTER=${O2CB_BOOTCLUSTER}
129
130# O2CB_HEARTBEAT_THRESHOLD: Iterations before a node is considered dead.
131O2CB_HEARTBEAT_THRESHOLD=${O2CB_HEARTBEAT_THRESHOLD}
132
133EOF
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#
147configure_ask()
148{
149 cat <<EOF
150Configuring the O2CB driver.
151
152This will configure the on-boot properties of the O2CB driver.
153The following questions will determine whether the driver is loaded on
154boot. The current values will be shown in brackets ('[]'). Hitting
155<ENTER> without typing an answer will keep that current value. Ctrl-C
156will abort.
157
158EOF
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#
221make_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#
256load_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#
287check_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#
319clean_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#
374unload_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#
416check_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#
443mount_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#
477check_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#
500unmount_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
523load()
524{
525 for i in $(seq 0 $((${#LOAD_ACTIONS[*]} - 1)) ); do
526 eval ${LOAD_ACTIONS[i]}
527 if_fail "$?"
528 done
529}
530
531load_status()
532{
533 for i in $(seq 0 $((${#LOAD_ACTIONS[*]} - 1)) ); do
534 eval "check_${LOAD_ACTIONS[i]}"
535 done
536 return "$?"
537}
538
539online()
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#
594check_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
622offline()
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
652start()
653{
654 if [ "$O2CB_ENABLED" != "true" ]
655 then
656 exit 0
657 fi
658
659 load
660 online "$1"
661}
662
663unload()
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
684stop()
685{
686 offline "$1"
687 unload
688}
689
690configure()
691{
692 configure_ask
693 write_sysconfig
694 if_fail "$?" "Unable to write the driver configuration"
695}
696
697status()
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
778case "$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 ;;
847esac
848
849exit 0
This page took 0.110965 seconds and 4 git commands to generate.