#! /usr/bin/sh
#
# ident	"@(#)sms.sh	1.34	03/01/27 SMI"
#
# Copyright (c) 1999-2001 by Sun Microsystems, Inc.
# All rights reserved.
#
# Start-up script to start-up and shut-down the sms software. The 'start'
# option starts a background process which starts and monitors the ssd. The ssd
# in turn starts and monitors all the sms daemons and servers. The 'stop'
# option kills the background loop that starts and monitors the ssd and then
# signals the ssd to shut itself and all the sms daemons and servers down.
#
# exit codes
# --------------------------------------------------------------------------
# 0 - operation was successful
# 1 - environment file missing or not readable
# 2 - usage error
# 3 - can not "start" sms, it is already running
# 4 - can not "stop" sms, it is not running
# 5 - SSC not yet configured as "MAIN" or "SPARE"
# 6 - smsconfig has not been run

PATH=/sbin:/usr/sbin:/usr/bin; export PATH

#
# GLOBAL DEFINITIONS
#
commandpath="$0"
command=`/usr/bin/basename $0`
sub_command=$1
SMS_VAR=/var/opt/SUNWSMS
SMS_ETC=/etc/opt/SUNWSMS
SMS_ENV=$SMS_ETC/startup/sms_env.sh
SSD_CNFG=$SMS_ETC/startup/ssd_start
SSD_LOOP=$SMS_VAR/data/ssd_loop.pid
NDD=/usr/sbin/ndd
SSD_WAIT_FILE=/tmp/.wait_daemons
SSD_TIME_FILE=/tmp/.time_daemons
SECURE_SSH=

PRIVATE_REMOTEHOST=/var/opt/SUNWSMS/data/.remotesc

############################################################################
#
# usage_error
#
# Prints a 'sms' script usage error message.
#
############################################################################
usage_error ()
{
	echo `gettext "Usage: $command { start | stop }"`
}


############################################################################
#
# process_exists
#
# Returns 0 if the process exists, 1 if it does not.
#
# $1 - name of process to look for (must be short name as in ps)
# $2 - owner of process (defaults to root)
#
############################################################################
process_exists ()
{
	/usr/bin/pgrep -x -U${2:-root} $1 >/dev/null 2>&1
}

