#!/bin/sh
#
# SAPInstance
#
# Description:	Manages a single SAP Instance as a High-Availability
#		resource. One SAP Instance is defined by one 
#               SAP Instance-Profile. start/stop handels all services
#               of the START-Profile, status and monitor care only
#               about essential services.
#
# Author:       Alexander Krauth, June 2006
# Support:      linux@sap.com
# License:      GNU General Public License (GPL)
# Copyright:    (c) 2006-2008 Alexander Krauth
#
# An example usage: 
#      See usage() function below for more details...
#
# OCF instance parameters:
#	OCF_RESKEY_InstanceName
#	OCF_RESKEY_DIR_EXECUTABLE   (optional, well known directories will be searched by default)
#	OCF_RESKEY_DIR_PROFILE      (optional, well known directories will be searched by default)
#	OCF_RESKEY_START_PROFILE    (optional, well known directories will be searched by default)
#	OCF_RESKEY_START_WAITTIME   (optional, to solve timing problems during J2EE-Addin start)
#	OCF_RESKEY_AUTOMATIC_RECOVER    (optional, automatic startup recovery using cleanipc, default is false)
#       OCF_RESKEY_MONITOR_SERVICES     (optional, default is to monitor critical services only)
#       OCF_RESKEY_ERS_InstanceName     (optional, InstanceName of the ERS instance in a Master/Slave configuration)
#       OCF_RESKEY_ERS_START_PROFILE    (optional, START_PROFILE of the ERS instance in a Master/Slave configuration)
#	OCF_RESKEY_PRE_START_USEREXIT	(optional, lists a script which can be executed before the resource is started)
#	OCF_RESKEY_POST_START_USEREXIT	(optional, lists a script which can be executed after the resource is started)
#	OCF_RESKEY_PRE_STOP_USEREXIT	(optional, lists a script which can be executed before the resource is stopped)
#	OCF_RESKEY_POST_STOP_USEREXIT	(optional, lists a script which can be executed after the resource is stopped)
#
#######################################################################
# Initialization:

: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/resource.d/heartbeat}
. ${OCF_FUNCTIONS_DIR}/.ocf-shellfuncs

#######################################################################

SH=/bin/sh

sapinstance_usage() {
  methods=`sapinstance_methods`
  methods=`echo $methods | tr ' ' '|'`
  cat <<-!
	usage: $0 ($methods)

	$0 manages a SAP Instance as an HA resource.

	The 'start' operation starts the instance or the ERS instance in a Master/Slave configuration
	The 'stop' operation stops the instance
	The 'status' operation reports whether the instance is running
	The 'monitor' operation reports whether the instance seems to be working
        The 'promote' operation starts the primary instance in a Master/Slave configuration
        The 'demote' operation stops the primary instance and starts the ERS instance
        The 'notify' operation always returns SUCCESS
	The 'validate-all' operation reports whether the parameters are valid
	The 'methods' operation reports on the methods $0 supports

	!
}

