#!/bin/ksh
#
#pragma	ident	"@(#)nfs_fm_start.sh 1.11 00/10/30"
#Copyright (C) 1997 Sun Microsystems, Inc.
#

##########################################################################
# nfs_fm_start.sh                                                        #
#                                                                        #
# This file contains routines for fault monitoring handling the list     #
# of of logical hosts.                                                   #
# It is invoked by the framework (FM_START) method with the  following   #
# parameters.                                                            #
# <List of Logical Host Names Mastered On this Node>                     #
# <List of Logical Host Names Not Mastered On this Node>                 #
#               -> This may(will) include all the logical host names     #
#               -> for which it may not do the backup service/fault      #
#               -> monitoring.                                           #
# <timeout-Value>                                                        #
##########################################################################

############################################################
# is_node_in_membership                                    #
#                                                          #
# Checks if the node is a cluster member                   #
# returns                                                  #
#	0 - If node is a cluster member.                   #
#	1 - If node is not a cluster member.               #
############################################################
function is_node_in_membership
{
	typeset checknode nodes
	typeset -i j

        checknode=$1

        # convert the current_nodes to current-names
        set -A nodes ${currnodenames}
        j=0
        while [ ! -z ${nodes[j]} ]
        do
                if [ ${nodes[j]} = ${checknode} ]; then
                        return 0;
                fi
                j=j+1;
        done
        return 1;

}

########################################################################
# get_the_monitor_host  <logical-host>  <backup_node>                  # 
# This function                                                        #
#       evaluates ${backup_node} to the backupnode.                    #
########################################################################
function get_the_monitor_host
{
	typeset host loghostccd current_master nodeids default_master

        integer j
        integer anchor
        integer i
	
	host=$1

        # Get the CCD entry for LOGHOST.
	# XXX: should get -f <ccdfile>
        loghostccd=`${CLUSTERBIN}/scccd -f ${ccdfile} ${clustname} \
			LOGHOST query lname ${host}`
	if [ -z ${loghostccd} ]; then
		return
	fi

        # get the current master from CCD.
        current_master=`${CLUSTERBIN}/scccd -f ${ccdfile} ${clustname} \
			LOGHOST_CM query lname ${host} | \
				/usr/bin/awk -F: '{ print $3}'`

	if [ -z ${current_master} ]; then
		#log_info "$pre.4601" "Could Not get LOGHOST_CM for ${host}"
		return
	fi

        # Get nnodelist
        nodeids=`echo ${loghostccd} | /usr/bin/awk -F: '{ print $3}' | \
			 /usr/bin/tr ',' ' '`

        # get default master
        default_master=$(get_first_item ${nodeids})

        # defensive check
        if [ ${current_master} = ${localhost} ]; then
		# error Should not happen
		echo "Error Framework Error for loghost_sync"
		return
        fi

	# 
	# check if default_master is not the current master
	# and if default master is up , then it is the backup host.
	#
	if [ ${default_master} != ${current_master} ]; then
		is_node_in_membership ${default_master}
		rval=$?
		if [ ${rval} = 0 ]; then
			eval $2=${default_master}
			return
		fi
	fi

	# now that we have to get the node which is best suited
	# for backup, get the anchor for the nodeid next to the
	# current master.
	set -A ccdnodes  ${nodeids}
        totalnodes=$(count_items ${nodeids})
        i=0
        while [ ! -z ${ccdnodes[i]} ]
        do
                if [ ${ccdnodes[i]} = ${current_master} ]; then
                        anchor=$i
			break;
                fi
                i=i+1
        done

	i=`expr ${anchor} + 1`
	while [ ${i} != ${anchor} ]
	do
		if [ ${i} -eq ${totalnodes} ]; then
			i=0
		fi
		is_node_in_membership ${ccdnodes[i]}
		rval=$?
		if [ ${rval} = 0 ]; then
			eval $2=${ccdnodes[i]}
			return
		fi
		if [ ${i} = ${anchor} ]; then
			break;
		fi
		i=i+1
	done

	eval $2=""
	return
}

