# Gate Specific Code -- BEGIN
#
# Copyright 1998-2004 Sun Microsystems, Inc.  All rights reserved.
# Use is subject to license terms.
#
#ident  "@(#)dns_probe.ksh 1.14     04/01/23 SMI"
# Gate Specific Code -- END
#!/bin/ksh
# Sun Cluster Data Services Builder template version 1.0
#
# Probe method for DNS.
#
# This method checks the health of the data service.

###############################################################################
# Parse program arguments.
#
function parse_args # [args ...]
{
	typeset opt

	while getopts 'R:G:T:' opt
	do
		case "$opt" in

		R)
		# Name of the DNS resource.
		RESOURCE_NAME=$OPTARG
		;;

		G)
		# Name of the resource group in which the resource is
		# configured.
		RESOURCEGROUP_NAME=$OPTARG
		;;

		T)
		# Name of the resource type.
		RESOURCETYPE_NAME=$OPTARG
		;;

		*)
		logger -p ${SYSLOG_FACILITY}.err \
		-t [$RESOURCETYPE_NAME,$RESOURCEGROUP_NAME,$RESOURCE_NAME] \
		"ERROR: Option $OPTARG unknown"
		exit 1
		;;

		esac
	done

}

###############################################################################
# restart_service ()
#
# This function tries to restart the dataservice by calling the STOP method
# followed by the START method of the dataservice. However, if the dataservice
# has already died and there is not tag registered for the dataservice under
# PMF, then we failover the service to another node in the cluster.
#
function restart_service
{

	# In order to restart the dataservice, first, make 
	# sure that dataservice itself is still registered 
	# under PMF
	pmfadm -q $PMF_TAG
	if [[ $? -eq 0 ]]; then
		# Since the TAG  for the dataservice is still registered under
		# PMF, we will first stop the dataservice and start it back
		# again.

		# Obtain the STOP method name and the STOP_TIMEOUT value for
		# this resource.
		STOP_TIMEOUT=`scha_resource_get -O STOP_TIMEOUT \
			-R $RESOURCE_NAME -G $RESOURCEGROUP_NAME`
		STOP_METHOD=`scha_resource_get -O STOP \
			-R $RESOURCE_NAME -G $RESOURCEGROUP_NAME`
		hatimerun -t $STOP_TIMEOUT $RT_BASEDIR/$STOP_METHOD \
			-R $RESOURCE_NAME -G $RESOURCEGROUP_NAME \
			-T $RESOURCETYPE_NAME

		if [[ $? -ne 0 ]]; then
			logger -p ${SYSLOG_FACILITY}.err -t [$SYSLOG_TAG] \
				"Stop method failed."
			return 1
		fi

		# Obtain the START method name and the START_TIMEOUT value for
                # this resource.
                START_TIMEOUT=`scha_resource_get -O START_TIMEOUT \
                        -R $RESOURCE_NAME -G $RESOURCEGROUP_NAME`
                START_METHOD=`scha_resource_get -O START \
                        -R $RESOURCE_NAME -G $RESOURCEGROUP_NAME`
                hatimerun -t $START_TIMEOUT $RT_BASEDIR/$START_METHOD \
                        -R $RESOURCE_NAME -G $RESOURCEGROUP_NAME \
                        -T $RESOURCETYPE_NAME

                if [[ $? -ne 0 ]]; then
                        logger -p ${SYSLOG_FACILITY}.err -t [$SYSLOG_TAG] \
                                "Start method failed."
                        return 1
                fi


	else
		# the fact that the TAG for the dataservice is not
		# present, implies that the dataservice has already
		# passed the max no of retries allowed under PMF. Hence
		# Hence, there is no point in trying to restart the
		# dataservice again. We might as well try to failover
		# to another node in the cluster.
		scha_control -O GIVEOVER -G $RESOURCEGROUP_NAME \
			-R $RESOURCE_NAME
	fi

	return 0
}

###############################################################################
# decide_restart_or_failover ()
#
# This function decides the action to be taken upon the failure of a probe 
# The action could be to restart the data service locally or it could be to
# failover the data service to another node in the cluster. 
#
function decide_restart_or_failover
{
	
	# Check if this is the first time we are trying to restart 
	if [ $retries -eq 0 ]; then
		# This is the first failure. Note the time when we are doing 
		# this first attempt. 
		start_time=`$RT_BASEDIR/gettime`
		retries=`expr $retries + 1`
		# Since this the first ever failure, we shall try to restart
		# the dataservice.
		restart_service
		if [[ $? -ne 0 ]] then
			logger -p ${SYSLOG_FACILITY}.err \
				-t [$SYSLOG_TAG] \
				"Could not restart dataservice."
                        return 1
		fi
	else
		# This is not the first failure
		current_time=`$RT_BASEDIR/gettime`
		time_diff=`expr $current_time - $start_time`
		if [ $time_diff -ge $RETRY_INTERVAL ]; then
			# This failure happened after the time window
			# elapsed, so we reset the retries counter,
			# slide the window, and do a retry.
			retries=1
			start_time=$current_time
                	# Since the previous failure occured quite sometime
			# back (i.e beyond the retry_interval duration), we
			# will try to do a restart
			restart_service
			if [[ $? -ne 0 ]] then
				logger -p ${SYSLOG_FACILITY}.err \
					-t [$SYSLOG_TAG] \
                                	"Could not restart dataservice"
                        	return 1
			fi
		elif [ $retries -ge $RETRY_COUNT ]; then
			# We are still within the time window,
			# and the retry counter expired. We have to failover.
			retries=0
			scha_control -O GIVEOVER -G $RESOURCEGROUP_NAME \
				-R $RESOURCE_NAME
			if [ $? -ne 0 ]; then
				logger -p ${SYSLOG_FACILITY}.err \
					-t [$SYSLOG_TAG] \
					"Failover attempt failed."
				exit 1
			fi
		else
			# We are still within the time window,
			# and retry counter has not expired,
			# so do another retry.
			retries=`expr $retries + 1`


			# Since we have not reached the maximum no of retires
			# allowed with in the specified retry_interval duration
			# we will try to restart again. 
			restart_service
			if [[ $? -ne 0 ]] then
				logger -p ${SYSLOG_FACILITY}.err \
					-t [$SYSLOG_TAG] \
                                	"Could not restart dataservice"
                        	return 1
			fi
		fi
	fi
}