sapinstance_meta_data() {
	cat <<END
<?xml version="1.0"?>
<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
<resource-agent name="SAPInstance">
<version>2.01</version>

<longdesc lang="en">
Resource script for SAP. It manages a SAP Instance as an HA resource.
</longdesc>
<shortdesc lang="en">Manages a SAP instance</shortdesc>

<parameters>
 <parameter name="InstanceName" unique="1" required="1">
  <longdesc lang="en">The full qualified SAP instance name. e.g. P01_DVEBMGS00_sapp01ci</longdesc>
  <shortdesc lang="en">instance name: SID_INSTANCE_VIR-HOSTNAME</shortdesc>
  <content type="string" default="" />
 </parameter>
 <parameter name="DIR_EXECUTABLE" unique="1" required="0">
  <longdesc lang="en">The full qualified path where to find sapstartsrv and sapcontrol.</longdesc>
  <shortdesc lang="en">path of sapstartsrv and sapcontrol</shortdesc>
  <content type="string" default="" />
 </parameter>
 <parameter name="DIR_PROFILE" unique="1" required="0">
  <longdesc lang="en">The full qualified path where to find the SAP START profile.</longdesc>
  <shortdesc lang="en">path of start profile</shortdesc>
  <content type="string" default="" />
 </parameter>
 <parameter name="START_PROFILE" unique="1" required="0">
  <longdesc lang="en">The name of the SAP START profile.</longdesc>
  <shortdesc lang="en">start profile name</shortdesc>
  <content type="string" default="" />
 </parameter>
 <parameter name="START_WAITTIME" unique="1" required="0">
  <longdesc lang="en">After that time in seconds a monitor operation is executed by the resource agent. Does the monitor return SUCCESS, the start is handled as SUCCESS. This is useful to resolve timing problems with e.g. the J2EE-Addin instance.</longdesc>
  <shortdesc lang="en">Check the successful start after that time (do not wait for J2EE-Addin)</shortdesc>
  <content type="string" default="3600" />
 </parameter>
 <parameter name="AUTOMATIC_RECOVER" unique="1" required="0">
  <longdesc lang="en">The SAPInstance resource agent tries to recover a failed start attempt automaticaly one time. This is done by killing runing instance processes and executing cleanipc.</longdesc>
  <shortdesc lang="en">Enable or disable automatic startup recovery</shortdesc>
  <content type="boolean" default="false"/>
 </parameter>
 <parameter name="MONITOR_SERVICES" unique="1" required="0">
  <longdesc lang="en"></longdesc>
  <shortdesc lang="en"></shortdesc>
  <content type="string" default="disp+work|msg_server|enserver|enrepserver|jcontrol|jstart"/>
 </parameter>
 <parameter name="ERS_InstanceName" unique="1" required="0">
  <longdesc lang="en"></longdesc>
  <shortdesc lang="en"></shortdesc>
  <content type="string" default=""/>
 </parameter>
 <parameter name="ERS_START_PROFILE" unique="1" required="0">
  <longdesc lang="en"></longdesc>
  <shortdesc lang="en"></shortdesc>
  <content type="string" default=""/>
 </parameter>
 <parameter name="PRE_START_USEREXIT" unique="1" required="0">
  <longdesc lang="en">The full qualified path where to find a script or program which should be executed before this resource gets started.</longdesc>
  <shortdesc lang="en">path to a pre-start script</shortdesc>
  <content type="string" default="" />
 </parameter>
 <parameter name="POST_START_USEREXIT" unique="1" required="0">
  <longdesc lang="en">The full qualified path where to find a script or program which should be executed after this resource got started.</longdesc>
  <shortdesc lang="en">path to a post-start script</shortdesc>
  <content type="string" default="" />
 </parameter>
 <parameter name="PRE_STOP_USEREXIT" unique="1" required="0">
  <longdesc lang="en">The full qualified path where to find a script or program which should be executed before this resource gets stopped.</longdesc>
  <shortdesc lang="en">path to a pre-start script</shortdesc>
  <content type="string" default="" />
 </parameter>
 <parameter name="POST_STOP_USEREXIT" unique="1" required="0">
  <longdesc lang="en">The full qualified path where to find a script or program which should be executed after this resource got stopped.</longdesc>
  <shortdesc lang="en">path to a post-start script</shortdesc>
  <content type="string" default="" />
 </parameter>
</parameters>

<actions>
<action name="start" timeout="180" />
<action name="stop" timeout="240" />
<action name="status" timeout="60" />
<action name="monitor" depth="0" timeout="60" interval="120" />
<action name="promote" timeout="320" />
<action name="demote" timeout="320" />
<action name="validate-all" timeout="5" />
<action name="meta-data" timeout="5" />
<action name="methods" timeout="5" />
</actions>
</resource-agent>
END
}


#
# methods: What methods/operations do we support?
#
sapinstance_methods() {
  cat <<-!
	start
	stop
	status
	monitor
        promote
        demote
        notify
	validate-all
	methods
	meta-data
	usage
	!
}



