Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > f8323d627545bdce716dd7342f24d29d > files > 2

cman-2.0.115-118.el5_10.1.x86_64.rpm

#!/bin/bash
#
# chkconfig: - 21 79
# description: Starts and stops cman
#
#
### BEGIN INIT INFO
# Provides:
### END INIT INFO
. /etc/init.d/functions

[ -f /etc/sysconfig/cman ] && . /etc/sysconfig/cman
[ -z "$CCSD_OPTS" ] && CCSD_OPTS=

# CMAN_CLUSTER_TIMEOUT -- amount of time to wait for joinging a cluster
#     before giving up.  If CMAN_CLUSTER_TIMEOUT is positive, then we will
#     wait CMAN_CLUSTER_TIMEOUT seconds before giving up and failing when
#     a cluster is not joined.  If CMAN_CLUSTER_TIMEOUT is zero, then
#     wait indefinately for a cluster join.  If CMAN_CLUSTER_TIMEOUT is
#     negative, do not check to see that the cluster has been joined
[ -z "$CMAN_CLUSTER_TIMEOUT" ] && CMAN_CLUSTER_TIMEOUT=120

# CMAN_QUORUM_TIMEOUT -- amount of time to wait for a quorate cluster on 
#     startup quorum is needed by many other applications, so we may as 
#     well wait here.  If CMAN_QUORUM_TIMEOUT is less than 1, quorum will 
#     be ignored.
[ -z "$CMAN_QUORUM_TIMEOUT" ] && CMAN_QUORUM_TIMEOUT=0

# CMAN_SHUTDOWN_TIMEOUT -- amount of time to wait for cman to become a 
#     cluster member before calling cman_tool leave during shutdown.  
#     The default is 60 seconds
[ -z "$CMAN_SHUTDOWN_TIMEOUT" ] && CMAN_SHUTDOWN_TIMEOUT=60

# SKIP_DLM_FINISH -- setting to 1 will cause groupd to be started with
# -f0, which causes groupd to not send finish callbacks to dlm_controld
# as part of a workaround for bz 561892.
[ -z "$SKIP_DLM_FINISH" ] && SKIP_DLM_FINISH=0

# FENCED_START_TIMEOUT -- amount of time to wait for starting fenced
#     before giving up.  If FENCED_START_TIMEOUT is positive, then we will
#     wait FENCED_START_TIMEOUT seconds before giving up and failing when
#     fenced does not start.  If FENCED_START_TIMEOUT is zero, then
#     wait indefinately for fenced to start.
[ -z "$FENCED_START_TIMEOUT" ] && FENCED_START_TIMEOUT=300

# FENCED_MEMBER_DELAY -- amount of time to delay fence_tool join to allow
#     all nodes in cluster.conf to become cluster members.  In seconds.
[ -z "$FENCED_MEMBER_DELAY" ] && FENCED_MEMBER_DELAY=45

# FENCE_JOIN -- boolean value used to control whether or not this node
#     should join the fence domain. If FENCE_JOIN is set to "no", then
#     the script will not attempt to the fence domain. If FENCE_JOIN is
#     set to "yes", then the script will attempt to join the fence domain.
#     If FENCE_JOIN is set to any other value, the default behavior is
#     to join the fence domain (equivalent to "yes").
[ -z "$FENCE_JOIN" ] && FENCE_JOIN="yes"

# FENCED_OPTS -- allow extra options to be passed to fence daemon.
[ -z "$FENCED_OPTS" ] && FENCED_OPTS=""

# NETWORK_BRIDGE_SCRIPT -- script to use for xen network bridging.
#     This script must exist in the /etc/xen/scripts directory.
#     The default script is "network-bridge".
[ -z "$NETWORK_BRIDGE_SCRIPT" ] && NETWORK_BRIDGE_SCRIPT="network-bridge"

[ -z "$LOCK_FILE" ] && LOCK_FILE="/var/lock/subsys/cman"

[ -n "$CLUSTERNAME" ] && cman_join_opts="-c $CLUSTERNAME"

[ -n "$NODENAME" ] && cman_join_opts+=" -n $NODENAME"


