#!/bin/sh
#
#
#    Copyright (c) 1996-2000 Brocade Communications Systems, Inc.
#    All rights reserved.
#
#
# NAME
#      diagstopburnin - terminate burnin run on a blade
# 
# SYNOPSIS
#      diagstopburnin [ --slot slotno ]
# 
# AVAILABILITY
#      admin
# 
# DESCRIPTION
#      This  determines  which PID is running burnin on a blade and
#      terminates that activity. It is  expected  that  the  burnin
#      script  handles  the  logging cleanup. It does not require a
#      reboot to take effect.
# 
# OPTIONS
#      --slot slotno
#                Specify which slot to operate on. If  this  option
#                is  not specifed, all the slots in the switch will
#                be assumed.
# 
# EXAMPLES
#      > diagstopburnin --slot 1
#      No burnin script active on slot 1
#       1 burninErrShow output:
#      0x1eea (fabos): Dec 19 14:42:18
#      Switch: 0, Error DIAG-MANUAL1, 1, " 1 Starting switchess ...
#      Err# 0140042 0100:101:000:001:24:37:
# 
#      0xc84 (fabos): Dec 20 08:57:27
#      Switch: 0, Error DIAG-MANUAL1, 1, " 1 switchess: ABORT   ...
#      Err# 0140042 0100:101:000:000:25:41:
# 
#      0x1b61 (fabos): Feb 07 19:02:28
#      Switch: 0, Error DIAG-MANUAL1, 1, " 1 Starting switchess ...
#      Err# 0140042 0100:101:000:001:26:39:
# 
#      0x47ff (fabos): Feb 07 21:45:36
#      Switch: 0, Error DIAG-MANUAL1, 1, " 1 switchess: ABORT   ...
#      Err# 0140042 0100:101:000:002:26:41:1N
# 
# SEE ALSO
#      diagsetburnin(1d)
# 

#
#
# Load library -- must be first.
#

# Get the PID burnin function send it a TERM signal to set the script
# to a COMPLETE state. Ensure that the script went from ACTIVE to 
# COMPLETE after 30 seconds, or forcably kill the process and place
# abort message in LOG.
#     $1 = slot to operate on
stop_a_slot()
{
	if [ -f /tmp/burnin_PID.$switch.$1 ]
	then
		# if the child process exists, then kill it
		target=`/bin/cat /tmp/burnin_PID.$switch.$1 | /usr/bin/cut -d" " -f1`
		if [ "`/bin/ps -p $target | /bin/grep -w $target`" != "" ]
		then
			if [ $multiBlade = TRUE ]
			then
			    slot_message=" for slot $1"
			else
			    slot_message=""
			fi
			echo "Terminating burnin script$slot_message."
			# Kill a child process
			/bin/kill -TERM $target
			_max_attempts=30
			_attempts=0
			state=`/bin/cat /tmp/burnin_PID.$switch.$1 | /usr/bin/cut -d" " -f2`
			while [ $_attempts -lt $_max_attempts -a "$state" = "ACTIVE" ]
			do
				/bin/echo " Waiting for burnin script$slot_message (PID $target) to stop."
				_attempts=`/usr/bin/expr $_attempts + 1`
			done
			if [ $_attempts -ge $_max_attempts ]
			then
				/bin/echo " Could not kill for burnin script$slot_message (PID $target)."
			else
				state=`/bin/cat /tmp/burnin_PID.$switch.$1 | /usr/bin/cut -d" " -f2`
				if [ "$state" != "ACTIVE" ]
				then
					/bin/echo " Burnin script$slot_message terminated."
				fi
			fi
		else
			/bin/echo "No burnin script to stop$slot_message."
			/bin/echo "$target COMPLETE" > /tmp/burnin_PID.$switch.$1
		fi
	else
	    /bin/echo "No burnin script active$slot_message."
	fi
}

# output the burnin log for he slot
#     $1 = slot to operate on
summary_for_a_slot()
{
	/bin/rm -f /tmp/burnin_PID.$switch.$1
	/bin/echo ""
	if [ $multiBlade = TRUE ]
	then
	    /bin/echo " $1 burninErrShow output:"
	else
	    /bin/echo "burninErrShow output:"
	fi
	/bin/echo ""
	burninErrShow $1
}

