#!/bin/sh
#  ALTRAN_PROLOG_BEGIN_TAG                                                    
#  This is an automatically generated prolog.                                  
#                                                                              
#  Copyright (C) Altran ACT S.A.S. 2017,2018,2020,2021.  All rights reserved.  
#                                                                              
#  ALTRAN_PROLOG_END_TAG                                                      
#                                                                              
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
# 61haes_r721 src/43haes/usr/sbin/cluster/sa/sap/sbin/SAPUtilities_xplatform.sh 1.18 
#  
# Licensed Materials - Property of IBM 
#  
# Restricted Materials of IBM 
#  
# COPYRIGHT International Business Machines Corp. 2013,2016 
# All Rights Reserved 
#  
# US Government Users Restricted Rights - Use, duplication or 
# disclosure restricted by GSA ADP Schedule Contract with IBM Corp. 
#  
# IBM_PROLOG_END_TAG 


#  @(#)  7d4c34b 43haes/usr/sbin/cluster/sa/sap/sbin/SAPUtilities_xplatform.sh, 726, 2147A_aha726, Feb 05 2021 09:50 PM

##
## NAME:    SAPUtilities_xplatform
##
## PURPOSE:
##          cross platform HA function library
##
##
## Conventions:
##       1) The shell should remain sh to be also supported under Systemz
##       2) Logging level 0:
##          * each return code is extended by an exported variable to pass fillings to the caller
##

typeset version="1.18"

#############################################################
##  Create Environment for Cluster Product and OS. 
#############################################################
# get platform where we are running on
RUNNING_ON_LINUX=0
RUNNING_ON_AIX=1
RUNNING_ON_OS390=0 # z/OS Unix System Services (OS390)
RUNNING_ON_POWERHA=1
RUNNING_ON_TSA=0

CUT=/usr/bin/cut
case $(/bin/uname) in
  "Linux")
      RUNNING_ON_LINUX=1
      RUNNING_ON_AIX=0
      INSTALL_DIR=$(/usr/bin/dirname $0)
      GREP_cmd=/bin/grep
      AWK_cmd=/bin/awk
      ECHO_cmd=/bin/echo
      PING_cmd=/bin/ping
      PING_timeout_flag=-w
      RPCINFO_cmd=/bin/rpcinfo
      SHOWMOUNT_cmd=
      MOUNT_cmd=/bin/mount
      SU_cmd=/bin/su
      HOSTNAME_cmd=/bin/hostname
      CAT_cmd=/bin/cat
      PS_cmd=/bin/ps
      PIDMON_cmd=/bin/pidmon
      KILL_cmd=/bin/kill
      SED_cmd=/bin/sed
      if [ -a /etc/SuSE-release ]
      then
        CUT=/usr/bin/cut
      else
        CUT=/bin/cut
      fi  
    ;;
  "AIX")  
      RUNNING_ON_AIX=1
      GREP_cmd=/usr/bin/grep
      EGREP_cmd=/usr/bin/egrep
      AWK_cmd=/usr/bin/awk
      ECHO_cmd=/usr/bin/echo
      PING_cmd=/etc/ping
      PING_timeout_flag=-w
      RPCINFO_cmd=/usr/bin/rpcinfo
      SHOWMOUNT_cmd=/usr/bin/showmount
      MOUNT_cmd=/usr/sbin/mount
      SU_cmd=/usr/bin/su
      HOSTNAME_cmd=/usr/bin/hostname
      CAT_cmd=/usr/bin/cat
      PS_cmd=/usr/bin/ps
      PIDMON_cmd=/bin/pidmon
      KILL_cmd=/usr/bin/kill
      SED_cmd=/usr/bin/sed
      CUT_cmd=/usr/bin/cut
      SLEEP_cmd=/usr/bin/sleep
      WHOAMI_cmd=/usr/bin/whoami
      if [ -e /usr/es/sbin/cluster/utilities/clmgr ]
      then
           RUNNING_ON_POWERHA=1
      else
          INSTALL_DIR=$(/usr/bin/dirname $0)
      fi
    ;;
  "OS/390")
      RUNNING_ON_OS390=1
      INSTALL_DIR=$(/bin/dirname $0)
      GREP_cmd=/bin/grep
      AWK_cmd=/bin/awk
      ECHO_cmd=echo
      CUT=/bin/cut
      SED_cmd=/bin/sed
      PING_cmd=/bin/ping
      PING_timeout_flag=-t
      RPCINFO_cmd=/bin/rpcinfo
      SHOWMOUNT_cmd=/usr/lpp/NFS/showmount
      MOUNT_cmd=/usr/sbin/mount
      DISPLAY_FILESYSTEM_cmd=/bin/df   
      SU_cmd=/bin/su
      HOSTNAME_cmd=/bin/hostname
      CAT_cmd=/bin/cat
      PS_cmd=/bin/ps
      PIDMON_cmd=/bin/pidmon
      KILL_cmd=/bin/kill
      SED_cmd=/bin/sed
      WHOAMI_cmd=/bin/whoami
    ;;
  *)
    OSNAME=$(/bin/uname)
    echo 0 ESAMS1172 $0 "${OSNAME}"
    if (( $RUNNING_ON_POWERHA == 1 )) ; then
        exit 1  #PowerHA specifics
    else
        exit 16
     fi  
    ;;
esac  


#############################################################
##  DEBUG - specify the amount of data written to the cluster specific logfiles 
#############################################################

#SAPUtilities_xplatform function to ensure logs are written to the cluster specific log files
trace_msg(){
  (( ${RUNNING_ON_TSA} == 1 )) && {
    return 0	
  }

  (( ${RUNNING_ON_POWERHA} == 1 )) && {
    (( $1 <= $sa_sap_xplatform_logging )) && (( $1 > 0 )) && { 
      shift 1;
      date=$(date)
      echo "${date} $@" >> ${logger_logfile}
    }  
  }
}

#############################################################
##  Returncodes of the functions 
#############################################################
typeset -i RC_WRONG_INPUT=100

common_function_filling=""     #only words which do not need translation 
common_function_returnstring="" #full text description

#Returncodes of sapcontrol: 0,1,2,3,4
#0  Last webmethod call successful
#1  Last webmethod call failed, invalid parameter
#2  StartWait, StopWait, WaitforStarted, WaitforStopped, RestartServiceWait timed out
#3  GetProcessList succeeded, all processes running correctly
#4  GetProcessList succeeded, all processes stopped
typeset -i sapcontrol_0=0
typeset -i sapcontrol_1=1
typeset -i sapcontrol_2=2
typeset -i sapcontrol_3=3
typeset -i sapcontrol_4=4

#Generic RC
#checks performed for RC contrain "-lt" KEEP ORDER
typeset -i OK=0
typeset -i WARNING=1
typeset -i ERROR=2

#Control_sapstartsrv "Check"
#checks performed for RC contrain "-lt" KEEP ORDER
#Returncodes 0, 1, 2
typeset -i Check_instance_OK=0
typeset -i Check_instance_WARNING=1
typeset -i Check_instance_ERROR=2

#Control_sapstartsrv   Prereq_and_start_cmd )  
#checks performed for RC contrain "-lt" KEEP ORDER
#Returncodes: 0,1
typeset -i sapstartsrv_running=0
typeset -i sapstartsrv_failed_to_start=1

#Control_instance   Start_cmd )
#checks performed for RC contain "-lt" KEEP ORDER
#Returncodes: 0,1,2,3
typeset -i instance_started=0
typeset -i wait_for_started_timeout=1
typeset -i wait_for_started_failed=2
typeset -i instance_failed_to_start=3

