#!/bin/sh
# $Id$
#
# Script:	S30ldom
#
# Description:	Logical Domain (LDom) control script
#
# Platform:	Solaris 10
#
# Author:	High-Availability.Com Ltd
#

#
# standard variables and functions
#
. /opt/HAC/bin/rsf.sh

service=${RSF_SERVICE:-"servicename"}	# edit for pre-1.3 releases
. ${PRODUCT_ETC}/ldom_lookup		# lookup name of LDom to control
PATH=$PATH:/opt/SUNWldm/bin             # add ldom package bin to path

#
# For ldom 1.02 use:
#LDOM_RELEASE="1.02"
#LDOM_NO_FLAGS="-----"
#LDOM_TR_FLAGS="-t---"
#LDOM_NR_FLAGS="-n---"

#
# For ldom 1.2 use:
LDOM_RELEASE="1.2"
LDOM_NO_FLAGS="------"
LDOM_TR_FLAGS="-t----"
LDOM_NR_FLAGS="-n----"

#
# args: <start|stop> [no_of_attempts]
#
script="`basename $0`"
state=$1		# starting or stopping?
attempts=${2:-'1'}	# no of attempts at this action

#
# you may or may not want this test
#
if [ ${attempts} -gt 3 ]; then
	# fail after three goes
	dated_echo "${service}: Too many retries on ${state}, aborting"
	exit ${RSF_ABORT}	# abort code
fi

#
# decide action based on first argument
#
case "${state}" in

'start')
	dated_echo "Dumping current state of ${ldomname} Logical Domain on ${servername}, for ldom ${LDOM_RELEASE}"
	ldm list ${ldomname}
	inactiveldom=false

	# bind LDom if unbound as failover LDom's are usually kept inactive to maximise free VCPU and memory resources
	if match "`ldm list ${ldomname} | grep ${ldomname} | awk '{print $2,$3}'`" "inactive ${LDOM_NO_FLAGS}"; then
		dated_echo "${ldomname} LDom is unbound, binding Logical Domain"
		ldm bind ${ldomname}
		if [ $? -ne 0 ]; then
			dated_echo "*** ERROR - Could not bind ${ldomname} LDom, Logical Domain startup aborted ***"
			ldm list ${ldomname}
			exit ${RSF_ABORT}
		fi
		ldm list ${ldomname}
		inactiveldom=true
	fi

	# rebind LDom if not previously inactive to circumvent LDom bind issue following Control Domain reboot
	if match "`ldm list ${ldomname} | grep ${ldomname} | awk '{print $2,$3}'`" "bound ${LDOM_NO_FLAGS}"; then
		if ${inactiveldom}; then
			: nothing
		else
			dated_echo "${ldomname} LDom is bound, unbinding Logical Domain"
			ldm unbind ${ldomname}
			if [ $? -ne 0 ]; then
				dated_echo "*** ERROR - Could not unbind ${ldomname} LDom, Logical Domain startup aborted ***"
				ldm list ${ldomname}
				exit ${RSF_ABORT}
			fi

			ldm list ${ldomname}
			dated_echo "Sleeping 30 seconds before rebinding ${ldomname} LDom ..."
			sleep 30

			ldm bind ${ldomname} 
			if [ $? -ne 0 ]; then
				dated_echo "*** ERROR - Could not bind ${ldomname} LDom, Logical Domain startup aborted ***"
				ldm list ${ldomname}
				exit ${RSF_ABORT}
			fi
			ldm list ${ldomname}
		fi

		dated_echo "${ldomname} LDom is bound, starting Logical Domain"
		ldm start ${ldomname}
		ldm list ${ldomname}
		while match "`ldm list ${ldomname} | grep ${ldomname} | awk '{print $2,$3}'`" "active ${LDOM_NO_FLAGS}"
		do
			dated_echo "${ldomname} LDom is starting, please wait ..."
			sleep 10
		done
	else
		dated_echo "${ldomname} LDom is not bound, Logical Domain startup aborted"
		ldm list ${ldomname}
		exit ${RSF_UNSAFE}
	fi

	ldm list ${ldomname}
	while match "`ldm list ${ldomname} | grep ${ldomname} | awk '{print $2,$3}'`" "active ${LDOM_TR_FLAGS}"
	do
		dated_echo "${ldomname} LDom is transitioning, please wait ..."
		sleep 10
	done

	dated_echo "${ldomname} LDom is running, although its OS may still be booting"
	dated_echo "Dumping current state of ${ldomname} Logical Domain on ${servername}"
	ldm list ${ldomname}
	;;