# Wait for all slots to terminate their processes. Give it 30 seconds
#     $1 = slot to operate on
wait_for_all_slots_to_die()
{
	# Terminate all burnin activity found on this switch
	for slot in $slots
	do
		if [ -f /tmp/burnin_PID.$switch.$slot ]
		then
			# if the child process exists, then kill it
			target=`/bin/cat /tmp/burnin_PID.$switch.$slot | /usr/bin/cut -d" " -f1`
			if [ "`/bin/ps -p $target | /bin/grep -w $target`" != "" ]
			then
				echo "Terminating burnin script$slot_message."
				# Kill a child process
				/bin/kill -TERM $target
			else
				/bin/echo "No burnin script to stop$slot_message."
				/bin/echo "$target COMPLETE" > /tmp/burnin_PID.$switch.$slot
			fi
		else
		    /bin/echo "No burnin script active$slot_message."
		fi
	done
	# wait for all switches to go to the COMPLETE state
	_max_attempts=30
	_attempts=0
	while [ $_attempts -lt $_max_attempts ]
	do
		_more=FALSE
		for slot in $slots
		do
			if [ -f /tmp/burnin_PID.$switch.$slot ]
			then
				target=`/bin/cat /tmp/burnin_PID.$switch.$slot | /usr/bin/cut -d" " -f1`
				if [ "`/bin/ps -p $target | /bin/grep -w $target`" != "" ]
				then
					/bin/echo " Waiting for burnin script$slot_message(PID $target) to stop."
					_more=TRUE
				fi
			fi
		done
		if [ "$_more" = FALSE ]
		then
			break;
		fi
		_attempts=`/usr/bin/expr $_attempts + 1`
	done
	if [ $_attempts -ge $_max_attempts ]
	then
		for slot in $slots
		do
			if [ -f /tmp/burnin_PID.$switch.$slot ]
			then
				target=`/bin/cat /tmp/burnin_PID.$switch.$slot | /usr/bin/cut -d" " -f1`
				if [ "`/bin/ps -p $target | /bin/grep -w $target`" != "" ]
				then
					/bin/echo " Could not kill for burnin script$slot_message (PID $target)."
				fi
			fi
		done
	fi
	for slot in $slots
	do
		_cmd=`commandPath exec_diag`
		eval $_cmd bogus_test_to_set_led --slot $slot --setled 0 > /dev/null 2>/dev/null &
		if [ $multiBlade = TRUE ]
		then
		    _cmd=`commandPath bladebeacon`
		    $_cmd $slot 0
		else
		    _cmd=`commandPath switchbeacon`
		    $_cmd 0
		fi
	done
	# The last guy running will reset the burnin mode
	# to preserve the logging to serial eeprom
	burninstate=`burninSetLevel -show | \
		/usr/bin/cut -d" " -f4 | \
		/usr/bin/cut -d"." -f1`
	if [ "$burninstate" != "0" ]
	then
		active=TRUE
		_max_attempts=30
		_attempts=0
		while [ $_attempts -lt $_max_attempts -a "$active" = "TRUE" ]
		do
			active=FALSE
			for fil in `/bin/ls /tmp/burnin_PID.$switch.* 2>/dev/null`
			do
				target=`/bin/cat $fil | /usr/bin/cut -d" " -f1`
				if [ ! -z "`/bin/ps -p $target | /bin/grep -w $target`" ]
				then
					active=TRUE
				fi
			done
			if [ "$active" = "FALSE" ]
			then
			    burninSetLevel 0
			    return
			fi
		done
		/bin/echo -n "Processes"
		for fil in `/bin/ls /tmp/burnin_PID.$switch.*`
		do
			target=`/bin/cat $fil | /usr/bin/cut -d" " -f1`
			if [ ! -z "`/bin/ps -p $target | /bin/grep -w $target`" ]
			then
				/bin/echo -n " $target"
			fi
		done
		/bin/echo " still active after $_max_attempts seconds."
		burninSetLevel 0
	fi
}
# Wait for a slot to terminate their processes. Give it 30 seconds
#     $1 = slot to operate on
wait_for_a_slot_to_die()
{
	# The last guy running will reset the burnin mode
	# to preserve the logging to serial eeprom
	burninstate=`burninSetLevel -show | \
		/usr/bin/cut -d" " -f4 | \
		/usr/bin/cut -d"." -f1`
	if [ "$burninstate" != "0" ]
	then
		active=TRUE
		_max_attempts=30
		_attempts=0
		target=`/bin/cat /tmp/burnin_PID.$switch.$1 | /usr/bin/cut -d" " -f1`
		while [ $_attempts -lt $_max_attempts -a "$active" = "TRUE" ]
		do
			active=FALSE
			if [ ! -z "`/bin/ps -p $target | /bin/grep -w $target`" ]
			then
				active=TRUE
			else
				return
			fi
		done
		/bin/echo -n "Process $target still active after $_max_attempts seconds."
	fi
	_cmd=`commandPath exec_diag`
	eval $_cmd bogus_test_to_set_led --slot $1 --setled 0 > /dev/null 2>/dev/null &
	if [ $multiBlade = TRUE ]
	then
	    _cmd=`commandPath bladebeacon`
	    $_cmd $1 0
	else
	    _cmd=`commandPath switchbeacon`
	    $_cmd 0
	fi
}

