#!/bin/ksh93
#  ALTRAN_PROLOG_BEGIN_TAG                                                    
#  This is an automatically generated prolog.                                  
#                                                                              
#  Copyright (C) Altran ACT S.A.S. 2017,2018,2021.  All rights reserved.  
#                                                                              
#  ALTRAN_PROLOG_END_TAG                                                      
#                                                                              
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
# 61haes_r720 src/43haes/lib/ksh93/hacmp/KLIB_HACMP_online_resourcegroup.sh 1.8 
#  
# Licensed Materials - Property of IBM 
#  
# Restricted Materials of IBM 
#  
# COPYRIGHT International Business Machines Corp. 2006,2015 
# 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 
# @(#)  e52d750 43haes/lib/ksh93/hacmp/KLIB_HACMP_online_resourcegroup.sh, 726, 2147A_aha726, Jul 12 2021 06:09 AM

# Start of POD-formatted documentation. Viewing suggestions:
#      perldoc <FILENAME>
#      pod2text -c <FILENAME>
#      pod2text -c --code <FILENAME>
#      pod2html <FILENAME>
function devDoc {
    : <<'=cut' >/dev/null 2>&1

=head1 NAME

 KLIB_HACMP_online_resourcegroup

=head1 VERSION

 Version Number:  1.8
 Last Extracted:  9/24/15 18:59:56
 Last Changed:    9/15/15 00:58:00

 Path, Component, Release(, Level):
 src/43haes/lib/ksh93/hacmp/KLIB_HACMP_online_resourcegroup.sh, hacmp.assist, 61haes_r720, 1539B_hacmp720

=head1 SYNOPSIS

 NON-CONCURRENT RESOURCE GROUPS
 clmgr online resource_group { <resource_group>[,<rg#2>,<rg#n>,...] | ALL } \
             [ NODE=<node> ] \
             [ PRIMARY={true} ] \
             [ SECONDARY={true} ]

 CONCURRENT RESOURCE GROUPS
 clmgr online resource_group { <resource_group>[,<rg#2>,<rg#n>,...] | ALL }\
             [ NODE={<node>[,<node#2>,...] | ALL} ] \
             [ SECONDARY={true} ]

 NOTE: the alias for "resource_group" is "rg".

=head1 DESCRIPTION

 Attempts to bring the specified resource group(s) online. If a specific
 node is provided, then the resource group will be started on that node.
 Otherwise, the default startup policy will be used.

=head1 ARGUMENTS

 1. rgs [REQUIRED] [string]
    One or more resource groups to be brought online.

 2. specified_nodes [OPTIONAL] [string]
    The label of one or more (for concurrent RGs only) nodes within
    the cluster that the resource group should be brought online on.

 3. secondary [OPTIONAL] [string]
    The label of a secondary node within the cluster that the
    resource group should be brought online on.

=head1 RETURN

 0: no errors were detected; the operation appears to have been successful
 1: a general error has occurred
 2: a specified resource does not exist, or could not be found
 3: some required input was missing
 4: some detected input was incorrect in some way
 5: a required dependency does not exist
 6: a specified search failed to match any data

=head1 COPYRIGHT

COPYRIGHT International Business Machines Corp. 2005,2010
All Rights Reserved

=cut
} # End of POD-formatted documentation.


function KLIB_HACMP_online_resourcegroup {
    LINENO=2 . $HALIBROOT/log_entry "$0()" "$CL"
    : @(#)  e52d750 43haes/lib/ksh93/hacmp/KLIB_HACMP_online_resourcegroup.sh, 726, 2147A_aha726, Jul 12 2021 06:09 AM
    : INPUTS: $*

    typeset rgs=${1//\"/}
    typeset specified_nodes=${2//\"/}
    #remove duplicates before any other processing takes place on specified_nodes string
    if [[ -n $specified_nodes ]]; then
        specified_nodes=$(echo $specified_nodes | tr "," "\n" | sort -u | tr "\n" " ")
        specified_nodes=${specified_nodes##+([[:space:]])}
        specified_nodes=${specified_nodes%%+([[:space:]])}
    fi
    typeset primary=${3//\"/}
    typeset secondary=${4//\"/}



    [[ $CLMGR_LOGGING == 'med' ]] && set +x  # Only trace param values

    #===================================
    : Declare and initialize variables
    #===================================
    typeset rg= nodes= node=
    typeset -A attr
    typeset -i rc=$RC_UNKNOWN timeout=120 inc=10 i=0
    typeset -u uc_val=$specified_nodes STATE=
    typeset DependentRG=""
    typeset IndependentRG=""
    typeset NodesForDependentRG=""
    typeset -i failures=0

    #=================
    : Validate input
    #=================
    rgs=${rgs#+([[:space:]])}
    rgs=${rgs%+([[:space:]])}
    rgs=${rgs//,/ }
    if [[ -z $rgs ]]; then
        /usr/bin/dspmsg -s $CLVT_SET $CLVT_MSGS 509 "\nERROR: at least one resource group must be specified.\n\n" 1>&2
        rc=$RC_MISSING_INPUT

    else
        if [[ $primary == @(t|T|y|Y)* && $secondary == @(t|T|y|Y)* && -n $specified_nodes ]]; then
            /usr/bin/dspmsg -s $CLVT_SET $CLVT_MSGS 536 "\nERROR: node information should not be passed to bring up both PRIMARY and SECONDARY.\n\n"
            rc=$RC_MISSING_INPUT
        elif [[ (-n $primary && $primary != @(t|T|y|Y)*) || (-n $secondary && $secondary != @(t|T|y|Y)*) ]]; then
            if [[ -n $primary && $primary != @(t|T|y|Y)* ]]; then
                /usr/bin/dspmsg -s $CLVT_SET $CLVT_MSGS 110 "\nERROR: invalid value specified for \"%1\$s\":  \"%2\$s\".\n" PRIMARY "$primary" 1>&2
            elif [[ -n $secondary && $secondary != @(t|T|y|Y)* ]]; then
                /usr/bin/dspmsg -s $CLVT_SET $CLVT_MSGS 110 "\nERROR: invalid value specified for \"%1\$s\":  \"%2\$s\".\n" SECONDARY "$secondary" 1>&2
            fi
            /usr/bin/dspmsg -s $CLVT_SET $CLVT_MSGS 3 "Valid values: %1\$s\n\n" "true, yes" 1>&2
            rc=$RC_INCORRECT_INPUT
        fi
        typeset -u uctext=$rgs
        if [[ $uctext == "ALL" ]]; then
            rgs=
            typeset available
            CL=$LINENO KLIB_HACMP_list_resourcegroups available
            for (( i=0; i<${#available[*]}; i++ )); do
                rgs="$rgs ${available[$i]}"
            done
        fi

        if [[ $uc_val == "ALL" ]]; then
            : Set to the special value of "All_Nodes_in_Group"
            specified_nodes="All_Nodes_in_Group"
        fi

        if [[ $primary == @(t|T|y|Y)* ]]; then
            pOpt="-s false"
        else
           pOpt="-s true"
        fi
        if [[ $secondary == @(t|T|y|Y)* ]]; then
            sOpt="-s true"
        else
            sOpt="-s false"
        fi

        #===========================================================
        : Check the status of the cluster manager. Must be STABLE.
        : Since clRGmove only checks the cluster manager status on
        : the local node, that is all we need to do, too.
        #===========================================================
        STATE=$(CL=$LINENO KLIB_HACMP_get_node_state 2>>$CLMGR_TMPLOG)
        for (( i=0; $i<timeout; i+=$inc )); do
            [[ $STATE == "ST_STABLE" ]] && break
            if (( $i < $timeout - $inc )); then
                STATE=$(CL=$LINENO KLIB_HACMP_get_node_state 2>>$CLMGR_TMPLOG)
                sleep $inc
            fi
        done

        #==========================================================================
        : Verify if user passed any dependent RGs as arguments
        : Creating DependentRG list from the list of rgs passed
        : if RG is not a part of any of the depedency mark it as IndependentRG
        #==========================================================================
        for rg in $rgs
        do
            checkparent=$(clodmget -f group_parent -q"group_parent=$rg" HACMPrgdependency)
            checkchild=$(clodmget -f group_parent -q"group_child=$rg" HACMPrgdependency)
            sameNodeDep=$(clrgdependency -t NODECOLLOCATION -sl | grep -w $rg)
            checkAntiCol=$(clodmget -q"group_name = $rg" HACMPrg_loc_dependency)
            if [[ -n $checkparent && -n $checkchild ]]; then
                rg_par_child="$rg_par_child $rg"
            elif [[ -n $checkparent ]]; then
                if [[ -z $par_list ]]; then
                    par_list=$rg
                else
                    par_list="$par_list $rg"
                fi
            elif [[ -n $checkchild ]]; then
                if [[ -z $child_list ]]; then
                    child_list=$rg
                else
                    child_list="$child_list $rg"
                fi
            elif [[ -n $sameNodeDep ]]; then
                if [[ -z $node_col ]];then
                    node_col=$rg
                else
                    node_col="$node_col $rg"
                fi
            elif [[ -n $checkAntiCol ]]; then
                if [[ $node_anticol == *$rg* ]]; then
                    continue
                fi
                OUTPUT=$(clrgdependency -t ANTICOLLOCATION -sl| grep -w $rg)
                print -- "$OUTPUT" | grep -v '#' |\
                while IFS=: read high int low; do
                    if [[ -z int ]];then
                        node_anticol="$node_anticol $high $low"
                    else
                        node_anticol="$node_anticol $high $int $low"
                    fi
                done
                #remove leading space and trailing spaces
                if [[ -n node_anticol ]]; then
                    node_anticol=${node_anticol#+([[:space:]])}
                    node_anticol=${node_anticol%+([[:space:]])}
                fi
            else
                if [[ -z $IndependentRG ]]; then
                    IndependentRG=$rg
                else
                    IndependentRG="$IndependentRG $rg"
                fi
            fi # end of depedency rg checks
        done # end of parsing rgs
        #==============================================================================================
        : RGs will be acquired in below order
        : priority 1:RG which is parent configured as parent and not as child in any other dependency
        : priority 2:RG which is configured as both parent and child
        : priority 3:RG configured as Child
        : priority 4:RG which is configured in same node dependencies
        : priority 5:RG which is configured in same node dependencies.
        #==============================================================================================
        DependentRG="$par_list $rg_par_child $child_list $node_col $node_anticol"
        if [[ -n $DependentRG ]]
        then
                # Remove leading, trailing space , remove if any duplicate RGs present in DependentRG.
                # Replace multiple spaces in DependentRG with single space if any.
                DependentRG=$(echo $DependentRG | sed -e 's/^[[:space:]]*//')
                DependentRG=$(echo $DependentRG | awk '{for (i=1;i<=NF;i++) if (!a[$i]++) printf("%s%s",$i,FS)}{printf("\n")}')
                DependentRG=$(echo $DependentRG | sed 's/  */ /g')
        fi

        if [[ -n $IndependentRG ]]
        then
                # Remove leading, trailing space for IndependentRG
                IndependentRG=$(echo $IndependentRG | sed -e 's/^[[:space:]]*//')
        fi

        #========================================================================
        : Bring dependent RGs ONLINE any. It is user responsibility to
        : pass proper RGs in this case.
        #========================================================================
        if [[ -n $DependentRG ]]
        then
            /usr/bin/dspmsg -s $CLVT_SET $CLVT_MSGS 533 "\nYou have specified dependent group(s) \n\"%1\$s\" to be brought ONLINE.\nNo checking of the current state or location will be done.\n\n" "$DependentRG"

            for rg in $DependentRG
            do
                #
                : check if RG is already in online state and if no secondary attribute is provided by user
                : skip this RG
                #
                CL=$LINENO KLIB_HACMP_get_resourcegroup_state "$rg" rgattrs1
                if [[ ${rgattrs1[STATE]} == "ONLINE" && $secondary != @(t|T|y|Y)* ]]; then
                    continue
                fi

                if [[ -n $specified_nodes ]]; then
                    if [[ $specified_nodes == "All_Nodes_in_Group" || \
                        $specified_nodes != *+([[:space:]])* ]]
                    then
                        NodesForDependentRG=$specified_nodes
                    else
                        CL=$LINENO KLIB_HACMP_get_rg_attributes "$rg" attr
                        NodesForDependentRG=" ${attr[NODES]} "

                        for node in $specified_nodes; do
                            NodesForDependentRG=${NodesForDependentRG// $node / }
                        done
                        #
                        # If user has specified a list of all the nodes in cluster,
                        # send All_Nodes_in_Group to clRGmove.
                        # This avoids calling clRGmove multiple times
                        #
                        if [[ $NodesForDependentRG == *([[:space:]]) ]]; then
                            NodesForDependentRG="All_Nodes_in_Group"
                        else
                            NodesForDependentRG=$specified_nodes
                        fi
                    fi
                else
                        CL=$LINENO KLIB_HACMP_get_rg_attributes "$rg" attr
                        if [[ ${attr[STARTUP]} == "OAAN" ]]; then
                            NodesForDependentRG="All_Nodes_in_Group"
                        else
                            NodesForDependentRG=${attr[NODES]%%+([[:space:]])*}
                        fi
                        #=================================================
                        # This check is added to the primary and secondary nodes of
                        # resourse group
                        #=================================================
                        if [[ $primary == @(t|T|y|Y)* && $secondary == @(t|T|y|Y)* ]]; then
                            primarynode=${attr[PRIMARYNODES]}
                            secondarynode=${attr[SECONDARYNODES]}
                            NodesForDependentRG="$primarynode $secondarynode"
                            # In case of site policy "ignore" and "online on both sites"
                            # we wont consider bring rg in  online secondary state
                            if [[  ${attr[SITE_POLICY]} == "both" || ${attr[SITE_POLICY]} == "ignore" ]]; then
                                primarynode="$primarynode $secondarynode"
                                secondarynode=""
                            fi
                        fi
                        if [[ -z $NodesForDependentRG ]]; then
                            /usr/bin/dspmsg -s $CLVT_SET $CLVT_MSGS 520 "\nWarning: unable to identify an eligible node\n where resource group \"%1\$s\" can be brought online.\n\n" "$rg"
                            rc=$RC_MISSING_DEPENDENCY
                        fi
                fi # end of specified_nodes check

                if (( $rc == RC_UNKNOWN || $rc == RC_SUCCESS )) && [[ -n $NodesForDependentRG ]]
                then
                    #
                    : This outer loop will be used whenever we dont pass primary and secondary attributes in the command
                    : if primary and secondary attributes are passed then inner loop will bring the RG ONLINE and ONLINE SECONDARY
                    : and break the loop.
                    #
                    for node in $NodesForDependentRG; do
                        if [[ $primary == @(t|T|y|Y)* && $secondary == @(t|T|y|Y)* ]]; then
                            if [[ -n $primarynode ]]; then
                                for primary_node in $primarynode
                                do
                                    rgstate=$(LC_ALL=C clRGinfo -s $rg | awk -F: '($3 == "'$primary_node'") {print $2}')
                                    if [[ "$rgstate" == "OFFLINE" ]]; then
                                        pOpt="-s false"
                                    else
                                        # if RG is already online the primary_node and startup policy
                                        # is not OAAN then we can skip bringing this RG online
                                        if [[ "$rgstate" == "ONLINE" && ${attr[STARTUP]} != "OAAN" ]]; then
                                            break
                                        elif [[ "$rgstate" == "ONLINE" && ${attr[STARTUP]} == "OAAN" ]]; then
                                            continue
                                        fi
                                    fi
                                    print "$0()[$LINENO]($SECONDS): $HAUTILS/clRGmove $pOpt -u -i -g \"$rg \" -n \"$primary_node\""\>>$CLMGR_TMPLOG
                                    VERBOSE_LOGGING="" $HAUTILS/clRGmove $pOpt -u -i -g "$rg" -n "$primary_node"
                                    rc=$?
                                    print "clRGmove RC: $rc" >>$CLMGR_TMPLOG  # Always log command result
                                    if (( $rc == RC_SUCCESS )); then
                                        if [[ ${attr[STARTUP]} != "OAAN" ]]; then
                                            break
                                        fi
                                    fi
                                done # end of primarynode
                            fi
                            if [[ -n $secondarynode ]]; then
                                #bring online secondary only if rg is already online
                                if (( $rc != RC_SUCCESS && $rc != RC_UNKNOWN )); then
                                    break
                                fi
                                for secondary_node in $secondarynode
                                do
                                    rgstate=$(LC_ALL=C clRGinfo -s $rg | awk -F: '($3 == "'$secondary_node'") {print $2}')
                                    if [[ "$rgstate" == "OFFLINE" ]]; then
                                        sOpt="-s true"
                                    else
                                        # if RG is already ONLINE SECONDARY on the primary_node
                                        # and RG policy is not OAAN skip bring RG in ONLINE SECONDARY
                                        if [[ "$rgstate" == "ONLINE SECONDARY" && ${attr[STARTUP]} != "OAAN" ]]; then
                                            break
                                        elif [[ "$rgstate" == "ONLINE SECONDARY" && ${attr[STARTUP]} == "OAAN" ]]; then
                                            continue
                                        fi
                                    fi
                                    print "$0()[$LINENO]($SECONDS): $HAUTILS/clRGmove $sOpt -u -i -g \"$rg \" -n \"$secondary_node\""\>>$CLMGR_TMPLOG
                                    VERBOSE_LOGGING="" $HAUTILS/clRGmove $sOpt -u -i -g "$rg" -n "$secondary_node"
                                    rc=$?
                                    print "clRGmove RC: $rc" >>$CLMGR_TMPLOG  # Always log command result
                                    if (( $rc == RC_SUCCESS )); then
                                        if [[ ${attr[STARTUP]} != "OAAN" ]]; then
                                            break
                                        fi
                                    fi
                                done  # end of secondarynodes loop
                            fi  # end if secondarynode condition
                            break
                        fi  # end of primary and secondary attributes condition check
                        rgstate=$(LC_ALL=C clRGinfo -s $rg | awk -F: '($3 == "'$node'") {print $2}')
                        # skip bringing RG ONLINE if RG is already ONLINE on the given node
                        # skip bringing the RG ONLINE if RG is online on someother node in case of
                        # RG policy not set to OAAN
                        if [[ ( "$rgstate" == "ONLINE"]] ) || ( ${attr[STARTUP]} != "OAAN" && -n ${attr[CURRENT_NODE]} ) ]]; then
                            continue
                        fi
                        print "$0()[$LINENO]($SECONDS): $HAUTILS/clRGmove $sOpt -u -i -g \"$rg\" -n \"$node\""\ >>$CLMGR_TMPLOG  # Always log commands
                        VERBOSE_LOGGING="" $HAUTILS/clRGmove $sOpt -u -i -g "$rg" -n "$node"
                        rc=$?
                        print "clRGmove RC: $rc" >>$CLMGR_TMPLOG  # Always log command result
                        (( $rc != RC_SUCCESS )) && (( failures++ ))
                    done # end of NodesForDependentRG loop
                    (( failures > 0 )) && rc=$RC_ERROR || rc=$RC_SUCCESS
                fi
            done # end of DependentRG loop
            #================================================================
            : Processing of dependent RGs over. Now filter out these RGs from main RG list and 
            : process only the remaining independent RGs.
            #================================================================
            rgs=$IndependentRG
        fi  #end of DependentRG check

        #==================================================================
        : Bring Independent RGs ONLINE
        : Loop through the specified groups, and attempt to bring each up
        #==================================================================
        if [[ -n $IndependentRG ]]
        then
            # Condier Serial order processing in case if it is Configured.
            # RGs which are configured in any other depedencies will be already
            # up by now and serial order processing may be neglected
            OUTPUT1=$(clrgorder -s)
            print -- "$OUTPUT1" | grep -v '#' |\
                IFS=: read sel_acq par_acq ser_rel par_rel
            ser_dep="$ser_dep $sel_acq"
            if [[ -n $ser_dep ]]; then
                for rg in $rgs
                do
                    if [[ -z $(echo $ser_dep | grep -w $rg ) ]]; then
                        rg_temp="$rg_temp $rg"
                    fi
                done
                ser_dep="$ser_dep $rg_temp"
            else
                ser_dep=$rgs
            fi
            # remove leading and trailing spaces and replace multiple spaces with single space
            # in between the ser_dep if any.
            ser_dep=$(echo $ser_dep | sed -e 's/^[[:space:]]*//')
            ser_dep=$(echo $ser_dep | sed 's/  */ /g')
            for rg in $ser_dep; do
                nodes= node=
                rg=$(echo $rg | sed -e 's/^[[:space:]]*//')
                # check if the rg is given in the list of RGs to be brought online otherwise skip bringing it.
                if [[ -z  $(echo $rgs | grep -w $rg) ]]; then
                       continue
                fi
                if [[ -n $specified_nodes ]]; then
                    if [[ $specified_nodes == "All_Nodes_in_Group" || \
                          $specified_nodes != *+([[:space:]])* ]]
                    then
                        nodes=$specified_nodes
                    else
                        CL=$LINENO KLIB_HACMP_get_rg_attributes "$rg" attr
                        nodes=" ${attr[NODES]} "

                        for node in $specified_nodes; do
                            nodes=${nodes// $node / }
                        done
                        #
                        # If user has specified a list of all the nodes in cluster,
                        # send All_Nodes_in_Group to clRGmove.
                        # This avoids calling clRGmove multiple times
                        #
                        if [[ $nodes == *([[:space:]]) ]]; then
                            nodes="All_Nodes_in_Group"
                        else
                            NodesForDependentRG=$specified_nodes
                        fi
                    fi
                else
                    CL=$LINENO KLIB_HACMP_get_rg_attributes "$rg" attr
                    if [[ ${attr[STARTUP]} == "OAAN" ]]; then
                        nodes="All_Nodes_in_Group"
                    else
                        nodes=${attr[NODES]%%+([[:space:]])*}
                    fi

                    #==============================================================
                    # This check is added to get primary and secondary nodes of
                    # resource group
                    #==============================================================
                    if [[ $primary == @(t|T|y|Y)* && $secondary == @(t|T|y|Y)* ]]; then
                        typeset -A rgAttrs
                        CL=$LINENO KLIB_HACMP_get_resourcegroup_state "$rg" rgAttrs
                        primarynode=${rgAttrs[PRIMARYNODES]}
                        secondarynode=${rgAttrs[SECONDARYNODES]}
                        nodes="$primarynode $secondarynode"
                        # In case of site policy "ignore" and "online on both sites"
                        # we wont consider bring rg in  online secondary state
                        if [[ ${attr[SITE_POLICY]} == "both" || ${attr[SITE_POLICY]} == "ignore" ]]; then
                            primarynode="$primarynode $secondarynode"
                            secondarynode=""
                        fi
                    fi
                    if [[ -z $nodes ]]; then
                        /usr/bin/dspmsg -s $CLVT_SET $CLVT_MSGS 520 "\nWarning: unable to identify an eligible node\n         where resource group \"%1\$s\" can be brought online.\n\n" "$rg"
                        rc=$RC_MISSING_DEPENDENCY
                    fi
                fi # end of specified_nodes check

                if (( $rc == RC_UNKNOWN || $rc == RC_SUCCESS )) && \
                   [[ -n $nodes ]]
                then
                    #
                    : This outer loop will be used whenever we dont pass primary and secondary attributes in the command.
                    : if primary and secondary attributes are passed then inner loop will bring the RGs ONLINE and ONLINE SECONDARY
                    : and break the loop.
                    #
                    for node in $nodes; do
                        if [[ $primary == @(t|T|y|Y)* && $secondary == @(t|T|y|Y)* ]]; then
                            if [[ -n $primarynode ]]; then
                                for primary_node in $primarynode
                                do
                                    rgstate=$(LC_ALL=C clRGinfo -s $rg | awk -F: '($3 == "'$primary_node'") {print $2}')
                                    if [[ "$rgstate" == "OFFLINE" ]]; then
                                        pOpt="-s false"
                                    else
                                        # if RG is already online the primary_node and startup policy
                                        # is not OAAN then we can skip bringing this RG online
                                        if [[ "$rgstate" == "ONLINE" && ${attr[STARTUP]} != "OAAN" ]]; then
                                            break
                                        elif [[ "$rgstate" == "ONLINE" && ${attr[STARTUP]} == "OAAN" ]]; then
                                            continue
                                        fi
                                    fi
                                    print "$0()[$LINENO]($SECONDS): $HAUTILS/clRGmove $pOpt -u -i -g \"$rg\" -n \"$primary_node\""\>>$CLMGR_TMPLOG
                                    VERBOSE_LOGGING="" $HAUTILS/clRGmove $pOpt -u -i -g "$rg" -n "$primary_node"
                                    rc=$?
                                    print "clRGmove RC: $rc" >>$CLMGR_TMPLOG  # Always log command result
                                    if (( $rc == RC_SUCCESS )); then
                                        if [[ ${attr[STARTUP]} != "OAAN" ]]; then
                                            break
                                        fi
                                    fi
                                done # end of primarynode loop
                            fi  # end of primarynode confition check
                            if [[ -n $secondarynode ]]; then
                                #bring online secondary only if rg is already online
                                if (( $rc != RC_SUCCESS && $rc != RC_UNKNOWN )); then
                                    break
                                fi
                                for secondary_node in $secondarynode
                                do
                                    rgstate=$(LC_ALL=C clRGinfo -s $rg | awk -F: '($3 == "'$secondary_node'") {print $2}')
                                    if [[ "$rgstate" == "OFFLINE" ]]; then
                                        sOpt="-s true"
                                    else
                                        # if RG is already ONLINE SECONDARY on the primary_node
                                        # and RG policy is not OAAN skip bring RG in ONLINE SECONDARY
                                        if [[ "$rgstate" == "ONLINE SECONDARY" && ${attr[STARTUP]} != "OAAN" ]]; then
                                            break
                                        elif [[ "$rgstate" == "ONLINE SECONDARY" && ${attr[STARTUP]} == "OAAN" ]]; then
                                            continue
                                        fi
                                    fi
                                    print "$0()[$LINENO]($SECONDS): $HAUTILS/clRGmove $sOpt -u -i -g \"$rg\" -n \"$secondary_node\""\>>$CLMGR_TMPLOG
                                    VERBOSE_LOGGING="" $HAUTILS/clRGmove $sOpt -u -i -g "$rg" -n "$secondary_node"
                                    rc=$?
                                    print "clRGmove RC: $rc" >>$CLMGR_TMPLOG
                                    if (( $rc == RC_SUCCESS )); then
                                        if [[ ${attr[STARTUP]} != "OAAN" ]]; then
                                            break
                                        fi
                                    fi
                                done # end of secondarynode loop
                            fi  # end of secondarynode condition check
                            break # break the outer loop as at this point we have tried bringing RGs already
                        fi # end of primary and secondary attributes condition check

                        rgstate=$(LC_ALL=C clRGinfo -s $rg | awk -F: '($3 == "'$node'") {print $2}')
                        # skip bringing RG ONLINE if RG is already ONLINE on the given node
                        # skip bringing the RG ONLINE if RG is online on someother node in case of
                        # RG policy not set to OAAN
                        if [[ ( "$rgstate" == "ONLINE"]] ) || ( ${attr[STARTUP]} != "OAAN" && -n ${attr[CURRENT_NODE]} ) ]]; then
                            continue
                        fi
                        print "$0()[$LINENO]($SECONDS): $HAUTILS/clRGmove $sOpt -u -i -g \"$rg\" -n \"$node\""\ >>$CLMGR_TMPLOG  # Always log commands
                        VERBOSE_LOGGING="" $HAUTILS/clRGmove $sOpt -u -i -g "$rg" -n "$node"
                        rc=$?
                        print "clRGmove RC: $rc" >>$CLMGR_TMPLOG  # Always log command result
                        (( $rc != RC_SUCCESS )) && (( failures++ ))
                    done # end of nodes loop
                    (( failures > 0 )) && rc=$RC_ERROR || rc=$RC_SUCCESS
                fi
            done
        fi
    fi

    #=======================================================================
    : If a user input error was detected, provide some helpful suggestions
    #=======================================================================
    if (( $rc == RC_MISSING_INPUT || $rc == RC_INCORRECT_INPUT )) && \
       [[ $CLVT_GUI == *([[:space:]]) ]]
    then
        CL=$LINENO cl_dspmsg -s $CLVT_SET $CLVT_MSGS 104 "For more information about available options and syntax, try\n\"$HAUTILS/clmgr %1\$s\". As an\nalternative, if the PowerHA SystemMirror man pages have been installed, invoke\n\"$HAUTILS/clmgr -hv\" (or \"/usr/bin/man clmgr\"),\nsearching for \"%2\$s\" in the displayed text.\n\n" \
        "online resource_group -h" "RESOURCE GROUP:" "$CLVT_PROGNAME" 1>&2
    fi

    log_return_msg "$rc" "$0()" "$LINENO"
    return $?
} # End of "KLIB_HACMP_online_resourcegroup()"
