#!/bin/ksh93
#  ALTRAN_PROLOG_BEGIN_TAG                                                     
#  This is an automatically generated prolog.                                  
#                                                                              
#  Copyright (C) Altran ACT S.A.S. 2022.  All rights reserved.         	
#                                                                              
#  ALTRAN_PROLOG_END_TAG                                                       
#                                                                              
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
# 61haes_r721 src/43haes/usr/sbin/cluster/events/node_down_local.sh 1.2.15.4 
#  
# Licensed Materials - Property of IBM 
#  
# COPYRIGHT International Business Machines Corp. 1990,2016 
# All Rights Reserved 
#  
# US Government Users Restricted Rights - Use, duplication or 
# disclosure restricted by GSA ADP Schedule Contract with IBM Corp. 
#  
# IBM_PROLOG_END_TAG 
# @(#)  bf03686 43haes/usr/sbin/cluster/events/node_down_local.sh, 61aha_r726, 2205A_aha726, May 10 2022 02:55 PM

#================================================
# The following, commented line enforces coding
# standards when this file is edited via vim.
#================================================
# vim:tabstop=4:shiftwidth=4:expandtab:smarttab
#================================================

#########################################################################
#
#   COMPONENT_NAME: EVENTS
#
#   FUNCTIONS: none
#
#########################################################################

#########################################################################
#                                                                       #
#       Name:           node_down_local                                 #
#                                                                       #
#	Description:	This script is called when the local node	#
#			leaves the cluster gracefully.		        #
#			The script releases resources taken over	#
#			from remote nodes (if any), then releases the	#
#			resources it owns. e.g.: stop application 	#
#			servers, release service address taken from 	#
#			remote node, release concurrent	volume		#
#			groups, unmount filesystem, release AIX         #
#			Connections realm/service pairs, and go to boot	#
#			address.					#
#									#
#       Called by:      node_down, reconfig_resource_release, rg_move   #
#                                                                       #
#       Calls to:       stop_server, release_takeover_addr,             #
#                       release_vg_fs, release_aconn_rs,                #
#                       cl_stop_snalink                                 #
#                                                                       #
#       Arguments:      None                                            #
#                                                                       #
#       Returns:        0       success                                 #
#                       1       failure                                 #
#			2 	bad argument				#
#                                                                       #
#########################################################################

function release_addr
{
    typeset PS4_FUNC="release_addr"
    [[ "$VERBOSE_LOGGING" == "high" ]] && set -x
    #
    # Check if there is any remote service address we have taken over.
    # If yes, release it.
    #
    if [[ -n "$TAKEOVER_LABEL" ]]
    then
	if [[ ${NOT_RELEASE} != TRUE ]]; then
	    if ! clcallev release_takeover_addr "$TAKEOVER_LABEL"
	    then
	        set_resource_status "ERROR"
                : exit status of set_resource_status is: $?
	        exit 1
	    fi
	fi
    fi
    #
    # Finally, release service address (go to boot address).
    #	
    if [[ -n "$SERVICE_LABEL" ]]
    then
	if [[ ${NOT_RELEASE} != TRUE ]]; then
	    if ! clcallev release_service_addr "$SERVICE_LABEL"
	    then
	        set_resource_status "ERROR"
                : exit status of set_resource_status is: $?
	        exit 1
	    fi
	fi
    fi
}