#Control_instance      Check_cmd ) 
#checks performed for RC contain "-lt" KEEP ORDER
#Returncodes: 0,1,2,3,4
typeset -i GetProcessList_GREEN=0     #(returncode if ${INSTANCE_TYPE} != @(ERS|*SCS) or replication disabled
typeset -i EnqGetStatistic_GREEN=1    #(returncode if ${INSTANCE_TYPE} == @(ERS|*SCS)
typeset -i EnqGetStatistic_YELLOW=2    #(returncode if ${INSTANCE_TYPE} == @(ERS|*SCS)
typeset -i EnqGetStatistic_err=3      #(returncode if ${INSTANCE_TYPE} == @(ERS|*SCS)
typeset -i GetProcessList_not_GREEN=4
typeset -i GetProcessList_ERROR=5

#Control_eval_severity_instance *SCS)
#checks performed for RC contain "-lt" KEEP ORDER
    #Returncodes:
typeset -i GetProc_en_mod=100      
typeset -i GetProc_en_GREEN=0
typeset -i GetProc_en_YELLOW=10
typeset -i GetProc_en_GRAY=20
typeset -i GetProc_en_RED=30

typeset -i GetProc_ms_mod=1000
typeset -i GetProc_ms_GREEN=0
typeset -i GetProc_ms_YELLOW=100
typeset -i GetProc_ms_GRAY=200
typeset -i GetProc_ms_RED=300

typeset -i GetProc_gw_mod=10  
typeset -i GetProc_gw_GREEN=0
typeset -i GetProc_gw_YELLOW=1
typeset -i GetProc_gw_GRAY=2
typeset -i GetProc_gw_RED=3

#Control_eval_severity_instance "ABAP")
typeset -i GetProc_dw_mod=100    
typeset -i GetProc_dw_GREEN=0
typeset -i GetProc_dw_YELLOW=10
typeset -i GetProc_dw_GRAY=20
typeset -i GetProc_dw_RED=30

typeset -i GetProc_ig_mod=1000    
typeset -i GetProc_ig_GREEN=0
typeset -i GetProc_ig_YELLOW=100
typeset -i GetProc_ig_GRAY=200
typeset -i GetProc_ig_RED=300
  #reuse GetProc_gw_*
typeset -i GetProc_icm_mod=10000  
typeset -i GetProc_icm_GREEN=0
typeset -i GetProc_icm_YELLOW=1000
typeset -i GetProc_icm_GRAY=2000
typeset -i GetProc_icm_RED=3000    

#Control_eval_severity_instance "JAVA")

typeset -i GetProc_jc_mod=10  
typeset -i GetProc_jc_GREEN=0
typeset -i GetProc_jc_YELLOW=1
typeset -i GetProc_jc_GRAY=2
typeset -i GetProc_jc_RED=3  
  #reuse GetProc_ig_*
typeset -i J2EEGetProc_ser0_mod=100000  
typeset -i J2EEGetProc_ser0_GREEN=0
typeset -i J2EEGetProc_ser0_YELLOW=10000
typeset -i J2EEGetProc_ser0_GRAY=20000
typeset -i J2EEGetProc_ser0_PA=30000
 
typeset -i J2EEGetProc_sdm_mod=100  
typeset -i J2EEGetProc_sdm_GREEN=0
typeset -i J2EEGetProc_sdm_YELLOW=10
typeset -i J2EEGetProc_sdm_GRAY=20
typeset -i J2EEGetProc_sdm_PA=30 

#Control_eval_severity_instance "DUAL")
  #reuse GetProc_dw_*  
  #reuse GetProc_ig_*
  #reuse J2EEGetProc_icm_
  #reuse J2EEGetProc_ser0_

typeset -i J2EEGetProc_prx_mod=10
typeset -i J2EEGetProc_prx_GREEN=0
typeset -i J2EEGetProc_prx_YELLOW=1
typeset -i J2EEGetProc_prx_GRAY=2
typeset -i J2EEGetProc_prx_PA=3

typeset -i GetProc_rs_mod=1000000   
typeset -i GetProc_rs_GREEN=0
typeset -i GetProc_rs_YELLOW=100000
typeset -i GetProc_rs_GRAY=200000
typeset -i GetProc_rs_RED=300000

typeset -i GetProc_rc_mod=10000000   
typeset -i GetProc_rc_GREEN=0
typeset -i GetProc_rc_YELLOW=1000000
typeset -i GetProc_rc_GRAY=2000000
typeset -i GetProc_rc_RED=3000000

#Control_eval_severity_instance ERS)
#checks performed for RC contain "-lt" KEEP ORDER
#Returncodes:
typeset -i GetProc_er_GREEN=0
typeset -i GetProc_er_YELLOW=1
typeset -i GetProc_er_GRAY=2
typeset -i GetProc_er_RED=3

#Check_replication_status
#checks performed for RC contain "-lt" KEEP ORDER
#Returncodes:
typeset -i Check_Replication_OK=0
typeset -i Check_Replication_CS_WARNING=1   
typeset -i Check_Replication_ERS_WARNING=2  
typeset -i Check_Replication_ERROR=3

#############################################################
##  Generic Functions - here no customization should be required. 
##  The APIs must remain stable
##  Shipped or proved changes must be uploaded into the development 
##  exchange repository for the Lab BB HA collaboration at:  
#############################################################