############################################################################
#
# 4508204: fomd shouldn't use R* services
#
# checkSecureSH()
#
# This method checks to see if security shell is installed and configured 
# on the system.
#
# If ssh is enabled, its' path is stored in $SECURE_SSH.
#
# Arg:
# $1	- remote SC I2 IP address
#
# Return:
# 0	- ssh is enabled.
# 1	- ssh is not enabled.
#
############################################################################
checkSecureSH()
{
	remoteSCIp=$1
	echo "Checking for ssh(1)... "

	#
	# Give some time for the prngd to start
	#
	# Wait for sshd to fully start
	#
	pgrep -f sshd >/dev/null 2>&1
	if [ "$?" -ne 0 ]; then
		sleep 10
	fi

	if [ -f /opt/SUNWSMS/bin/ssh -o -h /opt/SUNWSMS/bin/ssh ] ; then


		checkSSHEnabled "/opt/SUNWSMS/bin/ssh" $remoteSCIp
		if [ "$?" -eq 0 ]; then
			SECURE_SSH=/opt/SUNWSMS/bin/ssh
			return 0
		else	
			return 1
		fi	


	elif [ -f /usr/bin/ssh -o -h /usr/bin/ssh ]; then

		checkSSHEnabled "/usr/bin/ssh" $remoteSCIp
		if [ "$?" -eq 0 ]; then
			SECURE_SSH=/usr/bin/ssh
			return 0
		else	
			return 1
		fi	

	elif [ -f /opt/OBSDssh/bin/ssh -o -h /opt/OBSDssh/bin/ssh ]; then

		checkSSHEnabled "/usr/bin/ssh" $remoteSCIp
		if [ "$?" -eq 0 ]; then
			SECURE_SSH=/usr/bin/ssh
			return 0
		else	
			return 1
		fi	

	else
		echo "ssh(1) is not installed on the system"
		return 1
	fi

}
##################################################################
#
# checkSSHEnabled()
#
# This method checks to see if ssh is enabled on the system.
#
# Args:
# $1	- ssh path
# $2 	- remote SC I2 IP address
#
# Return:
# 0	- ssh is enabled
# 1	- ssh is not enabled.
#
##################################################################
checkSSHEnabled()
{
	sshPath=$1	
	ipAdd=$2
	
	#
	# $sshPath should not have zero size.
	#
	if [ ! -s ${sshPath} ]; then
		return 1
	fi

	rm /tmp/.sshout >/dev/null 2>&1

	echo "Password/passphrase authentication can be ignored."

	#
	# Issue a remote command "touch /tmp" using ssh.
	# 

	$sshPath $ipAdd touch /tmp >/tmp/.sshout 2>&1 &

	#
	# Get the ssh process ID.
	#
	sshPid=$!

	#
	# Added 1 sec delay so that it can capture the error message.
	#
	sleep 1
	
	#
	# In S8, based on the experiment, it takes ~15 sec 
	# for ssh to be fully functioning after sshd started, 
	# let's wait for 15 sec before we conclude whether 
	# ssh is hanging or not.
	#
	i=0
	while [ "$i" -lt 15 ]
	do
		#
		# Check if there is error message generated.
		#
		# When the sshd server is disabled, the ssh
		# connection request will be timeout with
		# a error message from ssh.
		#
		if [ -s "/tmp/.sshout" ];then
			break
		fi

		#
		# When gets here, it means no error message found.
		# Check to see if sshPid exists. If ps can't
		# find the sshPid, it means the ssh exits with
		# no error.
		#
		ps -p $sshPid > /dev/null
		if [ $? -ne 0 ]; then
			return 0
		fi

		sleep 1
		i=`expr $i + 1`
		continue
	done

	#
	# The remote command is still running, we
	# can saftly assume that ssh is not enabled.
	# Let's kill the command.
	#  
	ps -p $sshPid > /dev/null
	if [ $? -eq 0 ]; then
		kill -15 $sshPid >/dev/null 2>&1
		sleep 2
		kill -9 $sshPid >/dev/null 2>&1
	fi
	return 1
		
}