########################################################################
# get_my_backup_logical_list                                           #
#                                                                      #
# This function gets the list of logical host names that this physical #
# host needs to monitor (NFS) from the <List of Logical Host Names Not #
# Mastered On this Node>                                               #
# Environment Variable: BACKUP_LOGICAL_HOSTS                           #
########################################################################
function get_my_backup_list
{
	typeset logical_list i backup_node
        set -a
        logical_list=$1
        set +a
 
        for i in ${logical_list}
        do
		backup_node=""
                get_the_monitor_host ${i} backup_node
		if [ -z ${backup_node} ]; then
		# we do not have the backupnode for this.
			continue;
		fi
		if [ ${backup_node} = ${localhost} ]; then
                        BACKUP_LOGICAL_HOSTS="${BACKUP_LOGICAL_HOSTS} ${i}"
                fi
        done
}



######################################################################
# Main Program of nfs_fm_start                                       #
######################################################################
# include common utililites.
INCLUDE=.
FMBIN=/opt/SUNWcluster/ha/nfs/
${INCLUDE} ${FMBIN}/nfs_common_util

# Initialize the NFS environment required.
initnfsenv

MASTERED_LIST=`echo $1 | /usr/bin/tr ',' ' '`
NOT_MASTERED_LIST=`echo $2 | /usr/bin/tr ',' ' '`
TIMEOUT=$3
BACKUP_LOGICAL_HOSTS=""

ISLOCAL=0
ISREMOTE=1
PROBEONCE=0

CONF_FILE=/etc/opt/SUNWcluster/conf/dflt_sched_class

localhost=$(/bin/uname -n)

# get the list of logical hosts for which this node is
# supposed to be the backup/monitor node.
get_my_backup_list "${NOT_MASTERED_LIST}"

#
# Call nfs_probe_loghost for each logical host.
# This is called thru pmfadm so that this process is monitored.
# XXX: Note pmfadm we should experiment with 
#	-a for all the action scripts.
#	-w/-k for kill with signal.
# pmfadm will return immediately. Hence running in foreground.
#

started=0
# for Mastered List
for i in ${MASTERED_LIST}
do
	${CLUSTERBIN}/pmfadm -c "nfs_probe_${i}" \
		${FMBIN}/nfs_probe_loghost ${i} ${ISLOCAL} \
			${PROBEONCE} ${TIMEOUT} 2>/dev/null
done

# for Backup List
for i in ${BACKUP_LOGICAL_HOSTS}
do
	${CLUSTERBIN}/pmfadm -c "nfs_probe_${i}" \
		${FMBIN}/nfs_probe_loghost ${i} ${ISREMOTE} \
			${PROBEONCE} ${TIMEOUT} 2>/dev/null
done


# We need to restart the local daemon monitor if this node is 
# masters at least one loghost or is backup for at least one loghost. 
# XXX: Cannot start the nfs_probe_local_restart thru pmfadm which
# can invoke daemons which becomes a part of pmfadm, hence gets killed
# when pmfadm -k is issued.
#
if [[ -n ${MASTERED_LIST} || -n ${BACKUP_LOGICAL_HOSTS} ]]; then 
    pids=`/usr/bin/ps -ef | /usr/bin/grep -w nfs_probe_local_restart | \
		/usr/bin/grep -v grep | /usr/bin/awk ' { print $2 } '`

    if [ ! -z ${pids} ]; then
        kill -15 ${pids}
    fi
    DFLT_CLASS=TS
    if [ -f ${CONF_FILE} ] ; then
        DFLT_CLASS=`cat ${CONF_FILE}`
    fi


    /bin/priocntl -c ${DFLT_CLASS} -e ${FMBIN}/nfs_probe_local_restart \
		"${MASTERED_LIST}" "${BACKUP_LOGICAL_HOSTS}" &
fi
exit 0
