#!/bin/sh
#
# evms_failover
#       Description: Manages Private containers on shared storage media.
#  	Original Author: Ram Pai (linuxram@us.ibm.com)
#       Support: evms-devel@lists.sourceforge.net
#
# usage: evms_failover <container> {start|stop|status}
#		<container> : name of private container
#
# An example usage in /etc/ha.d/haresources:
#       node1  evms_failover::container1
#

. /etc/ha.d/shellfuncs

usage() {
cat <<-EOT;
	usage: $0 <container> {start|stop|status}
		<container> : name of private container to be imported
EOT
}


#attempt to make it as much LSB compliant as possible
LSB_STATUS_OK=0
LSB_STATUS_STOPPED=3
LSB_EXIT_OK=0
LSB_EXIT_NOTRUNNING=7
LSB_EXIT_GENERIC=1
LSB_EXIT_EINVAL=2
LOCKFILE=/var/lock/evms.lock
CSMDEVNODES=/dev/evms/.nodes
ENGINE_ERR=13

container=$1
if [ -z $container ]; then
	usage
	exit 1
fi



evms_exec()
{
	#modify the container
	ret=$ENGINE_ERR # loop till the command is able to open
	 	#the engine and execute successfully.
	while [ $ret -eq $ENGINE_ERR ]
	do
		#note READWRITE_CRITICAL mode is ***only**** to be used
		#by this failover script.
		evms -m READWRITE_CRITICAL -b <<-EOF >/dev/null 2>&1
			$1
			save
			exit
		EOF
		ret=$?
		if [ $ret -eq $ENGINE_ERR ]; then
		   #sleep random interval upto a max time of 10secs.
		   #this is done to avoid collisions between similar
		   #evms -m READWRITE_CRTIICAL invocations on
		   #other cluster nodes.

		   #Is there a better way to sleep random intervals??
		   #if so please change the below line with the better
		   #version. :)

		   sleep $(($RANDOM % 10))
		fi
	done
	return $ret
}

evms_report_status()
{
	if [ -d $CSMDEVNODES/$1 ]; then
		return 0
	fi
	return 1
}

evms_import()
{
	#modify the container
	node=`uname -n`
	evms_exec "Modify:$1,Node=$node,Type=private"
	return $?
}

evms_discover()
{
	#discover the container
	evms_exec ""
	return $?
}

evms_deport()
{
	#deport the container
	evms_exec "Modify:$1,Type=deported"
	return $?
}


evmsunlock()
{
	rm -f $1
}

evmslock()
{
	pid=`cat $1 2> /dev/null`
	while [  ! -z "$pid" -a  -d /proc/"$pid" ]
	do
		sleep 1
		pid=`cat $1 2> /dev/null`
	done
	echo $$ >  $1
}

cleanexit()
{
	evmsunlock $LOCKFILE
 	exit $1
}

#ensure ccm has a stable membership.
#we dont want to run evms command when the
#membership is unstable.
evmsccm
if [ $? -ne 0 ];then
	exit $LSB_EXIT_NOTRUNNING
fi

trap "cleanexit $LSB_EXIT_GENERIC" SIGINT SIGSEGV SIGQUIT SIGTERM
evmslock $LOCKFILE
ret=$LSB_EXIT_OK


# Look for the 'start', 'stop' or 'status' argument
case "$2" in
#
# START: Import the container
#
start)
	# import the container
	evms_report_status $1
	if [ $? -ne 0 ];then
		evms_import $1 && evms_report_status $1
		if [ $? -eq 0 ]; then
			ret=$LSB_EXIT_OK
		else
			ha_log "WARNING: Container $container failed to $2"
			ret=$LSB_EXIT_NOTRUNNING
		fi
	fi
	;;

#
# STOP: Release the container
#
stop)
	# deport the container
	evms_report_status $1
	if [ $? -eq 0 ];then
		evms_deport $1 && evms_report_status $1
		if [ $? -ne 0 ]; then
			ret=$LSB_EXIT_OK
		else
			ha_log "WARNING: Container $container failed to $2"
			ret=$LSB_EXIT_GENERIC
		fi
	fi
	;;

#
# STATUS: is the container already imported?
#
status)
	#  is the container owned by us?
	evms_report_status $1
	if [ $? -eq 0 ] ; then
		ha_log "Container $container is already running ( OK )"
		echo  "Container $container is already running ( OK )"
		ret=$LSB_STATUS_OK
	else
		ret=$LSB_STATUS_STOPPED
	fi
	;;

#
# STARTSPECIAL: is called only by the evmd daemon.
#
startspecial)
	evms_discover
	if [ $? -eq 0 ] ; then
		ret=$LSB_STATUS_OK
	else
		ret=$LSB_EXIT_GENERIC
	fi
	;;

*)
	echo "This script should be run with a second argument of "
	echo " 'start', 'stop', or 'status' "
	usage
	ret=$LSB_EXIT_EINVAL
	;;
esac

# If you got to this point, chances are everything is O.K.
cleanexit $ret