############################################################################
#
# 4490854 PCI bridge secondary clocks sometimes come up disabled from power on
#
# check_sscpost_status()
#
# This function checks the SSCPOST test results for a specific failure which
# indicates that the PCI secondary clocks have failed.  If they have, then the
# appropriate action is taken otherwise the function just returns.
#
# Returns 0 for success, 1 for failure
#
############################################################################
check_sscpost_status()
{
	date_format="date +'%b %e %T %Y'"
	localschost=`/bin/hostname`
	log_format="$localschost sms[]: [NOTICE check_sscpost_status]"
	man_config=$SMS_ETC/config/MAN.cf
	flag_dir=$SMS_VAR/data/.failover/local
	platform_log=/var/opt/SUNWSMS/adm/platform/messages
	flag_file=.scpost_status
	failed_status_string="Failed"
	scpost_status="FAILED"
	i2sc0host=`egrep SC0-I2 $man_config | egrep -v "^#" | awk '{print $3}'`
	i2sc1host=`egrep SC1-I2 $man_config | egrep -v "^#" | awk '{print $3}'`
	remoteI2host=$i2sc1host
	i2sc0hostIp=`egrep SC0-I2 $man_config | egrep -v "^#" | awk '{print $4}'`
	i2sc1hostIp=`egrep SC1-I2 $man_config | egrep -v "^#" | awk '{print $4}'`
	remoteI2hostIp=$i2sc1hostIp
	eaddr=
	rstatus=0
	shStatus=0

	#
	# get SSCPOST status from prtconf
	#
	prtconf -pv | grep ssc-post-results | cut -d':' -f2- | \
				egrep "$failed_status_string" >/dev/null 2>&1
	if [ "$?" -ne 0 ]; then
		return 0
	fi

	#
	# 4622245: Not all fomd resets attempt a graceful shutdown first 
	#
	# Found the string, return status is set to  0, otherwise, set to 1.
	#
	# If sscpost fails due to the bridge failure, one of these two bridge 
	# failure strings will be returned by SSCPOST.
	#
	pciBridgeFailure_1="Test 2: RIO EBus2 Tests"
	pciBridgeFailure_2="Test 1: CB PCI Search/Probe"

	prtconf -pv | grep ssc-post-results | cut -d':' -f2- | \
		egrep "$pciBridgeFailure_1|$pciBridgeFailure_2" >/dev/null 2>&1
	
	#
	# $scpost_status is used to store the type of SSCPOST failure and
	# report to the remote SC.
	#
	# If either $pciBridgeFailure_1 or $pciBridgeFailure_2 is found
	# from ssc-post-result, then set "PCI_BRIDGE FAILED" to $scpost_status
	# Any other SSCPOST failure, use default value("Failed") set in 
	# $scpost_status. 
	#  
	if [ "$?" -eq 0 ]; then
		scpost_status="PCI_BRIDGE FAILED"
	fi		

	echo "`eval $date_format` $log_format Attempting to transfer SSCPOST results to other SC" >>$platform_log

	#
	# 4508204: fomd shouldn't use R* services 
	# 
	# 4750572: sms startup fails to correctly determine
	#          remote SC and requires .rhosts/.shosts
	#
	if [ ! -f $PRIVATE_REMOTEHOST ]; then
		return 1
	fi

	egrep $i2sc0host $PRIVATE_REMOTEHOST  >/dev/null 2>&1


	if [ "$?" -eq 0 ]; then
		remoteI2hostIp=$i2sc0hostIp
		remoteI2host=$i2sc0host
	fi

	#
	# test for scman1 (I2 net) connectivity & create file
	#
 	# We need to ifconfig hme1 up using parameters from /etc/hostname.scman1
	#
	if [ -f "/etc/hostname.scman1" ]; then
		eaddr=`ifconfig scman1 | egrep ether | cut -d" "  -f2`
		ifconfig scman1 down
		ifconfig hme1 plumb `cat /etc/hostname.scman1` broadcast +
		ifconfig hme1 ether $eaddr
	elif [ -f "/etc/hostname6.scman1" ]; then
		ifconfig scman1 inet6 down
		ifconfig hme1 inet6 plumb
		ifconfig hme1 inet6 `cat /etc/hostname6.scman1`
	else
		return 1
	fi
	if [ "$?" -ne 0 ]; then
		echo "`eval $date_format` $log_format Unable to ifconfig hme1" \
								>>$platform_log
		if [ -f "/etc/hostname.scman1" ]; then
			ifconfig hme1 unplumb
			ifconfig scman1 up
		elif [ -f "/etc/hostname6.scman1" ]; then
			ifconfig hme1 inet6 unplumb
			ifconfig scman1 inet6 up
		else
			return 1
		fi
		echo "`eval $date_format` $log_format Unable to transfer " \
				"SSCPOST results, exiting" >>$platform_log

		return 1
	fi

	echo "`eval $date_format` $log_format hme1 successfully ifconfig'd" \
								>> $platform_log

	#
	# 4508204: fomd shouldn't use R* services 
	# 
	checkSecureSH $remoteI2hostIp

	#
	# 4755000: sms startup script does not fully handle 
	#          return code 255 from ssh.	
	#
	if [ "$?" -eq 0 ]; then
		remoteSH=$SECURE_SSH
		echo `gettext "Using $remoteSH......"`
	else
		remoteSH="rsh"
		echo `gettext "Attempting to use rsh(1)......"`
	fi

	$remoteSH -n $remoteI2hostIp sh -c "'/bin/echo $scpost_status' >\
			 $flag_dir/$flag_file" > /tmp/.sh_startup 2>&1 
	shStatus=$?
	sleep 1

	if [ -s "/tmp/.sh_startup" ]; then
		echo "`eval $date_format` $log_format Unable to transfer " \
				"SSCPOST results, exiting" >>$platform_log
		rstatus=1
	 
	elif [ "$shStatus" -eq 0 ] || [ "$shStatus" -eq 255 ]; then
		echo "`eval $date_format` $log_format Completed transfer " \
			"of SSCPOST results to other SC" >>$platform_log
		rstatus=0
	else
		echo "`eval $date_format` $log_format Unable to transfer " \
				"SSCPOST results, exiting" >>$platform_log
		rstatus=1
	fi

	
	if [ -f "/etc/hostname.scman1" ]; then
		ifconfig hme1 unplumb
		ifconfig scman1 up
	elif [ -f "/etc/hostname6.scman1" ]; then
		ifconfig hme1 inet6 unplumb
		ifconfig scman1 inet6 up
	else
		return 1
	fi
	
	#
	# 4622245: Not all fomd resets attempt a graceful shutdown first
	#
	# Flush all transactions out of the log  and  write  the
	# transactions to the master file system. It should apply to all 
	# mounted, UFS type  file  systems.  
	#
	/usr/sbin/lockfs -fa
	/usr/sbin/sync

	return $rstatus
}


