From 7de03e4e519705301265c0415b3c0af85263a7ac Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 09:52:36 +0200 Subject: Adding upstream version 1:4.13.0. Signed-off-by: Daniel Baumann --- heartbeat/sapdb.sh | 367 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 367 insertions(+) create mode 100755 heartbeat/sapdb.sh (limited to 'heartbeat/sapdb.sh') diff --git a/heartbeat/sapdb.sh b/heartbeat/sapdb.sh new file mode 100755 index 0000000..66e9854 --- /dev/null +++ b/heartbeat/sapdb.sh @@ -0,0 +1,367 @@ +# +# sapdb.sh - for systems having SAPHostAgent installed +# (sourced by SAPDatabase) +# +# Description: This code is separated from the SAPDatabase agent to +# introduce new functions for systems which having +# SAPHostAgent installed. +# Someday it might be merged back into SAPDatabase agein. +# +# Author: Alexander Krauth, September 2010 +# Support: linux@sap.com +# License: GNU General Public License (GPL) +# Copyright: (c) 2010, 2012 Alexander Krauth +# + + +# +# background_check_saphostexec : Run a request to saphostexec in a separate task, to be able to react to a hanging process +# +background_check_saphostexec() { + timeout=600 + count=0 + + $SAPHOSTCTRL -function ListDatabases >/dev/null 2>&1 & + pid=$! + + while kill -0 $pid > /dev/null 2>&1 + do + sleep 0.1 + count=$(( $count + 1 )) + if [ $count -ge $timeout ]; then + kill -9 $pid >/dev/null 2>&1 + ocf_log warn "saphostexec did not respond to the method 'ListDatabases' within 60 seconds" + return $OCF_ERR_GENERIC # Timeout + fi + done + + # child has already finished, now evaluate its returncode + wait $pid +} + +# +# cleanup_saphostexec : make sure to cleanup the SAPHostAgent in case of any +# misbehavior +# +cleanup_saphostexec() { + pkill -9 -f "$SAPHOSTEXEC" + pkill -9 -f "$SAPHOSTSRV" + oscolpid=$(pgrep -f "$SAPHOSTOSCOL") # we check saposcol pid, because it + # might not run under control of + # saphostexec + + # cleanup saposcol shared memory, otherwise it will not start again + if [ -n "$oscolpid" ];then + kill -9 $oscolpid + oscolipc=$(ipcs -m | grep "4dbe " | awk '{print $2}') + if [ -n "$oscolipc" ]; then + ipcrm -m $oscolipc + fi + fi + + # removing the unix domain socket file as it might have wrong permissions or + # ownership - it will be recreated by saphostexec during next start + [ -r /tmp/.sapstream1128 ] && rm -f /tmp/.sapstream1128 +} + +# +# check_saphostexec : Before using saphostctrl we make sure that the +# saphostexec is running on the current node. +# +check_saphostexec() { + chkrc=$OCF_SUCCESS + running=$(pgrep -f "$SAPHOSTEXEC" | wc -l) + + if [ $running -gt 0 ]; then + if background_check_saphostexec; then + return $OCF_SUCCESS + else + ocf_log warn "saphostexec did not respond to the method 'ListDatabases' correctly (rc=$?), it will be killed now" + running=0 + fi + fi + + if [ $running -eq 0 ]; then + ocf_log warn "saphostexec is not running on node `hostname`, it will be started now" + cleanup_saphostexec + output=`$SAPHOSTEXEC -restart 2>&1` + + # now make sure the daemon has been started and is able to respond + srvrc=1 + while [ $srvrc -ne 0 ] && [ "$(pgrep -f "$SAPHOSTEXEC" | wc -l)" -gt 0 ] + do + sleep 1 + background_check_saphostexec + srvrc=$? + done + + if [ $srvrc -eq 0 ] + then + ocf_log info "saphostexec on node $(hostname) was restarted !" + chkrc=$OCF_SUCCESS + else + ocf_log error "saphostexec on node $(hostname) could not be started! - $output" + chkrc=$OCF_ERR_GENERIC + fi + fi + + return $chkrc +} + + +# +# sapdatabase_start : Start the SAP database +# +sapdatabase_start() { + + check_saphostexec + rc=$? + + if [ $rc -eq $OCF_SUCCESS ] + then + sapuserexit PRE_START_USEREXIT "$OCF_RESKEY_PRE_START_USEREXIT" + + DBINST="" + if [ -n "$OCF_RESKEY_DBINSTANCE" ] + then + DBINST="-dbinstance $OCF_RESKEY_DBINSTANCE " + fi + FORCE="" + if ocf_is_true $OCF_RESKEY_AUTOMATIC_RECOVER + then + FORCE="-force" + fi + DBOSUSER="" + if [ -n "$OCF_RESKEY_DBOSUSER" ] + then + DBOSUSER="-dbuser $OCF_RESKEY_DBOSUSER " + fi + output=`$SAPHOSTCTRL -function StartDatabase -dbname $SID -dbtype $DBTYPE $DBINST $DBOSUSER $FORCE -service` + + sapdatabase_monitor 1 + rc=$? + + if [ $rc -eq 0 ] + then + ocf_log info "SAP database $SID started: $output" + rc=$OCF_SUCCESS + + sapuserexit POST_START_USEREXIT "$OCF_RESKEY_POST_START_USEREXIT" + else + ocf_log err "SAP database $SID start failed: $output" + rc=$OCF_ERR_GENERIC + fi + fi + + return $rc +} + +# +# sapdatabase_stop: Stop the SAP database +# +sapdatabase_stop() { + + check_saphostexec + rc=$? + + if [ $rc -eq $OCF_SUCCESS ] + then + sapuserexit PRE_STOP_USEREXIT "$OCF_RESKEY_PRE_STOP_USEREXIT" + + DBINST="" + if [ -n "$OCF_RESKEY_DBINSTANCE" ] + then + DBINST="-dbinstance $OCF_RESKEY_DBINSTANCE " + fi + DBOSUSER="" + if [ -n "$OCF_RESKEY_DBOSUSER" ] + then + DBOSUSER="-dbuser $OCF_RESKEY_DBOSUSER " + fi + output=`$SAPHOSTCTRL -function StopDatabase -dbname $SID -dbtype $DBTYPE $DBINST $DBOSUSER -force -service` + + if [ $? -eq 0 ] + then + ocf_log info "SAP database $SID stopped: $output" + rc=$OCF_SUCCESS + else + ocf_log err "SAP database $SID stop failed: $output" + rc=$OCF_ERR_GENERIC + fi + fi + + sapuserexit POST_STOP_USEREXIT "$OCF_RESKEY_POST_STOP_USEREXIT" + + return $rc +} + + +# +# sapdatabase_monitor: Can the given database instance do anything useful? +# +sapdatabase_monitor() { + strict=$1 + rc=$OCF_SUCCESS + + if ! ocf_is_true $strict + then + sapdatabase_status + rc=$? + else + check_saphostexec + rc=$? + + if [ $rc -eq $OCF_SUCCESS ] + then + count=0 + + DBINST="" + if [ -n "$OCF_RESKEY_DBINSTANCE" ] + then + DBINST="-dbinstance $OCF_RESKEY_DBINSTANCE " + fi + if [ -n "$OCF_RESKEY_DBOSUSER" ] + then + DBOSUSER="-dbuser $OCF_RESKEY_DBOSUSER " + fi + output=`$SAPHOSTCTRL -function GetDatabaseStatus -dbname $SID -dbtype $DBTYPE $DBINST $DBOSUSER` + + # we have to parse the output, because the returncode doesn't tell anything about the instance status + for SERVICE in `echo "$output" | grep -i 'Component[ ]*Name *[:=] [A-Za-z][A-Za-z0-9_]* (' | sed 's/^.*Component[ ]*Name *[:=] *\([A-Za-z][A-Za-z0-9_]*\).*$/\1/i'` + do + COLOR=`echo "$output" | grep -i "Component[ ]*Name *[:=] *$SERVICE (" | sed 's/^.*Status *[:=] *\([A-Za-z][A-Za-z0-9_]*\).*$/\1/i' | uniq` + STATE=0 + + case $COLOR in + Running) STATE=$OCF_SUCCESS;; + *) STATE=$OCF_NOT_RUNNING;; + esac + + SEARCH=`echo "$OCF_RESKEY_MONITOR_SERVICES" | sed 's/\+/\\\+/g' | sed 's/\./\\\./g'` + if [ `echo "$SERVICE" | egrep -c "$SEARCH"` -eq 1 ] + then + if [ $STATE -eq $OCF_NOT_RUNNING ] + then + ocf_log err "SAP database service $SERVICE is not running with status $COLOR !" + rc=$STATE + fi + count=1 + fi + done + + if [ $count -eq 0 -a $rc -eq $OCF_SUCCESS ] + then + ocf_log err "The resource does not run any services which this RA could monitor!" + rc=$OCF_ERR_ARGS + fi + + if [ $rc -ne $OCF_SUCCESS ] + then + ocf_log err "The SAP database $SID is not running: $output" + fi + fi + fi + return $rc +} + + +# +# sapdatabase_status: Are there any database processes on this host ? +# +sapdatabase_status() { + sid=`echo $SID | tr '[:upper:]' '[:lower:]'` + + SUSER=${OCF_RESKEY_DBOSUSER:-""} + + case $DBTYPE in + ADA) SEARCH="$SID/db/pgm/kernel" + [ -z "$SUSER" ] && SUSER=`grep "^SdbOwner" /etc/opt/sdb | awk -F'=' '{print $2}'` + SNUM=2 + ;; + ORA) DBINST=${OCF_RESKEY_DBINSTANCE} + DBINST=${OCF_RESKEY_DBINSTANCE:-${SID}} + SEARCH="ora_[a-z][a-z][a-z][a-z]_$DBINST" + + if [ -z "$SUSER" ]; then + id "oracle" > /dev/null 2> /dev/null && SUSER="oracle" + id "ora${sid}" > /dev/null 2> /dev/null && SUSER="${SUSER:+${SUSER},}ora${sid}" + fi + + SNUM=4 + ;; + DB6) SEARCH="db2[a-z][a-z][a-z]" + [ -z "$SUSER" ] && SUSER="db2${sid}" + SNUM=2 + ;; + SYB) SEARCH="dataserver" + [ -z "$SUSER" ] && SUSER="syb${sid}" + SNUM=1 + ;; + HDB) SEARCH="hdb[a-z]*server" + [ -z "$SUSER" ] && SUSER="${sid}adm" + SNUM=1 + ;; + esac + + [ -z "$SUSER" ] && return $OCF_ERR_INSTALLED + + cnt=`ps -u $SUSER -o args 2> /dev/null | grep -v grep | grep -c $SEARCH` + [ $cnt -ge $SNUM ] && return $OCF_SUCCESS + return $OCF_NOT_RUNNING +} + + +# +# sapdatabase_recover: +# +sapdatabase_recover() { + OCF_RESKEY_AUTOMATIC_RECOVER=1 + sapdatabase_stop + sapdatabase_start +} + + +# +# sapdatabase_validate: Check the semantics of the input parameters +# +sapdatabase_validate() { + rc=$OCF_SUCCESS + if [ `echo "$SID" | grep -c '^[A-Z][A-Z0-9][A-Z0-9]$'` -ne 1 ] + then + ocf_log err "Parsing parameter SID: '$SID' is not a valid system ID!" + rc=$OCF_ERR_ARGS + fi + + case "$DBTYPE" in + ORA|ADA|DB6|SYB|HDB) ;; + *) ocf_log err "Parsing parameter DBTYPE: '$DBTYPE' is not a supported database type!" + rc=$OCF_ERR_ARGS ;; + esac + + return $rc +} + +# +# sapdatabase_init: initialize global variables at the beginning +# +sapdatabase_init() { +OCF_RESKEY_AUTOMATIC_RECOVER_default=0 +: ${OCF_RESKEY_AUTOMATIC_RECOVER=${OCF_RESKEY_AUTOMATIC_RECOVER_default}} + +if [ -z "$OCF_RESKEY_MONITOR_SERVICES" ] +then + case $DBTYPE in + ORA) export OCF_RESKEY_MONITOR_SERVICES="Instance|Database|Listener" + ;; + ADA) export OCF_RESKEY_MONITOR_SERVICES="Database" + ;; + DB6) db2sid="db2`echo $SID | tr '[:upper:]' '[:lower:]'`" + export OCF_RESKEY_MONITOR_SERVICES="${SID}|${db2sid}" + ;; + SYB) export OCF_RESKEY_MONITOR_SERVICES="Server" + ;; + HDB) export OCF_RESKEY_MONITOR_SERVICES="hdbindexserver|hdbnameserver" + ;; + esac +fi +} -- cgit v1.2.3