#!/bin/sh

# pick up some helper functions
source /ciena/scripts/utils.sh
source /ciena/scripts/saos_utils.sh

source /etc/profile
source /ciena/scripts/krn getenv

SYSLOG_ALERT="logger -p USER.ALERT -t $(basename $0)"
SYSLOG_ERR="logger -p USER.ERR  -t $(basename $0)"
SYSLOG_INFO="logger -p USER.INFO  -t $(basename $0)"

# -----------------------------------------------------------------------------
handle_config_crash()
{
    if [ -n "$NOCONFIG" ] ; then
        $SYSLOG_ALERT "SAOS crashed with minimal config, rebooting"
        write_cookie $ParamType_LastResetReason $ResetReason_ErrorHandler
	reboot # To (presumably) alternate flash bank.
    else
        $SYSLOG_ALERT "SAOS crashed before config was marked good," \
                      "will restart with no config"
        touch $SAOS_NOCONFIG_FILE
    fi
}

# --- main --------------------------------------------------------------------

##########################################################
#   Stop previous instance of DHCP-C if running &
#   Unconfigure the interface, gw etc.
##########################################################
/ciena/scripts/stopDhcpc.sh

##########################################################
#   Kill any existing children of a prior LEOS server.
##########################################################
kill_saos_server

##########################################################
# Check for Monitor (xgrade) script and run it if required.
# Stops various system services first.
##########################################################
if [ -x /tmp/xgrade/monitor ] ; then
   /ciena/scripts/shutdown && /tmp/xgrade/monitor
   # If monitor didn't reboot something went wrong; wait for possible
   # core file generation, reboot and hope the board can boot.
   secs=10
   while [ $secs -gt 0 ]; do
       printf "\rUpgrade failed. Rebooting in %2d" $secs
       sleep 1
       secs=$(($secs - 1))
   done
   $SYSLOG_ALERT "Upgrade failed, rebooting"
   printf "\rUpgrade failed. Rebooting now..."
   write_cookie $ParamType_LastResetReason $ResetReason_ErrorHandler
   reboot
fi


if $(saos_server_pending_reboot) ; then
    $SYSLOG_ALERT "pending reboot detected, rebooting now"
    write_cookie $ParamType_LastResetReason $ResetReason_ErrorHandler
    reboot
fi

##########################################################
# Remove remnants of previous runs
##########################################################
rm -rf /tmp/xgrade/* /mnt/sysfs/temp_config/* /mnt/sysfs/software/*

if console_enabled; then
    ##########################################################
    #   Determine disposition of serial port (console).
    #   If in normal mode, only stderr makes it out.
    ##########################################################
    if [ "$KRN_CONSOLE" = "normal" ]; then
        CONSOLE_MIRROR=/tmp/log/console_mirror
        exec </dev/null >$CONSOLE_MIRROR
    fi
else
    ##########################################################
    #   There is no console enabled, so glue stdout and
    #   stderr to CONSOLE_COLLECTOR.
    ##########################################################
    CONSOLE_COLLECTOR=/tmp/log/console_collector
    exec </dev/null &>$CONSOLE_COLLECTOR
fi

# clear files that refer to the previous SAOS server run
rm -f $SAOS_RUNMODE_FILE $SAOS_CONFIG_GOOD_FILE $SAOS_PIDFILE

# Is this first run of SAOS server since power-up or reboot?
LEOS_LAST_RESET_FILE=/tmp/fifo/leos/LEOS_LAST_RESET
if [ -f $LEOS_LAST_RESET_FILE ]; then
    # PWE needs to be reset if SAOS restarts
    setup_pwe
fi

# check to see if we should start with no config
if [ -f "$SAOS_NOCONFIG_FILE" ] ; then
    NOCONFIG=-n
    export SAOS_NOCONFIG=1
    rm $SAOS_NOCONFIG_FILE
else
    NOCONFIG=
fi

# check for debug mode from krn settings
if [ "$KRN_MODE" = "debug" ] ; then
    DEBUG=-D
else
    DEBUG=
fi

PRELOAD=""

# If lttng is present, then force a preload of the appropriate libraries.
# We do not need to load liblttng-ust-fork.so as SAOS will always call
# exec() after calling fork().
if [ -e /usr/lib*/liblttng-ust.so ] ; then
    LTTNG_LIBS="liblttng-ust.so liblttng-ust-tracepoint.so"
    PRELOAD="$LTTNG_LIBS $PRELOAD"
fi

