#! /usr/bin/sh
#
#ident	"@(#)hammer.sh	1.12	04/12/15 SMI"
#
# Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
# Use is subject to license terms.
#
####
#### Hammers a driver instance in an infinite loop. 
#### Input : 	Driver - Name of driver
####		Instance - Instance of driver
#### 		Remote - Name or IP of remote machine
####		[Iter] - Number of times to repeat (infinite if not supplied.)


usage() {
	cat <<EOF
Usage:		$0 driver remote_machine
	OR	$0 driver instance remote_machine
	OR	$0 driver instance remote_machine times

	For any argument omitted from the above forms, the defaults are
	as follows:
		instance	: 0
		times		: Infinity (-1)

EOF

}

multiportfile=/tmp/multiportfile #file name to store multiport info

#### Check if the correct number of arguments have been sent
drv=""
inst=0
remote=""
times=-1
case $# in
2)
	drv="$1"
	remote="$2"
;;

3)
	drv="$1"
	inst="$2"
	remote="$3"
;;

4)
	drv="$1"
	inst="$2"
	remote="$3"
	times="$4"
;;

*)
	usage
	echo "!ERROR: Usage error."
	exit 1
;;
esac

if [ -f /etc/hostname.$drv$inst ]; then
	localhost=`cat /etc/hostname.$drv$inst`
else
	echo "!ERROR: There's no /etc/hostname.$drv$inst. Please create one."
	exit 1
fi

# Set up
trap "echo [Cleaning up]
      ifconfig $drv$inst plumb;
      ifconfig $drv$inst inet $localhost netmask +;
      ifconfig $drv$inst broadcast + -trailers up;
      echo '$drv$inst Up.';
      exit 0" 0 2 9 15

if [ $times -eq -1 ]
then
	sleep $RUNTIME &
	sleepid=$!
fi


echo "Starting to Hammer $drv$inst $times times."
echo "Using localhost: $localhost."
i=0

while [ 1 -eq 1 ]
do
	echo "Bringing $drv$inst Up - plumb."
	/sbin/ifconfig $drv$inst plumb
        if [ $? -ne 0 ]   
        then
               #retry one time due to e1000g may get device busy error sometimes.
                sleep 10
                /sbin/ifconfig $drv$inst plumb
                if [ $? -ne 0 ]
                then
                        echo "ERROR: Unable to plumb $drv$inst."
                        exit 1
                fi
        fi
        echo "Assigning ip address."
	/sbin/ifconfig $drv$inst  inet $localhost netmask + broadcast +  -trailers 
	if [ $? -ne 0 ]
	then
		echo "ERROR: Unable to assign ip-address for $drv$inst. "
		exit 1
	fi
        echo "Bringing $drv$inst up."
        /sbin/ifconfig $drv$inst up & 
        ping $remote 
        if [ $? -ne 0 ]
        then
               echo "WARNING: Could not bring $drv$inst up."
	       echo "Retrying to bring $drv$inst up."
               sleep 10
	       /sbin/ifconfig $drv$inst unplumb
	       /sbin/ifconfig $drv$inst plumb
	       /sbin/ifconfig $drv$inst  inet $localhost netmask + broadcast +  -trailers up 
               if [ $? -ne 0 ]
               then
		   echo "ERROR: Retry failed."
		   exit 1
               fi
        fi


	ping $remote

	if [ $? -ne 0 ]
	then
		echo "!ERROR: Ping failed."
	 	exit 1
	fi

	echo "Bringing $drv$inst Down."

	/sbin/ifconfig $drv$inst down 
	if [ $? -ne 0 ]
	then
		echo "WARNING: Failed to bring $drv$inst down."
	fi

        echo "Bringing $drv$inst unplumb."

	/sbin/ifconfig $drv$inst unplumb
	if [ $? -ne 0 ]
	then
		echo "ERROR: Unable to unplumb $drv$inst."
		exit 1
	fi
	
	#### Check if there are any instances of the driver left
	#### If there are then if module connot be unloaded!!!
        
        sleep 10
	
	if [ ! -s $multiportfile ] #unload module lead error for multiport certification
	then
		if [ 0 -eq `ifconfig -a | grep -c $drv` ] 
		then
			echo "Trying to unload module: $drv."
	
			modnum=`modinfo | grep -w $drv | awk '{printf "%s",$1}'`
			if [ -n "$modnum" ]
			then
			
				modunload -i $modnum 
				if [ $? -eq 0 ]; then
					echo "Unload module succeed."
				else
					echo "Unload module failed."
				fi
		
				modnum=`modinfo | grep -w $drv`
			
				if [ -n "$modnum" ]
				then 
					echo "ERROR: Could not unload $drv$inst."
					echo "Printing ifconfig -a."
					ifconfig -a
					echo "Modnum is $modnum."
				else
					echo "$modnum $drv$inst module unloaded."
				fi
			fi
		else
			echo "Can't unload driver - some instance still busy."
		fi
	fi


	#### Check if hammering should finish
        if [ $times -ne -1 ]
        then
                i=`expr $i + 1`
                echo "$i"
                if [ $i -ge $times ]
                then
			ifconfig $drv$inst plumb
			ifconfig $drv$inst inet $localhost netmask + broadcast + -trailers up
			echo "$drv Up."
                        exit 0
                fi
	else
		if [ ! -d /proc/$sleepid ]
		then
			ifconfig $drv$inst plumb
			ifconfig $drv$inst inet $localhost netmask + broadcast + -trailers up
			echo "$drv Up."
			echo "!PASS: Finished Hammering."
			exit 0
		fi
	fi
done

echo "!ERROR: Abnormal exit while hammering $drv$inst."
exit 1
