| #!/bin/bash |
| |
| # Authors: |
| # Andrew Beekhof <abeekhof@redhat.com> |
| # Fabio M. Di Nitto <fdinitto@redhat.com> |
| # |
| # License: Revised BSD |
| |
| # chkconfig: - 99 01 |
| # description: Pacemaker Cluster Manager |
| # processname: pacemakerd |
| # |
| ### BEGIN INIT INFO |
| # Provides: pacemaker |
| # Required-Start: $network $remote_fs corosync |
| # Should-Start: $syslog |
| # Required-Stop: $network $remote_fs corosync |
| # Default-Start: |
| # Default-Stop: |
| # Short-Description: Starts and stops Pacemaker Cluster Manager. |
| # Description: Starts and stops Pacemaker Cluster Manager. |
| ### END INIT INFO |
| |
| desc="Pacemaker Cluster Manager" |
| prog="pacemakerd" |
| |
| # set secure PATH |
| PATH="/sbin:/bin:/usr/sbin:/usr/bin:@sbindir@" |
| |
| checkrc() { |
| if [ $? = 0 ]; then |
| success |
| else |
| failure |
| fi |
| } |
| |
| success() |
| { |
| echo -ne "[ OK ]\r" |
| } |
| |
| failure() |
| { |
| echo -ne "[FAILED]\r" |
| } |
| |
| log() |
| { |
| logger -t pacemaker -p daemon.notice "$*" |
| } |
| |
| notify() |
| { |
| log "$*" |
| echo -n "$*" |
| } |
| |
| status() |
| { |
| pid=$(pidof $1 2>/dev/null) |
| local rtrn=$? |
| if [ $rtrn -ne 0 ]; then |
| echo "$1 is stopped" |
| if [ -f "@localstatedir@/run/$prog.pid" ]; then |
| rtrn=1 |
| else |
| rtrn=3 |
| fi |
| else |
| echo "$1 (pid $pid) is running..." |
| fi |
| return $rtrn |
| } |
| |
| if [ -d @CONFIGDIR@ ]; then |
| [ -f @INITDIR@/functions ] && . @INITDIR@/functions |
| set -a |
| [ -f @CONFIGDIR@/pacemaker ] && . @CONFIGDIR@/pacemaker |
| [ -f @CONFIGDIR@/sbd ] && . @CONFIGDIR@/sbd |
| set +a |
| fi |
| |
| LOCK_DIR="." |
| if [ -d "@localstatedir@/lock/subsys" ]; then |
| LOCK_DIR="@localstatedir@/lock/subsys" |
| elif [ -d "@localstatedir@/lock" ]; then |
| LOCK_DIR="@localstatedir@/lock" |
| fi |
| [ -z "$LOCK_FILE" ] && LOCK_FILE="$LOCK_DIR/pacemaker" |
| |
| # Unless specified otherwise, assume cman is in use if cluster.conf exists |
| if [ x = "x$PCMK_STACK" -a -f "@sysconfdir@/cluster/cluster.conf" ]; then |
| PCMK_STACK=cman |
| fi |
| |
| # Check if there is a valid watchdog-device configured in sbd config |
| if [ x != "x$SBD_WATCHDOG_DEV" -a "/dev/null" != "$SBD_WATCHDOG_DEV" -a -c "$SBD_WATCHDOG_DEV" ]; then |
| # enhance for unavailable chkconfig - don't touch sbd for now |
| if chkconfig --list sbd_helper 2>/dev/null | grep -q ":on"; then |
| SBD_SERVICE=sbd_helper |
| fi |
| fi |
| |
| start() |
| { |
| notify "Starting $desc" |
| |
| # most recent distributions use tmpfs for $@localstatedir@/run |
| # to avoid to clean it up on every boot. |
| # they also assume that init scripts will create |
| # required subdirectories for proper operations |
| mkdir -p "@localstatedir@/run" |
| |
| if status $prog > /dev/null 2>&1; then |
| success |
| else |
| $prog > /dev/null 2>&1 & |
| |
| # Time to connect to corosync and fail |
| sleep 5 |
| |
| if status $prog > /dev/null 2>&1; then |
| touch "$LOCK_FILE" |
| pidof $prog > "@localstatedir@/run/$prog.pid" |
| success |
| else |
| failure |
| rtrn=1 |
| fi |
| fi |
| echo |
| } |
| |
| cman_pre_start() |
| { |
| # start cman if it's not running |
| service cman status >/dev/null 2>&1 |
| if [ $? -ne 0 ]; then |
| service cman start |
| if [ $? -ne 0 ]; then |
| notify "Aborting startup of $desc" |
| echo |
| exit 1 |
| fi |
| fi |
| |
| # start cman's friends if they're not running but were configured to start automatically |
| for cservice in cmirrord clvmd gfs2 $SBD_SERVICE; do |
| chkconfig --list $cservice 2>/dev/null | grep -q ":on" |
| if [ $? -eq 0 ]; then |
| service $cservice status >/dev/null 2>&1 |
| if [ $? -ne 0 ]; then |
| log "Attempting to start $cservice" |
| service $cservice start |
| fi |
| fi |
| done |
| } |
| |
| cman_pre_stop() |
| { |
| # if cman is not running there is nothing we need to do here |
| service cman status >/dev/null 2>&1 |
| if [ $? -ne 0 ]; then |
| return |
| fi |
| |
| has_lvm=`crm_resource -c | grep Resource: | grep LVM` |
| |
| # migrate resources to another node or shut them down |
| cname=`crm_node --name` |
| crm_attribute -N $cname -n standby -v true -l reboot |
| notify "Waiting for shutdown of managed resources" |
| |
| |
| while [ 1 = 1 ]; do |
| # 0x0000000000000002 means managed |
| active=`crm_resource -c | grep Resource: | grep 0x...............[2367] | awk '{print $9}' | grep "^${cname}$" | wc -l` |
| if [ $active = 0 ]; then |
| break; |
| fi |
| sleep 2 |
| echo -n "." |
| done |
| success |
| echo |
| |
| if [ -d /sys/kernel/dlm/ ]; then |
| lockspace="$(ls -1 /sys/kernel/dlm/)" |
| if [ -n "$lockspace" ]; then |
| notify "DLM lockspace still in use" |
| echo "" |
| |
| for cservice in gfs2 clvmd cmirrord; do |
| service $cservice status >/dev/null 2>&1 |
| if [ $? -eq 0 ]; then |
| if [ -n "$has_lvm" ] && [ "$cservice" = "clvmd" ]; then |
| # allow HA-LVM to take a lock on vg/lv before clvmd can exit |
| notify "Waiting for LVM services to start somewhere else" |
| sleep 15 |
| success |
| fi |
| log "Attempting to shutdown $cservice" |
| service $cservice stop |
| fi |
| done |
| fi |
| fi |
| |
| notify "Leaving fence domain" |
| fence_tool leave -w 10 |
| checkrc |
| |
| fenced=$(pidof fenced) |
| notify "Stopping fenced $fenced" |
| kill -KILL $fenced > /dev/null 2>&1 |
| checkrc |
| } |
| |
| stop() |
| { |
| shutdown_prog=$prog |
| if ! status $prog > /dev/null 2>&1; then |
| shutdown_prog="crmd" |
| fi |
| |
| if status $shutdown_prog > /dev/null 2>&1; then |
| notify "Signaling $desc to terminate" |
| kill -TERM $(pidof $prog) > /dev/null 2>&1 |
| checkrc |
| echo |
| |
| notify "Waiting for cluster services to unload" |
| while status $prog > /dev/null 2>&1; do |
| sleep 1 |
| echo -n "." |
| done |
| else |
| echo -n "$desc is already stopped" |
| fi |
| |
| rm -f "$LOCK_FILE" |
| rm -f "@localstatedir@/run/$prog.pid" |
| killall -q -9 'crmd stonithd attrd cib lrmd pacemakerd' |
| success |
| echo |
| } |
| |
| rtrn=0 |
| |
| case "$1" in |
| start) |
| # For consistency with stop |
| [ "$PCMK_STACK" = cman ] && cman_pre_start |
| start |
| ;; |
| restart|reload|force-reload) |
| stop |
| start |
| ;; |
| condrestart|try-restart) |
| if status $prog > /dev/null 2>&1; then |
| stop |
| start |
| fi |
| ;; |
| status) |
| status $prog |
| rtrn=$? |
| ;; |
| stop) |
| # |
| # stonithd needs to be around until fenced is stopped |
| # fenced can't be stopped until any resource using dlm is active |
| # |
| # So: |
| # 1. put the node into standby |
| # 2. wait for all resources to be stopped |
| # 3. stop fenced and anything that needs it (borrowed from the cman script) |
| # 4. stop pacemaker |
| # 5. stop the rest of cman (so it doesn't end up half up/down) |
| # |
| [ "$PCMK_STACK" = cman ] && cman_pre_stop |
| stop |
| [ "x$SBD_SERVICE" != x ] && service $SBD_SERVICE stop |
| |
| # Stop cman if needed, unless --skip-cman is specified (which allows |
| # higher-level tooling to stop pacemaker on all nodes, then stop cman |
| # on all nodes, to maintain quorum for DLM-based resources while |
| # pacemaker shuts down). |
| [ "$PCMK_STACK" = cman ] && [ "$2" != "--skip-cman" ] && service cman stop |
| ;; |
| *) |
| echo "usage: $0 {start|stop|restart|reload|force-reload|condrestart|try-restart|status}" |
| rtrn=2 |
| ;; |
| esac |
| |
| exit $rtrn |