# 
# Set status of resource in resource location DB.  Note that we do only do this
# if NOT_REMOVING_GROUP is not true (only place this is set to true is in
# reconfig_resource_release).
#
function set_resource_status
{
    typeset PS4_FUNC="set_resource_status"
    [[ "$VERBOSE_LOGGING" == "high" ]] && set -x
    set +u
    NOT_DOIT=$NOT_REMOVING_GROUP
    set -u
# return if we are cleaning up resources. 
  if [[ $RESOURCES_CLEANUP == "CLEANUP" ]] ; then
   return
  fi

    if [[ "$NOT_DOIT" != "TRUE" ]]
    then
	if [[ "$EMULATE" == "EMUL" ]]
	then
	    cl_echo 3020 "NOTICE >>>> The following command was not executed <<<< \n"
	    echo	"clchdaemons -d clstrmgr_scripts -t resource_locator -n \""$LOCALNODENAME"\" -o \""$GROUPNAME"\" -v \"$1\"\n"
	else
	    if ! clchdaemons -d clstrmgr_scripts -t resource_locator -n "$LOCALNODENAME" -o "$GROUPNAME" -v "$1"
	    then
		cl_log 655 "$PROGNAME: Problem with resource location database in HACMPdaemons ODM.\n" $PROGNAME
		STATUS=1
	    fi
	fi
        #
        # Resource Manager Updates
        #
        if [[ "$1" == "RELEASING" ]]
        then
            if [[ "$FOLLOWER_ACTION" == "RELEASE_SECONDARY" ||
		  "$FOLLOWER_ACTION" == "SECONDARY_BECOMES_PRIMARY" ]]
            then
                cl_RMupdate releasing_secondary $GROUPNAME $PROGNAME 
	    else
                cl_RMupdate releasing $GROUPNAME $PROGNAME 
            fi
        else
            if [[ "$FOLLOWER_ACTION" == "RELEASE_SECONDARY" ||
		  "$FOLLOWER_ACTION" == "SECONDARY_BECOMES_PRIMARY" ]]
            then
                cl_RMupdate rg_error_secondary $GROUPNAME $PROGNAME 
	    else
                cl_RMupdate rg_error $GROUPNAME $PROGNAME 
            fi
        fi || STATUS=1
    fi
}

##############################################################################
# 
# Start of main function.
#
##############################################################################