Control_sapstartsrv(){
  #reset getopt index
  OPTIND=1
  while getopts A:I:S:E:V:L:J: option
  do
    case $option in
      A)  #Action
          ACTION=$OPTARG
      ;;
      I)  #Instance Name e.g. ASCS00  
          INSTANCE=$OPTARG
      ;;
      S)  #SID
          SID=$OPTARG
      ;;
      E)  #Executable Directory if sapcpe: /usr/sap/SID/INSTANCE/exe else: /usr/sap/SID/SYS/exe/run
          EXE_DIR=$OPTARG
      ;;
      V)  #Virtual IP the Instance is installed with or hostname 
          VirtualIP=$OPTARG
      ;;
      L)  #PowerHA Language
          LAN=$OPTARG
      ;;
      J)  #Tivoli Job name
          JobName=$OPTARG
      ;;
      *)
          #error or warning msg
      ;;
    esac
  done
            
  [[ -z $EXE_DIR ]]  && EXE_DIR=/usr/sap/${SID}/SYS/exe/run            
  typeset -l LC_SID=$SID        
  typeset USER="${LC_SID}adm"
  typeset INST_DIR=/usr/sap/${SID}/${INSTANCE}     
  typeset INSTANCE_TYPE=${INSTANCE%[0-9][0-9]}
  typeset INSTANCE_NO=${INSTANCE#${INSTANCE_TYPE}} 
  typeset -i kill_flag=0
      
  #we use -host VirtualIP to ensure this is a healthy channel also from  SAP perspective.
  #On AIX for function call StartService only the LPAR hostname will be # #accepted. 
  #Here it will not bring the call to fail if it would be set to 
  #VirtualIP. Therefore we encapsulate to be able to handle this later.
  typeset HOST_cmd="-host ${VirtualIP}"
  
  typeset USER_cmd="/usr/bin/su - ${USER} -c" 
          
  case "$ACTION" in
   Start ) 
       trace_msg 2 "Enter function Control_sapstartsrv() Start.\n"
       #Returncodes: 0,1
       #0  Last webmethod call successful
       #1  Last webmethod call failed, invalid parameter
       #2  StartWait, StopWait, WaitforStarted, WaitforStopped, RestartServiceWait timed out
       #3  GetProcessList succeeded, all processes running correctly
       #4  GetProcessList succeeded, all processes stopped
         
       HOST_cmd="" #AIX and OS390 cannot run this particular command using hostname info. 

       #Adding call for WaitforServiceStarted to catch the timing issue for instance start failures.
       #This will ensure that sapstartsrv is ready before we proceed to start the instance.
                   
       ${USER_cmd} "${LAN} ${EXE_DIR}/sapcontrol ${HOST_cmd} -nr ${INSTANCE_NO} -function StartService ${SID}" 
       typeset -i rc=$? 
       common_function_returnstring="${USER_cmd} ${LAN} ${EXE_DIR}/sapcontrol ${HOST_cmd} -nr ${INSTANCE_NO} -function StartService ${SID} returned ${rc}.\n"
       trace_msg 1 $common_function_returnstring "returncode: " $rc 
       ${USER_cmd} "${LAN} ${EXE_DIR}/sapcontrol ${HOST_cmd} -nr ${INSTANCE_NO} -function WaitforServiceStarted 120 0"
       typeset -i rc=$? 
       common_function_returnstring="${USER_cmd} ${LAN} ${EXE_DIR}/sapcontrol ${HOST_cmd} -nr ${INSTANCE_NO} -function WaitforServiceStarted 120 0 returned ${rc}.\n"
       trace_msg 1 $common_function_returnstring "returncode: " $rc 
       return $rc
   ;; 
   Stop  )
       trace_msg 2 "Enter function Control_sapstartsrv() Stop.\n"
       #Returncodes: 0,1
       #0  Last webmethod call successful
       #1  Last webmethod call failed, invalid parameter
       #2  StartWait, StopWait, WaitforStarted, WaitforStopped, RestartServiceWait timed out
       #3  GetProcessList succeeded, all processes running correctly
       #4  GetProcessList succeeded, all processes stopped
       ${USER_cmd} "${LAN} ${EXE_DIR}/sapcontrol ${HOST_cmd} -nr ${INSTANCE_NO} -function StopService" 
       typeset -i rc=$? 
       common_function_returnstring="${USER_cmd} ${LAN} ${EXE_DIR}/sapcontrol ${HOST_cmd} -nr ${INSTANCE_NO} -function StopService returned with ${rc}.\n"
       trace_msg 2 $common_function_returnstring "returncode: " $rc
       return $rc  
   ;;
   Check )
       trace_msg 2 "Enter function Control_sapstartsrv() Check.\n"
       #Returncodes 0, 1, 2
       #0  Check_instance_OK
       #2  Check_instance_ERROR
       #1  Check_instance_WARNING
       typeset -i rc=0
       ${USER_cmd} "${LAN} ${EXE_DIR}/sapcontrol ${HOST_cmd} -nr ${INSTANCE_NO} -function GetVersionInfo"  
       [[ $? == 0 ]] && {
         common_function_returnstring="${USER_cmd} ${LAN} ${EXE_DIR}/sapcontrol ${HOST_cmd} -nr ${INSTANCE_NO} -function GetVersionInfo"
         trace_msg 3 $common_function_returnstring "returncode: 0" 
         return $Check_instance_OK
       }
       ${PS_cmd} -fu ${USER}| ${GREP_cmd} "sapstartsrv" | ${GREP_cmd} -q ${INSTANCE}  
       [[ $? == 0 ]] && {
          common_function_returnstring="ps -fu ${USER} found sapstartsrv process for ${INSTANCE}. \nPrevious check sapcontrol ${HOST_cmd} -nr ${INSTANCE_NO} -function GetVersionInfo failed. \nThe sapstartsrv might not work as expected.\n"
          trace_msg 2 $common_function_returnstring "returncode: 0" 
          return $Check_instance_WARNING
       }
       common_function_returnstring="ps -fu ${USER} did not find any sapstartsrv process for ${INSTANCE}.\n"
       trace_msg 1 $common_function_returnstring "returncode: ERROR"
       return $Check_instance_ERROR
   ;;
   Prereq_and_start_cmd )  
       trace_msg 2 "Enter function Control_sapstartsrv() Prereq_and_start_cmd.\n"
       #Returncodes: 0,1
       #0 sapstartsrv_running
       #1 sapstartsrv_failed_to_start
       #ensure sapstartsrv is started or can be started
       Control_sapstartsrv -A "Check" -I ${INSTANCE} -S ${SID} -E ${EXE_DIR} -V ${VirtualIP} -L "${LAN}"  
       rc=$? 
       common_function_returnstring="sapcontrol ${HOST_cmd} -nr ${INSTANCE_NO} -function GetVersionInfo.\n"
       trace_msg 2 $common_function_returnstring "returncode: " $rc
       [[ $rc == $Check_instance_OK ]] && return $sapstartsrv_running
       #start sapstartsrv
       Control_sapstartsrv -A "Start" -I ${INSTANCE} -S ${SID} -E ${EXE_DIR} -V ${VirtualIP} -L "${LAN}" 
       rc=$? 
       common_function_returnstring="sapcontrol ${HOST_cmd} -nr ${INSTANCE_NO} -function StartService ${SID} returned ${rc}.\n"
       trace_msg 2 $common_function_returnstring "returncode: " $rc
       [[ $rc == $sapcontrol_0 ]] &&  return $sapstartsrv_running
       return $sapstartsrv_failed_to_start 
   ;;
   Kill )
       trace_msg 2 "Enter function Control_sapstartsrv() Kill.\n"
       #Returncodes: 0
       #0 OK 
       ${PS_cmd} -u $USER -o pid=,args= | ${GREP_cmd} $INSTANCE | ${GREP_cmd} "sapstartsrv" | while read PID CMD
       do
       	 trace_msg 3 "Kill process ${PID}."
         ${KILL_cmd} -2 $PID
         ${SLEEP_cmd} 1
         kill_flag=1
       done
       if (( ${kill_flag} == 1 ))
       then
           trace_msg 3 "sleep 5 seconds to make sure all the process are died...\n"
           ${SLEEP_cmd} 5
       fi
       common_function_returnstring="Executed ${KILL_cmd} -2 ${PID}.\n"
       trace_msg 2 $common_function_returnstring 
       return $OK
   ;;
   *     )
       common_function_returnstring="Function Control_sapstartsrv called with invalid ACTION of ${ACTION}.\n"
       trace_msg 2 $common_function_returnstring 
       return $RC_WRONG_INPUT
   ;;
  esac
  common_function_returnstring="Function Control_sapstartsrv failed. \n"
  trace_msg 2 $common_function_returnstring
  return $RC_WRONG_INPUT
}

