#!/bin/bash 
# Node Initialization Daemon startup/shutdown Script
#

### BEGIN INIT INFO
# Provides: opensaf
# Required-Start:    $local_fs $network $syslog
# Required-Stop:     $local_fs $network $syslog
# Should-Start:
# Should-Stop:
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Start OpenSAF services
# Description: Start OpenSAF System Controller services 
#         with HA role ACTIVE or STANDBY in the cluster. 
### END INIT INFO

# Source the configuration file if it is present
[ -r "/etc/opensaf/script.conf" ] && . "/etc/opensaf/script.conf"

# Log to syslog with tag and log to console with date
# Cannot use -s to 'logger' since it will not give us date & time
log()
{
    logger -t $SYSLOG_TAG $1
    now=$(date)
    echo "$now - $1"
}

export LEAP_TMR_THREAD_RT=1
export LEAP_THREADS_NON_RT=1
export MDS_QUIESCED_TMR_VAL_IN_10MS=40

if [ "$NODE_TYPE" == "controller" ] ; then
  NT=1
  AMF=opensaf_scap
elif [ "$NODE_TYPE" == "payload" ] ; then
  NT=2
  AMF=opensaf_pcap
else
  log "ERROR: NODE_TYPE is not properly set in $SYSCONFDIR/script.conf"
  exit 2
fi

DAEMON=ncs_nid
DESC="Node Initialization Daemon"
NIDPIDFILE="$PIDPATH/nodeinit.pid"
NISSTATUS="NONE"
STATUS=0

####################################################
# NID_ROLE_CONFIG is for flexibility to configure
# role for NID via environment variables in the
# event RDE fails to provide a Role
# For Active:  export NID_ROLE_CONFIG=ACTIVE
# For standby: export NID_ROLE_CONFIG=STDBY
####################################################
export NID_ROLE_CONFIG="ACTIVE"

if [ ! -x "$LIBPATH/$DAEMON" ]; then
   log "NID Daemon Not Found. Did OpenSAF installation succeed?"
   exit 1
fi

# Make sure this (Linux) system has POSIX shared memory configured
if ! test -d /dev/shm; then
    log "POSIX shared memory not enabled, exiting."
    exit 1
fi

# Exit if tipc-config is not installed
if [ ! -x "/sbin/tipc-config" ]; then
  if ! which tipc-config >/dev/null 2>&1 ; then
    log "Cannot find tipc-config, is TIPC properly installed?"
    exit 2
  fi
fi

# Function to start the services
start()
{
  	### Remove TIPC if already installed.
	if [ "$TIPC_MANAGE" == "YES" ] && grep tipc /proc/modules >& /dev/null;
	then
	  modprobe -r tipc
	  if [ $? -eq 1 ]; then
	    log "TIPC is already installed, Please
	    remove TIPC module first..."
	    exit 1
	  fi
	fi

        ### Remove shared memory files created by OpenSAF services.
	if [ -d /dev/shm/opensaf ]; then
	  rm -rf /dev/shm/opensaf
	fi
	  
	mkdir -p /dev/shm/opensaf

	if [ -f "$NIDPIDFILE" ]; then
	  log  "$LIBPATH/$DAEMON already running.."
	  exit 1
	fi

	  log "Starting $DESC: $LIBPATH/$DAEMON" 

        ####################################################
        # NID_CONFIG_PATH is to configure the path for
        # NID to pickup nodeinit.conf file
        ####################################################
	export NID_CONFIG_PATH="$SYSCONFDIR"
        export CONSOLE=/dev/tty

        ####################################################
        #  OpenSAF settings
        ####################################################
        if [ `ulimit -c` = 0 ]; then
            ulimit -Sc $CORE_FILE_SIZE
        fi

        if [ $CORE_PATTERN_CURRENT = "core" ]; then
            echo $CORE_PATTERN > /proc/sys/kernel/core_pattern
        fi
       
        ####################################################################################                                 
        # NCS_SIMULATION_CONFIG_ROOTDIR = This the directory from where node-configuration
        # files are read. It is recognized only in SIM builds, where multiple-nodes need
        # to be simulated on a single linux-desktop for testing purposes.
        ####################################################################################
	if [ ":$2" == ":" ]; then
            NODE_NAME=""
	    export NCS_SIMULATION_CONFIG_ROOTDIR="$SYSCONFDIR"
        else
            NODE_NAME=$2
            if [ -r "$SYSCONFDIR"/"$2"]; then
                export NCS_SIMULATION_CONFIG_ROOTDIR="$SYSCONFDIR/$2"
            else
                log "ERROR: $SYSCONFDIR/$2 not found"
                exit 1
            fi
        fi
 
        ###  NCS_LOG_PATH = This the directory where OPENSAF logs are stored.
        ###  It is recommended that this variable not be
        ###  modified other than for SIMULATION mode.
        if [ ":$3" == ":" ]; then
            ### No explicit NCS_LOG_PATH argument.
            ### Create it using NODE_NAME
            export NCS_LOG_PATH="$LOCALSTATEDIR/log$NODE_NAME"
            NCS_OLD_LOG_PATH="$LOCALSTATEDIR/old_log$NODE_NAME"
        else
            export NCS_LOG_PATH=$3
        fi

	if [ -e "$NCS_STDOUTS_PATH" ]; then
            if [ -e "$OLD_STDOUTSPATH" ]; then
               rm -rf "$OLD_STDOUTSPATH"
            fi
            mv "$NCS_STDOUTS_PATH" "$OLD_STDOUTSPATH"
        fi

        mkdir -p "$NCS_STDOUTS_PATH"
	[ "$NODE_TYPE" == "controller" ] && mkdir -p "$NCS_LOG_PATH"

        ######################################################
        #  OpenSAF Settings END
        #####################################################

    rm -f "$NISPIPE"
    touch $NISPIPE

    "$LIBPATH/$DAEMON" > "$NISPIPE" &

    # Wait a while for response
    timeout=$INITTIMEOUT
    while test $timeout -gt 0; do
        sleep 1
        if test -s $NISPIPE; then
            NISSTATUS=`cat $NISPIPE`
            timeout=0
        else
            timeout=$((timeout-1))
        fi
    done

	rm -f "$NISPIPE"
	if [ "${NISSTATUS}" != "SUCCESS" ]; then
	  log "SERVICE Initialization Failed: $NISSTATUS"
	  pkill -KILL -f "$LIBPATH/$DAEMON"
	  rm -rf "$NISPIPE" "$NIDPIDFILE"
	  exit 1
	fi;
	STATUS=0
	log "OpenSAF Service Initialization Success";

} #End of start()