#
# is_clone : find out if we are configured to run in a Master/Slave configuration
#
is_clone() {
  if [ -n "$OCF_RESKEY_CRM_meta_clone_max" ] \
   && [ "$OCF_RESKEY_CRM_meta_clone_max" -gt 0 ]
  then
    if [ "$OCF_RESKEY_CRM_meta_clone_max" -ne 2 ] || \
       [ "$OCF_RESKEY_CRM_meta_clone_node_max" -ne 1 ] || \
       [ "$OCF_RESKEY_CRM_meta_master_node_max" -ne 1 ] || \
       [ "$OCF_RESKEY_CRM_meta_master_max" -ne 1 ]
    then
            ocf_log err "Clone options misconfigured. (expect: clone_max=2,clone_node_max=1,master_node_max=1,master_max=1)"
            exit $OCF_ERR_CONFIGURED
    fi

    if [ -z "$OCF_RESKEY_ERS_InstanceName" ]
    then
      ocf_log err "In a Master/Slave configuration the ERS_InstanceName parameter is mandatory."
      exit $OCF_ERR_ARGS
    fi
  else
    return 0
  fi
  return 1
}


#
# sapinstance_init : Define global variables with default values, if optional parameters are not set
#
#
sapinstance_init() {

  myInstanceName="$1"

  SID=`echo "$myInstanceName" | cut -d_ -f1`
  InstanceName=`echo "$myInstanceName" | cut -d_ -f2`
  InstanceNr=`echo "$InstanceName" | sed 's/.*\([0-9][0-9]\)$/\1/'`
  SAPVIRHOST=`echo "$myInstanceName" | cut -d_ -f3`

  # optional OCF parameters, we try to guess which directories are correct
  if  [ -z "$OCF_RESKEY_DIR_EXECUTABLE" ]
  then
    if [ -x /usr/sap/$SID/$InstanceName/exe/sapstartsrv -a -x /usr/sap/$SID/$InstanceName/exe/sapcontrol ]
    then
      DIR_EXECUTABLE="/usr/sap/$SID/$InstanceName/exe"
      SAPSTARTSRV="/usr/sap/$SID/$InstanceName/exe/sapstartsrv"
      SAPCONTROL="/usr/sap/$SID/$InstanceName/exe/sapcontrol"
    elif [ -x /usr/sap/$SID/SYS/exe/run/sapstartsrv -a -x /usr/sap/$SID/SYS/exe/run/sapcontrol ]
    then
      DIR_EXECUTABLE="/usr/sap/$SID/SYS/exe/run"
      SAPSTARTSRV="/usr/sap/$SID/SYS/exe/run/sapstartsrv"
      SAPCONTROL="/usr/sap/$SID/SYS/exe/run/sapcontrol"
    else
      ocf_log warn "Cannot find sapstartsrv and sapcontrol executable, please set DIR_EXECUTABLE parameter!"
      exit $OCF_NOT_RUNNING
    fi
  else
    DIR_EXECUTABLE="$OCF_RESKEY_DIR_EXECUTABLE"
    SAPSTARTSRV="$OCF_RESKEY_DIR_EXECUTABLE/sapstartsrv"
    SAPCONTROL="$OCF_RESKEY_DIR_EXECUTABLE/sapcontrol"
  fi

  if [ -z "$OCF_RESKEY_DIR_PROFILE" ]
  then
    if [ -d /usr/sap/$SID/SYS/profile/ ]
    then
      DIR_PROFILE="/usr/sap/$SID/SYS/profile"
    else
      ocf_log warn "Expected /usr/sap/$SID/SYS/profile/ to be a directory, please set DIR_PROFILE parameter!"
      exit $OCF_NOT_RUNNING
    fi
  else
    DIR_PROFILE="$OCF_RESKEY_DIR_PROFILE"
  fi

  if [ "$myInstanceName" != "$OCF_RESKEY_InstanceName" ]
  then
    currentSTART_PROFILE=$OCF_RESKEY_ERS_START_PROFILE
  else
    currentSTART_PROFILE=$OCF_RESKEY_START_PROFILE
  fi

  if [ -z "$currentSTART_PROFILE" ]
  then
    SAPSTARTPROFILE="$DIR_PROFILE/START_${InstanceName}_${SAPVIRHOST}"
    if [ ! -r $SAPSTARTPROFILE ]
    then
      ocf_log warn "Expected $SAPSTARTPROFILE to be the instance START profile, please set START_PROFILE parameter!"
      exit $OCF_NOT_RUNNING
    fi
  else
    SAPSTARTPROFILE="$currentSTART_PROFILE"
  fi

  if [ -z "$OCF_RESKEY_START_WAITTIME" ]
  then
    export OCF_RESKEY_START_WAITTIME=3600
  fi

  if [ -z "$OCF_RESKEY_AUTOMATIC_RECOVER" ]
  then
    OCF_RESKEY_AUTOMATIC_RECOVER=0
  else
    case "$OCF_RESKEY_AUTOMATIC_RECOVER" in
     1|true|TRUE|yes|YES) export OCF_RESKEY_AUTOMATIC_RECOVER=1;;
     0|false|FALSE|no|NO) export OCF_RESKEY_AUTOMATIC_RECOVER=0;;
    esac
  fi

  if [ -z "$OCF_RESKEY_MONITOR_SERVICES" ]
  then
    export OCF_RESKEY_MONITOR_SERVICES="disp+work|msg_server|enserver|enrepserver|jcontrol|jstart"
  fi

  # as root user we need the library path to the SAP kernel to be able to call sapcontrol
  if [ `echo $LD_LIBRARY_PATH | grep -c "^$DIR_EXECUTABLE\>"` -eq 0 ]; then
    LD_LIBRARY_PATH=$DIR_EXECUTABLE:$LD_LIBRARY_PATH; export LD_LIBRARY_PATH
  fi

  sidadm="`echo $SID | tr [:upper:] [:lower:]`adm"

  return $OCF_SUCCESS
}