############################################################################
#
# man_set_ipparams
#
# Set kernel IP tunable parameters required for MAN network security.
#
############################################################################
man_set_ipparams()
{
    for IPVAR in ip_forwarding ip6_forwarding \
	ip_respond_to_echo_broadcast ip6_respond_to_echo_multicast
    do
	$NDD -set /dev/ip $IPVAR 0 >/dev/null 2>&1
    done
}


############################################################################
#
# start_ssd_monitor
#
# Start the background script to monitor and restart the ssd when and
# if it dies.
#
############################################################################
start_ssd_monitor()
{
	# Make some key variables accessible to the monitor script.
	export SSD_LOOP;
	export SSD_OPTIONS;

	# Spawn off the monitor script.
	sh -c 'echo $$ >$SSD_LOOP;
	while true; do
		if [ -s "$SSD_LOOP" ]; then
			PID=`cat $SSD_LOOP`;
			if [ "$$" -ne "$PID" ]; then
				# The PID is not equal to ours, exit.
				exit 1;
			fi
		else
			# The PID file is either missing or empty.
			# In either case, exit.
			exit 1;
		fi
		# If the ssd is not running then start it.
		/usr/bin/pgrep -x -U0 ssd >/dev/null 2>&1;
		if [ "$?" -ne 0 ]; then
			ssd $SSD_OPTIONS;
		fi
		sleep 3;
	done' >/dev/null 2>&1 &
}