# preload malloc() debugging tools if requested
#
# Note that electric fence and mtrace can not be used at the same time.
#
if [ -e /mnt/sysfs/system/efence_enable ] ; then
    # To enable electric-fence dynamically:
    #   - setup a preload of the electric fence shared object
    #   - increase /proc/sys/vm/max_map_count
    #   - remove the flag file so that we only follow this path only once
    PRELOAD="libefence.so $PRELOAD"
    echo 131072 > /proc/sys/vm/max_map_count
    rm -rf /mnt/sysfs/system/efence_enable

elif [ -e /ciena/lib*/libmemTrace.so ]; then
    #   If mtrace tool is present preload it into SAOS.
    PRELOAD="libmemTrace.so $PRELOAD"
fi

# Set up a handler for the SIGTERM signal (for this script process):
#   - pass the TERM signal to the server
#   - wait for the server to terminate
#   - log the fact that we were killed via SIGTERM
#   - exit the script
trap 'kill -TERM $SAOS_SERVER_PID;      \
      wait $SAOS_SERVER_PID;            \
      $SYSLOG_INFO "killed by SIGTERM"; \
      exit 0' SIGTERM

if [ ! -f $SAOS_PATH ]; then
    $SYSLOG_ALERT "$SAOS_PATH: No such file, rebooting"
    write_cookie $ParamType_LastResetReason $ResetReason_ErrorHandler
    reboot
fi

echo "System still initializing, there are"  >/etc/nologin
echo "no SAOS user accounts available yet." >>/etc/nologin
$SYSLOG_INFO "Starting SAOS from $SAOS_PATH"

rootfs_location=$(get_rootfs_location)
if [ $rootfs_location != "flash" -o $KRN_RESPAWN != "enable" ] ; then
    # Non-flash, or non-respawn.  Just run leos.
    LD_PRELOAD="$PRELOAD" exec $SAOS_PATH $DEBUG -s
fi

# We are running from flash and respawns are enabled.
if [ -n $NOCONFIG ] ; then
    /bin/tar xzf /etc/etc.tar.gz -C /
    chmod o-w /etc
    /ciena/scripts/fixup_etc_issue
fi

# Start SAOS in server mode and record the PID
if [[ -x "/sbin/gradm" ]]; then
    GRSEC_S=`/sbin/gradm -S`
    if [ "${GRSEC_S}" != "The RBAC system is currently disabled." ]; then
        # adopt role not requiring authentication
        /sbin/gradm -n r_leos
    fi
fi
LD_PRELOAD="$PRELOAD" $SAOS_PATH $DEBUG $NOCONFIG -s &
SAOS_SERVER_PID=$!

# Block here until the SAOS server dies.  Note that the call to trap above
# will catch any attempt to kill this script process with SIGTERM.
wait $SAOS_SERVER_PID
EXIT_STATUS=$?

# Check for respawn changes while leos was running.  If respawns have been
# disabled then skip the respawn logic.
source /ciena/scripts/krn getenv
if [ $KRN_RESPAWN != "enable" ] ; then
    exit $EXIT_STATUS
fi

if [ $EXIT_STATUS -eq 0 ] ; then
    $SYSLOG_INFO "SAOS exited normally"
    exit 0
fi

# From this point on, we know that SAOS server exited with an abnormal exit
# code (this is usually due to some type of crash).  Based upon the apparent
# state of the server when it stopped, we choose an appropriate action.  Note
# that SAOS will not record the runmode until it has been acknowledged by all
# components.

echo "System initialization has failed, there" >/etc/nologin
echo "are no SAOS user accounts available."   >>/etc/nologin

RUNMODE="$(saos_server_runmode)"
case "$RUNMODE" in

    "missing"|"unequip"|"init"|"setup-1")
        $SYSLOG_ALERT "SAOS crashed before config processing" \
                      "(runmode \"$RUNMODE\"), rebooting"
        write_cookie $ParamType_LastResetReason $ResetReason_ErrorHandler
        reboot # To (presumably) alternate flash bank.
        ;;

    "setup-2"|"post")
        handle_config_crash
	;;

    "run")
        if [ -f "$SAOS_CONFIG_GOOD_FILE" ] ; then
            $SYSLOG_INFO "SAOS crashed while running with a good config," \
                         "no further action required"
        else
            handle_config_crash
        fi
        ;;
    *)
        $SYSLOG_INFO "SAOS crashed in runmode \"$RUNMODE\"," \
                     "no further action required"
        ;;
esac