#
# check_sapstartsrv : Before using sapcontrol we make sure that the sapstartsrv is running for the correct instance.
#                     We cannot use sapinit and the /usr/sap/sapservices file in case of an enquerep instance,
#                     because then we have two instances with the same instance number.
#
check_sapstartsrv() {
  restart=0
  runninginst=""
  chkrc=$OCF_SUCCESS

  output=`$SAPCONTROL -nr $InstanceNr -function ParameterValue INSTANCE_NAME -format script`
  if [ $? -eq 0 ]
  then
    runninginst=`echo "$output" | grep '^0 : ' | cut -d' ' -f3`
    if [ "$runninginst" != "$InstanceName" ]
    then 
      ocf_log warn "sapstartsrv is running for instance $runninginst, that service will be killed"
      restart=1
    fi
  else
    ocf_log warn "sapstartsrv is not running for instance $SID-$InstanceName, it will be started now"
    restart=1
  fi

  if [ -z "$runninginst" ]; then runninginst=$InstanceName; fi

  if [ $restart -eq 1 ]
  then
    pkill -9 -f "sapstartsrv.*$runninginst"
    $SAPSTARTSRV pf=$SAPSTARTPROFILE -D -u $sidadm

    # now make sure the daemon has been started and is able to respond
    srvrc=1
    while [ $srvrc -eq 1 -a `pgrep -f "sapstartsrv.*$runninginst" | wc -l` -gt 0 ]
    do
      sleep 1
      $SAPCONTROL -nr $InstanceNr -function GetProcessList > /dev/null 2>&1
      srvrc=$?
    done

    if [ $srvrc -ne 1 ]
    then
      ocf_log info "sapstartsrv for instance $SID-$InstanceName was restarted !"
      chkrc=$OCF_SUCCESS
    else
      ocf_log error "sapstartsrv for instance $SID-$InstanceName could not be started!"
      chkrc=$OCF_NOT_RUNNING
    fi
  fi

  return $chkrc
}


#
# sapuserexit : Many SAP customers need some additional processes/tools to run their SAP systems.
#               This specialties do not allow a totally generic SAP cluster resource agent.
#               Someone should write a resource agent for each additional process you need, if it
#               is required to monitor that process within the cluster manager. To enable 
#               you to extent this resource agent without developing a new one, this user exit
#               was introduced.
#
sapuserexit() {
  NAME="$1"
  VALUE="$2"

  if [ -n "$VALUE" ]
  then
    if [ -x "$VALUE" ]
    then
      ocf_log info "Calling userexit ${NAME} with customer script file ${VALUE}"
      eval "$VALUE" >& /dev/null
      ocf_log info "Exiting userexit ${NAME} with customer script file ${VALUE}, returncode: $?"
    else
      ocf_log warn "Attribute ${NAME} is set to ${VALUE}, but this file is not executable"
    fi
  fi
  return 0
}