############################################################################
#
# sms_start
#
# Starts-up all of sms by starting the ssd.
#
############################################################################
sms_start ()
{
	# initialize ecode to zero
	ecode=0

	# Check if the ssd(1M) monitor script PID file is present.
	if [ -s "$SSD_LOOP" ]; then
		# It's present, make sure that this isn't a stale file.
		if /usr/bin/kill -0 "`cat $SSD_LOOP`" >/dev/null 2>&1; then
			# The monitor script PID file is present and contains
			# a valid PID. SMS is running. Set the exit code to
			# indicate this.
			ecode=3
		else
			# The monitor script PID file is no good. Clean it up.
			rm -f $SSD_LOOP >/dev/null 2>&1

			# If the ssd(1M) is present then the script died or
			# was killed, but SMS should be up and running.
			# Restart the monitor script and set the exit
			# code to indicate that SMS is already running.
			/usr/bin/pgrep -x -U0 ssd >/dev/null 2>&1
			if [ "$?" -eq 0 ]; then
				start_ssd_monitor
				ecode=3
			fi
		fi

	# Make sure that the monitor script PID file isn't just missing.
	# Check for the existence of ssd(1M)
	else
		# If ssd(1M) is present than start the monitor script and
		# set the exit code to indicate that SMS is already running.
		/usr/bin/pgrep -x -U0 ssd >/dev/null 2>&1
		if [ "$?" -eq 0 ]; then
			start_ssd_monitor
			ecode=3
		fi
	fi

	if [ "$ecode" -eq 3 ]; then
		# print message to indicate that sms is already running
		echo `gettext "$command: SMS is already running"`
		exit $ecode
	fi

	grep -v "^\#" $SMS_ETC/config/MAN.cf > /dev/null 2>&1
	if [ "$?" -ne 0 ]; then
		# indicate an error
		ecode=6

		# print message to indicate smsconfig not yet run
		echo `gettext "$command: smsconfig(1M) has not been run. Unable to start sms services."`
		exit $ecode
	fi

	# setup the core size limit and name
	coresize=`grep \^" " $SMS_ETC/config/mld_tuning | grep core_max_size | \
	cut -d "=" -f 2`
	if [ "$?" -eq 0 ]; then
		if [ -x "/usr/bin/ulimit" ]; then
			ulimit -HSc $coresize >/dev/null 2>&1
		fi
	fi
	if [ -x "/usr/bin/coreadm" ]; then
		/usr/bin/coreadm -p /var/tmp/sms_core.%f.new $$ >/dev/null 2>&1
	fi

	# start the mld prior to starting the ssd so that the ssd can have
	# logging capabilities. Once the ssd starts it will connect with
	# this running mld and begin monitoring it.
	process_exists mld
	if [ "$?" -ne 0 ]; then
		# get the command line options from the ssd_start config file
		MLD_CNFG=`grep '^[ 	]*mld[ 	]*:' $SSD_CNFG 2>/dev/null`
		MLD_OPTS=`expr "$MLD_CNFG" : '^[^:]*:\([^:]*\):.*$'`

		# start the mld
		mld ${MLD_OPTS} >/dev/null 2>&1;
	fi

	# make sure we can execute the ssd
	ssd_path=`which ssd`
	if [ ! -x "$ssd_path" ]; then
        	# indicate an error
        	ecode=3

        	# print message to indicate that sms is already running
        	echo `gettext "$command: Unable to execute ssd"`

        	exit $ecode
	fi

	# Remove the shutdown indicator files from any previous shutdowns.
	rm -f "$SSD_WAIT_FILE" >/dev/null 2>&1;
	rm -f "$SSD_TIME_FILE" >/dev/null 2>&1;

	SSD_START_MSG1="SMS software start-up initiated"
	SSD_START_MSG2="SC POST results:"`/usr/sbin/prtconf -pv | grep ssc-post-results | cut -d':' -f2-`
	ssd $SSD_OPTIONS -i "$SSD_START_MSG1" -i"$SSD_START_MSG2"
	# start the background loop to monitor and start the ssd when and
	# if it dies.
	start_ssd_monitor

	exit $ecode
}