Control_instance(){
  #reset getopt index
  OPTIND=1
  while getopts A:I:S:E:V:L:J:T: option
  do
    case $option in
      A)  #Action
          ACTION=$OPTARG
      ;;
      I)  #Instance Name e.g. ASCS00  
          INSTANCE=$OPTARG
      ;;
      S)  #SID
          SID=$OPTARG
      ;;
      E)  #Executable Directory if sapcpe: /usr/sap/SID/INSTANCE/exe else: /usr/sap/SID/SYS/exe/run
          EXE_DIR=$OPTARG
      ;;
      V)  #Virtual IP the Instance is installed with or hostname 
          VirtualIP=$OPTARG
      ;;
      L)  #PowerHA Language
          LAN=$OPTARG
      ;;
      J)  #Tivoli Job name
          JobName=$OPTARG
      ;;
      T)  #Timeout
          TIMEOUT=$OPTARG
      ;;
      *)
          #error or warning msg
      ;;
    esac
  done
  [[ -z $EXE_DIR ]]  && EXE_DIR=/usr/sap/${SID}/SYS/exe/run            
  typeset -l LC_SID=$SID        
  typeset USER="${LC_SID}adm"
  typeset INST_DIR=/usr/sap/${SID}/${INSTANCE}     
  typeset INSTANCE_TYPE=${INSTANCE%[0-9][0-9]}
  typeset INSTANCE_NO=${INSTANCE#${INSTANCE_TYPE}} 
      
  #we use -host VirtualIP to ensure this is a healthy channel also from  SAP perspective.
  #On AIX for function call StartService only the LPAR hostname will be accepted. 
  #Here it will not bring the call to fail if it would be set to 
  #VirtualIP. Therefore we encapsulate to be able to handle this later.
  typeset HOST_cmd="-host ${VirtualIP}"
  
  typeset USER_cmd="/usr/bin/su - ${USER} -c" 
    
  #Local_Host needs to be set if Rename_to_host renamed kill.sap/shutdown.sap
  typeset Local_HOST=""
  (( $RUNNING_ON_POWERHA == 1 )) && typeset Local_HOST=".$(hostname)" 
         
  case $ACTION in
    Stop  )
       trace_msg 2 "Enter function Control_instance() Stop.\n"
       #Returncodes: 0,1
       #0  Last webmethod call successful
       #1  Last webmethod call failed, invalid parameter
       #2  StartWait, StopWait, WaitforStarted, WaitforStopped, RestartServiceWait timed out
       #3  GetProcessList succeeded, all processes running correctly
       #4  GetProcessList succeeded, all processes stopped   
       ${USER_cmd} "${LAN} ${EXE_DIR}/sapcontrol ${HOST_cmd} -nr ${INSTANCE_NO} -function Stop"
       typeset -i rc=$? 
       common_function_returnstring="${USER_cmd} ${LAN} ${EXE_DIR}/sapcontrol ${HOST_cmd} -nr ${INSTANCE_NO} -function Stop returned ${rc}.\n"
       trace_msg 2 $common_function_returnstring "returncode: " $rc
       return $rc     
    ;;
    Start_cmd )
       trace_msg 2 "Enter function Control_instance() Start_cmd.\n"
       #Returncodes: 0,1,2,3
       #0  instance_started
       #1  wait_for_started_timeout
       #2  wait_for_started_failed
       #3  instance_failed_to_start
    
       ${USER_cmd} "${LAN} ${EXE_DIR}/sapcontrol ${HOST_cmd} -nr ${INSTANCE_NO} -function Start" 
       typeset -i rc=$?
       (( $rc == 0 )) && {
         ${USER_cmd} "${LAN} ${EXE_DIR}/sapcontrol ${HOST_cmd} -nr ${INSTANCE_NO} -function WaitforStarted ${TIMEOUT}" 
         rc=$?
         common_function_returnstring="${USER_cmd} ${LAN} ${EXE_DIR}/sapcontrol ${HOST_cmd} -nr ${INSTANCE_NO} -function WaitforStarted ${TIMEOUT} returned ${rc}.\n"
         trace_msg 2 $common_function_returnstring "returncode: " $rc
         [[ $rc == 0 ]] && return $instance_started
         [[ $rc == 2 ]] && return $wait_for_started_timeout
         return $wait_for_started_failed
       }
       common_function_returnstring="${USER_cmd} ${LAN} ${EXE_DIR}/sapcontrol ${HOST_cmd} -nr ${INSTANCE_NO} -function Start returned ${rc}.\n"
       trace_msg 2 $common_function_returnstring "returncode: " $rc
       return $instance_failed_to_start     
    ;;
    Check_cmd ) 
       trace_msg 2 "Enter function Control_instance() Check_cmd.\n"
       #Returncodes: 0,1,2,3,4
       #0  GetProcessList_GREEN   (returncode if ${INSTANCE_TYPE} != @(ERS|*SCS)
       #1  EnqGetStatistic_GREEN    (returncode if ${INSTANCE_TYPE} == @(ERS|*SCS)
       #2  EnqGetStatistic_YELLOW  (returncode if ${INSTANCE_TYPE} == @(ERS|*SCS)
       #3  EnqGetStatistic_err    (returncode if ${INSTANCE_TYPE} == @(ERS|*SCS)
       #4  GetProcessList_not_GREEN
    
       ${USER_cmd} "${LAN} ${EXE_DIR}/sapcontrol ${HOST_cmd} -nr ${INSTANCE_NO} -function GetProcessList" 
       typeset -i rc=$?
       (( $rc == 3 )) && {
         [[ ${INSTANCE_TYPE} == @(*SCS) ]] && [[ ${is_ers_enabled} == 1 ]] && { 
           #EnqGetStatistic: OSS NOTE 1751819 will not work for ERS Instances as of March 2013!
           GetEnqStat=$(${USER_cmd} "${LAN} ${EXE_DIR}/sapcontrol ${HOST_cmd} -nr ${INSTANCE_NO} -function EnqGetStatistic" | awk '/replication_state/ {print $2}')    
           [[ "${GetEnqStat}" == "GREEN" ]] && {
              common_function_returnstring=""
              return $EnqGetStatistic_GREEN 
           }
           [[ "${GetEnqStat}" == "YELLOW" ]] && {
              common_function_returnstring="sapcontrol -function EnqGetStatistic returned a replication state of YELLOW.\n"
              trace_msg 2 $common_function_returnstring "returncode: " $rc
              return $EnqGetStatistic_YELLOW 
           }
           common_function_returnstring="sapcontrol -function EnqGetStatistic returned a replication state of GRAY or RED.\n"
           return $EnqGetStatistic_err #Processes running, but replication not in status Green
        }
        [[ ${INSTANCE_TYPE} == @(ERS) ]] && { 
          Check_replication_status -I $INSTANCE -S $SID -E ${EXE_DIR} -V ${VirtualIP} -L "${LAN}" -T "1"
          [[ $rc == $Check_Replication_OK ]] &&  return $EnqGetStatistic_GREEN 
          [[ $rc == $Check_Replication_ERROR ]] && return $EnqGetStatistic_err
          return $EnqGetStatistic_YELLOW
        }
        return $GetProcessList_GREEN
      }
      (( $rc == 4 )) && return $GetProcessList_not_GREEN
      common_function_returnstring="${USER_cmd} ${LAN} ${EXE_DIR}/sapcontrol ${HOST_cmd} -nr ${INSTANCE_NO} -function GetProcessList returned ${rc}.\n"
      trace_msg 2 $common_function_returnstring "returncode: " $rc
      # We will return GetProcessList_not_GREEN so so we can evaluate the status better in Monitor.
      return $GetProcessList_not_GREEN
      
    ;;
    *     )
       common_function_returnstring="Function Control_instance called with invalid ACTION of ${ACTION}.\n"
       trace_msg 2 $common_function_returnstring
       return $RC_WRONG_INPUT
    ;;
  esac
  common_function_returnstring=""
  return $RC_WRONG_INPUT
}

GetInstType(){ 
  #returncodes:
  #JAVA=0
  #DUAL=1
  #ABAP=2
  #reset getopt index
  OPTIND=1
  while getopts I:S:E:V:L:J: option
  do
    case $option in
      I)  #Instance Name e.g. ASCS00  
          INSTANCE=$OPTARG
      ;;
      S)  #SID
          SID=$OPTARG
      ;;
      E)  #Executable Directory if sapcpe: /usr/sap/SID/INSTANCE/exe else: /usr/sap/SID/SYS/exe/run
          EXE_DIR=$OPTARG
      ;;
      V)  #Virtual IP the Instance is installed with or hostname 
          VirtualIP=$OPTARG
      ;;
      L)  #PowerHA Language
          LAN=$OPTARG
      ;;
      J)  #Tivoli Job name
          JobName=$OPTARG
      ;;
      *)
          #error or warning msg
      ;;
    esac	
    done

  [[ -z $EXE_DIR ]] && EXE_DIR=/usr/sap/${SID}/SYS/exe/run            
  typeset -l LC_SID=$SID        
  typeset USER="${LC_SID}adm"
  typeset INST_DIR=/usr/sap/${SID}/${INSTANCE}     
  typeset INSTANCE_TYPE=${INSTANCE%[0-9][0-9]}
  typeset INSTANCE_NO=${INSTANCE#${INSTANCE_TYPE}} 
  
  trace_msg 2 "Enter function GetInstType.\n"
  #we use -host VirtualIP to ensure this is a healthy channel also from  SAP perspective.
  #On AIX for function call StartService only the LPAR hostname will be # #accepted. 
  #Here it will not bring the call to fail if it would be set to 
  #VirtualIP. Therefore we encapsulate to be able to handle this later.
  typeset HOST_cmd="-host ${VirtualIP}"
  
  typeset USER_cmd="/usr/bin/su - ${USER} -c" 
 
  res=$(${USER_cmd} "${LAN} ${EXE_DIR}/sapcontrol ${HOST_cmd} -nr ${INSTANCE_NO} -format script -function ParameterValue system/type" | grep "0 : " | cut -f2 -d : | tr -d " "  )
  trace_msg 2 "System Type: " $res
  [[ $res == DS ]] && return 1 #DUAL
  [[ $res == ABAP ]] && return 2
  [[ $res == @(JAVA||J2EE) ]] && return 0
  trace_msg 2 "System Type not found. ERROR, return with 3"
  return 3
}