#
# cleanup_instance : remove resources (processes and shared memory) from a crashed instance)
#
cleanup_instance() {
  pkill -9 -f -U $sidadm $InstanceName
  $DIR_EXECUTABLE/cleanipc $InstanceNr remove
  return 0
}

#
# sapinstance_start : Start the SAP instance
#
sapinstance_start() {

  sapuserexit PRE_START_USEREXIT "$OCF_RESKEY_PRE_START_USEREXIT"

  rc=$OCF_NOT_RUNNING
  loopcount=0
  while [ $loopcount -lt 2 ]
  do
    loopcount=$(($loopcount + 1))

    check_sapstartsrv
    output=`$SAPCONTROL -nr $InstanceNr -function Start`
    rc=$?
    ocf_log info "Starting SAP Instance $SID-$InstanceName: $output"

    if [ $rc -ne 0 ]
    then
      ocf_log err "SAP Instance $SID-$InstanceName start failed."
      return $OCF_ERR_GENERIC
    fi

    startrc=1
    while [ $startrc -gt 0 ]
    do
      waittime_start=`date +%s`
      output=`$SAPCONTROL -nr $InstanceNr -function WaitforStarted $OCF_RESKEY_START_WAITTIME 10`
      startrc=$?
      waittime_stop=`date +%s`

      if [ $startrc -ne 0 ]
      then
        if [ $(($waittime_stop - $waittime_start)) -ge $OCF_RESKEY_START_WAITTIME ]
        then
          sapinstance_monitor NOLOG
          if [ $? -eq $OCF_SUCCESS ]
          then
            output="START_WAITTIME ($OCF_RESKEY_START_WAITTIME) has elapsed, but instance monitor returned SUCCESS. Instance considered running."
            startrc=0; loopcount=2
          fi
        else
          if [ $loopcount -eq 1 -a $OCF_RESKEY_AUTOMATIC_RECOVER -eq 1 ]
          then
            ocf_log warn "SAP Instance $SID-$InstanceName start failed: $output"
            ocf_log warn "Try to recover $SID-$InstanceName"
            cleanup_instance
          else
            loopcount=2
          fi
          startrc=-1
        fi
      else
        loopcount=2
      fi
    done
  done

  if [ $startrc -eq 0 ]
  then
    ocf_log info "SAP Instance $SID-$InstanceName started: $output"
    rc=$OCF_SUCCESS
    sapuserexit POST_START_USEREXIT "$OCF_RESKEY_POST_START_USEREXIT"
  else
    ocf_log err "SAP Instance $SID-$InstanceName start failed: $output"
    rc=$OCF_NOT_RUNNING
  fi

  return $rc
}


#
# sapinstance_recover: Try startup of failed instance by cleaning up resources
#
sapinstance_recover() {
  cleanup_instance
  sapinstance_start
  return $?
}


#
# sapinstance_stop: Stop the SAP instance
#
sapinstance_stop() {
  sapuserexit PRE_STOP_USEREXIT "$OCF_RESKEY_PRE_STOP_USEREXIT"

  check_sapstartsrv

  output=`$SAPCONTROL -nr $InstanceNr -function Stop`
  if [ $? -eq 0 ]
  then
    output=`$SAPCONTROL -nr $InstanceNr -function WaitforStopped 3600 1`
    if [ $? -eq 0 ]
    then
      ocf_log info "SAP Instance $SID-$InstanceName stopped: $output"
      rc=$OCF_SUCCESS
    else
      ocf_log err "SAP Instance $SID-$InstanceName stop failed: $output"
      rc=$OCF_ERR_GENERIC
    fi
  else
    ocf_log err "SAP Instance $SID-$InstanceName stop failed: $output"
    rc=$OCF_ERR_GENERIC
  fi

  sapuserexit POST_STOP_USEREXIT "$OCF_RESKEY_POST_STOP_USEREXIT"

  return $rc
}