############################################################################
#
# sms_stop
#
# Terminates all of sms by signaling the ssd.
#
############################################################################
sms_stop ()
{
	# initialize ecode to zero
	ecode=0

	# Check if the ssd(1M) monitor script PID file is present.
	if [ -s "$SSD_LOOP" ]; then
		# It's present, make sure that this isn't a stale file.
		if /usr/bin/kill -0 "`cat $SSD_LOOP`" >/dev/null 2>&1; then
			# The monitor script PID file is present and contains
			# a valid PID. SMS is running. Kill the monitor
			# script and remove the PID file.
			/usr/bin/kill `cat $SSD_LOOP` >/dev/null 2>&1
			rm -f $SSD_LOOP >/dev/null 2>&1
		else
			# The monitor script PID file is no good. Clean it up.
			rm -f $SSD_LOOP >/dev/null 2>&1

			# If the ssd(1M) is not present then SMS was stopped,
			# but the PID file wasn't cleaned up. Set the exit
			# code to indicate that SMS is not running and
			# continue.
			/usr/bin/pgrep -x -U0 ssd >/dev/null 2>&1
			if [ "$?" -ne 0 ]; then
				ecode=4
			fi
		fi

	# Make sure that the monitor script PID file isn't just missing.
	# Check for the existence of ssd(1M)
	else
		# If the ssd(1M) is not present then SMS was stopped.
		# Set the exit code to indicate that SMS is not running
		# and continue.
		/usr/bin/pgrep -x -U0 ssd >/dev/null 2>&1
		if [ "$?" -ne 0 ]; then
			ecode=4
		fi
	fi

	if [ "$ecode" -eq 4 ]; then
		# Inform user that SMS is not running.
		echo `gettext "$command: SMS is not running"`
	fi

	# determine from the ssd_start file the longest we should have to
	# wait for all the daemons to shut down
	SHUTDOWN_MAX=`/usr/bin/awk -F:< $SSD_CNFG '
	BEGIN                                     { shutdown_max = 0 }
	$0 ~ /^[ \t]*[^#]/ && $8 > shutdown_max   { shutdown_max = $8 }
	END                                       { print shutdown_max }'`

	# build list of args to use with pgrep that contains all the daemon and
	# server names and the user ids that they run under
	SIG_TARGETS=`awk -F:< $SSD_CNFG '
       BEGIN { i=0
               uid_list="-Uroot"
               comp_names="ssd"
             }
       $0 ~ /^[ \t]*[^#]/ { split($9,temp," \t")
                            uid_list = sprintf "%s,%s", uid_list, temp[1]
                            split($1,temp," \t")
                            comp_names = sprintf "%s|%s", comp_names, temp[1]
                          }
       END { targets = sprintf "%s \"%s\"", uid_list, comp_names
             print targets
           }'`

	# The default shutdown behavior is to time the daemons.
	HANDLE_SHUTDOWN="$SSD_TIME_FILE";

	# if the ssd exists, use it to shut-down sms
	if process_exists ssd; then
		# set flag to indicate that the ssd was used to shutdown sms
		SSD_USED=0;

		# signal the ssd to shut-down itself and all of sms
		/usr/bin/pkill -USR2 -x -U0 ssd >/dev/null 2>&1;

		# Wait until ssd indicates how to handle this shutdown (or
		# ssd dies) by creating one of two indicator files.
		while [ ! -f "$SSD_WAIT_FILE" ] && [ ! -f "$SSD_TIME_FILE" ]; do
			# If ssd is still around then sleep and try again.
			if process_exists ssd; then
				sleep 1;
			# If ssd has left us, then stop waiting.
			else
				break;
			fi
		done

		# Setup indication of how to handle this shutdown.
		if [ -f "$SSD_WAIT_FILE" ]; then
			HANDLE_SHUTDOWN="$SSD_WAIT_FILE";
		elif [ -f "$SSD_TIME_FILE" ]; then
			HANDLE_SHUTDOWN="$SSD_TIME_FILE";
		fi

	# if the ssd doesn't exist, then signal the SW components manually
	else
		# signal the daemons and servers based on their user ids
		/usr/bin/pkill -TERM -x $SIG_TARGETS >/dev/null 2>&1
	fi

	# If ssd has indicated that we should time this shutdown (or this
	# is not the case when ssd is going to orchestrate shutdown and
	# power off of all domains and boards).
	if [ "$HANDLE_SHUTDOWN" = "$SSD_TIME_FILE" ]; then
		# sleep upto SHUTDOWN_MAX seconds while waiting for the daemons to
		# shutdown
		SECONDS=$SHUTDOWN_MAX
		while [ "$SECONDS" -ne 0 ]; do
			# check to see if any of the daemons are still running
			/usr/bin/pgrep -x $SIG_TARGETS >/dev/null 2>&1
			DAEMONS_EXIST=$?

			# return if all the daemons have terminated
			if [ "$DAEMONS_EXIST" -ne 0 ]; then
				return 0
			fi

			# sleep for a second
			sleep 1

			# decrement the number of seconds left to sleep
			SECONDS=`expr $SECONDS - 1`
		done

		# if the ssd was used to shutdown the other daemons
		if [ "$SSD_USED" ]; then
			# if the ssd is running at this point it must be sick, kill it
			/usr/bin/pkill -KILL -x -U0 ssd >/dev/null 2>&1

			# if the daemons didn't respond to the SIGTERM we can not be
			# sure if it is because the ssd was sick or the daemons are
			# sick. signal the daemons manually and wait for shutdown
			if [ "$DAEMONS_EXIST" -eq 0 ]; then
				/usr/bin/pkill -TERM -x $SIG_TARGETS >/dev/null 2>&1

				# sleep upto SHUTDOWN_MAX seconds while waiting for
				# the daemons to shutdown
				SECONDS=$SHUTDOWN_MAX
				while [ "$SECONDS" -ne 0 ]; do
					# check to see if any of the daemons are
					# still running
					/usr/bin/pgrep -x $SIG_TARGETS >/dev/null 2>&1
					DAEMONS_EXIST=$?

					# return if all the daemons have terminated
					if [ "$DAEMONS_EXIST" -ne 0 ]; then
						return 0
					fi

					# sleep for a second
					sleep 1

					# decrement the number of seconds left to sleep
					SECONDS=`expr $SECONDS - 1`
				done
			fi
		fi

		# at this point regardless of how the daemons were signaled (via the
		# ssd or manually) we can be sure that they received the SIGTERM and
		# were given time to shutdown. if they still persist, kill them
		/usr/bin/pkill -KILL -x $SIG_TARGETS >/dev/null 2>&1

	# Otherwise, give ssd(1M) all the time it needs to orchestrate the
	# graceful shutdown of all active domains, the power off of all boards
	# and the shutdown of SMS.
	else
		echo `gettext "$command: SMS is being shutdown on the only present and powered on SC. All"`
		echo `gettext "domains are being shutdown gracefully and all boards are being powered off..."`

		# Wait on the ssd to shutdown.
		# Wait on the ssd to shutdown.
		SSD_PID=`/usr/bin/pgrep -x -U0 ssd 2>/dev/null`;
		/usr/bin/pwait $SSD_PID >/dev/null 2>&1;

		# At this point nothing should be running. Wait everything to
		# be safe. 
		/usr/bin/pkill -KILL -x $SIG_TARGETS >/dev/null 2>&1
	fi

	exit $ecode
}


