#! /usr/bin/ksh
#
# ident       "@(#)cvmreconfig.sh 1.13     02/02/28 SMI"
#
# Copyright 1997-2002 Sun Microsystems, Inc.  All rights reserved.
# Use is subject to license terms.
#

#
# cvmreconfig - reconfiguration program for Veritas Clustered Volume Manager
#
# Input:
#       Environment variables:
#               ${CLUSTNAME}
#               ${CURRSTEP}
#               ${CURRNODES}
#               ${LOCALNODEID}
#               ${RECONF_SCRIPTS}
#
# Action:	Run reconfiguration programs based on current ucmm step
#
# Output:	Return 0 if success
#		Return 1 if failure
#		Return 200 if reconfiguration program result is to be ignored
#

#
# set some flags (NOTE: they are not set implicitly in subroutines)
#
# set -x # print commands as executed
# set -e # execute ERR trap on command error
# set -u # treat unset variables as an error
# set -f # disable file name generation

#
# used for logging with unique name and id.
#
pre="SUNWcvm.cvmreconfig";

#
# set local variables
#
cfgmatch="/usr/cluster/lib/ucmm/cfgmatch";
cvm_cfgfile=/opt/SUNWcvm/etc/cvm.conf;
hatimerun=/usr/cluster/bin/hatimerun;
run_reserve=/usr/cluster/lib/sc/run_reserve;
vxclust=/usr/sbin/vxclust;
vxdctl=/usr/sbin/vxdctl;
vxlicense=/usr/sbin/vxlicense;
LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/opt/SUNWcvm/lib ; export LD_LIBRARY_PATH

#
# Include common files
#
include=.;
RECONF_SCRIPTS=${RECONF_SCRIPTS:-/usr/cluster/lib/ucmm};
${include} ${RECONF_SCRIPTS}/ucmm_reconf.common;

#
#	get the list of non member nodeids
#
get_nonmembers()
{

	fencenodes=""
	for nodeid in ${ALLNODES}; do
		found=0
		for member in ${CURRNODES}; do
			if [ ${nodeid} = ${member} ]; then
				found=1
				break
			fi
		done
		if [ ${found} -ne 1 ]; then
			fencenodes="${fencenodes} ${nodeid}"
		fi
	done

}

#
#	lookup a nodename given a nodeid
#
nodename()
{

	nodeid=$1
	${cfgmatch} cluster.node.${nodeid}.hostname ${cvm_cfgfile}

}

#
#	perform reservations on lowest node id only
#
hw_reserve()
{
	typeset i min_nodeid
	typeset i nodeid

	min_nodeid=${LOCALNODEID}
	for nodeid in ${CURRNODES}; do
		if [ ${nodeid} -lt ${min_nodeid} ]; then
			min_nodeid=${nodeid}
		fi
	done

	if [ ${LOCALNODEID} -eq ${min_nodeid} ]; then
		get_nonmembers
		for nodeid in ${fencenodes}; do
			node=`nodename ${nodeid}`
			scds_syslog -p notice -t "${pre}.hw_reserve" -m \
				"Fencing %s from shared disk devices." "${node}"
			${run_reserve} -c fence_node -f ${node} || return $?
		done
	fi

	return 0

}

#
#	enable failfast on all multinode attached devices
#
enable_ff()
{
	scds_syslog -p notice -t "${pre}.enable_ff" -m \
		"Enabling failfast on all shared disk devices"

	${run_reserve} -c enfailfast_all
	if [ $? -ne 0 ]; then
		scds_syslog -p error -t "${pre}.enable_ff" -m \
			"Error encountered enabling failfast"
		return 1
	fi
	return 0
}

#
#	abort command
#
cvmabort_cmd()
{

	${vxclust} $* || return $?;
	return 0;
	  
}

#
#	return command
#
cvmreturn_cmd()
{

	${vxclust} $* || return $?;
	return 0;

}

#
#	start command
#
cvmstart_cmd()
{

	#
	# initially call run_reserve to set a reservation failfast
	# to take down this node if we become fenced off by another
	#
	enable_ff || return $?;

	#
	# get volume manager configuration daemon mode
	#
	vmstatus=0;
	mode=`${hatimerun} -t 30 ${vxdctl} mode 2>/dev/null` \
		|| vmstatus=$?;
	if [ ${vmstatus} -ne 0 -o -z "${mode}" ]; then
		scds_syslog -p error -t "${pre}.cvmstart_cmd" -m \
			"Could not determine volume configuration daemon mode";
		return 1;
	fi

	#
	# vxdctl mode reports whether vxconfigd is running (if so it's mode).
	#
	case ${mode} in
		*not-running*)	# Abort node if Volume manager is not running.
			scds_syslog -p error -t "${pre}.cvmstart_cmd" -m \
				"Volume configuration daemon not running.";
			return 1;
		;;
	esac;

	${vxclust} $* || return $?;
	return ${vmstatus};

}