#
# sapinstance_monitor: Can the given SAP instance do anything useful?
#
sapinstance_monitor() {
  MONLOG=$1
  check_sapstartsrv
  rc=$?

  if [ $rc -eq $OCF_SUCCESS ]
  then
    count=0
    LOCALHOST=`hostname`
    output=`$SAPCONTROL -nr $InstanceNr -host $LOCALHOST -function GetProcessList -format script`

    # we have to parse the output, because the returncode doesn't tell anything about the instance status
    for SERVNO in `echo "$output" | grep '^[0-9] ' | cut -d' ' -f1 | sort -u`
    do
      COLOR=`echo "$output" | grep "^$SERVNO dispstatus: " | cut -d' ' -f3`
      SERVICE=`echo "$output" | grep "^$SERVNO name: " | cut -d' ' -f3`
      STATE=0

      case $COLOR in
        GREEN|YELLOW)       STATE=$OCF_SUCCESS;;
        *)                  STATE=$OCF_NOT_RUNNING;;
      esac 

      SEARCH=`echo "$OCF_RESKEY_MONITOR_SERVICES" | sed 's/\+/\\\+/g' | sed 's/\./\\\./g'`
      if [ `echo "$SERVICE" | egrep -c "$SEARCH"` -eq 1 ]
      then
          if [ $STATE -eq $OCF_NOT_RUNNING ]
          then
            if [ "$MONLOG" != "NOLOG" ]
            then
              ocf_log err "SAP instance service $SERVICE is not running with status $COLOR !"
            fi
          rc=$STATE
          fi
          count=1
      fi
    done

    if [ $count -eq 0 -a $rc -eq $OCF_SUCCESS ]
    then
      if [ "$MONLOG" != "NOLOG" ]
      then
        ocf_log err "The SAP instance does not run any services which this RA could monitor!"
      fi
      rc=$OCF_ERR_ARGS
    fi
  fi
 
  return $rc
}

#
# sapinstance_validate: Check the symantic of the input parameters 
#
sapinstance_validate() {
  rc=$OCF_SUCCESS
  if [ `echo "$SID" | grep -c '^[A-Z][A-Z0-9][A-Z0-9]$'` -ne 1 ]
  then
    ocf_log err "Parsing instance profile name: '$SID' is not a valid system ID!"
    rc=$OCF_ERR_ARGS
  fi

  if [ `echo "$InstanceName" | grep -c '^[A-Z].*[0-9][0-9]$'` -ne 1 ]
  then
    ocf_log err "Parsing instance profile name: '$InstanceName' is not a valid instance name!"
    rc=$OCF_ERR_ARGS
  fi

  if [ `echo "$InstanceNr" | grep -c '^[0-9][0-9]$'` -ne 1 ]
  then
    ocf_log err "Parsing instance profile name: '$InstanceNr' is not a valid instance number!"
    rc=$OCF_ERR_ARGS
  fi

  if [ `echo "$SAPVIRHOST" | grep -c '^[A-Za-z][A-Za-z0-9_-]*$'` -ne 1 ]
  then
    ocf_log err "Parsing instance profile name: '$SAPVIRHOST' is not a valid hostname!"
    rc=$OCF_ERR_ARGS
  fi

  return $rc
}


#
# sapinstance_start_clone
#
sapinstance_start_clone() {
  sapinstance_init $OCF_RESKEY_ERS_InstanceName
  ${HA_SBIN_DIR}/crm_master -v 100 -l reboot
  sapinstance_start
  return $?
}


#
# sapinstance_stop_clone
#
sapinstance_stop_clone() {
  sapinstance_init $OCF_RESKEY_ERS_InstanceName
  ${HA_SBIN_DIR}/crm_master -v 0 -l reboot
  sapinstance_stop
  return $?
}