Control_eval_severity_instance(){
  #reset getopt index
  OPTIND=1
  while getopts I:S:E:V:L:J:T: option
  do
    case $option in
      I)  #Instance Name e.g. ASCS00  
          INSTANCE=$OPTARG
      ;;
      S)  #SID
          SID=$OPTARG
      ;;
      E)  #Executable Directory if sapcpe: /usr/sap/SID/INSTANCE/exe else: /usr/sap/SID/SYS/exe/run
          EXE_DIR=$OPTARG
      ;;
      V)  #Virtual IP the Instance is installed with or hostname 
          VirtualIP=$OPTARG
      ;;
      L)  #PowerHA Language
          LAN=$OPTARG
      ;;
      J)  #Tivoli Job name
          JobName=$OPTARG
      ;;
      T)  #Timeout
          TIMEOUT=$OPTARG
      ;;
      *)
          #error or warning msg
      ;;
    esac
  done

  [[ -z $EXE_DIR ]] && EXE_DIR=/usr/sap/${SID}/SYS/exe/run            
  typeset -l LC_SID=$SID        
  typeset USER="${LC_SID}adm"
  typeset INST_DIR=/usr/sap/${SID}/${INSTANCE}     
  typeset INSTANCE_TYPE=${INSTANCE%[0-9][0-9]}
  typeset INSTANCE_NO=${INSTANCE#${INSTANCE_TYPE}} 

  #we use -host VirtualIP to ensure this is a healthy channel also from  SAP perspective.
  #On AIX for function call StartService only the LPAR hostname will be # #accepted. 
  #Here it will not bring the call to fail if it would be set to 
  #VirtualIP. Therefore we encapsulate to be able to handle this later.
  typeset HOST_cmd="-host ${VirtualIP}"
  
  typeset USER_cmd="/usr/bin/su - ${USER} -c" 
  
  #First handle CS and ERS instances, application server instances will follow later
  [[ $(${USER_cmd} "${LAN} ${EXE_DIR}/sapcontrol ${HOST_cmd} -nr ${INSTANCE_NO} -function GetProcessList -format script" | egrep -c "RED|GRAY|YELLOW|J2EE_RUNNING|J2EE_STOPPED|J2EE_CORE_RUNNING|J2EE_UNKNOWN|J2EE_STOPPING|J2EE_STARTING|J2EE_MAINTENANCE") == 0 ]] && return 3333333 #accumulated error codes for "RED" of all possible processes 
  case $INSTANCE_TYPE in   
    *SCS )
          trace_msg 2 "Enter function Control_eval_severity_instance *SCS.\n"
          typeset -i rc=0
          ${USER_cmd} "${LAN} ${EXE_DIR}/sapcontrol ${HOST_cmd} -nr ${INSTANCE_NO} -function GetProcessList" | tr -s ' ' '' | tr -d ' ' | tr ',' ' ' | while read name description dispstatus textstatus starttime elapsedtime pid
          do
          	[[ $description == "MessageServer" ]] && {
                  [[ $dispstatus == "GREEN" ]] && rc=$(( rc + GetProc_ms_GREEN ))
                  [[ $dispstatus == "RED" ]] && rc=$(( rc + GetProc_ms_RED ))
                  [[ $dispstatus == "GRAY" ]] && rc=$(( rc + GetProc_ms_GRAY ))
                  [[ $dispstatus == "YELLOW" ]] && rc=$(( rc + GetProc_ms_YELLOW ))
            }
            [[ $description == "EnqueueServer" ]] && {
            	  [[ $dispstatus == "GREEN" ]] && rc=$(( rc + GetProc_en_GREEN ))
                  [[ $dispstatus == "RED" ]] && rc=$(( rc + GetProc_en_RED ))
                  [[ $dispstatus == "GRAY" ]] && rc=$(( rc + GetProc_en_GRAY ))
                  [[ $dispstatus == "YELLOW" ]] && rc=$(( rc + GetProc_en_YELLOW ))
            }
            [[ $description == "EnqueueServer2" ]] && {
            	  [[ $dispstatus == "GREEN" ]] && rc=$(( rc + GetProc_en_GREEN ))
                  [[ $dispstatus == "RED" ]] && rc=$(( rc + GetProc_en_RED ))
                  [[ $dispstatus == "GRAY" ]] && rc=$(( rc + GetProc_en_GRAY ))
                  [[ $dispstatus == "YELLOW" ]] && rc=$(( rc + GetProc_en_YELLOW ))
            }			
            [[ $description == "Gateway" ]] && {   
                  [[ $dispstatus == "GREEN" ]] && rc=$(( rc + GetProc_gw_GREEN ))
                  [[ $dispstatus == "RED" ]] && rc=$(( rc + GetProc_gw_RED ))
                  [[ $dispstatus == "GRAY" ]] && rc=$(( rc + GetProc_gw_GRAY ))
                  [[ $dispstatus == "YELLOW" ]] && rc=$(( rc + GetProc_gw_YELLOW ))
            }          
          done
          common_function_filling=""
          common_function_returnstring="Accumulated returnvalues: ${rc}"
          trace_msg 2 $common_function_returnstring "returncode: " $rc
          return $rc
    ;;
    ERS ) 
          trace_msg 2 "Enter function Control_eval_severity_instance ERS.\n"
          typeset -i rc=0
          ${USER_cmd} "${LAN} ${EXE_DIR}/sapcontrol ${HOST_cmd} -nr ${INSTANCE_NO} -function GetProcessList" | tr -s ' ' '' | tr -d ' ' | tr ',' ' ' |  while read name description dispstatus textstatus starttime elapsedtime pid
          do
            case $description in
              EnqueueReplicator|EnqueueReplicator2 )
                 [[ $dispstatus == "GREEN" ]] && rc=$GetProc_er_GREEN
                 [[ $dispstatus == "RED" ]] && rc=$GetProc_er_RED
                 [[ $dispstatus == "GRAY" ]] && rc=$GetProc_er_GRAY
                 [[ $dispstatus == "YELLOW" ]] && rc=$GetProc_er_YELLOW
              ;;
            esac
          done
          common_function_returnstring="Accumulated returnvalues: ${rc}"
          trace_msg 2 $common_function_returnstring "returncode: " $rc
          return $rc
    ;;
  esac

  GetInstType -I ${INSTANCE} -S ${SID} -E ${EXE_DIR} -V ${VirtualIP} -L "${LAN}"
  type=$?
  case $type in   
    2 ) #ABAP
          trace_msg 2 "Enter function Control_eval_severity_instance AS ABAP.\n"
          typeset -i rc=0
          ${USER_cmd} "${LAN} ${EXE_DIR}/sapcontrol ${HOST_cmd} -nr ${INSTANCE_NO} -function GetProcessList" | tr -s ' ' '' | tr -d ' ' | tr ',' ' ' | while read name description dispstatus textstatus starttime elapsedtime pid
          do
          	[[ $name == "disp+work" ]] && {
                  [[ $dispstatus == "GREEN" ]] && rc=$(( rc + GetProc_dw_GREEN ))
                  [[ $dispstatus == "RED" ]] && rc=$(( rc + GetProc_dw_RED ))
                  [[ $dispstatus == "GRAY" ]] && rc=$(( rc + GetProc_dw_GRAY ))
                  [[ $dispstatus == "YELLOW" ]] && rc=$(( rc + GetProc_dw_YELLOW ))
            }
            [[ $name == "igswd_mt" ]] && {
            	  [[ $dispstatus == "GREEN" ]] && rc=$(( rc + GetProc_ig_GREEN ))
                  [[ $dispstatus == "RED" ]] && rc=$(( rc + GetProc_ig_RED ))
                  [[ $dispstatus == "GRAY" ]] && rc=$(( rc + GetProc_ig_GRAY ))
                  [[ $dispstatus == "YELLOW" ]] && rc=$(( rc + GetProc_ig_YELLOW ))
            }
            [[ $name == "gwrd" ]] && {   
                  [[ $dispstatus == "GREEN" ]] && rc=$(( rc + GetProc_gw_GREEN ))
                  [[ $dispstatus == "RED" ]] && rc=$(( rc + GetProc_gw_RED ))
                  [[ $dispstatus == "GRAY" ]] && rc=$(( rc + GetProc_gw_GRAY ))
                  [[ $dispstatus == "YELLOW" ]] && rc=$(( rc + GetProc_gw_YELLOW ))
            }   
            [[ $name == "icman" ]] && {   
                  [[ $dispstatus == "GREEN" ]] && rc=$(( rc + GetProc_icm_GREEN ))
                  [[ $dispstatus == "RED" ]] && rc=$(( rc + GetProc_icm_RED ))
                  [[ $dispstatus == "GRAY" ]] && rc=$(( rc + GetProc_icm_GRAY ))
                  [[ $dispstatus == "YELLOW" ]] && rc=$(( rc + GetProc_icm_YELLOW ))
            }        
          done
          common_function_returnstring="Accumulated returnvalues: ${rc}"
          trace_msg 2 $common_function_returnstring "returncode: " $rc
          return $rc
    ;;  
    1 )      ##DUAL:
          trace_msg 2 "Enter function Control_eval_severity_instance AS DUAL.\n"
          typeset -i rc=0
          ${USER_cmd} "${LAN} ${EXE_DIR}/sapcontrol ${HOST_cmd} -nr ${INSTANCE_NO} -function GetProcessList" | tr -s ' ' '' | tr -d ' ' | tr ',' ' ' | while read name description dispstatus textstatus starttime elapsedtime pid
          do
          	[[ $name == "disp+work" ]] && {
                  [[ $dispstatus == "GREEN" ]] && rc=$(( rc + GetProc_dw_GREEN ))
                  [[ $dispstatus == "RED" ]] && rc=$(( rc + GetProc_dw_RED ))
                  [[ $dispstatus == "GRAY" ]] && rc=$(( rc + GetProc_dw_GRAY ))
                  [[ $dispstatus == "YELLOW" ]] && rc=$(( rc + GetProc_dw_YELLOW ))
            }
            [[ $name == "rslgcoll" ]] && {
            	  [[ $dispstatus == "GREEN" ]] && rc=$(( rc + GetProc_rc_GREEN ))
                  [[ $dispstatus == "RED" ]] && rc=$(( rc + GetProc_rc_RED ))
                  [[ $dispstatus == "GRAY" ]] && rc=$(( rc + GetProc_rc_GRAY ))
                  [[ $dispstatus == "YELLOW" ]] && rc=$(( rc + GetProc_rc_YELLOW ))
            }
            [[ $name == "rslgsend" ]] && {   
                  [[ $dispstatus == "GREEN" ]] && rc=$(( rc + GetProc_rs_GREEN ))
                  [[ $dispstatus == "RED" ]] && rc=$(( rc + GetProc_rs_RED ))
                  [[ $dispstatus == "GRAY" ]] && rc=$(( rc + GetProc_rs_GRAY ))
                  [[ $dispstatus == "YELLOW" ]] && rc=$(( rc + GetProc_rs_YELLOW ))
            }   
            [[ $name == "igswd_mt" ]] && {   
                  [[ $dispstatus == "GREEN" ]] && rc=$(( rc + GetProc_ig_GREEN ))
                  [[ $dispstatus == "RED" ]] && rc=$(( rc + GetProc_ig_RED ))
                  [[ $dispstatus == "GRAY" ]] && rc=$(( rc + GetProc_ig_GRAY ))
                  [[ $dispstatus == "YELLOW" ]] && rc=$(( rc + GetProc_ig_YELLOW ))
            }        
          done
          ${USER_cmd} "${LAN} ${EXE_DIR}/sapcontrol ${HOST_cmd} -nr ${INSTANCE_NO} -function J2EEGetProcessList" | tr -s ' ' '' | tr -d ' ' | tr ',' ' ' | while read telnetPort name pid type restart exitCode state startTime elapsedTime restartCount errorCount cpu debug
          do
          	[[ $name == "debugproxy" ]] && {
                  [[ $state == "J2EE_RUNNING" ]] && rc=$(( rc + J2EEGetProc_prx_GREEN ))
                  [[ $state == "J2EE_STOPPED" ]] && rc=$(( rc + J2EEGetProc_prx_GRAY ))
                  [[ $state == @(J2EE_CORE_RUNNING|J2EE_UNKNOWN) ]] && rc=$(( rc + J2EEGetProc_prx_YELLOW ))
                  [[ $state == @(J2EE_STOPPING|J2EE_STARTING|J2EE_MAINTENANCE) ]] && rc=$(( rc + J2EEGetProc_prx_PA )) 
            }
            [[ $name == "icm" ]] && {
            	  [[ $state == "J2EE_RUNNING" ]]  && rc=$(( rc + GetProc_icm_GREEN ))
                  [[ $state == "J2EE_STOPPED" ]] && rc=$(( rc + GetProc_icm_GRAY ))
                  [[ $state == @(J2EE_CORE_RUNNING|J2EE_UNKNOWN) ]] && rc=$(( rc + GetProc_icm_YELLOW ))
                  [[ $state == @(J2EE_STOPPING|J2EE_STARTING|J2EE_MAINTENANCE) ]]  && rc=$(( rc + GetProc_icm_PA ))
            }
            [[ $name == "server0" ]] && { #we only check for the server0   
                  [[ $state == "J2EE_RUNNING" ]]  && rc=$(( rc + J2EEGetProc_ser0_GREEN ))
                  [[ $state == "J2EE_STOPPED" ]] && rc=$(( rc + J2EEGetProc_ser0_GRAY ))
                  [[ $state == @(J2EE_CORE_RUNNING|J2EE_UNKNOWN) ]] && rc=$(( rc + J2EEGetProc_ser0_YELLOW ))
                  [[ $state == @(J2EE_STOPPING|J2EE_STARTING|J2EE_MAINTENANCE) ]]  && rc=$(( rc + J2EEGetProc_ser0_PA ))
            }    
          done
          common_function_returnstring="Accumulated returnvalues: ${rc}"
          trace_msg 2 $common_function_returnstring "returncode: " $rc
          return $rc
    ;;
    0 ) #JAVA  
          trace_msg 2 "Enter function Control_eval_severity_instance AS JAVA.\n"
          typeset -i rc=0
          ${USER_cmd} "${LAN} ${EXE_DIR}/sapcontrol ${HOST_cmd} -nr ${INSTANCE_NO} -function GetProcessList" | tr -s ' ' '' | tr -d ' ' | tr ',' ' ' | while read name description dispstatus textstatus starttime elapsedtime pid
          do
          	[[ $name == @(jcontrol|jstart) ]] && { #used to be named jstart in older releases. leave this in for backward compatibility
                  [[ $dispstatus == "GREEN" ]] && rc=$(( rc + GetProc_jc_GREEN ))
                  [[ $dispstatus == "RED" ]] && rc=$(( rc + GetProc_jc_RED ))
                  [[ $dispstatus == "GRAY" ]] && rc=$(( rc + GetProc_jc_GRAY ))
                  [[ $dispstatus == "YELLOW" ]] && rc=$(( rc + GetProc_jc_YELLOW ))
            }
            [[ $name == "igswd_mt" ]] && {
            	  [[ $dispstatus == "GREEN" ]] && rc=$(( rc + GetProc_ig_GREEN ))
                  [[ $dispstatus == "RED" ]] && rc=$(( rc + GetProc_ig_RED ))
                  [[ $dispstatus == "GRAY" ]] && rc=$(( rc + GetProc_ig_GRAY ))
                  [[ $dispstatus == "YELLOW" ]] && rc=$(( rc + GetProc_ig_YELLOW ))
            }
          done
          ${USER_cmd} "${LAN} ${EXE_DIR}/sapcontrol ${HOST_cmd} -nr ${INSTANCE_NO} -function J2EEGetProcessList" | tr -s ' ' '' | tr -d ' ' | tr ',' ' ' | while read telnetPort name pid type restart exitCode state startTime elapsedTime restartCount errorCount cpu debug
          do
          	[[ $name == "SDM" ]] && {
                  [[ $state == "J2EE_RUNNING" ]]  && rc=$(( rc + J2EEGetProc_sdm_GREEN ))
                  [[ $state == "J2EE_STOPPED" ]] && rc=$(( rc + J2EEGetProc_sdm_GRAY ))
                  [[ $state == @(J2EE_CORE_RUNNING|J2EE_UNKNOWN) ]] && rc=$(( rc + J2EEGetProc_sdm_YELLOW ))
                  [[ $state == @(J2EE_STOPPING|J2EE_STARTING|J2EE_MAINTENANCE) ]]  && rc=$(( rc + J2EEGetProc_sdm_PA ))
            }
            [[ $name == "icm" ]] && { #after 7.10: jlaunch is replaces by an icm process 
            	  [[ $state == "J2EE_RUNNING" ]]  && rc=$(( rc + GetProc_icm_GREEN ))
                  [[ $state == "J2EE_STOPPED" ]] && rc=$(( rc + GetProc_icm_GRAY ))
                  [[ $state == @(J2EE_CORE_RUNNING|J2EE_UNKNOWN) ]] && rc=$(( rc + GetProc_icm_YELLOW ))
                  [[ $state == @(J2EE_STOPPING|J2EE_STARTING|J2EE_MAINTENANCE) ]]  && rc=$(( rc + GetProc_icm_PA ))
            }
            [[ $name == "server0" ]] && { #we only check for the server0   
                  [[ $state == "J2EE_RUNNING" ]]  && rc=$(( rc + J2EEGetProc_ser0_GREEN ))
                  [[ $state == "J2EE_STOPPED" ]] && rc=$(( rc + J2EEGetProc_ser0_GRAY ))
                  [[ $state == @(J2EE_CORE_RUNNING|J2EE_UNKNOWN) ]] && rc=$(( rc + J2EEGetProc_ser0_YELLOW ))
                  [[ $state == @(J2EE_STOPPING|J2EE_STARTING|J2EE_MAINTENANCE) ]]  && rc=$(( rc + J2EEGetProc_ser0_PA ))
            }    
          done
          common_function_returnstring="Accumulated returnvalues: ${rc}"
          trace_msg 2 $common_function_returnstring "returncode: " $rc
          return $rc      
          
    ;;
    3 )
    	common_function_returnstring="ERROR, could not determine stack type.\n Default returncode of 0.\n"
        trace_msg 2 $common_function_returnstring "returncode: " $rc
    	return 0
    ;;
  esac     
  common_function_returnstring="Function calle with wrong input.\n"
  trace_msg 2 $common_function_returnstring 
  return $RC_WRONG_INPUT
}

