#!/bin/sh
#
#    Copyright (c) 1996-2001 Brocade Communications Systems, Inc.
#    All rights reserved.
#
#    Initialization script to start/stop Fabric OS services and interfaces
#    on different platform.
#

PATH=/sbin:/bin:/usr/sbin:/usr/bin:/fabos/sbin:/fabos/bin

#
# Set a signal handler for the script.
#
trap sig_handler SIGBUS

#
# Signal handler for this script.
#
sig_handler()
{
	echo "**********************************************************"
	echo "RECEIVED UNEXPECTED SIGNAL. PROCESS INFORMATION:"
	echo "**********************************************************"
	ps auxw
	exit 1
}


#
# Getting platform code.
#
# Platform id is:
# 10: Ulysses
# 11: Wrap
# 12: Terminator
# 
PLATFORM=`sin 2>/dev/null | grep SWBD | cut -d ' ' -f 2 | cut -c 5-6`
if [ "$PLATFORM" != "10" -a "$PLATFORM" != "11" -a "$PLATFORM" != "12" ]; then
	echo "Platform code $PLATFORM is not supported"
	exit 1
fi

FABOSHOME=/fabos
export FABOSHOME

CONFIG=/etc
CHECK=/sbin/chkconfig

if $CHECK verbose ; then
    ECHO='echo -e'
else
    ECHO=:
fi

#
# startd <daemon name> <chkconfig flag> <sleep time> <flags>
#
# Start a system daemon
#
startd()
{
    if $CHECK $2 && test -x /fabos/sbin/$1; then
	$1 `cat $CONFIG/$1.options 2> /dev/null` $4 & echo -e " $1\c"; sleep $3
    fi
}

#
# start_daemons <switch_number>
# Start daemons related to a particular switch.
#
start_daemons()
{
    sw=$1

    startd  fabricd	fabricd	1	"-s $sw"
    startd  zoned	zoned	1	"-s $sw"
    startd  fspfd	fspfd	1	"-s $sw"
    startd  nsd		nsd	1	"-s $sw"
    startd  msd		msd	1	"-s $sw"
    startd  asd		asd	1	"-s $sw"
    startd  psd		psd	1	"-s $sw"
    startd  fcpd	fcpd	1	"-s $sw"
    startd  evmd	evmd	1	"-s $sw"
    startd  errlogd     errlogd 1       "-s $sw"
    startd  track_changes track_changes 1 "-s $sw"
}

#
# stop_daemons <switch_number>
# Stop daemons related to a particular switch.
#
stop_daemons()
{
    killproc1 $1
}

