#! /usr/bin/ksh
#
# ident       "@(#)cvmreconfig.sh 1.14     03/04/17 SMI"
#
# Copyright 1997-2003 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}
#               ${STEP_VERSION}
#
# 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;
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 of Step version A
#
cvmstep1_cmd_version_A()
{

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

}

#
#	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

}

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

# Set default step version if step version is empty

[ -z "${STEP_VERSION:-""}" ] &&  STEP_VERSION="B"


log_info "${pre}.cvmreconfig"  "Running step version \"${STEP_VERSION}\" step ${CURRSTEP}";

if [ "${STEP_VERSION}" = "A" ]; then
# Step order for version A

###################################################
# Steps  for version A
###################################################
#
#	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)
		initcvm;
		cvmstep1_cmd_version_A	step1	${CLUSTNAME} ${cvm_cfgfile};
		status=$?;;

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

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

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

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

	cmmstep3 | cmmstep4 | cmmstep5 | cmmstep6 | cmmstep10)
		# No work in these steps
		status=0
		;;
	cmmstop)
		initcvm;
		cvmstop_cmd	stop	${CLUSTNAME} ${cvm_cfgfile};
		status=$?;;

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


esac;
elif [ "${STEP_VERSION}" = "B" ]; then
###################################################
# Steps  for version B
###################################################

#
#	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=$?;;

	cmmstep4 | cmmstep5 | cmmstep6 | cmmstep7)
		# No work in these steps
		status=0
		;;
	*)
		initcvm;
		scds_syslog -p error -t "${pre}" -m \
			"Unknown step: %s" "${CURRSTEP}";
		status=200;;

esac;
else
	scds_syslog -p error -t "${pre}" -m \
		"Unknown step version: %s" "${STEP_VERSION}";
	exit 200;
fi


exit ${status};