############################################################################
#
# Execution begins here.
#
############################################################################

# Make these two variables available to ssd(1M). The names of these
# two environment variables can not be changed w/out a corresponding
# change to ssd(1M). The files pointed to however, can be.
export SSD_WAIT_FILE;
export SSD_TIME_FILE;

#
# 4490854 PCI bridge secondary clocks sometimes come up disabled from
#	  power on
#
#
# 4622245: Not all fomd resets attempt a graceful shutdown first
# We always report the SSCPOST failure to the remote SC, so 
# the env variable SMS_4490854 is no longer required.
#  
check_sscpost_status

# Bugid 4647053
# Added error messages, lack of error message was misleading and made
# SC and driver failures difficult to diagnose
# This code will prevent manual stop of sms if there is a driver error. 
# SMS should handle this situation automatically. 
#  
dev_count=`prtconf -p | grep -c \'gchip\'`
if [ "${dev_count}" -eq 0 ] ; then
        echo `gettext "Warning: Unable to detect gchip in system configuration."`
        echo `gettext "The $command command should only be executed on a SunFire 15K System Controller."`
        exit 1
fi
dev_count=`prtconf -p | grep -c \'echip\'`
if [ "${dev_count}" -eq 0 ] ; then
        echo `gettext "Warning: Unable to detect echip in system configuration."`
        echo `gettext "The $command command should only be executed on a SunFire 15K System Controller."`
        exit 1
fi
dev_count=`prtconf -p | grep -c \'consbus\'`
if [ "${dev_count}" -eq 0 ] ; then
        echo `gettext "Warning: Unable to detect consbus in system configuration."`
        echo `gettext "The $command command should only be executed on a SunFire 15K System Controller."`
        exit 1
fi


# source the sms environment file
if [ -r "$SMS_ENV" ]; then
	. $SMS_ENV
else
	echo `gettext "$command: sms_env.sh file missing or not readable"`
	exit 1
fi

# CD to a harmless directory first
cd /

# ignore HUP and QUIT signals
trap '' HUP QUIT

case "$sub_command" in

'start')
	man_set_ipparams
	sms_start
	;;

'stop')
	sms_stop
	;;

*)
	usage_error
	exit 2
	;;
esac

exit 0