clean_the_rest()
{
  	pkill -9 nid >& /dev/null
	pkill -9 opensaf_ >& /dev/null
	pkill -9 ncs >& /dev/null
	if [ "$TIPC_MANAGE" == "YES" ] && grep tipc /proc/modules >& /dev/null;
	then
	  sleep 2 # Give time for tipc to release.
	  modprobe -r tipc
	fi
        rm -f "$NIDPIDFILE" "$SPCAPFIFO"
        rm -rf /dev/shm/opensaf
}

# Function to stop the servcies
stop()
{
    log "Stopping OpenSAF Services..."

    STATUS="TIMEOUT"

    # First Check if AMF is alive.
    AMFPID=`pgrep -f "$LIBPATH"/"$AMF"`

    if [ -n "$AMFPID" ]; then
        # AMF is alive

        # Create regular file for termination response from AMF
        rm -f "$SPCAPFIFO"
        touch "$SPCAPFIFO"

        # Request AMF to stop services gracefully by sending a signal to it.
        kill -s SIGUSR1 $AMFPID 2>/dev/null

        # Wait a while for response
        timeout=$TERMTIMEOUT
        while test $timeout -gt 0; do
            sleep 1
            if test -s "$SPCAPFIFO"; then
                STATUS=`cat "$SPCAPFIFO"`
                timeout=0
            else
                timeout=$((timeout-1))
            fi
        done

        log "Hand Shake With AMF: $STATUS."
    fi

    if [ "${STATUS}" != "DONE" ]; then
        # AMF is not alive, failed to responds on time or responded with an error
        # If any remaining OpenSAF processes, kill them hard
        log "Forced termination of OpenSAF processes."
        clean_the_rest
        STATUS=1
    else
        # Kill the miscellaneous & non-amf.
        clean_the_rest
        log "OpenSAF Services Termination Success."
        STATUS=0
    fi

} # End of function stop()

case "$1" in
  start)
        start
        ;;
  stop)
	  stop
	;;
  restart|try-restart)
	stop
        sleep 2
        start
        ;;
  reload|force-reload)
	echo "This option is currently not supported."
        echo "."
        ;;
  status)
        if [ ! -f "$NIDPIDFILE" ]; then
            echo "OpenSAF is stopped."
        else 
           cat "$NODE_HA_STATE"
        echo ""
        fi
        ;;
  *)
        echo "Usage: $0 {start|stop|restart|try-restart|reload|force-reload|status}" >&2
        exit 1
        ;;
esac

exit $STATUS
