#
# Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
# Use is subject to license terms.
#

SCLOGGER=/usr/cluster/lib/sc/scds_syslog
PKG=SUNWscebs.cmg
METHOD=`basename $0`
LOGFILE=/var/tmp/${RESOURCE}_logfile
TMPFILE=/var/tmp/${RESOURCE}_sqlout
BIT=`echo $MODE | awk -F/ '{print $1}'`
SECURE=`echo $MODE | awk -F/ '{print $2}'`
TASK_COMMAND=""
RESOURCE_PROJECT_NAME=""
SCHA_RESOURCEGROUP_GET=/usr/cluster/bin/scha_resourcegroup_get
SCHA_RESOURCE_GET=/usr/cluster/bin/scha_resource_get
SCHA_CLUSTER_GET=/usr/cluster/bin/scha_cluster_get

STOP_TIMEOUT=`$SCHA_RESOURCE_GET -O Stop_timeout \
	-R $RESOURCE -G $RESOURCEGROUP`

SCLH=`$SCHA_RESOURCE_GET -O Network_resources_used \
	-R $RESOURCE -G $RESOURCEGROUP`

LHOST=`scrgadm -pvv -j ${SCLH} | grep HostnameList | \
	grep value: | awk -F: '{print $4}' | tr -d " "`

LHOSTNAME="LHOSTNAME=${LHOST}"

syslog_tag()
{
        #
        # Data Service message format
        #

        $SET_DEBUG

        print "SC[${PKG:-??}.${METHOD:-??}]:${RESOURCEGROUP:-??}:${RESOURCE:-??}"
}

scds_syslog()
{

        #
        # Log a message
        #

        $SET_DEBUG

        $SCLOGGER "$@" &
}

debug_message()
{
        #
        # Output a debug message to syslog if required
        #

        if [ "$DEBUG" = "$RESOURCE" -o "$DEBUG" = "ALL" ]
        then
                SET_DEBUG="set -x"

                DEBUG_TEXT=$1

                scds_syslog -p daemon.debug -t $(syslog_tag) -m \
                        "%s" "$DEBUG_TEXT"
        else
                SET_DEBUG=
        fi
}

log_message()
{
        #
        # Output a message to syslog as required
        #

        debug_message "Function: log_message - Begin"
        $SET_DEBUG

        if [ -s "${LOGFILE}" ]
        then
                PRIORITY=$1
                HEADER=$2

                strings ${LOGFILE} > ${LOGFILE}.copy
                while read MSG_TXT
                do
                        scds_syslog -p daemon.${PRIORITY} -t $(syslog_tag) -m \
                                "%s - %s" \
                                "${HEADER}" "${MSG_TXT}"
                done < ${LOGFILE}.copy

                su $CON_APPSUSER -c "cat /dev/null > $LOGFILE" > /dev/null
                cat /dev/null > ${LOGFILE}.copy
        fi

        debug_message "Function: log_message - End"
}

validate_options()
{
        #
        # Ensure all options are set
        #

        for i in RESOURCE RESOURCEGROUP CON_COMNTOP CON_APPSUSER APPS_PASSWD APP_SID \
		VERSION ORACLE_HOME CON_LIMIT MODE
        do
                case $i in
                        RESOURCE)
                        if [ -z $RESOURCE ]; then
                                logger -p daemon.err \
                                "ERROR: `basename $0` Option -R not set"
                                exit 1
                        fi;;

                        RESOURCEGROUP)
                        if [ -z $RESOURCEGROUP ]; then
                                logger -p daemon.err \
                                "ERROR: `basename $0` Option -G not set"
                                exit 1
                        fi;;

                        CON_COMNTOP)
                        if [ -z $CON_COMNTOP ]; then
                                logger -p daemon.err \
                                "ERROR: `basename $0` Option -C not set"
                                exit 1
                        fi;;

                        CON_APPSUSER)
                        if [ -z $CON_APPSUSER ]; then
                                logger -p daemon.err \
                                "ERROR: `basename $0` Option -U not set"
                                exit 1
                        fi;;

                        APPS_PASSWD)
                        if [ -z $APPS_PASSWD ]; then
                                logger -p daemon.err \
                                "ERROR: `basename $0` Option -P not set"
                                exit 1
                        fi;;

                        APP_SID)
                        if [ -z $APP_SID ]; then
                                logger -p daemon.err \
                                "ERROR: `basename $0` Option -S not set"
                                exit 1
                        fi;;

                        VERSION)
                        if [ -z $VERSION ]; then
                                logger -p daemon.err \
                                "ERROR: `basename $0` Option -V not set"
                                exit 1
                        fi;;

                        ORACLE_HOME)
                        if [ -z $ORACLE_HOME ]; then
                                logger -p daemon.err \
                                "ERROR: `basename $0` Option -O not set"
                                exit 1
                        fi;;

                        CON_LIMIT)
                        if [ -z $CON_LIMIT ]; then
                                logger -p daemon.err \
                                "ERROR: `basename $0` Option -L not set"
                                exit 1
                        fi;;

                        MODE)
                        if [ -z $MODE ]; then
                                logger -p daemon.err \
                                "ERROR: `basename $0` Option -M not set"
                                exit 1
                        fi;;

                esac
        done

	#
	# Validate $VERSION
	#

	case "${VERSION}" in
		11.5.8)		debug_message "Validate - $VERSION"

				# With 11.5.8 the SID didn't change

				SID=${APP_SID}
				;;

		11.5.9)		debug_message "Validate - $VERSION"

		      		# With 11.5.9 the SID changed to SID_<lhost>
				# for some directory structures and files

				SID=${APP_SID}
				APP_SID=${APP_SID}_${LHOST}
				;;

		*)		scds_syslog -p daemon.err -t $(syslog_tag) -m \
					"Validate - %s is invalid" \
					$VERSION
				;;
	esac

}