if [ ! $?FABOSHOME ]
then
	export FABOSHOME=/fabos
fi

home="/fabos/share"
util="diagcommon.sh"
ok=0
for f in "./$util" "$FABOSHOME/share/$util" "$home/$util" ; do
	if [ -r $f ] ; then
		. $f
		ok=1
		break;
	fi
done
if [ $ok -ne 1 ] ; then
	err "Could not locate $util"
	exit 3
fi
multiBlade=`isMultiBlade`
if [ $multiBlade = TRUE ]
then
     syntax="`/bin/basename $0` [ --slot slotno ]"
else
     syntax="`/bin/basename $0` "
fi
#
# Get slot number
#

def_slot=0

if [ $# = 0 ]
then
	multiple_slots=true
else
	s=`/usr/bin/expr "$1" : "[-]*slot"`
	if [ "0" -ne "$s" ] ; then
		x=`/usr/bin/expr "$2" : "\([0-9]\+\)"`
		multiple_slots=false
	fi
	if  [ -z $x ] ; then
	    ans="`isValidSlot $FABOS_SLOTNO`"
	    if [ "$ans" = TRUE ] ; then
	       slot=$FABOS_SLOTNO
	    else
	        slot=$def_slot
	    fi
	else
		ans="`isValidSlot $x`"
		avail=`getAvailSlots`
		if [ "$ans" = TRUE ] ; then
		   slot=$x
		else 
		    err "$x is an invalid slot number"
		    if [ $multiBlade = TRUE ] ; then
		       /bin/echo "Available slots are: $avail."
		    fi
		    exit 4
		fi
	fi
fi

#
# Get switch number
#

def_switch=0

x=`/usr/bin/expr "$FABOS_SWITCHNO" : "\([0-9]\+\)"`
if { [ -z $x ] || [ $x -lt $def_switch ] || [ $x -gt 10 ] ; }
then
	switch=$def_switch
else
	switch=$FABOS_SWITCHNO
fi

#
# Process the slots specified
#
if [ "$multiple_slots" = "false" ]
then
	stop_a_slot $slot
	wait_for_a_slot_to_die $slot
	summary_for_a_slot $slot
else
	slots=`/fabos/sbin/exec_diag diagshow | \
		/bin/grep Slot | \
		/usr/bin/cut -d " " -f2 | \
		/usr/bin/xargs /bin/echo`
	if [ -z "$slots" ] ;
	then
		/bin/echo "diagBurninStop: Nothing to test, please check switch: $switch"
		exit 3 ;
	fi
	if [ $multiBlade = TRUE ]
	then
		slot_message=" on slots: $slots"
		/bin/echo "Stopping burnin on switch: $switch$slot_message"
	else
		slot_message=""
		/bin/echo "Stopping burnin on switch."
	fi

	wait_for_all_slots_to_die
	for slot in $slots
	do
	    summary_for_a_slot $slot
	done
fi