'stop')
	dated_echo "Dumping current state of ${ldomname} Logical Domain on ${servername}, for ldom ${LDOM_RELEASE}"
	ldm list ${ldomname}

	# check if LDom has been unable to bind due to insufficient VCPU or memory resources
	if match "`ldm list ${ldomname} | grep ${ldomname} | awk '{print $2,$3}'`" "inactive ${LDOM_NO_FLAGS}"; then
		dated_echo "*** WARNING - ${ldomname} is inactive, was it unable to bind on"
		dated_echo "    service startup due to insufficient VCPU or memory resources"
		dated_echo "    which resulted in an RSF_ABORT being triggered ? ***"
		exit ${RSF_WARN}
	fi

	# check if LDom has already been shut down manually outside of cluster control
	if match "`ldm list ${ldomname} | grep ${ldomname} | awk '{print $2,$3}'`" "bound ${LDOM_NO_FLAGS}"; then
		dated_echo "*** WARNING - ${ldomname} LDom is not active, was it shut down"
		dated_echo "    manually outside of RSF-1 cluster control ? ***"
		if ${failoverldom}; then
			dated_echo "Unbinding ${ldomname} failover LDom on ${servername}"
			ldm unbind  ${ldomname}
		fi
		ldm list ${ldomname}
		exit ${RSF_WARN}}
	fi

	dated_echo "Shutting down ${ldomname} Logical Domain"
	ssh root@${ldomhostname} "uname -a; uptime; who -r; init 5"
	if [ $? -ne 0 ]; then
		dated_echo "SSH connection failure, has ${ldomname} LDom just started ?"
		sleep 20

		dated_echo "Second attempt to shut down ${ldomname} LDom"
		ssh root@${ldomhostname} "uname -a; uptime; who -r; init 5"
		if [ $? -ne 0 ]; then
			dated_echo "Second SSH connection failure, sleeping 30 seconds before third and final attempt ..."
			sleep 30

			dated_echo "Third and final attempt to shut down ${ldomname} LDom"
			ssh root@${ldomhostname} "uname -a; uptime; who -r; init 5"
			if [ $? -ne 0 ]; then
				dated_echo "Third and final SSH connection failure, Logical Domain shutdown aborted"
				ldm list ${ldomname}
				exit ${RSF_ABORT}
			fi
		fi
	fi

	ldm list ${ldomname}
	while match "`ldm list ${ldomname} | grep ${ldomname} | awk '{print $2,$3}'`" "active ${LDOM_NR_FLAGS}"
	do
		dated_echo "${ldomname} LDom is shutting down, please wait ..."
		sleep 20
	done

	if match "`ldm list ${ldomname} | grep ${ldomname} | awk '{print $2,$3}'`" "bound ${LDOM_NO_FLAGS}"; then
		if ${failoverldom}; then
			dated_echo "Unbinding ${ldomname} failover LDom on ${servername}"
			ldm unbind  ${ldomname}
			ldm list ${ldomname}
		fi
	else
		dated_echo "${ldomname} LDom is not bound, Logical Domain shutdown aborted"
		ldm list ${ldomname}
		exit ${RSF_ABORT}
	fi

	dated_echo "${ldomname} Logical Domain has shutdown"
	dated_echo "Dumping current state of ${ldomname} Logical Domain on ${servername}"
	ldm list ${ldomname}
	;;

*)
	echo "Usage: $0 <start|stop>"
	exit ${RSF_WARN}	# warning code
	;;

esac

exit ${RSF_OK}	# OK code (default)
