]>
Commit | Line | Data |
---|---|---|
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 |