#!/bin/sh
#
#pragma ident	"@(#)initucmm	1.11	05/04/21 SMI"
#
# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
# Use is subject to license terms.
#
# Start/stop user cluster membership monitor daemon.

BINDIR=/usr/cluster/lib/ucmm
SHUTDOWN_FILE=${BINDIR}/.ucmmd_shutdown
USRBIN=/usr/bin
SERVER=ucmmd
RGMD=rgmd
UCMMSTATE=${BINDIR}/ucmmstate


#
# The following list represents the exit codes from the ucmmstate command
#
OK_TO_JOIN=0
NOT_OK_TO_JOIN=1
OK_TO_JOIN_USAGE_ERROR=2
OK_TO_JOIN_INIT_ERROR=3

# Allow node to join if step number is OK_TO_JOIN_STEP or beyond
OK_TO_JOIN_STEP=2

#
# The environment variable ${RECONF_PROG} must be a non-zero length
# string in order to start this daemon.
#
RECONF_PROG=${BINDIR}/ucmm_reconf


#
# Wait in this function until it is OK to join the cluster
#
check_ok_to_join() {

	UCMMSTATE_RETRY_COUNT=30
	UCMMSTATE_INTERVAL=1
	ERROR_RETRY_LIMIT=10
	ERROR_RETRY_INTERVAL=30
	error_retry_count=0
	rc=0
	msg=""

	while : ; do

		# Retry 30 time seconds at 1 second interval
		# After exhausing retries, log message and try again

		msg="`$UCMMSTATE -s ${OK_TO_JOIN_STEP} \
			-r ${UCMMSTATE_RETRY_COUNT} -t ${UCMMSTATE_INTERVAL}  2>&1`"

		rc=$?

		if [ ${rc} -eq ${OK_TO_JOIN} ]; then
			# Success
			break

		elif [ ${rc} -eq ${NOT_OK_TO_JOIN} ]; then
			# Not OK to join
			/bin/logger -p local0.err -t INITUCMM \
				"Notice: not OK to join" 

		elif [ ${rc} -eq ${OK_TO_JOIN_USAGE_ERROR} ]; then
			# Error such as incorrect options,
			# non root user
			/bin/logger -p local0.err -t INITUCMM \
				"${UCMMSTATE} usage error : ${msg}" 
			return 1

		else
			# Other error such as initialization failure
			# Wait and retry
			/bin/logger -p local0.err -t INITUCMM \
				"Notice: not OK to join. Error: ${msg}"

			error_retry_count=`/bin/expr ${error_retry_count} + 1`
			if [ $error_retry_count -gt $ERROR_RETRY_LIMIT ]; then
			    # Exhausted all retries
			    #
			    /bin/logger -p local0.err -t INITUCMM \
			    "Unable to determine whether it is OK to join. "\
			    "Giving up after ${ERROR_RETRY_LIMIT} retries. "\
			    "The ucmmd will not be started on this node."
			    return 1
			fi

			/bin/sleep ${ERROR_RETRY_INTERVAL}
		fi
	done

	return 0
}

validate_setup()
{
	# test whether we are a cluster and exit if not a cluster
	/usr/sbin/clinfo > /dev/null 2>&1
	if [ $? != 0 ] ; then
		exit 0
	fi

	my_nodeid=`/usr/sbin/clinfo -n`

	# exit if ucmmd is already running
	pidlist=`${USRBIN}/pgrep -u 0 ${SERVER}`
	if [ $? -eq 0 ] ; then
		exit 1
	fi

	# exit if rgmd is not running
	pidlist=`${USRBIN}/pgrep -u 0 ${RGMD}`
	if [ $? -eq 1 ] ; then
		/bin/logger -p local0.err -t INITUCMM "Error: rgmd is not running, not starting ucmmd."
		exit 1
	fi

	# check for existence of executible ucmmstate program
	if [ ! -x ${UCMMSTATE} ]; then
		/bin/logger -p local0.err -t INITUCMM \
			"Error: ${UCMMSTATE} not an executible."
		exit 1
	fi

	if [ ! -x "${RECONF_PROG}" ]; then
		/bin/logger -p local0.err -t INITUCMM \
			"Error: ${RECONF_PROG} does not exist or not an executible."
		exit 1
	fi
	return 0

}

rac_rg_configured()
{
	#
	# ucmm_reconf will return 0 is rac_rg is configured
	#
	
	${RECONF_PROG} verify_rac_rg

	return $?
}

start_ucmmd()
{
	${RECONF_PROG} validate
	if [ $? -ne 0 ]; then
		# Validations failed
		# Cannot start ucmmd
		/bin/logger -p local0.err -t INITUCMM \
			"Validation failed. The ucmmd daemon will not be started on this node."
		exit 1
	fi

	#
	# Wait to join only if CVM is installed on the node
	#
	/usr/bin/pkginfo -q SUNWcvmr
	if [ $? -eq 0 ]; then
		check_ok_to_join
		if [ $? -ne 0 ]; then
			exit 1
		fi
	fi

	if [ -n "${RECONF_PROG}" ]; then
		${BINDIR}/${SERVER} -r ${RECONF_PROG}
	fi
}


case "$1" in
'start')
	validate_setup || exit $?
	
	# If RAC RG is configured, do not start UCMMD
	rac_rg_configured  && exit 0

	start_ucmmd &
	;;
'boot')
	validate_setup || exit $?
	start_ucmmd
	;;
'stop')
	# test whether we are a cluster and exit if not a cluster
	/usr/sbin/clinfo > /dev/null 2>&1
	if [ $? != 0 ] ; then
		exit 0
	fi
	/bin/cp /dev/null ${SHUTDOWN_FILE}
	;;
*)
	echo "Usage: /etc/init.d/initucmm { start | stop }"
	;;
esac

exit 0
