]>
Commit | Line | Data |
---|---|---|
bebea8a1 | 1 | #!/bin/bash |
2 | # | |
c566897e | 3 | # init fragment for O2CB. |
4 | # | |
bebea8a1 | 5 | # chkconfig: 2345 24 20 |
6 | # description: Load O2CB cluster services at system boot. | |
c566897e | 7 | # |
c566897e | 8 | |
bebea8a1 | 9 | # Source function library |
10 | . /etc/rc.d/init.d/functions | |
c566897e | 11 | |
bebea8a1 | 12 | # Try get config |
13 | [ -f /etc/sysconfig/o2cb ] && . /etc/sysconfig/o2cb | |
c566897e | 14 | |
bebea8a1 | 15 | CLUSTERCONF=/etc/ocfs2/cluster.conf |
c566897e | 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" | |
bebea8a1 | 40 | "mount_fs configfs /sys/kernel/config" |
c566897e | 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 | ||
c566897e | 74 | # |
75 | # load_module() | |
76 | # Load a module | |
77 | # | |
c566897e | 78 | load_module() |
79 | { | |
bebea8a1 | 80 | _modprobe single $1 |
c566897e | 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 | { | |
bebea8a1 | 90 | if [ "$#" -lt "1" -o -z "$1" ]; then |
c566897e | 91 | echo "check_heartbeat(): Requires an argument" >&2 |
92 | return 1 | |
93 | fi | |
94 | CLUSTER="$1" | |
95 | ||
96 | RC=0 | |
bebea8a1 | 97 | if [ -d "/sys/kernel/config/cluster/${CLUSTER}/heartbeat/" ] |
c566897e | 98 | then |
bebea8a1 | 99 | ls -1 "/sys/kernel/config/cluster/${CLUSTER}/heartbeat/" | while read HBUUID |
c566897e | 100 | do |
bebea8a1 | 101 | if [ -d "/sys/kernel/config/cluster/${CLUSTER}/heartbeat/${HBUUID}" ] |
c566897e | 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 | # | |
bebea8a1 | 119 | clean_heartbeat() { |
120 | if [ "$#" -lt "1" -o -z "$1" ]; then | |
c566897e | 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 | ||
bebea8a1 | 128 | if [ ! -d "/sys/kernel/config/cluster/${CLUSTER}/heartbeat/" ] |
c566897e | 129 | then |
130 | echo "OK" | |
131 | return | |
132 | fi | |
133 | ||
bebea8a1 | 134 | ls -1 "/sys/kernel/config/cluster/${CLUSTER}/heartbeat/" | while read HBUUID |
c566897e | 135 | do |
bebea8a1 | 136 | if [ ! -d "/sys/kernel/config/cluster/${CLUSTER}/heartbeat/${HBUUID}" ] |
c566897e | 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 | # | |
bebea8a1 | 172 | unload_module() { |
173 | if [ "$#" -lt "1" -o -z "$1" ]; then | |
c566897e | 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 | ||
bebea8a1 | 196 | echo "Unloading module \"$MODNAME\": " |
c566897e | 197 | modprobe -rs "$MODNAME" |
bebea8a1 | 198 | if [ "$?" != 0 ]; then |
c566897e | 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 | # | |
bebea8a1 | 211 | check_load_module() { |
c566897e | 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 | # | |
bebea8a1 | 237 | mount_fs() { |
238 | TYPE=$1 | |
c566897e | 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 | ||
bebea8a1 | 248 | run_cmd "Mounting ${TYPE} filesystems" mount -t ${TYPE} ${TYPE} $FULL_MOUNT |
c566897e | 249 | return 0 |
250 | } | |
251 | ||
252 | # | |
253 | # check_mount_fs() | |
254 | # | |
255 | # 0 is not mounted, 1 is error, 2 is already mounted | |
256 | # | |
bebea8a1 | 257 | check_mount_fs() { |
c566897e | 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 | # | |
bebea8a1 | 279 | unmount_fs() { |
280 | TYPE=$1 | |
281 | FULL_MOUNT=$2 | |
c566897e | 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 | ||
bebea8a1 | 290 | run_cmd "Unmounting ${TYPE} filesystem" umount $FULL_MOUNT |
c566897e | 291 | } |
292 | ||
bebea8a1 | 293 | load() { |
c566897e | 294 | for i in $(seq 0 $((${#LOAD_ACTIONS[*]} - 1)) ); do |
295 | eval ${LOAD_ACTIONS[i]} | |
c566897e | 296 | done |
297 | } | |
298 | ||
bebea8a1 | 299 | load_status() { |
c566897e | 300 | for i in $(seq 0 $((${#LOAD_ACTIONS[*]} - 1)) ); do |
301 | eval "check_${LOAD_ACTIONS[i]}" | |
302 | done | |
303 | return "$?" | |
304 | } | |
305 | ||
bebea8a1 | 306 | online() { |
c566897e | 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 | |
bebea8a1 | 332 | O2CB_HEARTBEAT_THRESHOLD_FILE=/sys/kernel/config/cluster/${CLUSTER}/heartbeat/dead_threshold |
c566897e | 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 | # | |
bebea8a1 | 360 | check_online() { |
c566897e | 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 | |
bebea8a1 | 369 | if [ -d "/sys/kernel/config/cluster/${CLUSTER}/node/" ] |
c566897e | 370 | then |
bebea8a1 | 371 | ls -1 "/sys/kernel/config/cluster/${CLUSTER}/node/" | while read NODE |
c566897e | 372 | do |
bebea8a1 | 373 | LOCAL="`cat \"/sys/kernel/config/cluster/${CLUSTER}/node/${NODE}/local\"`" |
c566897e | 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 | ||
bebea8a1 | 387 | offline() { |
c566897e | 388 | CLUSTER="${1:-${O2CB_BOOTCLUSTER}}" |
389 | if [ -z "$CLUSTER" ] | |
390 | then | |
391 | return | |
392 | fi | |
393 | ||
bebea8a1 | 394 | if [ ! -e "/sys/kernel/config/cluster/${CLUSTER}" ] |
c566897e | 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 | ||
bebea8a1 | 416 | start() { |
c566897e | 417 | if [ "$O2CB_ENABLED" != "true" ] |
418 | then | |
419 | exit 0 | |
420 | fi | |
421 | ||
422 | load | |
423 | online "$1" | |
424 | } | |
425 | ||
bebea8a1 | 426 | unload() { |
427 | if [ -d /sys/kernel/config/cluster/ ]; then | |
428 | ls -1 /sys/kernel/config/cluster/ | while read CLUSTER | |
c566897e | 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]}" | |
c566897e | 441 | done |
442 | } | |
443 | ||
bebea8a1 | 444 | stop() { |
c566897e | 445 | offline "$1" |
446 | unload | |
447 | } | |
448 | ||
bebea8a1 | 449 | status() { |
c566897e | 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 | ||
c566897e | 570 | *) |
bebea8a1 | 571 | msg_usage "$0 {start|stop|restart|force-reload|load|unload|online|offline|status}" |
572 | exit 3 | |
c566897e | 573 | ;; |
574 | esac | |
575 | ||
576 | exit 0 |