load_modules()
{
    errmsg=$( /sbin/modprobe configfs 2>&1 ) || return 1
    errmsg=$( /sbin/modprobe dlm 2>&1 ) || return 1
    errmsg=$( /sbin/modprobe lock_dlm 2>&1 ) || return 1
    return 0
}

start_configfs()
{
    # configfs
    awk '{ print $2 }' /etc/mtab | grep "/sys/kernel/config" &> /dev/null \
    && awk '{ print $3 }' /etc/mtab | grep "configfs" &> /dev/null
    if [ $? -ne 0 ]
    then
	errmsg=$( /bin/mount -t configfs none /sys/kernel/config 2>&1 )
	return $?
    fi
    return 0
}

start_ccsd()
{
    # ccsd
    status ccsd &> /dev/null
    if [ $? -ne 0 ]
    then
	errmsg=$(/sbin/ccsd $CCSD_OPTS 2>&1)
	rtrn=$?
	return $rtrn
    fi
    return 0
}

start_cman()
{
    # cman
    /usr/sbin/cman_tool status &> /dev/null
    if [ $? -ne 0 ]
    then
	errmsg=$( /usr/sbin/cman_tool -t $CMAN_CLUSTER_TIMEOUT -w join \
	    $cman_join_opts 2>&1 ) || return 1

	if [ $CMAN_QUORUM_TIMEOUT -gt 0 ]
	then
	    errmsg=$( /usr/sbin/cman_tool -t $CMAN_QUORUM_TIMEOUT \
		    -q wait 2>&1 ) || return 1
	fi
    fi
    return 0
}


start_qdiskd()
{
    declare current_runlevel

    current_runlevel=$(/sbin/runlevel 2>/dev/null | awk '{ print $2 }' 2>/dev/null)
    #
    # Start qdiskd before fenced to resolve bug #436381.  This only
    # happens if qdiskd is configured to run in the runlevel we are in
    #
    /sbin/chkconfig --levels "$current_runlevel" qdiskd 2>/dev/null
    if [ $? -ne 0 ]; then
        # qdiskd doesn't start at this runlevel.
        return 0
    fi

    echo -n "   Starting qdiskd... "
    /sbin/service qdiskd start &> /dev/null
    if [ $? -eq 0 ] 
    then
	echo "done"
    else
	echo "failed"
	return 1
    fi
    return 0
}


start_daemons()
{
    status groupd &> /dev/null
    if [ $? -ne 0 ]
    then
        if [ $SKIP_DLM_FINISH -eq 1 ]
        then
	    errmsg=$( /sbin/groupd -f0 2>&1 ) || return 1
        else
	    errmsg=$( /sbin/groupd 2>&1 ) || return 1
        fi
    fi

    status fenced &> /dev/null
    if [ $? -ne 0 ]; then
	errmsg=$( /sbin/fenced $FENCED_OPTS 2>&1 ) || return 1
    fi

    status dlm_controld &> /dev/null
    if [ $? -ne 0 ]; then
	errmsg=$( /sbin/dlm_controld 2>&1 ) || return 1
    fi

    status gfs_controld &> /dev/null
    if [ $? -ne 0 ]; then
	errmsg=$( /sbin/gfs_controld 2>&1 ) || return 1
    fi

    return 0
}

start_fence()
{
    /usr/sbin/cman_tool status | grep Flags | grep 2node &> /dev/null
    if [ $? -ne 0 ]
    then
        errmsg=$( /sbin/fence_tool -w -t $FENCED_START_TIMEOUT join \
                 > /dev/null 2>&1 ) || return 1
    else
        errmsg=$( /sbin/fence_tool -w -t $FENCED_START_TIMEOUT \
                 -m $FENCED_MEMBER_DELAY join \
                 > /dev/null 2>&1 ) || return 1
    fi
    return 0
}

start_fence_xvmd()
{
    status fence_xvmd &> /dev/null
    if [ $? -ne 0 ]; then
	errmsg=$( /sbin/fence_xvmd $FENCE_XVMD_OPTS 2>&1 ) || return 1
    fi
    return 0
}

