1#!/usr/local/bin/bash
2#
3# SAPInstance
4#
5# Description:  Manages a single SAP Instance as a High-Availability
6#               resource. One SAP Instance is defined by one
7#               SAP Instance-Profile. start/stop handles all services
8#               of the START-Profile, status and monitor care only
9#               about essential services.
10#
11# Author:       Alexander Krauth, June 2006
12# Support:      linux@sap.com
13# License:      GNU General Public License (GPL)
14# Copyright:    (c) 2006-2008 Alexander Krauth
15#
16# An example usage:
17#      See usage() function below for more details...
18#
19# OCF instance parameters:
20#   OCF_RESKEY_InstanceName
21#   OCF_RESKEY_DIR_EXECUTABLE   (optional, well known directories will be searched by default)
22#   OCF_RESKEY_DIR_PROFILE      (optional, well known directories will be searched by default)
23#   OCF_RESKEY_START_PROFILE    (optional, well known directories will be searched by default)
24#   OCF_RESKEY_START_WAITTIME   (optional, to solve timing problems during J2EE-Addin start)
25#   OCF_RESKEY_AUTOMATIC_RECOVER    (optional, automatic startup recovery using cleanipc, default is false)
26#   OCF_RESKEY_MONITOR_SERVICES     (optional, default is to monitor critical services only)
27#   OCF_RESKEY_SHUTDOWN_METHOD      (optional, defaults to NORMAL, KILL: terminate the SAP instance with OS commands - faster, at your own risk)
28#   OCF_RESKEY_ERS_InstanceName     (optional, InstanceName of the ERS instance in a Master/Slave configuration)
29#   OCF_RESKEY_ERS_START_PROFILE    (optional, START_PROFILE of the ERS instance in a Master/Slave configuration)
30#   OCF_RESKEY_PRE_START_USEREXIT	(optional, lists a script which can be executed before the resource is started)
31#   OCF_RESKEY_POST_START_USEREXIT	(optional, lists a script which can be executed after the resource is started)
32#   OCF_RESKEY_PRE_STOP_USEREXIT	(optional, lists a script which can be executed before the resource is stopped)
33#   OCF_RESKEY_POST_STOP_USEREXIT	(optional, lists a script which can be executed after the resource is stopped)
34#   OCF_RESKEY_IS_ERS               (needed for ENQ/REPL NW 740)
35#   OCF_RESKEY_MINIMAL_PROBE		(optional but needed for simple mount structure architecure)
36#
37#  TODO: - Option to shutdown sapstartsrv for non-active instances -> that means: do probes only with OS tools (sapinstance_status)
38#        - Option for better standalone enqueue server monitoring, using ensmon (test enque-deque)
39#        - Option for cleanup abandoned enqueue replication tables
40#
41#######################################################################
42# Initialization:
43
44: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
45. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs
46
47# Parameter defaults
48
49OCF_RESKEY_InstanceName_default=""
50OCF_RESKEY_DIR_EXECUTABLE_default=""
51OCF_RESKEY_DIR_PROFILE_default=""
52OCF_RESKEY_START_PROFILE_default=""
53OCF_RESKEY_START_WAITTIME_default="3600"
54OCF_RESKEY_AUTOMATIC_RECOVER_default="false"
55OCF_RESKEY_MONITOR_SERVICES_default="disp+work|msg_server|enserver|enrepserver|jcontrol|jstart|enq_server|enq_replicator"
56OCF_RESKEY_SHUTDOWN_METHOD_default="normal"
57OCF_RESKEY_ERS_InstanceName_default=""
58OCF_RESKEY_ERS_START_PROFILE_default=""
59OCF_RESKEY_PRE_START_USEREXIT_default=""
60OCF_RESKEY_POST_START_USEREXIT_default=""
61OCF_RESKEY_PRE_STOP_USEREXIT_default=""
62OCF_RESKEY_POST_STOP_USEREXIT_default=""
63OCF_RESKEY_IS_ERS_default="false"
64OCF_RESKEY_MINIMAL_PROBE_default="false"
65
66: ${OCF_RESKEY_InstanceName=${OCF_RESKEY_InstanceName_default}}
67: ${OCF_RESKEY_DIR_EXECUTABLE=${OCF_RESKEY_DIR_EXECUTABLE_default}}
68: ${OCF_RESKEY_DIR_PROFILE=${OCF_RESKEY_DIR_PROFILE_default}}
69: ${OCF_RESKEY_START_PROFILE=${OCF_RESKEY_START_PROFILE_default}}
70: ${OCF_RESKEY_START_WAITTIME=${OCF_RESKEY_START_WAITTIME_default}}
71: ${OCF_RESKEY_AUTOMATIC_RECOVER=${OCF_RESKEY_AUTOMATIC_RECOVER_default}}
72: ${OCF_RESKEY_MONITOR_SERVICES=${OCF_RESKEY_MONITOR_SERVICES_default}}
73: ${OCF_RESKEY_SHUTDOWN_METHOD=${OCF_RESKEY_SHUTDOWN_METHOD_default}}
74: ${OCF_RESKEY_ERS_InstanceName=${OCF_RESKEY_ERS_InstanceName_default}}
75: ${OCF_RESKEY_ERS_START_PROFILE=${OCF_RESKEY_ERS_START_PROFILE_default}}
76: ${OCF_RESKEY_PRE_START_USEREXIT=${OCF_RESKEY_PRE_START_USEREXIT_default}}
77: ${OCF_RESKEY_POST_START_USEREXIT=${OCF_RESKEY_POST_START_USEREXIT_default}}
78: ${OCF_RESKEY_PRE_STOP_USEREXIT=${OCF_RESKEY_PRE_STOP_USEREXIT_default}}
79: ${OCF_RESKEY_POST_STOP_USEREXIT=${OCF_RESKEY_POST_STOP_USEREXIT_default}}
80: ${OCF_RESKEY_IS_ERS=${OCF_RESKEY_IS_ERS_default}}
81: ${OCF_RESKEY_IS_MINIMAL_PROBE=${OCF_RESKEY_IS_MINIMAL_PROBE_default}}
82
83#######################################################################
84
85SH=/bin/sh
86
87sapinstance_usage() {
88  methods=`sapinstance_methods`
89  methods=`echo $methods | tr ' ' '|'`
90  cat <<-EOF
91	usage: $0 ($methods)
92
93	$0 manages a SAP Instance as an HA resource.
94
95	The 'start' operation starts the instance or the ERS instance in a Master/Slave configuration
96	The 'stop' operation stops the instance
97	The 'status' operation reports whether the instance is running
98	The 'monitor' operation reports whether the instance seems to be working
99	The 'promote' operation starts the primary instance in a Master/Slave configuration
100	The 'demote' operation stops the primary instance and starts the ERS instance
101	The 'reload' operation allows changed parameters (non-unique only) without restarting the service
102	The 'notify' operation always returns SUCCESS
103	The 'validate-all' operation reports whether the parameters are valid
104	The 'methods' operation reports on the methods $0 supports
105
106	EOF
107}
108
109sapinstance_meta_data() {
110	cat <<END
111<?xml version="1.0"?>
112<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
113<resource-agent name="SAPInstance">
114<version>2.14</version>
115
116<longdesc lang="en">
117Usually a SAP system consists of one database and at least one or more SAP instances (sometimes called application servers). One SAP Instance is defined by having exactly one instance profile. The instance profiles can usually be found in the directory /sapmnt/SID/profile. Each instance must be configured as it's own resource in the cluster configuration.
118The resource agent supports the following SAP versions:
119- SAP WebAS ABAP Release 6.20 - 7.40
120- SAP WebAS Java Release 6.40 - 7.40
121- SAP WebAS ABAP + Java Add-In Release 6.20 - 7.40 (Java is not monitored by the cluster in that case)
122When using a SAP Kernel 6.40 please check and implement the actions from the section "Manual postprocessing" from SAP note 995116 (http://sdn.sap.com).
123Other versions may also work with this agent, but have not been verified.
124
125All operations of the SAPInstance resource agent are done by using the startup framework called SAP Management Console or sapstartsrv that was introduced with SAP kernel release 6.40. Find more information about the SAP Management Console in SAP note 1014480. Using this framework defines a clear interface for the Heartbeat cluster, how it sees the SAP system. The options for monitoring the SAP system are also much better than other methods like just watching the ps command for running processes or doing some pings to the application. sapstartsrv uses SOAP messages to request the status of running SAP processes. Therefore it can actually ask a process itself what it's status is, independent from other problems that might exist at the same time.
126
127sapstartsrv knows 4 status colours:
128- GREEN   = everything is fine
129- YELLOW  = something is wrong, but the service is still working
130- RED     = the service does not work
131- GRAY    = the service has not been started
132
133The SAPInstance resource agent will interpret GREEN and YELLOW as OK. That means that minor problems will not be reported to the Heartbeat cluster. This prevents the cluster from doing an unwanted failover.
134The statuses RED and GRAY are reported as NOT_RUNNING to the cluster. Depending on the status the cluster expects from the resource, it will do a restart, failover or just nothing.
135</longdesc>
136<shortdesc lang="en">Manages a SAP instance as an HA resource.</shortdesc>
137<parameters>
138 <parameter name="InstanceName" unique="1" required="1">
139  <longdesc lang="en">The full qualified SAP instance name. e.g. P01_DVEBMGS00_sapp01ci. Usually this is the name of the SAP instance profile.</longdesc>
140  <shortdesc lang="en">Instance name: SID_INSTANCE_VIR-HOSTNAME</shortdesc>
141  <content type="string" default="${OCF_RESKEY_InstanceName_default}" />
142 </parameter>
143 <parameter name="DIR_EXECUTABLE" unique="0" required="0">
144  <longdesc lang="en">The full qualified path where to find sapstartsrv and sapcontrol. Specify this parameter, if you have changed the SAP kernel directory location after the default SAP installation.</longdesc>
145  <shortdesc lang="en">Path of sapstartsrv and sapcontrol</shortdesc>
146  <content type="string" default="${OCF_RESKEY_DIR_EXECUTABLE_default}" />
147 </parameter>
148 <parameter name="DIR_PROFILE" unique="0" required="0">
149  <longdesc lang="en">The full qualified path where to find the SAP START profile. Specify this parameter, if you have changed the SAP profile directory location after the default SAP installation.</longdesc>
150  <shortdesc lang="en">Path of start profile</shortdesc>
151  <content type="string" default="${OCF_RESKEY_DIR_PROFILE_default}" />
152 </parameter>
153 <parameter name="START_PROFILE" unique="1" required="0">
154  <longdesc lang="en">The name of the SAP START profile. Specify this parameter, if you have changed the name of the SAP START profile after the default SAP installation. As SAP release 7.10 does not have a START profile anymore, you need to specify the Instance Profile than.</longdesc>
155  <shortdesc lang="en">Start profile name</shortdesc>
156  <content type="string" default="${OCF_RESKEY_START_PROFILE_default}" />
157 </parameter>
158 <parameter name="START_WAITTIME" unique="0" required="0">
159  <longdesc lang="en">After that time in seconds a monitor operation is executed by the resource agent. Does the monitor return SUCCESS, the start ishandled as SUCCESS. This is useful to resolve timing problems with e.g. the J2EE-Addin instance.Usually the resource agent waits until all services are started and the SAP Management Console reports a GREEN status. A double stack installation (ABAP + Java AddIn) consists of an ABAP dispatcher and a JAVA instance. Normally the start of the JAVA instance takes much longer than the start of the ABAP instance. For a JAVA Instance you may need to configure a much higher timeout for the start operation of the resource in Heartbeat. The disadvantage here is, that the discovery of a failed start by the cluster takes longer. Somebody might say: For me it is important, that the ABAP instance is up and running. A failure of the JAVA instance shall not cause a failover of the SAP instance.
160Actually the SAP MC reports a YELLOW status, if the JAVA instance of a double stack system fails. From the resource agent point of view YELLOW means:everything is OK. Setting START_WAITTIME to a lower value determines the resource agent to check the status of the instance during a start operation after that time. As it would wait normally for a GREEN status, now it reports SUCCESS to the cluster in case of a YELLOW status already after the specified time.
161
162That is only useful for double stack systems.
163  </longdesc>
164  <shortdesc lang="en">Check the successful start after that time (do not wait for J2EE-Addin)</shortdesc>
165  <content type="string" default="${OCF_RESKEY_START_WAITTIME_default}" />
166 </parameter>
167 <parameter name="AUTOMATIC_RECOVER" unique="0" required="0">
168  <longdesc lang="en">The SAPInstance resource agent tries to recover a failed start attempt automatically one time. This is done by killing running instance processes, removing the kill.sap file and executing cleanipc. Sometimes a crashed SAP instance leaves some processes and/or shared memory segments behind. Setting this option to true will try to remove those leftovers during a start operation. That is to reduce manual work for the administrator.</longdesc>
169  <shortdesc lang="en">Enable or disable automatic startup recovery</shortdesc>
170  <content type="boolean" default="${OCF_RESKEY_AUTOMATIC_RECOVER_default}"/>
171 </parameter>
172 <parameter name="MONITOR_SERVICES" unique="0" required="0">
173  <longdesc lang="en">Within a SAP instance there can be several services. Usually you will find the defined services in the START profile of the related instance (Attention: with SAP Release 7.10 the START profile content was moved to the instance profile). Not all of those services are worth to monitor by the cluster. For example you properly do not like to failover your SAP instance, if the central syslog collector daemon fails.
174Those services are monitored within the SAPInstance resource agent:
175
176- disp+work
177- msg_server
178- enserver (ENSA1)
179- enq_server (ENSA2)
180- enrepserver (ENSA1)
181- enq_replicator (ENSA2)
182- jcontrol
183- jstart
184
185Some other services could be monitored as well. They have to be
186given with the parameter MONITOR_SERVICES, e.g.:
187
188 - sapwebdisp
189 - TREXDaemon.x
190
191That names match the strings used in the output of the command 'sapcontrol -nr [Instance-Nr] -function GetProcessList'.
192The default should fit most cases where you want to manage a SAP Instance from the cluster. You may change this with this parameter, if you like to monitor more/less or other services that sapstartsrv supports.
193You may specify multiple services separated by a | (pipe) sign in this parameter: disp+work|msg_server|enserver
194  </longdesc>
195  <shortdesc lang="en">Services to monitor</shortdesc>
196  <content type="string" default="${OCF_RESKEY_MONITOR_SERVICES_default}"/>
197 </parameter>
198  <parameter name="SHUTDOWN_METHOD" unique="0" required="0">
199  <longdesc lang="en">Usually a SAP Instance is stopped by the command 'sapcontrol -nr InstanceNr -function Stop'. SHUTDOWN_METHOD=KILL means to kill the SAP Instance using OS commands. SAP processes of the instance are terminated with 'kill -9', shared memory is deleted with 'cleanipc' and the 'kill.sap' file will be deleted. That method is much faster than the graceful stop, but the instance does not have the chance to say goodbye to other SAPinstances in the same system. USE AT YOUR OWN RISK !!</longdesc>
200  <shortdesc lang="en">Shutdown graceful or kill a SAP instance by terminating the processes. (normal|KILL)</shortdesc>
201  <content type="string" default="${OCF_RESKEY_SHUTDOWN_METHOD_default}"/>
202 </parameter>
203 <parameter name="ERS_InstanceName" unique="1" required="0">
204  <longdesc lang="en">Only used in a Master/Slave resource configuration:
205The full qualified SAP enqueue replication instance name. e.g. P01_ERS02_sapp01ers. Usually this is the name of the SAP instance profile.
206The enqueue replication instance must be installed, before you want to configure a master-slave cluster resource.
207
208The master-slave configuration in the cluster must use this properties:
209clone_max = 2
210clone_node_max = 1
211master_node_max = 1
212master_max = 1
213  </longdesc>
214  <shortdesc lang="en">Enqueue replication instance name: SID_INSTANCE_VIR-HOSTNAME</shortdesc>
215  <content type="string" default="${OCF_RESKEY_ERS_InstanceName_default}"/>
216 </parameter>
217 <parameter name="ERS_START_PROFILE" unique="1" required="0">
218  <longdesc lang="en">Only used in a Master/Slave resource configuration:
219The parameter ERS_InstanceName must also be set in this configuration.
220The name of the SAP START profile. Specify this parameter, if you have changed the name of the SAP START profile after the default SAP installation. As SAP release 7.10 does not have a START profile anymore, you need to specify the Instance Profile than.
221  </longdesc>
222  <shortdesc lang="en">Enqueue replication start profile name</shortdesc>
223  <content type="string" default="${OCF_RESKEY_ERS_START_PROFILE_default}"/>
224 </parameter>
225 <parameter name="PRE_START_USEREXIT" unique="0" required="0">
226  <longdesc lang="en">The full qualified path where to find a script or program which should be executed before this resource gets started.</longdesc>
227  <shortdesc lang="en">Path to a pre-start script</shortdesc>
228  <content type="string" default="${OCF_RESKEY_PRE_START_USEREXIT_default}" />
229 </parameter>
230 <parameter name="POST_START_USEREXIT" unique="0" required="0">
231  <longdesc lang="en">The full qualified path where to find a script or program which should be executed after this resource got started.</longdesc>
232  <shortdesc lang="en">Path to a post-start script</shortdesc>
233  <content type="string" default="${OCF_RESKEY_POST_START_USEREXIT_default}" />
234 </parameter>
235 <parameter name="PRE_STOP_USEREXIT" unique="0" required="0">
236  <longdesc lang="en">The full qualified path where to find a script or program which should be executed before this resource gets stopped.</longdesc>
237  <shortdesc lang="en">Path to a pre-start script</shortdesc>
238  <content type="string" default="${OCF_RESKEY_PRE_STOP_USEREXIT_default}" />
239 </parameter>
240 <parameter name="POST_STOP_USEREXIT" unique="0" required="0">
241  <longdesc lang="en">The full qualified path where to find a script or program which should be executed after this resource got stopped.</longdesc>
242  <shortdesc lang="en">Path to a post-start script</shortdesc>
243  <content type="string" default="${OCF_RESKEY_POST_STOP_USEREXIT_default}" />
244 </parameter>
245 <parameter name="IS_ERS" unique="0" required="0">
246  <longdesc lang="en">Only used for ASCS/ERS SAP Netweaver installations without implementing a master/slave resource to
247    allow the ASCS to 'find' the ERS running on another cluster node after a resource failure. This parameter should be set
248    to true 'only' for the ERS instance for implementations following the SAP NetWeaver 7.40 HA certification (NW-HA-CLU-740). This includes also
249    systems for NetWeaver less than 7.40, if you like to implement the NW-HA-CLU-740 scenario.
250  </longdesc>
251  <shortdesc lang="en">Mark SAPInstance as ERS instance</shortdesc>
252  <content type="boolean" default="${OCF_RESKEY_IS_ERS_default}" />
253 </parameter>
254 <parameter name="MINIMAL_PROBE" unique="0" required="0">
255 <longdesc lang="en">Setting MINIMAL_PROBE=true forces the resource agent to do only minimal check during a probe. This is needed for special
256 file system setups. The MINIMAL_PROBE=true is only supported, if requested either by your vendor's support or if described in an architecture document
257 from your HA vendor.
258 </longdesc>
259 <shortdesc lang="en">Switch probe action from full to minimal check</shortdesc>
260 <content type="boolean" default="${OCF_RESKEY_MINIMAL_PROBE_default}" />
261 </parameter>
262</parameters>
263
264<actions>
265<action name="start" timeout="180s" />
266<action name="stop" timeout="240s" />
267<action name="status" timeout="60s" />
268<action name="monitor" depth="0" timeout="60s" interval="120s" />
269<action name="monitor" depth="0" timeout="60s" interval="121s" role="Slave" />
270<action name="monitor" depth="0" timeout="60s" interval="119s" role="Master" />
271<action name="promote" timeout="320s" />
272<action name="demote" timeout="320s" />
273<action name="reload" timeout="320s" />
274<action name="validate-all" timeout="5s" />
275<action name="meta-data" timeout="5s" />
276<action name="methods" timeout="5s" />
277</actions>
278</resource-agent>
279END
280}
281
282
283#
284# methods: What methods/operations do we support?
285#
286sapinstance_methods() {
287  cat <<-EOF
288	start
289	stop
290	status
291	monitor
292        promote
293        demote
294	reload
295        notify
296	validate-all
297	methods
298	meta-data
299	usage
300	EOF
301}
302
303
304
305#
306# is_clone : find out if we are configured to run in a Master/Slave configuration
307#
308is_clone() {
309  if [ -n "$OCF_RESKEY_CRM_meta_clone_max" ] \
310   && [ "$OCF_RESKEY_CRM_meta_clone_max" -gt 0 ]
311  then
312    if [ "$OCF_RESKEY_CRM_meta_clone_max" -ne 2 ] || \
313       [ "$OCF_RESKEY_CRM_meta_clone_node_max" -ne 1 ] || \
314       [ "$OCF_RESKEY_CRM_meta_master_node_max" -ne 1 ] || \
315       [ "$OCF_RESKEY_CRM_meta_master_max" -ne 1 ]
316    then
317            ocf_log err "Clone options misconfigured. (expect: clone_max=2,clone_node_max=1,master_node_max=1,master_max=1)"
318            exit $OCF_ERR_CONFIGURED
319    fi
320
321    if [ -z "$OCF_RESKEY_ERS_InstanceName" ]
322    then
323      ocf_log err "In a Master/Slave configuration the ERS_InstanceName parameter is mandatory."
324      exit $OCF_ERR_ARGS
325    fi
326  else
327    return 0
328  fi
329  return 1
330}
331
332
333#
334# abnormal_end : essential things are missing, but in the natur of a SAP installation - which can be very different
335#                from customer to customer - we cannot handle this always as an error
336#                This would be the case, if the software is installed on shared disks and not visible
337#                to all cluster nodes at all times.
338#
339abnormal_end() {
340  local err_msg=$1
341
342  ocf_is_probe && {
343    sapinstance_status
344    exit $?
345  }
346
347  ocf_log err $err_msg
348  if [ "$ACTION" = "stop" ]
349  then
350    cleanup_instance
351    exit $OCF_SUCCESS
352  fi
353
354  exit $OCF_ERR_CONFIGURED
355}
356
357#
358# sapinstance_init : Define global variables with default values, if optional parameters are not set
359#
360#
361sapinstance_init() {
362
363  local myInstanceName="$1"
364
365  SID=`echo "$myInstanceName" | cut -d_ -f1`
366  InstanceName=`echo "$myInstanceName" | cut -d_ -f2`
367  InstanceNr=`echo "$InstanceName" | sed 's/.*\([0-9][0-9]\)$/\1/'`
368  SAPVIRHOST=`echo "$myInstanceName" | cut -d_ -f3`
369
370  # make sure that we don't care the content of variable from previous run of sapinstance_init
371  DIR_EXECUTABLE=""
372  SYSTEMCTL="systemctl"
373  # optional OCF parameters, we try to guess which directories are correct
374  if  [ -z "$OCF_RESKEY_DIR_EXECUTABLE" ]
375  then
376    if have_binary /usr/sap/$SID/$InstanceName/exe/sapstartsrv && have_binary /usr/sap/$SID/$InstanceName/exe/sapcontrol
377    then
378      DIR_EXECUTABLE="/usr/sap/$SID/$InstanceName/exe"
379      SAPSTARTSRV="/usr/sap/$SID/$InstanceName/exe/sapstartsrv"
380      SAPCONTROL="/usr/sap/$SID/$InstanceName/exe/sapcontrol"
381    elif have_binary /usr/sap/$SID/SYS/exe/run/sapstartsrv && have_binary /usr/sap/$SID/SYS/exe/run/sapcontrol
382    then
383      DIR_EXECUTABLE="/usr/sap/$SID/SYS/exe/run"
384      SAPSTARTSRV="/usr/sap/$SID/SYS/exe/run/sapstartsrv"
385      SAPCONTROL="/usr/sap/$SID/SYS/exe/run/sapcontrol"
386    fi
387  else
388    if have_binary "$OCF_RESKEY_DIR_EXECUTABLE/sapstartsrv" && have_binary "$OCF_RESKEY_DIR_EXECUTABLE/sapcontrol"
389    then
390      DIR_EXECUTABLE="$OCF_RESKEY_DIR_EXECUTABLE"
391      SAPSTARTSRV="$OCF_RESKEY_DIR_EXECUTABLE/sapstartsrv"
392      SAPCONTROL="$OCF_RESKEY_DIR_EXECUTABLE/sapcontrol"
393    fi
394  fi
395
396  sidadm="`echo $SID | tr '[:upper:]' '[:lower:]'`adm"
397
398  [ -z "$DIR_EXECUTABLE" ] && abnormal_end "Cannot find sapstartsrv and sapcontrol executable, please set DIR_EXECUTABLE parameter!"
399
400  if [ -z "$OCF_RESKEY_DIR_PROFILE" ]
401  then
402    DIR_PROFILE="/usr/sap/$SID/SYS/profile"
403  else
404    DIR_PROFILE="$OCF_RESKEY_DIR_PROFILE"
405  fi
406
407  if [ "$myInstanceName" != "$OCF_RESKEY_InstanceName" ]
408  then
409    currentSTART_PROFILE=$OCF_RESKEY_ERS_START_PROFILE
410  else
411    currentSTART_PROFILE=$OCF_RESKEY_START_PROFILE
412  fi
413
414  if [ -z "$OCF_RESKEY_IS_ERS" ]; then
415      is_ers="no"
416  else
417      is_ers="$OCF_RESKEY_IS_ERS"
418  fi
419
420  if [ -z "$currentSTART_PROFILE" ]
421  then
422    if [ ! -r "$DIR_PROFILE/START_${InstanceName}_${SAPVIRHOST}" -a -r "$DIR_PROFILE/${SID}_${InstanceName}_${SAPVIRHOST}" ]; then
423      SAPSTARTPROFILE="$DIR_PROFILE/${SID}_${InstanceName}_${SAPVIRHOST}"
424    else
425      SAPSTARTPROFILE="$DIR_PROFILE/START_${InstanceName}_${SAPVIRHOST}"
426    fi
427  else
428    SAPSTARTPROFILE="$currentSTART_PROFILE"
429  fi
430
431  if [ -z "$OCF_RESKEY_START_WAITTIME" ]
432  then
433    export OCF_RESKEY_START_WAITTIME="${OCF_RESKEY_START_WAITTIME_default}"
434  fi
435
436  if [ -z "$OCF_RESKEY_MONITOR_SERVICES" ]
437  then
438    export OCF_RESKEY_MONITOR_SERVICES="${OCF_RESKEY_MONITOR_SERVICES_default}"
439  fi
440
441  # as root user we need the library path to the SAP kernel to be able to call sapcontrol
442  if [ `echo $LD_LIBRARY_PATH | grep -c "^$DIR_EXECUTABLE\>"` -eq 0 ]; then
443    LD_LIBRARY_PATH=$DIR_EXECUTABLE${LD_LIBRARY_PATH:+:}$LD_LIBRARY_PATH
444    export LD_LIBRARY_PATH
445  fi
446
447  return $OCF_SUCCESS
448}
449
450#
451# check_systemd_integration : Check, if SAP instance is controlled by systemd unit file SAP<SID>_<InstanceNr>.service
452#                             rc == 0 : sap instance is controlled by the unit file (file at least exists)
453#                             rc == 1 : sap instance is NOT controlled by the unit file (file does not exist)
454#
455check_systemd_integration() {
456    local systemd_unit_name="SAP${SID}_${InstanceNr}"
457    local rc=1
458
459    if which "$SYSTEMCTL" 1>/dev/null 2>/dev/null; then
460        if $SYSTEMCTL list-unit-files | \
461            awk '$1 == service { found=1 } END { if (! found) {exit 1}}' service="${systemd_unit_name}.service"; then
462            rc=0
463        else
464            rc=1
465        fi
466    fi
467    return "$rc"
468}
469
470#
471# check_sapstartsrv : Before using sapcontrol we make sure that the sapstartsrv is running for the correct instance.
472#                     We cannot use sapinit and the /usr/sap/sapservices file in case of an enquerep instance,
473#                     because then we have two instances with the same instance number.
474#
475check_sapstartsrv() {
476  local restart=0
477  local runninginst=""
478  local chkrc=$OCF_SUCCESS
479  local output=""
480
481  # check for sapstartsrv/systemd integration
482
483  if check_systemd_integration; then
484    # do it the systemd way
485    local systemd_unit_name="SAP${SID}_${InstanceNr}"
486
487    if $SYSTEMCTL  status "$systemd_unit_name" 1>/dev/null 2>/dev/null; then
488       ocf_log info "systemd service $systemd_unit_name is active"
489    else
490       ocf_log warn "systemd service $systemd_unit_name is not active, it will be started using systemd"
491       $SYSTEMCTL start "$systemd_unit_name" 1>/dev/null 2>/dev/null
492       # use start, because restart does also stop sap instance
493    fi
494
495    return 0
496  else # otherwise continue with old code...
497      if [ ! -S /tmp/.sapstream5${InstanceNr}13 ]; then
498        ocf_log warn "sapstartsrv is not running for instance $SID-$InstanceName (no UDS), it will be started now"
499        restart=1
500      else
501        output=`$SAPCONTROL -nr $InstanceNr -function ParameterValue INSTANCE_NAME -format script`
502        if [ $? -eq 0 ]
503        then
504          runninginst=`echo "$output" | grep '^0 : ' | cut -d' ' -f3`
505          if [ "$runninginst" != "$InstanceName" ]
506          then
507            ocf_log warn "sapstartsrv is running for instance $runninginst, that service will be killed"
508            restart=1
509          else
510            output=`$SAPCONTROL -nr $InstanceNr -function AccessCheck Start`
511            if [ $? -ne 0 ]; then
512              ocf_log warn "FAILED : sapcontrol -nr $InstanceNr -function AccessCheck Start (`ls -ld1 /tmp/.sapstream5${InstanceNr}13`)"
513              ocf_log warn "sapstartsrv will be restarted to try to solve this situation, otherwise please check sapstsartsrv setup (SAP Note 927637)"
514              restart=1
515            fi
516          fi
517        else
518          ocf_log warn "sapstartsrv is not running for instance $SID-$InstanceName, it will be started now"
519          restart=1
520        fi
521      fi
522
523      if [ -z "$runninginst" ]; then runninginst=$InstanceName; fi
524
525      if [ $restart -eq 1 ]
526      then
527        if [ -d /usr/sap/$SID/SYS/profile/ ]
528        then
529          DIR_PROFILE="/usr/sap/$SID/SYS/profile"
530        else
531          abnormal_end "Expected /usr/sap/$SID/SYS/profile/ to be a directory, please set DIR_PROFILE parameter!"
532        fi
533
534        [ ! -r $SAPSTARTPROFILE ] && abnormal_end "Expected $SAPSTARTPROFILE to be the instance START profile, please set START_PROFILE parameter!"
535
536        pkill -9 -f "sapstartsrv.*$runninginst"
537
538        # removing the unix domain socket files as they might have wrong permissions
539        # or ownership - they will be recreated by sapstartsrv during next start
540        rm -f /tmp/.sapstream5${InstanceNr}13
541        rm -f /tmp/.sapstream5${InstanceNr}14
542
543        $SAPSTARTSRV pf=$SAPSTARTPROFILE -D -u $sidadm
544
545        # now make sure the daemon has been started and is able to respond
546        local srvrc=1
547        while [ $srvrc -eq 1 -a `pgrep -f "sapstartsrv.*$runninginst" | wc -l` -gt 0 ]
548        do
549          sleep 1
550          $SAPCONTROL -nr $InstanceNr -function GetProcessList > /dev/null 2>&1
551          srvrc=$?
552        done
553
554        if [ $srvrc -ne 1 ]
555        then
556          ocf_log info "sapstartsrv for instance $SID-$InstanceName was restarted !"
557          chkrc=$OCF_SUCCESS
558        else
559          ocf_log error "sapstartsrv for instance $SID-$InstanceName could not be started!"
560          chkrc=$OCF_ERR_GENERIC
561          ocf_is_probe && chkrc=$OCF_NOT_RUNNING
562        fi
563      fi
564
565      return $chkrc
566  fi
567}
568
569
570#
571# sapuserexit : Many SAP customers need some additional processes/tools to run their SAP systems.
572#               This specialties do not allow a totally generic SAP cluster resource agent.
573#               Someone should write a resource agent for each additional process you need, if it
574#               is required to monitor that process within the cluster manager. To enable
575#               you to extent this resource agent without developing a new one, this user exit
576#               was introduced.
577#
578sapuserexit() {
579  local NAME="$1"
580  local VALUE="$2"
581
582  if [ -n "$VALUE" ]
583  then
584    if have_binary "$VALUE"
585    then
586      ocf_log info "Calling userexit ${NAME} with customer script file ${VALUE}"
587      "$VALUE" >/dev/null 2>&1
588      ocf_log info "Exiting userexit ${NAME} with customer script file ${VALUE}, returncode: $?"
589    else
590      ocf_log warn "Attribute ${NAME} is set to ${VALUE}, but this file is not executable"
591    fi
592  fi
593  return 0
594}
595
596
597#
598# cleanup_instance : remove resources (processes and shared memory) from a crashed instance)
599#
600cleanup_instance() {
601  pkill -9 -f -U $sidadm $InstanceName
602  ocf_log info "Terminated instance using 'pkill -9 -f -U $sidadm $InstanceName'"
603
604  # it is necessary to call cleanipc as user sidadm if the system has 'vmcj/enable = ON' set - otherwise SHM-segments in /dev/shm/SAP_ES2* cannot be removed
605  su - $sidadm -c "cleanipc $InstanceNr remove"
606  ocf_log info "Tried to remove shared memory resources using 'cleanipc $InstanceNr remove' as user $sidadm"
607
608  ocf_run rm -fv /usr/sap/$SID/$InstanceName/work/kill.sap
609  ocf_run rm -fv /usr/sap/$SID/$InstanceName/work/shutdown.sap
610  ocf_run rm -fv /usr/sap/$SID/$InstanceName/data/rslgcpid
611  ocf_run rm -fv /usr/sap/$SID/$InstanceName/data/rslgspid
612
613  return 0
614}
615
616#
617# sapinstance_start : Start the SAP instance
618#
619sapinstance_start() {
620
621  sapuserexit PRE_START_USEREXIT "$OCF_RESKEY_PRE_START_USEREXIT"
622
623  local rc=$OCF_NOT_RUNNING
624  local output=""
625  local loopcount=0
626
627  while [ $loopcount -lt 2 ]
628  do
629    loopcount=$(($loopcount + 1))
630
631    check_sapstartsrv
632    rc=$?
633    if [ $rc -eq $OCF_SUCCESS ]; then
634      output=`$SAPCONTROL -nr $InstanceNr -function Start`
635      rc=$?
636      ocf_log info "Starting SAP Instance $SID-$InstanceName: $output"
637    fi
638
639    if [ $rc -ne 0 ]
640    then
641      ocf_log err "SAP Instance $SID-$InstanceName start failed."
642      return $OCF_ERR_GENERIC
643    fi
644
645    local startrc=1
646    while [ $startrc -gt 0 ]
647    do
648      local waittime_start=`date +%s`
649      output=`$SAPCONTROL -nr $InstanceNr -function WaitforStarted $OCF_RESKEY_START_WAITTIME 10`
650      startrc=$?
651      local waittime_stop=`date +%s`
652
653      if [ $startrc -ne 0 ]
654      then
655        if [ $(($waittime_stop - $waittime_start)) -ge $OCF_RESKEY_START_WAITTIME ]
656        then
657          sapinstance_monitor NOLOG
658          if [ $? -eq $OCF_SUCCESS ]
659          then
660            output="START_WAITTIME ($OCF_RESKEY_START_WAITTIME) has elapsed, but instance monitor returned SUCCESS. Instance considered running."
661            startrc=0; loopcount=2
662          fi
663        else
664          if [ $loopcount -eq 1 ] && ocf_is_true $OCF_RESKEY_AUTOMATIC_RECOVER
665          then
666            ocf_log warn "SAP Instance $SID-$InstanceName start failed: $output"
667            ocf_log warn "Try to recover $SID-$InstanceName"
668            cleanup_instance
669          else
670            loopcount=2
671          fi
672          startrc=-1
673        fi
674      else
675        loopcount=2
676      fi
677    done
678  done
679
680  if [ $startrc -eq 0 ]
681  then
682    ocf_log info "SAP Instance $SID-$InstanceName started: $output"
683    rc=$OCF_SUCCESS
684    sapuserexit POST_START_USEREXIT "$OCF_RESKEY_POST_START_USEREXIT"
685    if ocf_is_true $is_ers; then crm_attribute -n runs_ers_${SID} -v 1 -l reboot; fi
686  else
687    ocf_log err "SAP Instance $SID-$InstanceName start failed: $output"
688    rc=$OCF_NOT_RUNNING
689    if ocf_is_true $is_ers; then crm_attribute -n runs_ers_${SID} -v 0 -l reboot; fi
690  fi
691
692  return $rc
693}
694
695
696#
697# sapinstance_recover: Try startup of failed instance by cleaning up resources
698#
699sapinstance_recover() {
700  cleanup_instance
701  sapinstance_start
702  return $?
703}
704
705
706#
707# sapinstance_stop: Stop the SAP instance
708#
709sapinstance_stop() {
710  local output=""
711  local rc
712
713  sapuserexit PRE_STOP_USEREXIT "$OCF_RESKEY_PRE_STOP_USEREXIT"
714
715  if [ "$OCF_RESKEY_SHUTDOWN_METHOD" = "KILL" ]
716  then
717    ocf_log info "Stopping SAP Instance $SID-$InstanceName with shutdown method KILL!"
718    cleanup_instance
719    return $OCF_SUCCESS
720  fi
721
722  check_sapstartsrv
723  rc=$?
724  if [ $rc -eq $OCF_SUCCESS ]; then
725    output=`$SAPCONTROL -nr $InstanceNr -function Stop`
726    rc=$?
727    ocf_log info "Stopping SAP Instance $SID-$InstanceName: $output"
728  fi
729
730  if [ $rc -eq 0 ]
731  then
732    output=`$SAPCONTROL -nr $InstanceNr -function WaitforStopped 3600 1`
733    if [ $? -eq 0 ]
734    then
735      ocf_log info "SAP Instance $SID-$InstanceName stopped: $output"
736      rc=$OCF_SUCCESS
737    else
738      ocf_log err "SAP Instance $SID-$InstanceName stop failed: $output"
739      rc=$OCF_ERR_GENERIC
740    fi
741  else
742    ocf_log err "SAP Instance $SID-$InstanceName stop failed: $output"
743    rc=$OCF_ERR_GENERIC
744  fi
745
746  sapuserexit POST_STOP_USEREXIT "$OCF_RESKEY_POST_STOP_USEREXIT"
747  if ocf_is_true $is_ers; then crm_attribute -n runs_ers_${SID} -v 0 -l reboot;  fi
748
749  return $rc
750}
751
752
753#
754# sapinstance_monitor: Can the given SAP instance do anything useful?
755#
756sapinstance_monitor() {
757  local MONLOG=$1
758  local rc
759
760  if ocf_is_probe && ocf_is_true "$OCF_RESKEY_MINIMAL_PROBE"; then
761    # code for minimal probe: # grep for sapstartsrv and maybe also for sapstart
762    # TODO: Do we need to improve this minimal test?
763    if pgrep -f -l "sapstartsrv .*pf=.*${SID}_${InstanceName}_${SAPVIRHOST}"; then
764      rc="$OCF_SUCCESS"
765    elif pgrep -f -l "sapstart .*pf=.*${SID}_${InstanceName}_${SAPVIRHOST}"; then
766      rc="$OCF_SUCCESS"
767    else
768      rc="$OCF_NOT_RUNNING"
769    fi
770  else
771    # standard probe and monitoring code
772    check_sapstartsrv
773    rc=$?
774  fi
775
776  if [ $rc -eq $OCF_SUCCESS ]
777  then
778    local count=0
779    local SERVNO
780    local output
781
782    output=`$SAPCONTROL -nr $InstanceNr -function GetProcessList -format script`
783
784    # we have to parse the output, because the returncode doesn't tell anything about the instance status
785    for SERVNO in `echo "$output" | grep '^[0-9] ' | cut -d' ' -f1 | sort -u`
786    do
787      local COLOR=`echo "$output" | grep "^$SERVNO dispstatus: " | cut -d' ' -f3`
788      local SERVICE=`echo "$output" | grep "^$SERVNO name: " | cut -d' ' -f3`
789      local STATE=0
790      local SEARCH
791
792      case $COLOR in
793        GREEN|YELLOW)       STATE=$OCF_SUCCESS;;
794        *)                  STATE=$OCF_NOT_RUNNING;;
795      esac
796
797      SEARCH=`echo "$OCF_RESKEY_MONITOR_SERVICES" | sed 's/\+/\\\+/g' | sed 's/\./\\\./g'`
798      if [ `echo "$SERVICE" | egrep -c "$SEARCH"` -eq 1 ]
799      then
800          if [ $STATE -eq $OCF_NOT_RUNNING ]
801          then
802            [ "$MONLOG" != "NOLOG" ] && ocf_log err "SAP instance service $SERVICE is not running with status $COLOR !"
803            rc=$STATE
804          fi
805          count=1
806      fi
807    done
808
809    if [ $count -eq 0 -a $rc -eq $OCF_SUCCESS ]
810    then
811      if ocf_is_probe
812      then
813        rc=$OCF_NOT_RUNNING
814      else
815        [ "$MONLOG" != "NOLOG" ] && ocf_log err "The SAP instance does not run any services which this RA could monitor!"
816        rc=$OCF_ERR_GENERIC
817      fi
818    fi
819  fi
820
821  return $rc
822}
823
824
825#
826# sapinstance_status: Lightweight check of SAP instance only with OS tools
827#
828sapinstance_status() {
829  local pid
830  local pids
831
832  [ ! -f "/usr/sap/$SID/$InstanceName/work/kill.sap" ] && return $OCF_NOT_RUNNING
833  pids=`grep '^kill -[0-9]' /usr/sap/$SID/$InstanceName/work/kill.sap | awk '{print $3}'`
834  for pid in $pids
835  do
836    [ `pgrep -f -U $sidadm $InstanceName | grep -c $pid` -gt 0 ] && return $OCF_SUCCESS
837  done
838  return $OCF_NOT_RUNNING
839}
840
841
842#
843# sapinstance_validate: Check the semantics of the input parameters
844#
845sapinstance_validate() {
846  local rc=$OCF_SUCCESS
847  if [ `echo "$SID" | grep -c '^[A-Z][A-Z0-9][A-Z0-9]$'` -ne 1 ]
848  then
849    ocf_log err "Parsing instance profile name: '$SID' is not a valid system ID!"
850    rc=$OCF_ERR_ARGS
851  fi
852
853  if [ `echo "$InstanceName" | grep -c '^[A-Z].*[0-9][0-9]$'` -ne 1 ]
854  then
855    ocf_log err "Parsing instance profile name: '$InstanceName' is not a valid instance name!"
856    rc=$OCF_ERR_ARGS
857  fi
858
859  if [ `echo "$InstanceNr" | grep -c '^[0-9][0-9]$'` -ne 1 ]
860  then
861    ocf_log err "Parsing instance profile name: '$InstanceNr' is not a valid instance number!"
862    rc=$OCF_ERR_ARGS
863  fi
864
865  if [ `echo "$SAPVIRHOST" | grep -c '^[A-Za-z][A-Za-z0-9_-]*$'` -ne 1 ]
866  then
867    ocf_log err "Parsing instance profile name: '$SAPVIRHOST' is not a valid hostname!"
868    rc=$OCF_ERR_ARGS
869  fi
870
871  return $rc
872}
873
874
875#
876# sapinstance_start_clone
877#
878sapinstance_start_clone() {
879  sapinstance_init $OCF_RESKEY_ERS_InstanceName
880  ${HA_SBIN_DIR}/crm_master -v 50 -l reboot
881  sapinstance_start
882  return $?
883}
884
885
886#
887# sapinstance_stop_clone
888#
889sapinstance_stop_clone() {
890  sapinstance_init $OCF_RESKEY_ERS_InstanceName
891  ${HA_SBIN_DIR}/crm_master -v 0 -l reboot
892  sapinstance_stop
893  return $?
894}
895
896
897#
898# sapinstance_monitor_clone
899#
900sapinstance_monitor_clone() {
901  # first check with the status function (OS tools) if there could be something like a SAP instance running
902  # as we do not know here, if we are in master or slave state we do not want to start our monitoring
903  # agents (sapstartsrv) on the wrong host
904  local rc
905
906  sapinstance_init $OCF_RESKEY_InstanceName
907  if sapinstance_status; then
908    if sapinstance_monitor; then
909      ${HA_SBIN_DIR}/crm_master -Q -v 100 -l reboot
910      return $OCF_RUNNING_MASTER
911    fi
912    # by nature of the SAP enqueue server we have to make sure
913    # that we do a failover to the slave (enqueue replication server)
914    # in case the enqueue process has failed. We signal this to the
915    # cluster by setting our master preference to a lower value than the slave.
916    ${HA_SBIN_DIR}/crm_master -v 10 -l reboot
917    return $OCF_FAILED_MASTER
918  fi
919
920  sapinstance_init $OCF_RESKEY_ERS_InstanceName
921  sapinstance_status && sapinstance_monitor
922  rc=$?
923  if [ $rc -eq $OCF_SUCCESS ]; then
924    ${HA_SBIN_DIR}/crm_master -Q -v 100 -l reboot
925  fi
926  return $rc
927}
928
929
930#
931# sapinstance_promote_clone: In a Master/Slave configuration get Master by starting the SCS instance and stopping the ERS instance
932#                            The order is important here to behave correct from the application levels view
933#
934sapinstance_promote_clone() {
935  local rc
936
937  sapinstance_init $OCF_RESKEY_InstanceName
938  ocf_log info "Promoting $SID-$InstanceName to running Master."
939  sapinstance_start
940  rc=$?
941
942  if [ $rc -eq $OCF_SUCCESS ]; then
943    sapinstance_init $OCF_RESKEY_ERS_InstanceName
944    sapinstance_stop
945    rc=$?
946  fi
947
948  return $rc
949}
950
951
952#
953# sapinstance_demote_clone: In a Master/Slave configuration get Slave by stopping the SCS instance and starting the ERS instance
954#
955sapinstance_demote_clone() {
956  local rc
957
958  sapinstance_init $OCF_RESKEY_InstanceName
959  ocf_log info "Demoting $SID-$InstanceName to a slave."
960  sapinstance_stop
961  rc=$?
962
963  if [ $rc -eq $OCF_SUCCESS ]; then
964    sapinstance_init $OCF_RESKEY_ERS_InstanceName
965    sapinstance_start
966    rc=$?
967  fi
968
969  return $rc
970}
971
972
973#
974# sapinstance_notify: Handle master scoring - to make sure a slave gets the next master
975#
976sapinstance_notify() {
977  local n_type="$OCF_RESKEY_CRM_meta_notify_type"
978  local n_op="$OCF_RESKEY_CRM_meta_notify_operation"
979
980  if [ "${n_type}_${n_op}" = "post_promote" ]; then
981    # After promotion of one master in the cluster, we make sure that all clones reset their master
982    # value back to 100. This is because a failed monitor on a master might have degree one clone
983    # instance to score 10.
984    ${HA_SBIN_DIR}/crm_master -v 100 -l reboot
985  elif [ "${n_type}_${n_op}" = "pre_demote" ]; then
986    # if we are a slave and a demote event is announced, make sure we are highest on the list to become master
987    # that is, when a slave resource was started after the promote event of an already running master (e.g. node of slave was down)
988    # We also have to make sure to overrule the globally set resource_stickiness or any fail-count factors => INFINITY
989    local n_uname="$OCF_RESKEY_CRM_meta_notify_demote_uname"
990    if [ ${n_uname} != ${NODENAME} ]; then
991      ${HA_SBIN_DIR}/crm_master -v INFINITY -l reboot
992    fi
993  fi
994}
995
996
997#
998#	'main' starts here...
999#
1000
1001## GLOBALS
1002SID=""
1003sidadm=""
1004InstanceName=""
1005InstanceNr=""
1006SAPVIRHOST=""
1007DIR_EXECUTABLE=""
1008SAPSTARTSRV=""
1009SAPCONTROL=""
1010DIR_PROFILE=""
1011SAPSTARTPROFILE=""
1012CLONE=0
1013NODENAME=$(ocf_local_nodename)
1014
1015
1016if
1017  ( [ $# -ne 1 ] )
1018then
1019  sapinstance_usage
1020  exit $OCF_ERR_ARGS
1021fi
1022
1023ACTION=$1
1024if [ "$ACTION" = "status" ]; then
1025  ACTION=monitor
1026fi
1027
1028# These operations don't require OCF instance parameters to be set
1029case "$ACTION" in
1030  usage|methods)                sapinstance_$ACTION
1031                                exit $OCF_SUCCESS;;
1032  meta-data)                    sapinstance_meta_data
1033                                exit $OCF_SUCCESS;;
1034  notify)                       sapinstance_notify
1035                                exit $OCF_SUCCESS;;
1036  *);;
1037esac
1038
1039if ! ocf_is_root
1040then
1041  ocf_log err "$0 must be run as root"
1042  exit $OCF_ERR_PERM
1043fi
1044
1045# parameter check
1046if  [ -z "$OCF_RESKEY_InstanceName" ]
1047then
1048  ocf_log err "Please set OCF_RESKEY_InstanceName to the name to the SAP instance profile!"
1049  exit $OCF_ERR_ARGS
1050fi
1051
1052is_clone; CLONE=$?
1053if [ ${CLONE} -eq 1 ]
1054then
1055  CLACT=_clone
1056else
1057  if [ "$ACTION" = "promote" -o "$ACTION" = "demote" ]
1058  then
1059    ocf_log err "$ACTION called in a non master/slave environment"
1060    exit $OCF_ERR_ARGS
1061  fi
1062  sapinstance_init $OCF_RESKEY_InstanceName
1063fi
1064
1065# What kind of method was invoked?
1066case "$ACTION" in
1067  start|stop|monitor|promote|demote)      sapinstance_$ACTION$CLACT
1068                                          exit $?;;
1069  validate-all)                           sapinstance_validate
1070                                          exit $?;;
1071  reload )
1072                                          ocf_log info "reloading SAPInstance parameters"
1073                                          exit $OCF_SUCCESS;;
1074  *)                                      sapinstance_methods
1075                                          exit $OCF_ERR_UNIMPLEMENTED;;
1076esac
1077