###############################################################################
# MAIN
###############################################################################

export PATH=/bin:/usr/bin:/usr/cluster/bin:/usr/sbin:/usr/proc/bin:$PATH

# Obtain the syslog facility to use. This will be used to log the messages.
SYSLOG_FACILITY=`scha_cluster_get -O SYSLOG_FACILITY`

# Parse the arguments that have been passed to this method
parse_args "$@"

SYSLOG_TAG=$RESOURCETYPE_NAME,$RESOURCEGROUP_NAME,$RESOURCE_NAME
PMF_TAG=$RESOURCEGROUP_NAME,$RESOURCE_NAME,0.svc

# The interval at which probing is to to be done is set in the system defined
# property THOROUGH_PROBE_INTERVAL. Obtain this information using 
# scha_resource_get 
PROBE_INTERVAL=`scha_resource_get -O THOROUGH_PROBE_INTERVAL \
	-R $RESOURCE_NAME -G $RESOURCEGROUP_NAME`

# Obtain the time-out value allowed for the probe. 
# This value is set in the extension property probe_timeout of the data
# service.
probe_timeout_info=`scha_resource_get -O Extension -R $RESOURCE_NAME \
	-G $RESOURCEGROUP_NAME Probe_timeout`
PROBE_TIMEOUT=`echo $probe_timeout_info | awk '{print $2}'`

# We need to know the full path for the gettime utility which resides in the
# directory <RT_BASEDIR>. Get this from the RT_BASEDIR property of the
# resource type.
RT_BASEDIR=`scha_resource_get -O RT_BASEDIR -R $RESOURCE_NAME \
	-G $RESOURCEGROUP_NAME`

# Get the Retry count value from the system defined property Retry_count
RETRY_COUNT=`scha_resource_get -O RETRY_COUNT -R $RESOURCE_NAME \
	-G $RESOURCEGROUP_NAME`

# Get the Retry Interval value from the system defined property Retry_interval
RETRY_INTERVAL=`scha_resource_get -O RETRY_INTERVAL -R $RESOURCE_NAME \
	-G $RESOURCEGROUP_NAME`


typeset -i retries=0

hostnames=`$RT_BASEDIR/gethostnames -R $RESOURCE_NAME -G $RESOURCEGROUP_NAME \
	-T $RESOURCETYPE_NAME`

probe_cmd_args=

# Obtain the program name of the probe command and make sure it exists.
probe_cmd_prog=`echo $probe_cmd_args | nawk '{print $1}'`

# User added code -- BEGIN vvvvvvvvvvvvvvv
# User added code -- END   ^^^^^^^^^^^^^^^

while :
do
	# The interval at which the probe needs to run is specified 
	# in the property THOROUGH_PROBE_INTERVAL. So we need to 
	# sleep for a duration of <THOROUGH_PROBE_INTERVAL>
	sleep $PROBE_INTERVAL

	# User added code -- BEGIN vvvvvvvvvvvvvvv
	# User added code -- END   ^^^^^^^^^^^^^^^

	if [[ -f $probe_cmd_prog && -x $probe_cmd_prog ]]; then
		hatimerun -t $PROBE_TIMEOUT $probe_cmd_args

		# User added code -- BEGIN vvvvvvvvvvvvvvv
		# User added code -- END   ^^^^^^^^^^^^^^^
	else
		# We were not supplied with a probe command. We will use the 
		# simple_probe that comes bundled as an utility.
		hatimerun -t $PROBE_TIMEOUT $RT_BASEDIR/simple_probe \
			-R $RESOURCE_NAME -G $RESOURCEGROUP_NAME \
			-T $RESOURCETYPE_NAME

		# User added code -- BEGIN vvvvvvvvvvvvvvv
		# User added code -- END   ^^^^^^^^^^^^^^^
	fi

	if [[ $? != 0 ]]; then
		# User added code -- BEGIN vvvvvvvvvvvvvvv
		# User added code -- END   ^^^^^^^^^^^^^^^

		decide_restart_or_failover
		if [[ $? -ne 0 ]] then
			logger -p ${SYSLOG_FACILITY}.err -t [$SYSLOG_TAG] \
				"Could not Restart/Failover the dataservice. "
		fi
	else
		logger -p ${SYSLOG_FACILITY}.info -t [$SYSLOG_TAG] \
			"Probe for resource DNS successful"
	fi

	# User added code -- BEGIN vvvvvvvvvvvvvvv
	# User added code -- END   ^^^^^^^^^^^^^^^
done