xend_bridged_net_enabled() {
	# Not a xen kernel
	test -d /proc/xen || return 1

    current_runlevel=$(/sbin/runlevel 2>/dev/null | awk '{ print $2 }' 2>/dev/null)
    if [ -z "$current_runlevel" ]; then
        errmsg='Unable to determine the current runlevel'
        return 1
    fi

    /sbin/chkconfig --levels "$current_runlevel" xend 2>/dev/null
    if [ $? -ne 0 ]; then
        # xend doesn't start at this runlevel.
        return 1
    fi

    if [ ! -f /etc/xen/xend-config.sxp ]; then
        # xend isn't configured to use bridged networking.
        return 1
    fi

    egrep "^[[:blank:]]*\([[:blank:]]*network-script[[:blank:]]+(')?[[:blank:]]*${NETWORK_BRIDGE_SCRIPT}([[:blank:]]*\)|[[:blank:]]+)" /etc/xen/xend-config.sxp >&/dev/null
    if [ $? -ne 0 ]; then
        # xend isn't configured to use bridged networking.
        return 1
    fi
    return 0
}

xend_bridged_net_start() {
    if [ ! -x /etc/xen/scripts/${NETWORK_BRIDGE_SCRIPT} ]; then
        if [ -f /etc/xen/scripts/${NETWORK_BRIDGE_SCRIPT} ]; then
            errmsg='The xend bridged network script cannot be run'
        else
            errmsg='The xend bridged network script is missing'
        fi
        return 1
    fi

    /sbin/modprobe netbk >& /dev/null
    /sbin/modprobe netloop >& /dev/null
    bridge_parms=`egrep -m 1 "^[[:blank:]]*\([[:blank:]]*network-script[[:blank:]]+(')?[[:blank:]]*${NETWORK_BRIDGE_SCRIPT}([[:blank:]]*\)|[[:blank:]]+)" /etc/xen/xend-config.sxp| sed -r "s/^[[:blank:]]*\([[:blank:]]*network-script[[:blank:]]+'?[[:blank:]]*${NETWORK_BRIDGE_SCRIPT}[[:blank:]]*//; s/'?[[:blank:]]*\).*//"`
    errmsg=$(/etc/xen/scripts/${NETWORK_BRIDGE_SCRIPT} start $bridge_parms 2>&1) || return 1
    return 0
}

fence_xvmd_enabled()
{
    #
    # Check the value of FENCE_JOIN.
    # If FENCE_JOIN is set to "no", then we should disable fence_xvm.
    #
    if [ "$FENCE_JOIN" == "no" ]; then
	return 1
    fi

    #
    # Check for the 'virsh' binary.  If it's not here, we are not
    # running on a machine capable of running xvmd, as fence_xvmd
    # requires libvirt (which provides the virsh command)
    #
    which virsh &> /dev/null || return 1
	
    #
    # Check for presence of /cluster/fence_xvmd in cluster.conf
    # (If -X is specified, it doesn't matter if it's in cluster.conf;
    #  we'll start it anyway since ccsd is not required)
    #
    if [ "$FENCE_XVMD_OPTS" = "${FENCE_XVMD_OPTS/-X/}" ]; then
        xmllint --shell /etc/cluster/cluster.conf 2> /dev/null \
            < <(echo ls cluster) | grep -q fence_xvmd || return 1
    fi   
    
    return 0
}

fence_join_enabled()
{
    #
    # Check the value of FENCE_JOIN.
    # If FENCE_JOIN is set to "no", we will not attempt to join
    # the fence domain. If FENCE_JOIN is set to any other value,
    # we will attempt to join the fence domain (default).
    #
    if [ "$FENCE_JOIN" == "no" ]; then
	return 1
    else
	return 0
    fi
}