#
#	step1 command
#
cvmstep1_cmd()
{

	${vxclust} $* || return $?;	
	return 0;

}

#
#	step2 command
#
cvmstep2_cmd()
{

	${vxclust} $* || return $?;
	return 0;

}

#
#	step3 command
#
cvmstep3_cmd()
{

	${vxclust} $* || return $?;
	return 0;

}

#
#	step4 command
#
cvmstep4_cmd()
{

	${vxclust} $* || return $?;
	return 0;

}

#
#	step6 command
#
cvmstep6_cmd()
{

	scds_syslog -p notice -t "${pre}.cvmstep6_cmd" -m \
		"cluster volume manager shared access mode enabled";
	name=`/bin/uname -n`;
	case `${vxdctl} -c mode 2>/dev/null` in
		*MASTER*) vm_on_node="master"
			scds_syslog -p notice -t "${pre}.cvmstep6_cmd" -m \
			"- node %s vm_on_node is %s" "${name}" "${vm_on_node}";;
		*SLAVE*) vm_on_node="slave"
			scds_syslog -p notice -t "${pre}.cvmstep6_cmd" -m \
			"- node %s vm_on_node is %s" "${name}" "${vm_on_node}";;
	esac;
	return 0;

}

#
#	stop command
#
cvmstop_cmd()
{

	${vxclust} $* || return $?;
	return 0;

}

initcvm()
{

        if [ -d "${vxclust}" -o ! -x "${vxclust}" ]; then
		scds_syslog -p error -t "${pre}.initcvm" -m \
                        "Veritas is not properly installed, %s not found." "${vxclust}"
		exit 1
        fi

	if [ -d "${vxlicense}" -o ! -x "${vxlicense}" ]; then
		scds_syslog -p error -t "${pre}.initcvm" -m \
                        "Veritas is not properly installed, %s not found." "${vxlicense}"
		exit 1
	else
		${vxlicense} -t 68 >/dev/null 2>&1
		if [ $? -ne 0 ]; then
			scds_syslog -p error -t "${pre}.initcvm" -m \
				"%s: Veritas CVM license error." "${vxlicense}"
			exit 1
		fi
	fi

}

#
# turns on tracing for all functions
#
# typeset -tf $(typeset +f)

#
#	main switch statement, execute appropriate reconfiguration step
#
case ${CURRSTEP} in

	cmmstart)
		initcvm;
		cvmstart_cmd	start	${CLUSTNAME} ${cvm_cfgfile};
		status=$?;;

	cmmabort)
		initcvm;
		cvmabort_cmd	abort	${CLUSTNAME} ${cvm_cfgfile};
		status=$?;;

	cmmreturn)
		initcvm;
		cvmreturn_cmd	return	${CLUSTNAME} ${cvm_cfgfile};
		status=$?;;

	cmmstep1)
		hw_reserve;
		status=$?;;

	cmmstep2)
		initcvm;
		cvmstep1_cmd	step1	${CLUSTNAME} ${cvm_cfgfile};
		status=$?;;

	cmmstep3)
		initcvm;
		cvmstep2_cmd	step2	${CLUSTNAME} ${cvm_cfgfile};
		status=$?;;

	cmmstep8)
		initcvm;
		cvmstep3_cmd	step3	${CLUSTNAME} ${cvm_cfgfile};
		status=$?;;

	cmmstep9)
		initcvm;
		cvmstep4_cmd	step4	${CLUSTNAME} ${cvm_cfgfile};
		status=$?;;

	cmmstep10)
		initcvm;
		cvmstep6_cmd;
		status=$?;;

	cmmstop)
		initcvm;
		cvmstop_cmd	stop	${CLUSTNAME} ${cvm_cfgfile};
		status=$?;;

	*)
		initcvm;
		scds_syslog -p error -t "${pre}" -m \
			"Unknown step: %s" "${CURRSTEP}";
		status=200;;

esac;

exit ${status};