validate()
{
        #
        # Validate
        #

        debug_message "Function: validate - Begin"
        $SET_DEBUG

        rc_validate=0

        #
        # Validate that $CON_COMNTOP exists
        #
	
        if [ ! -d "${CON_COMNTOP}" ]
        then
                scds_syslog -p daemon.err -t $(syslog_tag) -m \
                        "Validate - Applications directory %s does not exist" \
                        "${CON_COMNTOP}"
                rc_validate=1
        else
                debug_message "Validate - Applications directory ${CON_COMNTOP} exists"
        fi

        #
        # Validate that ${CON_COMNTOP}/admin/scripts/${APP_SID} exists
        #
	
        if [ ! -d "${CON_COMNTOP}/admin/scripts/${APP_SID}" ]
        then
                scds_syslog -p daemon.err -t $(syslog_tag) -m \
                        "Validate - Applications directory %s does not exist" \
                        "${CON_COMNTOP}/admin/scripts/${APP_SID}"
                rc_validate=1
        else
                debug_message "Validate - Applications directory ${CON_COMNTOP}/admin/scripts/${APP_SID} exists"
        fi

        #
        # Validate that $CON_APPSUSER exists
        #
	
        if cat /etc/passwd | awk -F: '{print $1}' | grep ${CON_APPSUSER} > /dev/null
        then
                debug_message "Validate - Application user ${CON_APPSUSER} exists"
        else
                scds_syslog -p daemon.err -t $(syslog_tag) -m \
                        "Validate - Application user <%s> does not exist" \
                        "${CON_APPSUSER}"
                rc_validate=1
        fi

        #
        # Validate that $ORACLE_HOME exists
        #
	
        if [ ! -d "${ORACLE_HOME}" ]
        then
                scds_syslog -p daemon.err -t $(syslog_tag) -m \
                        "Validate - ORACLE_HOME directory %s does not exist" \
                        "${ORACLE_HOME}"
                rc_validate=1
        else
                debug_message "Validate - ORACLE_HOME dir ${ORACLE_HOME} exists"
        fi

	#
        # Validate $CON_LIMIT 
        #
	
        if [ "${CON_LIMIT}" -gt "100" ]
	then
                scds_syslog -p daemon.info -t $(syslog_tag) -m \
                        "Validate - CON_LIMIT=%s is incorrect, default CON_LIMIT=70 is being used"
                        "${CON_LIMIT}"

		CON_LIMIT=70
	else
		debug_message "Validate - CON_LIMIT=$CON_LIMIT"
	fi

	#
	# Validate $BIT 
	#
	
	case "${BIT}" in
		32|64) 	debug_message "Validate - $BIT-bit mode" 
			;;
		*)	scds_syslog -p daemon.err -t $(syslog_tag) -m \
				"Validate - 32|64-bit mode invalid in %s" \
				"${MODE}"
			rc_validate=1
			;;
	esac

	# 
	# Validate $SECURE
	#
	
	case "${SECURE}" in
	  Y|y|N|n)	debug_message "Validate - Secure library"
				;;
		*)	scds_syslog -p daemon.err -t $(syslog_tag) -m \
				"Validate - Secure mode invalid in %s" \
				"${MODE}"
			rc_validate=1
			;;
	esac

        debug_message "Function: validate - End"
}

