2 # init fragment for O2CB.
4 # chkconfig: 2345 24 20
5 # description: Load O2CB cluster services at system boot.
9 # Required-Start: $network
12 # Default-Start: 2 3 5
14 # Description: Load O2CB cluster services at system boot.
20 CLUSTERCONF=/etc/ocfs2/cluster.conf
22 if [ -f /etc/sysconfig/o2cb ]
25 CONFIGURATION=/etc/sysconfig/o2cb
26 elif [ -f /etc/default/o2cb ]
29 CONFIGURATION=/etc/default/o2cb
30 elif [ -d /etc/sysconfig ]
32 CONFIGURATION=/etc/sysconfig/o2cb
34 CONFIGURATION=/etc/default/o2cb
37 # Source configuration,
38 [ -f "${CONFIGURATION}" ] && . "${CONFIGURATION}"
42 # Note that this is only valid *after* configfs is loaded
43 if [ -d /sys/kernel/config ]
45 echo /sys/kernel/config
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
58 # Eval of the exact lines, in order. So, the first call is
59 # "eval load_module configfs".
62 # Eval of the lines with "check_" prepended, in order. So the first
63 # call is "eval check_load_module configfs".
66 # Eval of the lines with "un" prepened, in reverse order. So the
67 # *last* call is "eval unload_module configfs".
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.
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")
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.
101 if [ -n "${REASON}" ]
112 # Writes the system configuration out
116 echo -n "Writing O2CB configuration: "
117 cat >"${CONFIGURATION}" <<EOF
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
124 # O2CB_ENABELED: 'true' means to load the driver on boot.
125 O2CB_ENABLED=${O2CB_ENABLED:-false}
127 # O2CB_BOOTCLUSTER: If not empty, the name of a cluster to start.
128 O2CB_BOOTCLUSTER=${O2CB_BOOTCLUSTER}
130 # O2CB_HEARTBEAT_THRESHOLD: Iterations before a node is considered dead.
131 O2CB_HEARTBEAT_THRESHOLD=${O2CB_HEARTBEAT_THRESHOLD}
145 # Ask configuration questions, setting the shell vars.
150 Configuring the O2CB driver.
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
162 if [ "$O2CB_ENABLED" = "true" ]
168 echo -n "Load O2CB driver on boot (y/n) [$CUR]: "
183 echo "Invalid answer: $LINE" >&2
190 echo -n "Cluster to start on boot (Enter \"none\" to clear) [$O2CB_BOOTCLUSTER]: "
202 echo "Invalid cluster name: $LINE" >&2
205 O2CB_BOOTCLUSTER="$LINE"
211 # XXX ask about mount point base
219 # Returns 0 on success, 1 on error, 2 if it already exists.
223 if [ "$#" -lt "1" -o -z "$1" ]
225 echo "make_dir(): Requires an argument" >&2
235 echo "make_dir(): File $DIR is not a directory" >&2
239 echo -n "Creating directory '$DIR': "
240 mkdir -p "$DIR" 2>/dev/null
243 echo "Unable to create directory '$DIR'" >&2
254 # 0 is success, 1 is error, 2 is already loaded
258 if [ "$#" -lt "1" -o -z "$1" ]
260 echo "load_module(): Requires an argument" >&2
265 MODOUT="`awk '$1 ~ /^'$MODNAME'$/{print $1;exit}' < /proc/modules 2>/dev/null`"
271 echo -n "Loading module \"$MODNAME\": "
272 modprobe -s "$MODNAME"
275 echo "Unable to load module \"$MODNAME\"" >&2
285 # 0 is hb not active, 1 is error, 2 is hb active
289 if [ "$#" -lt "1" -o -z "$1" ]
291 echo "check_heartbeat(): Requires an argument" >&2
297 if [ -d "$(configfs_path)/cluster/${CLUSTER}/heartbeat/" ]
299 ls -1 "$(configfs_path)/cluster/${CLUSTER}/heartbeat/" | while read HBUUID
301 if [ -d "$(configfs_path)/cluster/${CLUSTER}/heartbeat/${HBUUID}" ]
317 # Removes the inactive heartbeat regions
321 if [ "$#" -lt "1" -o -z "$1" ]
323 echo "clean_heartbeat(): Requires an argument" >&2
328 echo -n "Cleaning heartbeat on ${CLUSTER}: "
330 if [ ! -d "$(configfs_path)/cluster/${CLUSTER}/heartbeat/" ]
336 ls -1 "$(configfs_path)/cluster/${CLUSTER}/heartbeat/" | while read HBUUID
338 if [ ! -d "$(configfs_path)/cluster/${CLUSTER}/heartbeat/${HBUUID}" ]
343 OUTPUT="`ocfs2_hb_ctl -I -u ${HBUUID} 2>&1`"
351 REF="`echo ${OUTPUT} | awk '/refs/ {print $2; exit;}' 2>&1`"
355 echo "At least one heartbeat region still active" >&2
358 OUTPUT="`ocfs2_hb_ctl -K -u ${HBUUID} 2>&1`"
372 # 0 is success, 1 is error, 2 is not loaded
376 if [ "$#" -lt "1" -o -z "$1" ]
378 echo "unload_module(): Requires an argument" >&2
383 MODOUT="`awk '$1 ~ /^'$MODNAME'$/{print $1,$3;exit}' < /proc/modules 2>/dev/null`"
395 echo -n "Invalid module parsing! "
400 echo -n "Unloading module \"$MODNAME\": "
401 modprobe -rs "$MODNAME"
404 echo "Unable to unload module \"$MODNAME\"" >&2
412 # check_load_module()
414 # 0 is not loaded, 1 is error, 2 is already loaded
418 if [ "$#" -lt "1" -o -z "$1" ]
420 echo "check_load_module(): Requires an argument" >&2
425 echo -n "Module \"$MODNAME\": "
426 MODOUT="`awk '$1 ~ /^'$MODNAME'$/{print $1,$3;exit}' < /proc/modules 2>/dev/null`"
439 # Mount a filesystem.
441 # 0 is success, 1 is error, 2 is already mounted
447 FULL_MOUNTSEARCH="`echo "$FULL_MOUNT" | sed -e 's/\//\\\\\//g'`"
448 MOUNTOUT="`awk '$2 ~ /^'$FULL_MOUNTSEARCH'$/{print $2; exit}' < /proc/mounts 2>/dev/null`"
450 if [ -n "$MOUNTOUT" ]
456 if [ ! -e "$FULL_MOUNT" ]; then
461 echo -n "Mounting ${TYPE} filesystem at $FULL_MOUNT: "
462 mount -t ${TYPE} ${TYPE} $FULL_MOUNT
465 echo "Unable to mount ${TYPE} filesystem" >&2
475 # 0 is not mounted, 1 is error, 2 is already mounted
481 FULL_MOUNTSEARCH="`echo "$FULL_MOUNT" | sed -e 's/\//\\\\\//g'`"
482 MOUNTOUT="`awk '$2 ~ /^'$FULL_MOUNTSEARCH'$/{print $2; exit}' < /proc/mounts 2>/dev/null`"
484 echo -n "Filesystem \"$TYPE\": "
485 if [ -n "$MOUNTOUT" ]
496 # Unmount a filesystem
498 # 0 is success, 1 is error, 2 is not mounted
504 FULL_MOUNTSEARCH="`echo "$FULL_MOUNT" | sed -e 's/\//\\\\\//g'`"
505 MOUNTOUT="`awk '$2 ~ /^'$FULL_MOUNTSEARCH'$/{print $2; exit}' < /proc/mounts 2>/dev/null`"
507 if [ -z "$MOUNTOUT" ]
512 echo -n "Unmounting ${TYPE} filesystem: "
516 echo "Unable to unmount ${TYPE} filesystem" >&2
525 for i in $(seq 0 $((${#LOAD_ACTIONS[*]} - 1)) ); do
526 eval ${LOAD_ACTIONS[i]}
533 for i in $(seq 0 $((${#LOAD_ACTIONS[*]} - 1)) ); do
534 eval "check_${LOAD_ACTIONS[i]}"
541 CLUSTER="${1:-${O2CB_BOOTCLUSTER}}"
544 echo "Cluster not known"
548 check_online $CLUSTER
551 echo "Cluster ${CLUSTER} already online"
555 if ! [ -f ${CLUSTERCONF} ]
557 echo -n "Checking cluster configuration : "
561 echo -n "Starting cluster ${CLUSTER}: "
562 OUTPUT="`o2cb_ctl -H -n "${CLUSTER}" -t cluster -a online=yes 2>&1`"
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"
573 echo "WARNING: Unable to set heartbeat dead threshold" >&2
584 echo -n "Stopping cluster ${CLUSTER}: "
585 OUTPUT="`o2cb_ctl -H -n "${CLUSTER}" -t cluster -a online=no 2>&1`"
586 if_fail "$?" "$OUTPUT"
592 # 0 is not online, 1 is error, 2 is online
596 if [ "$#" -lt "1" -o -z "$1" ]
598 echo "check_online(): Requires an argument" >&2
604 if [ -d "$(configfs_path)/cluster/${CLUSTER}/node/" ]
606 ls -1 "$(configfs_path)/cluster/${CLUSTER}/node/" | while read NODE
608 LOCAL="`cat \"$(configfs_path)/cluster/${CLUSTER}/node/${NODE}/local\"`"
624 CLUSTER="${1:-${O2CB_BOOTCLUSTER}}"
630 if [ ! -e "$(configfs_path)/cluster/${CLUSTER}" ]
635 clean_heartbeat $CLUSTER
637 echo -n "Stopping cluster ${CLUSTER}: "
638 check_heartbeat $CLUSTER
642 echo "Unable to stop cluster as heartbeat region still active" >&2
645 OUTPUT="`o2cb_ctl -H -n "${CLUSTER}" -t cluster -a online=no 2>&1`"
646 if_fail "$?" "$OUTPUT"
654 if [ "$O2CB_ENABLED" != "true" ]
665 if [ -d "$(configfs_path)/cluster/" ]
667 ls -1 $(configfs_path)/cluster/ | while read CLUSTER
669 echo "Unable to unload modules as Cluster ${CLUSTER} is still online" >&2
678 for i in $(seq $((${#LOAD_ACTIONS[*]} - 1)) -1 0); do
679 eval "un${LOAD_ACTIONS[i]}"
694 if_fail "$?" "Unable to write the driver configuration"
705 CLUSTER="${1:-${O2CB_BOOTCLUSTER}}"
711 echo -n "Checking cluster $CLUSTER: "
712 check_online $CLUSTER
721 echo -n "Checking heartbeat: "
722 check_heartbeat $CLUSTER
733 echo -n "Checking if O2CB is loaded: "
735 for MODSPEC in $MODULE_LIST
737 MODULE_NAME="`echo $MODSPEC | cut -d: -f1`"
738 FSTYPE="`echo $MODSPEC | cut -d: -f2`"
739 MOUNT_POINT="`echo $MODSPEC | cut -d: -f3`"
741 if grep "^${MODULE_NAME} " /proc/modules >/dev/null 2>&1
743 echo -n "${MODULE_NAME} "
751 echo -n "Checking O2CB mount points: "
752 for MODSPEC in $MODULE_LIST
754 MODULE_NAME="`echo $MODSPEC | cut -d: -f1`"
755 FSTYPE="`echo $MODSPEC | cut -d: -f2`"
756 MOUNT_POINT="`echo $MODSPEC | cut -d: -f3`"
758 if [ -z "$FSTYPE" -o -z "$MOUNT_POINT" ]
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
767 echo -n "${MOUNT_POINT} "
821 if [ "$O2CB_ENABLED" = "true" ]
832 if_fail "$?" "Unable to write the driver configuration"
839 if_fail "$?" "Unable to write the driver configuration"
844 echo "Usage: $0 {start|stop|restart|force-reload|enable|disable|configure|load|unload|online|offline|status}"