#!/bin/sh
#
#pragma ident	"@(#)initpmf	1.13	01/12/10 SMI"
#
# Copyright (c) 1998-2001 by Sun Microsystems, Inc.
# All rights reserved.
#

# Start/stop processes required for init pmf

LIBSCDIR=/usr/cluster/lib/sc
BINDIR=/usr/cluster/bin
USRBIN=/usr/bin
SERVER=rpc.pmfd

# The following three variables are used in the rpcinfo call to check
# whether the rpc.pmfd is really up and registered in rpcbind
# after we launch it.
TRANSPORT=ticotsord
PROGNUM=100248
LOCALHOST=`${USRBIN}/uname -n`

svcfound=no


case "$1" in
'start')
	# 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

	# Find if an instance of rpc.pmfd is already running and if yes exit
	# We only allow one rpc.pmfd at a time.
	pidlist=`${USRBIN}/ps -e | ${USRBIN}/grep ${SERVER} \
		| ${USRBIN}/awk '{print $1}'`
	if [ -n "${pidlist}" ] ; then
		${USRBIN}/logger -p local0.err -t INITPMF "Error: ${SERVER} is already running."
                exit 1;
	fi

	# Find out if host is running 32 or 64 bit Solaris
	# and start the appropriate server 
	version=`${USRBIN}/optisa sparcv9 sparc`
	if [ "${version}" = "sparcv9" ] ; then
		${LIBSCDIR}/sparcv9/${SERVER}
	else 
		${LIBSCDIR}/${SERVER}
	fi

	if [ $? -ne 0 ]; then
		${USRBIN}/logger -p local0.err -t INITPMF "Error: Can't start ${SERVER}."
		exit 1
	fi

	# sleep for 2 sec to give the server the chance to come up
	${USRBIN}/sleep 2

        # Loop for 7 min checking that the server is up.
	# We check by querying rpcbind for the hardcoded program
	# number under which we know rpc.pmfd is registered.
	#
	# We need to wait until the rpc.pmfd is up and registered before
	# moving on, so that init scripts that follow us will be able
	# to succeed if they depend on rpc.pmfd being up.
	for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42; do
		${USRBIN}/rpcinfo -T ${TRANSPORT} ${LOCALHOST} ${PROGNUM} > /dev/null 2>&1
		if [ $? -eq 0 ]; then
			svcfound=yes
			break
		fi

		# We print a status message explainaing that we're waiting
		# for the rpc.pmfd to register with rpcbind every minute,
		# starting after 30 seconds.
		case $i in
		    4|10|16|22|28|34|40)
			${USRBIN}/logger -p local0.warning -t INITPMF "Waiting for ${SERVER} to register with rpcbind."
			;;
		esac
		${USRBIN}/sleep 10
	done

	# At this point, we've either found the rpc.pmfd service (under the
	# hardcoded program number) registered in rpcbind or we've timed out.
	# Either way, verify that we can or cannot talk to rpc.pmfd with
	# pmfadm -L, in case the rpcinfo call was not accurate.
	# The rpcinfo call could be inaccurate for the following reasons:
	#    1. If rpcinfo reports that rpc.pmfd is registered, we still
	#       may not be able to use pmfadm.  This could occur if the daemon
	#       successfully registered, then subsequently died.
	#    2. The libsecurity code caches the rpcbind lookups so that pmfadm
	#       does not need to go through rpcbind each time.  Thus, if
	#       rpcbind died after the rpc.pmfd registered, we still may be
	#       able to use pmfadm.
	available=no
	${BINDIR}/pmfadm -L 2>/dev/null 1>/dev/null
	if [ $? -eq 0 ]; then
		available=yes
	fi

	# If the service is not available, we need to log an error message
	# and exit.  We log a different error message, depending on whether
	# or not we found the service registered in rpcbind.
	if [ $available = no -a $svcfound = no ]; then
		${USRBIN}/logger -p local0.err -t INITPMF "Error: Timed out waiting for ${SERVER} service to register."		
		exit 1
	fi

	if [ $available = no -a $svcfound = yes ]; then
		${USRBIN}/logger -p local0.err -t INITPMF "Error: ${SERVER} registered in rpcbind, but is not available."
		exit 1
	fi

	# If we're here, we've successfully verified that rpc.pmfd is
	# up and registered in rpcbind, so we can exit normally.

	;;

'stop')
	# Find if rpc.pmfd is running and if yes kill it.
	# This works on a list, but there shouldn't be more than one
	# instance running (see start case).
	pidlist=`${USRBIN}/ps -e | ${USRBIN}/grep ${SERVER} \
		| ${USRBIN}/awk '{print $1}'`
	if [ -n "${pidlist}" ] ; then
	        # kill each process in list
	        for pid in ${pidlist}
	        do
	                kill -TERM ${pid}
			echo "Notice: ${SERVER} is being stopped."
	        done
	fi

	;;
*)
	echo "Usage: /etc/init.d/initpmf { start | stop }"
	;;
esac