Check_NFS_Service(){
  #Returncodes: 0,1
  #0 OK
  #1 ERROR
  #reset getopt index
  OPTIND=1
  while getopts V:M:J: option
  do
    case $option in
      V)  #Virtual IP the NFS Server should respond on 
          NFS_SERVER=$OPTARG
      ;;
      M)  #export directory, typically /export/sapmnt/SID
          SAPMNT_NFS=$OPTARG
      ;;
      J)  #Tivoli Job name
          JobName=$OPTARG
      ;;
      *)
          #error or warning msg
      ;;
    esac
  done
  trace_msg 2 "Enter function Check_NFS_Service.\n" 
  if ! $PING_cmd -c 1 $PING_timeout_flag 3 $NFS_SERVER
  then
    common_function_returnstring="${PING_cmd} -c 1 ${PING_timeout_flag} 3 ${NFS_SERVER} failed.\n"
    trace_msg 2 $common_function_returnstring
    return $ERROR                      # check network connectivity to NFS server
  fi
     
  if ! $RPCINFO_cmd -t $NFS_SERVER nfs  
  then                                 # As some customers might be using UDP or TCP, let's check UDP if TCP connectivity fails
    if ! $RPCINFO_cmd -u $NFS_SERVER nfs  
    then
      common_function_returnstring="Both TCP and UDP connectivity fails with nfs server. \n"
      trace_msg 2 $common_function_returnstring
      return $ERROR                         # check that NFS services are running on NFS server
    fi
  fi
  
  rc=$($MOUNT_cmd | $GREP_cmd -c "${SAPMNT_NFS}") 
  (( $rc < 1 )) && {
    common_function_returnstring="${MOUNT_cmd} | ${GREP_cmd} -c ${SAPMNT_NFS} failed. \n"
    trace_msg 2 $common_function_returnstring
    return $ERROR                 # check that sapmnt is mounted on local host
  }
  common_function_returnstring="NFS up and running.\n"
  trace_msg 2 $common_function_returnstring
  return $OK
}