standard_resource_get()
{
        debug_message "Function: standard_resource_get - Begin"
        $SET_DEBUG

        PROPERTY=$1

        ${SCHA_RESOURCE_GET} -R ${RESOURCE} -G ${RESOURCEGROUP} -O ${PROPERTY}

        s1=$?

        if [ "${s1}" -ne 0 ]; then
                debug_message "standard_resource_get - Get property ${PROPERTY} rc<${s1}>, ignore if SC3.0"
        fi

        debug_message "Function: standard_resource_get - End"
        return ${s1}
}

standard_resourcegroup_get()
{
        debug_message "Function: standard_resourcegroup_get - Begin"
        $SET_DEBUG

        PROPERTY=$1

        ${SCHA_RESOURCEGROUP_GET} -R ${RESOURCE} -G ${RESOURCEGROUP} -O ${PROPERTY}

        s1=$?

        if [ "${s1}" -ne 0 ]; then
                debug_message "standard_resource_get - Get property ${PROPERTY} rc<${s1}>, ignore if SC3.0"
        fi

        debug_message "Function: standard_resourcegroup_get - End"

        return ${s1}
}

srm_function()
{
        debug_message "Function: srm_function - Begin"
        $SET_DEBUG

        USER=$1
  
        #
        # If Solaris 8 just return
        #

        if [ `/usr/bin/uname -r` = "5.8" ];
        then
                return 0
        fi

        #
        # Retrieve RESOURCE_PROJECT_NAME
        #

        RESOURCE_PROJECT_NAME=`standard_resource_get RESOURCE_PROJECT_NAME`

        #
        # Retrieve RG_PROJECT_NAME if RESOURCE_PROJECT_NAME is not set
        #

        if [ -z "${RESOURCE_PROJECT_NAME}" ]; then

                RESOURCE_PROJECT_NAME=`standard_resourcegroup_get RG_PROJECT_NAME`
        fi

        #
        # Return if no projects are defined
        #

        if [ -z "${RESOURCE_PROJECT_NAME}" ]; then
                return 0
        fi

        #
        # Validate that $USER belongs to the project defined by
        # ${RESOURCE_PROJECT_NAME}
        #

        PROJ_MEMBER=`/usr/bin/projects ${USER} | /usr/bin/grep -w ${RESOURCE_PROJECT_NAME}`

        if [ -z "${PROJ_MEMBER}" ];
        then
             scds_syslog -p daemon.error -t $(syslog_tag) -m \
                        "Validate - The user %s does not belongs to project %s" \
                        "${USER}" "${RESOURCE_PROJECT_NAME}"
                return 1
        else
                debug_message "srm_function - User ${USER} belongs to project ${RESOURCE_PROJECT_NAME}"
        fi

        #
        # Set TASK_COMMAND
        #

        TASK_COMMAND="/usr/bin/newtask -p ${RESOURCE_PROJECT_NAME}"

        debug_message "Function: srm_function - End"

        return 0
}

create_dummy_process()
{
        debug_message "Function: create_dummy_process - Begin"
        $SET_DEBUG

        DUMMY_PROCESS="/tmp/${RESOURCE}_${RESOURCEGROUP}_dummy.csh"

        cat > ${DUMMY_PROCESS} <<-EOF
	#!/bin/csh

	while (1)
		sleep 3600
	end
	EOF

        /bin/chmod 755 ${DUMMY_PROCESS}

        ${DUMMY_PROCESS} &

        scds_syslog -p daemon.notice -t $(syslog_tag) -m \
                "Create_dummy_process - Concurrent Manager was manually started"

        debug_message "Function: create_dummy_process - End"
}

wait_for_db()
{
	# 
	# Check that Oracle is available
	#

	debug_message "Function: wait_for_db - Begin"
	$SET_DEBUG

        . ${ORACLE_HOME}/${APP_SID}.env

	echo ORA- > ${TMPFILE}

	while grep ORA- ${TMPFILE} > /dev/null
	do
		sleep 2
		echo exit | ${ORACLE_HOME}/bin/sqlplus -s \
                	apps/${APPS_PASSWD}@${SID} > $TMPFILE
	done

	debug_message "Function: wait_for_db - End"
}