tune_dlm_hash_sizes()
{
	dlmdir="/sys/kernel/config/dlm/cluster"
	maxloop=21

	if [ -z "$DLM_LKBTBL_SIZE" ] && \
	   [ -z "$DLM_RSBTBL_SIZE" ] && \
	   [ -z "$DLM_DIRTBL_SIZE" ] && \
	   [ -z "$DLM_TCP_PORT" ]; then
		return 0
	fi
	for i in $(seq 1 $maxloop); do
		if [ -d $dlmdir ]; then
			break
		fi
		sleep 0.5
	done
	if [ "$i" = "$maxloop" ]; then
		return 1
	fi
	if [ -n "$DLM_LKBTBL_SIZE" ]; then
		echo $DLM_LKBTBL_SIZE > $dlmdir/lkbtbl_size
	fi
	if [ -n "$DLM_RSBTBL_SIZE" ]; then
		echo $DLM_RSBTBL_SIZE > $dlmdir/rsbtbl_size
	fi
	if [ -n "$DLM_DIRTBL_SIZE" ]; then
		echo $DLM_DIRTBL_SIZE > $dlmdir/dirtbl_size
	fi
	if [ -n "$DLM_TCP_PORT" ]; then
		echo $DLM_TCP_PORT > $dlmdir/tcp_port
	fi
	return 0
}

start()
{
    echo "Starting cluster: "

    xend_bridged_net_enabled
    if [ $? -eq 0 ]
    then
        echo -n "   Enabling workaround for Xend bridged networking... "
        xend_bridged_net_start
        if [ $? -eq 0 ] 
        then
            echo "done"
        else
            echo "failed: $errmsg"
			return 1
        fi
    fi

    echo -n "   Loading modules... "
    ulimit -c unlimited
    load_modules
    if [ $? -eq 0 ] 
    then
	echo "done"
    else
	echo "failed"
	return 1
    fi

    echo -n "   Mounting configfs... "
    start_configfs
    if [ $? -eq 0 ] 
    then
	echo "done"
    else
	echo "failed"
	return 1
    fi

    echo -n "   Starting ccsd... "
    start_ccsd
    if [ $? -eq 0 ] 
    then
	echo "done"
    else
	echo "failed"
	return 1
    fi

    echo -n "   Starting cman... "
    start_cman
    if [ $? -eq 0 ] 
    then
	echo "done"
    else
	echo "failed"
	return 1
    fi

    start_qdiskd

    echo -n "   Starting daemons... "
    start_daemons
    if [ $? -eq 0 ] 
    then
	echo "done"
    else
	echo "failed"
	return 1
    fi

    if fence_join_enabled; then
	echo -n "   Starting fencing... "
	start_fence
	if [ $? -eq 0 ] 
	    then
	    echo "done"
	else
	    echo "failed"
	    return 1
	fi
    fi

    if fence_xvmd_enabled; then
	echo -n "   Starting virtual machine fencing host... "
	start_fence_xvmd
	if [ $? -eq 0 ]
	then
	    echo "done"
	else
	    echo "failed"
	return 1
	fi
    fi

    echo -n "   Tuning DLM... "
    tune_dlm_hash_sizes
    if [ $? -eq 0 ] 
    then
	echo "done"
    else
	echo "failed"
	return 1
    fi

    return 0
}

stop_configfs()
{
    awk '{ print $2 }' /etc/mtab | grep "/sys/kernel/config" &> /dev/null\
    && awk '{ print $3 }' /etc/mtab | grep "configfs" &> /dev/null
    if [ $? -eq 0 ] && [ -z "$(ls -1 /sys/kernel/config)" ]
    then
	errmsg=$( /bin/umount /sys/kernel/config 2>&1 )
	if [ $? -ne 0 ]
	then
	    echo -n $errmsg " "
	fi
    fi
    return 0
}

stop_ccsd()
{
    for sec in $(seq 1 10)
    do
	if /sbin/pidof ccsd &> /dev/null
	then
	    # get the pid of ccsd from /var/run/cluster/ccsd.pid
	    # and break if the file is not there
	    [ -r /var/run/cluster/ccsd.pid ] || break

	    pid=$(cat /var/run/cluster/ccsd.pid)
	    /usr/bin/kill $pid &> /dev/null || break
	    
	    sleep 1
	else
	    return 0
	fi
    done
    return 1
}

stop_cman()
{
    /usr/sbin/cman_tool status &> /dev/null
    if [ $? -eq 0 ]
    then
    errmsg=$( /usr/sbin/cman_tool -t $CMAN_SHUTDOWN_TIMEOUT \
	    -w leave $1 2>&1 ) || return 1
    fi
    return 0 # all ok
}