Check_replication_status(){ 
  # Future alternatives as soon they can also cover ERS instances:
  # sapcontrol -nr 0 -function EnqGetLockTable
  # sapcontrol -nr 10 -function EnqGetStatistic
  #reset getopt index
  OPTIND=1
  while getopts I:S:E:V:L:J:T:P: option
  do
    case $option in
      I)  #Instance Name e.g. ASCS00  
          INSTANCE=$OPTARG
      ;;
      S)  #SID
          SID=$OPTARG
      ;;
      E)  #Executable Directory if sapcpe: /usr/sap/SID/INSTANCE/exe else: /usr/sap/SID/SYS/exe/run
          EXE_DIR=$OPTARG
      ;;
      V)  #Virtual IP the Instance is installed with or hostname 
          VirtualIP=$OPTARG
      ;;
      L)  #PowerHA Language
          LAN=$OPTARG
      ;;
      J)  #Tivoli Job name
          JobName=$OPTARG
      ;;
      T)  #Timeout
          TIMEOUT=$OPTARG
      ;;
      P)  #Instance Profile We want this to ensure to become agnostic from NFS. e.g. ERSes do have local copies today!
          INSTANCE_PROF=$OPTARG
      ;;
      *)
          #error or warning msg
      ;;
    esac
  done

  [[ -z $EXE_DIR ]]  && EXE_DIR=/usr/sap/${SID}/SYS/exe/run            
  [[ -z $INSTANCE_PROF ]]  && INSTANCE_PROF=/usr/sap/${SID}/SYS/profile/${SID}_${INSTANCE}_${VirtualIP}
  typeset -l LC_SID=$SID        
  typeset USER="${LC_SID}adm"
  typeset INST_DIR=/usr/sap/${SID}/${INSTANCE}     
  typeset INSTANCE_TYPE=${INSTANCE%[0-9][0-9]}
  typeset INSTANCE_NO=${INSTANCE#${INSTANCE_TYPE}} 

  #we use -host VirtualIP to ensure this is a healthy channel also from  SAP perspective.
  #On AIX for function call StartService only the LPAR hostname will be # #accepted. 
  #Here it will not bring the call to fail if it would be set to 
  #VirtualIP. Therefore we encapsulate to be able to handle this later.
  typeset HOST_cmd="-host ${VirtualIP}"
  
  typeset USER_cmd="/usr/bin/su - ${USER} -c" 
  
  typeset retries=0
  typeset -i rc=0  
  
  INSTANCE_TYPE=${INSTANCE%[0-9][0-9]}
  INSTANCE_NO=${INSTANCE#${INSTANCE_TYPE}}
  trace_msg 2 "Enter function Check_replication_status.\n" 
  #Returncodes:
  #0  Check_Replication_OK
  #1  Check_Replication_CS_WARNING
  #2  Check_Replication_ERS_WARNING
  #3  Check_Replication_ERROR
  while (( $retries < ${TIMEOUT} ))
  do
    # Get replication state either using ensmon or enq_admin command based on the EnqueueReplicator version
     /usr/bin/su - $SAPADMNUSR -c "env LANG=C sapcontrol -nr ${INSTANCE_NO} -function GetProcessList" | tr -s ' ' '' | tr -d ' ' | tr ',' ' ' | while read name description rest
    do
      if [[ $description == "EnqueueReplicator2" ]]
      then
           # call enq_admin with PROFILENAME as parameter to get the replication status
           ${USER_cmd} "${LAN} ${EXE_DIR}/enq_admin --replication_state pf=${INSTANCE_PROF}"
           rc=$?
      elif [[ $description == "EnqueueReplicator" ]]
      then
           # call ensmon with PROFILENAME as parameter. option 2
           ${USER_cmd} "${LAN} ${EXE_DIR}/ensmon pf=${INSTANCE_PROF} 2"
           rc=$?
      else
           continue
      fi
    done      
    (( $rc == 0 )) && {
      common_function_returnstring="Replication table complete.\n"
      trace_msg 2 $common_function_returnstring "returncode: " $rc
      return $Check_Replication_OK
    }
    (( $rc == 4 )) && [[ $INSTANCE_TYPE != "ERS" ]] && { #its an ASCS or SCS as this function must not be called by other instance types
      common_function_returnstring="CS instance: replication table not build"
      trace_msg 2 $common_function_returnstring "returncode: " $rc
      return $Check_Replication_CS_WARNING
    }                              
    (( $rc == 4 )) && ${SLEEP_cmd} 5
    (( retries++ ))
  done 
  (( $rc == 4 )) && { 
    common_function_returnstring="sapcontrol function EnqGetStatistic returned a replication state of YELLOW.\n"
    trace_msg 2 $common_function_returnstring "returncode: " $rc
    return $Check_Replication_ERS_WARNING 
  }
  common_function_returnstring="sapcontrol -function EnqGetStatistic returned a replication state of GRAY or RED.\n"
  trace_msg 2 $common_function_returnstring "returncode: " $rc
  return $Check_Replication_ERROR #Processes running, but replication not in status Green
}


Kill_instance(){
  typeset -i kill_flag=0  
  NFS_down=0
  #reset getopt index
  OPTIND=1
  while getopts NI:S:E:V:L:J: option
  do
    case $option in
      I)  #Instance Name e.g. ASCS00  
          INSTANCE=$OPTARG
      ;;
      S)  #SID
          SID=$OPTARG
      ;;
      E)  #Executable Directory if sapcpe: /usr/sap/SID/INSTANCE/exe else: /usr/sap/SID/SYS/exe/run
          EXE_DIR=$OPTARG
      ;;
      V)  #Virtual IP the Instance is installed with or hostname 
          VirtualIP=$OPTARG
      ;;
      L)  #PowerHA Language
          LAN=$OPTARG
      ;;
      N)  #Called when NFS is Down
          NFS_down=1
      ;;
      J)  #Tivoli Job name
          JobName=$OPTARG
      ;;
      *)
          #error or warning msg
      ;;
    esac
  done

  [[ -z $EXE_DIR ]]  && EXE_DIR=/usr/sap/${SID}/SYS/exe/run            
  [[ -z $INSTANCE_PROF ]]  && INSTANCE_PROF=/usr/sap/${SID}/SYS/profile/${SID}_${INSTANCE}_${VirtualIP}
  typeset -l LC_SID=$SID        
  typeset USER="${LC_SID}adm"
  typeset INST_DIR=/usr/sap/${SID}/${INSTANCE}     
  typeset INSTANCE_TYPE=${INSTANCE%[0-9][0-9]}
  typeset INSTANCE_NO=${INSTANCE#${INSTANCE_TYPE}} 
      
  #we use -host VirtualIP to ensure this is a healthy channel also from  SAP perspective.
  #On AIX for function call StartService only the LPAR hostname will be accepted. 
  #Here it will not bring the call to fail if it would be set to 
  #VirtualIP. Therefore we encapsulate to be able to handle this later.
  typeset HOST_cmd="-host ${VirtualIP}"
  
  typeset USER_cmd="/usr/bin/su - ${USER} -c" 
    
  #Local_Host needs to be set if Rename_to_host renamed kill.sap/shutdown.sap
  typeset Local_HOST=""
  (( $RUNNING_ON_POWERHA == 1 )) && typeset Local_HOST=".$(hostname)" 
 
  #must be called if sapstartsrv is inoperative
  #try to call Control_instance(Stop) and Control_sapstartsrv(Stop) first

  #for AS instances stop saposcol --> find out first if this is allowed. saposcol belongs to hoscontrol and hence not eligable to be stopped by the cluster.

  # original zOS 
  #ps -ef: ${PS_CMD} -ef | ${GREP_CMD} -Ei "${SAPSYSTEM}|sap" | ${GREP_CMD} -v SCS | ${GREP_CMD} ${SAPSYSTEM}_${INSTANCEDIR} | ${GREP_CMD} -v grep`
  #igs wurde noch extra gekillt ggf ein 6.40 feature
  trace_msg 2 "Enter function Kill_instance.\n" 
  #Returncodes: 0,1
  #0  Last webmethod call successful = 
  #1  sapstartsrv_failed_to_start (Last webmethod call failed, invalid parameter)
  #2  StartWait, StopWait, WaitforStarted, WaitforStopped, RestartServiceWait timed out
  #3  GetProcessList succeeded, all processes running correctly
  #4  GetProcessList succeeded, all processes stopped
           
  ${PS_cmd} -u $USER -o pid=,args= | ${GREP_cmd} ${INSTANCE} | ${EGREP_cmd} -v "grep|sapstartsrv" | while read PID CMD
  do
    trace_msg 3 "Kill -2 Process ${PID}.\n" 
    ${KILL_cmd} -2 $PID
    ${SLEEP_cmd} 1
    kill_flag=1
  done
  if (( ${kill_flag} == 1 ))
  then
      trace_msg 3 "sleep 5 seconds to make sure all the process are died with kill -2...\n"
      kill_flag=0
      ${SLEEP_cmd} 5
  fi
  if [[ $INSTANCE_TYPE != @(ERS|*SCS) ]] && (( ${kill_flag} == 1 ))
  then
      trace_msg 3 "Additional 20 seconds sleep for only ApplicationServer(AS) processes..."
      ${SLEEP_cmd} 20 #is this is an application server we sleep in sum 30 seconds. 20+10 = 30
  fi
  
  ${PS_cmd} -u $USER -o pid=,args= | ${GREP_cmd} ${INSTANCE} | ${EGREP_cmd} -v "grep|sapstartsrv" | while read PID CMD
  do
    trace_msg 3 "Kill -9 Process ${PID}.\n" 
    ${KILL_cmd} -9 $PID
    kill_flag=1
    ${SLEEP_cmd} 1
  done
  if (( ${kill_flag} == 1 ))
  then
      trace_msg 3 "sleep 5 seconds to make sure all the process are died with kill -9...\n"
      ${SLEEP_cmd} 5
  fi
  # if NFS is down, we cannot su to SIDADM, so we will skip the call to cleanipc.
  (( $NFS_down == 0 )) &&
  {
  #cleanipc must be run as SIDadm refer to http://scn.sap.com/docs/DOC-27773
  eval "${USER_cmd}  ${EXE_DIR}/cleanipc ${INSTANCE_NO} remove >> ${INST_DIR}/work/stopsap_${VirtualIP}_${INSTANCE_NO}.log"
  trace_msg 3 "Execute cleanipc. Log written to ${INST_DIR}/work/stopsap_${VirtualIP}_${INSTANCE_NO}.log. \n"
  ${GREP_cmd} -w "remove failed" ${INST_DIR}/work/stopsap_${VirtualIP}_${INSTANCE_NO}.log | while read oskey smnum memaddr rest
  do
    ipcs -s | ${GREP_cmd} -w $memaddr | while read somechar procid rest
    do
      ipcrm -s $procid
    done
  done
  }
  return $OK       
}
