You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1991 lines
85 KiB
1991 lines
85 KiB
7 years ago
|
diff -uNr a/heartbeat/SAPHana b/heartbeat/SAPHana
|
||
|
--- a/heartbeat/SAPHana 2016-10-14 10:09:56.479051279 +0200
|
||
|
+++ b/heartbeat/SAPHana 2016-10-14 10:29:23.990066292 +0200
|
||
|
@@ -2,8 +2,8 @@
|
||
|
#
|
||
|
# SAPHana
|
||
|
#
|
||
|
-# Description: Manages two single SAP HANA Instance in System Replication
|
||
|
-# Planned: do also manage scale-up scenarios
|
||
|
+# Description: Manages two SAP HANA Databases in System Replication
|
||
|
+# Planned: do also manage scale-out scenarios
|
||
|
# currently the SAPHana is dependent of the analysis of
|
||
|
# SAPHanaTopology
|
||
|
# For supported scenarios please read the README file provided
|
||
|
@@ -16,7 +16,7 @@
|
||
|
# Support: linux@sap.com
|
||
|
# License: GNU General Public License (GPL)
|
||
|
# Copyright: (c) 2013,2014 SUSE Linux Products GmbH
|
||
|
-# Copyright: (c) 2015 SUSE Linux GmbH
|
||
|
+# (c) 2015-2016 SUSE Linux GmbH
|
||
|
#
|
||
|
# An example usage:
|
||
|
# See usage() function below for more details...
|
||
|
@@ -29,12 +29,13 @@
|
||
|
# OCF_RESKEY_INSTANCE_PROFILE (optional, well known directories will be searched by default)
|
||
|
# OCF_RESKEY_PREFER_SITE_TAKEOVER (optional, default is no)
|
||
|
# OCF_RESKEY_DUPLICATE_PRIMARY_TIMEOUT (optional, time difference needed between two last-primary-tiemstampe (lpt))
|
||
|
-# OCF_RESKEY_SAPHanaFilter (optional, should only be set if been told by support or for debugging purposes)
|
||
|
+# OCF_RESKEY_SAPHanaFilter (outdated, replaced by cluster property hana_${sid}_glob_filter)
|
||
|
#
|
||
|
#
|
||
|
#######################################################################
|
||
|
#
|
||
|
# Initialization:
|
||
|
+SAPHanaVersion="0.152.17"
|
||
|
timeB=$(date '+%s')
|
||
|
|
||
|
: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
|
||
|
@@ -43,6 +44,12 @@
|
||
|
#
|
||
|
#######################################################################
|
||
|
#
|
||
|
+log_attributes=false
|
||
|
+if ocf_is_true "$log_attributes"; then
|
||
|
+ log_attr_file="/var/log/fhATTRIBUTES"
|
||
|
+else
|
||
|
+ log_attr_file="/dev/null"
|
||
|
+fi
|
||
|
|
||
|
HANA_STATE_PRIMARY=0
|
||
|
HANA_STATE_SECONDARY=1
|
||
|
@@ -107,7 +114,7 @@
|
||
|
cat <<-EOF
|
||
|
usage: $0 ($methods)
|
||
|
|
||
|
- $0 manages a SAP HANA Instance as an HA resource.
|
||
|
+ $0 manages two SAP HANA databases (scale-up) in system replication.
|
||
|
|
||
|
The 'start' operation starts the HANA instance or bring the "clone instance" to a WAITING status
|
||
|
The 'stop' operation stops the HANA instance
|
||
|
@@ -145,15 +152,14 @@
|
||
|
<?xml version="1.0"?>
|
||
|
<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
|
||
|
<resource-agent name="SAPHana">
|
||
|
-<version>0.151.1</version>
|
||
|
+<version>$SAPHanaVersion</version>
|
||
|
|
||
|
-<shortdesc lang="en">Manages two SAP HANA instances in system replication (SR).</shortdesc>
|
||
|
+<shortdesc lang="en">Manages two SAP HANA database systems in system replication (SR).</shortdesc>
|
||
|
<longdesc lang="en">
|
||
|
-The SAPHanaSR resource agent manages two SAP Hana instances (databases) which are configured
|
||
|
-in system replication. This first version is limited to the scale-up scenario. Scale-Out is
|
||
|
-not supported in this version.
|
||
|
+The SAPHanaSR resource agent manages two SAP HANA database systems which are configured
|
||
|
+in system replication. SAPHana supports Scale-Up scenarios.
|
||
|
|
||
|
-Managing the two SAP HANA instances means that the resource agent controls the start/stop of the
|
||
|
+Managing the two SAP HANA database systems means that the resource agent controls the start/stop of the
|
||
|
instances. In addition the resource agent is able to monitor the SAP HANA databases to check their
|
||
|
availability on landscape host configuration level. For this monitoring the resource agent relies on interfaces
|
||
|
provided by SAP. A third task of the resource agent is to also check the synchronisation status
|
||
|
@@ -205,9 +211,10 @@
|
||
|
<longdesc lang="en">Should cluster/RA prefer to switchover to slave instance instead of restarting master locally? Default="yes"
|
||
|
no: Do prefer restart locally
|
||
|
yes: Do prefer takever to remote site
|
||
|
+ never: Do never run a sr_takeover (promote) at the secondary side. THIS VALUE IS CURRENTLY NOT SUPPORTED.
|
||
|
</longdesc>
|
||
|
<shortdesc lang="en">Local or site recover preferred?</shortdesc>
|
||
|
- <content type="boolean" default="yes" />
|
||
|
+ <content type="string" default="yes" />
|
||
|
</parameter>
|
||
|
<parameter name="AUTOMATED_REGISTER" unique="0" required="0">
|
||
|
<shortdesc lang="en">Define, if a former primary should automatically be registered.</shortdesc>
|
||
|
@@ -220,7 +227,7 @@
|
||
|
<shortdesc lang="en">Time difference needed between to primary time stamps, if a dual-primary situation occurs</shortdesc>
|
||
|
<longdesc lang="en">Time difference needed between to primary time stamps,
|
||
|
if a dual-primary situation occurs. If the time difference is
|
||
|
- less than the time gap, then the cluster hold one or both instances in a "WAITING" status. This is to give an admin
|
||
|
+ less than the time gap, then the cluster holds one or both instances in a "WAITING" status. This is to give an admin
|
||
|
a chance to react on a failover. A failed former primary will be registered after the time difference is passed. After
|
||
|
this registration to the new primary all data will be overwritten by the system replication.
|
||
|
</longdesc>
|
||
|
@@ -290,6 +297,45 @@
|
||
|
local rc=0; tr -d '"'; return $rc
|
||
|
}
|
||
|
|
||
|
+# function: version: cpmpare two HANA version strings
|
||
|
+function ver_lt() {
|
||
|
+ ocf_version_cmp $1 $2
|
||
|
+ test $? -eq 0 && return 0 || return 1
|
||
|
+}
|
||
|
+
|
||
|
+function ver_le() {
|
||
|
+ ocf_version_cmp $1 $2
|
||
|
+ test $? -eq 0 -o $? -eq 1 && return 0 || return 1
|
||
|
+}
|
||
|
+
|
||
|
+function ver_gt() {
|
||
|
+ ocf_version_cmp $1 $2
|
||
|
+ test $? -eq 2 && return 0 || return 1
|
||
|
+}
|
||
|
+
|
||
|
+function ver_ge() {
|
||
|
+ ocf_version_cmp $1 $2
|
||
|
+ test $? -eq 2 -o $? -eq 1 && return 0 || return 1
|
||
|
+}
|
||
|
+#
|
||
|
+# function: version: cpmpare two HANA version strings
|
||
|
+#
|
||
|
+function version() {
|
||
|
+ if [ $# -eq 3 ]; then
|
||
|
+ case "$2" in
|
||
|
+ LE | le | "<=" ) ver_le $1 $3;;
|
||
|
+ LT | lt | "<" ) ver_lt $1 $3;;
|
||
|
+ GE | ge | ">=" ) ver_ge $1 $3;;
|
||
|
+ GT | gt | ">" ) ver_gt $1 $3;;
|
||
|
+ * ) return 1;
|
||
|
+ esac
|
||
|
+ elif [ $# -ge 5 ]; then
|
||
|
+ version $1 $2 $3 && shift 2 && version $*
|
||
|
+ else
|
||
|
+ return 1;
|
||
|
+ fi
|
||
|
+}
|
||
|
+
|
||
|
#
|
||
|
# function: remoteHost2remoteNode - convert a SAP remoteHost to the cluster node name
|
||
|
# params: remoteHost
|
||
|
@@ -372,12 +418,16 @@
|
||
|
dstr=$(date)
|
||
|
case "$attr_store" in
|
||
|
reboot | forever )
|
||
|
- echo "$dstr: SAPHana: crm_attribute -N ${attr_node} -G -n \"$attr_name\" -l $attr_store -q" >> /var/log/fhATTRIBUTE
|
||
|
- crm_attribute -N ${attr_node} -G -n "$attr_name" -l $attr_store -q -d "$attr_default" 2>>/var/log/fhATTRIBUTE; rc=$?
|
||
|
+ if ocf_is_true "$log_attributes"; then
|
||
|
+ echo "$dstr: SAPHana: crm_attribute -N ${attr_node} -G -n \"$attr_name\" -l $attr_store -q" >> $log_attr_file
|
||
|
+ fi
|
||
|
+ crm_attribute -N ${attr_node} -G -n "$attr_name" -l $attr_store -q -d "$attr_default" 2>>$log_attr_file; rc=$?
|
||
|
;;
|
||
|
props )
|
||
|
- echo "$dstr: SAPHana: crm_attribute -G -n \"$attr_name\" -t crm_config -q" >> /var/log/fhATTRIBUTE
|
||
|
- crm_attribute -G -n "$attr_name" -t crm_config -q -d "$attr_default" 2>>/var/log/fhATTRIBUTE; rc=$?
|
||
|
+ if ocf_is_true "$log_attributes"; then
|
||
|
+ echo "$dstr: SAPHana: crm_attribute -G -n \"$attr_name\" -t crm_config -q" >> $log_attr_file
|
||
|
+ fi
|
||
|
+ crm_attribute -G -n "$attr_name" -t crm_config -q -d "$attr_default" 2>>$log_attr_file; rc=$?
|
||
|
;;
|
||
|
esac
|
||
|
super_ocf_log info "FLOW $FUNCNAME rc=$rc"
|
||
|
@@ -405,12 +455,16 @@
|
||
|
dstr=$(date)
|
||
|
case "$attr_store" in
|
||
|
reboot | forever )
|
||
|
- echo "$dstr: SAPHana: crm_attribute -N $attr_node -v $attr_value -n \"$attr_name\" -l $attr_store" >> /var/log/fhATTRIBUTE
|
||
|
- crm_attribute -N $attr_node -v $attr_value -n "$attr_name" -l $attr_store 2>>/var/log/fhATTRIBUTE; rc=$?
|
||
|
+ if ocf_is_true "$log_attributes"; then
|
||
|
+ echo "$dstr: SAPHana: crm_attribute -N $attr_node -v $attr_value -n \"$attr_name\" -l $attr_store" >> $log_attr_file
|
||
|
+ fi
|
||
|
+ crm_attribute -N $attr_node -v $attr_value -n "$attr_name" -l $attr_store 2>>$log_attr_file; rc=$?
|
||
|
;;
|
||
|
props )
|
||
|
- echo "$dstr: SAPHana: crm_attribute -v $attr_value -n \"$attr_name\" -t crm_config -s SAPHanaSR" >> /var/log/fhATTRIBUTE
|
||
|
- crm_attribute -v $attr_value -n "$attr_name" -t crm_config -s SAPHanaSR 2>>/var/log/fhATTRIBUTE; rc=$?
|
||
|
+ if ocf_is_true "$log_attributes"; then
|
||
|
+ echo "$dstr: SAPHana: crm_attribute -v $attr_value -n \"$attr_name\" -t crm_config -s SAPHanaSR" >> $log_attr_file
|
||
|
+ fi
|
||
|
+ crm_attribute -v $attr_value -n "$attr_name" -t crm_config -s SAPHanaSR 2>>$log_attr_file; rc=$?
|
||
|
;;
|
||
|
esac
|
||
|
else
|
||
|
@@ -460,6 +514,10 @@
|
||
|
# DONE: PRIO2: Only adjust master if value is really different (try to check that)
|
||
|
oldscore=$(${HA_SBIN_DIR}/crm_master -G -q -l reboot)
|
||
|
if [ "$oldscore" != "$score" ]; then
|
||
|
+ dstr=$(date)
|
||
|
+ if ocf_is_true "$log_attributes"; then
|
||
|
+ echo "$dstr: SAPHana: crm_master -v $score -l reboot " >> $log_attr_file
|
||
|
+ fi
|
||
|
super_ocf_log debug "DBG: SET crm master: $score (old: $oldscore)"
|
||
|
${HA_SBIN_DIR}/crm_master -v $score -l reboot; rc=$?
|
||
|
else
|
||
|
@@ -471,9 +529,9 @@
|
||
|
}
|
||
|
|
||
|
#
|
||
|
-# function: scoring_crm_master - score instance due to role ans sync match (table SCORING_TABLE_PREFERRED_SITE_TAKEOVER)
|
||
|
+# function: scoring_crm_master - score instance due to role ans sync match (table SCORING_TABLE)
|
||
|
# params: NODE_ROLES NODE_SYNC_STATUS
|
||
|
-# globals: SCORING_TABLE_PREFERRED_SITE_TAKEOVER[@],
|
||
|
+# globals: SCORING_TABLE[@],
|
||
|
#
|
||
|
scoring_crm_master()
|
||
|
{
|
||
|
@@ -482,7 +540,7 @@
|
||
|
local sync="$2"
|
||
|
local skip=0
|
||
|
local myScore=""
|
||
|
- for scan in "${SCORING_TABLE_PREFERRED_SITE_TAKEOVER[@]}"; do
|
||
|
+ for scan in "${SCORING_TABLE[@]}"; do
|
||
|
if [ $skip -eq 0 ]; then
|
||
|
read rolePatt syncPatt score <<< $scan
|
||
|
if grep "$rolePatt" <<< "$roles"; then
|
||
|
@@ -494,7 +552,7 @@
|
||
|
fi
|
||
|
done
|
||
|
super_ocf_log debug "DBG: scoring_crm_master adjust score $myScore"
|
||
|
- # TODO: PRIO1: DO Not Score, If we did not found our role/sync at this moment - bsc#919925
|
||
|
+ # DONE: PRIO1: DO Not Score, If we did not found our role/sync at this moment - bsc#919925
|
||
|
if [ -n "$myScore" ]; then
|
||
|
set_crm_master $myScore
|
||
|
fi
|
||
|
@@ -514,28 +572,91 @@
|
||
|
}
|
||
|
|
||
|
#
|
||
|
+# function: HANA_CALL
|
||
|
+# params: timeout-in-seconds cmd-line
|
||
|
+# globals: sid(r), SID(r), InstanceName(r)
|
||
|
+#
|
||
|
+function HANA_CALL()
|
||
|
+{
|
||
|
+ #
|
||
|
+ # TODO: PRIO 5: remove 'su - ${sidadm} later, when SAP HANA resoled issue with
|
||
|
+ # root-user-called hdbnsutil -sr_state (which creates root-owned shared memory file in /var/lib/hdb/SID/shmgrp)
|
||
|
+ # TODO: PRIO 5: Maybe make "su" optional by a parameter
|
||
|
+ local timeOut=0
|
||
|
+ local onTimeOut=""
|
||
|
+ local rc=0
|
||
|
+ local use_su=1 # Default to be changed later (see TODO above)
|
||
|
+ local pre_cmd=""
|
||
|
+ local cmd=""
|
||
|
+ local pre_script=""
|
||
|
+ local output=""
|
||
|
+ while [ $# -gt 0 ]; do
|
||
|
+ case "$1" in
|
||
|
+ --timeout ) timeOut=$2; shift;;
|
||
|
+ --use-su ) use_su=1;;
|
||
|
+ --on-timeout ) onTimeOut="$2"; shift;;
|
||
|
+ --cmd ) shift; cmd="$*"; break;;
|
||
|
+ esac
|
||
|
+ shift
|
||
|
+ done
|
||
|
+
|
||
|
+ if [ $use_su -eq 1 ]; then
|
||
|
+ pre_cmd="su - ${sid}adm -c"
|
||
|
+ pre_script="true"
|
||
|
+ else
|
||
|
+ # as root user we need the library path to the SAP kernel to be able to call sapcontrol
|
||
|
+ # check, if we already added DIR_EXECUTABLE at the beginning of LD_LIBRARY_PATH
|
||
|
+ if [ "${LD_LIBRARY_PATH%%*:}" != "$DIR_EXECUTABLE" ]
|
||
|
+ then
|
||
|
+ MY_LD_LIBRARY_PATH=$DIR_EXECUTABLE${LD_LIBRARY_PATH:+:}$LD_LIBRARY_PATH
|
||
|
+ fi
|
||
|
+ pre_cmd="bash -c"
|
||
|
+ pre_script="LD_LIBRARY_PATH=$MY_LD_LIBRARY_PATH; export LD_LIBRARY_PATH"
|
||
|
+ fi
|
||
|
+ case $timeOut in
|
||
|
+ 0 | inf )
|
||
|
+ output=$($pre_cmd "$pre_script; /usr/sap/$SID/$InstanceName/HDBSettings.sh $cmd"); rc=$?
|
||
|
+ ;;
|
||
|
+ * )
|
||
|
+ output=$(timeout $timeOut $pre_cmd "$pre_script; /usr/sap/$SID/$InstanceName/HDBSettings.sh $cmd"); rc=$?
|
||
|
+ #
|
||
|
+ # on timeout ...
|
||
|
+ #
|
||
|
+ if [ $rc -eq 124 -a -n "$onTimeOut" ]; then
|
||
|
+ local second_output=""
|
||
|
+ second_output=$($pre_cmd "$pre_script; /usr/sap/$SID/$InstanceName/HDBSettings.sh $onTimeOut");
|
||
|
+ fi
|
||
|
+ ;;
|
||
|
+ esac
|
||
|
+ echo "$output"
|
||
|
+ return $rc;
|
||
|
+}
|
||
|
+
|
||
|
+#
|
||
|
# function: saphana_init - initialize variables for the resource agent
|
||
|
# params: InstanceName
|
||
|
-# globals: OCF_*(r), SID(w), sid(rw), sidadm(w), InstanceName(w), InstanceNr(w), SAPVIRHOST(w), PreferSiteTakeover(w),
|
||
|
-# globals: sr_name(w), remoteHost(w), otherNodes(w), rem_SR_name(w)
|
||
|
+# globals: OCF_*(r), SID(w), sid(rw), sidadm(w), InstanceName(w), InstanceNr(w), SAPVIRHOST(w), PreferSiteTakeover(w),
|
||
|
+# globals: sr_name(w), remoteHost(w), otherNodes(w), remSR_name(w)
|
||
|
# globals: ATTR_NAME_HANA_SYNC_STATUS(w), ATTR_NAME_HANA_CLONE_STATE(w)
|
||
|
# globals: DIR_EXECUTABLE(w), SAPSTARTSRV(w), SAPCONTROL(w), DIR_PROFILE(w), SAPSTARTPROFILE(w), LD_LIBRARY_PATH(w), PATH(w)
|
||
|
# globals: LPA_DIRECTORY(w), SIDInstanceName(w), remoteNode(w), hdbSrQueryTimeout(w)
|
||
|
+# globals: NODENAME(w), vNAME(w), hdbver(w),
|
||
|
# saphana_init : Define global variables with default values, if optional parameters are not set
|
||
|
#
|
||
|
function saphana_init() {
|
||
|
super_ocf_log info "FLOW $FUNCNAME ($*)"
|
||
|
local rc=$OCF_SUCCESS
|
||
|
- local vName
|
||
|
local clN
|
||
|
# local site
|
||
|
# two parameter models (for transition only)
|
||
|
# OLD: InstanceName
|
||
|
# NEW: SID InstanceNumber
|
||
|
+ NODENAME=$(crm_node -n)
|
||
|
SID=$OCF_RESKEY_SID
|
||
|
InstanceNr=$OCF_RESKEY_InstanceNumber
|
||
|
SIDInstanceName="${SID}_HDB${InstanceNr}"
|
||
|
InstanceName="HDB${InstanceNr}"
|
||
|
+ export SAPSYSTEMNAME=$SID
|
||
|
super_ocf_log debug "DBG: Used new method to get SID ($SID) and InstanceNr ($InstanceNr)"
|
||
|
sid=$(echo "$SID" | tr [:upper:] [:lower:])
|
||
|
sidadm="${sid}adm"
|
||
|
@@ -544,15 +665,23 @@
|
||
|
# DONE: PRIO4: SAPVIRHOST might be different to NODENAME
|
||
|
# DONE: PRIO1: ASK: Is the output format of ListInstances fix? Could we take that as an API? Answer: Yes
|
||
|
# try to catch: Inst Info : LNX - 42 - lv9041 - 740, patch 36, changelist 1444691
|
||
|
- # We rely on the following format: SID is word#4, NR is work#6, vHost is word#8
|
||
|
- vName=$(/usr/sap/hostctrl/exe/saphostctrl -function ListInstances \
|
||
|
- | awk '$4 == SID && $6=NR { print $8 }' SID=$SID NR=$InstanceNr)
|
||
|
+ # We rely on the following format: SID is word#4, SYSNR is work#6, vHost is word#8
|
||
|
+ if [ -e /usr/sap/hostctrl/exe/saphostctrl ]; then
|
||
|
+ vName=$(/usr/sap/hostctrl/exe/saphostctrl -function ListInstances \
|
||
|
+ | awk '$4 == SID && $6 == SYSNR { print $8 }' SID=$SID SYSNR=$InstanceNr 2>/dev/null )
|
||
|
+ super_ocf_log debug "DBG: ListInstances: $(/usr/sap/hostctrl/exe/saphostctrl -function ListInstances)"
|
||
|
+ else
|
||
|
+ super_ocf_log error "ERR: SAPHOSTAGENT is not installed at /usr/sap/hostctrl/exe (saphostctrl missing)"
|
||
|
+ fi
|
||
|
if [ -z "$vName" ]; then
|
||
|
#
|
||
|
# if saphostctrl does not know the answer, try to fallback to attribute provided by SAPHanaTopology
|
||
|
#
|
||
|
vName=$(get_hana_attribute ${NODENAME} ${ATTR_NAME_HANA_VHOST[@]} "$NODENAME");
|
||
|
fi
|
||
|
+ if [ -z "$vName" ]; then # last fallback if we are not able to figure out the virtual host name
|
||
|
+ vName="$NODENAME"
|
||
|
+ fi
|
||
|
SAPVIRHOST=${vName}
|
||
|
PreferSiteTakeover="$OCF_RESKEY_PREFER_SITE_TAKEOVER"
|
||
|
AUTOMATED_REGISTER="${OCF_RESKEY_AUTOMATED_REGISTER:-false}"
|
||
|
@@ -571,6 +700,12 @@
|
||
|
ATTR_NAME_HANA_SRMODE=("hana_${sid}_srmode" "forever")
|
||
|
ATTR_NAME_HANA_VHOST=("hana_${sid}_vhost" "forever")
|
||
|
ATTR_NAME_HANA_STATUS=("hana_${sid}_status" "reboot")
|
||
|
+ ATTR_NAME_HANA_OPERATION_MODE=("hana_${sid}_op_mode" "forever")
|
||
|
+ #
|
||
|
+ # new "central" attributes
|
||
|
+ #
|
||
|
+ ATTR_NAME_HANA_FILTER=("hana_${sid}_glob_filter" "props" "ra-act-dec-lpa")
|
||
|
+ SAPHanaFilter=$(get_hana_attribute "X" ${ATTR_NAME_HANA_FILTER[@]})
|
||
|
#
|
||
|
# TODO: PRIO4: Table for non-preferred-site-takeover
|
||
|
#
|
||
|
@@ -591,9 +726,7 @@
|
||
|
)
|
||
|
SCORING_TABLE_PREFERRED_LOCAL_RESTART=(
|
||
|
"[0-9]*:P:[^:]*:master .* 150"
|
||
|
- "[0-9]*:P:[^:]*:slave .* 140"
|
||
|
- "[0-9]*:P:[^:]*:\? .* 0"
|
||
|
- "[0-9]*:P:[^:]*:- .* 0"
|
||
|
+ "[0-9]*:P:[^:]*:.* .* 140"
|
||
|
"[0-9]*:S:[^:]*:master SOK 100"
|
||
|
"[0-9]*:S:[^:]*:master SFAIL -INFINITY"
|
||
|
"[0-9]*:S:[^:]*:slave SOK 10"
|
||
|
@@ -602,6 +735,25 @@
|
||
|
"[0-9]*:S:[^:]*:- .* 0"
|
||
|
".* .* -1"
|
||
|
)
|
||
|
+ SCORING_TABLE_PREFERRED_NEVER=(
|
||
|
+ "[234]*:P:[^:]*:master .* 150"
|
||
|
+ "[015-9]*:P:[^:]*:master .* 90"
|
||
|
+ "[0-9]*:P:[^:]*:.* .* -INFINITY"
|
||
|
+ "[0-9]*:S:[^:]*:.* .* -INFINITY"
|
||
|
+ ".* .* -INFINITY"
|
||
|
+ )
|
||
|
+ if ocf_is_true $PreferSiteTakeover; then
|
||
|
+ SCORING_TABLE=("${SCORING_TABLE_PREFERRED_SITE_TAKEOVER[@]}")
|
||
|
+ else
|
||
|
+ case "$PreferSiteTakeover" in
|
||
|
+ never|NEVER|Never )
|
||
|
+ SCORING_TABLE=("${SCORING_TABLE_PREFERRED_NEVER[@]}")
|
||
|
+ ;;
|
||
|
+ * )
|
||
|
+ SCORING_TABLE=("${SCORING_TABLE_PREFERRED_LOCAL_RESTART[@]}")
|
||
|
+ ;;
|
||
|
+ esac
|
||
|
+ fi
|
||
|
#
|
||
|
DUPLICATE_PRIMARY_TIMEOUT="${OCF_RESKEY_DUPLICATE_PRIMARY_TIMEOUT:-7200}"
|
||
|
super_ocf_log debug "DBG: DUPLICATE_PRIMARY_TIMEOUT=$DUPLICATE_PRIMARY_TIMEOUT"
|
||
|
@@ -615,7 +767,7 @@
|
||
|
esac
|
||
|
#
|
||
|
#
|
||
|
-
|
||
|
+ #
|
||
|
remoteHost=$(get_hana_attribute ${NODENAME} ${ATTR_NAME_HANA_REMOTEHOST[@]});
|
||
|
if [ -z "$remoteHost" ]; then
|
||
|
if [ ${#otherNodes[@]} -eq 1 ]; then # we are a 2 node cluster, lets assume the other is the remote-host
|
||
|
@@ -640,7 +792,7 @@
|
||
|
sr_mode="sync"
|
||
|
fi
|
||
|
if [ -n "$remoteNode" ]; then
|
||
|
- rem_SR_name=$(get_hana_attribute ${remoteNode} ${ATTR_NAME_HANA_SITE[@]});
|
||
|
+ remSR_name=$(get_hana_attribute ${remoteNode} ${ATTR_NAME_HANA_SITE[@]});
|
||
|
fi
|
||
|
super_ocf_log debug "DBG: sr_name=$sr_name, remoteHost=$remoteHost, remoteNode=$remoteNode, sr_mode=$sr_mode"
|
||
|
# optional OCF parameters, we try to guess which directories are correct
|
||
|
@@ -671,26 +823,21 @@
|
||
|
#
|
||
|
SAPSTARTPROFILE="$(ls -1 $DIR_PROFILE/${OCF_RESKEY_INSTANCE_PROFILE:-${SID}_${InstanceName}_*})"
|
||
|
fi
|
||
|
- # as root user we need the library path to the SAP kernel to be able to call sapcontrol
|
||
|
- # check, if we already added DIR_EXECUTABLE at the beginning of LD_LIBRARY_PATH
|
||
|
- if [ "${LD_LIBRARY_PATH%%*:}" != "$DIR_EXECUTABLE" ]
|
||
|
- then
|
||
|
- LD_LIBRARY_PATH=$DIR_EXECUTABLE${LD_LIBRARY_PATH:+:}$LD_LIBRARY_PATH
|
||
|
- export LD_LIBRARY_PATH
|
||
|
- fi
|
||
|
PATH=${PATH}:${DIR_EXECUTABLE}; export PATH
|
||
|
+ local ges_ver
|
||
|
+ ges_ver=$(HANA_CALL --timeout 10 --cmd "HDB version" | tr -d " " | awk -F: '$1 == "version" {print $2}')
|
||
|
+ hdbver=${ges_ver%.*.*}
|
||
|
+ #
|
||
|
+ # since rev 111.00 we should use a new hdbnsutil option to get the -sr_state
|
||
|
+ # since rev 112.03 the old option is changed and we should use -sr_stateConfiguration where ever possible
|
||
|
+ #
|
||
|
+ hdbState="hdbnsutil -sr_state"
|
||
|
+ hdbMap="hdbnsutil -sr_state"
|
||
|
+ if version "$hdbver" ">=" "1.00.111"; then
|
||
|
+ hdbState="hdbnsutil -sr_stateConfiguration"
|
||
|
+ hdbMap="hdbnsutil -sr_stateHostMapping"
|
||
|
+ fi
|
||
|
super_ocf_log info "FLOW $FUNCNAME rc=$OCF_SUCCESS"
|
||
|
- #############################
|
||
|
- # TODO: PRIO9: To be able to call landscapeHostConfig.py without su (so as root)
|
||
|
- # TODO: PRIO9: Research for environment script .htacces or something like that
|
||
|
- #export SAPSYSTEMNAME=ZLF
|
||
|
- #export DIR_INSTANCE=/usr/sap/ZLF/HDB02
|
||
|
- #export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$DIR_INSTANCE/exe:$DIR_INSTANCE/exe/Python/lib
|
||
|
- #export PYTHONPATH=$DIR_INSTANCE/$HOST:$DIR_INSTANCE/exe/python_support:$DIR_INSTANCE/exe
|
||
|
- #export PYTHONHOME=$DIR_INSTANCE/exe/Python
|
||
|
- #export SAP_RETRIEVAL_PATH=$DIR_INSTANCE/$HOST
|
||
|
- #export DIR_EXECUTABLE=$DIR_INSTANCE/exe
|
||
|
- #############################
|
||
|
return $OCF_SUCCESS
|
||
|
}
|
||
|
|
||
|
@@ -765,7 +912,11 @@
|
||
|
# or ownership - they will be recreated by sapstartsrv during next start
|
||
|
rm -f /tmp/.sapstream5${InstanceNr}13
|
||
|
rm -f /tmp/.sapstream5${InstanceNr}14
|
||
|
- $SAPSTARTSRV pf=$SAPSTARTPROFILE -D -u $sidadm
|
||
|
+ (
|
||
|
+ export PATH="$DIR_EXECUTABLE${PATH:+:}$PATH"
|
||
|
+ export LD_LIBRARY_PATH="$DIR_EXECUTABLE${LD_LIBRARY_PATH:+:}$LD_LIBRARY_PATH"
|
||
|
+ $SAPSTARTSRV pf=$SAPSTARTPROFILE -D -u $sidadm
|
||
|
+ )
|
||
|
# now make sure the daemon has been started and is able to respond
|
||
|
local srvrc=1
|
||
|
while [ $srvrc -eq 1 -a $(pgrep -f "sapstartsrv.*$runninginst" | wc -l) -gt 0 ]
|
||
|
@@ -809,31 +960,47 @@
|
||
|
function check_for_primary() {
|
||
|
super_ocf_log info "FLOW $FUNCNAME ($*)"
|
||
|
local rc=$HANA_STATE_DEFECT
|
||
|
- node_full_status=$(su - ${sidadm} -c "hdbnsutil -sr_state" 2>/dev/null )
|
||
|
- node_status=$(echo "$node_full_status" | awk '$1=="mode:" {print $2}')
|
||
|
- super_ocf_log debug "DBG: check_for_primary: node_status=$node_status"
|
||
|
- # TODO: PRIO2: Maybe we need to use a fallback interface when hdbnsitil does not answer properly -> lookup in config files?
|
||
|
+ # TODO: PRIO 3: Check beginning from which SPS does SAP support HDBSettings.sh?
|
||
|
+ # TODO: Limit the runtime of hdbnsutil and use getParameter.py as fallback
|
||
|
+ # TODO: PRIO2: Maybe we need to use a fallback interface when hdbnsutil does not answer properly -> lookup in config files?
|
||
|
# This might also solve some problems when we could not figure-out the ilocal or remote site name
|
||
|
- for i in 1 2 3 4 5 6 7 8 9; do
|
||
|
+ local chkMethod=""
|
||
|
+ for chkMethod in hU hU hU gP; do
|
||
|
+ case "$chkMethod" in
|
||
|
+ gP )
|
||
|
+ local gpKeys=""
|
||
|
+ gpKeys=$(echo --key=global.ini/system_replication/{mode,site_name,site_id})
|
||
|
+ node_full_status=$(HANA_CALL --timeout 60 --cmd "HDBSettings.sh getParameter.py $gpKeys --sapcontrol=1" 2>&1 | awk -F/ 'BEGIN {out=0} /^SAPCONTROL-OK: <begin>/ { out=1 } /^SAPCONTROL-OK: <end>/ { out=0 } /=/ {if (out==1) {print $3} }')
|
||
|
+ node_status=$(echo "$node_full_status" | awk -F= '$1=="mode" {print $2}')
|
||
|
+ super_ocf_log info "ACT: Using getParameter.py as fallback - node_status=$node_status"
|
||
|
+ ;;
|
||
|
+ hU | * )
|
||
|
+ # DONE: PRIO1: Begginning from SAP HANA rev 112.03 -sr_state is not longer supported
|
||
|
+ node_full_status=$(HANA_CALL --timeout 60 --cmd "$hdbState" 2>/dev/null )
|
||
|
+ node_status=$(echo "$node_full_status" | awk '$1=="mode:" {print $2}')
|
||
|
+ super_ocf_log debug "DBG: check_for_primary: node_status=$node_status"
|
||
|
+ ;;
|
||
|
+ esac
|
||
|
case "$node_status" in
|
||
|
primary )
|
||
|
- super_ocf_log info "FLOW: $FUNCNAME rc=HANA_STATE_PRIMARY"
|
||
|
- return $HANA_STATE_PRIMARY;;
|
||
|
+ rc=$HANA_STATE_PRIMARY
|
||
|
+ break;;
|
||
|
syncmem | sync | async )
|
||
|
- super_ocf_log info "FLOW: $FUNCNAME rc=HANA_STATE_SECONDARY"
|
||
|
- return $HANA_STATE_SECONDARY;;
|
||
|
+ rc=$HANA_STATE_SECONDARY
|
||
|
+ break;;
|
||
|
none ) # have seen that mode on second side BEFEORE we registered it as replica
|
||
|
- super_ocf_log info "FLOW: $FUNCNAME rc=HANA_STATE_STANDALONE"
|
||
|
- return $HANA_STATE_STANDALONE;;
|
||
|
+ rc=$HANA_STATE_STANDALONE
|
||
|
+ break;;
|
||
|
* )
|
||
|
super_ocf_log err "ACT: check_for_primary: we didn't expect node_status to be: <$node_status>"
|
||
|
dump=$( echo $node_status | hexdump -C );
|
||
|
super_ocf_log err "ACT: check_for_primary: we didn't expect node_status to be: DUMP <$dump>"
|
||
|
- node_full_status=$(su - ${sidadm} -c "hdbnsutil -sr_state" 2>/dev/null )
|
||
|
- node_status=$(echo "$node_full_status" | awk '$1=="mode:" {print $2}')
|
||
|
+ # TODO: Limit the runtime of hdbnsutil and use getParameter.py as fallback
|
||
|
+ # SAP_CALL
|
||
|
super_ocf_log debug "DEC: check_for_primary: loop=$i: node_status=$node_status"
|
||
|
# TODO: PRIO1: Maybe we need to keep the old value for P/S/N, if hdbnsutil just crashes
|
||
|
esac;
|
||
|
+ sleep 2
|
||
|
done
|
||
|
super_ocf_log info "FLOW $FUNCNAME rc=$rc"
|
||
|
return $rc
|
||
|
@@ -854,12 +1021,18 @@
|
||
|
{
|
||
|
super_ocf_log info "FLOW $FUNCNAME ($*)"
|
||
|
local rc=-1 srRc=0 all_nodes_other_side="" n="" siteParam=""
|
||
|
- if [ -n "$rem_SR_name" ]; then
|
||
|
- siteParam="--site=$rem_SR_name"
|
||
|
+ if [ -n "$remSR_name" ]; then
|
||
|
+ siteParam="--site=$remSR_name"
|
||
|
fi
|
||
|
- FULL_SR_STATUS=$(su - $sidadm -c "python $DIR_EXECUTABLE/python_support/systemReplicationStatus.py $siteParam" 2>/dev/null); srRc=$?
|
||
|
- super_ocf_log info "DEC $FUNCNAME systemReplicationStatus.py (to site '$rem_SR_name')-> $srRc"
|
||
|
- super_ocf_log info "FLOW $FUNCNAME systemReplicationStatus.py (to site '$rem_SR_name')-> $srRc"
|
||
|
+ # TODO: Get rid of the su by using a new interface:
|
||
|
+ # SAPSYSTEMNAME=SLE /usr/sap/SLE/HDB00/HDBSettings.sh systemReplicationStatus.py $siteParam
|
||
|
+ # TODO: Check beginning from which SPS does SAP support HDBSettings.sh?
|
||
|
+ # TODO: Limit the runtime of systemReplicationStatus.py
|
||
|
+ # SAP_CALL
|
||
|
+ # FULL_SR_STATUS=$(su - $sidadm -c "python $DIR_EXECUTABLE/python_support/systemReplicationStatus.py $siteParam" 2>/dev/null); srRc=$?
|
||
|
+ FULL_SR_STATUS=$(HANA_CALL --timeout 60 --cmd "systemReplicationStatus.py" 2>/dev/null); srRc=$?
|
||
|
+ super_ocf_log info "DEC $FUNCNAME systemReplicationStatus.py (to site '$remSR_name')-> $srRc"
|
||
|
+ super_ocf_log info "FLOW $FUNCNAME systemReplicationStatus.py (to site '$remSR_name')-> $srRc"
|
||
|
#
|
||
|
# TODO: PRIO2: Here we might also need to filter additional sites (if multi tier should be supported)
|
||
|
# And is the check for return code capable for chains?
|
||
|
@@ -890,7 +1063,7 @@
|
||
|
# ok we should be careful and set secondary to SFAIL
|
||
|
super_ocf_log info "FLOW $FUNCNAME SFAIL"
|
||
|
set_hana_attribute "$remoteNode" "SFAIL" ${ATTR_NAME_HANA_SYNC_STATUS[@]}
|
||
|
- super_ocf_log info "ACT site=$sr_name, seting SFAIL for secondary (5) - srRc=$srRc lss=$lss"
|
||
|
+ super_ocf_log info "ACT site=$sr_name, setting SFAIL for secondary (5) - srRc=$srRc lss=$lss"
|
||
|
# TODO: PRIO1 - P004: need to check LSS again to avoid dying primary to block (SFAIL) secondary
|
||
|
lpa_set_lpt 10 "$remoteNode"
|
||
|
rc=1
|
||
|
@@ -898,7 +1071,7 @@
|
||
|
else
|
||
|
super_ocf_log info "FLOW $FUNCNAME SFAIL"
|
||
|
set_hana_attribute "$remoteNode" "SFAIL" ${ATTR_NAME_HANA_SYNC_STATUS[@]}
|
||
|
- super_ocf_log info "ACT site=$sr_name, seting SFAIL for secondary (2) - srRc=$srRc"
|
||
|
+ super_ocf_log info "ACT site=$sr_name, setting SFAIL for secondary (2) - srRc=$srRc"
|
||
|
# TODO: PRIO1 - P004: need to check LSS again to avoid dying primary to block (SFAIL) secondary
|
||
|
lpa_set_lpt 10 "$remoteNode"
|
||
|
rc=1;
|
||
|
@@ -992,14 +1165,28 @@
|
||
|
super_ocf_log info "FLOW $FUNCNAME ($*)"
|
||
|
local rc=0
|
||
|
#
|
||
|
- su - $sidadm -c "python $DIR_EXECUTABLE/python_support/landscapeHostConfiguration.py" 1>/dev/null 2>/dev/null; rc=$?
|
||
|
+ # TODO: Get rid of the su by using a new interface:
|
||
|
+ # SAPSYSTEMNAME=SLE /usr/sap/SLE/HDB00/HDBSettings.sh landscapeHostConfiguration.py
|
||
|
+ # TODO: Check beginning from which SPS does SAP support HDBSettings.sh?
|
||
|
+ # DONE: Limit the runtime of landscapeHostConfiguration.py
|
||
|
+ HANA_CALL --timeout 60 --cmd "landscapeHostConfiguration.py" 1>/dev/null 2>/dev/null; rc=$?
|
||
|
+ if [ $rc -eq 124 ]; then
|
||
|
+ # TODO: PRIO 1: Check, if we should loop here like 'for i in 1 2 3 ...' ?
|
||
|
+ # landscape timeout
|
||
|
+ sleep 20
|
||
|
+ HANA_CALL --timeout 60 --cmd "landscapeHostConfiguration.py" 1>/dev/null 2>/dev/null; rc=$?
|
||
|
+ if [ $rc -eq 124 ]; then
|
||
|
+ # TODO PRIO2: How to handle still hanging lss - current solution is to say "FATAL"
|
||
|
+ rc=0
|
||
|
+ fi
|
||
|
+ fi
|
||
|
return $rc;
|
||
|
}
|
||
|
|
||
|
#
|
||
|
# function: register_hana_secondary - register local hana as secondary to the other site
|
||
|
# params: -
|
||
|
-# globals: sidadm(r), remoteHost(r), InstanceNr(r), sr_mode(r), sr_name(r)
|
||
|
+# globals: sidadm(r), remoteHost(r), InstanceNr(r), sr_mode(r), sr_name(r), hdbver(r)
|
||
|
# register_hana_secondary
|
||
|
#
|
||
|
function register_hana_secondary()
|
||
|
@@ -1007,17 +1194,31 @@
|
||
|
super_ocf_log info "FLOW $FUNCNAME ($*)"
|
||
|
local rc=2;
|
||
|
local remoteInstance="";
|
||
|
+ local newParameter=0
|
||
|
remoteInstance=$InstanceNr
|
||
|
+
|
||
|
+
|
||
|
+ if version "$hdbver" ">=" "1.00.110"; then
|
||
|
+ newParameter=1
|
||
|
+ fi
|
||
|
+
|
||
|
if ocf_is_true ${AUTOMATED_REGISTER}; then
|
||
|
- #
|
||
|
- #
|
||
|
- #
|
||
|
- #
|
||
|
- #
|
||
|
- super_ocf_log info "ACT: REGISTER: hdbnsutil -sr_register --remoteHost=$remoteHost --remoteInstance=$remoteInstance --mode=$sr_mode --name=$sr_name"
|
||
|
- #
|
||
|
- #
|
||
|
- su - $sidadm -c "hdbnsutil -sr_register --remoteHost=$remoteHost --remoteInstance=$remoteInstance --mode=$sr_mode --name=$sr_name"; rc=$?
|
||
|
+ # TODO: Get rid of the su by using a new interface:
|
||
|
+ # SAPSYSTEMNAME=SLE /usr/sap/SLE/HDB00/HDBSettings.sh hdbnsutil -sr_register ...
|
||
|
+ # TODO: Check beginning from which SPS does SAP support HDBSettings.sh?
|
||
|
+ # TODO: Limit the runtime of hdbnsutil -sr_register ????
|
||
|
+ if [ $newParameter -eq 1 ]; then
|
||
|
+ local hanaOM=""
|
||
|
+ hanaOM=$(get_hana_attribute ${NODENAME} ${ATTR_NAME_HANA_OPERATION_MODE[@]})
|
||
|
+ if [ -n "$hanaOM" ]; then
|
||
|
+ hanaOM="--operationMode=$hanaOM"
|
||
|
+ fi
|
||
|
+ super_ocf_log info "ACT: REGISTER: hdbnsutil -sr_register --remoteHost=$remoteHost --remoteInstance=$remoteInstance --replicationMode=$sr_mode $hanaOM --name=$sr_name"
|
||
|
+ HANA_CALL --timeout inf --use-su --cmd "hdbnsutil -sr_register --remoteHost=$remoteHost --remoteInstance=$remoteInstance --replicationMode=$sr_mode $hanaOM --name=$sr_name"; rc=$?
|
||
|
+ else
|
||
|
+ super_ocf_log info "ACT: REGISTER: hdbnsutil -sr_register --remoteHost=$remoteHost --remoteInstance=$remoteInstance --mode=$sr_mode --name=$sr_name"
|
||
|
+ HANA_CALL --timeout inf --use-su --cmd "hdbnsutil -sr_register --remoteHost=$remoteHost --remoteInstance=$remoteInstance --mode=$sr_mode --name=$sr_name"; rc=$?
|
||
|
+ fi
|
||
|
# backup_global_and_nameserver
|
||
|
else
|
||
|
super_ocf_log info "ACT: SAPHANA DROP REGISTER because AUTOMATED_REGISTER is set to FALSE"
|
||
|
@@ -1051,7 +1252,7 @@
|
||
|
check_sapstartsrv
|
||
|
rc=$?
|
||
|
#
|
||
|
- # TODO: ASK: PRIO5: For SCALE-OUT - do we need to use an other call like StartSystem? Or better to use the HDB command?
|
||
|
+ # DONE: ASK: PRIO5: For SCALE-OUT - do we need to use an other call like StartSystem? Or better to use the HDB command?
|
||
|
#
|
||
|
if [ $rc -eq $OCF_SUCCESS ]; then
|
||
|
output=$($SAPCONTROL -nr $InstanceNr -function Start)
|
||
|
@@ -1169,7 +1370,7 @@
|
||
|
0 ) # LPA says start-up
|
||
|
lpa_advice="start"
|
||
|
# TODO: PRIO1: We need to do a special handling for remote being a 234-Secondary in SR Status SOK
|
||
|
- # if ( remote_role like [234]:S ) && ( remote_sync_status is SOK|PRIM ) && ( PreferSiteTakeover )
|
||
|
+ # if ( remote_role like [234]:S ) && ( remote_sync_status is SOK|PRIM ) && ( PreferSiteTakeover )
|
||
|
# then lpa_advice="wait"
|
||
|
remoteRole=$(get_hana_attribute $remoteNode ${ATTR_NAME_HANA_ROLES[@]})
|
||
|
remoteSync=$(get_hana_attribute $remoteNode ${ATTR_NAME_HANA_SYNC_STATUS[@]})
|
||
|
@@ -1193,17 +1394,20 @@
|
||
|
1) # LPA says register!
|
||
|
lpa_advice="register"
|
||
|
;;
|
||
|
- 2) # LPA says wait for second LPT
|
||
|
+ 2) # LPA says wait for older LPA to expire
|
||
|
+ lpa_advice="wait"
|
||
|
+ ;;
|
||
|
+ 3) # LPA says to wait for remote LPA to be reported/announced
|
||
|
lpa_advice="wait"
|
||
|
;;
|
||
|
- 3 | 4 ) # LPA says something is completely wrong - FAIL resource # TODO: PRIO1: RC3 for waiting remote side to report lss
|
||
|
+ 4) # LPA says something is completely wrong - FAIL resource # TODO: PRIO1: RC3 for waiting remote side to report lss
|
||
|
lpa_advice="fail"
|
||
|
;;
|
||
|
- * ) # LPA failed with an unkonown status - FAIL resource
|
||
|
+ *) # LPA failed with an unkonown status - FAIL resource
|
||
|
lpa_advice="fail"
|
||
|
;;
|
||
|
esac
|
||
|
-
|
||
|
+
|
||
|
# DONE: PRIO2: Do we need to differ 0 and 1 here? While 0 is a fatal SAP error, 1 for down/error
|
||
|
if [ $lss -eq 0 ]; then
|
||
|
super_ocf_log err "ACT: get_hana_landscape_status reports FATAL"
|
||
|
@@ -1218,7 +1422,7 @@
|
||
|
2 | 3 | 4 ) # as landcape says we are up - just set the scores and return code
|
||
|
super_ocf_log info "LPA: landcape: UP, LPA: start ==> keep running"
|
||
|
LPTloc=$(date '+%s')
|
||
|
- lpa_set_lpt $LPTloc
|
||
|
+ lpa_set_lpt $LPTloc $NODENAME
|
||
|
rc=$OCF_SUCCESS
|
||
|
;;
|
||
|
1 ) # landcape says we are down, lets start and adjust scores and return code
|
||
|
@@ -1226,7 +1430,7 @@
|
||
|
saphana_start
|
||
|
rc=$?
|
||
|
LPTloc=$(date '+%s')
|
||
|
- lpa_set_lpt $LPTloc
|
||
|
+ lpa_set_lpt $LPTloc $NODENAME
|
||
|
;;
|
||
|
esac
|
||
|
scoring_crm_master "$my_role" "$my_sync"
|
||
|
@@ -1250,11 +1454,11 @@
|
||
|
if [ $primary_status -eq $HANA_STATE_SECONDARY ]; then
|
||
|
super_ocf_log info "ACT: Register successful"
|
||
|
lpa_push_lpt 10
|
||
|
- lpa_set_lpt 10
|
||
|
+ lpa_set_lpt 10 $NODENAME
|
||
|
set_crm_master 0
|
||
|
saphana_start_secondary
|
||
|
rc=$?
|
||
|
- lpa_set_lpt 10
|
||
|
+ lpa_set_lpt 10 $NODENAME
|
||
|
else
|
||
|
super_ocf_log err "ACT: Register failed"
|
||
|
rc=$OCF_NOT_RUNNING
|
||
|
@@ -1279,11 +1483,19 @@
|
||
|
rc=$OCF_ERR_GENERIC
|
||
|
;;
|
||
|
1 ) # we are down, so we should wait --> followup in next monitor
|
||
|
- super_ocf_log info "LPA: landcape: DOWN, LPA: wait ==> keep waiting"
|
||
|
- # TODO: PRIO3: Check, if WAITING is correct here
|
||
|
- set_hana_attribute ${NODENAME} "WAITING4LPA" ${ATTR_NAME_HANA_CLONE_STATE[@]}
|
||
|
- set_crm_master -9000
|
||
|
- rc=$OCF_SUCCESS
|
||
|
+ # DONE: PRIO3: Check, if WAITING is correct here
|
||
|
+ if ocf_is_true "$AUTOMATED_REGISTER" ; then
|
||
|
+ super_ocf_log info "LPA: landcape: DOWN, LPA: wait ==> keep waiting"
|
||
|
+ super_ocf_log info "RA: landcape: DOWN, LPA: wait ==> keep waiting"
|
||
|
+ set_hana_attribute ${NODENAME} "WAITING4LPA" ${ATTR_NAME_HANA_CLONE_STATE[@]}
|
||
|
+ set_crm_master -9000
|
||
|
+ rc=$OCF_SUCCESS
|
||
|
+ else
|
||
|
+ super_ocf_log warning "LPA: OLD primary needs manual registration (AUTOMATED_REGISTER='false')"
|
||
|
+ set_hana_attribute ${NODENAME} "WAITING4REG" ${ATTR_NAME_HANA_CLONE_STATE[@]}
|
||
|
+ set_crm_master -9000
|
||
|
+ rc=$OCF_NOT_RUNNING
|
||
|
+ fi
|
||
|
;;
|
||
|
esac
|
||
|
;;
|
||
|
@@ -1309,22 +1521,24 @@
|
||
|
local ch ch_role
|
||
|
#
|
||
|
# get actual list of cluster members
|
||
|
- #
|
||
|
+ #
|
||
|
if [ -n "$otherNodes" ]; then
|
||
|
for ch in ${otherNodes[@]}; do
|
||
|
if [ $rc -eq 1 ]; then
|
||
|
ch_role=$(get_hana_attribute ${ch} ${ATTR_NAME_HANA_ROLES[@]})
|
||
|
-# TODO: PRIO3: check if [0-9], [234] or [34] is correct
|
||
|
-# TODO: PRIO4: Do we need different checks like "any-primary-master" or "running-primary-master" ?
|
||
|
-# grep '[0-9]*:P:[^:]*:master:' <<< $ch_role && rc=0
|
||
|
-# grep '[34]:P:[^:]*:master:' <<< $ch_role && rc=0
|
||
|
-# Match "Running+Available Primary" Master -> Match field 1: 3/4, 2: P, 4: master
|
||
|
- awk -F: 'BEGIN { rc=1 }
|
||
|
- $1 ~ "[34]" && $2 ="P" && $4="master" { rc=0 }
|
||
|
- END { exit rc }' <<< $ch_role ; rc=$?
|
||
|
+ # TODO: PRIO3: check if [0-9], [234] or [34] is correct
|
||
|
+ # TODO: PRIO4: Do we need different checks like "any-primary-master" or "running-primary-master" ?
|
||
|
+ # grep '[0-9]*:P:[^:]*:master:' <<< $ch_role && rc=0
|
||
|
+ # grep '[34]:P:[^:]*:master:' <<< $ch_role && rc=0
|
||
|
+ # Match "Running+Available Primary" Master -> Match field 1: 3/4, 2: P, 4: master
|
||
|
+ super_ocf_log debug "DBG: check_for_primary_master (3) ch_role=$ch_role"
|
||
|
+ awk -F: 'BEGIN { rc=1 }
|
||
|
+ $1 ~ "[34]" && $2 == "P" && $4 == "master" { rc=0 }
|
||
|
+ END { exit rc }' <<< $ch_role ; rc=$?
|
||
|
+ super_ocf_log debug "DBG: check_for_primary_master (4) rc=$rc"
|
||
|
fi
|
||
|
done
|
||
|
- fi
|
||
|
+ fi
|
||
|
super_ocf_log info "FLOW $FUNCNAME rc=$rc"
|
||
|
return $rc
|
||
|
}
|
||
|
@@ -1378,7 +1592,7 @@
|
||
|
####### LPA - begin
|
||
|
#
|
||
|
lpa_push_lpt 10
|
||
|
- lpa_set_lpt 10
|
||
|
+ lpa_set_lpt 10 $NODENAME
|
||
|
#
|
||
|
####### LPA - end
|
||
|
#
|
||
|
@@ -1404,7 +1618,7 @@
|
||
|
rc=$OCF_SUCCESS
|
||
|
fi
|
||
|
else
|
||
|
- lpa_set_lpt 10
|
||
|
+ lpa_set_lpt 10 $NODENAME
|
||
|
fi
|
||
|
else
|
||
|
super_ocf_log info "ACT: wait_for_primary_master ==> WAITING"
|
||
|
@@ -1454,7 +1668,7 @@
|
||
|
then
|
||
|
if [ $STATE -eq $OCF_NOT_RUNNING ]
|
||
|
then
|
||
|
- [ "$MONLOG" != "NOLOG" ] && ocf_log err "SAP instance service $SERVICE is not running with status $COLOR !"
|
||
|
+ [ "$MONLOG" != "NOLOG" ] && ocf_log err "SAP instance service $SERVICE status color is $COLOR !"
|
||
|
rc=$STATE
|
||
|
fi
|
||
|
count=1
|
||
|
@@ -1511,13 +1725,17 @@
|
||
|
local crm_rc=1
|
||
|
local lpt=$1
|
||
|
local clpt=-1
|
||
|
- local node=${2:-${NODENAME}}
|
||
|
+ local node=$2
|
||
|
set_hana_attribute ${node} "$lpt" ${LPA_ATTR[@]}; crm_rc=$?
|
||
|
- clpt=$(lpa_get_lpt $NODENAME)
|
||
|
- if [ "$lpt" != "$clpt" ]; then
|
||
|
- rc=2
|
||
|
+ if [ -n "$node" ]; then
|
||
|
+ clpt=$(lpa_get_lpt $NODENAME)
|
||
|
+ if [ "$lpt" != "$clpt" ]; then
|
||
|
+ rc=2
|
||
|
+ else
|
||
|
+ rc=0
|
||
|
+ fi
|
||
|
else
|
||
|
- rc=0
|
||
|
+ super_ocf_log info "DEC: lpa_set_lpt ignore to change value for empty node name"
|
||
|
fi
|
||
|
super_ocf_log info "FLOW $FUNCNAME rc=$rc"
|
||
|
return $rc
|
||
|
@@ -1608,7 +1826,7 @@
|
||
|
else
|
||
|
rc=2
|
||
|
fi
|
||
|
- lpa_set_lpt $LPTloc
|
||
|
+ lpa_set_lpt $LPTloc $NODENAME
|
||
|
super_ocf_log info "FLOW $FUNCNAME rc=$rc"
|
||
|
return $rc
|
||
|
}
|
||
|
@@ -1621,9 +1839,10 @@
|
||
|
#
|
||
|
# Returncodes:
|
||
|
# 0: start
|
||
|
-# 1: register than start
|
||
|
-# 2: wait4gab
|
||
|
-# 3: wait4other
|
||
|
+# 1: register (then start)
|
||
|
+# 2: wait4gab (WAIT4LPA - Older LPA needs to expire)
|
||
|
+# 3: wait4other (WAIT4LPA - Remote LPA needs to be announced)
|
||
|
+# 4: lpa internal error
|
||
|
#
|
||
|
# Initializing (if NO local LPT-file):
|
||
|
# SECONDARY sets to 10
|
||
|
@@ -1648,7 +1867,7 @@
|
||
|
#
|
||
|
function lpa_check_lpt_status() {
|
||
|
super_ocf_log info "FLOW $FUNCNAME ($*)"
|
||
|
- local rc=0
|
||
|
+ local rc=4
|
||
|
local LPTloc=-1
|
||
|
local LPTrem=-1
|
||
|
local LPTMark=1000
|
||
|
@@ -1666,16 +1885,16 @@
|
||
|
if [ -z "$LPTloc" -o "$LPTloc" -eq -1 -o "$lparc" -ne 0 ]; then
|
||
|
# last option - try to initialize as PRIMARY
|
||
|
lpa_push_lpt 20
|
||
|
- lpa_set_lpt 20
|
||
|
+ lpa_set_lpt 20 $NODENAME
|
||
|
LPTloc=20 # DEFAULT
|
||
|
fi
|
||
|
fi
|
||
|
- # TODO PRIO1: REMOVE remoteNode dependency - lpa_get_lpt
|
||
|
+ # TODO PRIO1: REMOVE remoteNode dependency - lpa_get_lpt
|
||
|
LPTrem=$(lpa_get_lpt $remoteNode); lparc=$?
|
||
|
if [ $lparc -ne 0 ]; then
|
||
|
# LPT of the other node could not be evaluated - LPA says WAIT
|
||
|
super_ocf_log debug "DBG: LPA: LPTloc=$LPTloc, LPTrem undefined ==> WAIT"
|
||
|
- rc=2
|
||
|
+ rc=3
|
||
|
else
|
||
|
super_ocf_log debug "DBG: LPA: LPTloc ($LPTloc) LPTrem ($LPTrem) delta ($delta)"
|
||
|
if [ $LPTloc -lt $LPTMark -a $LPTrem -lt $LPTMark ]; then
|
||
|
@@ -1683,11 +1902,11 @@
|
||
|
else
|
||
|
delta=$DUPLICATE_PRIMARY_TIMEOUT # at least one of the lpts is a real timestamp so include delta-gap
|
||
|
fi
|
||
|
- if (( delta < LPTloc - LPTrem )); then
|
||
|
+ if (( delta < LPTloc - LPTrem )); then
|
||
|
# We are the winner - LPA says STARTUP
|
||
|
super_ocf_log debug "DBG: LPA: LPTloc wins $LPTloc > $LPTrem + $delta ==> START"
|
||
|
rc=0
|
||
|
- elif (( delta < LPTrem - LPTloc )); then
|
||
|
+ elif (( delta < LPTrem - LPTloc )); then
|
||
|
if ocf_is_true "$AUTOMATED_REGISTER" ; then
|
||
|
# The other one has won - LPA says REGISTER
|
||
|
super_ocf_log debug "DBG: LPA: LPTrem wins $LPTrem > $LPTloc + $delta ==> REGISTER"
|
||
|
@@ -1697,12 +1916,12 @@
|
||
|
rc=2
|
||
|
fi
|
||
|
|
||
|
- else
|
||
|
+ else
|
||
|
super_ocf_log debug "DBG: LPA: Difference between LPTloc and LPTrem is less than delta ($delta) ==> WAIT"
|
||
|
# TODO: PRIO3: ADD STALEMATE-HANDLING HERE; currently admin should set one of the lpa to 20
|
||
|
rc=2
|
||
|
- fi
|
||
|
- fi
|
||
|
+ fi
|
||
|
+ fi
|
||
|
super_ocf_log info "FLOW $FUNCNAME rc=$rc"
|
||
|
return $rc
|
||
|
}
|
||
|
@@ -1716,6 +1935,7 @@
|
||
|
{
|
||
|
super_ocf_log info "FLOW $FUNCNAME ($*)"
|
||
|
local rc=0
|
||
|
+ # always true for scale-up
|
||
|
super_ocf_log info "FLOW $FUNCNAME rc=$rc"
|
||
|
return $rc
|
||
|
}
|
||
|
@@ -1728,23 +1948,15 @@
|
||
|
#
|
||
|
function saphana_start_clone() {
|
||
|
super_ocf_log info "FLOW $FUNCNAME ($*)"
|
||
|
- local primary_status sync_attr score_master rc=$OCF_NOT_RUNNING
|
||
|
+ local primary_status sync_attr score_master rc=$OCF_NOT_RUNNING
|
||
|
local sqlrc;
|
||
|
- local chkusr;
|
||
|
- # TODO: PRIO4: remove check_secstore_users later
|
||
|
- secUser=$(check_secstore_users SAPHANA${SID}SR SLEHALOC RHELHALOC) ; chkusr=$?
|
||
|
- if [ $chkusr -ne 0 ]; then
|
||
|
- super_ocf_log err "ACT: Secure store users are missing (see best practice manual how to setup the users)"
|
||
|
- rc=$OCF_ERR_CONFIGURED
|
||
|
+ set_hana_attribute ${NODENAME} "DEMOTED" ${ATTR_NAME_HANA_CLONE_STATE[@]}
|
||
|
+ check_for_primary; primary_status=$?
|
||
|
+ if [ $primary_status -eq $HANA_STATE_PRIMARY ]; then
|
||
|
+ saphana_start_primary; rc=$?
|
||
|
else
|
||
|
- set_hana_attribute ${NODENAME} "DEMOTED" ${ATTR_NAME_HANA_CLONE_STATE[@]}
|
||
|
- check_for_primary; primary_status=$?
|
||
|
- if [ $primary_status -eq $HANA_STATE_PRIMARY ]; then
|
||
|
- saphana_start_primary; rc=$?
|
||
|
- else
|
||
|
- lpa_set_lpt 10
|
||
|
- saphana_start_secondary; rc=$?
|
||
|
- fi
|
||
|
+ lpa_set_lpt 10 $NODENAME
|
||
|
+ saphana_start_secondary; rc=$?
|
||
|
fi
|
||
|
super_ocf_log info "FLOW $FUNCNAME rc=$rc"
|
||
|
return $rc
|
||
|
@@ -1761,9 +1973,10 @@
|
||
|
local rc=0
|
||
|
local primary_status="x"
|
||
|
set_hana_attribute ${NODENAME} "UNDEFINED" ${ATTR_NAME_HANA_CLONE_STATE[@]}
|
||
|
+ super_ocf_log debug "DBG: SET UNDEFINED"
|
||
|
check_for_primary; primary_status=$?
|
||
|
if [ $primary_status -eq $HANA_STATE_SECONDARY ]; then
|
||
|
- lpa_set_lpt 10
|
||
|
+ lpa_set_lpt 10 $NODENAME
|
||
|
fi
|
||
|
saphana_stop; rc=$?
|
||
|
return $rc
|
||
|
@@ -1813,26 +2026,42 @@
|
||
|
# seems admin already decided that for us? -> we are running - set DEMOTED
|
||
|
promoted=0;
|
||
|
LPTloc=$(date '+%s')
|
||
|
- lpa_set_lpt $LPTloc
|
||
|
+ lpa_set_lpt $LPTloc $NODENAME
|
||
|
fi
|
||
|
lpa_check_lpt_status; lparc=$?
|
||
|
- # TODO: PRIO1: Need to differ lpa_check_lpt_status return codes
|
||
|
- if [ $lparc -lt 2 ]; then
|
||
|
- # lpa - no need to wait any longer - lets try a new start
|
||
|
- saphana_start_clone
|
||
|
- rc=$?
|
||
|
- super_ocf_log info "FLOW $FUNCNAME rc=$rc"
|
||
|
- return $rc
|
||
|
- else
|
||
|
- lpa_init_lpt $HANA_STATE_PRIMARY
|
||
|
- # still waiting for second site to report lpa-lpt
|
||
|
- if ocf_is_true "$AUTOMATED_REGISTER" ; then
|
||
|
- super_ocf_log info "LPA: Still waiting for remote site to report LPA status"
|
||
|
- else
|
||
|
- super_ocf_log info "LPA: Dual primary detected and AUTOMATED_REGISTER='false' ==> WAITING"
|
||
|
- fi
|
||
|
- return $OCF_SUCCESS
|
||
|
- fi
|
||
|
+ # DONE: PRIO1: Need to differ lpa_check_lpt_status return codes
|
||
|
+ case "$lparc" in
|
||
|
+ 0 | 1 )
|
||
|
+ # lpa - no need to wait any longer - lets try a new start
|
||
|
+ saphana_start_clone
|
||
|
+ rc=$?
|
||
|
+ super_ocf_log info "FLOW $FUNCNAME rc=$rc"
|
||
|
+ return $rc
|
||
|
+ ;;
|
||
|
+ 2 )
|
||
|
+ lpa_init_lpt $HANA_STATE_PRIMARY
|
||
|
+ # still waiting for second site to expire
|
||
|
+ if ocf_is_true "$AUTOMATED_REGISTER" ; then
|
||
|
+ super_ocf_log info "LPA: Still waiting for remote site to report LPA status"
|
||
|
+ else
|
||
|
+ super_ocf_log info "LPA: Dual primary detected and AUTOMATED_REGISTER='false' ==> WAITING"
|
||
|
+ super_ocf_log info "LPA: You need to manually sr_register the older primary"
|
||
|
+ fi
|
||
|
+ return $OCF_SUCCESS
|
||
|
+ ;;
|
||
|
+ 3 )
|
||
|
+ lpa_init_lpt $HANA_STATE_PRIMARY
|
||
|
+ # still waiting for second site to report lpa-lpt
|
||
|
+ super_ocf_log info "LPA: Still waiting for remote site to report LPA status"
|
||
|
+ return $OCF_SUCCESS
|
||
|
+ ;;
|
||
|
+ 4 )
|
||
|
+ # lpa internal error
|
||
|
+ # TODO PRIO3: Impplement special handling for this issue - should we fail the ressource?
|
||
|
+ super_ocf_log info "LPA: LPA reports an internal error"
|
||
|
+ return $OCF_SUCCESS
|
||
|
+ ;;
|
||
|
+ esac
|
||
|
promoted=0;
|
||
|
;;
|
||
|
UNDEFINED )
|
||
|
@@ -1848,7 +2077,7 @@
|
||
|
;;
|
||
|
esac
|
||
|
fi
|
||
|
- get_hana_landscape_status; lss=$?
|
||
|
+ get_hana_landscape_status; lss=$?
|
||
|
super_ocf_log debug "DBG: saphana_monitor_clone: get_hana_landscape_status=$lss"
|
||
|
case "$lss" in
|
||
|
0 ) # FATAL or ERROR
|
||
|
@@ -1876,19 +2105,20 @@
|
||
|
#
|
||
|
# TODO PRIO1: REMOVE remoteNode dependency - get_sync_status
|
||
|
remoteSync=$(get_hana_attribute $remoteNode ${ATTR_NAME_HANA_SYNC_STATUS[@]})
|
||
|
+ # TODO HANDLING OF "NEVER"
|
||
|
case "$remoteSync" in
|
||
|
SOK | PRIM )
|
||
|
super_ocf_log info "DEC: PreferSiteTakeover selected so decrease promotion score here (and reset lpa)"
|
||
|
set_crm_master 5
|
||
|
if check_for_primary_master; then
|
||
|
- lpa_set_lpt 20
|
||
|
+ lpa_set_lpt 20 $NODENAME
|
||
|
fi
|
||
|
;;
|
||
|
SFAIL )
|
||
|
- super_ocf_log info "DEC: PreferSiteTakeover selected BUT remoteHost is not in sync (SFAIL) ==> local restart preferred"
|
||
|
+ super_ocf_log info "DEC: PreferSiteTakeover selected BUT remoteHost is not in sync (SFAIL) ==> local restart preferred"
|
||
|
;;
|
||
|
* )
|
||
|
- super_ocf_log info "DEC: PreferSiteTakeover selected BUT remoteHost is not in sync ($remoteSync) ==> local restart preferred"
|
||
|
+ super_ocf_log info "DEC: PreferSiteTakeover selected BUT remoteHost is not in sync ($remoteSync) ==> local restart preferred"
|
||
|
;;
|
||
|
esac
|
||
|
else
|
||
|
@@ -1916,7 +2146,7 @@
|
||
|
rc=$OCF_SUCCESS
|
||
|
else
|
||
|
LPTloc=$(date '+%s')
|
||
|
- lpa_set_lpt $LPTloc
|
||
|
+ lpa_set_lpt $LPTloc $NODENAME
|
||
|
lpa_push_lpt $LPTloc
|
||
|
if [ "$promoted" -eq 1 ]; then
|
||
|
set_hana_attribute "$NODENAME" "PRIM" ${ATTR_NAME_HANA_SYNC_STATUS[@]}
|
||
|
@@ -1931,12 +2161,14 @@
|
||
|
fi
|
||
|
my_sync=$(get_hana_attribute ${NODENAME} ${ATTR_NAME_HANA_SYNC_STATUS[@]})
|
||
|
my_role=$(get_hana_attribute ${NODENAME} ${ATTR_NAME_HANA_ROLES[@]})
|
||
|
- case "$my_role" in
|
||
|
+ case "$my_role" in
|
||
|
[12]:P:*:master:* ) # primary is down or may not anser hdbsql query so drop analyze_hana_sync_status
|
||
|
;;
|
||
|
[34]:P:*:*:* ) # primary is up and should now be able to anser hdbsql query
|
||
|
if [ -f $DIR_EXECUTABLE/python_support/systemReplicationStatus.py ]; then
|
||
|
- analyze_hana_sync_statusSRS
|
||
|
+ if [ "$promote_attr" = "PROMOTED" ]; then
|
||
|
+ analyze_hana_sync_statusSRS
|
||
|
+ fi
|
||
|
else
|
||
|
analyze_hana_sync_statusSQL
|
||
|
fi
|
||
|
@@ -1949,8 +2181,8 @@
|
||
|
[234]:P:* ) # dual primary, but other instance marked as PROMOTED by the cluster
|
||
|
lpa_check_lpt_status; again_lpa_rc=$?
|
||
|
if [ $again_lpa_rc -eq 2 ]; then
|
||
|
- super_ocf_log info "DEC: Dual primary detected, other instance is PROMOTED and lpa stalemate ==> local restart"
|
||
|
- lpa_set_lpt 10
|
||
|
+ super_ocf_log info "DEC: Dual primary detected, other instance is PROMOTED and lpa stalemate ==> local restart"
|
||
|
+ lpa_set_lpt 10 $NODENAME
|
||
|
lpa_push_lpt 10
|
||
|
rc=$OCF_NOT_RUNNING
|
||
|
fi
|
||
|
@@ -1993,7 +2225,7 @@
|
||
|
# OK, we are running as HANA SECONDARY
|
||
|
#
|
||
|
if ! lpa_get_lpt ${NODENAME}; then
|
||
|
- lpa_set_lpt 10
|
||
|
+ lpa_set_lpt 10 $NODENAME
|
||
|
lpa_push_lpt 10
|
||
|
fi
|
||
|
promote_attr=$(get_hana_attribute ${NODENAME} ${ATTR_NAME_HANA_CLONE_STATE[@]})
|
||
|
@@ -2042,17 +2274,25 @@
|
||
|
0 ) # FATAL
|
||
|
# DONE: PRIO1: Maybe we need to differ between 0 and 1. While 0 is a fatal sap error, 1 is down/error
|
||
|
# TODO: PRIO3: is OCF_ERR_GENERIC best option?
|
||
|
- lpa_set_lpt 10
|
||
|
+ lpa_set_lpt 10 $NODENAME
|
||
|
rc=$OCF_ERR_GENERIC
|
||
|
;;
|
||
|
1 ) # ERROR
|
||
|
- lpa_set_lpt 10
|
||
|
+ lpa_set_lpt 10 $NODENAME
|
||
|
rc=$OCF_NOT_RUNNING
|
||
|
;;
|
||
|
2 | 3 | 4 ) # WARN INFO OK
|
||
|
rc=$OCF_SUCCESS
|
||
|
- lpa_set_lpt 30
|
||
|
+ lpa_set_lpt 30 $NODENAME
|
||
|
sync_attr=$(get_hana_attribute ${NODENAME} ${ATTR_NAME_HANA_SYNC_STATUS[@]})
|
||
|
+ local hanaOM=""
|
||
|
+ local hanaOut1=""
|
||
|
+ # TODO: PRIO 3: check, if using getParameter.py is the best option to analyze the set operationMode
|
||
|
+ # DONE: PRIO 3: Should we default to logreplay for SAP HANA >= SPS11 ?
|
||
|
+ hanaOut1=$(HANA_CALL --timeout 10 --use-su --cmd "getParameter.py --key=global.ini/system_replication/operation_mode --sapcontrol=1")
|
||
|
+ hanaFilter1=$(echo "$hanaOut1" | awk -F/ 'BEGIN {out=0} /^SAPCONTROL-OK: <begin>/ { out=1 } /^SAPCONTROL-OK: <end>/ { out=0 } /=/ {if (out==1) {print $3} }')
|
||
|
+ hanaOM=$(echo "$hanaFilter1" | awk -F= '$1=="operation_mode" {print $2}')
|
||
|
+ set_hana_attribute ${NODENAME} "$hanaOM" ${ATTR_NAME_HANA_OPERATION_MODE[@]}
|
||
|
super_ocf_log debug "DBG: sync_attr=$sync_attr"
|
||
|
case "$sync_attr" in
|
||
|
"SOK" ) # This is a possible node to promote, when primary is missing
|
||
|
@@ -2112,7 +2352,7 @@
|
||
|
fi
|
||
|
#
|
||
|
# First check, if we are PRIMARY or SECONDARY
|
||
|
- #
|
||
|
+ #
|
||
|
check_for_primary; primary_status=$?
|
||
|
if [ $primary_status -eq $HANA_STATE_PRIMARY ]; then
|
||
|
# FIX: bsc#919925 Leaving Node Maintenance stops HANA Resource Agent
|
||
|
@@ -2145,7 +2385,7 @@
|
||
|
#
|
||
|
# function: saphana_promote_clone - promote a hana clone
|
||
|
# params: -
|
||
|
-# globals: OCF_*(r), NODENAME(r), HANA_STATE_*, SID(r), InstanceName(r),
|
||
|
+# globals: OCF_*(r), NODENAME(r), HANA_STATE_*, SID(r), InstanceName(r),
|
||
|
# saphana_promote_clone:
|
||
|
# In a Master/Slave configuration get Master being the primary OR by running hana takeover
|
||
|
#
|
||
|
@@ -2169,7 +2409,7 @@
|
||
|
else
|
||
|
if [ $primary_status -eq $HANA_STATE_SECONDARY ]; then
|
||
|
#
|
||
|
- # we are SECONDARY/SLAVE and need to takepover ...
|
||
|
+ # we are SECONDARY/SLAVE and need to takeover ... promote on the replica (secondary) side...
|
||
|
# promote on the replica side...
|
||
|
#
|
||
|
hana_sync=$(get_hana_attribute ${NODENAME} ${ATTR_NAME_HANA_SYNC_STATUS[@]})
|
||
|
@@ -2178,9 +2418,14 @@
|
||
|
super_ocf_log info "ACT: !!!!!!! Promote REPLICA $SID-$InstanceName to be primary. !!!!!!"
|
||
|
LPTloc=$(date '+%s')
|
||
|
# lpa_set_lpt 20 $remoteNode
|
||
|
- lpa_set_lpt $LPTloc
|
||
|
+ lpa_set_lpt $LPTloc $NODENAME
|
||
|
lpa_push_lpt $LPTloc
|
||
|
- su - $sidadm -c "hdbnsutil -sr_takeover"
|
||
|
+ # TODO: Get rid of the su by using a new interface:
|
||
|
+ # SAPSYSTEMNAME=SLE /usr/sap/SLE/HDB00/HDBSettings.sh hdbnsutil -sr_takeover ...
|
||
|
+ # TODO: Check beginning from which SPS does SAP support HDBSettings.sh?
|
||
|
+ # TODO: Limit the runtime of hdbnsutil -sr_takeover ????
|
||
|
+ # SAP_CALL
|
||
|
+ HANA_CALL --timeout inf --use-su --cmd "hdbnsutil -sr_takeover"
|
||
|
#
|
||
|
# now gain check, if we are primary NOW
|
||
|
#
|
||
|
@@ -2248,7 +2493,6 @@
|
||
|
SAPSTARTPROFILE=""
|
||
|
SAPHanaFilter="ra-act-dec-lpa"
|
||
|
|
||
|
-NODENAME=$(crm_node -n)
|
||
|
|
||
|
|
||
|
if [ $# -ne 1 ]
|
||
|
@@ -2306,8 +2550,7 @@
|
||
|
fi
|
||
|
|
||
|
# What kind of method was invoked?
|
||
|
-THE_VERSION=$(saphana_meta_data | grep '<version')
|
||
|
-super_ocf_log info "RA ==== begin action $ACTION$CLACT ($THE_VERSION) ===="
|
||
|
+super_ocf_log info "RA ==== begin action $ACTION$CLACT ($SAPHanaVersion) ===="
|
||
|
ra_rc=$OCF_ERR_UNIMPLEMENTED
|
||
|
case "$ACTION" in
|
||
|
start|stop|monitor|promote|demote) # Standard controling actions
|
||
|
@@ -2329,6 +2572,6 @@
|
||
|
esac
|
||
|
timeE=$(date '+%s')
|
||
|
(( timeR = timeE - timeB ))
|
||
|
-#super_ocf_log info "RA ==== SAPHanaFilter=$SAPHanaFilter"
|
||
|
-super_ocf_log info "RA ==== end action $ACTION$CLACT with rc=${ra_rc} ($THE_VERSION) (${timeR}s)===="
|
||
|
+super_ocf_log debug "DBG: ==== SAPHanaFilter=$SAPHanaFilter"
|
||
|
+super_ocf_log info "RA ==== end action $ACTION$CLACT with rc=${ra_rc} ($SAPHanaVersion) (${timeR}s)===="
|
||
|
exit ${ra_rc}
|
||
|
diff -uNr a/heartbeat/SAPHanaTopology b/heartbeat/SAPHanaTopology
|
||
|
--- a/heartbeat/SAPHanaTopology 2016-10-14 10:09:56.480051268 +0200
|
||
|
+++ b/heartbeat/SAPHanaTopology 2016-10-14 10:29:45.384831725 +0200
|
||
|
@@ -14,7 +14,7 @@
|
||
|
# Support: linux@sap.com
|
||
|
# License: GNU General Public License (GPL)
|
||
|
# Copyright: (c) 2014 SUSE Linux Products GmbH
|
||
|
-# (c) 2015 SUSE Linux GmbH
|
||
|
+# (c) 2015-2016 SUSE Linux GmbH
|
||
|
#
|
||
|
# An example usage:
|
||
|
# See usage() function below for more details...
|
||
|
@@ -23,17 +23,25 @@
|
||
|
# OCF_RESKEY_SID (LNX, NDB, SLE)
|
||
|
# OCF_RESKEY_InstanceNumber (00..99)
|
||
|
# OCF_RESKEY_DIR_EXECUTABLE (optional, well known directories will be searched by default)
|
||
|
-# OCF_RESKEY_SAPHanaFilter
|
||
|
+# OCF_RESKEY_SAPHanaFilter (outdated, replaced by cluster property hana_${sid}_glob_filter)
|
||
|
#
|
||
|
#######################################################################
|
||
|
#
|
||
|
# Initialization:
|
||
|
+SAPHanaVersion="0.152.17"
|
||
|
timeB=$(date '+%s')
|
||
|
|
||
|
: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
|
||
|
. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs
|
||
|
|
||
|
#######################################################################
|
||
|
+#
|
||
|
+log_attributes=false
|
||
|
+if ocf_is_true "$log_attributes"; then
|
||
|
+ log_attr_file="/var/log/fhATTRIBUTES"
|
||
|
+else
|
||
|
+ log_attr_file="/dev/null"
|
||
|
+fi
|
||
|
|
||
|
HANA_STATE_PRIMARY=0
|
||
|
HANA_STATE_SECONDARY=1
|
||
|
@@ -125,7 +133,7 @@
|
||
|
<?xml version="1.0"?>
|
||
|
<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
|
||
|
<resource-agent name="SAPHanaTopology">
|
||
|
- <version>0.151.1</version>
|
||
|
+ <version>$SAPHanaVersion</version>
|
||
|
<shortdesc lang="en">Analyzes SAP HANA System Replication Topology.</shortdesc>
|
||
|
<longdesc lang="en">This RA analyzes the SAP HANA topology and "sends" all findings via the node status attributes to
|
||
|
all nodes in the cluster. These attributes are taken by the SAPHana RA to control the SAP Hana Databases.
|
||
|
@@ -207,12 +215,12 @@
|
||
|
dstr=$(date)
|
||
|
case "$attr_store" in
|
||
|
reboot | forever )
|
||
|
- echo "$dstr: SAPHanaTopology: crm_attribute -N ${attr_node} -G -n \"$attr_name\" -l $attr_store -q" >> /var/log/fhATTRIBUTE
|
||
|
- crm_attribute -N ${attr_node} -G -n "$attr_name" -l $attr_store -q -d "$attr_default" 2>>/var/log/fhATTRIBUTE; rc=$?
|
||
|
+ echo "$dstr: SAPHanaTopology: crm_attribute -N ${attr_node} -G -n \"$attr_name\" -l $attr_store -q" >> $log_attr_file
|
||
|
+ crm_attribute -N ${attr_node} -G -n "$attr_name" -l $attr_store -q -d "$attr_default" 2>>$log_attr_file; rc=$?
|
||
|
;;
|
||
|
props )
|
||
|
- echo "$dstr: SAPHanaTopology: crm_attribute -G -n \"$attr_name\" -t crm_config -q" >> /var/log/fhATTRIBUTE
|
||
|
- crm_attribute -G -n "$attr_name" -t crm_config -q -d "$attr_default" 2>>/var/log/fhATTRIBUTE; rc=$?
|
||
|
+ echo "$dstr: SAPHanaTopology: crm_attribute -G -n \"$attr_name\" -t crm_config -q" >> $log_attr_file
|
||
|
+ crm_attribute -G -n "$attr_name" -t crm_config -q -d "$attr_default" 2>>$log_attr_file; rc=$?
|
||
|
;;
|
||
|
esac
|
||
|
super_ocf_log info "FLOW $FUNCNAME rc=$rc"
|
||
|
@@ -282,6 +290,53 @@
|
||
|
}
|
||
|
|
||
|
#
|
||
|
+# function: dequote - filter: remove quotes (") from stdin
|
||
|
+# params: -
|
||
|
+# globals: -
|
||
|
+function dequote()
|
||
|
+{
|
||
|
+ local rc=0; tr -d '"'; return $rc
|
||
|
+}
|
||
|
+
|
||
|
+# function: version: cpmpare two HANA version strings
|
||
|
+function ver_lt() {
|
||
|
+ ocf_version_cmp $1 $2
|
||
|
+ test $? -eq 0 && return 0 || return 1
|
||
|
+}
|
||
|
+
|
||
|
+function ver_le() {
|
||
|
+ ocf_version_cmp $1 $2
|
||
|
+ test $? -eq 0 -o $? -eq 1 && return 0 || return 1
|
||
|
+}
|
||
|
+
|
||
|
+function ver_gt() {
|
||
|
+ ocf_version_cmp $1 $2
|
||
|
+ test $? -eq 2 && return 0 || return 1
|
||
|
+}
|
||
|
+
|
||
|
+function ver_ge() {
|
||
|
+ ocf_version_cmp $1 $2
|
||
|
+ test $? -eq 2 -o $? -eq 1 && return 0 || return 1
|
||
|
+}
|
||
|
+#
|
||
|
+# function: version: cpmpare two HANA version strings
|
||
|
+#
|
||
|
+function version() {
|
||
|
+ if [ $# -eq 3 ]; then
|
||
|
+ case "$2" in
|
||
|
+ LE | le | "<=" ) ver_le $1 $3;;
|
||
|
+ LT | lt | "<" ) ver_lt $1 $3;;
|
||
|
+ GE | ge | ">=" ) ver_ge $1 $3;;
|
||
|
+ GT | gt | ">" ) ver_gt $1 $3;;
|
||
|
+ * ) return 1;
|
||
|
+ esac
|
||
|
+ elif [ $# -ge 5 ]; then
|
||
|
+ version $1 $2 $3 && shift 2 && version $*
|
||
|
+ else
|
||
|
+ return 1;
|
||
|
+ fi
|
||
|
+}
|
||
|
+#
|
||
|
# function: is_clone - report, if resource is configured as a clone (also master/slave)
|
||
|
# params: -
|
||
|
# globals: OCF_*(r)
|
||
|
@@ -314,12 +369,74 @@
|
||
|
}
|
||
|
|
||
|
#
|
||
|
+# function: HANA_CALL
|
||
|
+# params: timeout-in-seconds cmd-line
|
||
|
+# globals: sid(r), SID(r), InstanceName(r)
|
||
|
+#
|
||
|
+function HANA_CALL()
|
||
|
+{
|
||
|
+ #
|
||
|
+ # TODO: PRIO 5: remove 'su - ${sidadm} later, when SAP HANA resoled issue with
|
||
|
+ # root-user-called hdbnsutil -sr_state (which creates root-owned shared memory file in /var/lib/hdb/SID/shmgrp)
|
||
|
+ # TODO: PRIO 5: Maybe make "su" optional by a parameter
|
||
|
+ local timeOut=0
|
||
|
+ local onTimeOut=""
|
||
|
+ local rc=0
|
||
|
+ local use_su=1 # Default to be changed later (see TODO above)
|
||
|
+ local pre_cmd=""
|
||
|
+ local cmd=""
|
||
|
+ local pre_script=""
|
||
|
+ local output=""
|
||
|
+ while [ $# -gt 0 ]; do
|
||
|
+ case "$1" in
|
||
|
+ --timeout ) timeOut=$2; shift;;
|
||
|
+ --use-su ) use_su=1;;
|
||
|
+ --on-timeout ) onTimeOut="$2"; shift;;
|
||
|
+ --cmd ) shift; cmd="$*"; break;;
|
||
|
+ esac
|
||
|
+ shift
|
||
|
+ done
|
||
|
+
|
||
|
+ if [ $use_su -eq 1 ]; then
|
||
|
+ pre_cmd="su - ${sid}adm -c"
|
||
|
+ pre_script="true"
|
||
|
+ else
|
||
|
+ # as root user we need the library path to the SAP kernel to be able to call sapcontrol
|
||
|
+ # check, if we already added DIR_EXECUTABLE at the beginning of LD_LIBRARY_PATH
|
||
|
+ if [ "${LD_LIBRARY_PATH%%*:}" != "$DIR_EXECUTABLE" ]
|
||
|
+ then
|
||
|
+ MY_LD_LIBRARY_PATH=$DIR_EXECUTABLE${LD_LIBRARY_PATH:+:}$LD_LIBRARY_PATH
|
||
|
+ fi
|
||
|
+ pre_cmd="bash -c"
|
||
|
+ pre_script="LD_LIBRARY_PATH=$MY_LD_LIBRARY_PATH; export LD_LIBRARY_PATH"
|
||
|
+ fi
|
||
|
+ case $timeout in
|
||
|
+ 0 | inf )
|
||
|
+ output=$($pre_cmd "$pre_script; /usr/sap/$SID/$InstanceName/HDBSettings.sh $cmd"); rc=$?
|
||
|
+ ;;
|
||
|
+ * )
|
||
|
+ output=$(timeout $timeOut $pre_cmd "$pre_script; /usr/sap/$SID/$InstanceName/HDBSettings.sh $cmd"); rc=$?
|
||
|
+ #
|
||
|
+ # on timeout ...
|
||
|
+ #
|
||
|
+ if [ $rc -eq 124 -a -n "$onTimeOut" ]; then
|
||
|
+ local second_output=""
|
||
|
+ second_output=$($pre_cmd "$pre_script; /usr/sap/$SID/$InstanceName/HDBSettings.sh $onTimeOut");
|
||
|
+ fi
|
||
|
+ ;;
|
||
|
+ esac
|
||
|
+ echo "$output"
|
||
|
+ return $rc;
|
||
|
+}
|
||
|
+
|
||
|
+#
|
||
|
# function: sht_init - initialize variables for the resource agent
|
||
|
# params: -
|
||
|
# globals: OCF_*(r), SID(w), sid(rw), sidadm(w), InstanceName(w), InstanceNr(w),
|
||
|
-# globals: meta_notify_master_uname(w), HANA_SR_TOLOPOGY(w), sr_name(w), remoteHost(w)
|
||
|
+# globals: meta_notify_master_uname(w), HANA_SR_TOLOPOGY(w), sr_name(w)
|
||
|
# globals: ATTR_NAME_HANA_SYNC_STATUS(w), ATTR_NAME_HANA_PRIMARY_AT(w), ATTR_NAME_HANA_CLONE_STATE(w)
|
||
|
# globals: DIR_EXECUTABLE(w), SAPSTARTSRV(w), SAPCONTROL(w), DIR_PROFILE(w), SAPSTARTPROFILE(w), LD_LIBRARY_PATH(w), PATH(w), nodelist(w)
|
||
|
+# globals: NODENAME(w), hdbver(w)
|
||
|
# sht_init : Define global variables with default values, if optional parameters are not set
|
||
|
#
|
||
|
#
|
||
|
@@ -331,12 +448,14 @@
|
||
|
local hdbANSWER=""
|
||
|
local siteID
|
||
|
local siteNAME
|
||
|
+ local chkMethod=""
|
||
|
HOSTEXECNAME=saphostexec
|
||
|
USRSAP=/usr/sap
|
||
|
SAPSERVICE_PATH=${USRSAP}/sapservices
|
||
|
SAPHOSTCTRL_PATH=${USRSAP}/hostctrl/exe
|
||
|
HOSTEXEC_PATH=${SAPHOSTCTRL_PATH}/${HOSTEXECNAME}
|
||
|
HOSTEXEC_PROFILE_PATH=${SAPHOSTCTRL_PATH}/host_profile
|
||
|
+ NODENAME=$(crm_node -n)
|
||
|
SID=$OCF_RESKEY_SID
|
||
|
InstanceNr=$OCF_RESKEY_InstanceNumber
|
||
|
myInstanceName="${SID}_HDB${InstanceNr}"
|
||
|
@@ -382,13 +501,6 @@
|
||
|
DIR_PROFILE="$OCF_RESKEY_DIR_PROFILE"
|
||
|
fi
|
||
|
|
||
|
- # as root user we need the library path to the SAP kernel to be able to call sapcontrol
|
||
|
- # check, if we already added DIR_EXECUTABLE at the beginning of LD_LIBRARY_PATH
|
||
|
- if [ "${LD_LIBRARY_PATH%%*:}" != "$DIR_EXECUTABLE" ]
|
||
|
- then
|
||
|
- LD_LIBRARY_PATH=$DIR_EXECUTABLE${LD_LIBRARY_PATH:+:}$LD_LIBRARY_PATH
|
||
|
- export LD_LIBRARY_PATH
|
||
|
- fi
|
||
|
|
||
|
PATH=${PATH}:${DIR_EXECUTABLE}
|
||
|
#
|
||
|
@@ -399,12 +511,45 @@
|
||
|
*openais* ) nodelist=$(crm_node -l | awk '/member/ {print $2}');;
|
||
|
*cman* ) nodelist=$(crm_node -l);;
|
||
|
esac
|
||
|
+ #
|
||
|
+ # get HANA version
|
||
|
+ #
|
||
|
+ local ges_ver
|
||
|
+ ges_ver=$(HANA_CALL --timeout 10 --cmd "HDB version" | tr -d " " | awk -F: '$1 == "version" {print $2}')
|
||
|
+ hdbver=${ges_ver%.*.*}
|
||
|
+ #
|
||
|
+ # since rev 111.00 we should use a new hdbnsutil option to get the -sr_state
|
||
|
+ # since rev 112.03 the old option is changed and we should use -sr_stateConfiguration where ever possible
|
||
|
+ #
|
||
|
+ hdbState="hdbnsutil -sr_state"
|
||
|
+ hdbMap="hdbnsutil -sr_state"
|
||
|
+ if version "$hdbver" ">=" "1.00.111"; then
|
||
|
+ hdbState="hdbnsutil -sr_stateConfiguration"
|
||
|
+ hdbMap="hdbnsutil -sr_stateHostMapping"
|
||
|
+ fi
|
||
|
#### SAP-CALL
|
||
|
# hdbnsutil was a bit unstable in some tests so we recall the tool, if it fails to report the srmode
|
||
|
- for i in 1 2 3 4 5 6 7 8 9; do
|
||
|
- hdbANSWER=$(su - ${sidadm} -c "hdbnsutil -sr_state --sapcontrol=1" 2>/dev/null)
|
||
|
- super_ocf_log debug "DBG2: hdbANSWER=\$\(su - ${sidadm} -c \"hdbnsutil -sr_state --sapcontrol=1\"\)"
|
||
|
- srmode=$(echo "$hdbANSWER" | awk -F= '/mode/ {print $2}')
|
||
|
+ for chkMethod in hU hU hU gP ; do
|
||
|
+ # DONE: Limit the runtime of hdbnsutil.
|
||
|
+ # TODO: Use getParameter.py if we get no answer
|
||
|
+ # SAP_CALL
|
||
|
+ #super_ocf_log debug "DBG2: hdbANSWER=$hdbANSWER"
|
||
|
+ #srmode=$(echo "$hdbANSWER" | awk -F= '/mode/ {print $2}')
|
||
|
+ case "$chkMethod" in
|
||
|
+ gP ) # call getParameter (gP)
|
||
|
+ local gpKeys=""
|
||
|
+ gpKeys=$(echo --key=global.ini/system_replication/{mode,site_name,site_id})
|
||
|
+ hdbANSWER=$(HANA_CALL --timeout 60 --cmd "HDBSettings.sh getParameter.py $gpKeys --sapcontrol=1" 2>&1 | awk -F/ 'BEGIN {out=0} /^SAPCONTROL-OK: <begin>/ { out=1 } /^SAPCONTROL-OK: <end>/ { out=0 } /=/ {if (out==1) {print $3} }')
|
||
|
+ srmode=$(echo "$hdbANSWER" | awk -F= '$1=="mode" {print $2}')
|
||
|
+ super_ocf_log info "ACT: hdbnsutil not answering - using global.ini as fallback - srmode=$srmode"
|
||
|
+ ;;
|
||
|
+ hU | * ) # call hdbnsUtil (hU) ( also for unknown chkMethod )
|
||
|
+ # DONE: PRIO1: Begginning from SAP HANA rev 112.03 -sr_state is not longer supported
|
||
|
+ hdbANSWER=$(HANA_CALL --timeout 60 --cmd "$hdbState --sapcontrol=1" 2>/dev/null)
|
||
|
+ super_ocf_log debug "DBG2: hdbANSWER=$hdbANSWER"
|
||
|
+ srmode=$(echo "$hdbANSWER" | awk -F= '$1=="mode" {print $2}')
|
||
|
+ ;;
|
||
|
+ esac
|
||
|
case "$srmode" in
|
||
|
primary | syncmem | sync | async | none )
|
||
|
# we can leave the loop as we already got a result
|
||
|
@@ -417,27 +562,51 @@
|
||
|
esac
|
||
|
done
|
||
|
# TODO PRIO3: Implement a file lookup, if we did not get a result
|
||
|
- siteID=$(echo "$hdbANSWER" | awk -F= '/site id/ {print $2}')
|
||
|
- siteNAME=$(echo "$hdbANSWER" | awk -F= '/site name/ {print $2}')
|
||
|
+ siteID=$(echo "$hdbANSWER" | awk -F= '/site.id/ {print $2}') # allow 'site_id' AND 'site id'
|
||
|
+ siteNAME=$(echo "$hdbANSWER" | awk -F= '/site.name/ {print $2}')
|
||
|
site=$siteNAME
|
||
|
srmode=$(echo "$hdbANSWER" | awk -F= '/mode/ {print $2}')
|
||
|
- MAPPING=$(echo "$hdbANSWER" | awk -F[=/] '$1 ~ "mapping" && $3 !~ site { print $4 }' site=$site)
|
||
|
- super_ocf_log debug "DBG: site=$site, mode=$srmode, MAPPING=$MAPPING"
|
||
|
#
|
||
|
- # filter all non-cluster mappings
|
||
|
+ # for rev >= 111 we use the new mapping query
|
||
|
#
|
||
|
- # DONE: PRIO2: Need mapping between HANA HOSTS not cluster NODES
|
||
|
- local hanaVHost
|
||
|
- hanaRemoteHost=$(for n1 in $nodelist; do
|
||
|
- hanaVHost=$(get_hana_attribute ${n1} ${ATTR_NAME_HANA_VHOST[@]})
|
||
|
- for n2 in $MAPPING; do
|
||
|
- if [ "$hanaVHost" == "$n2" ]; then
|
||
|
- echo $hanaVHost;
|
||
|
- fi;
|
||
|
- done;
|
||
|
- done )
|
||
|
- super_ocf_log info "DEC: site=$site, mode=$srmode, MAPPING=$MAPPING, hanaRemoteHost=$hanaRemoteHost"
|
||
|
- super_ocf_log debug "DBG: site=$site, mode=$srmode, MAPPING=$MAPPING, hanaRemoteHost=$hanaRemoteHost"
|
||
|
+ if version "$hdbver" ">=" "1.00.111"; then
|
||
|
+ hdbANSWER=$(HANA_CALL --timeout 60 --cmd "$hdbMap --sapcontrol=1" 2>/dev/null)
|
||
|
+ fi
|
||
|
+ MAPPING=$(echo "$hdbANSWER" | awk -F[=/] '$1 == "mapping" && $3 != site { print $4 }' site=$site)
|
||
|
+ super_ocf_log debug "DBG: site=$site, mode=$srmode, MAPPING=$MAPPING"
|
||
|
+ if [ -n "$MAPPING" ]; then
|
||
|
+ # we have a mapping from HANA, lets use it
|
||
|
+ #
|
||
|
+ # filter all non-cluster mappings
|
||
|
+ #
|
||
|
+ local hanaVHost=""
|
||
|
+ local n1=""
|
||
|
+ hanaRemoteHost=""
|
||
|
+ for n1 in $nodelist; do
|
||
|
+ hanaVHost=$(get_hana_attribute ${n1} ${ATTR_NAME_HANA_VHOST[@]})
|
||
|
+ for n2 in $MAPPING; do
|
||
|
+ if [ "$hanaVHost" == "$n2" ]; then
|
||
|
+ hanaRemoteHost="$hanaVHost"
|
||
|
+ fi;
|
||
|
+ done;
|
||
|
+ done
|
||
|
+ super_ocf_log info "DEC: site=$site, mode=$srmode, MAPPING=$MAPPING, hanaRemoteHost=$hanaRemoteHost"
|
||
|
+ super_ocf_log debug "DBG: site=$site, mode=$srmode, MAPPING=$MAPPING, hanaRemoteHost=$hanaRemoteHost"
|
||
|
+ else
|
||
|
+ # HANA DID NOT TOLD THE MAPPING, LETS TRY TO USE THE SITE ATTRIBUTES
|
||
|
+ local n1=""
|
||
|
+ local hanaSite=""
|
||
|
+ for n1 in $nodelist; do
|
||
|
+ # TODO: PRIO9 - For multi tier with more than 2 chain/star members IN the cluster we might need to be
|
||
|
+ # able to catch more than one remoteHost
|
||
|
+ # currently having more than 2 HANA in a chain/star members IN the cluster is not allowed, the third must be external
|
||
|
+ if [ "$NODENAME" != "$n1" ]; then
|
||
|
+ hanaSite=$(get_hana_attribute ${n1} ${ATTR_NAME_HANA_SITE[@]})
|
||
|
+ hanaRemoteHost="$n1"
|
||
|
+ fi
|
||
|
+ done
|
||
|
+ super_ocf_log info "DEC: site=$site, mode=$srmode, hanaRemoteHost=$hanaRemoteHost - found by remote site ($hanaSite)"
|
||
|
+ fi
|
||
|
super_ocf_log info "FLOW $FUNCNAME rc=$OCF_SUCCESS"
|
||
|
return $OCF_SUCCESS
|
||
|
}
|
||
|
@@ -446,38 +615,29 @@
|
||
|
# function: check_for_primary - check if local SAP HANA is configured as primary
|
||
|
# params: -
|
||
|
# globals: HANA_STATE_PRIMARY(r), HANA_STATE_SECONDARY(r), HANA_STATE_DEFECT(r), HANA_STATE_STANDALONE(r)
|
||
|
+# srmode(r)
|
||
|
#
|
||
|
function check_for_primary() {
|
||
|
super_ocf_log info "FLOW $FUNCNAME ($*)"
|
||
|
local rc=0
|
||
|
- node_status=$srmode
|
||
|
- super_ocf_log debug "DBG2: check_for_primary: node_status=$node_status"
|
||
|
- super_ocf_log debug "DBG: check_for_primary: node_status=$node_status"
|
||
|
- for i in 1 2 3 4 5 6 7 8 9; do
|
||
|
- case "$node_status" in
|
||
|
- primary )
|
||
|
- super_ocf_log info "FLOW $FUNCNAME rc=HANA_STATE_PRIMARY"
|
||
|
- return $HANA_STATE_PRIMARY;;
|
||
|
- syncmem | sync | async )
|
||
|
- super_ocf_log info "FLOW $FUNCNAME rc=HANA_STATE_SECONDARY"
|
||
|
- return $HANA_STATE_SECONDARY;;
|
||
|
- none ) # have seen that mode on second side BEFEORE we registered it as replica
|
||
|
- super_ocf_log info "FLOW $FUNCNAME rc=HANA_STATE_STANDALONE"
|
||
|
- return $HANA_STATE_STANDALONE;;
|
||
|
- * )
|
||
|
- # TODO: PRIO1: Should we set SFAIL?
|
||
|
- # TODO: PRIO2: Maybe we need to keep the old value for P/S/N, if hdbnsutil just crashes
|
||
|
- dump=$( echo $node_status | hexdump -C );
|
||
|
- super_ocf_log err "ACT: check_for_primary: we didn't expect node_status to be: DUMP: <$dump>"
|
||
|
- #### SAP-CALL
|
||
|
- node_full_status=$(su - ${sidadm} -c "hdbnsutil -sr_state" 2>/dev/null )
|
||
|
- node_status=$(echo "$node_full_status" | awk '$1=="mode:" {print $2}')
|
||
|
- super_ocf_log info "DEC: check_for_primary: loop=$i: node_status=$node_status"
|
||
|
- # TODO: PRIO1: Maybe we need to keep the old value for P/S/N, if hdbnsutil just crashes
|
||
|
- esac;
|
||
|
- done
|
||
|
- super_ocf_log info "FLOW $FUNCNAME rc=HANA_STATE_DEFECT"
|
||
|
- return $HANA_STATE_DEFECT
|
||
|
+ super_ocf_log debug "DBG: check_for_primary: srmode=$srmode"
|
||
|
+ case "$srmode" in
|
||
|
+ primary )
|
||
|
+ super_ocf_log info "FLOW $FUNCNAME rc=HANA_STATE_PRIMARY"
|
||
|
+ rc=$HANA_STATE_PRIMARY;;
|
||
|
+ syncmem | sync | async )
|
||
|
+ super_ocf_log info "FLOW $FUNCNAME rc=HANA_STATE_SECONDARY"
|
||
|
+ rc=$HANA_STATE_SECONDARY;;
|
||
|
+ none ) # have seen that mode on second side BEFEORE we registered it as replica
|
||
|
+ super_ocf_log info "FLOW $FUNCNAME rc=HANA_STATE_STANDALONE"
|
||
|
+ rc=$HANA_STATE_STANDALONE;;
|
||
|
+ * )
|
||
|
+ dump=$( echo $srmode | hexdump -C );
|
||
|
+ super_ocf_log err "ACT: check_for_primary: we didn't expect srmode to be: DUMP: <$dump>"
|
||
|
+ rc=$HANA_STATE_DEFECT
|
||
|
+ esac;
|
||
|
+ super_ocf_log info "FLOW $FUNCNAME rc=$rc"
|
||
|
+ return $rc
|
||
|
}
|
||
|
|
||
|
|
||
|
@@ -653,7 +813,7 @@
|
||
|
function sht_stop_clone() {
|
||
|
super_ocf_log info "FLOW $FUNCNAME ($*)"
|
||
|
local rc=0
|
||
|
- check_for_primary; primary_status=$?
|
||
|
+ check_for_primary; primary_status=$?
|
||
|
if [ $primary_status -eq $HANA_STATE_PRIMARY ]; then
|
||
|
hanaPrim="P"
|
||
|
elif [ $primary_status -eq $HANA_STATE_SECONDARY ]; then
|
||
|
@@ -663,7 +823,7 @@
|
||
|
else
|
||
|
hanaPrim="-"
|
||
|
fi
|
||
|
- set_hana_attribute "${NODENAME}" "1:$hanaPrim:-:-:-:-" ${ATTR_NAME_HANA_ROLES[@]}
|
||
|
+ set_hana_attribute "${NODENAME}" "1:$hanaPrim:-:-:-:-" ${ATTR_NAME_HANA_ROLES[@]}
|
||
|
sht_stop; rc=$?
|
||
|
return $rc
|
||
|
}
|
||
|
@@ -718,28 +878,49 @@
|
||
|
fi
|
||
|
# DONE: PRIO1: ASK: Is the output format of ListInstances fix? Could we take that as an API?
|
||
|
# try to catch: Inst Info : LNX - 42 - lv9041 - 740, patch 36, changelist 1444691
|
||
|
- # We rely on the following format: SID is word#4, NR is work#6, vHost is word#8
|
||
|
+ # We rely on the following format: SID is word#4, SYSNR is word#6, vHost is word#8
|
||
|
#### SAP-CALL
|
||
|
vName=$(/usr/sap/hostctrl/exe/saphostctrl -function ListInstances \
|
||
|
- | awk '$4 == SID && $6=NR { print $8 }' SID=$SID NR=$InstanceNr 2>/dev/null )
|
||
|
+ | awk '$4 == SID && $6 == SYSNR { print $8 }' SID=$SID SYSNR=$InstanceNr 2>/dev/null )
|
||
|
# super_ocf_log debug "DBG: ListInstances: $(/usr/sap/hostctrl/exe/saphostctrl -function ListInstances)"
|
||
|
if [ -n "$vName" ]; then
|
||
|
- set_hana_attribute ${NODENAME} "$vName" ${ATTR_NAME_HANA_VHOST[@]}
|
||
|
+ set_hana_attribute ${NODENAME} "$vName" ${ATTR_NAME_HANA_VHOST[@]}
|
||
|
else
|
||
|
vName=$(get_hana_attribute ${NODENAME} ${ATTR_NAME_HANA_VHOST[@]})
|
||
|
fi
|
||
|
#site=$(get_site_name)
|
||
|
#### SAP-CALL
|
||
|
- hanaANSWER=$(su - $sidadm -c "python exe/python_support/landscapeHostConfiguration.py" 2>/dev/null); hanalrc="$?"
|
||
|
- hanarole=$(echo "$hanaANSWER" | tr -d ' ' | awk -F'|' '$2 == host { printf "%s:%s:%s:%s\n",$10,$11,$12,$13 } ' host=${vName})
|
||
|
+ # SAP_CALL
|
||
|
+ #hanaANSWER=$(su - $sidadm -c "python exe/python_support/landscapeHostConfiguration.py" 2>/dev/null); hanalrc="$?"
|
||
|
+ #
|
||
|
+ # since rev 09x SAP has added the --sapcontrol option for the landscapeHostConfiguration interface
|
||
|
+ # we begin to use --sapcontrol with rev 100
|
||
|
+ # since rev 120 we need to use the --sapcontrol, because SAP changed the tool output
|
||
|
+ #
|
||
|
+ if version "$hdbver" ">=" "1.00.100"; then
|
||
|
+ hanaANSWER=$(HANA_CALL --timeout 60 --cmd "landscapeHostConfiguration.py --sapcontrol=1" 2>/dev/null); hanalrc="$?"
|
||
|
+ # TODO: PRIO9: Do we need to check the lines: 'SAPCONTROL-OK: <begin>' and 'SAPCONTROL-OK: <end>'?
|
||
|
+ hanarole=$(echo "$hanaANSWER" | tr -d ' ' | \
|
||
|
+ awk -F= '$1 == "nameServerConfigRole" {f1=$2}
|
||
|
+ $1 == "nameServerActualRole" {f2=$2}
|
||
|
+ $1 == "indexServerConfigRole" {f3=$2}
|
||
|
+ $1 == "indexServerActualRole" {f4=$2}
|
||
|
+ END { printf "%s:%s:%s:%s\n", f1, f2, f3,f4 }')
|
||
|
+ else
|
||
|
+ #
|
||
|
+ # old code for backward compatability
|
||
|
+ #
|
||
|
+ hanaANSWER=$(HANA_CALL --timeout 60 --cmd "landscapeHostConfiguration.py" 2>/dev/null); hanalrc="$?"
|
||
|
+ hanarole=$(echo "$hanaANSWER" | tr -d ' ' | awk -F'|' '$2 == host { printf "%s:%s:%s:%s\n",$10,$11,$12,$13 } ' host=${vName})
|
||
|
+ fi
|
||
|
#if [ -z "$MAPPING" ]; then
|
||
|
# super_ocf_log info "ACT: Did not find remote Host at this moment"
|
||
|
#fi
|
||
|
# FH TODO PRIO3: TRY TO GET RID OF "ATTR_NAME_HANA_REMOTEHOST"
|
||
|
if [ -n "$hanaRemoteHost" ]; then
|
||
|
- set_hana_attribute ${NODENAME} "$hanaRemoteHost" ${ATTR_NAME_HANA_REMOTEHOST[@]}
|
||
|
+ set_hana_attribute ${NODENAME} "$hanaRemoteHost" ${ATTR_NAME_HANA_REMOTEHOST[@]}
|
||
|
fi
|
||
|
- set_hana_attribute ${NODENAME} "$hanalrc:$hanaPrim:$hanarole" ${ATTR_NAME_HANA_ROLES[@]}
|
||
|
+ set_hana_attribute ${NODENAME} "$hanalrc:$hanaPrim:$hanarole" ${ATTR_NAME_HANA_ROLES[@]}
|
||
|
if [ -n "$site" ]; then
|
||
|
set_hana_attribute ${NODENAME} "$site" ${ATTR_NAME_HANA_SITE[@]}
|
||
|
fi
|
||
|
@@ -748,8 +929,8 @@
|
||
|
S ) # only secondary may propargate its sync status
|
||
|
case $(crm_attribute --type crm_config --name cluster-infrastructure -q) in
|
||
|
*corosync* ) nodelist=$(crm_node -l | awk '{ print $2 }');;
|
||
|
- *openais* ) nodelist=$(crm_node -l | awk '/member/ {print $2}');;
|
||
|
- *cman* ) nodelist=$(crm_node -l);;
|
||
|
+ *openais* ) nodelist=$(crm_node -l | awk '/member/ {print $2}');;
|
||
|
+ *cman* ) nodelist=$(crm_node -l);;
|
||
|
esac
|
||
|
|
||
|
for n in ${nodelist}; do
|
||
|
@@ -789,7 +970,6 @@
|
||
|
InstanceNr=""
|
||
|
DIR_EXECUTABLE=""
|
||
|
SAPHanaFilter="ra-act-dec-lpa"
|
||
|
-NODENAME=$(crm_node -n)
|
||
|
|
||
|
if [ $# -ne 1 ]
|
||
|
then
|
||
|
@@ -846,8 +1026,7 @@
|
||
|
fi
|
||
|
fi
|
||
|
|
||
|
-THE_VERSION=$(sht_meta_data | grep '<version')
|
||
|
-super_ocf_log info "RA ==== begin action $ACTION$CLACT ($THE_VERSION) ===="
|
||
|
+super_ocf_log info "RA ==== begin action $ACTION$CLACT ($SAPHanaVersion) ===="
|
||
|
ra_rc=$OCF_ERR_UNIMPLEMENTED
|
||
|
case "$ACTION" in
|
||
|
start|stop|monitor) # Standard controling actions
|
||
|
@@ -865,5 +1044,5 @@
|
||
|
esac
|
||
|
timeE=$(date '+%s')
|
||
|
(( timeR = timeE - timeB ))
|
||
|
-super_ocf_log info "RA ==== end action $ACTION$CLACT with rc=${ra_rc} ($THE_VERSION) (${timeR}s)===="
|
||
|
+super_ocf_log info "RA ==== end action $ACTION$CLACT with rc=${ra_rc} ($SAPHanaVersion) (${timeR}s)===="
|
||
|
exit ${ra_rc}
|
||
|
diff -uNr a/tools/show_SAPHanaSR_attributes b/tools/show_SAPHanaSR_attributes
|
||
|
--- a/tools/show_SAPHanaSR_attributes 2016-10-14 10:09:56.467051414 +0200
|
||
|
+++ b/tools/show_SAPHanaSR_attributes 2016-10-14 10:31:28.051676675 +0200
|
||
|
@@ -1,19 +1,78 @@
|
||
|
#!/usr/bin/perl
|
||
|
#
|
||
|
-# get_all_lnx_attributes
|
||
|
-#
|
||
|
-# license: GPL
|
||
|
-# author: fabian.herschel@suse.com
|
||
|
-# date: 2014-05-13
|
||
|
-#
|
||
|
+# SAPHanaSR-showAttr
|
||
|
+# (c) 2014 SUSE Linux Products GmbH, Nuremberg, Germany
|
||
|
+# (c) 2015-2016 SUSE Linux GmbH, Nuremberg Germany
|
||
|
+# Author: Fabian Herschel <fabian.herschel@suse.com>
|
||
|
+# License: GPL v2+
|
||
|
+my $Version="0.18.2016.02.16.1";
|
||
|
#
|
||
|
+##################################################################
|
||
|
use POSIX;
|
||
|
use strict;
|
||
|
+use Sys::Syslog;
|
||
|
+use Sys::Hostname;
|
||
|
+use File::Path;
|
||
|
+use Getopt::Long;
|
||
|
+use lib '/usr/share/SAPHanaSR/tests';
|
||
|
+use SAPHanaSRTools;
|
||
|
+
|
||
|
+###################################
|
||
|
+## this part is not for scale out and currently NOT zero-config
|
||
|
+
|
||
|
+my $ClusterNodes=2;
|
||
|
+my $ClusterPrimaries=1;
|
||
|
+my $ClusterSecondaries=1;
|
||
|
+my %Name;
|
||
|
+my %Host;
|
||
|
+my $host = hostname();
|
||
|
|
||
|
+my $varlib='/var/lib/SAPHanaTD';
|
||
|
+my $testfile='SAPHanaTD.status';
|
||
|
+my $testcount=0;
|
||
|
+my $first_test=1;
|
||
|
my $sid="";
|
||
|
-my $table_title = "Host \\ Attr";
|
||
|
-my %Name;
|
||
|
+my @sids;
|
||
|
+my $ino="";
|
||
|
+my $sortBy="";
|
||
|
+my $table_titleH = "Host";
|
||
|
+#my %Name;
|
||
|
my %Host;
|
||
|
+my %Site;
|
||
|
+my %Global;
|
||
|
+my %HName;
|
||
|
+my %SName;
|
||
|
+my %GName;
|
||
|
+my $help;
|
||
|
+my $version;
|
||
|
+my $cibFile="";
|
||
|
+
|
||
|
+sub init()
|
||
|
+{
|
||
|
+ my $result = GetOptions ("sid=s" => \@sids,
|
||
|
+ "sort=s" => \$sortBy,
|
||
|
+ "cib=s" => \$cibFile,
|
||
|
+ "version" => \$version,
|
||
|
+ "help" => \$help,
|
||
|
+ );
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+init();
|
||
|
+
|
||
|
+if ( $help ) {
|
||
|
+ printf "SAPHanaSR-showAttr {[--sid=<sid[:instNr]>]} [--sort=<SortBy>] [--cib=<OfflineCibFile>]\n";
|
||
|
+ printf "";
|
||
|
+ exit 0;
|
||
|
+}
|
||
|
+if ( $version ) {
|
||
|
+ printf "%s\n", $Version;
|
||
|
+ exit 0;
|
||
|
+}
|
||
|
+
|
||
|
+if ( $cibFile ne "" ) {
|
||
|
+ printf "Using cib file %s\n", $cibFile;
|
||
|
+}
|
||
|
|
||
|
sub max { # thanks to http://www.perlunity.de/perl/forum/thread_018329.shtml
|
||
|
my $a = shift;
|
||
|
@@ -21,113 +80,75 @@
|
||
|
return $a > $b ? $a : $b;
|
||
|
}
|
||
|
|
||
|
-sub print_attr_host()
|
||
|
-{
|
||
|
- my ($HKey, $AKey);
|
||
|
- printf "%-22s", "Attribute \\ Host";
|
||
|
- foreach $HKey (sort keys %Host) {
|
||
|
- printf "%-16s ", $HKey;
|
||
|
- }
|
||
|
- printf "\n";
|
||
|
-
|
||
|
- printf "%s\n", "-" x 120 ;
|
||
|
-
|
||
|
- foreach $AKey (sort keys %Name) {
|
||
|
- printf "%-22s", $AKey;
|
||
|
- foreach $HKey (sort keys %Host) {
|
||
|
- printf "%-16.16s ", $Host{$HKey} -> {$AKey};
|
||
|
- }
|
||
|
-
|
||
|
- printf "\n";
|
||
|
- }
|
||
|
- return 0;
|
||
|
-}
|
||
|
-
|
||
|
-sub print_host_attr()
|
||
|
-{
|
||
|
- my ($AKey, $HKey, $len, $line_len, $hclen);
|
||
|
- $hclen=$Name{_hosts}->{_length};
|
||
|
- $line_len=$hclen+1;
|
||
|
- printf "%-$hclen.${hclen}s ", "$table_title";
|
||
|
- foreach $AKey (sort keys %Name) {
|
||
|
- if ($AKey ne "_hosts") {
|
||
|
- $len = $Name{$AKey}->{_length};
|
||
|
- $line_len=$line_len+$len+1;
|
||
|
- printf "%-$len.${len}s ", $Name{$AKey}->{_title};
|
||
|
+sub read_cib($) {
|
||
|
+ my $sid = shift();
|
||
|
+ if ( $cibFile eq "" ) {
|
||
|
+ printf "Open live cib\n";
|
||
|
+ open CIB, "cibadmin -Ql |" or die "CIB could not be read from cluster";
|
||
|
+ } else {
|
||
|
+ open CIB, "<$cibFile" or die "CIB file $cibFile not found or not able to read it";
|
||
|
+ }
|
||
|
+ while (<CIB>) {
|
||
|
+ chomp;
|
||
|
+ my ($host, $name, $site, $value);
|
||
|
+ if ( $_ =~ /cib-last-written="([^"]*)"/ ) {
|
||
|
+ printf "CIB-time: %s\n", $1;
|
||
|
}
|
||
|
- }
|
||
|
- printf "\n";
|
||
|
- printf "%s\n", "-" x $line_len ;
|
||
|
- foreach $HKey (sort keys %Host) {
|
||
|
- printf "%-$hclen.${hclen}s ", $HKey;
|
||
|
- foreach $AKey (sort keys %Name) {
|
||
|
- if ($AKey ne "_hosts") {
|
||
|
- $len = $Name{$AKey}->{_length};
|
||
|
- printf "%-$len.${len}s ", $Host{$HKey} -> {$AKey};
|
||
|
- }
|
||
|
- }
|
||
|
- printf "\n";
|
||
|
- }
|
||
|
- return 0;
|
||
|
-}
|
||
|
-
|
||
|
-open ListInstances, "/usr/sap/hostctrl/exe/saphostctrl -function ListInstances|";
|
||
|
-while (<ListInstances>) {
|
||
|
- # try to catch: Inst Info : LNX - 42 - lv9041 - 740, patch 36, changelist 1444691
|
||
|
- chomp;
|
||
|
- if ( $_ =~ /:\s+([A-Z][A-Z0-9][A-Z0-9])\s+-/ ) {
|
||
|
- $sid=tolower("$1");
|
||
|
- }
|
||
|
-}
|
||
|
-close ListInstances;
|
||
|
-
|
||
|
-
|
||
|
-open CIB, "cibadmin -Ql |";
|
||
|
-while (<CIB>) {
|
||
|
- chomp;
|
||
|
- my ($host, $name, $value);
|
||
|
- my $found=0;
|
||
|
- if ( $_ =~ /nvpair.*name="(\w+_${sid}_\w+)"/ ) {
|
||
|
- $name=$1;
|
||
|
- # find attribute in forever and reboot store :)
|
||
|
- if ( $_ =~ /id="(status|nodes)-([a-zA-Z0-9\_\-]+)-/ ) {
|
||
|
- $host=$2;
|
||
|
- }
|
||
|
- if ( $_ =~ /value="([^"]+)"/ ) {
|
||
|
- $value=$1;
|
||
|
- $found=1;
|
||
|
- }
|
||
|
- }
|
||
|
- if ( $found == 1 ) {
|
||
|
- #
|
||
|
- # handle the hosts name and table-title
|
||
|
- #
|
||
|
- $Host{$host}->{$name}=${value};
|
||
|
- if ( defined ($Name{_hosts}->{_length})) {
|
||
|
- $Name{_hosts}->{_length} = max($Name{_hosts}->{_length}, length($host ));
|
||
|
- } else {
|
||
|
- $Name{_hosts}->{_length} = length($host );
|
||
|
+ if ( $_ =~ /node_state id=".+" uname="([a-zA-Z0-9\-\_]+)" .*crmd="([a-zA-Z0-9\-\_]+)"/ ) {
|
||
|
+ insertAttribute($sid, \%Host, \%HName, $1, "node_status", $2);
|
||
|
}
|
||
|
- $Name{_hosts}->{_length} = max($Name{_hosts}->{_length}, length( $table_title));
|
||
|
- #
|
||
|
- # now handle the attributes name and value
|
||
|
- #
|
||
|
- $Name{$name}->{$host}=${value};
|
||
|
- if ( defined ($Name{$name}->{_length})) {
|
||
|
- $Name{$name}->{_length} = max($Name{$name}->{_length}, length($value ));
|
||
|
- } else {
|
||
|
- $Name{$name}->{_length} = length($value );
|
||
|
+ if ( $_ =~ /nvpair.*name="([a-zA-Z0-9\_\-]+_${sid}_([a-zA-Z0-9\-\_]+))"/ ) {
|
||
|
+ $name=$1;
|
||
|
+ if ( $_ =~ /id=.(status|nodes)-([a-zA-Z0-9\_\-]+)-/ ) {
|
||
|
+ # found attribute in nodes forever and reboot store
|
||
|
+ $host=$2;
|
||
|
+ if ( $_ =~ /value="([^"]+)"/ ) {
|
||
|
+ $value=$1;
|
||
|
+ insertAttribute($sid, \%Host, \%HName, $host, $name, $value);
|
||
|
+ }
|
||
|
+ } elsif ( $_ =~ /id=.SAPHanaSR-[a-zA-Z0-9\_\-]+_site_[a-zA-Z0-9\-]+_([a-zA-Z0-9\_\-]+)/) {
|
||
|
+ # found a site attribute
|
||
|
+ $site=$1;
|
||
|
+ if ( $name =~ /[a-zA-Z0-9\_\-]+_site_([a-zA-Z0-9\-]+)/ ) {
|
||
|
+ $name = $1;
|
||
|
+ }
|
||
|
+ if ( $_ =~ /value="([^"]+)"/ ) {
|
||
|
+ $value=$1;
|
||
|
+ insertAttribute($sid, \%Site, \%SName, $site, $name, $value);
|
||
|
+ }
|
||
|
+ } elsif ( $_ =~ /id=.SAPHanaSR-[a-zA-Z0-9\_\-]+_glob_[a-zA-Z0-9\_\-]+/) {
|
||
|
+ # found a global attribute
|
||
|
+ $host="GLOBAL";
|
||
|
+ if ( $name =~ /([a-zA-Z0-9\_\-]+)_glob_([a-zA-Z0-9\_\-]+)/ ) {
|
||
|
+ $name = $2;
|
||
|
+ }
|
||
|
+ if ( $_ =~ /value="([^"]+)"/ ) {
|
||
|
+ $value=$1;
|
||
|
+ insertAttribute($sid, \%Global, \%GName, "global", $name, $value);
|
||
|
+ }
|
||
|
+ }
|
||
|
}
|
||
|
- if ( $name =~ /hana_${sid}_(.*)/ ) {
|
||
|
- $Name{$name}->{_title} = $1;
|
||
|
- } else {
|
||
|
- $Name{$name}->{_title} = $name;
|
||
|
- }
|
||
|
- $Name{$name}->{_length} = max($Name{$name}->{_length}, length( $Name{$name}->{_title}));
|
||
|
- # printf "%-8s %-20s %-30s\n", $1, $2, $3;
|
||
|
- }
|
||
|
+ }
|
||
|
+ close CIB;
|
||
|
}
|
||
|
-close CIB;
|
||
|
|
||
|
-#print_attr_host;
|
||
|
-print_host_attr;
|
||
|
+if ( 0 == @sids ) {
|
||
|
+ my $sid_ino_list;
|
||
|
+ ( $sid_ino_list ) = get_sid_and_InstNr();
|
||
|
+ @sids = split(",", $sid_ino_list);
|
||
|
+
|
||
|
+}
|
||
|
+
|
||
|
+foreach $sid (@sids) {
|
||
|
+ ( $sid, $ino ) = split(":", $sid);
|
||
|
+ $sid=tolower("$sid");
|
||
|
+ %Host=();
|
||
|
+ %HName=();
|
||
|
+ read_cib($sid);
|
||
|
+ get_hana_attributes($sid);
|
||
|
+ if ( keys(%Host) == 0 ) {
|
||
|
+ printf "No attributes found for SID=%s\n", $sid;
|
||
|
+ } else {
|
||
|
+ print_host_attr(\%Host, \%HName, "Hosts", $sortBy);
|
||
|
+ }
|
||
|
+}
|