stop_daemons()
{
    if pid=$(/sbin/pidof gfs_controld 2>&1); then
	errmsg=$(/usr/bin/kill $pid 2>&1) || return 1
    fi
    if pid=$(/sbin/pidof dlm_controld 2>&1); then
	errmsg=$(/usr/bin/kill $pid 2>&1) || return 1
    fi
    if pid=$(/sbin/pidof fenced 2>&1); then
	errmsg=$(/usr/bin/kill $pid 2>&1) || return 1
    fi
    if pid=$(/sbin/pidof groupd 2>&1); then
	errmsg=$(/usr/bin/kill $pid 2>&1) || return 1
    fi
    return 0 # all ok
}

stop_fence()
{
    if /sbin/pidof fenced &> /dev/null
    then
	/sbin/fence_tool -w leave > /dev/null 2>&1
	rtrn=$?
	sleep 1 # A bit of time for fenced to exit
	return $rtrn
    fi
    return 0 # all ok
}

stop_fence_xvmd()
{
    if /sbin/pidof fence_xvmd &> /dev/null
    then
    	pkill -TERM fence_xvmd
	sleep 1 # A bit of time for fenced to exit
    fi
    
    [ -z "`pidof fence_xvmd`" ]
    return $?
}

stop()
{
    echo "Stopping cluster: "

    if fence_xvmd_enabled; then
	echo -n "   Stopping virtual machine fencing host... "
	stop_fence_xvmd
	if [ $? -eq 0 ]
	then
	    echo "done"
	else
	    echo "failed"
	    return 1
	fi
    fi

    if fence_join_enabled; then
	echo -n "   Stopping fencing... "
	stop_fence
	if [ $? -eq 0 ]
	    then
	    echo "done"
	else
	    echo "failed"
	    return 1
	fi
    fi

    echo -n "   Stopping cman... "
    if [ $1 ]; then
	stop_cman $1
    else
	stop_cman
    fi
    if [ $? -eq 0 ]
    then
	echo "done"
    else
	echo "failed"
	return 1
    fi

#   stop_daemons
#   [ $? -ne 0 ] && return 1

    echo -n "   Stopping ccsd... "
    stop_ccsd
    if [ $? -eq 0 ]
    then
	echo "done"
    else
	echo "failed"
	return 1
    fi

    echo -n "   Unmounting configfs... "
    stop_configfs
    if [ $? -eq 0 ]
    then
	echo "done"
    else
	echo "failed"
	return 1
    fi

    return 0
}

cmanstatus()
{
	errmsg=$( status ccsd 2>&1) || return 1
	errmsg=$( status groupd 2>&1) || return 1
	errmsg=$( status fenced 2>&1) || return 1
	errmsg=$( status dlm_controld 2>&1) || return 1
	errmsg=$( status gfs_controld 2>&1) || return 1
	
	fence_xvmd_enabled || return 0
	errmsg=$( status fence_xvmd 2>&1) || return 1

	return 0
}

rtrn=1

# See how we were called.
case "$1" in
    start)
	start
	rtrn=$?
	[ $rtrn = 0 ] && touch $LOCK_FILE
	if [ $rtrn -ne 0 ] 
	then
	    echo $errmsg
	    failure "failed to start cman"
	    echo
	else
	    success "start"
	    echo
	fi
	;;
    stop)
	if [ $2 ]; then
	    stop
	else
	    stop remove
	fi
	rtrn=$?
	[ $rtrn = 0 ] && rm -f $LOCK_FILE
	if [ $rtrn -ne 0 ] 
	then
	    echo $errmsg
	    failure "failed to stop cman"
	    echo
	else
	    success "shutdown"
	    echo
	fi
	;;

    restart)
	$0 stop restart
	$0 start
	rtrn=$?
	;;

    status)
	cmanstatus
	rtrn=$?
	if [ $rtrn -ne 0 ] ; then
	    echo $errmsg
	else
	    echo "cman is running."
	fi
	;;

    *)
	    echo $"Usage: $0 {start|stop|restart|status}"
	    ;;
esac

exit $rtrn