#! /bin/bash

# This script performs initialization for switchd that needs to be done prior to
# starting switchd.

PATH=/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:/usr/local/sbin:/usr/cumulus/bin
DESC="Cumulus Networks switch chip daemon"
NAME=switchd
DAEMON=/usr/sbin/$NAME
PIDFILE=/run/$NAME.pid
SCRIPTNAME=$0
BCMDIR=/etc/bcm.d
BCMCFGDIR=/etc/bcm.d/config.d
SWITCHD_INIT=/etc/cumulus/switchd.init
SWITCHD_CFG=/etc/cumulus/switchd.conf

# Read configuration variable file if it is present
[ -r /etc/default/$NAME ] && . /etc/default/$NAME

#
# Starting in release 2.1, switch configuration is stored in
# /etc/cumulus/switchd.conf.  Transfer pre-2.1 release configuration
# from /etc/default/switchd (in DAEMON_OPT_ARGS) to
# /etc/cumulus/switchd.conf
#
do_cfg_upgrade()
{
	a=($DAEMON_OPT_ARGS)
	for i in "${!a[@]}"; do
		match=""
		if [ ${a[i]} = "-L" ]; then
			match="logging = "
			a[((i+1))]=${a[((i+1))]//\//\\/}
		fi
		if [ ${a[i]} = "-bp" ]; then
			match="buf_util.poll_interval = "
		fi
		if [ ${a[i]} = "-bm" ]; then
			match="buf_util.measure_interval = "
		fi
		if [ ${a[i]} = "-c" ]; then
			match="coalescing.reducer = "
		fi
		if [ ${a[i]} = "-C" ]; then
			match="coalescing.timeout = "
		fi
		if [ ${a[i]} = "-t" ]; then
			match="route.table = "
		fi
		if [ ${a[i]} = "-s" ]; then
			sed -i -e "s/^#*ignore_non_swps = .*$/ignore_non_swps = TRUE/" $file
		fi
		if [ ${a[i]} = "-n" ]; then
			sed -i -e "s/^#*arp.next_hops = .*$/arp.next_hops = TRUE/" $file
		fi
		if [ ${a[i]} = "-d" ]; then
			sed -i -e "s/^#*route.delete_dead_routes = .*$/route.delete_dead_routes = TRUE/" $file
		fi
		if [ -n "$match" ]; then
			sed -i -e "s/^#*$match.*$/$match${a[((i+1))]}/" $SWITCHD_CFG
		fi
	done
}

do_cfg_upgrade

#
# Generate switchd configuration
#
check_and_set_port_type()
{
	if grep -iq "^use_tuntap[[:space:]]*=[[:space:]]*TRUE" /etc/cumulus/switchd.conf; then
		export SWPORT_USE_TUNTAP=1
	fi
}

do_init()
{
	# run any switchd setup scripts
	#
	if [ -x $SWITCHD_INIT ]; then
		$SWITCHD_INIT || { echo $SWITCHD_INIT failed; return 2; }
	fi

	# generate port configuration
	#
	if [ -x /usr/lib/cumulus/update-ports ]; then
		check_and_set_port_type
		if [ -n "$OFFLINE_MODE" ]; then
		    /usr/lib/cumulus/update-ports --exploded --mac_mode $MACMODE
                else
		    /usr/lib/cumulus/update-ports --mac_mode $MACMODE
                fi
                rval=$?
                if [ $rval -ne 0 ]; then
                    echo update-ports failed: $rval
                    return 2
                fi
        fi

        # generate datapath configurations
        #
        if [ -x /usr/lib/cumulus/datapath-config ]; then
                /usr/lib/cumulus/datapath-config ||
                { echo datapath-config failed: $?; return 2; }
        fi

        # generate the backend config file
        #
        if [ -x /usr/lib/cumulus/generate-backend-config ]; then
                /usr/lib/cumulus/generate-backend-config ||
                { echo generate-backend-config failed: $?; return 2; }
        fi
}  

# If module $1 is loaded return - 0 else - 1
is_module()
{
        local RC

        /sbin/lsmod | grep -w "$1" > /dev/null
        RC=$?

        return $RC
}

restart_mlx()
{
       systemctl stop sx_sdk
       systemctl stop smond
       rmmod sx_netdev
       rmmod mlnx_asic_drv
       rmmod sx_core
       modprobe sx_core
       modprobe mlnx_asic_drv
       modprobe sx_netdev
       systemctl start smond
       systemctl start sx_sdk
       systemctl --no-block start ledmgrd
}

#
# Function that starts the daemon/service
#
do_start()
{

	/usr/sbin/switchd -lic
	RETVAL="$?"
	if [ "$RETVAL" = 1 ]; then
		logger -s -p syslog.alert -- "No license.  Switchd will not start"
		return 2;
	fi

	if [ "$RETVAL" = 2 ]; then
	    logger -s -p syslog.alert -- "No valid license.  Switchd will not start"
	    return 2;
	fi

	if [ -n "$SEPARATE_ROUTING" ]; then
		separate_routing $SEPARATE_ROUTING
		SEPARATE_ROUTING_ARGS="-s -t 1"
	fi

	do_init 

	# if mlx/sx drivers present, assume we need to do this
	if is_module sx_netdev; then
		restart_mlx
		if [ -x /usr/bin/mst ] && [ -x /usr/lib/cumulus/mlxfwupgrade ]; then
			/usr/bin/mst start && /usr/lib/cumulus/mlxfwupgrade
			if [ $? -eq 0 ]; then
				restart_mlx
			else
				/bin/true
			fi
		fi
	fi

	return $?
}

sendsigs_omit() {
        OMITDIR=/run/sendsigs.omit.d
        mkdir -p $OMITDIR
        ln -sf $PIDFILE $OMITDIR/switchd
}

# We can run in normal mode (start), and diags mode (start-offline)
# handle both cases, and error out with other (or no) arguments.

case "$1" in
  start)
	echo "Initializing $DESC $NAME"
	do_start
	rval=$?
	case "$rval" in
		0) sendsigs_omit ;;
		*) exit $rval ;;
	esac
	;;
  start-offline)
	echo "Starting $DESC $NAME in diag mode"
	OFFLINE_MODE="offline"
	do_start
	rval=$?
	case "$rval" in
		0) ;;
		*) exit $rval ;;
	esac
	;;
  *)
	echo "Usage: $SCRIPTNAME {start|start-offline}" >&2
	exit 3
	;;
esac

exit 0