#
# sapinstance_monitor_clone
#
sapinstance_monitor_clone() {
  # resource agents running in Master mode must return other returncodes than default
  if [ "$OCF_RESKEY_CRM_meta_op_target_rc" -eq $OCF_RUNNING_MASTER ]
  then
    sapinstance_init $OCF_RESKEY_InstanceName
    sapinstance_monitor
    case "$?" in
       $OCF_SUCCESS)     return $OCF_RUNNING_MASTER;;
       $OCF_NOT_RUNNING) ${HA_SBIN_DIR}/crm_master -v 10 -l reboot
                         return $OCF_FAILED_MASTER;;
       *)                return $?;;
    esac
  else
    sapinstance_init $OCF_RESKEY_ERS_InstanceName
    sapinstance_monitor
    return $?
  fi
}


#
# sapinstance_promote_clone: In a Master/Slave configuration get Master by starting the SCS instance and stopping the ERS instance
#                            The order is important here to behave correct from the application levels view
#
sapinstance_promote_clone() {
  sapinstance_init $OCF_RESKEY_InstanceName
  ocf_log info "Promoting $SID-$InstanceName to running Master."
  sapinstance_start
  rc=$?

  if [ $rc -eq $OCF_SUCCESS ]; then
    sapinstance_init $OCF_RESKEY_ERS_InstanceName
    sapinstance_stop
    rc=$?
  fi

  return $rc
}


#
# sapinstance_demote_clone: In a Master/Slave configuration get Slave by stopping the SCS instance and starting the ERS instance
#
sapinstance_demote_clone() {
  sapinstance_init $OCF_RESKEY_InstanceName
  ocf_log info "Demoting $SID-$InstanceName to a slave."
  sapinstance_stop
  rc=$?

  if [ $rc -eq $OCF_SUCCESS ]; then
    sapinstance_init $OCF_RESKEY_ERS_InstanceName
    sapinstance_start
    rc=$?
  fi

  return $rc
}


#
# sapinstance_notify: After promotion of one master in the cluster, we make sure that all clones reset thier master
#                     value back to 100. This is because a failed monitor on a master might have degree one clone
#                     instance to score 10.
#
sapinstance_notify() {
  local n_type="$OCF_RESKEY_CRM_meta_notify_type"
  local n_op="$OCF_RESKEY_CRM_meta_notify_operation"

  if [ "${n_type}_${n_op}" = "post_promote" ]; then
    ${HA_SBIN_DIR}/crm_master -v 100 -l reboot
  fi
}


#
#	'main' starts here...
#

## GLOBALS
SID=""
sidadm=""
InstanceName=""
InstanceNr=""
SAPVIRHOST=""
DIR_EXECUTABLE=""
SAPSTARTSRV=""
SAPCONTROL=""
DIR_PROFILE=""
SAPSTARTPROFILE=""
CLONE=0


if
  ( [ $# -ne 1 ] )
then
  sapinstance_usage
  exit $OCF_ERR_ARGS
fi

ACTION=$1
if [ "$ACTION" = "status" ]; then
  ACTION=monitor
fi

# These operations don't require OCF instance parameters to be set
case "$ACTION" in
  usage|methods)                sapinstance_$ACTION
                                exit $OCF_SUCCESS;;
  meta-data)                    sapinstance_meta_data
                                exit $OCF_SUCCESS;;
  notify)                       sapinstance_notify
                                exit $OCF_SUCCESS;;
  *);;
esac

US=`id -u -n`
US=`echo $US`
if
  [ $US != root  ]
then
  ocf_log err "$0 must be run as root"
  exit $OCF_ERR_PERM
fi

# parameter check
if  [ -z "$OCF_RESKEY_InstanceName" ]
then
  ocf_log err "Please set OCF_RESKEY_InstanceName to the name to the SAP instance profile!"
  exit $OCF_ERR_ARGS
fi

is_clone; CLONE=$?
if [ ${CLONE} -eq 1 ]
then
  CLACT=_clone
else
  sapinstance_init $OCF_RESKEY_InstanceName
fi

# What kind of method was invoked?
case "$ACTION" in
  start|stop|monitor|promote|demote)      sapinstance_$ACTION$CLACT
                                          exit $?;;
  validate-all)                           sapinstance_validate
                                          exit $?;;
  *)                                      sapinstance_methods
                                          exit $OCF_ERR_UNIMPLEMENTED;;
esac