#
# killproc1 <switch no>
#
killproc1()
{
    pid=`cat /var/run/*$1.pid 2> /dev/null`

    if [ "$pid" != "" ] ; then
	kill -TERM $pid > /dev/null 2>&1
	sleep 2
	pid=`ps -eaf | grep "\-s $1" |  /usr/bin/tr -s " " : | /usr/bin/cut -d: -f2`
	kill -KILL $pid > /dev/null 2>&1
    fi

    sleep 1
    ent=`ps -eaf | grep "\-s $1" | wc -l`
    if [ $ent -gt 1 ]; then
        echo "All daemons NOT properly killed. Exiting...\n";
        ps -eaf | grep "\-s $1"
	exit 1;
    fi

    # remove pid file if any.
    rm -f /var/run/*$1.pid
}

fdet_error()
{
    killproc $1
}

#
# killproc <switch no>
# Kill the switch specific daemons
#
killproc()
{
    # kill switch specific daemons
    pid=`cat /var/run/*$1.pid 2> /dev/null`
    if [ "$pid" != "" ] ; then
	kill -TERM $pid > /dev/null 2>&1
	sleep 1
	kill -KILL $pid > /dev/null 2>&1
    fi

    # remove pid file if any.
    rm -f /var/run/*$1.pid
}

#
# kill httpd
#
killhttp()
{
    # kill webtools for this switch
    if [ -f '/tmp/webtools/logs/httpd.pid.$1' ] ; then
        pid=`cat /tmp/webtools/logs/httpd.pid.$1 2> /dev/null`
        if [ "$pid" != "" ] ; then
	    kill -TERM $pid > /dev/null 2>&1
        fi
    fi
}

#
# modutil <load | unload> <module name>
#
# Load a kernel module
#
INSMOD_SUCESS=0
modutil()
{

    case $1 in

    load)
	insmod -q $2

	RETURN_VALUE=$?
	if [ $RETURN_VALUE -ne $INSMOD_SUCESS ]; then
	  echo "Error " $RETURN_VALUE " returned by insmod while loading " $2
	fi
	;;

    *)
	;;
    esac
}

#
# Start module for ULYSSES platform.
#
swbd10_module()
{
	modutil load db-module
	modutil load fablog-module
	modutil load ulysses-module
	modutil load haulysses-module
	modutil load portlog-module
	modutil load fabsys-module
	modutil load iu
	modutil load switch-module
	modutil load blade-module
	modutil load bloom-module
	modutil load fc-module
	modutil load dma-module
	modutil load fmf-module
	modutil load ham-module
	modutil	load swd-module
	return 0
}

#
# Load module for WARP platform.
#
swd11_module()
{
	#
	# Note defined yet.
	#
	return 1	
}

#
# Load module for TERMINATOR platform.
#
swbd12_module()
{
	modutil load fablog-module
	modutil load terminator-module
	modutil load portlog-module
	modutil load fabsys-module
	modutil load iu
	modutil load switch-module
	modutil load blade-module

	# BLOOM default debugging levels - 4: BLM_WARN_LVL
#	setDbg BLOOM 4
#	setDbg TRUNK 4
#	setDbg FLTR  4
#	setDbg INTR  4
#	setDbg PHAN  4
#	setDbg LOOP  4
#	setDbg SPEED 4
	modutil load bloom-module

	modutil load fc-module
	modutil load fmf-module
	modutil load ham-module
	modutil	load swd-module
	return 0
}

#
# Start daemon for ULYSSES 
#
swbd10_daemon()
{
	startd emd	emd	10	""
	startd proxy	ipc	1	"-d 0"
	startd dmad     dmad	1	""
	startd pdmd	pdmd	1	""
	startd hamd	hamd	1	""
	startd fmfd	fmfd	1	""
	startd swdd	swdd	1	""
	startd rpcd	rpcd	1	""
	startd logind   track_changes   1       ""
	return 0
}

#
# Start daemon for WARP 
#
swbd11_daemon()
{
	#
	# XXXX Note defined yet.
	#
	return 1
}

#
# Start daemon for TERMINATOR 
#
swbd12_daemon()
{
	startd emd	emd	10	""
	startd pdmd	pdmd	1	""
	startd hamd	hamd	1	""
	startd fmfd	fmfd	1	""
	startd swdd	swdd	1	""
	startd rpcd	rpcd	1	""
	startd logind   track_changes   1       ""
	return 0
}

#
# Create node for each device driver.
# mk_device <device names>
#
mk_device()
{

	for node in $@; do
		major=`grep $node\$ /proc/devices | cut -d ' ' -f 1`

		if [ ! $major ]; then
			exit 1;
		fi

		# Every node has a default

		if [ $node != "fabsys" ]; then
		   rm -f /dev/$node
		   mknod --mode=644 /dev/$node c $major 0
		else
		   rm -f /dev/$node
		   mknod --mode=666 /dev/$node c $major 0
		fi

		if [ $node != "fabsys" ]; then
		    for i in 0 1; do
			rm -f /dev/$node$i
			mknod --mode=644 /dev/$node$i c $major $i
		    done
		fi
	done
}

#
# Create device driver for ULYSSES
#
mk10_device()
{	
	DEV_LIST="fabsys portlog fc switch pcidma ham fmf swd"
	mk_device "$DEV_LIST"
	return 0
}

#
# Create device driver for WARP
#
mk11_device()
{
	# XXXX Not defined yet
	return 1
}
	
#
# Link platform specific lib for ULYSSES
#
mk10_lib()
{
	libs=`ls $FABOSHOME/lib/libhil-ulysses*` 
	for i in $libs; do
		 ln -sif $i `echo $i | sed -e 's/\(libhil\).\+\(\.[a\|so].*\)/\1\2/g'`
	done
	return 0
}

#
# Link platform specific lib for WARP
#
mk11_lib()
{
	return 1
}

#
# Link platform specific lib for TERMINATOR
#
mk12_lib()
{
	libs=`ls $FABOSHOME/lib/libhil-terminator*` 
	for i in $libs; do
		 ln -sif $i `echo $i | sed -e 's/\(libhil\).\+\(\.[a\|so].*\)/\1\2/g'`
	done
	return 0
}
	
#
# Create device driver for TERMINATOR 
#
mk12_device()
{
	DEV_LIST="fabsys portlog fc switch ham fmf swd"
	mk_device $DEV_LIST
	return 0
}

#
# Run sysconfig for ULYSSES
#
run_sysconfig_10()
{
	.sysconfig-ulysses
	if [ $? -ne 0 ]; then
		return 1
	fi
	return 0
}

#
# Run sysconfig for WARP 
#
run_sysconfig_11()
{
	return 1
}


#
# this script restores  the latest persistent error log to the
# active partition
#
sync_el()
{
EL_FILES="el_save.[01].0"
EL_DIR1="/var/log/"
EL_DIR2="/mnt/var/log/"
if [ -d $EL_DIR1 ]
then
	cd $EL_DIR1
	/bin/ls ${EL_FILES}  > /dev/null 2>&1
	if [ $? -eq 0 ]
		then
		/bin/ls ${EL_FILES}|/bin/cpio -mp ${EL_DIR2} > /tmp/cpio.output1 2>&1
		if [ $? -ne 0 ];
		then
			printf "WARNING: SYNC-ERRLOG (primary) failed (%d)" $?
			cat /tmp/cpio.output1 > /dev/console
		fi
	fi
fi
if [ -d $EL_DIR2 ]
then
	cd $EL_DIR2
	/bin/ls ${EL_FILES}  > /dev/null 2>&1
	if [ $? -eq 0 ]
		then
		/bin/ls ${EL_FILES}|/bin/cpio -mp ${EL_DIR1} > /tmp/cpio.output2 2>&1
		if [ $? -ne 0 ];
		then
			printf "WARNING: SYNC-ERRLOG (secondary) failed (%d)" $?
			cat /tmp/cpio.output2 > /dev/console
		fi
	fi
fi
}

#
# Run sysconfig for TERMINATOR 
#
run_sysconfig_12()
{
	.sysconfig-terminator
	if [ $? -ne 0 ]; then
		return 1
	fi
	return 0
}
#
# Setup errorlog files for ULYSSES 
#
setup10_el()
{
#backup saved error log files from a previous incarnation

#WARNING do not change names and location of these files
#if you change it also update sys/dev/portlog/portlog_drv.c and
#/sys/dev/portlog/syslog_drv.c
#these files are used by portlog/errrorlog driver

#for switch 0

	$ECHO "Setup errorlog for ULYSSES switch 0..."

	mv -f /var/log/el_common.0 /var/log/el_common.0.b >/dev/null 2>&1
	mv -f /var/log/pl.0 /var/log/pl.0.b >/dev/null 2>&1
	rm -f /var/log/el_save.0 >/dev/null 2>&1
	rm -f /var/log/el_save.0.b >/dev/null 2>&1

#for switch 1

	$ECHO "Setup errorlog for ULYSSES switch 1..."

	mv -f /var/log/el_common.1 /var/log/el_common.1.b >/dev/null 2>&1
	mv -f /var/log/pl.1 /var/log/pl.1.b >/dev/null 2>&1
	rm -f /var/log/el_save.1 >/dev/null 2>&1
	rm -f /var/log/el_save.1.b >/dev/null 2>&1

	return 0

}

#
# Setup errorlog files for WARP
#
#setup11_el()
#{
#
#}

#
# Setup errorlog and portlog files for TERMINATOR
#
setup12_el()
{
#backup saved error log files from a previous incarnation

#WARNING do not change names and location of these files
#if you change it also update sys/dev/portlog/portlog_drv.c and
#/sys/dev/portlog/syslog_drv.c
#these files are used by portlog/errrorlog driver

	$ECHO "Setup errorlog for ULYSSES switch 0..."

	mv -f /var/log/el_common.0 /var/log/el_common.0.b >/dev/null 2>&1
	mv -f /var/log/pl.0 /var/log/pl.0.b >/dev/null 2>&1
	rm -f /var/log/el_save.0 >/dev/null 2>&1

	return 0
}

#
# main
#
case "$1" in

'start')

    $ECHO "Starting Fabric OS Services..."

	if $CHECK fabos; then
	   # restore /mnt/var/log/el* and /var/log/el*, so that the
	   # latest persistent errlog is preserved on both / and /mnt
	   sync_el

	   # backup errorlog
	   setup"$PLATFORM"_el

	    # Load modules

	    mk"$PLATFORM"_lib
	    if [ $? -ne 0 ]; then
		echo "Platform code $PLATFORM isn't supported" >&2
		exit 1
	    fi

	    swbd"$PLATFORM"_module
	    if [ $? -ne 0 ]; then
		echo "Platform code $PLATFORM isn't supported" >&2
		exit 1
	    fi

	    # Set-up diagnostics

	    if $CHECK diag; then
		modutil load dfs

		if [ ! -d /diag ]; then mkdir /diag; fi

		# The following modules will not load without DFS mounted.

		mount -t dfs /diag /diag
		sleep 3

		modutil load dcomm
		modutil load ddpat
		modutil load dtest
	    fi

	    # Build device nodes

	    mk"$PLATFORM"_device
	    if [ $? -ne 0 ]; then
		echo "Platform code $PLATFORM isn't supported" >&2
		exit 1
	    fi
	    # BLOOM default debugging levels - 4: BLM_WARN_LVL
#	    setDbg BLOOM 4
#	    setDbg TRUNK 4
#	    setDbg FLTR 4
#	    setDbg INTR 4
#	    setDbg PHAN 4
#	    setDbg LOOP 4
#	    setDbg SPEED 4
#	    setDbg BLADE 1

	    # Fix-up library links as necessary

	    # Push system configuration

	    run_sysconfig_$PLATFORM
	    if [ $? -ne 0 ]; then
		echo "Error loading $PLATFORM config loader." >&2
		exit 1
	    fi

	    # Invoke system daemons

	    # Clean-up latent IPC files

	    rm -f /tmp/.ipc*

	    # clean-up latent debug files

	    rm -f /tmp/debug.*.conf
	    rm -f /tmp/debug.pid

	    # Use /proc/fabos/configInfo to figure out instances

	    instances=`cat /proc/fabos/configInfo | tail +2 | wc -l`

	    if [ $instances -gt 0 ]; then

    		$ECHO "Fabric OS Daemons:\c"
		startd diagd diag 1

		# Start instance-specific daemons

		i=0

		while [ $i -ne $instances ]; do
		# when make change here, please make change for webd and snmpstartd, 17 lines down
		# while [ $i -ne 1 ]; do

		    $ECHO "  Instance $i:\c"

		    start_daemons $i

		    $ECHO "."

		    ((i++))
		done

    		#start uptime clock
                /fabos/bin/switchuptime startall >/dev/null 2>&1
 
		swbd"$PLATFORM"_daemon
		if [ $? -ne 0 ]; then
		    echo "Platform code $PLATFORM isn't supported" >&2
		    exit 1
		fi

		# Start webd and snmpstartd, both have to be started after emd and hamd
		j=0
		while [ $j -ne $instances ]; do
		# while [ $j -ne 1 ]; do
		    $ECHO "Instance $j:\c"
		    startd webd		webtools 1 "-s $j"
		    startd  snmpstartd  snmpd 1 "-s $j"
    		    startd fwd		fwd	 1 "-s $j"
 		    $ECHO "."
		    ((j++))
		done
	    fi
	fi

    $ECHO "."
    ;;

'stop')
    $ECHO "Stopping Fabric OS services..."

	# First, we should shutdown SWD, otherwise it will blow the whistle
	# for every daemon's death
	/sbin/swdadmin shutdown

        #stop uptime clock for both switches
    	/fabos/bin/switchuptime stopall >/dev/null 2>&1

	# stop all the switch based daemons
	/etc/rc.d/init.d/fabos stop_daemons 0
	/etc/rc.d/init.d/fabos stop_daemons 1

	# stop all chassis based daemons
	DAEMONS='swdd pdmd hamd proxy emd dmad fmfd rpcd evmd diagd logind'
	/usr/bin/killall -q -TERM $DAEMONS >/dev/null 2>&1
	/usr/bin/killall -q $DAEMONS >/dev/null 2>&1
	/fabos/sbin/errSave
	/fabos/sbin/errNvLogDisable
	/fabos/sbin/portlogNvDisable

    $ECHO "Done."
    ;;

'start_daemons')

    $ECHO "Starting Switch $2 daemons:\c"
    start_daemons $2
    #
    # temporarily start the switch specific daemons here
    # which are not part of start_daemons script
    #
    startd webd		webtools 1	"-s $2"
    startd snmpstartd	snmpd	 1	"-s $2"
    startd fwd  	fwd	 1	"-s $2"

    $ECHO "Done."
    ;;

'stop_daemons')

    $ECHO "Stopping Switch $2 daemons:\c"
    stop_daemons $2

    $ECHO "Done."
    ;;

'start_webtools')
	
	$ECHO "Starting webtools for switch $2\c"
	startd webd webtools 1 "-s $2"
	$ECHO "done."
	;;

'stop_webtools')
	
	$ECHO "Stopping webtools for switch $2\c"
	killhttp $2
	$ECHO "done."
	;;
 
'fdet_error')

    $ECHO "Processing Switch $2 FDET error:\c"
    fdet_error $2

    $ECHO "Done."
    ;;

*)
    echo "Usage: $0 {start | stop | start_daemons <sno> | stop_daemons <sno> | start_webtools <sno> | stop_webtools <sno> | fdet_error <sno>}"
    ;;

esac
