Blame SOURCES/bz1168251-SAPHana-agents.patch

261ad6
From ef36b33da922b2b8501e80ca840bfb7accc65ff0 Mon Sep 17 00:00:00 2001
261ad6
From: David Vossel <dvossel@redhat.com>
261ad6
Date: Thu, 26 Feb 2015 14:21:20 -0600
261ad6
Subject: [PATCH] bz1168251-SAPHana-agents
261ad6
261ad6
---
261ad6
 doc/man/Makefile.am             |    2 +
261ad6
 heartbeat/Makefile.am           |    2 +
261ad6
 heartbeat/SAPHana               | 2106 +++++++++++++++++++++++++++++++++++++++
261ad6
 heartbeat/SAPHanaTopology       |  813 +++++++++++++++
261ad6
 tools/Makefile.am               |    2 +-
261ad6
 tools/show_SAPHanaSR_attributes |  133 +++
261ad6
 6 files changed, 3057 insertions(+), 1 deletion(-)
261ad6
 create mode 100755 heartbeat/SAPHana
261ad6
 create mode 100755 heartbeat/SAPHanaTopology
261ad6
 create mode 100755 tools/show_SAPHanaSR_attributes
261ad6
261ad6
diff --git a/doc/man/Makefile.am b/doc/man/Makefile.am
261ad6
index 5a1ad4d..31fc1f5 100644
261ad6
--- a/doc/man/Makefile.am
261ad6
+++ b/doc/man/Makefile.am
261ad6
@@ -78,6 +78,8 @@ man_MANS	       = ocf_heartbeat_AoEtarget.7 \
261ad6
                           ocf_heartbeat_Route.7 \
261ad6
                           ocf_heartbeat_SAPDatabase.7 \
261ad6
                           ocf_heartbeat_SAPInstance.7 \
261ad6
+                          ocf_heartbeat_SAPHana.7 \
261ad6
+                          ocf_heartbeat_SAPHanaTopology.7 \
261ad6
                           ocf_heartbeat_SendArp.7 \
261ad6
                           ocf_heartbeat_ServeRAID.7 \
261ad6
                           ocf_heartbeat_SphinxSearchDaemon.7 \
261ad6
diff --git a/heartbeat/Makefile.am b/heartbeat/Makefile.am
261ad6
index f08dad4..dd5b0a9 100644
261ad6
--- a/heartbeat/Makefile.am
261ad6
+++ b/heartbeat/Makefile.am
261ad6
@@ -105,6 +105,8 @@ ocf_SCRIPTS	     =  ClusterMon		\
261ad6
 			rsyslog			\
261ad6
 			SAPDatabase		\
261ad6
 			SAPInstance		\
261ad6
+			SAPHana			\
261ad6
+			SAPHanaTopology		\
261ad6
 			SendArp			\
261ad6
 			ServeRAID		\
261ad6
 			slapd			\
