#!/bin/sh

NCS_PROC=/proc/ncs
NCS_ETC=/etc/opt/novell/ncs
NCS_VAR=/var/opt/novell/ncs
NCS_BIN=/opt/novell/ncs/bin
NCS_NODENAME=`cat $NCS_ETC/nodename`

SBINDIR=/opt/novell/adminfs/sbin
DEVNAME="adminfsdrv"
DEVFILE="/dev/$DEVNAME"
PIDFILE=/var/run/adminfsd.pid
MOUNTPOINT=/admin
CMDFILE=${MOUNTPOINT}/adminfs.cmd

PATH="/sbin":${PATH}
delay_time=20
# export NCSCONFIGD=1
# export NCSRESOURCED=1

#**********************************************************************
# Name:         change_permission_and_ownership
# Description:  change the ownership and permision of /proc/ncs and /admin/Novell/Cluster
# Parameters:   None
# Return:       None
# Notes:
#**********************************************************************
. /etc/rc.status
rc_reset

change_permission_and_ownership()
{
    if ! getent group ncsgroup > /dev/null; then
        groupadd -r ncsgroup
    fi

#   logger -t NCS "change_permission_and_ownership"
    rshell="$(which rbash)"
    if ! ncsclient=$(getent passwd ncsclient) > /dev/null; then
#        logger -t NCS "adding ncsclient=${ncsclient}"
        useradd -rc "Novell Cluster Services System User" -d /var/lib/ncs -g ncsgroup -s "${rshell}" ncsclient
    else
#       logger -t NCS "ncsclient user exists ncsclient exists"
         ncsshell=$(echo ${ncsclient} | cut -d ':' -f 7)
         if [[ "${ncsshell}" != "${rshell}" ]]; then
#            logger -t NCS " modifying the rshell"
             usermod -s "${rshell}" ncsclient
#        else
#            logger -t NCS "rshell is already set"
         fi
    fi

    if ! [ -d /var/lib/ncs ]; then
        mkdir /var/lib/ncs
        chown ncsclient:ncsgroup /var/lib/ncs
    fi

    if [ -d /admin/Novell/Cluster ]; then
        chmod 0750 /admin/Novell/Cluster
        chmod 0660 /admin/Novell/Cluster/*
        chown -R ncsclient:ncsgroup /admin/Novell/Cluster
    fi

    if [ -d /proc/ncs ]; then
        chmod 0660 /proc/ncs/*
        chown -R ncsclient:ncsgroup /proc/ncs
    fi
}

# This is added to support the removal of 20secs in uldncs from
# OES2018SP3 to support heterogeneous environement.

find_time_gap()
{
	check_homogeneity=0
	service_down_time="$(systemctl show -p InactiveEnterTimestamp novell-ncs)"
	IFS='='
	read -r key value_time_down <<< "$service_down_time"
	if [ -n $value_time_down ] | [ $value_time_down != "n/a" ];then
		down_epoch=`(date +%s --date="$value_time_down")`
		current_epoch=`(date +%s)`
		if [[ $((${current_epoch}-${down_epoch})) -lt ${delay_time} ]];then
			check_homogeneity=1
		fi
	fi
}

find_homogeneity()
{
	is_hetrogeneous=0
	cluster homogeneous OES2018SP3 > /dev/null 2>&1
	if [ $? -ne 0 ]; then
		is_hetrogeneous=1
	fi
}

find_homogeneity_induce_delay()
{
	find_homogeneity
	if [[ ${is_hetrogeneous} -eq 1 ]];then
		logger -t NCS -i "The cluster is heterogeneous, sleeping."
		sleep ${delay_time}
	fi
}

#**********************************************************************
# Name:         join_cluster
# Description:  Joins the cluster
# Parameters:   None
# Return:       None
# Notes:
#**********************************************************************
join_cluster()
{
    echo -n 1 > /proc/sys/kernel/panic_on_oops

    cluster join

} # join_cluster

function load_kernel_module() {
	until [ -z "$1" ] ; do
		echo -n "Loading $1.ko ... "
		modinfo $1 >/dev/null 2>&1 
		if [ $? -eq 0 ] ; then
			adminfs_status $1
			if [ $? -eq 0 ] ; then
				echo -n "already loaded."
				rc_status -v
				shift
				continue
			fi
			modprobe $1
			if [ $? -ne 0 ] ; then
				echo -n "unable to load."
				rc_failed 7
				rc_status -v
				rc_exit
			fi
			echo -n "done"
			rc_status -v
		else
			echo -n "not found."
			rc_failed 7
			rc_status -v
			rc_exit
		fi
		shift
	done
	return 0
}

function remove_device() {
	if [ -e "${DEVFILE}" ] ; then
		echo -n "Removing ${DEVFILE} ... "
		rm -f ${DEVFILE}
		echo -n "done"
		rc_status -v
	fi
}

function adminfsd_status() {
	if [ -f $PIDFILE ] ; then
		PID=`cat $PIDFILE`
		if [ -e /proc/$PID ] ; then
			pgrep adminfsd > /dev/null
			return $?
		fi
	fi
	return 1  # not found
}

function mount_status() {
	mp=`mount | awk '/ type adminfs /{print $3}'`
	if [ -n "$mp" ] ; then
		return 0 #mounted
	else
		return 1 #not mounted
	fi
}

function start_lvmlock() {
	#load watchdog kernel module
	modprobe softdog
	systemctl start lvmlockd
	if [ ! $? -eq 0 ]
	then
		echo "ERROR: lvmlockd not loaded"
		exit -1
	fi
	systemctl start wdmd
	if [ ! $? -eq 0 ]
	then
		echo "ERROR: wdmd not loaded"
		exit -1
	fi
	systemctl start sanlock
	if [ ! $? -eq 0 ]
	then
		echo "ERROR: sanlock not loaded"
		exit -1
	fi
	vgchange --lock-start

}
pkill -f '/python /opt/novell/ncs/bin/ncs-configd.py$'
#lsmod | grep adminfs > /dev/null 2>&1
#if [ ! $? -eq 0 ]
#then
#    systemctl start adminfs.service
#    if [ ! $? -eq 0 ]
#    then
#    echo "ERROR: adminfs not loaded"
#    exit -1
#    fi
#fi
#/opt/novell/adminfs/sbin/adminfs mount

#if ! /etc/init.d/micasad status &> /dev/null
#then
    #echo "ERROR: CASA Daemon is not running"
    #exit -2
#fi

if [ -e "$NCS_PROC/cluster" ]
then
    killproc ncs-emaild
    killproc ncsdkd
    killproc NCS_NDSD_monitord

    $NCS_BIN/ncs-configd.py -init > /dev/null 2>&1
    args=$(echo "$(/opt/novell/ncs/install/ncs_install.py -m get-monitor-action)" | grep -o "[A-Z] [0-9]\+ [0-9]\+")
    if [ "" != "$args" ]
    then
        $NCS_BIN/NCS_NDSD_monitord $args
    fi

    $NCS_BIN/ncsdkd
    $NCS_BIN/ncs-emaild

    join_cluster
    exit
fi

if [ ! -s "$NCS_ETC/clstrlib.conf" ]
then
    cp -f $NCS_ETC/clstrlib.conf.rpmsave $NCS_ETC/clstrlib.conf
    chmod 600 $NCS_ETC/clstrlib.conf
fi

if [ ! -s "$NCS_ETC/clstrlib.conf" ]
then
    echo "ERROR: clstrlib.conf is empty or missing"
    exit -1
fi

$NCS_BIN/ncs-configd.py -init > /dev/null 2>&1




# SBD
SBD="$(${NCS_BIN}/sbdutil -f)"
if [[ "${SBD}" == "NotFound" ]];
then
    logger -t NCS -i "NCS is configured with SBD but the SBD device is not available, please make it available and try ncs service start again!!!"
    exit -1
elif [[ "${SBD}" == "NoSharedDisk" ]] ; then
    logger  -t NCS -i "NCS is not configured with SBD, continuing to load NCS"
else 
    logger -t NCS -i  "NCS starting to load"
fi




if [ ! -e "$NCS_VAR/cluster.xml" ]
then
    echo "ERROR: failed to init cluster configuration"
    exit -1
fi

grep -i "dn=\"cn=$NCS_NODENAME," $NCS_VAR/nodes.xml > /dev/null 2>&1
if [ ! $? -eq 0 ]
then
    echo "ERROR: failed to init this node's configuration"
    exit -1
fi

if [ ! -s $NCS_VAR/gipc.conf ]
then
    echo "ERROR : $NCS_VAR/gipc.conf is empty or missing"
    echo "Check cluster credentials in oescredstore"
    exit -1
fi

args=$(echo "$(/opt/novell/ncs/install/ncs_install.py -m get-monitor-action)" | grep -o "[A-Z] [0-9]\+ [0-9]\+")
if [ "" != "$args" ]
then
    $NCS_BIN/NCS_NDSD_monitord $args
fi


#lsmod | grep nwraid > /dev/null 2>&1
#if [ ! $? -eq 0 ]
#then
    #modprobe nwraid
#fi

awk '/tolerance/ {exit $3/1000000}' $NCS_VAR/gipc.conf
TOLERANCE=$?

if ! modprobe adminfsdrv; then exit 15; fi
if ! modprobe adminfs; then exit 16; fi

if ! modprobe ncs_timer ncs_tolerance=$TOLERANCE ; then exit 14; fi

if ! modprobe clstrlib; then exit 1; fi
$NCS_BIN/ncs-configd.py
echo -n $NCS_NODENAME > $NCS_PROC/clstrlib
if ! modprobe sbdlib; then exit 2; fi
$NCS_BIN/sbdutil -f | tail -1 > $NCS_PROC/sbdlib
if [[ $? -ne 0 ]];
then
    echo "Failed to write SBD info to proc"
    exit 3;
fi
if ! modprobe vll; then exit 4; fi
if ! modprobe gipc; then exit 5; fi
if ! modprobe sbd; then exit 6; fi
if ! modprobe vipx; then exit 7; fi
if ! modprobe css; then exit 8; fi

lsmod | grep nsscomn > /dev/null 2>&1
if [ $? -eq 0 ]
then
    if ! modprobe cvb; then exit 9; fi
fi

if ! modprobe crm; then exit 10; fi
if ! modprobe cmsg; then exit 11; fi
if ! modprobe cma; then exit 12; fi

# create device file
major=`grep ${DEVNAME} /proc/devices | awk "{print \\$1}"`
remove_device
echo -n "Creating $DEVFILE (major number: $major) ... "
mknod ${DEVFILE} c $major 0
if [ $? -ne 0 ]; then
	echo -n "failed"
	rc_failed 1
	rc_status -v
	rc_exit
else
	echo -n "done"
	rc_reset
	rc_status -v
fi

# start daemon
echo -n "Starting admin file system daemon ... "
adminfsd_status
if [ $? -eq 0 ] ; then
	echo -n "adminfsd already running."
	rc_reset
	rc_status -v
else
	export LD_LIBRARY_PATH=/usr/lib64/jvm/java-21-openjdk-21/lib/server/
	$SBINDIR/adminfsd
	if [ $? -ne 0 ] ; then
		echo -n "unable to start."
		rc_failed 7
		rc_status -v
		rc_exit
	fi
	echo -n "done"
	rc_status -v
fi

# mount in the default location
echo -n "Mounting adminfs at ${MOUNTPOINT} ... "
found=
if mount_status ; then
	for m in $mp ; do
		if [ "$m" == ${MOUNTPOINT} ] ; then
			found="found"
		fi
	done
fi
if [ $found ] ; then
	echo -n "already mounted"
	rc_status -v
else
	mkdir -p ${MOUNTPOINT}
	if mount -t adminfs adminfs ${MOUNTPOINT} ; then
		echo -n "mounted"
		rc_status -v

		#set up the command file for adminfs
		echo -n "Setting up command file \"${CMDFILE}\" ... "
		echo "<virtualIO><define/></virtualIO><transform><datastream><function><writefunc symname=\"adminfs_command_handler\"></writefunc></function></datastream></transform>" >${CMDFILE}
		chmod 600 ${CMDFILE}
		
		#make sure NCP server remounts if it was already mounted
		if ncpcon volume admin >/dev/null 2>&1; then
			ncpcon dismount admin >/dev/null 2>&1
			ncpcon remove volume admin >/dev/null 2>&1
			ncpcon create volume admin /admin >/dev/null 2>&1
		fi
		echo -n "done"
		rc_status -v
	else
		echo -n "unable to mount"
		rc_failed 1
		rc_status -v
	fi
fi

$NCS_BIN/adminfs

change_permission_and_ownership

# echo -n "TRACE ON" > /proc/ncs/vll
# echo -n "TRACE SBD ON" > /proc/ncs/vll
# echo -n "TRACE GIPC ON" > /proc/ncs/vll
# echo -n "TRACE MCAST ON" > /proc/ncs/vll
# echo -n "TRACE CVB ON" > /proc/ncs/cluster
# echo -n "TRACE CSS ON" > /proc/ncs/cluster
# echo -n "TRACE CRM ON" > /proc/ncs/cluster
# echo -n "TRACE CMA ON" > /proc/ncs/cluster

# echo -n "debug" > /admin/adminfs.cmd

$NCS_BIN/ncsdkd
$NCS_BIN/ncs-resourced.py $NCS_ETC
$NCS_BIN/ncs-emaild

# Let volmnd know that NCS is running now. This has become a need due to the
# following reasons:
# 01. NCS nad NSS order of startup is not in controlled as it is driven by
# systemd.
# 02. New install of NCS (always) makes volmnd miss the NCS SDK registration
#

VOLMNDPID=$(pgrep volmnd)
if [ -d /proc/${VOLMNDPID}/ ]; then
    kill -USR1 ${VOLMNDPID}
fi

find_time_gap
if [[ ${check_homogeneity} -eq 1 ]];then
	find_homogeneity_induce_delay
fi
#start lvmlockd, sanlock and wdmd
start_lvmlock

join_cluster &