check_ld_preload()
{
	# 
	# Check LD_PRELOAD path 
	#
	
	debug_message "Function: check_ld_preload - Begin"
	$SET_DEBUG

        #
        # Check if a secure path is used for LD_PRELOAD
	#  otherwise we accept the warning message, ie
	#  warning illegal insecure pathname
        #

	case $SECURE in
		Y|y)	LDPRE_PATH=/usr/lib/secure
			;;
		*)	LDPRE_PATH=${BASEDIR}/${BIT}
			;;
	esac
		
	#
	# If /usr/lib/secure is being used then at installation
	#  time a symlink needs to be setup for the appropiate 
	#  $BASEDIR/32 or 64-bit directory containing libloghost.so.1
	#

	LDPRELOAD="LD_PRELOAD_${BIT}=${LDPRE_PATH}/libloghost.so.1"

	debug_message "Function: check_ld_preload - End"
}

start_cmg()
{
	#
	# Start cmg
	#

        debug_message "Function: start_cmg - Begin"
	$SET_DEBUG
	
        #
        # This should take care of sh, ksh, csh, tcsh and bash
        #

	srm_function ${CON_APPSUSER}

	check_ld_preload

        if getent passwd ${CON_APPSUSER} | awk -F: '{print $7}' | grep csh > /dev/null
        then
                su ${CON_APPSUSER} -c "$TASK_COMMAND env $LHOSTNAME env $LDPRELOAD \
			${CON_COMNTOP}/admin/scripts/${APP_SID}/adcmctl.sh start \
			apps/${APPS_PASSWD} >& ${LOGFILE}" > /dev/null
                rc_start_cmg=$?
        else
                su ${CON_APPSUSER} -c "$TASK_COMMAND env $LHOSTNAME env $LDPRELOAD \
			${CON_COMNTOP}/admin/scripts/${APP_SID}/adcmctl.sh start \
			apps/${APPS_PASSWD} >${LOGFILE} 2>&1" > /dev/null
                rc_start_cmg=$?
        fi

	debug_message "Function: start_cmg - End"
}

stop_cmg()
{
       	#
	# Stop cmg
	#

        debug_message "Function: stop_cmg - Begin"
	$SET_DEBUG
	
        #
        # This should take care of sh, ksh, csh, tcsh and bash
        #

	srm_function ${CON_APPSUSER}

	check_ld_preload

        if getent passwd ${CON_APPSUSER} | awk -F: '{print $7}' | grep csh > /dev/null
        then
                su ${CON_APPSUSER} -c "$TASK_COMMAND env $LHOSTNAME env $LDPRELOAD \
			${CON_COMNTOP}/admin/scripts/${APP_SID}/adcmctl.sh stop \
			apps/${APPS_PASSWD} >& ${LOGFILE}" > /dev/null
                rc_stop_cmg=$?
        else
                su ${CON_APPSUSER} -c "$TASK_COMMAND env $LHOSTNAME env $LDPRELOAD \
			${CON_COMNTOP}/admin/scripts/${APP_SID}/adcmctl.sh stop \
			apps/${APPS_PASSWD} >${LOGFILE} 2>&1" > /dev/null
                rc_stop_cmg=$?
        fi

        if [ "$rc_stop_cmg" -ne 0 ]
        then
                log_message err stop_cmg
        fi

	debug_message "Function: stop_cmg - End"
}

cleanup_cmg()
{
       	#
	# Cleanup cmg
	#

        debug_message "Function: cleanup_cmg - Begin"
	$SET_DEBUG

	for pid in `pgrep -f -u ${CON_APPSUSER} FND` 
	do
		kill -9 $pid
	done

	debug_message "Function: cleanup_cmg - End"
}

orderly_stop_cmg()
{
	#
	# Orderly stop cmg
	#

	debug_message "Function: orderly_stop_cmg - Begin"
	$SET_DEBUG

        for func in stop_cmg \
                    cleanup_cmg
        do
                case $func in
                        stop_cmg)       ((FORCE_TIME=$STOP_TIMEOUT *75/100));;
                        cleanup_cmg)    ((FORCE_TIME=$STOP_TIMEOUT *5/100));;
                esac

                LOOP_TIME=$FORCE_TIME

                $func

                # Test if any ${CON_APPSUSER} FND pids are still running

                while (( $LOOP_TIME > 0 ))
                do
                        if pgrep -f -u ${CON_APPSUSER} FND > /dev/null
                        then
                                sleep 1
                                LOOP_TIME=`expr $LOOP_TIME - 1`
                        else
                                break
                        fi
                done

                # Test if we broke out of the loop or the time
                # allocated for the function has expired.

                if pgrep -f -u ${CON_APPSUSER} FND > /dev/null
                then
                        continue
                else
                        # Break out of running all the functions
                        break
                fi
        done

	debug_message "Function: orderly_stop_cmg - End"
}
	