261ad6
diff --git a/heartbeat/SAPHana b/heartbeat/SAPHana
261ad6
new file mode 100755
261ad6
index 0000000..f4db17a
261ad6
--- /dev/null
261ad6
+++ b/heartbeat/SAPHana
261ad6
@@ -0,0 +1,2106 @@
261ad6
+#!/bin/bash
261ad6
+#
261ad6
+# SAPHana
261ad6
+#
261ad6
+# Description:	Manages two single SAP HANA Instance in System Replication 
261ad6
+#               Planned: do also manage scale-up scenarios
261ad6
+#               currently the SAPHana is dependent of the analysis of 
261ad6
+#               SAPHanaTopology
261ad6
+#               For supported scenarios please read the README file provided
261ad6
+#               in the same software package (rpm)
261ad6
+#
261ad6
+##############################################################################
261ad6
+#
261ad6
+# SAPHana
261ad6
+# Author:       Fabian Herschel, November 2013
261ad6
+# Support:      linux@sap.com
261ad6
+# License:      GNU General Public License (GPL)
261ad6
+# Copyright:    (c) 2013,2014 SUSE Linux Products GmbH
261ad6
+#
261ad6
+# An example usage: 
261ad6
+#      See usage() function below for more details...
261ad6
+#
261ad6
+# OCF instance parameters:
261ad6
+#	OCF_RESKEY_SID
261ad6
+#	OCF_RESKEY_InstanceNumber       
261ad6
+#	OCF_RESKEY_DIR_EXECUTABLE   (optional, well known directories will be searched by default)
261ad6
+#	OCF_RESKEY_DIR_PROFILE      (optional, well known directories will be searched by default)
261ad6
+#	OCF_RESKEY_INSTANCE_PROFILE (optional, well known directories will be searched by default)
261ad6
+#   OCF_RESKEY_PREFER_SITE_TAKEOVER (optional, default is no)
261ad6
+#   OCF_RESKEY_DUPLICATE_PRIMARY_TIMEOUT (optional, time difference needed between two last-primary-tiemstampe (lpt))
261ad6
+#   OCF_RESKEY_SAPHanaFilter    (optional, should only be set if been told by support or for debugging purposes)
261ad6
+#
261ad6
+#
261ad6
+#######################################################################
261ad6
+#
261ad6
+# Initialization:
261ad6
+timeB=$(date '+%s')
261ad6
+
261ad6
+: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
261ad6
+. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs
261ad6
+
261ad6
+#
261ad6
+#######################################################################
261ad6
+#
261ad6
+
261ad6
+HANA_STATE_PRIMARY=0
261ad6
+HANA_STATE_SECONDARY=1
261ad6
+HANA_STATE_STANDALONE=2
261ad6
+HANA_STATE_DEFECT=3
261ad6
+
261ad6
+SH=/bin/sh
261ad6
+
261ad6
+#
261ad6
+# function: super_ocf_log - wrapper function for ocf log in order catch usual logging into super log
261ad6
+# params:   LOG_MESSAGE
261ad6
+# globals:  SAPHanaFilter
261ad6
+function super_ocf_log() {
261ad6
+    local level="$1"
261ad6
+    local message="$2"
261ad6
+    local skip=1
261ad6
+    local mtype=""
261ad6
+    local search=0
261ad6
+    local shf="${SAPHanaFilter:-all}"
261ad6
+    # message levels: (dbg)|info|warn|err|error
261ad6
+    # message types:  (ACT|RA|FLOW|DBG|LPA|DEC|DBG2...
261ad6
+    case "$level" in
261ad6
+        debug | dbg | warn | err | error ) skip=0
261ad6
+        ;;
261ad6
+        info )
261ad6
+        case "$shf" in
261ad6
+            all) skip=0
261ad6
+            ;;          
261ad6
+            none )
261ad6
+                skip=1
261ad6
+                ;;
261ad6
+            * ) mtype=${message%% *}
261ad6
+                mtype=${mtype%:}
261ad6
+                mtype=${mtype#fh}
261ad6
+                echo "$shf"|  grep -iq ${mtype}; search=$?
261ad6
+                if [ $search -eq 0 ]; then
261ad6
+                     skip=0  
261ad6
+                else
261ad6
+                    skip=1
261ad6
+                fi
261ad6
+            ;;
261ad6
+        esac
261ad6
+        ;;    
261ad6
+    esac
261ad6
+    if [ $skip -eq 0 ]; then
261ad6
+        ocf_log "$level" "$message"
261ad6
+    fi
261ad6
+}
261ad6
+
261ad6
+#
261ad6
+# function: saphana_usage - short usage info
261ad6
+# params:   -
261ad6
+# globals:  $0(r)
261ad6
+#
261ad6
+function saphana_usage() {
261ad6
+    super_ocf_log info "FLOW $FUNCNAME ($*)"
261ad6
+    local rc=0
261ad6
+    methods=$(saphana_methods)
261ad6
+    methods=$(echo $methods | tr ' ' '|')
261ad6
+  cat <<-!
261ad6
+	usage: $0 ($methods)
261ad6
+
261ad6
+    $0 manages a SAP HANA Instance as an HA resource.
261ad6
+
261ad6
+    The 'start'        operation starts the HANA instance or bring the "clone instance" to a WAITING status
261ad6
+    The 'stop'         operation stops the HANA instance
261ad6
+    The 'status'       operation reports whether the HANA instance is running
261ad6
+    The 'monitor'      operation reports whether the HANA instance seems to be working in master/slave it also needs to check the system replication status
261ad6
+    The 'promote'      operation either runs a takeover for a secondary or a just-nothing for a primary
261ad6
+    The 'demote'       operation neary does nothing and just mark the instance as demoted
261ad6
+    The 'notify'       operation always returns SUCCESS
261ad6
+    The 'validate-all' operation reports whether the parameters are valid
261ad6
+    The 'methods'      operation reports on the methods $0 supports
261ad6
+
261ad6
+	!
261ad6
+	return $rc
261ad6
+}
261ad6
+
261ad6
+#
261ad6
+# function: saphana_meta_data - print resource agent meta-data for cluster
261ad6
+# params:   -
261ad6
+# globals:  -
261ad6
+#
261ad6
+function saphana_meta_data() {
261ad6
+    super_ocf_log info "FLOW $FUNCNAME ($*)"
261ad6
+    local rc=0
261ad6
+	cat <
261ad6
+
261ad6
+
261ad6
+<resource-agent name="SAPHana">
261ad6
+<version>0.149.4</version>
261ad6
+
261ad6
+<shortdesc lang="en">Manages two SAP HANA instances in system replication (SR).</shortdesc>
261ad6
+<longdesc lang="en">
261ad6
+The SAPHanaSR resource agent manages two SAP Hana instances (databases) which are configured
261ad6
+in system replication. This first version is limitted to the scale-up scenario. Scale-Up is
261ad6
+not supported in this version.
261ad6
+
261ad6
+Managing the two SAP HANA instances means that the resource agent controls the start/stop of the
261ad6
+instances. In addition the resource agent is able to monitor the SAP HANA databases to check their
261ad6
+availability on landscape host configuration level. For this monitoring the resource agent relies on interfaces
261ad6
+provided by SAP. A third task of the resource agent is to also check the synchronisation status
261ad6
+of the two SAP HANA databases. If the synchronisation is not "SOK", than the cluster avoids to
261ad6
+failover to the secondary side, if the primary fails. This is to improve the data consistency.
261ad6
+
261ad6
+The resource agent uses the following four interfaces provided by SAP:
261ad6
+
261ad6
+1. sapcontrol/sapstartsrv
261ad6
+   The interface sapcontrol/sapstartsrv is used to start/stop a HANA database instance/system
261ad6
+
261ad6
+2. landscapeHostConfiguration
261ad6
+   The interface is used to monitor a HANA system. The python script is named landscapeHostConfiguration.py.
261ad6
+   landscapeHostConfiguration.py has some detailed output about HANA system status
261ad6
+   and node roles. For our monitor the overall status is relevant. This overall 
261ad6
+   status is reported by the returncode of the script:
261ad6
+   0: Internal Fatal, 1: ERROR, 2: WARNING, 3: INFO, 4: OK
261ad6
+   The SAPHana resource agent will interpret returncodes 0 as FATAL, 1 as not-running or ERROR and and returncodes 2+3+4 as RUNNING.
261ad6
+
261ad6
+3. hdbnsutil
261ad6
+   The interface hdbnsutil is used to check the "topology" of the system replication as well as the current configuration
261ad6
+   (primary/secondary) of a SAP HANA database instance. A second task of the interface is the posibility to run a
261ad6
+   system replication takeover (sr_takeover) or to register a former primary to a newer one (sr_register).
261ad6
+
261ad6
+4. hdbsql / systemReplicationStatus
261ad6
+   Interface is SQL query into HANA (system replication table).  The hdbsql query will be replaced by a python script 
261ad6
+   "systemReplicationStatus.py" in SAP HANA SPS8 or 9.
261ad6
+   As long as we need to use hdbsql you need to setup secure store users for linux user root to be able to
261ad6
+   access the SAP HANA database. You need to configure a secure store user key "SAPHANA${SID}SR" which can connect the SAP
261ad6
+   HANA database: 
261ad6
+
261ad6
+5. saphostctrl
261ad6
+   The interface saphostctrl uses the function ListInstances to figure out the virtual host name of the 
261ad6
+   SAP HANA instance. This is the hostname used during the HANA installation.
261ad6
+
261ad6
+</longdesc>
261ad6
+<parameters>
261ad6
+    <parameter name="SID" unique="0" required="1">
261ad6
+        <longdesc lang="en">SAP System Identifier (SID) like "SLE" or "HAE"</longdesc>
261ad6
+        <shortdesc lang="en">SAP System Identifier (SID)</shortdesc>
261ad6
+        <content type="string" default="" />
261ad6
+    </parameter>
261ad6
+    <parameter name="InstanceNumber" unique="0" required="1">
261ad6
+        <longdesc lang="en">SAP instance number like "00" or "07"</longdesc>
261ad6
+        <shortdesc lang="en">SAP instance number</shortdesc>
261ad6
+        <content type="string" default="" />
261ad6
+    </parameter>
261ad6
+    <parameter name="PREFER_SITE_TAKEOVER" unique="0" required="0">
261ad6
+        <longdesc lang="en">Should cluster/RA prefer to switchover to slave instance instead of restarting master locally? Default="yes"
261ad6
+        no: Do prefer restart locally
261ad6
+        yes: Do prefer takever to remote site
261ad6
+        </longdesc>
261ad6
+        <shortdesc lang="en">Local or site recover preferred?</shortdesc>
261ad6
+        <content type="boolean" default="yes" />
261ad6
+    </parameter>
261ad6
+    <parameter name="AUTOMATED_REGISTER"  unique="0" required="0">
261ad6
+        <shortdesc lang="en">Define, if a former primary should automatically be registered.</shortdesc>
261ad6
+        <longdesc lang="en">The parameter AUTOMATED_REGISTER defines, wether a former primary instance should
261ad6
+             be registered automatically by the resource agent during cluster/resource start, if  the DUPLICATE_PRIMARY_TIMEOUT is expired... TDB
261ad6
+        </longdesc>
261ad6
+        <content type="boolean" default="false" />
261ad6
+    </parameter>
261ad6
+    <parameter name="DUPLICATE_PRIMARY_TIMEOUT" unique="0" required="0">
261ad6
+        <shortdesc lang="en">Time difference needed between to primary time stamps, if a dual-primary situation occurs</shortdesc>
261ad6
+        <longdesc lang="en">Time difference needed between to primary time stamps, 
261ad6
+        if a dual-primary situation occurs. If the time difference is
261ad6
+        less than the time gap, than the cluster hold one or both instances in a "WAITING" status. This is to give a admin
261ad6
+        a chance to react on a failover. A failed former primary will be registered after the time difference is passed. After
261ad6
+        this registration to the new primary all data will be overwritten by the system replication.
261ad6
+        </longdesc>
261ad6
+        <content type="string" default="7200" />
261ad6
+    </parameter>
261ad6
+    <parameter name="DIR_EXECUTABLE" unique="0" required="0">
261ad6
+        <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>
261ad6
+        <shortdesc lang="en">Path of sapstartsrv and sapcontrol</shortdesc>
261ad6
+        <content type="string" default="" />
261ad6
+    </parameter>
261ad6
+    <parameter name="DIR_PROFILE" unique="0" required="0">
261ad6
+        <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>
261ad6
+        <shortdesc lang="en">Path of start profile</shortdesc>
261ad6
+        <content type="string" default="" />
261ad6
+    </parameter>
261ad6
+    <parameter name="INSTANCE_PROFILE" unique="1" required="0">
261ad6
+        <longdesc lang="en">The name of the SAP HANA instance profile. Specify this parameter, if you have changed the name of the SAP HANA instance profile after the default SAP installation. Normally you do not need to set this parameter.</longdesc>
261ad6
+        <shortdesc lang="en">HANA instance profile name</shortdesc>
261ad6
+        <content type="string" default="" />
261ad6
+    </parameter>
261ad6
+    <parameter name="SAPHanaFilter" unique="0" required="0">
261ad6
+        <shortdesc lang="en">Define SAPHana resource agent messages to be printed</shortdesc>
261ad6
+        <longdesc lang="en">Define SAPHana resource agent messages to be printed.
261ad6
+        This parameter should only be set of been requested by SUSE support. The default is sufficient for normal operation.
261ad6
+        </longdesc>
261ad6
+        <content type="string" default="" />
261ad6
+    </parameter>
261ad6
+</parameters>
261ad6
+
261ad6
+<actions>
261ad6
+    <action name="start"   timeout="180" />
261ad6
+    <action name="stop"    timeout="240" />
261ad6
+    <action name="status"  timeout="60" />
261ad6
+    <action name="monitor" depth="0" timeout="60" interval="120" />
261ad6
+    <action name="monitor" depth="0" timeout="60" interval="121" role="Slave" />
261ad6
+    <action name="monitor" depth="0" timeout="60" interval="119" role="Master" />
261ad6
+    <action name="promote" timeout="320" />
261ad6
+    <action name="demote"  timeout="320" />
261ad6
+    <action name="validate-all" timeout="5" />
261ad6
+    <action name="meta-data" timeout="5" />
261ad6
+    <action name="methods" timeout="5" />
261ad6
+</actions>
261ad6
+</resource-agent>
261ad6
+END
261ad6
+return $rc
261ad6
+}
261ad6
+
261ad6
+#
261ad6
+# function: saphana_methods - report supported cluster methods
261ad6
+# params:   -
261ad6
+# globals:  -
261ad6
+# methods: What methods/operations do we support?
261ad6
+#
261ad6
+function saphana_methods() {
261ad6
+    super_ocf_log info "FLOW $FUNCNAME ($*)"
261ad6
+    local rc=0 m
261ad6
+    for m in start stop status monitor promote demote notify validate-all methods meta-data usage; do
261ad6
+        echo "$m"
261ad6
+    done
261ad6
+	return $rc
261ad6
+}
261ad6
+
261ad6
+#
261ad6
+# function: dequote - filter: remove quotes (") from stdin
261ad6
+# params:   -
261ad6
+# globals:  -
261ad6
+function dequote()
261ad6
+{
261ad6
+    local rc=0; tr -d '"'; return $rc
261ad6
+}
261ad6
+
261ad6
+#
261ad6
+# function: remoteHost2remoteNode - convert a SAP remoteHost to the cluster node name
261ad6
+# params:   remoteHost
261ad6
+# globals:  ATTR_NAME_HANA_VHOST[*]
261ad6
+#
261ad6
+function remoteHost2remoteNode()
261ad6
+{
261ad6
+    super_ocf_log info "FLOW $FUNCNAME ($*)"
261ad6
+    local -a clusterNodes=()
261ad6
+    local cl=""
261ad6
+    local vHost=""
261ad6
+    local remoteHost="$1"
261ad6
+    local remoteNode=""
261ad6
+    local rc=1
261ad6
+    for cl in ${otherNodes[@]}; do
261ad6
+        vHost=$(get_hana_attribute $cl  ${ATTR_NAME_HANA_VHOST[@]})
261ad6
+        if [ "$vHost" = "$remoteHost" ]; then # we found the correct node
261ad6
+            remoteNode=$cl
261ad6
+            rc=0
261ad6
+        fi
261ad6
+    done
261ad6
+    if [ -n "$remoteNode"  ]; then
261ad6
+        echo "$remoteNode"
261ad6
+    fi
261ad6
+    super_ocf_log info "FLOW $FUNCNAME rc=$rc"
261ad6
+    return $rc
261ad6
+}
261ad6
+
261ad6
+#
261ad6
+# function: is_clone - report, if resource is configured as a clone (also master/slave)
261ad6
+# params:   -
261ad6
+# globals:  OCF_*(r)
261ad6
+# descript: is_clone : find out if we are configured to run in a Master/Slave configuration
261ad6
+# rc: 0: it is a clone, 1: it is not a clone
261ad6
+#
261ad6
+# DONE: PRIO2: For the first shippment (scale-out) we need to limit the clones to 2
261ad6
+#
261ad6
+function is_clone() {
261ad6
+    super_ocf_log info "FLOW $FUNCNAME ($*)"
261ad6
+    local rc=0
261ad6
+    #
261ad6
+    # is a clone config?
261ad6
+    #
261ad6
+    if [ -n "$OCF_RESKEY_CRM_meta_clone_max" ] \
261ad6
+       && [ "$OCF_RESKEY_CRM_meta_clone_max" -gt 0 ]; then
261ad6
+       #
261ad6
+       # yes it is a clone config - check, if its configured well
261ad6
+       #
261ad6
+        if [ "$OCF_RESKEY_CRM_meta_clone_node_max" -ne 1 ] || \
261ad6
+            [ "$OCF_RESKEY_CRM_meta_clone_max" -ne 2 ] || \
261ad6
+            [ "$OCF_RESKEY_CRM_meta_master_node_max" -ne 1 ] || \
261ad6
+            [ "$OCF_RESKEY_CRM_meta_master_max" -ne 1 ]; then
261ad6
+                super_ocf_log err "ACT: Clone options misconfigured. (expect: clone_max=2,clone_node_max=1,master_node_max=1,master_max=1)"
261ad6
+                exit $OCF_ERR_CONFIGURED
261ad6
+        fi
261ad6
+        rc=0;
261ad6
+    else
261ad6
+        rc=1;
261ad6
+    fi
261ad6
+    super_ocf_log info "FLOW $FUNCNAME rc=$rc"
261ad6
+    return $rc
261ad6
+}
261ad6
+
261ad6
+#
261ad6
+# function: get_hana_attribute 
261ad6
+# params:   NODE ATTR [STORE]
261ad6
+# globals:  -
261ad6
+#
261ad6
+function get_hana_attribute()
261ad6
+{
261ad6
+    super_ocf_log info "FLOW $FUNCNAME ($*)"
261ad6
+    local rc=0
261ad6
+    local attr_node=$1
261ad6
+    local attr_name=$2
261ad6
+    local attr_store=${3:-reboot} # DONE: PRIO5 get this (optional) from parameter
261ad6
+    crm_attribute -N ${attr_node} -G -n "$attr_name" -l $attr_store -q; rc=$?
261ad6
+    super_ocf_log info "FLOW $FUNCNAME rc=$rc"
261ad6
+    return $rc
261ad6
+}
261ad6
+
261ad6
+#
261ad6
+# function: set_hana_attribute - set the multi-state status of a node
261ad6
+# params:   NODE VALUE ATTR [STORE]
261ad6
+# globals:  -
261ad6
+#
261ad6
+function set_hana_attribute()
261ad6
+{
261ad6
+    super_ocf_log info "FLOW $FUNCNAME ($*)"
261ad6
+    local attr_node=$1
261ad6
+    local attr_value=$2
261ad6
+    local attr_name=$3
261ad6
+    local attr_store=${4:-reboot} # DONE: PRIO5 get this (optional) from parameter
261ad6
+    local rc=1
261ad6
+    local attr_old=""
261ad6
+    attr_old=$(get_hana_attribute $attr_node $attr_name $attr_store); get_rc=$?
261ad6
+    if [ "$attr_old" != "$attr_value" ]; then
261ad6
+        super_ocf_log debug "DBG: SET attribute $attr_name for node ${attr_node} to ${attr_value} former ($attr_old) get_rc=$get_rc "
261ad6
+        crm_attribute -N $attr_node -v $attr_value -n "$attr_name" -l $attr_store; rc=$?
261ad6
+    else
261ad6
+        super_ocf_log debug "DBG: LET attribute $attr_name for node ${attr_node} still be ${attr_value}"
261ad6
+        rc=0
261ad6
+    fi
261ad6
+    super_ocf_log info "FLOW $FUNCNAME rc=$rc"
261ad6
+    return $rc
261ad6
+}
261ad6
+
261ad6
+#
261ad6
+# function: assert - quickly go out of here with minimal error/return code handling and log
261ad6
+# params:   MESSAGE
261ad6
+# globals:  OCF_*(r)
261ad6
+#
261ad6
+function assert() {
261ad6
+    super_ocf_log info "FLOW $FUNCNAME ($*)"
261ad6
+    local err_msg=$1 local default_rc=$OCF_NOT_RUNNING
261ad6
+    # DONE: Check, if we need to destinguish between probe and others
261ad6
+    if ocf_is_probe; then
261ad6
+        default_exit=$OCF_NOT_RUNNING
261ad6
+    else
261ad6
+        default_exit=$OCF_ERR_CONFIGURED
261ad6
+    fi
261ad6
+    if [ "$ACTION" = "stop" ]; then
261ad6
+        cleanup_instance
261ad6
+        exit $OCF_SUCCESS
261ad6
+    fi
261ad6
+    super_ocf_log err "ACT: $err_msg"
261ad6
+    exit $OCF_NOT_RUNNING
261ad6
+}
261ad6
+
261ad6
+#
261ad6
+# function: set_crm_master - set the crm master score of the local node
261ad6
+# params:   SCORE
261ad6
+# globals:  HA_SBIN_DIR(r), OCF_RESOURCE_INSTANCE(r)
261ad6
+#
261ad6
+function set_crm_master()
261ad6
+{
261ad6
+    super_ocf_log info "FLOW $FUNCNAME ($*)"
261ad6
+    local rc=0
261ad6
+    local score=0
261ad6
+    if [ -n "$1" ]; then
261ad6
+        score=$1
261ad6
+    fi 
261ad6
+    # DONE: PRIO2: Only adjust master if value is really different (try to check that)
261ad6
+    oldscore=$(${HA_SBIN_DIR}/crm_master -G -q -l reboot)
261ad6
+    if [ "$oldscore" != "$score" ]; then
261ad6
+       super_ocf_log debug "DBG: SET crm master: $score (old: $oldscore)"
261ad6
+       ${HA_SBIN_DIR}/crm_master -v $score -l reboot; rc=$?
261ad6
+    else
261ad6
+       super_ocf_log debug "DBG: LET crm master: $score"
261ad6
+       rc=0
261ad6
+    fi
261ad6
+    #logger -t fhLOG "crm_master with: $OCF_RESOURCE_INSTANCE -v $score -l reboot"
261ad6
+    return $rc
261ad6
+}
261ad6
+
261ad6
+#
261ad6
+# function: scoring_crm_master - score instance due to role ans sync match (table SCORING_TABLE_PREFERRED_SITE_TAKEOVER)
261ad6
+# params:   NODE_ROLES NODE_SYNC_STATUS
261ad6
+# globals:  SCORING_TABLE_PREFERRED_SITE_TAKEOVER[@], 
261ad6
+#
261ad6
+scoring_crm_master()
261ad6
+{
261ad6
+    super_ocf_log info "FLOW $FUNCNAME ($*)"
261ad6
+    local roles="$1"
261ad6
+    local sync="$2"
261ad6
+    local skip=0
261ad6
+    local myScore=-1
261ad6
+    for scan in "${SCORING_TABLE_PREFERRED_SITE_TAKEOVER[@]}"; do
261ad6
+        if [ $skip -eq 0 ]; then
261ad6
+            read rolePatt syncPatt score <<< $scan
261ad6
+            if grep "$rolePatt" <<< "$roles"; then
261ad6
+               if grep "$syncPatt" <<< "$sync"; then
261ad6
+                  skip=1
261ad6
+                  myScore=$score 
261ad6
+               fi
261ad6
+            fi
261ad6
+        fi
261ad6
+    done
261ad6
+    super_ocf_log debug "DBG: scoring_crm_master adjust score $myScore"
261ad6
+    set_crm_master $myScore
261ad6
+}
261ad6
+
261ad6
+#
261ad6
+# function: get_crm_master - get the crm master score of the local node
261ad6
+# params:   -
261ad6
+# globals:  HA_SBIN_DIR(r)
261ad6
+#
261ad6
+function get_crm_master()
261ad6
+{
261ad6
+  super_ocf_log info "FLOW $FUNCNAME ($*)"
261ad6
+  local rc=0
261ad6
+   ${HA_SBIN_DIR}/crm_master -G -q -l reboot; rc=$?
261ad6
+   return $rc
261ad6
+}
261ad6
+
261ad6
+#
261ad6
+# function: saphana_init - initialize variables for the resource agent
261ad6
+# params:   InstanceName
261ad6
+# globals:  OCF_*(r), SID(w), sid(rw), sidadm(w), InstanceName(w), InstanceNr(w), SAPVIRHOST(w), PreferSiteTakeover(w), 
261ad6
+# globals:  sr_name(w), remoteHost(w), otherNodes(w) 
261ad6
+# globals:  ATTR_NAME_HANA_SYNC_STATUS(w), ATTR_NAME_HANA_CLONE_STATE(w)
261ad6
+# globals:  DIR_EXECUTABLE(w), SAPSTARTSRV(w), SAPCONTROL(w), DIR_PROFILE(w), SAPSTARTPROFILE(w), LD_LIBRARY_PATH(w), PATH(w)
261ad6
+# globals:  LPA_DIRECTORY(w), SIDInstanceName(w), remoteNode(w)
261ad6
+# saphana_init : Define global variables with default values, if optional parameters are not set
261ad6
+#
261ad6
+function saphana_init() {
261ad6
+    super_ocf_log info "FLOW $FUNCNAME ($*)"
261ad6
+    local rc=$OCF_SUCCESS
261ad6
+    local vName
261ad6
+    # two parameter models (for transition only)
261ad6
+    # OLD: InstanceName
261ad6
+    # NEW: SID InstanceNumber
261ad6
+    SID=$OCF_RESKEY_SID
261ad6
+    InstanceNr=$OCF_RESKEY_InstanceNumber
261ad6
+    SIDInstanceName="${SID}_HDB${InstanceNr}"
261ad6
+    InstanceName="HDB${InstanceNr}"
261ad6
+    super_ocf_log debug "DBG: Used new method to get SID ($SID) and InstanceNr ($InstanceNr)"
261ad6
+    sid=$(echo "$SID" | tr [:upper:] [:lower:])
261ad6
+    sidadm="${sid}adm"
261ad6
+    # DONE: PRIO4: SAPVIRHOST might be different to NODENAME
261ad6
+    # DONE: PRIO1: ASK: Is the output format of ListInstances fix? Could we take that as an API? Answer: Yes
261ad6
+    # try to catch:  Inst Info : LNX - 42 - lv9041 - 740, patch 36, changelist 1444691
261ad6
+    # We rely on the following format: SID is word#4, NR is work#6, vHost is word#8
261ad6
+    vName=$(/usr/sap/hostctrl/exe/saphostctrl -function ListInstances \
261ad6
+        | awk '$4 == SID && $6=NR { print $8 }' SID=$SID NR=$InstanceNr)
261ad6
+    if [ -z "$vName" ]; then
261ad6
+       #
261ad6
+       # if saphostctrl does not know the answer, try to fallback to attribute provided by SAPHanaTopology
261ad6
+       #
261ad6
+       vName=$(get_hana_attribute ${NODENAME} ${ATTR_NAME_HANA_VHOST[@]});
261ad6
+    fi
261ad6
+    SAPVIRHOST=${vName}
261ad6
+    PreferSiteTakeover="$OCF_RESKEY_PREFER_SITE_TAKEOVER"
261ad6
+    SAPHanaFilter="${OCF_RESKEY_SAPHanaFilter:-ra-act-dec-lpa}"
261ad6
+    AUTOMATED_REGISTER="${OCF_RESKEY_AUTOMATED_REGISTER:-false}"
261ad6
+    LPA_DIRECTORY=/var/lib/SAPHanaRA
261ad6
+    LPA_ATTR=("lpa_${sid}_lpt" "forever")
261ad6
+    super_ocf_log debug "DBG: SID=$SID, sid=$sid, SIDInstanceName=$SIDInstanceName, InstanceName=$InstanceName, InstanceNr=$InstanceNr, SAPVIRHOST=$SAPVIRHOST"
261ad6
+    ocf_env=$(env | grep 'OCF_RESKEY_CRM')
261ad6
+    super_ocf_log debug "DBG: OCF: $ocf_env"
261ad6
+    #
261ad6
+    ATTR_NAME_HANA_SYNC_STATUS=("hana_${sid}_sync_state" "reboot")  # SOK, SFAIL, UNKNOWN?
261ad6
+    ATTR_NAME_HANA_PRIMARY_AT=("hana_${sid}_primary_at"   "reboot") # Not used so far
261ad6
+    ATTR_NAME_HANA_CLONE_STATE=("hana_${sid}_clone_state" "reboot") # UKNOWN?, DEMOTED, PROMOTED
261ad6
+    ATTR_NAME_HANA_REMOTEHOST=("hana_${sid}_remoteHost" "forever")
261ad6
+    ATTR_NAME_HANA_SITE=("hana_${sid}_site" "forever")
261ad6
+    ATTR_NAME_HANA_ROLES=("hana_${sid}_roles" "reboot")
261ad6
+    ATTR_NAME_HANA_SRMODE=("hana_${sid}_srmode" "forever")
261ad6
+    ATTR_NAME_HANA_VHOST=("hana_${sid}_vhost" "forever")
261ad6
+    ATTR_NAME_HANA_STATUS=("hana_${sid}_status" "reboot")
261ad6
+    #
261ad6
+    # TODO: PRIO4: Table for non-preferred-site-takeover
261ad6
+    #
261ad6
+    SCORING_TABLE_PREFERRED_SITE_TAKEOVER=(
261ad6
+       "[234]*:P:[^:]*:master .*     150"
261ad6
+       "[015-9]*:P:[^:]*:master .*    90"
261ad6
+       "[0-9]*:P:[^:]*:slave  .*      60"
261ad6
+       "[0-9]*:P:[^:]*:\?     .*       0"
261ad6
+       "[0-9]*:P:[^:]*:-      .*       0"
261ad6
+       "[234]*:S:[^:]*:master SOK    100"
261ad6
+       "[015-9]*:S:[^:]*:master SOK   80"
261ad6
+       "[0-9]*:S:[^:]*:master SFAIL  -INFINITY"
261ad6
+       "[0-9]*:S:[^:]*:slave  SOK     10"
261ad6
+       "[0-9]*:S:[^:]*:slave  SFAIL  -INFINITY"
261ad6
+       "[0-9]*:S:[^:]*:\?     .*    0"
261ad6
+       "[0-9]*:S:[^:]*:-      .*    0"
261ad6
+       ".*                    .*   -1"
261ad6
+    )
261ad6
+    SCORING_TABLE_PREFERRED_LOCAL_RESTART=(
261ad6
+       "[0-9]*:P:[^:]*:master .*  150"
261ad6
+       "[0-9]*:P:[^:]*:slave  .*  140"
261ad6
+       "[0-9]*:P:[^:]*:\?     .*    0"
261ad6
+       "[0-9]*:P:[^:]*:-     .*     0"
261ad6
+       "[0-9]*:S:[^:]*:master SOK    100"
261ad6
+       "[0-9]*:S:[^:]*:master SFAIL  -INFINITY"
261ad6
+       "[0-9]*:S:[^:]*:slave  SOK     10"
261ad6
+       "[0-9]*:S:[^:]*:slave  SFAIL  -INFINITY"
261ad6
+       "[0-9]*:S:[^:]*:\?     .*    0"
261ad6
+       "[0-9]*:S:[^:]*:-      .*    0"
261ad6
+       ".*                    .*   -1"
261ad6
+    )
261ad6
+    #
261ad6
+    DUPLICATE_PRIMARY_TIMEOUT="${OCF_RESKEY_DUPLICATE_PRIMARY_TIMEOUT:-7200}"
261ad6
+    super_ocf_log debug "DBG: DUPLICATE_PRIMARY_TIMEOUT=$DUPLICATE_PRIMARY_TIMEOUT"
261ad6
+    #
261ad6
+    # Determine list of other cluster nodes and store in otherNodes variable
261ad6
+    otherNodes=()
261ad6
+    case $(crm_attribute --type crm_config --name cluster-infrastructure -q) in
261ad6
+       *corosync* ) otherNodes=($(crm_node -l | awk '{ if ($2 != me) { print $2 }}' me=${NODENAME}));;
261ad6
+       *openais* ) otherNodes=($(crm_node -l | awk '$3 == "member" { if ($2 != me) { print $2 }}' me=${NODENAME}));;
261ad6
+       *cman*    ) otherNodes=($(crm_node -l | awk '{for (i=1; i<=NF; i++) { if ($i != me) { print $i }}}' me=${NODENAME}));;
261ad6
+    esac
261ad6
+
261ad6
+    remoteHost=$(get_hana_attribute ${NODENAME} ${ATTR_NAME_HANA_REMOTEHOST[@]});
261ad6
+    if [ -z "$remoteHost" ]; then
261ad6
+       if [ ${#otherNodes[@]} -eq 1 ]; then # we are a 2 node cluster, lets assume the other is the remote-host
261ad6
+          remoteHost=${otherNodes[0]}
261ad6
+          remoteNode=$remoteHost
261ad6
+          super_ocf_log debug "DBG: auto-guess remoteHost=$remoteHost"
261ad6
+       else
261ad6
+          super_ocf_log debug "DBG: Could not auto-guess remoteHost out of list (${otherNodes[@]})"
261ad6
+       fi
261ad6
+    else
261ad6
+        #
261ad6
+        # search cluster node which vhost is equal remoteHost
261ad6
+        #
261ad6
+        remoteNode=$(remoteHost2remoteNode $remoteHost)
261ad6
+        # TODO: PRIO5: catch rc!=0
261ad6
+    fi
261ad6
+    #  ATTR_NAME_HANA_SITE
261ad6
+    sr_name=$(get_hana_attribute ${NODENAME} ${ATTR_NAME_HANA_SITE[@]});
261ad6
+    sr_mode=$(get_hana_attribute "${NODENAME}" ${ATTR_NAME_HANA_SRMODE[@]})
261ad6
+    if [ -z "$sr_mode" ]; then
261ad6
+        sr_mode="sync"
261ad6
+    fi
261ad6
+    super_ocf_log debug "DBG: sr_name=$sr_name, remoteHost=$remoteHost, remoteNode=$remoteNode, sr_mode=$sr_mode"
261ad6
+    # optional OCF parameters, we try to guess which directories are correct
261ad6
+    if  [ -z "$OCF_RESKEY_DIR_EXECUTABLE" ]
261ad6
+    then
261ad6
+        if have_binary /usr/sap/$SID/$InstanceName/exe/sapstartsrv && have_binary /usr/sap/$SID/$InstanceName/exe/sapcontrol
261ad6
+        then
261ad6
+            DIR_EXECUTABLE="/usr/sap/$SID/$InstanceName/exe"
261ad6
+        fi
261ad6
+    else
261ad6
+        if have_binary "$OCF_RESKEY_DIR_EXECUTABLE/sapstartsrv" && have_binary "$OCF_RESKEY_DIR_EXECUTABLE/sapcontrol"
261ad6
+        then
261ad6
+            DIR_EXECUTABLE="$OCF_RESKEY_DIR_EXECUTABLE"
261ad6
+        fi
261ad6
+    fi
261ad6
+    SAPSTARTSRV="$DIR_EXECUTABLE/sapstartsrv"
261ad6
+    SAPCONTROL="$DIR_EXECUTABLE/sapcontrol"
261ad6
+
261ad6
+    [ -z "$DIR_EXECUTABLE" ] && assert "Cannot find sapstartsrv and sapcontrol executable, please set DIR_EXECUTABLE parameter!"
261ad6
+    DIR_PROFILE="${OCF_RESKEY_DIR_PROFILE:-/usr/sap/$SID/SYS/profile}"
261ad6
+    # check, if the following fall-back is ok, or if there could be multiple profiles matching this pattern
261ad6
+    if [ -n "${SAPVIRHOST}" ]; then
261ad6
+        SAPSTARTPROFILE="$DIR_PROFILE/${OCF_RESKEY_INSTANCE_PROFILE:-${SID}_${InstanceName}_${SAPVIRHOST}}"
261ad6
+    else
261ad6
+        # check, if the following fall-back is ok, or if there could be multiple profiles matching this pattern
261ad6
+        # also take profile versions into account - they might break this fall-back
261ad6
+        # TODO: PRIO4: Check, if it makes sense to implement an additional last fall-back: get the SAPSTARTPROFILE from /usr/sap/sapservices
261ad6
+        #
261ad6
+        SAPSTARTPROFILE="$(ls -1 $DIR_PROFILE/${OCF_RESKEY_INSTANCE_PROFILE:-${SID}_${InstanceName}_*})"
261ad6
+    fi
261ad6
+    # as root user we need the library path to the SAP kernel to be able to call sapcontrol
261ad6
+    # check, if we already added DIR_EXECUTABLE at the beginning of LD_LIBRARY_PATH
261ad6
+    if [ "${LD_LIBRARY_PATH%%*:}" != "$DIR_EXECUTABLE" ]
261ad6
+    then
261ad6
+        LD_LIBRARY_PATH=$DIR_EXECUTABLE${LD_LIBRARY_PATH:+:}$LD_LIBRARY_PATH
261ad6
+        export LD_LIBRARY_PATH
261ad6
+    fi
261ad6
+    PATH=${PATH}:${DIR_EXECUTABLE}; export PATH
261ad6
+    super_ocf_log info "FLOW $FUNCNAME rc=$OCF_SUCCESS"
261ad6
+    #############################
261ad6
+    # TODO: PRIO9: To be able to call landscapeHostConfig.py without su (so as root)
261ad6
+    # TODO: PRIO9: Research for environment script .htacces or something like that
261ad6
+    #export SAPSYSTEMNAME=ZLF
261ad6
+    #export DIR_INSTANCE=/usr/sap/ZLF/HDB02
261ad6
+    #export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$DIR_INSTANCE/exe:$DIR_INSTANCE/exe/Python/lib
261ad6
+    #export PYTHONPATH=$DIR_INSTANCE/$HOST:$DIR_INSTANCE/exe/python_support:$DIR_INSTANCE/exe
261ad6
+    #export PYTHONHOME=$DIR_INSTANCE/exe/Python
261ad6
+    #export SAP_RETRIEVAL_PATH=$DIR_INSTANCE/$HOST
261ad6
+    #export DIR_EXECUTABLE=$DIR_INSTANCE/exe
261ad6
+    #############################
261ad6
+    return $OCF_SUCCESS
261ad6
+}
261ad6
+
261ad6
+# function: check_secstore_users
261ad6
+# params:   USER
261ad6
+# globals:  DIR_EXECUTABLE(r)
261ad6
+#
261ad6
+# TODO: PRIO5: Might be dropped, if we get a script for fetching the sync status
261ad6
+function check_secstore_users()
261ad6
+{
261ad6
+    super_ocf_log info "FLOW $FUNCNAME ($*)"
261ad6
+    local user=""
261ad6
+    local rc=1
261ad6
+    while [ $# -gt 0 ]; do
261ad6
+        user="$1"
261ad6
+        $DIR_EXECUTABLE/hdbuserstore list | grep -q "KEY $user" && echo "$user" && rc=0 && break
261ad6
+        shift
261ad6
+    done
261ad6
+    super_ocf_log info "FLOW $FUNCNAME rc=$rc"
261ad6
+    return $rc
261ad6
+}
261ad6
+
261ad6
+#
261ad6
+# function: check_sapstartsrv - check for sapstartsrv - optional start
261ad6
+# params:   -
261ad6
+# globals:  DIR_PROFILE(w), SAPSTARTPROFILE(r), SAPCONTROL(r), SID(r), InstanceName(r), InstanceNr(r), OCF_*(r)
261ad6
+# check_sapstartsrv : Before using sapcontrol we make sure that the sapstartsrv is running.
261ad6
+#
261ad6
+function check_sapstartsrv() {
261ad6
+    super_ocf_log info "FLOW $FUNCNAME ($*)"
261ad6
+    local restart=0
261ad6
+    local runninginst=""
261ad6
+    local rc=$OCF_SUCCESS
261ad6
+    local output=""
261ad6
+    if [ ! -S /tmp/.sapstream5${InstanceNr}13 ]; then
261ad6
+        super_ocf_log warn "ACT: sapstartsrv is not running for instance $SID-$InstanceName (no UDS), it will be started now"
261ad6
+        restart=1
261ad6
+    else
261ad6
+        output=$($SAPCONTROL -nr $InstanceNr -function ParameterValue INSTANCE_NAME -format script)
261ad6
+        if [ $? -eq 0 ]
261ad6
+        then
261ad6
+            runninginst=$(echo "$output" | grep '^0 : ' | cut -d' ' -f3)
261ad6
+            if [ "$runninginst" != "$InstanceName" ]
261ad6
+            then 
261ad6
+                super_ocf_log warn "ACT: sapstartsrv is running for instance $runninginst, that service will be killed"
261ad6
+                restart=1
261ad6
+            else
261ad6
+                output=$($SAPCONTROL -nr $InstanceNr -function AccessCheck Start)
261ad6
+                if [ $? -ne 0 ]; then
261ad6
+                    super_ocf_log warn "ACT: FAILED - sapcontrol -nr $InstanceNr -function AccessCheck Start ($(ls -ld1 /tmp/.sapstream5${InstanceNr}13))"
261ad6
+                    super_ocf_log warn "ACT: sapstartsrv will be restarted to try to solve this situation, otherwise please check sapstsartsrv setup (SAP Note 927637)"
261ad6
+                    restart=1
261ad6
+                fi
261ad6
+            fi
261ad6
+        else
261ad6
+            super_ocf_log warn "ACT: sapstartsrv is not running for instance $SID-$InstanceName, it will be started now"
261ad6
+            restart=1
261ad6
+        fi
261ad6
+    fi
261ad6
+    if [ -z "$runninginst" ]; then runninginst=$InstanceName; fi
261ad6
+    if [ $restart -eq 1 ]
261ad6
+    then
261ad6
+        if [ -d /usr/sap/$SID/SYS/profile/ ]
261ad6
+        then
261ad6
+            DIR_PROFILE="/usr/sap/$SID/SYS/profile"
261ad6
+        else
261ad6
+            assert "Expected /usr/sap/$SID/SYS/profile/ to be a directory, please set DIR_PROFILE parameter!"
261ad6
+        fi
261ad6
+        [ ! -r $SAPSTARTPROFILE ] && assert "Expected $SAPSTARTPROFILE to be the instance START profile, please set INSTANCE_PROFILE parameter!"
261ad6
+        pkill -9 -f "sapstartsrv.*$runninginst"
261ad6
+        # removing the unix domain socket files as they might have wrong permissions
261ad6
+        # or ownership - they will be recreated by sapstartsrv during next start
261ad6
+        rm -f /tmp/.sapstream5${InstanceNr}13
261ad6
+        rm -f /tmp/.sapstream5${InstanceNr}14
261ad6
+        $SAPSTARTSRV pf=$SAPSTARTPROFILE -D -u $sidadm
261ad6
+        # now make sure the daemon has been started and is able to respond
261ad6
+        local srvrc=1
261ad6
+        while [ $srvrc -eq 1 -a $(pgrep -f "sapstartsrv.*$runninginst" | wc -l) -gt 0 ]
261ad6
+        do
261ad6
+            sleep 1
261ad6
+            $SAPCONTROL -nr $InstanceNr -function GetProcessList > /dev/null 2>&1
261ad6
+            srvrc=$?
261ad6
+        done
261ad6
+        if [ $srvrc -ne 1 ]
261ad6
+        then
261ad6
+            super_ocf_log info "ACT: sapstartsrv for instance $SID-$InstanceName was restarted!"
261ad6
+            rc=$OCF_SUCCESS
261ad6
+        else
261ad6
+            super_ocf_log error "ACT: sapstartsrv for instance $SID-$InstanceName could not be started!"
261ad6
+            rc=$OCF_ERR_GENERIC
261ad6
+            ocf_is_probe && rc=$OCF_NOT_RUNNING
261ad6
+        fi
261ad6
+    fi
261ad6
+    return $rc
261ad6
+}
261ad6
+
261ad6
+#
261ad6
+# function: cleanup_instance - remove resources from a crashed instance
261ad6
+# params:   -
261ad6
+# globals:  -
261ad6
+#
261ad6
+function cleanup_instance() {
261ad6
+  super_ocf_log info "FLOW $FUNCNAME ($*)"
261ad6
+  local rc=0
261ad6
+  # TODO: PRIO5: Check, if we need HANA cleanup procedure (processes, ipc obj, pid files); Currently not needed
261ad6
+  super_ocf_log debug "DBG: cleanup_instance currently not implemented"
261ad6
+  rc=0
261ad6
+  super_ocf_log info "FLOW $FUNCNAME rc=$rc"
261ad6
+}
261ad6
+
261ad6
+#
261ad6
+# function: check_for_primary - check if local SAP HANA is configured as primary
261ad6
+# params:   -
261ad6
+# globals:  HANA_STATE_PRIMARY(r), HANA_STATE_SECONDARY(r), HANA_STATE_DEFECT(r)
261ad6
+#
261ad6
+function check_for_primary() {
261ad6
+    super_ocf_log info "FLOW $FUNCNAME ($*)"
261ad6
+    local rc=$HANA_STATE_DEFECT
261ad6
+    node_full_status=$(su - ${sidadm} -c "hdbnsutil -sr_state" 2>/dev/null )
261ad6
+    node_status=$(echo "$node_full_status" | awk '$1=="mode:" {print $2}')
261ad6
+    super_ocf_log debug "DBG: check_for_primary: node_status=$node_status"
261ad6
+    for i in  1 2 3 4 5 6 7 8 9; do
261ad6
+       case "$node_status" in
261ad6
+           primary ) 
261ad6
+                  super_ocf_log info "FLOW $FUNCNAME rc=HANA_STATE_PRIMARY"
261ad6
+                  return $HANA_STATE_PRIMARY;;
261ad6
+           syncmem | sync | async )
261ad6
+                  super_ocf_log info "FLOW $FUNCNAME rc=HANA_STATE_SECONDARY"
261ad6
+                  return $HANA_STATE_SECONDARY;;
261ad6
+           none )     # have seen that mode on second side BEFEORE we registered it as replica
261ad6
+                  super_ocf_log info "FLOW $FUNCNAME rc=HANA_STATE_STANDALONE"
261ad6
+                  return $HANA_STATE_STANDALONE;;
261ad6
+           * )
261ad6
+	          super_ocf_log err "ACT: check_for_primary:  we didn't expect node_status to be: <$node_status>"
261ad6
+                  dump=$( echo $node_status | hexdump -C );
261ad6
+	          super_ocf_log err "ACT: check_for_primary:  we didn't expect node_status to be: DUMP <$dump>"
261ad6
+                  node_full_status=$(su - ${sidadm} -c "hdbnsutil -sr_state" 2>/dev/null )
261ad6
+                  node_status=$(echo "$node_full_status" | awk '$1=="mode:" {print $2}')
261ad6
+                  super_ocf_log debug "DEC: check_for_primary: loop=$i: node_status=$node_status"
261ad6
+                  # TODO: PRIO1: Maybe we need to keep the old value for P/S/N, if hdbnsutil just crashes
261ad6
+       esac;
261ad6
+    done
261ad6
+    super_ocf_log info "FLOW $FUNCNAME rc=$rc"
261ad6
+    return $rc
261ad6
+}
261ad6
+
261ad6
+#
261ad6
+# function: analyze_hana_sync_status - query and check hana system replication status
261ad6
+# params:   -
261ad6
+# globals:  DIR_EXECUTABLE(r), remoteHost(r)
261ad6
+# get the HANA sync status
261ad6
+# 
261ad6
+function analyze_hana_sync_status()
261ad6
+{
261ad6
+    super_ocf_log info "FLOW $FUNCNAME ($*)"
261ad6
+    local -a clusterNodes=()
261ad6
+    local cl=""
261ad6
+    local vHost=""
261ad6
+    local n=""
261ad6
+    local hana_sync_status="" what_does_the_chamelion_say=""
261ad6
+    local secUser="SLEHALOC"
261ad6
+    local chkusr;
261ad6
+    local rc=0
261ad6
+    local sqlrc=0
261ad6
+# local query_state='select distinct REPLICATION_STATUS from SYS.M_SERVICE_REPLICATION'
261ad6
+# select distinct REPLICATION_STATUS from SYS.M_SERVICE_REPLICATION where SITE_NAME='"SITE1"'"
261ad6
+    local query_state="select distinct REPLICATION_STATUS from SYS.M_SERVICE_REPLICATION where SITE_NAME='"${sr_name}"'"
261ad6
+    local query_secondaries='select distinct  SECONDARY_HOST from SYS.M_SERVICE_REPLICATION'
261ad6
+    local query_failed_secondaries="select distinct SECONDARY_HOST from SYS.M_SERVICE_REPLICATION  where SECONDARY_SITE_NAME = (select distinct  SECONDARY_SITE_NAME from SYS.M_SERVICE_REPLICATION WHERE REPLICATION_STATUS != 'ACTIVE')"
261ad6
+    local all_cluster_hosts all_secondary_hosts all_broken_secondaries
261ad6
+#
261ad6
+#####################################################################################################
261ad6
+#
261ad6
+# select distinct SITE_NAME, HOST, REPLICATION_STATUS, SECONDARY_SITE_NAME, SECONDARY_HOST from SYS.M_SERVICE_REPLICATION
261ad6
+#
261ad6
+# ===> "Walldorf", "sap-app-8"  "ACTIVE", "Rot",  "sap-app-5"
261ad6
+#      "Rot",      "sap-app-5", "ACTIVE", "oslo", "sap-app-7"
261ad6
+#
261ad6
+#####################################################################################################
261ad6
+#
261ad6
+    secUser=$(check_secstore_users SAPHANA${SID}SR SLEHALOC RHELHALOC) ; chkusr=$?
261ad6
+    if [ $chkusr -ne 0 ]; then
261ad6
+        super_ocf_log err  "ACT: Secure store users are missing (see best practice manual how to setup the users)"
261ad6
+        rc=$OCF_ERR_CONFIGURED
261ad6
+    fi
261ad6
+    hana_sync_status=$(timeout 60 $DIR_EXECUTABLE/hdbsql -a -x -U $secUser  $query_state); sqlrc=$?
261ad6
+    hana_sync_status=$(echo $hana_sync_status | dequote)
261ad6
+    super_ocf_log debug "DBG: hdbsql rc=$sqlrc hana_sync_status=\"$hana_sync_status\""
261ad6
+    if [ "$sqlrc" -eq 0 -a "$hana_sync_status" != "" ]; then
261ad6
+        #
261ad6
+        # UNKNOWN, ACTIVE, ERROR, INITIALIZING
261ad6
+        #
261ad6
+        if [ "${hana_sync_status}" == "ACTIVE" ]; then
261ad6
+            # TODO PRIO1: REMOVE remoteNode dependency - set SOK
261ad6
+            set_hana_attribute "$remoteNode" "SOK" ${ATTR_NAME_HANA_SYNC_STATUS[@]}
261ad6
+        else
261ad6
+            super_ocf_log warn "ACT: HANA SYNC STATUS is: ${hana_sync_status}"
261ad6
+            # TODO PRIO1: REMOVE remoteNode dependency - set SFAIL
261ad6
+            set_hana_attribute "$remoteNode" "SFAIL" ${ATTR_NAME_HANA_SYNC_STATUS[@]}
261ad6
+        fi
261ad6
+        # first get a list of all secondary hosts, than a list of all secondary hosts, if the is ANY failure at this site
261ad6
+        #    TODO: PRIO9: for first we assume there is only ONE secondary site (like ROT)
261ad6
+        #    TODO: PRIO3: should we loop over all cluster nodes fetching their roles-attribute? To minimize sql-queries?
261ad6
+        #
261ad6
+        all_secondary_hosts=$(timeout 60 hdbsql -a -x -U $secUser $query_secondaries ); sqlrc=$?
261ad6
+        all_secondary_hosts=$(echo $all_secondary_hosts | dequote);
261ad6
+        if [ "$sqlrc" -eq 0 ]; then
261ad6
+            all_broken_secondary_hosts=$(timeout 60 hdbsql -a -x -U $secUser $query_failed_secondaries); sqlrc=$?
261ad6
+            all_broken_secondary_hosts=$(echo $all_broken_secondary_hosts | dequote);
261ad6
+            if  [ "$sqlrc" -eq 0 ]; then                 
261ad6
+                 if [ -n "$all_broken_secondary_hosts" ]; then
261ad6
+                     #
261ad6
+                     # we have a broken secondary site - set all hosts to "SFAIL"
261ad6
+                     #
261ad6
+                     # Note: since HANA hostname can be different from nodename we need to check all vhost attributes
261ad6
+                     for n in $all_broken_secondary_hosts; do
261ad6
+                         for cl in ${otherNodes[@]}; do
261ad6
+                             vHost=$(get_hana_attribute $cl  ${ATTR_NAME_HANA_VHOST[@]})
261ad6
+                             if [ "$vHost" = "$n" ]; then # we found the correct node
261ad6
+                                set_hana_attribute $cl "SFAIL" ${ATTR_NAME_HANA_SYNC_STATUS[@]}
261ad6
+                             fi
261ad6
+                         done  
261ad6
+                     done
261ad6
+                 fi
261ad6
+            fi
261ad6
+        fi                  
261ad6
+    else
261ad6
+        # return codes 19: license error -> set SFAIL!
261ad6
+        case "$sqlrc" in
261ad6
+            19 ) 
261ad6
+                # DONE: PRIO1: We should NOT set SFAIL, if HDB is exactly broken now
261ad6
+                #       When HDB breaks during monitor this could prevent a prositive remote failover
261ad6
+                super_ocf_log warn "ACT: Was not able to fetch HANA SYNC STATUS - set sync status to SFAIL for ALL OTHER cluster hosts"
261ad6
+                for n in $otherNodes; do
261ad6
+                    set_hana_attribute "$n" "SFAIL" ${ATTR_NAME_HANA_SYNC_STATUS[@]}
261ad6
+                done
261ad6
+                ;;
261ad6
+        esac
261ad6
+    fi  
261ad6
+    return $rc
261ad6
+}
261ad6
+
261ad6
+#
261ad6
+# function: get_hana_landscape_status - figure out hana ladscape status
261ad6
+# params:   -
261ad6
+# globals:  sidadm(r), DIR_EXECUTABLE(r)
261ad6
+#
261ad6
+function get_hana_landscape_status()
261ad6
+{
261ad6
+    super_ocf_log info "FLOW $FUNCNAME ($*)"
261ad6
+    local rc=0
261ad6
+    #
261ad6
+    su - $sidadm -c "python $DIR_EXECUTABLE/python_support/landscapeHostConfiguration.py" 1>/dev/null 2>/dev/null; rc=$?
261ad6
+    return $rc;
261ad6
+}
261ad6
+
261ad6
+#
261ad6
+# function: register_hana_secondary - register local hana as secondary to the other site
261ad6
+# params:   -
261ad6
+# globals:  sidadm(r), remoteHost(r), InstanceNr(r), sr_mode(r), sr_name(r)
261ad6
+# register_hana_secondary
261ad6
+#
261ad6
+function register_hana_secondary()
261ad6
+{
261ad6
+    super_ocf_log info "FLOW $FUNCNAME ($*)"
261ad6
+    local rc=2;
261ad6
+    local remoteInstance="";
261ad6
+    remoteInstance=$InstanceNr
261ad6
+    if ocf_is_true ${AUTOMATED_REGISTER}; then
261ad6
+       super_ocf_log info "ACT: REGISTER: hdbnsutil -sr_register --remoteHost=$remoteHost --remoteInstance=$remoteInstance --mode=$sr_mode --name=$sr_name"
261ad6
+       su - $sidadm -c "hdbnsutil -sr_register --remoteHost=$remoteHost --remoteInstance=$remoteInstance --mode=$sr_mode --name=$sr_name"; rc=$?
261ad6
+    else
261ad6
+       super_ocf_log info "ACT: IGNORE REGISTER because AUTOMATED_REGISTER is set to FALSE"
261ad6
+       rc=1
261ad6
+    fi
261ad6
+    super_ocf_log info "FLOW $FUNCNAME rc=$rc"
261ad6
+    return $rc;
261ad6
+}
261ad6
+
261ad6
+#
261ad6
+# function: saphana_status - pure status check
261ad6
+# params:   -
261ad6
+# globals:  SIDInstanceName, OCF_*, 
261ad6
+function saphana_status() {
261ad6
+    local binDeam="hdb.sap${SIDInstanceName}" rc=0
261ad6
+    binDeam=${binDeam:0:15}   # Process name is limited to the first 15 characters
261ad6
+    if pgrep $binDeam 1>/dev/null; then rc=$OCF_SUCCESS; else rc=$OCF_NOT_RUNNING; fi
261ad6
+    return $rc
261ad6
+}
261ad6
+
261ad6
+#
261ad6
+# function: saphana_start - start a hana instance
261ad6
+# params:   -
261ad6
+# globals:  OCF_*, SAPCONTROL, InstanceNr, SID, InstanceName, 
261ad6
+#
261ad6
+function saphana_start() {
261ad6
+    super_ocf_log info "FLOW $FUNCNAME ($*)"
261ad6
+    local rc=$OCF_NOT_RUNNING
261ad6
+    local output=""
261ad6
+    local loopcount=0  
261ad6
+    check_sapstartsrv
261ad6
+    rc=$?
261ad6
+    #
261ad6
+    # TODO: ASK: PRIO5: For SCALE-OUT - do we need to use an other call like StartSystem? Or better to use the HDB command?
261ad6
+    #
261ad6
+    if [ $rc -eq $OCF_SUCCESS ]; then
261ad6
+        output=$($SAPCONTROL -nr $InstanceNr -function Start)
261ad6
+        rc=$?
261ad6
+        super_ocf_log info "ACT: Starting SAPHANA Instance $SID-$InstanceName: $output"
261ad6
+    fi
261ad6
+    if [ $rc -eq 0 ]
261ad6
+    then
261ad6
+        # TODO: PRIO9: something more dynamic than 3600 seconds in WaitforStarted
261ad6
+        output=$($SAPCONTROL -nr $InstanceNr -function WaitforStarted 3600 1)
261ad6
+        if [ $? -eq 0 ]
261ad6
+        then
261ad6
+            super_ocf_log info "ACT: SAPHANA Instance $SID-$InstanceName started: $output"
261ad6
+            rc=$OCF_SUCCESS
261ad6
+        else
261ad6
+            super_ocf_log err "ACT: SAPHANA Instance $SID-$InstanceName start failed: $output"
261ad6
+            rc=$OCF_ERR_GENERIC
261ad6
+        fi
261ad6
+    else
261ad6
+        super_ocf_log err "ACT: SAPHANA Instance $SID-$InstanceName start failed: $output"
261ad6
+        rc=$OCF_ERR_GENERIC
261ad6
+    fi
261ad6
+    super_ocf_log info "FLOW $FUNCNAME rc=$rc"
261ad6
+    return $rc
261ad6
+}
261ad6
+
261ad6
+#
261ad6
+# function: saphana_stop - stop a hana instance
261ad6
+# params:   -
261ad6
+# globals:  OCF_*(r), SAPCONTROL(r), SID(r), InstanceName(r)
261ad6
+# saphana_stop: Stop the SAP instance
261ad6
+#
261ad6
+function saphana_stop() {
261ad6
+  super_ocf_log info "FLOW $FUNCNAME ($*)"
261ad6
+  local output=""
261ad6
+  local rc=0
261ad6
+  check_sapstartsrv; rc=$?
261ad6
+  if [ $rc -eq $OCF_SUCCESS ]; then
261ad6
+    output=$($SAPCONTROL -nr $InstanceNr -function Stop)
261ad6
+    rc=$?
261ad6
+    super_ocf_log info "ACT: Stopping SAP Instance $SID-$InstanceName: $output"
261ad6
+  fi
261ad6
+  if [ $rc -eq 0 ]
261ad6
+  then
261ad6
+    output=$($SAPCONTROL -nr $InstanceNr -function WaitforStopped 3600 1)
261ad6
+    if [ $? -eq 0 ]
261ad6
+    then
261ad6
+      super_ocf_log info "ACT: SAP Instance $SID-$InstanceName stopped: $output"
261ad6
+      rc=$OCF_SUCCESS
261ad6
+    else
261ad6
+      super_ocf_log err "ACT: SAP Instance $SID-$InstanceName stop failed: $output"
261ad6
+      rc=$OCF_ERR_GENERIC
261ad6
+    fi
261ad6
+  else
261ad6
+    super_ocf_log err "ACT: SAP Instance $SID-$InstanceName stop failed: $output"
261ad6
+    rc=$OCF_ERR_GENERIC
261ad6
+  fi
261ad6
+  super_ocf_log info "FLOW $FUNCNAME rc=$rc"
261ad6
+  return $rc
261ad6
+}
261ad6
+
261ad6
+#
261ad6
+# function: saphana_validate - validation of (some) variables/parameters
261ad6
+# params:   -
261ad6
+# globals:  OCF_*(r), SID(r), InstanceName(r), InstanceNr(r), SAPVIRHOST(r)
261ad6
+# saphana_validate: Check the symantic of the input parameters 
261ad6
+#
261ad6
+function saphana_validate() {
261ad6
+  super_ocf_log info "FLOW $FUNCNAME ($*)"
261ad6
+  local rc=$OCF_SUCCESS
261ad6
+  #
261ad6
+  # SID is Alpha-AlphaNumeric-Alphanumeric?
261ad6
+  #
261ad6
+  if [ $(echo "$SID" | grep -c '^[A-Z][A-Z0-9][A-Z0-9]$') -ne 1 ]
261ad6
+  then
261ad6
+    super_ocf_log err "ACT: Parsing instance profile name: '$SID' is not a valid SID!"
261ad6
+    rc=$OCF_ERR_ARGS
261ad6
+  fi
261ad6
+  #
261ad6
+  # InstanceNr is a two-Digit?
261ad6
+  #
261ad6
+  if [ $(echo "$InstanceNr" | grep -c '^[0-9][0-9]$') -ne 1 ]
261ad6
+  then
261ad6
+    super_ocf_log err "ACT: Parsing instance profile name: '$InstanceNr' is not a valid instance number!"
261ad6
+    rc=$OCF_ERR_ARGS
261ad6
+  fi
261ad6
+  super_ocf_log info "FLOW $FUNCNAME rc=$rc"
261ad6
+  return $rc
261ad6
+}
261ad6
+
261ad6
+#
261ad6
+# function: saphana_start_primary - handle startup of PRIMARY in M/S
261ad6
+# params:
261ad6
+# globals: OCF_*(r), NODENAME, ATTR_NAME_*, HANA_STATE_*, 
261ad6
+#
261ad6
+function saphana_start_primary()
261ad6
+{
261ad6
+    super_ocf_log info "FLOW $FUNCNAME ($*)"
261ad6
+	local primary_status sync_attr score_master rc=$OCF_NOT_RUNNING
261ad6
+    local lss sqlrc;
261ad6
+    local rc=0
261ad6
+    local lpa_dec=4
261ad6
+    local lpa_advice=""
261ad6
+    #
261ad6
+    # we will be a master (PRIMARY) so checking, if the is an OTHER master
261ad6
+    #
261ad6
+    super_ocf_log debug "DBG: saphana_primary - check_for_primary reports HANA_STATE_PRIMARY"
261ad6
+    # 
261ad6
+    lpa_init_lpt $HANA_STATE_PRIMARY
261ad6
+    lpa_check_lpt_status; lpa_dec=$?
261ad6
+    get_hana_landscape_status; lss=$?
261ad6
+    my_role=$(get_hana_attribute ${NODENAME} ${ATTR_NAME_HANA_ROLES[@]})
261ad6
+    my_sync=$(get_hana_attribute ${NODENAME} ${ATTR_NAME_HANA_SYNC_STATUS[@]})
261ad6
+    case "$lpa_dec" in
261ad6
+        0 ) # LPA says start-up
261ad6
+            lpa_advice="start"
261ad6
+            ;;
261ad6
+        1)  # LPA says register!
261ad6
+            lpa_advice="register"
261ad6
+            ;;
261ad6
+        2)  # LPA says wait for second LPT
261ad6
+            lpa_advice="wait"
261ad6
+            ;;
261ad6
+        3 | 4 ) # LPA says something is completely wrong - FAIL resource
261ad6
+            lpa_advice="fail"
261ad6
+            ;;
261ad6
+        * ) # LPA failed with an unkonown status - FAIL resource
261ad6
+            lpa_advice="fail"
261ad6
+            ;;
261ad6
+    esac
261ad6
+    
261ad6
+    # DONE: PRIO2: Do we need to differ 0 and 1 here? While 0 is a fatal SAP error, 1 for down/error
261ad6
+    if [ $lss -eq 0 ]; then
261ad6
+       super_ocf_log err "ACT: get_hana_landscape_status reports FATAL"
261ad6
+       # DONE: PRIO1: what to do for lss=0?
261ad6
+       # TODO: PRIO3: Check, if OCF_ERR_GENERIC is best reaction
261ad6
+       lpa_advice="skip"
261ad6
+       rc=$OCF_ERR_GENERIC
261ad6
+    fi
261ad6
+    case "$lpa_advice" in
261ad6
+        start )  # process a normal START
261ad6
+            case "$lss" in
261ad6
+                2 | 3 | 4 ) # as landcape says we are up - just set the scores and return code
261ad6
+                    super_ocf_log info "LPA: landcape: UP, LPA: start ==> keep running"
261ad6
+                    LPTloc=$(date '+%s')
261ad6
+                    lpa_set_lpt $LPTloc
261ad6
+                    rc=$OCF_SUCCSESS
261ad6
+                    ;;
261ad6
+                1 ) # landcape says we are down, lets start and adjust scores and return code
261ad6
+                    super_ocf_log info "LPA: landcape: DOWN, LPA: start ==> start instance"
261ad6
+                    saphana_start
261ad6
+                    rc=$?                    
261ad6
+                    LPTloc=$(date '+%s')
261ad6
+                    lpa_set_lpt $LPTloc
261ad6
+                    ;;
261ad6
+            esac
261ad6
+            scoring_crm_master "$my_role" "$my_sync"
261ad6
+            ;;
261ad6
+        register ) # process a REGISTER
261ad6
+            case "$lss" in
261ad6
+                2 | 3 | 4 ) # upps we are up - but shoudn't? - we could not register with started HDB
261ad6
+                    # DONE: PRIO3: check if this reaction is correct - tell cluster about failed start
261ad6
+                    super_ocf_log info "LPA: landcape: UP, LPA: register ==> take down"
261ad6
+                    set_crm_master -inf
261ad6
+                    rc=$OCF_NOT_RUNNING 
261ad6
+                    ;;
261ad6
+                1 ) # lets try to register
261ad6
+                    # DONE: PRIO2: Like Action in start_secondary
261ad6
+                    super_ocf_log info "LPA: landcape: DOWN, LPA: register ==> try to register"
261ad6
+                    super_ocf_log info "DEC: AN OTHER HANA IS AVAILABLE ==> LETS REGISTER"
261ad6
+                    set_crm_master  0
261ad6
+                    if wait_for_primary_master 1; then
261ad6
+                        register_hana_secondary 
261ad6
+                        check_for_primary; primary_status=$?
261ad6
+                        if [ $primary_status -eq $HANA_STATE_SECONDARY ]; then
261ad6
+                            super_ocf_log info "ACT: Register successful"
261ad6
+                            lpa_push_lpt 10
261ad6
+                            lpa_set_lpt  10
261ad6
+                            set_crm_master  0
261ad6
+                            saphana_start_secondary
261ad6
+                            rc=$?
261ad6
+                            lpa_set_lpt  30
261ad6
+                        else
261ad6
+                            super_ocf_log err "ACT: Register failed"
261ad6
+                            rc=$OCF_NOT_RUNNING
261ad6
+                        fi                                         
261ad6
+                    else
261ad6
+                        # lets check next monitor, if we can register
261ad6
+                        rc=$OCF_SUCCESS
261ad6
+                    fi
261ad6
+                    ;;
261ad6
+            esac
261ad6
+            ;;
261ad6
+        wait )  # process a WAIT
261ad6
+            case "$lss" in
261ad6
+                2 | 3 | 4 ) # as we ARE up we just keep it up
261ad6
+                    # TODO: PRIO3: I now change from "just keep it up to take that down"
261ad6
+                    # TODO: PRIO3: OCF_SUCCSESS, OCF_NOT_RUNNING or OCF_ERR_xxxx ?
261ad6
+                    set_crm_master -9000
261ad6
+                    #scoring_crm_master "$my_role" "$my_sync"
261ad6
+                    rc=$OCF_ERR_GENERIC
261ad6
+                    ;;
261ad6
+                1 ) # we are down, so we should wait --> followup in next monitor
261ad6
+                    super_ocf_log info "LPA: landcape: DOWN, LPA: wait ==> keep waiting"
261ad6
+                    # TODO: PRIO3: Check, if WAITING is correct here
261ad6
+                    set_hana_attribute ${NODENAME} "WAITING" ${ATTR_NAME_HANA_CLONE_STATE[@]}
261ad6
+                    set_crm_master -9000
261ad6
+                    rc=$OCF_SUCCSESS
261ad6
+                    ;;
261ad6
+            esac
261ad6
+            ;;
261ad6
+        fail )   # process a lpa FAIL
261ad6
+            super_ocf_log info "LPA: LPA reports FAIL"
261ad6
+            set_crm_master -inf
261ad6
+            rc=$OCF_NOT_RUNNING 
261ad6
+            ;;
261ad6
+    esac
261ad6
+    super_ocf_log info "FLOW $FUNCNAME rc=$rc"
261ad6
+    return $rc
261ad6
+}
261ad6
+
261ad6
+#
261ad6
+# check_for_primary_master
261ad6
+# params: -
261ad6
+# globals: ATTR_NAME_HANA_ROLES[@], NODENAME
261ad6
+#
261ad6
+check_for_primary_master()
261ad6
+{
261ad6
+    super_ocf_log info "FLOW $FUNCNAME ($*)"
261ad6
+    local rc=1
261ad6
+    local ch ch_role
261ad6
+    #
261ad6
+    # get actual list of cluster members
261ad6
+    # 
261ad6
+    if [ -n "$otherNodes" ]; then
261ad6
+        for ch in ${otherNodes[@]}; do
261ad6
+            if [ $rc -eq 1 ]; then
261ad6
+                ch_role=$(get_hana_attribute ${ch} ${ATTR_NAME_HANA_ROLES[@]})
261ad6
+# TODO: PRIO3: check if [0-9], [234] or [34] is correct
261ad6
+# TODO: PRIO4: Do we need different checks like "any-primary-master" or "running-primary-master" ?
261ad6
+#                grep '[0-9]*:P:[^:]*:master:' <<< $ch_role && rc=0
261ad6
+#                grep '[34]:P:[^:]*:master:' <<< $ch_role && rc=0
261ad6
+#               Match "Running+Available Primary" Master -> Match field 1: 3/4, 2: P, 4: master 
261ad6
+                awk -F: 'BEGIN { rc=1 } 
261ad6
+                         $1 ~ "[34]" && $2 ="P" && $4="master" { rc=0 } 
261ad6
+                         END { exit rc }' <<< $ch_role  ; rc=$? 
261ad6
+            fi
261ad6
+        done
261ad6
+    fi 
261ad6
+    super_ocf_log info "FLOW $FUNCNAME rc=$rc"
261ad6
+    return $rc
261ad6
+}
261ad6
+
261ad6
+#
261ad6
+# wait_for_primary_master: wait some time till a running primary master is shown in attributes
261ad6
+# params: optional: loop count - currently time in 10s waiting loop
261ad6
+# globals: -
261ad6
+#
261ad6
+wait_for_primary_master()
261ad6
+{
261ad6
+    local wait=1
261ad6
+    local rc=1
261ad6
+    local loops=${1:-0}
261ad6
+    local count=0
261ad6
+    super_ocf_log info "FLOW $FUNCNAME ($*)"
261ad6
+    #
261ad6
+    # hana_ndb_roles=primary:master1:master:worker:master
261ad6
+    #
261ad6
+    while [ "$wait" -eq 1 ]; do
261ad6
+        if check_for_primary_master; then
261ad6
+           wait=0
261ad6
+           rc=0
261ad6
+        else
261ad6
+           if [ $loops -gt 0 ]; then
261ad6
+              (( count++ ))
261ad6
+              if [ $count -gt $loops ]; then
261ad6
+                 wait=0
261ad6
+                 rc=1
261ad6
+              fi
261ad6
+           fi
261ad6
+           sleep 10
261ad6
+        fi
261ad6
+    done
261ad6
+    super_ocf_log info "FLOW $FUNCNAME rc=$rc"
261ad6
+    return $rc
261ad6
+}
261ad6
+
261ad6
+#
261ad6
+# function: saphana_start_secondary - handle startup of PRIMARY in M/S
261ad6
+# params:
261ad6
+# globals: OCF_*(r), NODENAME, ATTR_NAME_*, 
261ad6
+#
261ad6
+function saphana_start_secondary()
261ad6
+{
261ad6
+    super_ocf_log info "FLOW $FUNCNAME ($*)"
261ad6
+	local primary_status sync_attr score_master rc=$OCF_NOT_RUNNING
261ad6
+    local sqlrc;
261ad6
+    set_crm_master 0
261ad6
+    #
261ad6
+    ####### LPA - begin
261ad6
+    #
261ad6
+    lpa_push_lpt 10
261ad6
+    lpa_set_lpt  10
261ad6
+    # 
261ad6
+    ####### LPA - end
261ad6
+    # 
261ad6
+    #
261ad6
+    # we would be slave (secondary)
261ad6
+    # we first need to check, if there are Master Nodes, because the Scecondary only starts
261ad6
+    # successfuly, if the Primary is available. Thatfore we mark the Secondary as "WAITING"
261ad6
+    # DONE: PRIO3: wait_for_primary_master 10 is just a test value: 10 loops x10 seconds than go to WAITING
261ad6
+    # DONE: PRIO3: rename 'wait_for_primary_master' to match better the use case ("wait_some_time")
261ad6
+    #
261ad6
+    super_ocf_log debug "DBG: wait for promoted side"
261ad6
+    # TODO: PRIO3: Check if setting SFAIL during secondary start is ok
261ad6
+    set_hana_attribute "${NODENAME}" "SFAIL" ${ATTR_NAME_HANA_SYNC_STATUS[@]}
261ad6
+    if wait_for_primary_master 10; then
261ad6
+       saphana_start; rc=$?
261ad6
+       if [ $rc -ne $OCF_SUCCESS ]; then
261ad6
+           if ! wait_for_primary_master 1; then
261ad6
+               # It seams the stating secondary could not start because of stopping primary
261ad6
+               #    so this is a WAITING situation
261ad6
+               super_ocf_log info "ACT: PRIMARY seams to be down now ==> WAITING"
261ad6
+               set_hana_attribute ${NODENAME} "WAITING" ${ATTR_NAME_HANA_CLONE_STATE[@]}
261ad6
+               set_crm_master -INFINITY
261ad6
+               rc=$OCF_SUCCSESS
261ad6
+           fi
261ad6
+       else
261ad6
+               lpa_set_lpt  30
261ad6
+       fi
261ad6
+    else
261ad6
+       super_ocf_log info "ACT: wait_for_primary_master ==> WAITING"
261ad6
+       set_hana_attribute ${NODENAME} "WAITING" ${ATTR_NAME_HANA_CLONE_STATE[@]}
261ad6
+       set_crm_master -INFINITY
261ad6
+       rc=$OCF_SUCCSESS
261ad6
+    fi
261ad6
+    super_ocf_log info "FLOW $FUNCNAME rc=$rc"
261ad6
+    return $rc
261ad6
+}
261ad6
+
261ad6
+#
261ad6
+# function: lpa_get_lpt - get lpt from cluster
261ad6
+# params:   NODE
261ad6
+# output:   LPT
261ad6
+# rc:       rc=0: OK, rc=1: InternalERROR, rc=2: ERROR
261ad6
+# globals:  LPA_ATTR_*, 
261ad6
+#
261ad6
+function lpa_get_lpt() {
261ad6
+    super_ocf_log info "FLOW $FUNCNAME ($*)"
261ad6
+    local rc=1
261ad6
+    local node=$1
261ad6
+    local lpt=""
261ad6
+    lpt=$(get_hana_attribute ${node} ${LPA_ATTR[@]})
261ad6
+    if [ -n "$lpt" ]; then
261ad6
+        rc=0
261ad6
+        echo $lpt
261ad6
+    else
261ad6
+        rc=2
261ad6
+    fi
261ad6
+    super_ocf_log info "FLOW $FUNCNAME rc=$rc"
261ad6
+    return $rc    
261ad6
+}
261ad6
+
261ad6
+#
261ad6
+# function: lpa_set_lpt - set lpt in cluster
261ad6
+# params:   LPT [node]
261ad6
+# globals:  LPA_ATTR(r), NODENAME(r),
261ad6
+# rc:       rc=0: OK, rc=1: InternalERROR, rc=2: ERROR
261ad6
+#
261ad6
+function lpa_set_lpt() {
261ad6
+    super_ocf_log info "FLOW $FUNCNAME ($*)"
261ad6
+    local rc=1
261ad6
+    local crm_rc=1
261ad6
+    local lpt=$1
261ad6
+    local clpt=-1
261ad6
+    local node=${2:-${NODENAME}}
261ad6
+    set_hana_attribute ${node} "$lpt" ${LPA_ATTR[@]}; crm_rc=$?
261ad6
+    clpt=$(lpa_get_lpt $NODENAME)
261ad6
+    if [ "$lpt" != "$clpt" ]; then
261ad6
+        rc=2
261ad6
+    else
261ad6
+        rc=0
261ad6
+    fi
261ad6
+    super_ocf_log info "FLOW $FUNCNAME rc=$rc"
261ad6
+    return $rc    
261ad6
+}
261ad6
+
261ad6
+#
261ad6
+# function: lpa_pull_lpt - fetch lpt from file
261ad6
+# params:   -
261ad6
+# globals:  LPA_DIRECTORY(r), sid, NODENAME
261ad6
+# output:   LPT
261ad6
+# rc:       rc=0: OK, rc=1: InternalERROR, rc=2: ERROR
261ad6
+#
261ad6
+function lpa_pull_lpt() {
261ad6
+    super_ocf_log info "FLOW $FUNCNAME ($*)"
261ad6
+    local rc=1
261ad6
+    local lpt=""
261ad6
+    local readrest=0
261ad6
+    local lpa_file=$LPA_DIRECTORY/lpa_${sid}_${NODENAME}
261ad6
+    if [ -f $lpa_file ]; then
261ad6
+        read lpt readrest <<<$(cat $lpa_file) # exactly load first word from file to lpt
261ad6
+    fi
261ad6
+    if [ -n "$lpt" ]; then
261ad6
+        rc=0
261ad6
+        echo $lpt
261ad6
+    else
261ad6
+        rc=2
261ad6
+    fi
261ad6
+    super_ocf_log info "FLOW $FUNCNAME rc=$rc"
261ad6
+    return $rc    
261ad6
+}
261ad6
+
261ad6
+#
261ad6
+# function: lpa_push_lpt - put lpt to file
261ad6
+# params:   LPT
261ad6
+# globals:  LPA_DIRECTORY(r), sid, NODENAME
261ad6
+# output:   --
261ad6
+# rc:       rc=0: OK, rc=1: InternalERROR, rc=2: ERROR
261ad6
+#
261ad6
+function lpa_push_lpt() {
261ad6
+    super_ocf_log info "FLOW $FUNCNAME ($*)"
261ad6
+    local lpt=$1
261ad6
+    local clpt=-1
261ad6
+    local rc=1
261ad6
+    local lpa_file=$LPA_DIRECTORY/lpa_${sid}_${NODENAME}
261ad6
+    #
261ad6
+    mkdir -p $LPA_DIRECTORY
261ad6
+    echo "$lpt" > $lpa_file
261ad6
+    clpt=$(lpa_pull_lpt); lpt_rc=$?
261ad6
+    if [ "$clpt" != "$lpt" -o "$lpt_rc" -ne 0 ]; then
261ad6
+        rc=2
261ad6
+    else
261ad6
+        rc=0
261ad6
+    fi     
261ad6
+    super_ocf_log info "FLOW $FUNCNAME rc=$rc"
261ad6
+    return $rc    
261ad6
+}
261ad6
+
261ad6
+#
261ad6
+# function: lpa_init_lpt - initialize local lpt, if needed
261ad6
+# params:   HANA_STATE
261ad6
+# globals:  HANA_STATE_*(r), LPA_DIRECTORY(r), sid(r), NODENAME(r), 
261ad6
+# lpa_init_lpt
261ad6
+#
261ad6
+# Returncodes:
261ad6
+#    rc=0: OK,  rc=1 InternalERROR,  rc=2: ERROR
261ad6
+#
261ad6
+# Initializing (if NO local LPT-file):
261ad6
+#    SECONDARY sets to 0
261ad6
+#    PRIMARY   sets to 1
261ad6
+# 
261ad6
+function lpa_init_lpt() {
261ad6
+    super_ocf_log info "FLOW $FUNCNAME ($*)"
261ad6
+    local rc=1
261ad6
+    local LPTloc=-1
261ad6
+    local LPTrem=-1
261ad6
+    local hana_state=$1
261ad6
+    local lpa_file=$LPA_DIRECTORY/lpa_${sid}_${NODENAME}
261ad6
+    mkdir -p $LPA_DIRECTORY
261ad6
+    LPTloc=$(lpa_get_lpt ${NODENAME}) || LPTloc=$(lpa_pull_lpt) || \
261ad6
+        if   [ "$hana_state" -eq "$HANA_STATE_PRIMARY" ];  then    # Initialize for Primary
261ad6
+            # init primary
261ad6
+            LPTloc=20
261ad6
+            lpa_push_lpt "20"; rc=$?
261ad6
+        elif [ "$hana_state" -eq "$HANA_STATE_SECONDARY" ]; then   # Initialize for Secondary
261ad6
+            # init secondary
261ad6
+            LPTloc=10
261ad6
+            lpa_push_lpt "10"; rc=$?
261ad6
+        else
261ad6
+            rc=2                                   
261ad6
+        fi
261ad6
+    lpa_set_lpt $LPTloc
261ad6
+    super_ocf_log info "FLOW $FUNCNAME rc=$rc"
261ad6
+    return $rc    
261ad6
+}
261ad6
+
261ad6
+#
261ad6
+# function: lpa_check_lpt_status - start a hana clone instance
261ad6
+# params:   -
261ad6
+# globals:  DUPLICATE_PRIMARY_TIMEOUT, NODENAME, remoteNode
261ad6
+# lpa_check_lpt_status
261ad6
+#
261ad6
+# Returncodes:
261ad6
+#
261ad6
+# Initializing (if NO local LPT-file):
261ad6
+#    SECONDARY sets to 10
261ad6
+#    PRIMARY   sets to 20
261ad6
+#
261ad6
+#    LPRlocal OR LPTremore ARE real lpt (>1000)
261ad6
+#        THEN:
261ad6
+#            Bigger LPR wins, if delta-gab is OK
261ad6
+#               LPTlocal >> LPTremore ===> rc=0 (start) 
261ad6
+#               LPTRemote >> LPTlocal ===> rc=1 (register)
261ad6
+#            Stalemate in all other cases ==> STALEMATE-HANDLING ===> rc=2 (wait)
261ad6
+#    LPRlocal AND LPTremore ARE NOT real lpt (<=1000)
261ad6
+#        THEN:
261ad6
+#            Bigger LPT wins
261ad6
+#               LPTlocal > LPTremore ===> rc=0 (start) 
261ad6
+#               LPTRemote > LPTlocal ===> rc=1 (register)
261ad6
+#            Stalemate in all other cases ==> STALEMATE-HANDLING ===> rc=2 (wait)
261ad6
+#    LPTRemote is not initialized (0)
261ad6
+#        THEN:
261ad6
+#            WAIT ==> like STALEMATE-HANDLING ===> rc=2 (wait)
261ad6
+#    
261ad6
+function lpa_check_lpt_status() {
261ad6
+    super_ocf_log info "FLOW $FUNCNAME ($*)"
261ad6
+    local rc=0
261ad6
+    local LPTloc=-1
261ad6
+    local LPTrem=-1
261ad6
+    local LPTMark=1000
261ad6
+    local delta=0
261ad6
+    #
261ad6
+    # First GET LPT from ATTR-FILE-DEFAULT
261ad6
+    #
261ad6
+    LPTloc=$(lpa_get_lpt $NODENAME); lparc=$?   # ATTR
261ad6
+    if [ "$lparc" -ne 0 ]; then
261ad6
+        # as a fallback try to fetch the value from external status file
261ad6
+        LPTloc=$(lpa_pull_lpt);                 # FILE
261ad6
+        lparc=$?
261ad6
+        if [ -z "$LPTloc" -o "$LPTloc" -eq -1 -o "$lparc" -ne 0 ]; then
261ad6
+            # last option - try to initialize as PRIMARY
261ad6
+            lpa_push_lpt 20
261ad6
+            lpa_set_lpt  20
261ad6
+            LPTloc=20                           # DEFAULT
261ad6
+        fi
261ad6
+    fi
261ad6
+            # TODO PRIO1: REMOVE remoteNode dependency - lpa_get_lpt
261ad6
+    LPTrem=$(lpa_get_lpt $remoteNode); lparc=$?
261ad6
+    if [ $lparc -ne 0 ]; then
261ad6
+        # LPT of the other node could not be evaluated - LPA says WAIT
261ad6
+        super_ocf_log debug "DBG: LPA: LPTloc=$LPTloc, LPTrem undefined ==> WAIT"
261ad6
+        rc=2
261ad6
+    else
261ad6
+        super_ocf_log debug "DBG: LPA: LPTloc ($LPTloc) LPTrem ($LPTrem) delta ($delta)"
261ad6
+        if [ $LPTloc -lt $LPTMark -a $LPTrem -lt $LPTMark ]; then
261ad6
+           delta=0   # both lpts are not a real timestamp so just take the greater one
261ad6
+        else
261ad6
+           delta=$DUPLICATE_PRIMARY_TIMEOUT   # at least one of the lpts is a real timestamp so include delta-gap
261ad6
+        fi
261ad6
+        if (( delta < LPTloc - LPTrem )); then 
261ad6
+            # We are the winner - LPA says STARTUP
261ad6
+            super_ocf_log debug "DBG: LPA: LPTloc wins $LPTloc > $LPTrem + $delta ==> START"
261ad6
+            rc=0
261ad6
+        elif (( delta < LPTrem - LPTloc )); then 
261ad6
+            if ocf_is_true "$AUTOMATED_REGISTER" ; then
261ad6
+                # The other one has won - LPA says REGISTER
261ad6
+                super_ocf_log debug "DBG: LPA: LPTrem wins $LPTrem > $LPTloc + $delta ==> REGISTER"
261ad6
+                rc=1
261ad6
+            else
261ad6
+                super_ocf_log debug "DBG: LPA: LPTrem wins $LPTrem > $LPTloc + $delta BUT AUTOMATED_REGISTER='false' ==> WAIT"
261ad6
+                rc=2
261ad6
+            fi
261ad6
+
261ad6
+        else                                     
261ad6
+            super_ocf_log debug "DBG: LPA: Difference between LPTloc and LPTrem is less than delta ($delta) ==> WAIT"
261ad6
+            # TODO: PRIO3: ADD STALEMATE-HANDLING HERE; currently admin should set one of the lpa to 20
261ad6
+            rc=2
261ad6
+        fi        
261ad6
+    fi    
261ad6
+    super_ocf_log info "FLOW $FUNCNAME rc=$rc"
261ad6
+    return $rc    
261ad6
+}
261ad6
+
261ad6
+#
261ad6
+# function: saphana_start_clone - start a hana clone instance
261ad6
+# params:   -
261ad6
+# globals:  OCF_*, ATTR_NAME_*, HANA_STATE_*, NODENAME
261ad6
+# saphana_start_clone
261ad6
+#
261ad6
+function saphana_start_clone() {
261ad6
+    super_ocf_log info "FLOW $FUNCNAME ($*)"
261ad6
+	local primary_status sync_attr score_master rc=$OCF_NOT_RUNNING
261ad6
+    local sqlrc;
261ad6
+    local chkusr;
261ad6
+    # TODO: PRIO4: remove check_secstore_users later
261ad6
+    secUser=$(check_secstore_users SAPHANA${SID}SR SLEHALOC RHELHALOC) ; chkusr=$?
261ad6
+    if [ $chkusr -ne 0 ]; then
261ad6
+        super_ocf_log err  "ACT: Secure store users are missing (see best practice manual how to setup the users)"
261ad6
+        rc=$OCF_ERR_CONFIGURED
261ad6
+    else
261ad6
+        set_hana_attribute ${NODENAME} "DEMOTED" ${ATTR_NAME_HANA_CLONE_STATE[@]}
261ad6
+        check_for_primary; primary_status=$?
261ad6
+        if [ $primary_status -eq $HANA_STATE_PRIMARY ]; then
261ad6
+            saphana_start_primary; rc=$?
261ad6
+        else 
261ad6
+            saphana_start_secondary; rc=$?
261ad6
+            lpa_set_lpt  30
261ad6
+        fi 
261ad6
+    fi
261ad6
+    return $rc
261ad6
+}
261ad6
+
261ad6
+#
261ad6
+# function: saphana_stop_clone - stop a hana clone instance
261ad6
+# params:   -
261ad6
+# globals:  NODENAME(r), HANA_STATE_*(r)
261ad6
+# saphana_stop_clone
261ad6
+#
261ad6
+function saphana_stop_clone() {
261ad6
+    super_ocf_log info "FLOW $FUNCNAME ($*)"
261ad6
+    local rc=0
261ad6
+    local primary_status="x"
261ad6
+    set_hana_attribute ${NODENAME} "UNDEFINED" ${ATTR_NAME_HANA_CLONE_STATE[@]}
261ad6
+    check_for_primary; primary_status=$?
261ad6
+    if [ $primary_status -eq $HANA_STATE_SECONDARY ]; then
261ad6
+        lpa_set_lpt  10
261ad6
+    fi 
261ad6
+    saphana_stop; rc=$?
261ad6
+    return $rc
261ad6
+}
261ad6
+
261ad6
+#
261ad6
+# function: saphana_monitor_primary - monitor a hana clone instance
261ad6
+# params:   -
261ad6
+# globals:  HANA_STATE_*(r), remoteHost, NODENAME, ATTR_NAME_*, OCF_*, PreferSiteTakeover
261ad6
+#
261ad6
+function saphana_monitor_primary()
261ad6
+{
261ad6
+    super_ocf_log info "FLOW $FUNCNAME ($*)"
261ad6
+    local rc=$OCF_ERR_GENERIC
261ad6
+    local promoted=0
261ad6
+    local init_attribute=0
261ad6
+    local LPTloc=-1
261ad6
+    local lparc=4
261ad6
+    local lss
261ad6
+    local remoreSync=""
261ad6
+    local my_role=""
261ad6
+    #
261ad6
+    # OK, we are running/are configured as HANA PRIMARY
261ad6
+    #
261ad6
+    super_ocf_log debug "DBG: saphana_monitor_clone: HANA_STATE_PRIMARY"
261ad6
+    #
261ad6
+    ##### CHECK, IF WE ARE DEMOTED (CLUSTER NODE ATTRIBUTE)
261ad6
+    #
261ad6
+    promote_attr=$(get_hana_attribute ${NODENAME} ${ATTR_NAME_HANA_CLONE_STATE[@]})
261ad6
+    super_ocf_log debug "DBG: saphana_monitor_clone: $ATTR_NAME_HANA_CLONE_STATE=$promote_attr"
261ad6
+    if [ -z "$promote_attr" ]; then
261ad6
+        init_attribute=1
261ad6
+        promoted=0;
261ad6
+    else
261ad6
+        case "$promote_attr" in
261ad6
+            PROMOTED )
261ad6
+                promoted=1;
261ad6
+                ;;
261ad6
+            DEMOTED )
261ad6
+                promoted=0;
261ad6
+                ;;
261ad6
+            WAITING )  
261ad6
+                # DONE: lpa_check_lpt_status to come out of here :)
261ad6
+                # DONE: PRIO2: CHECK IF THE FIX FOR COMING OUT OF WAITING IS CORRECT
261ad6
+                get_hana_landscape_status; lss=$?
261ad6
+                if [ $lss -ge 2 ]; then
261ad6
+                    # seems admin already decided that for us? -> we are running - set DEMOTED
261ad6
+                    promoted=0;
261ad6
+                    LPTloc=$(date '+%s')
261ad6
+                    lpa_set_lpt $LPTloc
261ad6
+                fi
261ad6
+                lpa_check_lpt_status; lparc=$?
261ad6
+                if [ $lparc -ne 2 ]; then
261ad6
+                    # lpa - no need to wait any longer - lets try a new start
261ad6
+                    saphana_start_clone
261ad6
+                    rc=$?
261ad6
+                    super_ocf_log info "FLOW $FUNCNAME rc=$rc"
261ad6
+                    return $rc
261ad6
+                else
261ad6
+                    lpa_init_lpt $HANA_STATE_PRIMARY
261ad6
+                    # still waiting for second site to report lpa-lpt
261ad6
+                    if ocf_is_true "$AUTOMATED_REGISTER" ; then
261ad6
+                       super_ocf_log info "LPA: Still waiting for remote site to report LPA status"
261ad6
+                    else
261ad6
+                       super_ocf_log info "LPA: Dual primary detected and AUTOMATED_REGISTER='false' ==> WAITING"
261ad6
+                    fi
261ad6
+
261ad6
+                    return $OCF_SUCCESS
261ad6
+                fi                             
261ad6
+                promoted=0;
261ad6
+                ;;
261ad6
+            UNDEFINED )
261ad6
+                if ocf_is_probe; then
261ad6
+                   promoted=0;
261ad6
+                else
261ad6
+                   set_hana_attribute ${NODENAME} "DEMOTED" ${ATTR_NAME_HANA_CLONE_STATE[@]}
261ad6
+                   promoted=0;
261ad6
+                fi
261ad6
+                ;;
261ad6
+            * )
261ad6
+                promoted=0;
261ad6
+                ;;
261ad6
+        esac
261ad6
+    fi
261ad6
+    get_hana_landscape_status; lss=$? 
261ad6
+    super_ocf_log debug "DBG: saphana_monitor_clone: get_hana_landscape_status=$lss"
261ad6
+    case "$lss" in
261ad6
+        0 ) # FATAL or ERROR 
261ad6
+            rc=$OCF_ERR_GENERIC
261ad6
+            ;;
261ad6
+        1 ) # DOWN or ERROR 
261ad6
+            # DONE: PRIO2: Maybe we need to differ between 0 and 1. While 0 is a fatal sap error, 1 is down/error
261ad6
+            if ocf_is_probe; then
261ad6
+                # 
261ad6
+                # leave master score untouched, only set return code
261ad6
+                #
261ad6
+                rc=$OCF_NOT_RUNNING
261ad6
+            else
261ad6
+                if [ "$promoted" -eq 1 ]; then
261ad6
+                    # INSTANCE IS FAILED PRIMARY IN PROMOTED STATE
261ad6
+                    # DONE: PRIO2: Adjust with set_crm_master?
261ad6
+                    #       For Migration it would be good to decrease master score
261ad6
+                    #       For Reload locally we should NOT adjust the master score
261ad6
+                    # ===>  Should we rely on the migration threshold?
261ad6
+                    #       set_crm_master 
261ad6
+                    if ocf_is_true "${PreferSiteTakeover}" ; then
261ad6
+                        #
261ad6
+                        # DONE: PRIO1: first check, if remote site is already (and still) in sync
261ad6
+                        # TODO: PRIO4: Decide if penality (-9000) or weak (5) is better here to cover situations where other clone is gone
261ad6
+                        #
261ad6
+            # TODO PRIO1: REMOVE remoteNode dependency - get_sync_status
261ad6
+                        remoteSync=$(get_hana_attribute $remoteNode ${ATTR_NAME_HANA_SYNC_STATUS[@]})
261ad6
+                        case "$remoteSync" in
261ad6
+                            SOK )
261ad6
+                                 super_ocf_log info "DEC: PreferSiteTakeover selected so decrease promotion score here (and reset lpa)"
261ad6
+                                 set_crm_master 5
261ad6
+                                 if check_for_primary_master; then
261ad6
+                                     lpa_set_lpt 20
261ad6
+                                 fi
261ad6
+                                 ;;
261ad6
+                            SFAIL )
261ad6
+                                 super_ocf_log info "DEC: PreferSiteTakeover selected BUT remoteHost is not in sync (SFAIL) ==> local restart preferred"                            
261ad6
+                                 ;;
261ad6
+                            * ) 
261ad6
+                                 super_ocf_log info "DEC: PreferSiteTakeover selected BUT remoteHost is not in sync ($remoteSync) ==> local restart preferred"                            
261ad6
+                                 ;;
261ad6
+                        esac                        
261ad6
+                    else 
261ad6
+                        # TODO:  PRIO5: SCALE-OUT ONLY? Implement for local restart
261ad6
+                        #        It maybe that for the local restart we only need to decrease the secondaries promotion score
261ad6
+                        #super_ocf_log info "DEC: PreferSiteTakeover selected so decrease promotion score here"
261ad6
+                        my_role=$(get_hana_attribute ${NODENAME} ${ATTR_NAME_HANA_ROLES[@]})
261ad6
+                        my_sync=$(get_hana_attribute ${NODENAME} ${ATTR_NAME_HANA_SYNC_STATUS[@]})
261ad6
+                        scoring_crm_master "$my_role" "$my_sync"
261ad6
+                        rc=$OCF_FAILED_MASTER
261ad6
+                    fi
261ad6
+                    rc=$OCF_FAILED_MASTER
261ad6
+                else
261ad6
+                    # INSTANCE IS FAILED PRIMARY IN DEMOTED STATE
261ad6
+                    # TODO: PRIO3: Adjust with set_crm_master?
261ad6
+                    #       Current decission: Do NOT adjust master score now as other
261ad6
+                    #       steps should already have done that
261ad6
+                    #
261ad6
+                    rc=$OCF_NOT_RUNNING
261ad6
+                fi
261ad6
+            fi
261ad6
+            ;;
261ad6
+        2 | 3 | 4 ) # WARN, INFO or OK
261ad6
+            if ocf_is_probe; then
261ad6
+                rc=$OCF_SUCCESS
261ad6
+            else
261ad6
+                LPTloc=$(date '+%s')
261ad6
+                lpa_set_lpt $LPTloc
261ad6
+                lpa_push_lpt $LPTloc
261ad6
+                if [ "$promoted" -eq 1 ]; then
261ad6
+                    set_hana_attribute "$NODENAME" "PRIM" ${ATTR_NAME_HANA_SYNC_STATUS[@]}
261ad6
+                    rc=$OCF_RUNNING_MASTER
261ad6
+                else
261ad6
+                    if [ "$init_attribute" -eq 1 ]; then
261ad6
+                        set_hana_attribute ${NODENAME} "DEMOTED" ${ATTR_NAME_HANA_CLONE_STATE[@]}
261ad6
+                        rc=$OCF_RUNNING_MASTER
261ad6
+                    else
261ad6
+                        rc=$OCF_SUCCESS
261ad6
+                    fi
261ad6
+                fi
261ad6
+                my_sync=$(get_hana_attribute ${NODENAME} ${ATTR_NAME_HANA_SYNC_STATUS[@]})
261ad6
+                my_role=$(get_hana_attribute ${NODENAME} ${ATTR_NAME_HANA_ROLES[@]})
261ad6
+                case "$my_role" in 
261ad6
+                    [12]:P:*:master:*  ) # primary is down or may not anser hdbsql query so drop analyze_hana_sync_status
261ad6
+                        ;;
261ad6
+                    [34]:P:*:master:*  ) # primary is up and should now be able to anser hdbsql query
261ad6
+                        analyze_hana_sync_status
261ad6
+                        ;;
261ad6
+                esac
261ad6
+                rem_role=$(get_hana_attribute ${remoteHost} ${ATTR_NAME_HANA_ROLES[@]})
261ad6
+                rem_clone_status=$(get_hana_attribute ${remoteHost} ${ATTR_NAME_HANA_CLONE_STATE[@]})
261ad6
+                if [ "$promote_attr" = "DEMOTED" -a "$rem_clone_status" = "PROMOTED" ]; then
261ad6
+                   case "$rem_role" in
261ad6
+                       [234]:P:* ) # dual primary, but other instance marked as PROMOTED by the cluster
261ad6
+                           lpa_check_lpt_status; again_lpa_rc=$?
261ad6
+                           if [ $again_lpa_rc -eq 2 ]; then
261ad6
+                               super_ocf_log info "DEC: Dual primary detected, other instance is PROMOTED and lpa stalemate ==> local restart"                            
261ad6
+                               lpa_set_lpt 10
261ad6
+                               lpa_push_lpt 10
261ad6
+                              rc=$OCF_NOT_RUNNING
261ad6
+                           fi
261ad6
+                          ;;
261ad6
+                   esac
261ad6
+                fi
261ad6
+                scoring_crm_master "$my_role" "$my_sync"
261ad6
+            fi
261ad6
+            ;;
261ad6
+        * ) # UNDEFINED STATUS
261ad6
+            if ocf_is_probe; then
261ad6
+                rc=$OCF_NOT_RUNNING
261ad6
+            else
261ad6
+                if [ "$promoted" -eq 1 ]; then
261ad6
+                     rc=$OCF_FAILED_MASTER
261ad6
+                else
261ad6
+                     rc=$OCF_NOT_RUNNING
261ad6
+                fi
261ad6
+            fi
261ad6
+            ;;
261ad6
+    esac
261ad6
+    super_ocf_log info "FLOW $FUNCNAME rc=$rc"
261ad6
+    return $rc
261ad6
+}
261ad6
+
261ad6
+#
261ad6
+# function: saphana_monitor_secondary - monitor a hana clone instance
261ad6
+# params:   -
261ad6
+# globals:  OCF_*, ATTR_NAME_*, NODENAME
261ad6
+# saphana_monitor_secondary
261ad6
+#
261ad6
+function saphana_monitor_secondary()
261ad6
+{
261ad6
+    super_ocf_log info "FLOW $FUNCNAME ($*)"
261ad6
+	local rc=$OCF_ERR_GENERIC
261ad6
+	local promoted=0
261ad6
+    local init_attribute=0
261ad6
+    local lss
261ad6
+    #
261ad6
+    # OK, we are running as HANA SECONDARY
261ad6
+    #    
261ad6
+    if ! lpa_get_lpt ${NODENAME}; then
261ad6
+        lpa_set_lpt  10
261ad6
+        lpa_push_lpt 10
261ad6
+    fi
261ad6
+    promote_attr=$(get_hana_attribute ${NODENAME} ${ATTR_NAME_HANA_CLONE_STATE[@]})
261ad6
+    super_ocf_log debug "DBG: saphana_monitor_clone: $ATTR_NAME_HANA_CLONE_STATE=$promote_attr"
261ad6
+    if [ -z "$promote_attr" ]; then
261ad6
+        init_attribute=1
261ad6
+        #  DONE: PRIO3: do we need to inizialize also the DEMOTED attribute value?
261ad6
+        set_hana_attribute ${NODENAME} "DEMOTED" ${ATTR_NAME_HANA_CLONE_STATE[@]}
261ad6
+        promoted=0;
261ad6
+    else
261ad6
+        case "$promote_attr" in
261ad6
+            PROMOTED ) # However - PROMOTED should never happen for a SECONDARY
261ad6
+                promoted=1;
261ad6
+                ;;
261ad6
+            DEMOTED )  # This is the status we expect
261ad6
+                promoted=0;
261ad6
+                ;;
261ad6
+            WAITING* )  # We are WAITING for PRIMARY so not testing the HANA engine now but check for a new start
261ad6
+                if check_for_primary_master; then
261ad6
+                    super_ocf_log info "ACT: SECONDARY still in status WAITING - Primary now available - try a new start"
261ad6
+                    saphana_start_clone
261ad6
+                    rc=$?
261ad6
+                else
261ad6
+                    super_ocf_log info "ACT: saphana_monitor_clone: SECONDARY still in status WAITING - Primary is still missing"
261ad6
+                    return $OCF_SUCCESS
261ad6
+                fi
261ad6
+                promoted=0;
261ad6
+                ;;
261ad6
+            UNDEFINED | * )
261ad6
+                if ocf_is_probe; then
261ad6
+                   promoted=0;
261ad6
+                else
261ad6
+                   set_hana_attribute ${NODENAME} "DEMOTED" ${ATTR_NAME_HANA_CLONE_STATE[@]}
261ad6
+                   promoted=0;
261ad6
+                fi
261ad6
+                ;;
261ad6
+        esac
261ad6
+    fi
261ad6
+    #
261ad6
+    super_ocf_log debug "DBG: saphana_monitor_clone: HANA_STATE_SECONDARY"
261ad6
+    #
261ad6
+    # old method was: saphana_monitor - new method is get_hana_landscape_status
261ad6
+    get_hana_landscape_status; lss=$? 
261ad6
+    super_ocf_log debug "DBG: saphana_monitor_clone: get_hana_landscape_status=$lss"
261ad6
+    case "$lss" in
261ad6
+        0 ) # FATAL
261ad6
+            # DONE: PRIO1: Maybe we need to differ between 0 and 1. While 0 is a fatal sap error, 1 is down/error
261ad6
+            # TODO: PRIO3: is OCF_ERR_GENERIC best option?
261ad6
+            lpa_set_lpt  10
261ad6
+            rc=$OCF_ERR_GENERIC
261ad6
+            ;;
261ad6
+        1 ) # ERROR
261ad6
+            lpa_set_lpt  10
261ad6
+            rc=$OCF_NOT_RUNNING
261ad6
+            ;;
261ad6
+        2 | 3 | 4 ) # WARN INFO OK
261ad6
+            rc=$OCF_SUCCESS
261ad6
+            lpa_set_lpt  30
261ad6
+            sync_attr=$(get_hana_attribute ${NODENAME} ${ATTR_NAME_HANA_SYNC_STATUS[@]})
261ad6
+            super_ocf_log debug "DBG: sync_attr=$sync_attr"
261ad6
+            case "$sync_attr" in
261ad6
+                "SOK"   ) # This is a possible node to promote, when primary is missing
261ad6
+                    super_ocf_log info "DEC: secondary with sync status SOK ==> possible takeover node"
261ad6
+                    my_role=$(get_hana_attribute ${NODENAME} ${ATTR_NAME_HANA_ROLES[@]})
261ad6
+                    my_sync=$(get_hana_attribute ${NODENAME} ${ATTR_NAME_HANA_SYNC_STATUS[@]})
261ad6
+                    scoring_crm_master "$my_role" "$my_sync"
261ad6
+                    ;;
261ad6
+                "SFAIL" ) # This is currently NOT a possible node to promote
261ad6
+                    super_ocf_log info "DEC: secondary with sync status FAILED ==> EXCLUDE as posible takeover node"
261ad6
+                    set_crm_master -INFINITY
261ad6
+                    ;;
261ad6
+                "*" )     # Unknown sync status
261ad6
+                    super_ocf_log info "DEC: secondary with sync status UKNOWN/UNDEFINED ==> EXCLUDE as posible takeover node"
261ad6
+                    set_crm_master -INFINITY
261ad6
+                    ;;
261ad6
+            esac
261ad6
+            ;;
261ad6
+        * ) # UNDEFINED STATUS
261ad6
+            rc=$OCF_NOT_RUNNING
261ad6
+            ;;
261ad6
+    esac
261ad6
+    super_ocf_log info "FLOW $FUNCNAME rc=$rc"
261ad6
+    return $rc
261ad6
+}
261ad6
+
261ad6
+#
261ad6
+# function: saphana_monitor_clone - monitor a hana clone instance
261ad6
+# params:   -
261ad6
+# globals:  OCF_*, ATTR_NAME_*, HOSTNANE, HANA_STATE_*
261ad6
+# saphana_monitor_clone
261ad6
+#
261ad6
+function saphana_monitor_clone() {
261ad6
+    super_ocf_log info "FLOW $FUNCNAME ($*)"
261ad6
+    #
261ad6
+    # TODO: PRIO3: For the secondary, which is missing the primary (so in status WAITING) what is better:
261ad6
+    #       a) returning 7 here and force cluster a restart of the slave
261ad6
+    #       b) starting the instance here inside the monitor -> may result in longer runtime, timeouts
261ad6
+    #
261ad6
+	# first check with the status function (OS tools) if there could be something like a SAP instance running
261ad6
+	# as we do not know here, if we are in master or slave state we do not want to start our monitoring
261ad6
+	# agents (sapstartsrv) on the wrong host
261ad6
+	local rc=$OCF_ERR_GENERIC
261ad6
+	local promoted=0
261ad6
+    local init_attribute=0
261ad6
+
261ad6
+    my_role=$(get_hana_attribute ${NODENAME} ${ATTR_NAME_HANA_ROLES[@]})
261ad6
+    my_sync=$(get_hana_attribute ${NODENAME} ${ATTR_NAME_HANA_SYNC_STATUS[@]})
261ad6
+    lpa_check_lpt_status  # TODO: PRIO3 : remove that line later - its only to call lpa_check_lpt_status much more often for checking
261ad6
+
261ad6
+	if ocf_is_probe; then
261ad6
+		super_ocf_log debug "DBG: PROBE ONLY"
261ad6
+	else
261ad6
+		super_ocf_log debug "DBG: REGULAR MONITOR"
261ad6
+	fi
261ad6
+	#
261ad6
+	# First check, if we are PRIMARY or SECONDARY
261ad6
+	# 
261ad6
+	check_for_primary; primary_status=$?
261ad6
+    if [ $primary_status -eq $HANA_STATE_PRIMARY ]; then
261ad6
+        saphana_monitor_primary; rc=$?
261ad6
+    else
261ad6
+        if [ $primary_status -eq $HANA_STATE_SECONDARY  ]; then
261ad6
+            saphana_monitor_secondary; rc=$?
261ad6
+        else
261ad6
+            #
261ad6
+            # OK, we are neither HANA PRIMARY nor HANA SECONDARY
261ad6
+            #
261ad6
+            super_ocf_log warn "ACT: saphana_monitor_clone: HANA_STATE_DEFECT"
261ad6
+            # TODO: PRIO2: Or only set_crm_master -INFINITY ?
261ad6
+            rc=$OCF_ERR_GENERIC
261ad6
+        fi
261ad6
+    fi
261ad6
+    super_ocf_log info "FLOW $FUNCNAME rc=$rc"
261ad6
+    return $rc
261ad6
+}
261ad6
+
261ad6
+#
261ad6
+# function: saphana_promote_clone - promote a hana clone
261ad6
+# params:   -
261ad6
+# globals:  OCF_*(r), NODENAME(r), HANA_STATE_*, SID(r), InstanceName(r), 
261ad6
+# saphana_promote_clone: 
261ad6
+#    In a Master/Slave configuration get Master being the primary OR by running hana takeover
261ad6
+#
261ad6
+function saphana_promote_clone() {
261ad6
+  super_ocf_log info "FLOW $FUNCNAME ($*)"
261ad6
+  local rc=$OCF_ERR_GENERIC;
261ad6
+  local hana_sync;
261ad6
+  local primary_status;
261ad6
+  #
261ad6
+  # first check, if we WILL be PRIMARY (checking HANA status)
261ad6
+  #
261ad6
+  set_hana_attribute ${NODENAME} "PROMOTED" ${ATTR_NAME_HANA_CLONE_STATE[@]}
261ad6
+  check_for_primary; primary_status=$?
261ad6
+  #
261ad6
+  if [ $primary_status -eq $HANA_STATE_PRIMARY ]; then
261ad6
+     #
261ad6
+     # as we are already planned to be PRIMARY we only mark the node as PROMOTED
261ad6
+     #
261ad6
+     super_ocf_log info "ACT: Promoted $SID-$InstanceName as master (no hdbnsutil action needed)."
261ad6
+     rc=$OCF_SUCCESS;
261ad6
+  else
261ad6
+     if [ $primary_status -eq $HANA_STATE_SECONDARY ]; then
261ad6
+        #
261ad6
+        # we are SECONDARY/SLAVE and need to takepover ...
261ad6
+        # promote on the replica side...
261ad6
+        #
261ad6
+        hana_sync=$(get_hana_attribute ${NODENAME} ${ATTR_NAME_HANA_SYNC_STATUS[@]})
261ad6
+        case "$hana_sync" in
261ad6
+             SOK )
261ad6
+                super_ocf_log info "ACT: !!!!!!! Promote REPLICA $SID-$InstanceName to be primary. !!!!!!"
261ad6
+                LPTloc=$(date '+%s')
261ad6
+                # lpa_set_lpt 20 $remoteNode
261ad6
+                lpa_set_lpt $LPTloc
261ad6
+                lpa_push_lpt $LPTloc
261ad6
+                su - $sidadm -c "hdbnsutil -sr_takeover"
261ad6
+                #
261ad6
+                # now gain check, if we are primary NOW
261ad6
+                #
261ad6
+                # TODO: PRIO3: check, if we need to destinguish between HANA_STATE_PRIMARY, HANA_STATE_SECONDARY, HANA_STATE_DEFECT
261ad6
+                #
261ad6
+                if check_for_primary; then
261ad6
+                    rc=$OCF_SUCCESS;
261ad6
+                else
261ad6
+                    rc=$OCF_FAILED_MASTER
261ad6
+                fi 
261ad6
+                ;;
261ad6
+             * )
261ad6
+                super_ocf_log err "ACT: HANA SYNC STATUS IS NOT 'SOK' SO THIS HANA SITE COULD NOT BE PROMOTED"
261ad6
+                rc=$OCF_ERR_GENERIC
261ad6
+                ;;
261ad6
+        esac
261ad6
+     else
261ad6
+        #
261ad6
+        # neither MASTER nor SLAVE - This clone instance seams to be broken!!
261ad6
+        #
261ad6
+        rc=$OCF_ERR_GENERIC
261ad6
+     fi
261ad6
+  fi
261ad6
+  rc=$?
261ad6
+  super_ocf_log info "FLOW $FUNCNAME rc=$rc"
261ad6
+  return $rc
261ad6
+}
261ad6
+
261ad6
+#
261ad6
+# function: saphana_demote_clone - demote a hana clone instance
261ad6
+# params:   -
261ad6
+# globals:  OCF_*(r), NODENAME(r), 
261ad6
+# saphana_demote_clone
261ad6
+#   the HANA System Replication (SR) runs in a Master/Slave 
261ad6
+#   While we could not change a HANA instance to be really demoted, we only mark the status for 
261ad6
+#   correct monitor return codes
261ad6
+#
261ad6
+function saphana_demote_clone() {
261ad6
+    super_ocf_log info "FLOW $FUNCNAME ($*)"
261ad6
+    local rc=$OCF_ERR_GENERIC;
261ad6
+    set_hana_attribute ${NODENAME} "DEMOTED" ${ATTR_NAME_HANA_CLONE_STATE[@]}
261ad6
+    rc=$OCF_SUCCESS;
261ad6
+    super_ocf_log info "ACT: Demoted $SID-$InstanceName."
261ad6
+    super_ocf_log info "FLOW $FUNCNAME rc=$rc"
261ad6
+    return $rc
261ad6
+}
261ad6
+
261ad6
+#
261ad6
+# function: main - main function to operate 
261ad6
+# params:   ACTION
261ad6
+# globals:  OCF_*(r), SID(w), sidadm(w), InstanceName(w), SAPVIRHOST(w), DIR_EXECUTABLE(w), 
261ad6
+# globals:  SAPSTARTSRV(w), SAPCONTROL(w), DIR_PROFILE(w), SAPSTARTPROFILE(w), ACTION(w), CLACT(w), ra_rc(rw), $0(r), %ENV(r)
261ad6
+#
261ad6
+
261ad6
+## GLOBALS
261ad6
+SID=""
261ad6
+sidadm=""
261ad6
+InstanceName=""
261ad6
+InstanceNr=""
261ad6
+SAPVIRHOST=""
261ad6
+DIR_EXECUTABLE=""
261ad6
+SAPSTARTSRV=""
261ad6
+SAPCONTROL=""
261ad6
+DIR_PROFILE=""
261ad6
+SAPSTARTPROFILE=""
261ad6
+SAPHanaFilter="${OCF_RESKEY_SAPHanaFilter:-ra-act-dec-lpa}"
261ad6
+
261ad6
+NODENAME=$(crm_node -n)
261ad6
+
261ad6
+
261ad6
+if [ $# -ne 1 ]
261ad6
+then
261ad6
+  saphana_usage
261ad6
+  exit $OCF_ERR_ARGS
261ad6
+fi
261ad6
+
261ad6
+ACTION=$1
261ad6
+if [ "$ACTION" = "status" ]; then
261ad6
+    ACTION=monitor
261ad6
+fi
261ad6
+
261ad6
+# These operations don't require OCF parameters to be set
261ad6
+# TODO: PRIO5: check, if notify is still not needing OCF parameters
261ad6
+case "$ACTION" in
261ad6
+    usage|methods)  saphana_$ACTION
261ad6
+                    exit $OCF_SUCCESS;;
261ad6
+    meta-data)      saphana_meta_data
261ad6
+                    exit $OCF_SUCCESS;;
261ad6
+    notify)         #saphana_notify
261ad6
+                    exit $OCF_SUCCESS;;
261ad6
+    *);;
261ad6
+esac
261ad6
+saphana_init 
261ad6
+
261ad6
+if ! ocf_is_root
261ad6
+then
261ad6
+    super_ocf_log err "ACT: $0 must be run as root"
261ad6
+    exit $OCF_ERR_PERM
261ad6
+fi
261ad6
+
261ad6
+# parameter check
261ad6
+if  [ -z "$OCF_RESKEY_SID" ]
261ad6
+then
261ad6
+    super_ocf_log err "ACT: Please set parameter SID!"
261ad6
+    exit $OCF_ERR_ARGS
261ad6
+fi
261ad6
+
261ad6
+if  [ -z "$OCF_RESKEY_InstanceNumber" ]
261ad6
+then
261ad6
+    super_ocf_log err "ACT: Please set parameter InstanceNumber!"
261ad6
+    exit $OCF_ERR_ARGS
261ad6
+fi
261ad6
+
261ad6
+if is_clone
261ad6
+then
261ad6
+    CLACT=_clone
261ad6
+else
261ad6
+    if [ "$ACTION" = "promote" -o "$ACTION" = "demote" ]
261ad6
+    then
261ad6
+        super_ocf_log err "ACT: $ACTION called in a non master/slave environment"
261ad6
+        exit $OCF_ERR_ARGS
261ad6
+    fi
261ad6
+fi
261ad6
+
261ad6
+# What kind of method was invoked?
261ad6
+THE_VERSION=$(saphana_meta_data | grep '
261ad6
+super_ocf_log info "RA ==== begin action $ACTION$CLACT ($THE_VERSION) ===="
261ad6
+ra_rc=$OCF_ERR_UNIMPLEMENTED
261ad6
+case "$ACTION" in
261ad6
+    start|stop|monitor|promote|demote) # Standard controling actions
261ad6
+        saphana_$ACTION$CLACT
261ad6
+        ra_rc=$?
261ad6
+        ;;
261ad6
+    validate-all) 
261ad6
+        saphana_validate
261ad6
+        ra_rc=$?
261ad6
+        ;;
261ad6
+    lpa_check)
261ad6
+        lpa_check_lpt_status
261ad6
+        ra_rc=$?
261ad6
+        ;;
261ad6
+    *)  # seams to be a unknown request 
261ad6
+        saphana_methods 
261ad6
+        ra_rc=$OCF_ERR_UNIMPLEMENTED
261ad6
+        ;;
261ad6
+esac
261ad6
+timeE=$(date '+%s')
261ad6
+(( timeR = timeE - timeB ))
261ad6
+super_ocf_log info "RA ==== end action $ACTION$CLACT with rc=${ra_rc} ($THE_VERSION) (${timeR}s)===="
261ad6
+exit ${ra_rc}
261ad6
diff --git a/heartbeat/SAPHanaTopology b/heartbeat/SAPHanaTopology
261ad6
new file mode 100755
261ad6
index 0000000..19fbbb4
261ad6
--- /dev/null
261ad6
+++ b/heartbeat/SAPHanaTopology
261ad6
@@ -0,0 +1,813 @@
261ad6
+#!/bin/bash
261ad6
+#
261ad6
+# SAPHanaTopology
261ad6
+#
261ad6
+# Description:	Clone resource to anylyze SAPHana-Topology
261ad6
+#
261ad6
+###########################################################################################################################
261ad6
+#
261ad6
+# SAPHanaTopology is a fork of SAPHana
261ad6
+# Thanks to Alexander Krauth for providing SAPInstance and SAPDatabase
261ad6
+#
261ad6
+# SAPHanaTopology: (short sht)
261ad6
+# Author:       Fabian Herschel, February 2014
261ad6
+# Support:      linux@sap.com
261ad6
+# License:      GNU General Public License (GPL)
261ad6
+# Copyright:    (c) 2014 SUSE Linux Products GmbH
261ad6
+#
261ad6
+# An example usage: 
261ad6
+#      See usage() function below for more details...
261ad6
+#
261ad6
+# OCF instance parameters:
261ad6
+#   OCF_RESKEY_SID            (LNX, NDB, SLE)
261ad6
+#   OCF_RESKEY_InstanceNumber (00..99)
261ad6
+#	OCF_RESKEY_DIR_EXECUTABLE   (optional, well known directories will be searched by default)
261ad6
+#   OCF_RESKEY_SAPHanaFilter
261ad6
+#
261ad6
+#######################################################################
261ad6
+#
261ad6
+# Initialization:
261ad6
+timeB=$(date '+%s')
261ad6
+
261ad6
+: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
261ad6
+. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs
261ad6
+
261ad6
+#######################################################################
261ad6
+
261ad6
+HANA_STATE_PRIMARY=0
261ad6
+HANA_STATE_SECONDARY=1
261ad6
+HANA_STATE_STANDALONE=2
261ad6
+HANA_STATE_DEFECT=3
261ad6
+
261ad6
+SH=/bin/sh
261ad6
+
261ad6
+#
261ad6
+# function: super_ocf_log - wrapper function for ocf log in order catch usual logging into super log
261ad6
+# params:   LOG_MESSAGE
261ad6
+# globals:  SUPER_LOG_PATH, SAPHanaFilter
261ad6
+function super_ocf_log() {
261ad6
+    local level="$1"
261ad6
+    local message="$2"
261ad6
+    local skip=1
261ad6
+    local mtype=""
261ad6
+    local search=0
261ad6
+    local shf="${SAPHanaFilter:-all}"
261ad6
+    #ocf_log "info" "super_ocf_log: f:$shf l:$level m:$message"
261ad6
+    # message levels: (dbg)|info|warn|err|error
261ad6
+    # 
261ad6
+    # message types:  (ACT|RA|FLOW|DBG|LPA|DEC
261ad6
+    case "$level" in
261ad6
+        dbg | debug | warn | err | error ) skip=0
261ad6
+        ;;
261ad6
+        info )
261ad6
+        case "$shf" in
261ad6
+            all) skip=0
261ad6
+            ;;          
261ad6
+            none )
261ad6
+                skip=1
261ad6
+                ;;
261ad6
+            * ) mtype=${message%% *}
261ad6
+                mtype=${mtype%:}
261ad6
+                mtype=${mtype#fh}
261ad6
+                echo "$shf"|  grep -iq ${mtype}; search=$?
261ad6
+                if [ $search -eq 0 ]; then
261ad6
+                     skip=0  
261ad6
+                else
261ad6
+                    skip=1
261ad6
+                fi
261ad6
+            ;;
261ad6
+        esac
261ad6
+        ;;    
261ad6
+    esac
261ad6
+    if [ $skip -eq 0 ]; then
261ad6
+        ocf_log "$level" "$message"
261ad6
+    fi
261ad6
+}
261ad6
+
261ad6
+#
261ad6
+# function: sht_usage - short usage info
261ad6
+# params:   -
261ad6
+# globals:  $0(r)
261ad6
+#
261ad6
+function sht_usage() {
261ad6
+    super_ocf_log info "FLOW $FUNCNAME ($*)"
261ad6
+    local rc=0
261ad6
+    methods=$(sht_methods)
261ad6
+    methods=$(echo $methods | tr ' ' '|')
261ad6
+  cat <<-!
261ad6
+	usage: $0 ($methods)
261ad6
+
261ad6
+    $0 manages a SAP HANA Instance as an HA resource.
261ad6
+
261ad6
+    The 'start'        operation starts the HANA instance or bring the "instance" to a WAITING (for primary) status
261ad6
+    The 'stop'         operation stops the HANA instance
261ad6
+    The 'status'       operation reports whether the HANA instance is running
261ad6
+    The 'monitor'      operation reports whether the HANA instance seems to be working in master/slave it also needs to check the system replication status
261ad6
+    The 'notify'       operation always returns SUCCESS
261ad6
+    The 'validate-all' operation reports whether the parameters are valid
261ad6
+    The 'methods'      operation reports on the methods $0 supports
261ad6
+
261ad6
+	!
261ad6
+	return $rc
261ad6
+}
261ad6
+
261ad6
+#
261ad6
+# function: sht_meta_data - print resource agent meta-data for cluster
261ad6
+# params:   -
261ad6
+# globals:  -
261ad6
+#
261ad6
+function sht_meta_data() {
261ad6
+    super_ocf_log info "FLOW $FUNCNAME ($*)"
261ad6
+    local rc=0
261ad6
+	cat <
261ad6
+
261ad6
+
261ad6
+<resource-agent name="SAPHanaTopology">
261ad6
+    <version>0.149.3</version>
261ad6
+    <shortdesc lang="en">Analyzes SAP HANA System Replication Topology.</shortdesc>
261ad6
+    <longdesc lang="en">This RA analyzes the SAP HANA topology and "sends" all findings via the node status attributes to
261ad6
+        all nodes in the cluster. These attributes are taken by the SAPHana RA to control the SAP Hana Databases.
261ad6
+        In addition it starts and monitors the local saphostagent.
261ad6
+
261ad6
+1. Interface to monitor a HANA system: landscapeHostConfiguration.py 
261ad6
+landscapeHostConfiguration.py has some detailed output about HANA system status
261ad6
+and node roles. For our monitor the overall status is relevant. This overall 
261ad6
+status is reported by the returncode of the script:
261ad6
+0: Internal Fatal
261ad6
+1: ERROR
261ad6
+2: WARNING
261ad6
+3: INFO (maybe a switch of the resource running)
261ad6
+4: OK
261ad6
+The SAPHanaTopology resource agent will interpret returncodes 1 as NOT-RUNNING (or 1 failure) and returncodes 2+3+4 as RUNNING.
261ad6
+SAPHanaTopology scans the output table of landscapeHostConfiguration.py to identify the roles of the cluster node. Roles means configured and current role of the nameserver as well as the indexserver.
261ad6
+
261ad6
+2. Interface is hdbnsutil
261ad6
+   The interface hdbnsutil is used to check the "topology" of the system replication as well as the current configuration
261ad6
+   (primary/secondary) of a SAP HANA database instance. A second task of the interface is the posibility to run a
261ad6
+   system replication takeover (sr_takeover) or to register a former primary to a newer one (sr_register).
261ad6
+
261ad6
+3. saphostctrl
261ad6
+   The interface saphostctrl uses the function ListInstances to figure out the virtual host name of the 
261ad6
+   SAP HANA instance. This is the hostname used during the HANA installation.
261ad6
+    </longdesc>
261ad6
+<parameters>
261ad6
+    <parameter name="SID" unique="0" required="1">
261ad6
+        <longdesc lang="en">The SAP System Identifier (SID)</longdesc>
261ad6
+        <shortdesc lang="en">The SAP System Identifier (SID)</shortdesc>
261ad6
+        <content type="string" default="" />
261ad6
+    </parameter>
261ad6
+    <parameter name="InstanceNumber" unique="0" required="1">
261ad6
+        <longdesc lang="en">The SAP Instance Number</longdesc>
261ad6
+        <shortdesc lang="en">The SAP Instance Number</shortdesc>
261ad6
+        <content type="string" default="" />
261ad6
+    </parameter>
261ad6
+    <parameter name="DIR_EXECUTABLE" unique="0" required="0">
261ad6
+        <longdesc lang="en">Path to the SAP Hana Instance executable directory. If not set the RA tries /usr/sap/\$SID/\$InstanceName/exe.
261ad6
+        While InstanceName is the string of "HDB" and \$InstanceNumber for SAP Hana databases.
261ad6
+        </longdesc>
261ad6
+        <shortdesc lang="en">Path to the SAP Hana Instance executable directory.</shortdesc>
261ad6
+        <content type="string" default="" />
261ad6
+    </parameter>
261ad6
+    <parameter name="SAPHanaFilter" unique="0" required="0">
261ad6
+        <shortdesc lang="en">Define type of SAPHanaTopology RA messages to be printed</shortdesc>
261ad6
+        <longdesc lang="en">Define type of SAPHanaTopology RA messages to be printed. 
261ad6
+Define SAPHana resource agent messages to be printed.
261ad6
+        This parameter should only be set of been requested by SUSE support. The default is sufficient for normal operation.
261ad6
+        Values: ra-act-lpa-dec-flow
261ad6
+        You could specify any combination of the above values like "ra-act-flow"
261ad6
+        </longdesc>
261ad6
+        <content type="string" default="" />
261ad6
+    </parameter>
261ad6
+</parameters>
261ad6
+<actions>
261ad6
+    <action name="start" timeout="180" />
261ad6
+    <action name="stop" timeout="60" />
261ad6
+    <action name="status" timeout="60" />
261ad6
+    <action name="monitor" depth="0" timeout="60" interval="60" />
261ad6
+    <action name="validate-all" timeout="5" />
261ad6
+    <action name="meta-data" timeout="5" />
261ad6
+    <action name="methods" timeout="5" />
261ad6
+</actions>
261ad6
+</resource-agent>
261ad6
+END
261ad6
+return $rc
261ad6
+}
261ad6
+
261ad6
+#
261ad6
+# function: get_hana_attribute 
261ad6
+# params:   NODE ATTR [STORE]
261ad6
+# globals:  -
261ad6
+#
261ad6
+function get_hana_attribute()
261ad6
+{
261ad6
+    super_ocf_log info "FLOW $FUNCNAME ($*)"
261ad6
+    local rc=0
261ad6
+    local attr_node=$1
261ad6
+    local attr_name=$2
261ad6
+    local attr_store=${3:-reboot} # DONE: PRIO5 get this (optional) from parameter
261ad6
+    crm_attribute -N ${attr_node} -G -n "$attr_name" -l $attr_store -q; rc=$?
261ad6
+    if [ $rc -ne 0 ]; then
261ad6
+           super_ocf_log debug "DBG: ATTRIBUTE-FAILURE: crm_attribute -N $attr_node -G -n "$attr_name" -l $attr_store -q"
261ad6
+    fi
261ad6
+    super_ocf_log info "FLOW $FUNCNAME rc=$rc"
261ad6
+    return $rc
261ad6
+}
261ad6
+
261ad6
+#
261ad6
+# function: set_hana_attribute - set the multi-state status of a node
261ad6
+# params:   NODE VALUE ATTR [STORE]
261ad6
+# globals:  -
261ad6
+#
261ad6
+function set_hana_attribute()
261ad6
+{
261ad6
+    super_ocf_log info "FLOW $FUNCNAME ($*)"
261ad6
+    local attr_node=$1
261ad6
+    local attr_value=$2
261ad6
+    local attr_name=$3
261ad6
+    local attr_store=${4:-reboot} # DONE: PRIO5 get this (optional) from parameter
261ad6
+    local rc=1
261ad6
+    local attr_old
261ad6
+    attr_old=$(get_hana_attribute $attr_node $attr_name $attr_store); get_rc=$?
261ad6
+    if [ "$attr_old" != "$attr_value" ]; then
261ad6
+        super_ocf_log debug "DBG: SET attribute $attr_name for node ${attr_node} to ${attr_value} former ($attr_old) get_rc=$get_rc "
261ad6
+        crm_attribute -N $attr_node -v "$attr_value" -n "$attr_name" -l $attr_store; rc=$?
261ad6
+        if [ $rc -ne 0 ]; then
261ad6
+           super_ocf_log debug "DBG: ATTRIBUTE-FAILURE: crm_attribute -N $attr_node -v $attr_value -n "$attr_name" -l $attr_store"
261ad6
+        fi
261ad6
+    else
261ad6
+        super_ocf_log debug "DBG: LET attribute $attr_name for node ${attr_node} still be ${attr_value}"
261ad6
+        rc=0
261ad6
+    fi
261ad6
+    super_ocf_log info "FLOW $FUNCNAME rc=$rc"
261ad6
+    return $rc
261ad6
+}
261ad6
+
261ad6
+#
261ad6
+# function: sht_methods - report supported cluster methods
261ad6
+# params:   -
261ad6
+# globals:  -
261ad6
+# methods: What methods/operations do we support?
261ad6
+#
261ad6
+function sht_methods() {
261ad6
+  super_ocf_log info "FLOW $FUNCNAME ($*)"
261ad6
+  local rc=0
261ad6
+  cat <<-!
261ad6
+    start
261ad6
+    stop
261ad6
+    status
261ad6
+    monitor
261ad6
+    notify
261ad6
+    validate-all
261ad6
+    methods
261ad6
+    meta-data
261ad6
+    usage
261ad6
+    admin-setup
261ad6
+	!
261ad6
+	return $rc
261ad6
+}
261ad6
+
261ad6
+#
261ad6
+# function: is_clone - report, if resource is configured as a clone (also master/slave)
261ad6
+# params:   -
261ad6
+# globals:  OCF_*(r)
261ad6
+# descript: is_clone : find out if we are configured to run in a Master/Slave configuration
261ad6
+#   rc: 0: it is a clone
261ad6
+#       1: it is not a clone
261ad6
+#   Special EXIT of RA, if clone is missconfigured
261ad6
+#
261ad6
+function is_clone() {
261ad6
+    super_ocf_log info "FLOW $FUNCNAME ($*)"
261ad6
+    local rc=0
261ad6
+    #
261ad6
+    # is a clone config?
261ad6
+    #
261ad6
+    if [ -n "$OCF_RESKEY_CRM_meta_clone_max" ] \
261ad6
+       && [ "$OCF_RESKEY_CRM_meta_clone_max" -gt 0 ]; then
261ad6
+       #
261ad6
+       # yes it is a clone config - check, if its configured well
261ad6
+       #
261ad6
+        if [ "$OCF_RESKEY_CRM_meta_clone_node_max" -ne 1 ] ; then 
261ad6
+                super_ocf_log err "ACT: Clone options misconfigured. (expect: clone_node_max=1)"
261ad6
+                exit $OCF_ERR_CONFIGURED
261ad6
+        fi
261ad6
+        rc=0;
261ad6
+    else
261ad6
+        rc=1;
261ad6
+    fi
261ad6
+    super_ocf_log info "FLOW $FUNCNAME rc=$rc"
261ad6
+    return $rc
261ad6
+}
261ad6
+
261ad6
+#
261ad6
+# function: sht_init - initialize variables for the resource agent
261ad6
+# params:   -
261ad6
+# globals:  OCF_*(r), SID(w), sid(rw), sidadm(w), InstanceName(w), InstanceNr(w), 
261ad6
+# globals:  meta_notify_master_uname(w), HANA_SR_TOLOPOGY(w), sr_name(w), remoteHost(w) 
261ad6
+# globals:  ATTR_NAME_HANA_SYNC_STATUS(w), ATTR_NAME_HANA_PRIMARY_AT(w), ATTR_NAME_HANA_CLONE_STATE(w)
261ad6
+# globals:  DIR_EXECUTABLE(w), SAPSTARTSRV(w), SAPCONTROL(w), DIR_PROFILE(w), SAPSTARTPROFILE(w), LD_LIBRARY_PATH(w), PATH(w), nodelist(w)
261ad6
+# sht_init : Define global variables with default values, if optional parameters are not set
261ad6
+#
261ad6
+#
261ad6
+
261ad6
+function sht_init() {
261ad6
+    super_ocf_log info "FLOW $FUNCNAME ($*)"
261ad6
+    local myInstanceName=""
261ad6
+    local rc=$OCF_SUCCESS
261ad6
+    local hdbANSWER=""
261ad6
+    HOSTEXECNAME=saphostexec
261ad6
+    USRSAP=/usr/sap
261ad6
+    SAPSERVICE_PATH=${USRSAP}/sapservices
261ad6
+    SAPHOSTCTRL_PATH=${USRSAP}/hostctrl/exe
261ad6
+    HOSTEXEC_PATH=${SAPHOSTCTRL_PATH}/${HOSTEXECNAME}
261ad6
+    HOSTEXEC_PROFILE_PATH=${SAPHOSTCTRL_PATH}/host_profile
261ad6
+    SID=$OCF_RESKEY_SID
261ad6
+    InstanceNr=$OCF_RESKEY_InstanceNumber
261ad6
+    myInstanceName="${SID}_HDB${InstanceNr}"
261ad6
+    InstanceName="HDB${InstanceNr}"
261ad6
+    super_ocf_log debug "DBG2: Used new method to get SID ($SID) and InstanceNr ($InstanceNr)"
261ad6
+    sid=$(echo "$SID" | tr [:upper:] [:lower:])
261ad6
+    sidadm="${sid}adm"
261ad6
+    SAPHanaFilter="${OCF_RESKEY_SAPHanaFilter:-ra-act-dec-lpa}"
261ad6
+    ocf_env=$(env | grep 'OCF_RESKEY_CRM')
261ad6
+    super_ocf_log debug "DBG3: OCF: $ocf_env"
261ad6
+    ATTR_NAME_HANA_SYNC_STATUS=("hana_${sid}_sync_state" "reboot")   # SOK, SFAIL, UNKNOWN?
261ad6
+    ATTR_NAME_HANA_PRIMARY_AT=("hana_${sid}_primary_at" "reboot")   # Not really used
261ad6
+    ATTR_NAME_HANA_CLONE_STATE=("hana_${sid}_clone_state" "reboot") # UKNOWN?, DEMOTED, PROMOTED
261ad6
+    ATTR_NAME_HANA_REMOTEHOST=("hana_${sid}_remoteHost" "forever")
261ad6
+    ATTR_NAME_HANA_SITE=("hana_${sid}_site" "forever")
261ad6
+    ATTR_NAME_HANA_ROLES=("hana_${sid}_roles" "reboot")
261ad6
+    ATTR_NAME_HANA_SRMODE=("hana_${sid}_srmode" "forever")
261ad6
+    ATTR_NAME_HANA_VHOST=("hana_${sid}_vhost" "forever")
261ad6
+    ATTR_NAME_HANA_STATUS=("hana_${sid}_status" "reboot")
261ad6
+
261ad6
+    # optional OCF parameters, we try to guess which directories are correct
261ad6
+    if  [ -z "$OCF_RESKEY_DIR_EXECUTABLE" ]
261ad6
+    then
261ad6
+        DIR_EXECUTABLE="/usr/sap/$SID/$InstanceName/exe"
261ad6
+    else
261ad6
+        DIR_EXECUTABLE="$OCF_RESKEY_DIR_EXECUTABLE"
261ad6
+    fi
261ad6
+
261ad6
+    if [ -z "$DIR_EXECUTABLE" ]; then
261ad6
+        super_ocf_log err "DEC: Can not determine DIR_EXECUTABLE. Please set this parameter. -> OCF_ERR_CONFIGURED"
261ad6
+        rc=$OCF_ERR_CONFIGURED
261ad6
+    fi
261ad6
+
261ad6
+    if [ -z "$OCF_RESKEY_DIR_PROFILE" ]
261ad6
+    then
261ad6
+        DIR_PROFILE="/usr/sap/$SID/SYS/profile"
261ad6
+    else
261ad6
+        DIR_PROFILE="$OCF_RESKEY_DIR_PROFILE"
261ad6
+    fi
261ad6
+
261ad6
+    # as root user we need the library path to the SAP kernel to be able to call sapcontrol
261ad6
+    # check, if we already added DIR_EXECUTABLE at the beginning of LD_LIBRARY_PATH
261ad6
+    if [ "${LD_LIBRARY_PATH%%*:}" != "$DIR_EXECUTABLE" ]
261ad6
+    then
261ad6
+        LD_LIBRARY_PATH=$DIR_EXECUTABLE${LD_LIBRARY_PATH:+:}$LD_LIBRARY_PATH
261ad6
+        export LD_LIBRARY_PATH
261ad6
+    fi
261ad6
+
261ad6
+    PATH=${PATH}:${DIR_EXECUTABLE}
261ad6
+    #
261ad6
+    # figure-out all needed values from system replication status with ONE call
261ad6
+    # we need: mode=primary|sync|syncmem|...; site name=<site>; mapping/<me>=<site>/<node> (multiple lines)
261ad6
+    case $(crm_attribute --type crm_config --name cluster-infrastructure -q) in
261ad6
+       *corosync* ) nodelist=$(crm_node -l | awk '{ print $2 }');;
261ad6
+       *openais* ) nodelist=$(crm_node -l | awk '/member/ {print $2}');;    
261ad6
+       *cman*    ) nodelist=$(crm_node -l);; 
261ad6
+    esac
261ad6
+    hdbANSWER=$(su - ${sidadm} -c "hdbnsutil -sr_state --sapcontrol=1" 2>/dev/null)
261ad6
+    super_ocf_log debug "DBG2: hdbANSWER=\$\(su - ${sidadm} -c \"hdbnsutil -sr_state --sapcontrol=1\"\)"
261ad6
+    site=$(echo "$hdbANSWER" | awk -F= '/site name/ {print $2}')
261ad6
+    srmode=$(echo "$hdbANSWER" | awk -F= '/mode/ {print $2}')
261ad6
+    MAPPING=$(echo "$hdbANSWER" | awk -F[=/] '$1 ~ "mapping" && $3 !~ site { print $4 }' site=$site)
261ad6
+    super_ocf_log debug "DBG: site=$site, mode=$srmode, MAPPING=$MAPPING"
261ad6
+    #
261ad6
+    # filter all non-cluster mappings
261ad6
+    #
261ad6
+    hanaRemoteHost=$(for n1 in $nodelist; do for n2 in $MAPPING; do if [ "$n1" == "$n2" ]; then echo $n1; fi; done; done )
261ad6
+        super_ocf_log info "DEC: site=$site, mode=$srmode, MAPPING=$MAPPING, hanaRemoteHost=$hanaRemoteHost"
261ad6
+        super_ocf_log debug "DBG: site=$site, mode=$srmode, MAPPING=$MAPPING, hanaRemoteHost=$hanaRemoteHost"
261ad6
+    super_ocf_log info "FLOW $FUNCNAME rc=$OCF_SUCCESS"
261ad6
+    return $OCF_SUCCESS
261ad6
+}  
261ad6
+
261ad6
+#
261ad6
+# function: check_for_primary - check if local SAP HANA is configured as primary
261ad6
+# params:   -
261ad6
+# globals:  HANA_STATE_PRIMARY(r), HANA_STATE_SECONDARY(r), HANA_STATE_DEFECT(r), HANA_STATE_STANDALONE(r)
261ad6
+#
261ad6
+function check_for_primary() {
261ad6
+    super_ocf_log info "FLOW $FUNCNAME ($*)"
261ad6
+    local rc=0
261ad6
+   # DONE: Change stderr location!!
261ad6
+   #sidadm=lnxadm
261ad6
+   #node_status=$(check_for_primary_single) 
261ad6
+   node_status=$srmode
261ad6
+   super_ocf_log debug "DBG2: check_for_primary: node_status=$node_status"
261ad6
+   super_ocf_log debug "DBG: check_for_primary: node_status=$node_status"
261ad6
+   for i in  1 2 3 4 5 6 7 8 9; do
261ad6
+       case "$node_status" in
261ad6
+           primary ) 
261ad6
+                  super_ocf_log info "FLOW $FUNCNAME rc=HANA_STATE_PRIMARY"
261ad6
+                  return $HANA_STATE_PRIMARY;;
261ad6
+           syncmem | sync | async )
261ad6
+                  super_ocf_log info "FLOW $FUNCNAME rc=HANA_STATE_SECONDARY"
261ad6
+                  return $HANA_STATE_SECONDARY;;
261ad6
+           none )     # have seen that mode on second side BEFEORE we registered it as replica
261ad6
+                  super_ocf_log info "FLOW $FUNCNAME rc=HANA_STATE_STANDALONE"
261ad6
+                  return $HANA_STATE_STANDALONE;;
261ad6
+           * )
261ad6
+	          super_ocf_log err "ACT: check_for_primary:  we didn't expect node_status to be: <$node_status>"
261ad6
+                  dump=$( echo $node_status | hexdump -C );
261ad6
+	          super_ocf_log err "ACT: check_for_primary:  we didn't expect node_status to be: DUMP <$dump>"
261ad6
+                  node_full_status=$(su - ${sidadm} -c "hdbnsutil -sr_state" 2>/dev/null )
261ad6
+                  node_status=$(echo "$node_full_status" | awk '$1=="mode:" {print $2}')
261ad6
+                  super_ocf_log info "DEC: check_for_primary: loop=$i: node_status=$node_status"
261ad6
+                  # TODO: PRIO1: Maybe we need to keep the old value for P/S/N, if hdbnsutil just crashes
261ad6
+       esac;
261ad6
+   done
261ad6
+   super_ocf_log info "FLOW $FUNCNAME rc=HANA_STATE_DEFECT"
261ad6
+   return $HANA_STATE_DEFECT
261ad6
+}
261ad6
+
261ad6
+
261ad6
+#
261ad6
+# function: start_saphostagent
261ad6
+# params:   -
261ad6
+# globals:  
261ad6
+#
261ad6
+function start_saphostagent()
261ad6
+{
261ad6
+    if [ -x "${HOSTEXEC_PATH}" ]; then
261ad6
+        ${HOSTEXEC_PATH} pf=${HOSTEXEC_PROFILE_PATH}
261ad6
+    fi
261ad6
+    return 0
261ad6
+}
261ad6
+
261ad6
+#
261ad6
+# function: stop_saphostagent
261ad6
+# params:   -
261ad6
+# globals: 
261ad6
+#
261ad6
+function stop_saphostagent()
261ad6
+{
261ad6
+        if [ -x "${HOSTEXEC_PATH}" ]; then
261ad6
+                ${HOSTEXEC_PATH} -stop
261ad6
+        fi
261ad6
+}
261ad6
+
261ad6
+#
261ad6
+# function: check_saphostagent
261ad6
+# params:   -
261ad6
+# globals:
261ad6
+#
261ad6
+function check_saphostagent()
261ad6
+{
261ad6
+    local rc=1
261ad6
+    pgrep -f /usr/sap/hostctrl/exe/saphostexec; rc=$?
261ad6
+    return $rc
261ad6
+}
261ad6
+
261ad6
+#
261ad6
+#############################################################################
261ad6
+#
261ad6
+# function: sht_start - start a hana instance
261ad6
+# params:   -
261ad6
+# globals:  OCF_*
261ad6
+# sht_start : Start the SAP HANA instance
261ad6
+#
261ad6
+function sht_start() {
261ad6
+  
261ad6
+  super_ocf_log info "FLOW $FUNCNAME ($*)"
261ad6
+
261ad6
+  local rc=$OCF_NOT_RUNNING
261ad6
+  local output=""
261ad6
+  local loopcount=0  
261ad6
+
261ad6
+  mkdir -p /var/lib/SAPHana
261ad6
+  touch /var/lib/SAPHana/SAPTopologyON
261ad6
+  if ! check_saphostagent; then
261ad6
+     start_saphostagent
261ad6
+  fi
261ad6
+
261ad6
+  rc=$OCF_SUCCESS
261ad6
+
261ad6
+  super_ocf_log info "FLOW $FUNCNAME rc=$rc"
261ad6
+  return $rc
261ad6
+}
261ad6
+
261ad6
+#
261ad6
+# function: sht_stop - stop a hana instance
261ad6
+# params:   -
261ad6
+# globals:  OCF_*(r), SAPCONTROL(r), SID(r), InstanceName(r)
261ad6
+# sht_stop: Stop the SAP instance
261ad6
+#
261ad6
+function sht_stop() {
261ad6
+  super_ocf_log info "FLOW $FUNCNAME ($*)"
261ad6
+  local output=""
261ad6
+  local rc=0
261ad6
+
261ad6
+  rm /var/lib/SAPHana/SAPTopologyON
261ad6
+  rc=$OCF_SUCCESS
261ad6
+  
261ad6
+  super_ocf_log info "FLOW $FUNCNAME rc=$rc"
261ad6
+  return $rc
261ad6
+}
261ad6
+
261ad6
+
261ad6
+#
261ad6
+# function: sht_monitor - monitor a hana topology instance
261ad6
+# params:   --
261ad6
+# globals:  OCF_*(r), SAPCONTROL(r), InstanveNr(r)
261ad6
+# sht_monitor: Can the given SAP instance do anything useful?
261ad6
+#
261ad6
+function sht_monitor() {
261ad6
+  super_ocf_log info "FLOW $FUNCNAME ($*)"
261ad6
+  local rc=0
261ad6
+
261ad6
+  if [ -f /var/lib/SAPHana/SAPTopologyON ]; then
261ad6
+     rc=$OCF_SUCCESS
261ad6
+  else
261ad6
+     rc=$OCF_NOT_RUNNING
261ad6
+  fi
261ad6
+
261ad6
+  super_ocf_log info "FLOW $FUNCNAME rc=$rc" 
261ad6
+  return $rc
261ad6
+}
261ad6
+
261ad6
+
261ad6
+#
261ad6
+# function: sht_status - get status of a hana instance (os tools only)
261ad6
+# params:   -
261ad6
+# globals:  SID(r), InstanceName(r), OCF_*(r), sidarm(r)
261ad6
+# sht_status: Lightweight check of SAP instance only with OS tools
261ad6
+#
261ad6
+function sht_status() {
261ad6
+  super_ocf_log info "FLOW $FUNCNAME ($*)"
261ad6
+  local rc=0
261ad6
+
261ad6
+  sht_monitor; rc=$?
261ad6
+  return $rc
261ad6
+}
261ad6
+
261ad6
+
261ad6
+#
261ad6
+# function: sht_validate - validation of (some) variables/parameters
261ad6
+# params:   -
261ad6
+# globals:  OCF_*(r), SID(r), InstanceName(r), InstanceNr(r), 
261ad6
+# sht_validate: Check the symantic of the input parameters 
261ad6
+#
261ad6
+function sht_validate() {
261ad6
+  super_ocf_log info "FLOW $FUNCNAME ($*)"
261ad6
+  local rc=$OCF_SUCCESS
261ad6
+  if [ $(echo "$SID" | grep -c '^[A-Z][A-Z0-9][A-Z0-9]$') -ne 1 ]
261ad6
+  then
261ad6
+    super_ocf_log err "ACT: Parsing instance profile name: '$SID' is not a valid SID!"
261ad6
+    rc=$OCF_ERR_ARGS
261ad6
+  fi
261ad6
+
261ad6
+  if [ $(echo "$InstanceNr" | grep -c '^[0-9][0-9]$') -ne 1 ]
261ad6
+  then
261ad6
+    super_ocf_log err "ACT: Parsing instance profile name: '$InstanceNr' is not a valid instance number!"
261ad6
+    rc=$OCF_ERR_ARGS
261ad6
+  fi
261ad6
+
261ad6
+  super_ocf_log info "FLOW $FUNCNAME rc=$rc"
261ad6
+  return $rc
261ad6
+}
261ad6
+
261ad6
+#
261ad6
+# function: sht_start_clone - start a hana clone instance
261ad6
+# params:   -
261ad6
+# globals:  OCF_*(r),
261ad6
+# sht_start_clone
261ad6
+#
261ad6
+function sht_start_clone() {
261ad6
+    super_ocf_log info "FLOW $FUNCNAME ($*)"
261ad6
+       local rc=$OCF_NOT_RUNNING
261ad6
+    sht_start; rc=$?
261ad6
+    return $rc
261ad6
+}
261ad6
+
261ad6
+#
261ad6
+# function: sht_stop_clone - stop a hana clone instance
261ad6
+# params:   -
261ad6
+# globals:  NODENAME(r), HANA_STATE_*, ATTR_NAME_*
261ad6
+# sht_stop_clone
261ad6
+#
261ad6
+function sht_stop_clone() {
261ad6
+    super_ocf_log info "FLOW $FUNCNAME ($*)"
261ad6
+    local rc=0
261ad6
+	check_for_primary; primary_status=$?
261ad6
+    if [ $primary_status -eq $HANA_STATE_PRIMARY ]; then
261ad6
+        hanaPrim="P"
261ad6
+    elif [ $primary_status -eq $HANA_STATE_SECONDARY ]; then
261ad6
+        hanaPrim="S"
261ad6
+    elif [ $primary_status -eq $HANA_STATE_STANDALONE ]; then
261ad6
+        hanaPrim="N"
261ad6
+    else
261ad6
+        hanaPrim="-"
261ad6
+    fi
261ad6
+    set_hana_attribute "${NODENAME}" "1:$hanaPrim:-:-:-:-" ${ATTR_NAME_HANA_ROLES[@]} 
261ad6
+    sht_stop; rc=$?
261ad6
+    return $rc
261ad6
+}
261ad6
+
261ad6
+#
261ad6
+# function: sht_monitor_clone - monitor a hana clone instance
261ad6
+# params:   -
261ad6
+# globals:  OCF_*, SID, InstanceNr, InstanceName, MAPPING(r)
261ad6
+# sht_monitor_clone
261ad6
+#
261ad6
+function sht_monitor_clone() {
261ad6
+    super_ocf_log info "FLOW $FUNCNAME ($*)"
261ad6
+    #
261ad6
+	local rc=$OCF_ERR_GENERIC
261ad6
+	local promoted=0
261ad6
+    local init_attribute=0
261ad6
+
261ad6
+
261ad6
+	if ocf_is_probe; then
261ad6
+		super_ocf_log debug "DBG2: PROBE ONLY"
261ad6
+	else
261ad6
+		super_ocf_log debug "DBG2: REGULAR MONITOR"
261ad6
+        if ! check_saphostagent; then
261ad6
+             start_saphostagent
261ad6
+        fi
261ad6
+	fi
261ad6
+	#
261ad6
+	# First check, if we are PRIMARY or SECONDARY
261ad6
+	# 
261ad6
+    super_ocf_log debug "DBG2: HANA SID $SID"
261ad6
+    super_ocf_log debug "DBG2: HANA InstanceName $InstanceName"
261ad6
+    super_ocf_log debug "DBG2: HANA InstanceNr $InstanceNr"
261ad6
+	check_for_primary; primary_status=$?
261ad6
+    if [ $primary_status -eq $HANA_STATE_PRIMARY ]; then
261ad6
+        hanaPrim="P"
261ad6
+        super_ocf_log debug "DBG2: HANA IS PRIMARY"
261ad6
+        sht_monitor; rc=$?
261ad6
+    else
261ad6
+        if [ $primary_status -eq $HANA_STATE_SECONDARY  ]; then
261ad6
+            hanaPrim="S"
261ad6
+            super_ocf_log debug "DBG2: HANA IS SECONDARY"
261ad6
+            sht_monitor; rc=$?
261ad6
+        elif [ $primary_status -eq $HANA_STATE_STANDALONE  ]; then
261ad6
+            hanaPrim="N"
261ad6
+            super_ocf_log debug "DBG2: HANA IS STANDALONE"
261ad6
+            sht_monitor; rc=$?
261ad6
+        else
261ad6
+            hanaPrim="-"
261ad6
+            super_ocf_log warn "ACT: sht_monitor_clone: HANA_STATE_DEFECT"
261ad6
+            rc=$OCF_ERR_CONFIGURED
261ad6
+        fi
261ad6
+    fi
261ad6
+    # DONE: PRIO1: ASK: Is the output format of ListInstances fix? Could we take that as an API?
261ad6
+    # try to catch:  Inst Info : LNX - 42 - lv9041 - 740, patch 36, changelist 1444691
261ad6
+    # We rely on the following format: SID is word#4, NR is work#6, vHost is word#8
261ad6
+    vName=$(/usr/sap/hostctrl/exe/saphostctrl -function ListInstances \
261ad6
+        | awk '$4 == SID && $6=NR { print $8 }' SID=$SID NR=$InstanceNr 2>/dev/null )
261ad6
+    super_ocf_log debug "DBG: ListInstances: $(/usr/sap/hostctrl/exe/saphostctrl -function ListInstances)"
261ad6
+    if [ -n "$vName" ]; then
261ad6
+       set_hana_attribute ${NODENAME} "$vName" ${ATTR_NAME_HANA_VHOST[@]} 
261ad6
+    else
261ad6
+       vName=$(get_hana_attribute ${NODENAME} ${ATTR_NAME_HANA_VHOST[@]})
261ad6
+    fi
261ad6
+    #site=$(get_site_name)
261ad6
+    hanaANSWER=$(su - $sidadm -c "python exe/python_support/landscapeHostConfiguration.py" 2>/dev/null); hanalrc="$?" 
261ad6
+    hanarole=$(echo "$hanaANSWER" | tr -d ' ' | awk -F'|' '$2 == host {  printf "%s:%s:%s:%s\n",$10,$11,$12,$13 }  ' host=${vName})
261ad6
+    #if [ -z "$MAPPING" ]; then
261ad6
+    #   super_ocf_log info "ACT: Did not find remote Host at this moment"
261ad6
+    #fi
261ad6
+    # FH TODO PRIO1: TRY TO GET RID OF "ATTR_NAME_HANA_REMOTEHOST"
261ad6
+    if [ -n "$hanaRemoteHost" ]; then
261ad6
+        set_hana_attribute ${NODENAME} "$hanaRemoteHost" ${ATTR_NAME_HANA_REMOTEHOST[@]} 
261ad6
+    fi
261ad6
+    set_hana_attribute ${NODENAME} "$hanalrc:$hanaPrim:$hanarole" ${ATTR_NAME_HANA_ROLES[@]} 
261ad6
+    set_hana_attribute ${NODENAME} "$site" ${ATTR_NAME_HANA_SITE[@]} 
261ad6
+    set_hana_attribute ${NODENAME} "$vName" ${ATTR_NAME_HANA_VHOST[@]} 
261ad6
+    case "$hanaPrim" in
261ad6
+       P ) ;;
261ad6
+       S ) # only secondary may propargate its sync status
261ad6
+        case $(crm_attribute --type crm_config --name cluster-infrastructure -q) in
261ad6
+           *corosync* ) nodelist=$(crm_node -l | awk '{ print $2 }');;
261ad6
+           *openais* ) nodelist=$(crm_node -l | awk '/member/ {print $2}');;    
261ad6
+           *cman*    ) nodelist=$(crm_node -l);; 
261ad6
+        esac
261ad6
+
261ad6
+        for n in ${nodelist}; do
261ad6
+           set_hana_attribute ${n} "$srmode" ${ATTR_NAME_HANA_SRMODE[@]}
261ad6
+        done
261ad6
+          ;;
261ad6
+    esac
261ad6
+    #ATTR_NAME_HANA_STATUS  # TODO: PRIO5: For SCALE-OUT: Fill that attribute later
261ad6
+    super_ocf_log info "FLOW $FUNCNAME rc=$rc"
261ad6
+    return $rc
261ad6
+}
261ad6
+
261ad6
+#
261ad6
+# function: sht_notify - notify action
261ad6
+# params:   -
261ad6
+# globals:  OCF_*(r), ACTION(r), CLACT(r), NODENAME(r)
261ad6
+# sht_notify: Handle master scoring - to make sure a slave gets the next master
261ad6
+#
261ad6
+function sht_notify() {
261ad6
+    super_ocf_log info "FLOW $FUNCNAME ($*)"
261ad6
+    local rc=0
261ad6
+    super_ocf_log info "RA ==== end action $ACTION$CLACT (${n_type}/${n_op})===="
261ad6
+    return $rc
261ad6
+}
261ad6
+
261ad6
+#
261ad6
+# function: main - main function to operate 
261ad6
+# params:   ACTION
261ad6
+# globals:  OCF_*(r), SID(w), sidadm(w), InstanceName(w), DIR_EXECUTABLE(w), ACTION(w), CLACT(w), ra_rc(rw), $0(r), %ENV(r)
261ad6
+#
261ad6
+
261ad6
+## GLOBALS
261ad6
+SID=""
261ad6
+sidadm=""
261ad6
+InstanceName=""
261ad6
+InstanceNr=""
261ad6
+DIR_EXECUTABLE=""
261ad6
+SAPHanaFilter="${OCF_RESKEY_SAPHanaFilter:-ra-act-dec-lpa}"
261ad6
+NODENAME=$(crm_node -n)
261ad6
+
261ad6
+if [ $# -ne 1 ]
261ad6
+then
261ad6
+  sht_usage
261ad6
+  exit $OCF_ERR_ARGS
261ad6
+fi
261ad6
+
261ad6
+ACTION=$1
261ad6
+if [ "$ACTION" = "status" ]; then
261ad6
+    ACTION=monitor
261ad6
+fi
261ad6
+
261ad6
+# These operations don't require OCF parameters to be set
261ad6
+case "$ACTION" in
261ad6
+    usage|methods)  sht_$ACTION
261ad6
+                    exit $OCF_SUCCESS;;
261ad6
+    meta-data)      sht_meta_data
261ad6
+                    exit $OCF_SUCCESS;;
261ad6
+    notify)         sht_notify
261ad6
+                    exit $OCF_SUCCESS;;
261ad6
+    admin-setup)   admin-setup
261ad6
+                                 exit $OCF_SUCCESS;;  
261ad6
+    *);;
261ad6
+esac
261ad6
+sht_init 
261ad6
+
261ad6
+if ! ocf_is_root
261ad6
+then
261ad6
+    super_ocf_log err "ACT: $0 must be run as root"
261ad6
+    exit $OCF_ERR_PERM
261ad6
+fi
261ad6
+
261ad6
+# parameter check
261ad6
+if  [ -z "$OCF_RESKEY_SID" ]
261ad6
+then
261ad6
+    super_ocf_log err "ACT: Please set parameter SID!"
261ad6
+    exit $OCF_ERR_ARGS
261ad6
+fi
261ad6
+
261ad6
+if  [ -z "$OCF_RESKEY_InstanceNumber" ]
261ad6
+then
261ad6
+    super_ocf_log err "ACT: Please set parameter InstanceNumber!"
261ad6
+    exit $OCF_ERR_ARGS
261ad6
+fi
261ad6
+
261ad6
+
261ad6
+if is_clone
261ad6
+then
261ad6
+    CLACT=_clone
261ad6
+else
261ad6
+    if [ "$ACTION" = "promote" -o "$ACTION" = "demote" ]
261ad6
+    then
261ad6
+        super_ocf_log err "ACT: $ACTION called in a non clone environment"
261ad6
+        exit $OCF_ERR_ARGS
261ad6
+    fi
261ad6
+fi
261ad6
+
261ad6
+THE_VERSION=$(sht_meta_data | grep '
261ad6
+super_ocf_log info "RA ==== begin action $ACTION$CLACT ($THE_VERSION) ===="
261ad6
+ra_rc=$OCF_ERR_UNIMPLEMENTED
261ad6
+case "$ACTION" in
261ad6
+    start|stop|monitor) # Standard controling actions
261ad6
+        sht_$ACTION$CLACT
261ad6
+        ra_rc=$?
261ad6
+        ;;
261ad6
+    validate-all) 
261ad6
+        sht_validate
261ad6
+        ra_rc=$?
261ad6
+        ;;
261ad6
+    *)  # seams to be a unknown request 
261ad6
+        sht_methods 
261ad6
+        ra_rc=$OCF_ERR_UNIMPLEMENTED
261ad6
+        ;;
261ad6
+esac
261ad6
+timeE=$(date '+%s')
261ad6
+(( timeR = timeE - timeB ))
261ad6
+super_ocf_log info "RA ==== end action $ACTION$CLACT with rc=${ra_rc} ($THE_VERSION) (${timeR}s)===="
261ad6
+exit ${ra_rc}
261ad6
diff --git a/tools/Makefile.am b/tools/Makefile.am
261ad6
index 3205bbd..c70707f 100644
261ad6
--- a/tools/Makefile.am
261ad6
+++ b/tools/Makefile.am
261ad6
@@ -28,7 +28,7 @@ halibdir		= $(libexecdir)/heartbeat
261ad6
 EXTRA_DIST		= ocf-tester.8 sfex_init.8