PROGNAME=${0##*/}
export PATH="$(/usr/es/sbin/cluster/utilities/cl_get_path all)"
[[ "$VERBOSE_LOGGING" == "high" ]] && set -x
[[ "$VERBOSE_LOGGING" == "high" ]] && version='1.2.15.4 $Source: 61haes_r711 43haes/usr/sbin/cluster/events/node_down_local.sh 1$'

. /usr/es/sbin/cluster/events/reconfig_udresources

NOT_RELEASE=""
integer STATUS=0

EMULATE=${EMULATE:-"REAL"}

if (( $# !=0  ))
then
    cl_echo 1035 "Usage: $PROGNAME \n" $PROGNAME
    exit 2
fi

# Initialize Resource grroup cleanup variable if is not already
# initialized
set +u
RESOURCES_CLEANUP=${RESOURCES_CLEANUP:-""}
set -u

# Intialize the OEM variables if not already initialized.
set +u
OEM_FILESYSTEM=${OEM_FILESYSTEM:-""}
OEM_VOLUME_GROUP=${OEM_VOLUME_GROUP:-""}

# Read the state of RG
eval echo "\${RESGRP_${GROUPNAME}_${LOCALNODENAME//-/$HA_DASH_CHAR}}" | read group_state
# do not change the DB if we are just cleaning up the resources for
# resource_offline_cleanup

if [[ $RESOURCES_CLEANUP != "CLEANUP" ]] ; then
    # 
    #   First, see if resource is "UP".  If it isn't, don't mess with resource
    #   locator DB.  Note that this value may be already TRUE or FALSE from the
    #   calling script.  We simply turn off any "RELEASING" message if the
    #   resource is not already up.
    #
    eval "echo \${RESGRP_${GROUPNAME}_${LOCALNODENAME//-/$HA_DASH_CHAR}}" | read state
    if [[   ${RG_MOVE_ONLINE:-OFFLINE} != "TMP_ERROR" &&
            $state != "ONLINE" &&
	    $state != "ERROR" &&
	    $state != "ERROR_SECONDARY" &&
            $state != "ONLINE_SECONDARY" ]]
    then
        NOT_REMOVING_GROUP="TRUE"
    fi
    
    #
    # Next, indicate that the resource is leaving (only if it is up)
    #
    if [ "${state}" != "OFFLINE" ]
    then
        set_resource_status "RELEASING"
    fi
    
    #
    # The purpose of setting NOT_RELEASE to TRUE is to control the release
    # of resources in a resource group.  The only case where the resources
    # in a resource group should not be released is when node_down_local
    # runs on the node that does not have the resource group on-line.  This
    # happens when there are NFS cross-mounts and the cross mount is being
    # removed via DARE.
    #
    if [[ -z ${state} && ${RG_MOVE_ONLINE:-OFFLINE} != TMP_ERROR && ${RG_MOVE_ONLINE:-OFFLINE} != ONLINE ]]
    then
       NOT_RELEASE=TRUE
    fi
    
fi

set -u

release_udresources BEFORE_APPICATION
RC=$?
: exit status of release_udresources is: $RC
if (( $RC != 0 ))
then
   (( $STATUS == 0 )) && STATUS=1
fi

#
#   Stop application server(s) in the opposite order that they were started.
#
if [[ -n "$APPLICATIONS" ]]
then

    #
    #   Reverse the order of the list of application servers, so that they are
    #   stopped in the opposite order in which they are started.
    #
    TMPLIST=""
    while [[ -n "$APPLICATIONS" ]] ; do
	print $APPLICATIONS | read first_one APPLICATIONS
	TMPLIST=$first_one${TMPLIST:+" "$TMPLIST}
    done

    APPLICATIONS="${TMPLIST}"	    # reversed order now


    if [[ "$EMULATE" == "EMUL" ]]
    then 
	cl_echo 3020 "NOTICE >>>> The following command was not executed <<<< \n" 
	echo "clcallev stop_server $APPLICATIONS\n"
    else
	if [[ ${NOT_RELEASE} != TRUE ]]; then
	    if ! clcallev stop_server "$APPLICATIONS"
	    then
	        STATUS=1
	    fi
	fi
    fi
    
    #
    #	Release any dynamically acquired machine resources held by those
    #	applications
    #
    clmanageroha -o release -s -l "${APPLICATIONS// /,}" 3>&2
    : exit status of \"clmanageroha -o release -s -l \"${APPLICATIONS// /,}\"\" is: $?
fi

release_udresources BEFORE_TAPE
RC=$?
: exit status of release_udresources is: $RC
if (( $RC != 0 ))
 then
   echo "Failed to Stop userdefined resources for '${GROUPNAME}' "
   (( $STATUS == 0 )) && STATUS=1
 fi


#
#   Stop tape resources
#
if [[ -n "$SHARED_TAPE_RESOURCES" ]]
then
    if [[ "$EMULATE" == "EMUL" ]]
    then 
	cl_echo 3020 "NOTICE >>>> The following command was not executed <<<< \n" 
	echo "cl_tape_resource_release_multi $SHARED_TAPE_RESOURCES\n"
    else
	if [[ ${NOT_RELEASE} != TRUE ]]; then
	    if ! cl_tape_resource_release_multi "$SHARED_TAPE_RESOURCES"
	    then
	        STATUS=1
	    fi
	fi
    fi
fi

#
#   Stop AIX Connections services
#
if [[ -n "$AIX_CONNECTIONS_SERVICES" ]]
then
    if [[ "$EMULATE" == "EMUL" ]]
    then 
	cl_echo 3020 "NOTICE >>>> The following command was not executed <<<< \n" 
	echo "clcallev release_aconn_rs $AIX_CONNECTIONS_SERVICES\n"
    else
	if [[ ${NOT_RELEASE} != TRUE ]]; then
	    if ! clcallev release_aconn_rs "$AIX_CONNECTIONS_SERVICES"
	    then
	        STATUS=1
	    fi
	fi
    fi
fi

#
#   Start of commlink processing.
#
if [[ -n $COMMUNICATION_LINKS ]]
then
    if [[ "$EMULATE" == "EMUL" ]]
    then
	cl_echo 3020 "NOTICE >>>> The following command was not executed <<<< \n"
	echo "cl_stop_commlinks\n"
    else
	if [[ ${NOT_RELEASE} != TRUE ]]; then
	    if ! cl_stop_commlinks "$COMMUNICATION_LINKS"
	    then
	        STATUS=1
	    fi
	fi
    fi
fi

#
#   Shutdown SMB/FASTConnect resources
#
#   This is placed so that file system activity is closed, but no changes have
#   been made to IP addresses and such.
#
if [[ -n "$AIX_FAST_CONNECT_SERVICES" ]]
then
    if [[ "$EMULATE" == "EMUL" ]]
    then
	cl_echo 3020 "NOTICE >>>> The following command was not executed <<<< \n"
	echo "release_fast_connect_rs \n"
    else
	if [[ ${NOT_RELEASE} != TRUE ]]; then
	    if ! release_fast_connect_rs
	    then
	        STATUS=1
	    fi
	fi
    fi
fi

#
#   Unmount NFS_mount filesystem.
#
integer CROSSMOUNT=0
export CROSSMOUNT

if [[ -n "$MOUNT_FILESYSTEM" ]]
then

    #
    # If this is an RG move event, and there are cross mounted filesystems,
    # then remove the crossmounted filesystems from the list of filesystems
    # to process, we don't want to unmount the NFS mounts before proceeding.
    #

    TMP_MOUNT_FILESYSTEM=$MOUNT_FILESYSTEM
    set +u
    if [[ "$RG_MOVE_EVENT" == "true" && "$USER_RG_MOVE_TYPE" != "USER_RG_OFFLINE" && "$group_state" != "ERROR" && "$group_state" != "ERROR_SECONDARY" && \
          "$EVENT_TYPE" != "RELEASE_PRIMARY" && "$EVENT_TYPE" != "RELEASE_PRIMARY_NFS" ]]; then
        TMP_MOUNT_FILESYSTEM=""
        for fs in $MOUNT_FILESYSTEM; do
           if ! echo $fs | grep -q "\;"; then
              TMP_MOUNT_FILESYSTEM="$TMP_MOUNT_FILESYSTEM $fs"
           fi
        done
    fi
    set -u

    #
    #	Crossmounts are indicated by "/exported_path_name;/local_path_name"
    #
    if echo $MOUNT_FILESYSTEM | grep -q "\;/"
    then
	CROSSMOUNT=1
    fi

    #
    #	Unmount any locally NFS mounted file systems.  Uses the crossmounts
    #	indicator set above
    #
    if ! cl_deactivate_nfs "$TMP_MOUNT_FILESYSTEM"
    then
	STATUS=1
    fi
fi

if (( $UPDATESTATD == 0 ))
then
    #
    #	If this is a two node cluster and exported filesystems exist, then
    #	when the cluster topology is stable notify rpc.statd of the changes
    #
    if (( 2 == $(odmget HACMPnode | grep 'name =' | sort | uniq | wc -l ) ))
    then
	RESOURCE_GROUPS=$(odmget HACMPgroup | grep 'group =' | cut -f2 -d'"')
	for group in $RESOURCE_GROUPS
	do
	    EXPORTLIST=$(odmget -q "group=$group AND name=EXPORT_FILESYSTEM" HACMPresource \
		| grep 'value =' | cut -f2 -d'"')
	    if [[ -n "$EXPORTLIST" ]]
	    then
		if [[ "$EMULATE" == "EMUL" ]]
		then
		    cl_echo 3020 "NOTICE >>>> The following command was not executed <<<< \n"
		    echo "cl_update_statd\n"
		else
		    if ! cl_update_statd
		    then
			cl_log 1074 "$PROGNAME: Failure occurred while processing cl_update_statd.\n" $PROGNAME
			STATUS=1
		    fi
		fi
		break			# only need to update statd once
	    fi
	done
    fi
fi

#
#   Release IP address first if the order of takeover is to take FS before
#   IPaddr.
#
if [[ "$FS_BEFORE_IPADDR" == "true" ]]
then

    release_udresources BEFORE_SERVICEIP
    RC=$?
    : exit status of release_udresources is: $RC
    if (( $RC != 0 ))
    then
       echo "Failed to Stop userdefined resources for '${GROUPNAME}' "
       (( $STATUS == 0 )) && STATUS=1
    fi

    release_addr;
    : exit status of release_addr is: $?
fi

#
#   If there were any exported file systems, unexport them
#
if [[ -n "$EXPORT_FILESYSTEM$EXPORT_FILESYSTEM_V4" ]]
then
    if [[ ${NOT_RELEASE} != TRUE ]]; then
        cl_unexport_fs "$EXPORT_FILESYSTEM" "$EXPORT_FILESYSTEM_V4"
        : exit status of cl_unexport_fs $EXPORT_FILESYSTEM $EXPORT_FILESYSTEM_V4 is: $?
    fi
fi

release_udresources BEFORE_FILE_SYSTEM
RC=$?
: exit status of release_udresources is: $RC
if (( $RC != 0 ))
then
    echo "Failed to Stop userdefined resources for '${GROUPNAME}' "
    (( $STATUS == 0 )) && STATUS=1
fi


#
#   Release filesystem(s) and volume group(s).
#
if [[ ${NOT_RELEASE} != TRUE ]]; then
    if ! clcallev release_vg_fs "$FILESYSTEM" "$VOLUME_GROUP" "$OEM_FILESYSTEM" "$OEM_VOLUME_GROUP"
    then
        STATUS=1
    fi
fi

#
#   Release concurrent volume group(s).
#
if [[ -n "$CONCURRENT_VOLUME_GROUP" ]]
then
    if ! cl_deactivate_vgs "$CONCURRENT_VOLUME_GROUP"
    then
        STATUS=1
    fi
    #
    #	Call replicated resource postvg-offline method associated with any
    #	replicated resource defined in the resource group we are currently
    #	processing. 
    #
    call_conc_replicated_methods "postvg_offline" $CONCURRENT_VOLUME_GROUP
    RC=$?
    : exit status of call_conc_replicated_methods postvg_offline $CONCURRENT_VOLUME_GROUP is: $RC
    if [[ 0 != $RC ]]
    then
        set_resource_status "ERROR"
        : exit status of set_resource_status is: $?
        exit 1
    fi
fi

if [[ "$PRINCIPAL_ACTIONS" == "RELEASE" && 
      "$AUXILLIARY_ACTIONS" == "ACQUIRE_SECONDARY" ]]
then    
    #
    #	Call replicated resource clear-primary method associated with any
    #	replicated resource defined in the resource group we are currently
    #	processing. 
    #
    call_replicated_methods  "clear_primary"  ""
    STATUS=$?
    : exit status of call_replicated_methods is: $STATUS 
fi

#
#   If order of takeover is to take IPaddr than FS, then release address here.
#
if [[ "$FS_BEFORE_IPADDR" != "true" ]]
then

    release_udresources BEFORE_SERVICEIP
    RC=$?
    : exit status of release_udresources is: $RC
    if (( $RC != 0 ))
    then
       echo "Failed to Stop userdefined resources for '${GROUPNAME}' "
       (( $STATUS == 0 )) && STATUS=1
    fi

    release_addr;
    : exit status of release_addr is: $?
fi

release_udresources BEFORE_WPAR
RC=$?
: exit status of release_udresources is: $RC
if (( $RC != 0 ))
then
    echo "Failed to Stop userdefined resources for '${GROUPNAME}' "
    (( $STATUS == 0 )) && STATUS=1
fi


# Stop the WPAR.  Due to the fact that WPAR enablement/disablement is
# done in a lazy fashion, the actual state of WPAR activity will not
# necessarily match our ODM state.  Consequently, we can't simply look
# at the WPAR_NAME environment variable.
#
# The command clstop_wpar will check if the resource group actually has
# a WPAR so we don't need to check for that here.
clstop_wpar
RC=$?
: exit status of clstop_wpar is: $RC

if (( $RC != 0 ))
then
    echo "Failed to stop the WPAR associated with resource group '${GROUPNAME}'"
    (( $STATUS == 0 )) && STATUS=1
fi

release_udresources FIRST
RC=$?
: exit status of release_udresources is: $RC
if (( $RC != 0 ))
then
    echo "Failed to Stop userdefined resources for '${GROUPNAME}' "
    (( $STATUS == 0 )) && STATUS=1
fi

#
#   If there is a lingering error, set error status, then exit.
#
if (( $STATUS != 0 ))
then
    set_resource_status "ERROR"
    : exit status of set_resource_status is: $?
    exit $STATUS
fi

if [[ $RESOURCES_CLEANUP != "CLEANUP" ]] ; then

# 
#   Finally, indicate that the resource has made it DOWN by removing the
#   marker in the resource location DB (ODM HACMPdaemons).  We only do this if
#   NOT_REMOVING_GROUP is not true... (only place this is set to true is
#   reconfig_resource_release).
#
set +u
NOT_DOIT=$NOT_REMOVING_GROUP
set -u
if [[ "$NOT_DOIT" != "TRUE" ]]
then
    if [[ "$EMULATE" == "EMUL" ]]
    then
        cl_echo 3020 "NOTICE >>>> The following command was not executed <<<< \n"
	    echo "clchdaemons -r -d clstrmgr_scripts -t resource_locator -o \""$GROUPNAME"\"\n"

	    cl_echo 3020 "NOTICE >>>> The following command was not executed <<<< \n"
        echo "cl_RMupdate rg_down $GROUPNAME $PROGNAME\n"
    else
        if ! clchdaemons -r -d clstrmgr_scripts -t resource_locator -o "$GROUPNAME"
        then
	        cl_log 655 "$PROGNAME: Problem with resource location database in HACMPdaemons ODM.\n" $PROGNAME
	        STATUS=1
        fi
        
        # 
        # Resource manager updates
	    #
        cl_RMupdate rg_down $GROUPNAME $PROGNAME ||
	    STATUS=1
    fi
 fi
fi
exit $STATUS
