#!/bin/ksh93
#  ALTRAN_PROLOG_BEGIN_TAG
#  This is an automatically generated prolog.
#
#  Copyright (C) Altran ACT S.A.S. 2017,2020,2021.  All rights reserved.
#
#  ALTRAN_PROLOG_END_TAG
#
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
# 61haes_r721 src/43haes/lib/ksh93/hacmp/KLIB_HACMP_modify_node.sh 1.19 
#  
# Licensed Materials - Property of IBM 
#  
# COPYRIGHT International Business Machines Corp. 1990,2010 
# 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 
# @(#)  7d4c34b 43haes/lib/ksh93/hacmp/KLIB_HACMP_modify_node.sh, 726, 2147A_aha726, Feb 05 2021 09:50 PM

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

# 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_modify_node

=head1 SYNOPSIS

 clmgr modify node <node> \
             [ NAME=<new_node_label> ] \
             [ COMMPATH=<new_commpath> ] \
             [ PERSISTENT_IP=<IP> NETWORK=<network>
               {NETMASK=<255.255.255.0 | PREFIX=1..128} ] \
             [ START_ON_BOOT={false|true} ] \
             [ BROADCAST_ON_START={true|false} ] \
             [ CLINFO_ON_START={false|true|consistent} ] \
             [ HMCS=<hmc>[,<hmc#2>,...] ] \
             [ ENABLE_LIVE_UPDATE={true|false} ] \
             [ ENABLE_CAA_AFTER_MERGE={true|false} ] \
             [ CRIT_DAEMON_RESTART_GRACE_PERIOD=<0..240> ]

 NOTE: the alias for "node" is "no".

=head1 DESCRIPTION

Attempts to modify the specified PowerHA node
to conform to the provided specifications.

=head1 ARGUMENTS

 1. properties [REQUIRED] [hash ref]
    An associative array within which data about the
    created object can be returned to the caller.

 2. nodename [REQUIRED] [string]
    The label of the node that is to be modified.

 3. new_node {OPTIONAL] [string]
    A new label to attempt to apply to the specified node.

 4. commpath [OPTIONAL] [string]
    A new communication path to the node, which may be either an IP
    address, or a resolvable hostname.

 5. persistentIP [OPTIONAL] [string]
    A persistent IP to add to the node.

 6. network [OPTIONAL] [string]
    A network to which the specified persistent IP (if any) should
    be added to.

 7. prefix [OPTIONAL] [string]
    The specified network's (if any) prefix length (IPv6).

 8. netmask [OPTIONAL] [string]
    The specified network's (if any) netmask (IPv4).

 9. restart [OPTIONAL] [string]
    A Boolean-like indicator of whether or not to start cluster
    services on this node automatically whenever the system itself
    is restarted.

    Valid values include: {false|true}

 10. broadcast [OPTIONAL] [string]
    A Boolean-like indicator of whether or not to broadcast cluster
    services startup.

    Valid values include: {true|false}

 11. clinfo [OPTIONAL] [string]
    This Enum-like value indicates of whether or not to start the CLINFO
    subsystem when cluster services start, and if so, in what mode to start
    it.

    Valid values include: {false|true|consistent}

 12. hmcs [OPTIONAL] [string]
    At least two hmcs. Use this option to set the precedence order
    of the hmcs to be used by the node. You cannot add nor remove
    any hmc using this option, you simply can change the precedence
    order of them.

 13. enable_lku [OPTIONAL] [string]
    A Boolean-like indicator of whether or not AIX Live Update operation
    should be allowed on this node.

    Valid values include: {true|false}

 14. enable_caa_after_merge [OPTIONAL] [string]
    Nodes on the loosing partition will be rebooted and CAA will not 
    be started with reboot option disable caa auto start. Use this
    option to enable CAA after the split condition is healed to bring
    cluster back to stable state.

    Valid values include: {true|false}
	 
  15. crit_daemon_restart_grace_period [OPTIONAL] [integer]
    Sets the RSCT resource attribute IBM.PeerNode.CritDaemonRestartGracePeriod
    for tuning the response to loss of critical daemons in heavily loaded systems.
    Value is in seconds and the recommended value is less than 120 seconds.
    Default value is 0 and range is 0-240.

=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

=cut
} # End of POD-formatted documentation.


function KLIB_HACMP_modify_node {
    LINENO=2 . $HALIBROOT/log_entry "$0()" "$CL"
    : version=@(#)  7d4c34b 43haes/lib/ksh93/hacmp/KLIB_HACMP_modify_node.sh, 726, 2147A_aha726, Feb 05 2021 09:50 PM
    : INPUTS: $*

    typeset -n properties=$1
    typeset node=${2//\"/}
    shift; shift

    typeset new_node=${1//\"/}
    typeset commpath=${2//\"/}
    typeset persistentIP=${3//\"/}
    typeset network=${4//\"/}
    typeset prefix=${5//\"/}
    typeset netmask=${6//\"/}
    typeset -l restart=${7//\"/}
    typeset -l broadcast=${8//\"/}
    typeset -l clinfo=${9//\"/}
    typeset old_node_=$node
    typeset new_node_=$new_node
    typeset hmcs=${10//\"/}
            hmcs=${hmcs//,/ }
    typeset -l enable_lku=${11//\"/}
    typeset -l enable_caa_after_merge=${12//\"/}
    typeset    crit_daemon_restart_grace_period=${13//\"/}
    typeset daemon_grace_period_bkp

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

    #================================================================
    : Check for a defined cluster. No need to continue without one.
    #================================================================
    CL=$LINENO isClusterDefined
    if (( $? != RC_SUCCESS )); then
        log_return_msg "$RC_MISSING_DEPENDENCY" "$0()" "$LINENO"
        return $?
    fi

    #===================================
    : Declare and initialize variables
    #===================================
    typeset -i rc=$RC_UNKNOWN
    typeset -i i=0

    #================================================================
    : Assuming an object was specified, see if it is a known object
    #================================================================
    if [[ $node != *([[:space:]]) ]]; then
        CL=$LINENO KLIB_HACMP_is_known_node "$node" >/dev/null 2>&1
        (( $? != RC_SUCCESS )) && rc=$RC_NOT_FOUND
    fi

    #=================
    : Validate input
    #=================
    if [[ -z $node ]]; then
        /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 100 "\nERROR: a name/label must be provided.\n\n" 1>&2
        rc=$RC_MISSING_INPUT

    elif (( $rc == RC_NOT_FOUND )); then
        /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 102 "\nERROR: \"%1\$s\" does not appear to exist!\n\n" "$node" 1>&2
        /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 151 "Available Nodes:\n\n" 1>&2

        typeset available
        CL=$LINENO KLIB_HACMP_list_nodes available
        for (( i=0; i<${#available[*]}; i++ )); do
            if [[ ${available[$i]} != *([[:space:]]) ]]; then
                print -u2 "\t${available[$i]}"
            fi
        done
        print -u2 ""
    fi

    if [[ -n $new_node ]]; then
        if [[ -n "${new_node//[!0-9]*/}" || -n "${new_node//[a-zA-Z0-9_\-]/}" ]]; then
            /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 188 "\nERROR: one or more invalid characters were detected in \"%1\$s\" (\"%2\$s\").\n\nValid characters include letters, numbers, underscores, and dashes only.\n\n" "$new_node" "${new_node//[a-zA-Z0-9_\-]/}" 1>&2
            rc=$RC_INCORRECT_INPUT
        elif (( ${#new_node} > $MAX_NAME_LENGTH )); then
            cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1466 '\nERROR: Node name %1$s should not be more than %2$ld characters.\n' "$new_node" "$MAX_NAME_LENGTH" 1>&2 
            rc=$RC_INCORRECT_INPUT
        fi

        typeset CSTATE=$(CL=$LINENO KLIB_HACMP_get_cluster_state)
        if [[ $CSTATE == *([[:space:]]) || $CSTATE == "UNKNOWN" ]]; then
            cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 775 '\nERROR: unable to determine the current state of all the nodes in the cluster. This makes it unsafe to modify the configuration%1$s.\n\n' " (\"$new_node\")" 1>&2
            rc=$RC_ERROR
        elif [[ $CSTATE != @(OFFLINE|NOT_CONFIGURED) ]]; then
            cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 776 '\nERROR: one or more nodes in the cluster are active. This makes it unsafe to modify the configuration%1$s.\n\n' " (\"$new_node\")" 1>&2
            rc=$RC_MISSING_DEPENDENCY
        fi
        #==================================================================================================
        : Taking backup for critical daemon restart grace period value if user tries to modify node name.
        #==================================================================================================
        if (( $rc == RC_UNKNOWN || $rc == RC_SUCCESS )); then
            daemon_grace_period_bkp=$(clodmget -n -q "object=CRIT_DAEMON_RESTART_GRACE_PERIOD and name=$node" -f value HACMPnode)
        fi
    fi

    if [[ "$*" == *([[:space:]]) ]]; then
        /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 401 "\nERROR: no valid modifications were specified for \"%1\$s\".\n\n" "$node" 1>&2
        rc=$RC_MISSING_INPUT
    fi

    if [[ -n $network ]]; then
        CL=$LINENO KLIB_HACMP_is_known_network "$network" >/dev/null 2>&1
        if (( $? != RC_SUCCESS )); then
            rc=$RC_INCORRECT_INPUT
            /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 102 "\nERROR: \"%1\$s\" does not appear to exist!\n\n" "$network" 1>&2

            /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 150 "Available Networks:\n\n" 1>&2
            typeset available
            CL=$LINENO KLIB_HACMP_list_networks available
            for (( i=0; i<${#available[*]}; i++ )); do
                if [[ ${available[$i]} != *([[:space:]]) ]]; then
                    print -u2 "\t${available[$i]}"
                fi
            done
            print -u2 ""
        fi
    fi

    if [[ -n $netmask && -n $prefix ]]; then
        /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 36 "\nERROR: conflicting options were provided,\n\       \"%1\$s\" versus \"%2\$s\".\n\n" NETMASK PREFIX 1>&2
        rc=$RC_INCORRECT_INPUT
    fi

    if [[ $prefix != *([[:space:]]) ]] && \
         ( [[ $prefix != +([[:digit:]]) ]] || (( prefix < 1 || prefix > 128 )) )
    then
        /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 113 "\nERROR: an invalid IPv6 prefix length was specified: %1\$s\n\n" "$prefix" 1>&2
        /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 3 "Valid values: %1\$s\n\n" "1 .. 128" 1>&2
        rc=$RC_INCORRECT_INPUT
    fi

    if [[ -n $netmask ]]; then
        typeset nodots=${netmask//\./}
        if (( ${#netmask} - ${#nodots} != 3 )); then
            /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 115 "\nERROR: an invalid IPv4 netmask was specified: %1\$s\n\n" "$netmask" 1>&2
            /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 3 "Valid values: %1\$s\n\n" "<###.###.###.###>; \"###\" must be in the range 0 .. 255." 1>&2
            rc=$RC_INCORRECT_INPUT
        else
            typeset value=$netmask
            for (( i=0; i<4; i++ )); do
                typeset octet=${value%%.*}
                value=${value#*.}
                if [[ $octet == *([[:space:]]) || \
                      $octet != +([[:digit:]]) ]] || \
                   (( octet < 0 || octet > 255 ))
                then
                     /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 115 "\nERROR: an invalid IPv4 netmask was specified: %1\$s\n\n" "$netmask" 1>&2
                     /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 3 "Valid values: %1\$s\n\n" "<###.###.###.###>; \"###\" must be in the range 0 .. 255." 1>&2
                     rc=$RC_INCORRECT_INPUT
                     break
                fi
            done
        fi
    fi

    if [[ -n $restart ]]; then
        if [[ $restart != @(1|0|n|f|y|t)* ]]; then
            /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 110 "\nERROR: invalid value specified for \"%1\$s\":  \"%2\$s\".\n" START_ON_BOOT "$restart" 1>&2
            /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 3 "Valid values: %1\$s\n\n" "false, true" 1>&2
            rc=$RC_INCORRECT_INPUT
        fi
    fi

    if [[ -n $broadcast ]]; then
        if [[ $broadcast != @(1|0|n|f|y|t)* ]]; then
            /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 110 "\nERROR: invalid value specified for \"%1\$s\":  \"%2\$s\".\n" BROADCAST_ON_START "$broadcast" 1>&2
            /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 3 "Valid values: %1\$s\n\n" "true, false" 1>&2
            rc=$RC_INCORRECT_INPUT
        fi
    fi

    if [[ -n $clinfo ]]; then
        if [[ $clinfo != @(1|0|n|f|y|t|c)* ]]; then
            /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 110 "\nERROR: invalid value specified for \"%1\$s\":  \"%2\$s\".\n" CLINFO_ON_START "$clinfo" 1>&2
            /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 3 "Valid values: %1\$s\n\n" "false, true, consistent" 1>&2
            rc=$RC_INCORRECT_INPUT
        fi
    fi

    typeset -i error_found=1;
    if [[ -n $hmcs ]]; then
        #========================================================
        : Verify that the list of hmcs passed is the exact
        :  list of hmcs already set on this node
        #========================================================
        typeset HMCLABELS=
        error_found=0
        typeset hmclabels=
        print "$0()[$LINENO]($SECONDS): cllshmcparam -n $node -o " >>$CLMGR_TMPLOG  # Always log commands
        hmclabels=$(cllshmcparam -n $node -o | sort -u)
        rc=$?
        print "$0()[$LINENO]($SECONDS): cllshmcparam -n $node -o rc=$rc" >>$CLMGR_TMPLOG  # Always log commands result
        HMCLABELS=$(print -- "$hmclabels" | tr ' ' '\n' )
        typeset hmcs_sorted=$(print -- "$hmcs" | tr ' ' '\n' | sort -u)
        if [[ $hmclabels != $hmcs_sorted ]]; then
            error_found=1
        fi


        #===============================================
        : if verification fails, then reject the change
        #===============================================
        if (( $error_found == 1 )); then
            /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 110 "\nERROR: invalid value specified for \"%1\$s\":  \"%2\$s\".\n" HMCS "$hmcs" 1>&2
            /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 3 "Valid values: %1\$s\n\n" "$HMCLABELS" 1>&2
            rc=$RC_INCORRECT_INPUT
        else
            rc=$RC_UNKNOWN
        fi
    fi

    if [[ -n $commpath ]]; then
        commPathCheck=$(host $commpath 2> /dev/null | awk -F" " '{print $1}')
        if [[ -z $commPathCheck ]]; then
            dspmsg -s $CLVT_SET $CLVT_MSGS 198 "\nERROR: Invalid hostname \"%1\$s\" for communication path, please check and provide valid hostname.\n\n" $commpath 1>&2
            rc=$RC_INCORRECT_INPUT
        elif ! $(LC_ALL=C lscluster -m | grep -w "Node name" | grep -qw "$commpath") ; then
            dspmsg -s $CLVT_SET $CLVT_MSGS 196 "\nWARNING: The COMMUNICATION_PATH of node(\"%1\$s\") has changed to \"%2\$s\".\nThe new communication path does not match with hostname. The communication path\nof PowerHA cluster node must match the host name of that node. Otherwise, The cluster\nverification may fail. You can run the\"hostname\" command to display the hostname\nof that PowerHA node.\n\n" $node $commpath 1>&2
        fi
    fi

    if [[ -n $enable_lku ]]; then
        if [[ $enable_lku != @(1|0|n|f|y|t)* ]]; then
            /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 110 "\nERROR: invalid value specified for \"%1\$s\":  \"%2\$s\".\n" ENABLE_LIVE_UPDATE "$enable_lku" 1>&2
            /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 3 "Valid values: %1\$s\n\n" "true, false" 1>&2
            rc=$RC_INCORRECT_INPUT
        fi
    fi
	
    if [[ -n $enable_caa_after_merge ]]; then
        if [[ $enable_caa_after_merge != @(1|0|n|f|y|t)* ]]; then
            /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 110 "\nERROR: invalid value specified for \"%1\$s\":  \"%2\$s\".\n" ENABLE_CAA_AFTER_MERGE "$enable_caa_after_merge" 1>&2
            /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 3 "Valid values: %1\$s\n\n" "true, false" 1>&2
            rc=$RC_INCORRECT_INPUT
        fi
    fi

    #
    :  Before validating critical daemon restart grace period, verifying the installed RSCT version
    :  supports crit_daemon_restart_grace_period attribute or not.
    #
    if [[ -n $crit_daemon_restart_grace_period ]]; then
        typeset RSCT_SUPPORTED_VERSION="3.2.5.0"
        typeset RSCT_VERSION
        RSCT_VERSION=$(ctversion | cut -s -f 2 -d ' ')
        echo $RSCT_VERSION | IFS="." read V R M F
        if (( $V$R$M$F < 3250 ));then
            dspmsg -s 63 cluster.cat 80 "\nERROR: Installed RSCT verion \"%1\$s\" is not supported for CRIT_DAEMON_RESTART_GRACE_PERIOD attribute.\n\
Minimum RSCT version required to support CRIT_DAEMON_RESTART_GRACE_PERIOD is \"%2\$s\"" $RSCT_VERSION  $RSCT_SUPPORTED_VERSION 1>&2            
            rc=$RC_INCORRECT_INPUT
        else
           typeset DESC="CRIT_DAEMON_RESTART_GRACE_PERIOD"
           [[ -n $CLMGR_GUI ]] && DESC=$(dspmsg -s 63 cluster.cat 78 "Critical Daemon Restart Grace Period")
           CL=$LINENO verify_numeric_range "$crit_daemon_restart_grace_period" 0 240 "$DESC"
           (( $? != RC_SUCCESS )) && rc=$RC_INCORRECT_INPUT
        fi
    fi

    #========================================================
    : Modify the node if no input errors have been detected
    #========================================================
    if (( $rc == RC_UNKNOWN )); then
        if [[ -n $new_node ]]; then
            if [[ -n $commpath ]]; then
                print "$0()[$LINENO]($SECONDS): $HAUTILS/clnodename -o \"$node\" -n \"$new_node\" -p \"$commpath\"" >>$CLMGR_TMPLOG  # Always log commands
                $HAUTILS/clnodename -o "$node" -n "$new_node" -p "$commpath"
            else
                print -- "$0()[$LINENO]($SECONDS): $HAUTILS/clnodename -o \"$node\" -n \"$new_node\"" >>$CLMGR_TMPLOG  # Always log commands
                $HAUTILS/clnodename -o "$node" -n "$new_node"
            fi
            rc=$?
            print "clnodename rc=$rc" >>$CLMGR_TMPLOG  # Always log command result
            if (( $rc == RC_SUCCESS )); then
                node=$new_node
            else
                rc=$RC_ERROR
            fi
        : check for commpath only
        elif [[ -n $commpath ]]; then
            print "$0()[$LINENO]($SECONDS): $HAUTILS/clnodename -o \"$node\" -p \"$commpath\"" >>$CLMGR_TMPLOG  # Always log commands
            $HAUTILS/clnodename -o "$node" -p "$commpath"
            rc=$?
            print "clnodename rc=$rc" >>$CLMGR_TMPLOG  # Always log command result
            if (( $rc != RC_SUCCESS )); then
                rc=$RC_ERROR
            fi
        fi

        #==============================================================
        : If verification step for hmcs  is ok, then perform the change
        #==============================================================
        if (( $error_found == 0 )); then
            hmcs=${hmcs// /,}
            print "$0()[$LINENO]($SECONDS): clchhmcparam -n $node -c HMC_IP=$hmcs " >>$CLMGR_TMPLOG  # Always log commands
            clchhmcparam -n $node -c HMC_IP="$hmcs"
            rc=$?
            print "$0()[$LINENO]($SECONDS): clchhmcparam -n $node -c HMC_IP=$hmcs rc=$rc" >>$CLMGR_TMPLOG # Always log commands result
            if (( $rc != RC_SUCCESS )); then
                rc=$RC_ERROR
            fi
        fi
    fi

    #=============================================================
    : If any cluster services settings were specified, make them
    #=============================================================
    if (( $rc == RC_UNKNOWN || $rc == RC_SUCCESS )) && \
       [[ -n $restart || -n $broadcast || -n $clinfo ]]
    then
        typeset opt_i= opt_R= opt_b= 
        if [[ -n $clinfo ]]; then
            case $clinfo in
                @(1|y|t)*) opt_i=-i ;;
                    @(c)*) opt_i=-I ;;
            esac
        fi
        if [[ -n $restart ]]; then
            case $restart in
                @(1|y|t)*) opt_R=-R ;;  # Automatically restart
                        *) opt_R=-N ;;  # No auto-restart
            esac
        fi
        if [[ -n $broadcast ]]; then
            case $broadcast in
                @(1|y|t)*) opt_b=-b ;;  # Broadcast at startup
                        *) opt_b=   ;;  # Disable startup broadcast
            esac
        fi

        if [[ -z $LOCAL_NODE || $LOCAL_NODE == $node ]]; then
            print "$0()[$LINENO]($SECONDS): $HAUTILS/cl_auto_versync_options -s $opt_R $opt_b $opt_i" >>$CLMGR_TMPLOG  # Always log commands
            $HAUTILS/cl_auto_versync_options -s $opt_R $opt_b $opt_i 
        else
            print "$0()[$LINENO]($SECONDS): $CLRSH $node $HAUTILS/cl_auto_versync_options -s $opt_R $opt_b $opt_i" >>$CLMGR_TMPLOG  # Always log commands
            $CLRSH $node $HAUTILS/cl_auto_versync_options -s $opt_R $opt_b $opt_i 
        fi
        rc=$?
        print "cl_auto_versync_options RC: $rc" >>$CLMGR_TMPLOG  # Always log command result
        (( $rc != RC_SUCCESS )) && rc=$RC_ERROR
    fi

    #=========================================================
    : If any persistent IP changes were specified, make them
    #=========================================================
    if (( $rc == RC_UNKNOWN || $rc == RC_SUCCESS )); then
        if [[ -n $persistentIP ]]; then
            if [[ -n $network ]]; then
                print "$0()[$LINENO]($SECONDS): $HAUTILS/clodmget -q \"name = $network\" -f nimname HACMPnetwork" >>$CLMGR_TMPLOG  # Always log commands
                typeset NETTYPE=$($HAUTILS/clodmget -q "name = $network" -f nimname HACMPnetwork)
                print "clodmget RC: $rc; NETTYPE == \"$NETTYPE\"" >>$CLMGR_TMPLOG  # Always log command result

                # Usage: claddnode [-n <name>] -a <adapter>:<net-type>:<net-name>:<attr>:<func>:[<ipaddr|device-file>]:[<hwaddr>]
                if [[ -n $prefix ]]; then
                    print "$0()[$LINENO]($SECONDS): $HAUTILS/claddnode -n \"$node\" -a $persistentIP:${NETTYPE//\\\"/}:$network::persistent:::$prefix" >>$CLMGR_TMPLOG  # Always log commands
                    $HAUTILS/claddnode -n "$node" -a $persistentIP:${NETTYPE//\"/}:$network::persistent:::$prefix
                else
                    print "$0()[$LINENO]($SECONDS): $HAUTILS/claddnode -n \"$node\" -a $persistentIP:${NETTYPE//\\\"/}:$network::persistent:::$netmask" >>$CLMGR_TMPLOG  # Always log commands
                    $HAUTILS/claddnode -n "$node" -a $persistentIP:${NETTYPE//\"/}:$network::persistent:::$netmask
                fi
                rc=$?
                print "claddnode RC: $rc" >>$CLMGR_TMPLOG  # Always log command result
                (( $rc != RC_SUCCESS )) && rc=$RC_ERROR

            else
                /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 101 "\nERROR: this operation requires the \"%1\$s\" attribute.\n\n" NETWORK 1>&2
                rc=$RC_MISSING_INPUT
            fi

        elif [[ -n $network ]]; then
            /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 101 "\nERROR: this operation requires the \"%1\$s\" attribute.\n\n" PERSISTENT_IP 1>&2
            rc=$RC_MISSING_INPUT
        fi
    fi

    #==========================================================
    : If enabling/disabling Live Update was specified, make it
    #==========================================================
    if (( $rc == RC_UNKNOWN || $rc == RC_SUCCESS )) && \
       [[ -n $enable_lku ]]
    then
        typeset opt_l=
        case $enable_lku in
            @(1|y|t)*) opt_l=""   ;;  # Enable AIX Live Update
                    *) opt_l="-u" ;;  # Disable AIX Live Update
        esac
        if [[ -z $LOCAL_NODE || $LOCAL_NODE == $node ]]; then
            print "$0()[$LINENO]($SECONDS): $HAUTILS/clenablelku $opt_l" >>$CLMGR_TMPLOG  # Always log commands
            $HAUTILS/clenablelku $opt_l >>$CLMGR_TMPLOG 2>&1
        else
            print "$0()[$LINENO]($SECONDS): $CLRSH $node $HAUTILS/clenablelku $opt_l" >>$CLMGR_TMPLOG  # Always log commands
            $CLRSH $node $HAUTILS/clenablelku $opt_l >>$CLMGR_TMPLOG 2>&1
        fi
        rc=$?
        print "clenablelku rc=$rc" >>$CLMGR_TMPLOG  # Always log command result
        # cleanablelku return 6 when live update not supported by AIX
        if (( $rc == 6 )); then
            dspmsg -s $CLMGR_SET $CLMGR_MSGS 1462 '\tCurrent AIX level %1$s does not support Live kernel update operation.\n\tLive kernel update feature is available from AIX 7.2\n' "$(oslevel -s)" 1>&2
            rc=$RC_ERROR
        fi	
        (( $rc != RC_SUCCESS )) && rc=$RC_ERROR
    fi

    #==========================================================
    : If enabling CAA was specified, make it
    #==========================================================
    if (( $rc == RC_UNKNOWN || $rc == RC_SUCCESS )) && \
       [[ -n $enable_caa_after_merge ]]
    then
        typeset opt_l=
        case $enable_caa_after_merge in
            @(1|y|t)*) opt_l="yes"   ;;  # Enable CAA after merge
                    *) opt_l="no" ;;  # Disable CAA
        esac
        if [[ -z $LOCAL_NODE || $LOCAL_NODE == $node ]]; then
            print "$0()[$LINENO]($SECONDS): $HAUTILS/clenablepostsplit $opt_l" >>$CLMGR_TMPLOG  # Always log commands
            $HAUTILS/clenablepostsplit $opt_l >>$CLMGR_TMPLOG 2>&1
        else
            print "$0()[$LINENO]($SECONDS): $CLRSH $node $HAUTILS/clenablepostsplit $opt_l" >>$CLMGR_TMPLOG  # Always log commands
            $CLRSH $node $HAUTILS/clenablepostsplit $opt_l >>$CLMGR_TMPLOG 2>&1
        fi
        rc=$?
        print "clenablepostsplit rc=$rc" >>$CLMGR_TMPLOG  # Always log command result
        (( $rc != RC_SUCCESS )) && rc=$RC_ERROR
    fi

    #===========================================================
    : if any sys mg exists with modified node name, then
    : change the odm
    #===========================================================
    if (( $rc == RC_UNKNOWN || $rc == RC_SUCCESS )); then
        if [[ -f $HAXDCLI/clxd_list_mg ]] &&
           lscluster -c >>$CLMGR_TMPLOG 2>&1
        then  # XD might *not* be installed!!
            if [[ -n $old_node_ ]]; then
                if [[ -n $new_node_ ]]; then
                    typeset is_clxd=$($HAXDCLI/clxd_list_mg -d:|tail +2 2>/dev/null)
                    if [[ -n $is_clxd ]]; then
                        print "HACMPxd_ext_attr:\nvalue=$new_node_" |\
                        odmchange -o HACMPxd_ext_attr -q "field_type=NODE and value=$old_node_" 2>/dev/null
                        rc=$?
                        /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 772 "\nModifying node with name \"%1\$s\" in system mirror group completed with RC = \"%2\$d\".\n\n" "$old_node_" "$rc"
                        if (( $rc == RC_SUCCESS )); then
                            $HAXDCLI/clxd_refresh
                            rc=$?
                        fi
                        (( $rc != RC_SUCCESS )) && rc=$RC_ERROR
                    fi
                fi
            fi
        fi
    fi

    #==============================================================
    : Modify node name for critical daemon restart grace period
    : This Block will execute only if user tries to modify nodename
    : and not passed critical daemon restart grace period,
    : then updating odm with backup value.
    #==============================================================
    if (( $rc == RC_UNKNOWN || $rc == RC_SUCCESS )) && [[ -n $new_node_ && -n $old_node_ ]];then
       if [[ -z $crit_daemon_restart_grace_period && -n $daemon_grace_period_bkp ]]; then
          typeset node_data
          node_data=$(clodmget -q "object=COMMUNICATION_PATH and name=$new_node" -f node_id,node_handle,version HACMPnode)
          print -- "$node_data" | IFS=: read id handle ver
          print "HACMPnode: name=$node\nobject = CRIT_DAEMON_RESTART_GRACE_PERIOD\nvalue=$daemon_grace_period_bkp\nnode_id=$id\nnode_handle=$handle\nversion=$ver" | odmadd 2>/dev/null
          rc=$?
          if (( $rc != RC_SUCCESS ));then
              cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1453 '\nERROR: An error occurred while configuring critical daemon restart grace period for node "%1$s".\n\n' "$node" 1>&2
          fi 
       fi
    fi

    #==============================================================
    : Modify critical daemon restart grace period for node $node
    #==============================================================
    if (( $rc == RC_UNKNOWN || $rc == RC_SUCCESS )) && \
       [[ -n $crit_daemon_restart_grace_period ]] ; then
       typeset rsct_grace_period
       rsct_grace_period=$(clodmget -n -q "object=CRIT_DAEMON_RESTART_GRACE_PERIOD and name=$node" -f value HACMPnode)
       if [[ -z $rsct_grace_period ]];then
           typeset node_data
           node_data=$(clodmget -q "object=COMMUNICATION_PATH and name=$node" -f node_id,node_handle,version HACMPnode)
           print -- "$node_data" | IFS=: read id handle ver
           print "HACMPnode: name=$node\nobject = CRIT_DAEMON_RESTART_GRACE_PERIOD\nvalue=$crit_daemon_restart_grace_period\nnode_id=$id\nnode_handle=$handle\nversion=$ver" | odmadd 2>/dev/null
           rc=$?
           if (( $rc != RC_SUCCESS ));then
              cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1453 '\nERROR: An error occurred while configuring critical daemon restart grace period for node "%1$s".\n\n' "$node" 1>&2
           else
              cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1454 "\nSuccessfully configured the node level RSCT critical daemon restart grace period for node %1\$s.\n" $node
           fi
       else
           print "HACMPnode: value = $crit_daemon_restart_grace_period" | odmchange -q "name=$node and object=CRIT_DAEMON_RESTART_GRACE_PERIOD" -o HACMPnode
           rc=$?
           if (( $rc != RC_SUCCESS ));then
               cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1453 '\nERROR: An error occurred while configuring critical daemon restart grace period for node "%1$s".\n\n' "$node" 1>&2
           else
              cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1454 "\nSuccessfully configured the node level RSCT critical daemon restart grace period for node %1\$s.\n" $node
           fi
       fi
    fi
 
    #===========================================================
    : If output from this operation was requested, retrieve it
    #===========================================================
    if (( $rc == RC_SUCCESS )); then
        if (( CLMGR_VERBOSE )) || [[ -n $CLMGR_ATTRS ]]; then
            CL=$LINENO KLIB_HACMP_get_node_attributes "$node" properties
        fi
    fi

    #=======================================================================
    : If a user input error was detected, provide some helpful suggestions
    #=======================================================================
    if (( $rc == RC_MISSING_INPUT || $rc == RC_INCORRECT_INPUT )) && \
       [[ $CLMGR_GUI == *([[:space:]]) ]]
    then
        CL=$LINENO cl_dspmsg -s $CLMGR_SET $CLMGR_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" \
        "modify node -h" "NODE:" "$CLMGR_PROGNAME" 1>&2
    fi

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