261ad6
 
261ad6
 sbin_PROGRAMS		= 
261ad6
-sbin_SCRIPTS		= ocf-tester
261ad6
+sbin_SCRIPTS		= ocf-tester show_SAPHanaSR_attributes
261ad6
 halib_PROGRAMS		= findif
261ad6
 
261ad6
 man8_MANS		= ocf-tester.8
261ad6
diff --git a/tools/show_SAPHanaSR_attributes b/tools/show_SAPHanaSR_attributes
261ad6
new file mode 100755
261ad6
index 0000000..4dc55f9
261ad6
--- /dev/null
261ad6
+++ b/tools/show_SAPHanaSR_attributes
261ad6
@@ -0,0 +1,133 @@
261ad6
+#!/usr/bin/perl
261ad6
+#
261ad6
+# get_all_lnx_attributes
261ad6
+#
261ad6
+# license: GPL
261ad6
+# author:  fabian.herschel@suse.com
261ad6
+# date:    2014-05-13
261ad6
+# 
261ad6
+#
261ad6
+use POSIX;
261ad6
+use strict;
261ad6
+
261ad6
+my $sid="";
261ad6
+my $table_title = "Host \\ Attr";
261ad6
+my %Name;
261ad6
+my %Host;
261ad6
+
261ad6
+sub max { # thanks to http://www.perlunity.de/perl/forum/thread_018329.shtml
261ad6
+ my $a = shift;
261ad6
+ my $b = shift;
261ad6
+ return $a > $b ? $a : $b;
261ad6
+}
261ad6
+
261ad6
+sub print_attr_host()
261ad6
+{
261ad6
+    my ($HKey, $AKey);
261ad6
+	printf "%-22s", "Attribute \\ Host";
261ad6
+	foreach $HKey (sort keys %Host) {
261ad6
+	   printf "%-16s ", $HKey;
261ad6
+	}
261ad6
+	printf "\n";
261ad6
+
261ad6
+	printf "%s\n", "-" x 120 ;
261ad6
+
261ad6
+	foreach $AKey (sort keys %Name) {
261ad6
+	   printf "%-22s", $AKey;
261ad6
+	   foreach $HKey (sort keys %Host) {
261ad6
+		   printf "%-16.16s ", $Host{$HKey} -> {$AKey};
261ad6
+		}
261ad6
+
261ad6
+	   printf "\n";
261ad6
+	}
261ad6
+	return 0;
261ad6
+}
261ad6
+
261ad6
+sub print_host_attr()
261ad6
+{
261ad6
+    my ($AKey, $HKey, $len, $line_len, $hclen);
261ad6
+    $hclen=$Name{_hosts}->{_length};
261ad6
+    $line_len=$hclen+1;
261ad6
+	printf "%-$hclen.${hclen}s ", "$table_title";
261ad6
+	foreach $AKey (sort keys %Name) {
261ad6
+       if ($AKey ne "_hosts") {
261ad6
+           $len = $Name{$AKey}->{_length};
261ad6
+           $line_len=$line_len+$len+1;
261ad6
+           printf "%-$len.${len}s ", $Name{$AKey}->{_title};
261ad6
+       }
261ad6
+	}
261ad6
+	printf "\n";
261ad6
+	printf "%s\n", "-" x $line_len ;
261ad6
+	foreach $HKey (sort keys %Host) {
261ad6
+	   printf "%-$hclen.${hclen}s ", $HKey;
261ad6
+	   foreach $AKey (sort keys %Name) {
261ad6
+           if ($AKey ne "_hosts") {
261ad6
+               $len = $Name{$AKey}->{_length};
261ad6
+               printf "%-$len.${len}s ", $Host{$HKey} -> {$AKey};
261ad6
+            }
261ad6
+        }
261ad6
+	   printf "\n";
261ad6
+	}
261ad6
+	return 0;
261ad6
+}
261ad6
+
261ad6
+open ListInstances, "/usr/sap/hostctrl/exe/saphostctrl -function ListInstances|";
261ad6
+while (<ListInstances>) {
261ad6
+   # try to catch:  Inst Info : LNX - 42 - lv9041 - 740, patch 36, changelist 1444691
261ad6
+   chomp;
261ad6
+   if ( $_ =~ /:\s+([A-Z][A-Z0-9][A-Z0-9])\s+-/ ) {
261ad6
+      $sid=tolower("$1");
261ad6
+   }
261ad6
+}
261ad6
+close ListInstances;
261ad6
+
261ad6
+
261ad6
+open CIB, "cibadmin -Ql |";
261ad6
+while (<CIB>) {
261ad6
+   chomp;
261ad6
+   my ($host, $name, $value);
261ad6
+   my $found=0;
261ad6
+   if ( $_ =~ /nvpair.*name="(\w+_${sid}_\w+)"/ ) {
261ad6
+      $name=$1;
261ad6
+      # find attribute in forever and reboot store :)
261ad6
+      if ( $_ =~ /id="(status|nodes)-([a-zA-Z0-9\_\-]+)-/ ) {
261ad6
+         $host=$2;
261ad6
+      }
261ad6
+      if ( $_ =~ /value="([^"]+)"/ ) {
261ad6
+         $value=$1;
261ad6
+         $found=1;
261ad6
+      }
261ad6
+   }
261ad6
+   if ( $found == 1 ) {
261ad6
+       #
261ad6
+       # handle the hosts name and table-title
261ad6
+       #
261ad6
+       $Host{$host}->{$name}=${value};
261ad6
+       if ( defined ($Name{_hosts}->{_length})) {
261ad6
+          $Name{_hosts}->{_length} = max($Name{_hosts}->{_length}, length($host ));
261ad6
+       } else {
261ad6
+          $Name{_hosts}->{_length} = length($host );
261ad6
+       }
261ad6
+       $Name{_hosts}->{_length} = max($Name{_hosts}->{_length}, length( $table_title));
261ad6
+       #
261ad6
+       # now handle the attributes name and value
261ad6
+       #
261ad6
+       $Name{$name}->{$host}=${value};
261ad6
+       if ( defined ($Name{$name}->{_length})) {
261ad6
+          $Name{$name}->{_length} = max($Name{$name}->{_length}, length($value ));
261ad6
+       } else {
261ad6
+          $Name{$name}->{_length} = length($value );
261ad6
+       }
261ad6
+       if ( $name =~ /hana_${sid}_(.*)/ ) {
261ad6
+          $Name{$name}->{_title} =  $1;
261ad6
+       } else {
261ad6
+          $Name{$name}->{_title} = $name; 
261ad6
+       }
261ad6
+       $Name{$name}->{_length} = max($Name{$name}->{_length}, length( $Name{$name}->{_title}));
261ad6
+       # printf "%-8s %-20s %-30s\n", $1, $2, $3;
261ad6
+   }
261ad6
+}
261ad6
+close CIB;
261ad6
+
261ad6
+#print_attr_host;
261ad6
+print_host_attr;
261ad6
-- 
261ad6
1.8.4.2
261ad6