check_cmg()
{
	#
	# Check the concurrent managers
	#

        debug_message "Function: check_cmg - Begin"
	$SET_DEBUG

	rc_check_cmg=0

	#
	# As wait_for_online processing also calls the probe
	#  we only try the full probe if there are a few 
	#  concurrent manager processes running
	#
	
	if [ `pgrep -f -u ${CON_APPSUSER} FND | wc -l` -le 1 ]
	then
		rc_check_cmg=100
		return
	fi

	#
	# Check for the Internal Manager pid
	#  (Ensures a quick bail out if the IM goes down)
	#

	if pgrep -f -u ${CON_APPSUSER} CPMGR > /dev/null
	then
		debug_message "check_cmg - Internal Manager found"
	else
		rc_check_cmg=100
		return
	fi

	# 
	# Test if we can still connect to the database
	#  otherwise we request a restart after two 
	#  two failures within the probe_interval
	#

	. ${ORACLE_HOME}/${APP_SID}.env

        echo exit | ${ORACLE_HOME}/bin/sqlplus -s \
		apps/${APPS_PASSWD}@${SID} > $TMPFILE

	if grep ORA- $TMPFILE >/dev/null
	then
		scds_syslog -p daemon.err -t $(syslog_tag) -m \
			"check_cmg - Database connect to %s failed" \
			"${SID}"

		rc_check_cmg=50
		return
	else
		debug_message "check_cmg - Database connect ${SID} OK"
	fi

	#
	# Calculate the number of concurrent processes running as a percentage
	# 	the maximum number of concurrent processes allowed
	#
	
	output="set echo off verify off termout off feedback off head off"

	sqlrun="select count(*) Actual from apps.fnd_v\$process, apps.fnd_concurrent_processes \
		where Pid = Oracle_Process_ID And Spid = Os_Process_ID \
		And (Process_Status_Code in ('A', 'C', 'T'));"

	sqlmax="select sum(MAX_PROCESSES) Target from apps.Fnd_Concurrent_Queues ;"

	. ${ORACLE_HOME}/${APP_SID}.env

	# Find number of concurrent processes running

	${ORACLE_HOME}/bin/sqlplus -s apps/${APPS_PASSWD}@${SID} <<-END > $TMPFILE
	$output 
	$sqlrun
	END

	integer FNDRUN=`tail -1 $TMPFILE | awk '{print $1}'`

	# Find maximum number of concurrent processes

	${ORACLE_HOME}/bin/sqlplus -s apps/${APPS_PASSWD}@${SID} <<-END > $TMPFILE
	$output
	$sqlmax
	END

	integer FNDMAX=`tail -1 $TMPFILE | awk '{print $1}'`

	# Calculate the percentage

	integer ACTUAL=`echo "$FNDRUN / $FNDMAX * 100" | bc -l`

	# Test if actual percentage is less than the user defined limit

	if [ "$FNDRUN" -lt "$FNDMAX" ] 
	then
		if [ $ACTUAL -lt $CON_LIMIT ]
		then
                	scds_syslog -p daemon.err -t $(syslog_tag) -m \
                        	"check_cmg - Actual (%s) FND processes running is below limit (%s)" \
				"${ACTUAL}%" "${CON_LIMIT}%"

                	scds_syslog -p daemon.err -t $(syslog_tag) -m \
                        	"check_cmg - FUNDRUN =  %s, FNDMAX = %s" \
				"${FNDRUN}" "${FNDMAX}"

			rc_check_cmg=50
		else
			debug_message "check_cmg - FNDRUN = ${FNDRUN}, FNDMAX = ${FNDMAX}"
		fi
	else
		debug_message "check_cmg - FNDRUN = ${FNDRUN}, FNDMAX = ${FNDMAX}"
	fi

	debug_message "Function: check_cmg - End"
}

set_status()
{
        #
        # Set appropriate resource status
        #

        debug_message "Function: set_status - Begin"
        $SET_DEBUG

        STATUS_TYPE=$1

        scha_resource_setstatus -R $RESOURCE -G $RESOURCEGROUP -s $STATUS_TYPE

        rc_scha_resource_setstatus=$?

        if [ "$rc_scha_resource_setstatus" != 0 ]
        then
                scds_syslog -p daemon.err -t $(syslog_tag) -m \
                "set_status - rc<%s>  type<%s>" \
                "${rc_scha_resource_setstatus}" "${STATUS_TYPE}"
        fi

        debug_message "Function: set_status - End"
}

