#!/bin/ksh93
#  ALTRAN_PROLOG_BEGIN_TAG
#  This is an automatically generated prolog.
#
#  Copyright (C) Altran ACT S.A.S. 2017,2019,2020,2021.  All rights reserved.
#
#  ALTRAN_PROLOG_END_TAG
#
# @(#)  03a409f 43haes/lib/ksh93/hacmp/KLIB_HACMP_modify_cluster.sh, 726, 2147A_aha726, May 19 2021 03:11 PM

#======================================================================
#If signature of properties for modify cluster need to be changed,make
#sure that same changes are done in KLIB_HACMP_add_cluster,
#resource_modify.
#======================================================================

#============================================================================
#
# Name:        devDoc
#
# Description: This is a never-to-be-called, wrapper function that all the
#              clmgr FPATH functions implement in order to hide embedded
#              syntax from trace logging. This information is implemented
#              in POD format, and can be viewed in a number of ways using
#              POD tools. Some viewing suggestions for this function's POD-
#              formatted information are:
#
#                  perldoc <FILENAME>
#                  pod2text -c <FILENAME>
#                  pod2text -c --code <FILENAME>
#                  pod2html <FILENAME>
#
#              However, the more important use for this information is that
#              it is parsed by clmgr to display the syntax for this file's
#              operation. The information in the "SYNOPSIS" section is used
#              for this purpose. This feature was originally implemented
#              using the man page information. However, in a code review it
#              was pointed out that this approach had to be changed because
#              customers do not have to install the man pages! Therefore, a
#              built-in dependency on man page information would break the
#              automatic help feature of clmgr. So the SYNPOSIS section must
#              be used instead.
#
#              IMPORTANT: As a result of this, it is imperative that the
#                         information in this SYNOPSIS be kept in sync
#                         with the man page information, which is owned
#                         by the IDD team.
#
# Inputs:      None.
#
# Outputs:     None.
#
# Returns:     n/a (not intended to be invoked)
#
#============================================================================
function devDoc {
    : <<'=cut' >/dev/null 2>&1

=head1 NAME

 KLIB_HACMP_modify_cluster

=head1 SYNOPSIS

 clmgr modify cluster \
             [ NAME=<new_cluster_label> ] \
             [ NODES=<host>[,<host#2>,...] ] \
             [ TYPE={NSC|SC} ] \
             [ HEARTBEAT_TYPE={unicast|multicast} ] \
             [ CLUSTER_IP=<IP_Address> ] \
             [ REPOSITORIES=<disk>[,<backup_disk>,...] ] \
             [ FC_SYNC_INTERVAL=## ] \
             [ RG_SETTLING_TIME=## ] \
             [ MAX_EVENT_TIME=### ] \
             [ MAX_RG_PROCESSING_TIME=### ] \
             [ DAILY_VERIFICATION={Enabled|Disabled} ] \
             [ VERIFICATION_NODE={Default|<node>} ] \
             [ VERIFICATION_HOUR=<00..23> ] \
             [ VERIFICATION_DEBUGGING={Enabled|Disabled} ] \
             [ HEARTBEAT_FREQUENCY=<min....max> ] \
             [ GRACE_PERIOD=<min..max> ] \
             [ SITE_POLICY_FAILURE_ACTION={fallover|notify} ] \
             [ SITE_POLICY_NOTIFY_METHOD="<FULL_PATH_TO_FILE>" ]
             [ SITE_HEARTBEAT_CYCLE=<min..max> ] \
             [ SITE_GRACE_PERIOD=### ] \
             [ TEMP_HOSTNAME={disallow|allow} ] \
             [ LPM_POLICY={manage|unmanage} ] \
             [ HEARTBEAT_FREQUENCY_DURING_LPM=### ] \
             [ NETWORK_FAILURE_DETECTION_TIME=<0,5...590> ] \
             [ CAA_AUTO_START_DR={Enabled|Disabled} ] \
             [ CAA_REPOS_MODE={assert|event} ] \
             [ CAA_CONFIG_TIMEOUT=<0..2147483647> ] \
             [ LVM_PREFERRED_READ=<roundrobin|favorcopy|siteaffinity> ] \
             [ CRIT_DAEMON_RESTART_GRACE_PERIOD=<0..240> ] \
             [ SKIP_EVENT_PROCESSING_MANAGE_MODE={true|false} ]

 clmgr modify cluster \
             [ NAME=<new_cluster_label> ] \
             [ NODES=<host>[,<host#2>,...] ] \
             [ TYPE="LC" ] \
             [ HEARTBEAT_TYPE={unicast|multicast} ] \
             [ FC_SYNC_INTERVAL=## ] \
             [ RG_SETTLING_TIME=## ] \
             [ MAX_EVENT_TIME=### ] \
             [ MAX_RG_PROCESSING_TIME=### ] \
             [ DAILY_VERIFICATION={Enabled|Disabled} ] \
             [ VERIFICATION_NODE={Default|<node>} ] \
             [ VERIFICATION_HOUR=<00..23> ] \
             [ VERIFICATION_DEBUGGING={Enabled|Disabled} ] \
             [ HEARTBEAT_FREQUENCY=<min...max> ] \
             [ GRACE_PERIOD=<min..max> ] \
             [ SITE_POLICY_FAILURE_ACTION={fallover|notify} ] \
             [ SITE_POLICY_NOTIFY_METHOD="<FULL_PATH_TO_FILE>" ]
             [ SITE_HEARTBEAT_CYCLE=<min..max> ] \
             [ SITE_GRACE_PERIOD=### ] \
             [ TEMP_HOSTNAME={disallow|allow} ] \
             [ LPM_POLICY={manage|unmanage} ] \
             [ HEARTBEAT_FREQUENCY_DURING_LPM=### ] \
             [ NETWORK_FAILURE_DETECTION_TIME=<0,5...590> ] \
             [ CAA_REPOS_MODE={assert|event} ] \
             [ CAA_CONFIG_TIMEOUT=<0..2147483647> ] \
             [ LVM_PREFERRED_READ=<roundrobin|favorcopy|siteaffinity> ] \
             [ CRIT_DAEMON_RESTART_GRACE_PERIOD=<0..240> ] \
             [ SKIP_EVENT_PROCESSING_MANAGE_MODE={true|false} ]

 NOTE: "NSC": "Non-Site Cluster"; no sites will be defined.
        "SC": "Stretched Cluster"; simplified infrastructure, ideal
              for limited distance data replication. Sites *must* be
              defined.
        "LC": "Linked Cluster"; full-featured infrastructure, ideal
              for long distance data replication. Sites *must* be
              defined.
 NOTE: the cluster name cannot be modified once the cluster is fully
       defined and synchronized.
 NOTE: the cluster type cannot be modified once the cluster is fully
       defined and synchronized if sites are already in use.
 NOTE: "CLUSTER_IP" may only be used with a cluster type of "NSC"
       or "SC".
NOTE: "REPOSITORIES" may only be used with a cluster type of "NSC"
       or "SC". No more than MAX_NB_OF_BACKUP_REPOSITORIES backup
       repository disks may be defined per "NSC" or "SC" cluster.
 NOTE: the "RG_SETTLING_TIME" attribute only affects resource groups
       with a startup policy of "Online On First Available Node".

 : Split-merge support for linked clusters only
 clmgr modify cluster \
              [ SPLIT_POLICY={none|tiebreaker|manual|NFS|Cloud} ] \
                 [ TIEBREAKER=<disk> ] \
                 [ CLOUD_SERVICE={ibm|aws} ] \
                 [ BUCKET_NAME={<bucket_name>} ] \
                 [ USE_EXISTING_BUCKET={yes|no} ] \
             [ MERGE_POLICY={none|majority|tiebreaker|manual|NFS|Cloud} ] \
                 [ NFS_QUORUM_SERVER=<server> ] \
                 [ LOCAL_QUORUM_DIRECTORY=<local_mount>] \
                 [ REMOTE_QUORUM_DIRECTORY=<remote_mount>] \
                 [ QUARANTINE_POLICY=<disable|node_halt|fencing|halt_with_fencing>] \
                 [ CRITICAL_RG=<rgname> ] \
                 [ NOTIFY_METHOD=<method> ] \
                 [ NOTIFY_INTERVAL=### ] \
                 [ MAXIMUM_NOTIFICATIONS=### ] \
                 [ DEFAULT_SURVIVING_SITE=<site> ] \
                 [ APPLY_TO_PPRC_TAKEOVER={yes|no} ] \
[ ACTION_PLAN={reboot|disable_rgs_autostart|disable_cluster_services_autostart} ]

 NOTE: the alias for "cluster" is "cl".

=head1 DESCRIPTION

Attempts to modify the cluster configuration to
conform to the provided specifications.

=head1 ARGUMENTS

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

 2. new_name [OPTIONAL] [string]
    The new label to attempt to apply to the cluster.

 3. fc_sync_interval [OPTIONAL] [integer]
    A new file collection propagation interval to apply to the cluster.

 4. rg_settling_time [OPTIONAL] [integer]
    A new resource group settling time to apply to the cluster.

 5. rg_dist_policy [OPTIONAL] [set]
    A new resource group distribution policy to apply to the cluster,
    from the set {node|network}.

 6. max_event_time [OPTIONAL] [integer]
    The maximum number of seconds to allot for an event to complete
    its processing. If this limit is exceeded, a CONFIG_TOO_LONG
    error will occur.

 7. max_rg_processing_time [OPTIONAL] [integer]
    The maximum number of seconds to allot for a resource group-related
    event to complete its processing (this value is added to the
    max_event_time to arrive at the total time limit). If this limit is
    exceeded, a CONFIG_TOO_LONG error will occur.

 8. faction [OPTIONAL] [set]
    A new site policy failure action to apply to the cluster (if sites
    are configured within the cluster), from the set {fallover|notify}.

 9. nmethod [OPTIONAL] [string]
    A new site policy notify method to use within the cluster (if sites
    are configured within the cluster).

 10. autover [OPTIONAL] [string]
    A Boolean-like toggle to indicate if automatic, daily verification
    should be performed.

 11. autover_node [OPTIONAL] [string]
    An indicator of which node to initiate the automatic verification
    on.

 12. autover_hour [OPTIONAL] [string]
    The hour when the automatic verification should be launched.

 13. autover_debug [OPTIONAL] [string]
    A Boolean-like toggle to indicate if the automatic verification
    should be run with debugging enabled.

 14. repositories [OPTIONAL] [string]
    One or more disks that will be added as repository disks within the
    cluster.
    First disk is the active repository, and following ones are
    backup repositories. Nor more than MAX_NB_OF_BACKUP_REPOSITORIES
    backup repositories are accepted.
    If a CAA cluster is detected, then the disks will be treated
    as backup repositories.

 15. cluster_ip [OPTIONAL] [string]
    A multicast IP address that will be used for CAA communications within
    the cluster.

 16. heartbeat [OPTIONAL] [posint]
    This attribute controls the frequency with which the node heartbeats
    across the various enabled heart beating sources. It is stated in
    terms of the number of milliseconds that another node may consider
    node X to be DOWN if it receives no incoming heartbeats from node X.
    CAA uses this attribute to control the frequency of Gossip Packets,
    the aggregated heartbeat message sent by gateway servers in linked
    clusters as well as the interval based heartbeat algorithms that
    tick over SAN and DISK. The default value is 20. The valid range
    differs depending on AIX version. Hence the value is directly taken
    from AIX.

 17. node_down_delay [OPTIONAL] [posint]
    This attribute controls the behavior of the node monitor which
    periodically evaluates the set of activated heart beating sources
    to determine whether a node is UP or DOWN. This attribute specifies
    the amount of time in milliseconds that the node monitor must wait
    after it makes the determination that another node is DOWN before
    posting it as DOWN. The default value is 10. The valid range
    differs depending on AIX version. Hence the value is directly taken
    from AIX.

 18. site_heartbeat_cycle [OPTIONAL] [posint]
    The remote_HB_factor defines how infrequently CAA would be periodically
    unreliable message to remote site. This factor is a scaling factor, it
    would be set to 10 by default with a range of 1 to 100. This means a
    periodic message would be sent to the remote site once for every 10 same
    type of message sent locally.

 19. site_grace_period [OPTIONAL] [posint]
    This refers to link_timeout in CAA design. This attribute is applied as
    a delta to the node timeout for nodes that are in remote sites. That is,
    the node monitor will wait "node_timeout + link_timeout" seconds before
    determining that a remote node is DOWN. Then, it will wait an additional
    node_down_delay seconds before posting that the remote node is DOWN.

 20. type [OPTIONAL] [set]
     "NSC": "Non-Site Cluster"; no sites will be defined.
      "SC": "Stretched Cluster"; simplified infrastructure, ideal for
            limited distance data replication. Sites *must* be defined.
      "LC": "Linked Cluster"; full-featured infrastructure, ideal for
            long distance data replication. Sites *must* be defined.
    NOTE: the cluster type cannot be modified once the cluster is fully
          defined and synchronized if sites are already in use.

 21. heartbeat_type [OPTIONAL] [set]
    This determines whether CAA will use unicast or multicast
    heartbeat on the cluster. If unicast is chosen, then the
    cluster IP address is not used.

    Valid values: unicast, multicast

 22. temp_hostname
    Toggles the honorTempHostNameChanges setting in HACMPcluster,
    indicating if temporary hostname changes (i.e. via the "hostname"
    command) should be allowed.

 ======================
   Split-Merge Inputs
 ======================
 23. split_policy [OPTIONAL] [set]
    The split handling policy specifies the response when a split has
    been detected in a cluster.  A choice of "None" takes no action;
    the other choices select a mechanism to identify which portion of
    the cluster will continue.

    Valid values include: none, tiebreaker, manual

    Defaults to "none".

 24. merge_policy
    The merge handling policy specifies the mechanism to identify
    which part of a split cluster will continue after the merge.

    Valid values include: majority, none, tiebreaker, nfs, manual

    Defaults to "majority".

 25. quaratine_policy
     Cluster wide Quarantine policy informs PowerHA SystemMirror
     about the method it should use to isolate a unresponsive node
     that was hosting the Critical Resource Group previously.

 26. critical_rg
     A Resource Group for which the selected Quarantine Policy
     would be applicable.
     All the resources assosciated with this Resource Group would be
     handled by the Quarantine Policy that was configured.


 27. action_plan
    The action plan describes the action taken on the nodes in the
    portion of a cluster that has split, or has merged after a split,
    and which has not been selected to continue.

    Valid values include: reboot,disable_rgs_autostart,disable_cluster_services_autostart
    1.reboot - Nodes on the loosing partition will be rebooted.
    2.disable_rgs_autostart - Nodes  on the loosing partition will be rebooted,
    the Resource Groups can not be brought online until merge is finished.
    3. disable_cluster_services_autostart - Nodes  on the loosing partition
    will be rebooted, manual intervention is needed to bring the cluster back
    to stable state.

    Defaults to "Disable_cluster_services_autostart". 
    Defaults to "Reboot" for AIX level less than 7210.

  28. tiebreaker [OPTIONAL] [set]
    In the event of a split or merge for which the "tiebreaker"
    policy is selected, the portion of the cluster that can first
    access the tie breaker disk will continue. Select the "None"
    option to have the tie breaker specification removed. If a tie
    breaker is selected, but neither split nor merge policy uses as
    tie breaker, the specification is accepted, but unused. Once a
    disk has been specified to be a tie breaker, it is not available
    for use in a volume group, or for any other purpose.

 29. nfs_quorum_server
    The hostname of the used NFSv4 server. Enter the Fully Qualified
    Domain Name.
    Example :
    NodeA.in.ibm.com.

 30. local_quorum_directory
     Enter the Absolute Path of the  Local node directory, which is use
     by the NFS TieBreaker Server as a Local Mount Point.

 31. remote_quorum_directory
     Enter the Absolute Path of the NFS TieBreaker Server directory,
     which is exported by the nfsQuorumServer.
 32. notify_method
    A script to run that will notify whomever needs to know
    that the cluster has been split.


 33. notify_interval
    The amount of time to wait before running the notify method
    again. If maximum notifications is set to one, then this
    input is not used.

 34. maximum_notifications
    The maximum number of times to run the notify method before
    giving up.

 35. typeset default_surviving_site
    The site that is to be given preferential treatment when

    a winner when the merge policy is set to "priority". This user-
    provided input indicates which site survives.

 36. apply_to_pprc_takeover

 37. nodes [OPTIONAL] [string]
     A full-membership node list for the cluster. Must contain the
     local node.

 38. lpm_policy [OPTIONAL] [set]
    The LPM policy specifies the action to be taken on the node during
    a Live Partition Mobility operation. If "unmanage" is selected, the
    cluster services are stopped with the 'Unmanage Resource Groups'
    option during the duration of the LPM operation. Otherwise PowerHA
    SystemMirror will continue to monitor the resource group(s) and
    application availablity.

    Valid values include: manage, unmanage

    Defaults to "manage".

 39. lpm_heartbeat [OPTIONAL] [posint]
    This attribute supersedes the value of the heartbeat attribute
    during the time of a Live Partition Mobility processing.
    Default value is 600 and range is 10-600.
    Unit is second.

 40. Node Failure Detection Time
    This attribute determines the amount of time CAA would wait to
    give a network failure notification.It is stated in terms of
    milliseconds.The default value is 10.The valid range differs
    depending on AIX version. Hence the value is directly taken
    from AIX.

 41. caa_auto_start_dr [OPTIONAL] [string]
    Sets a CAA tunable to enable/disable PVID based identification
    of repository disk(s) during disaster recovery.

 42. caa_repos_mode [OPTIONAL] [string]
    This attribute controls node behavior when cluster repository
    access is lost. Default value is "event" and valid values are
    assert and event.

 43. caa_config_timeout [OPTIONAL] [integer]
    This attribute controls the timeout for coordinated configuration
    changes. Default value is 240 and range is 0-2147483647.
    Unit is second.

 44. lvm_preferred_read [OPTIONAL] [string]
    This attribute controls LVM read operations when there are mirror pools.
    This option decides which copy should be used for reading the data.
    Supported options are roundrobin, favorcopy or siteaffinity. 
    favorcopy - Choose if you would like to read from Flash storage. 
    siteaffinity - Choose if you would like to read from local storage path 
    always based on the resource group location. 
    siteaffinity option is available only for site based clusters.

45. 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.

46. skip_events_on_manage [OPTIONAL] [boolean]
    Set this flag to true to skip any event processing when cluster services
    are started after stopping with the unmanaged option.

47. bucket_name [OPTIONAL] [string]
    Provide bucket_name when split merge policy is configured as Cloud-Cloud.
    During split and merge scenario, PowerHA tries to upload the Cloud tiebreaker file
    in to provided bucket.

48. cloud_service [OPTIONAL] [string]
    Provide cloud_service when split merge policy is configured as Cloud-Cloud.
    This is the cloud service provider. It can be either ibm or aws.

49. use_existing_bucket [OPTIONAL] [boolean]
    Provide this option when split merge policy is configured as Cloud-Cloud.
    Supported values are yes or no. If this is set to yes, then the cloud
    tiebreaker file will upload to existing bucket which is provided. If
    this is set to no, then new bucket name will be created with the provided
    bucket name.

=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.


#==============================================================================
#
# Name:          list_tie_breaker_disks
#
# Description: Borrows the logic (and a great deal of code!) from the SMIT
#              panel "command to list" for the Tie Breaker pick list. Lists
#              all potential tie breaker disks on STDOUT.
#
# Inputs:      None.
#
# Outputs:     All potential tie breaker disks are displayed on STDOUT in
#              the following format:
#
#              hdisk0  (00caed8c11314304) on node r8r4m11 at site austin
#
# Returns:     Zero if the disks (if any) were listed successfully.
#              Otherwise a non-zero value is returned.
#
#==============================================================================
function list_tie_breaker_disks {
    . $HALIBROOT/log_entry "$0()" "$CL"

    typeset -i rc=$RC_UNKNOWN

    #
    : Check for hyperswap present in the environment
    #
    typeset hs_check=""
    if whence lspprc > /dev/null 2>&1
    then
        hs_check=TRUE
    fi

    #
    : List free disks that can function as a repository
    #
    typeset nodelist=$(clnodename)
    typeset last_good_disk=""
    LC_ALL=C cllspvids -P $nodelist >$TMPDIR/clmgr.KHmc.ltbd.$$
    rc=$?
    (( rc != RC_SUCCESS )) && rm -f $TMPDIR/clmgr.KHmc.ltbd.$$

    while read line; do
        #
        : For each line from cllspvids, pick up the PVID
        #
        typeset pvid=""
        print "$line" | read skip pvid skip
        pvid=${pvid#\(}
        pvid=${pvid%\)}

        #
        : Get the local disk name.
        : Display a line if its the same disk as a previously displayed disk,
        : or its a new disk that supports a reserve policy of PR_exclusive
        #
        if [[ $last_good_disk == $pvid ]]
        then
            print -- "\t$line"  # same disk, different name
        else
            typeset local_hdisk_name=$(clodmget -q "attribute = pvid and value like ${pvid}*" -f name -n CuAt)
            if [[ -n $hs_check ]] && lspprc -p $local_hdisk_name >/dev/null 2>&1
            then
                #
                : Skip hyperswap enabled disks
                #
                continue
            elif LC_ALL=C lsattr -R -l $local_hdisk_name -a reserve_policy | grep -qw PR_exclusive
            then
                #
                : Only if this device supports a reserve_policy
                : of PR_exclusive is it displayed
                #
                print -- "\t$line"
                last_good_disk=$pvid
            fi
        fi
    done <$TMPDIR/clmgr.KHmc.ltbd.$$
    rm -f $TMPDIR/clmgr.KHmc.ltbd.$$

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


#==============================================================================
#
# Name:        handle_split_merge
#
# Description: If any split-merge manipulations are requested, this
#              function is invoked to handle them. It attempts to
#              perform any input validations the the "cl_sm" does
#              not (because SMIT does it automatically).
#
# Inputs:      split_policy   One of {none|tiebreaker|nfs|manual}.
#              merge_policy   One of {none|majority|manual|tiebreaker|nfs}.
#              action_plan    One of {reboot|disable_rgs_autostart|disable_cluster_services_autostart}.
#              nfs_quorum_server hostname of the used NFSv4 server
#              local_quorum_directory Absolute Path of the  Local node directory
#              remote_quorum_directory Absolute Path of the NFS TieBreaker Server
#                                     directory
#              quarantine_policy Cluster wide Quarantine policy
#              critical_rg     Resource Group for which the selected Quarantine
#                              Policy would be applicable.
#              tiebreaker     An available disk shared by all nodes in the
#                             cluster.
#              notify_method  An executable to invoke when a split occurs,
#                             ostensibly to notify one or more admins that
#                             something very bad has happened.
#              notify_interval  Number of seconds between each repeated
#                             invocation of the notify method.
#              maximum_notifications  Maximum number of times to invoke the
#                             notify method before going silent.
#              default_surviving_site  The default surviving site.
#              apply_to_pprc_takeover  One of {yes|no}.
#              bucket_name   Cloud bucket to which the cloud tie breaker file 
#                            should upload.
#              cloud_service Cloud service provider name
#              use_existing_bucket  if yes, use provided bucket
#                                   if no, create a new bucket with bucket_name
#
# Outputs:     Any errors are written to STDERR. Otherwise, cl_sm displays
#              results of the operation on STDOUT.
#
# Returns:     Zero if operation succeeded; non-zero otherwise.
#
#==============================================================================
function handle_split_merge {
    . $HALIBROOT/log_entry "$0()" "$CL"

    typeset split_policy=$1
    typeset merge_policy=$2
    typeset nfs_quorum_server=$3
    typeset local_quorum_directory=$4
    typeset remote_quorum_directory=$5
    typeset quarantine_policy=$6
    typeset critical_rg=$7
    typeset action_plan=$8
    typeset tiebreaker=$9
    typeset notify_method=${10}
    typeset notify_interval=${11}
    typeset maximum_notifications=${12}
    typeset default_surviving_site=${13}
    typeset apply_to_pprc_takeover=${14}
    typeset bucket_name=${15}
    typeset cloud_service=${16}
    typeset use_existing_bucket=${17}

    typeset -i rc=$RC_UNKNOWN cmd_rc=$RC_UNKNOWN

    if [[ $split_policy != *([[:space:]]) ]]; then
        CL=$LINENO verify_in_set SPLIT_POLICY "$split_policy" "None, TieBreaker, Manual, NFS, Cloud" split_policy
        (( $? != RC_SUCCESS )) && rc=$RC_INCORRECT_INPUT
    fi

    if [[ $merge_policy != *([[:space:]]) ]]; then
        CL=$LINENO verify_in_set MERGE_POLICY "$merge_policy" "None, Majority, Manual, TieBreaker, NFS, Cloud" merge_policy
        (( $? != RC_SUCCESS )) && rc=$RC_INCORRECT_INPUT
    fi

    if [[ $action_plan != *([[:space:]]) ]]; then
        CL=$LINENO verify_in_set ACTION_PLAN "$action_plan" "Reboot,Disable_rgs_autostart,Disable_cluster_services_autostart" action_plan
        (( $? != RC_SUCCESS )) && rc=$RC_INCORRECT_INPUT
    fi

    if [[ $tiebreaker != *([[:space:]]) ]]; then
        if [[ $split_policy != "TieBreaker" || $merge_policy != "TieBreaker" ]]; then
            /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 1447 "\nERROR: TieBreaker disk option is supported only for split policy 'TieBreaker' and merge policy 'TieBreaker'.\n\n" 1>&2
            rc=$RC_INCORRECT_INPUT
        else
            if [[ $tiebreaker == *\(* ]]; then
                # The tie breaker is in "<DEVICE_NAME (PVID)>" format
                typeset PVID=${tiebreaker##*\(}
                        PVID=${PVID%%\)*}
                if [[ -n $PVID ]] && \
                   lspv | grep -qw $PVID
                then
                    tiebreaker=$PVID
                fi
                unset PVID
            fi
    
            #=================================================
            : Get the list of all possible tie breaker disks
            #=================================================
            typeset TIEBREAKERS=$(list_tie_breaker_disks | grep -we $LOCAL_NODE -e "on all nodes" -e "on all cluster nodes")
    
            typeset IDENTIFIERS=""
            CL=$LINENO KLIB_HACMP_is_known_physical_volume "$tiebreaker" "$LOCAL_NODE" IDENTIFIERS
            if (( $? != RC_SUCCESS )) || [[ -z $IDENTIFIERS ]]; then
                dspmsg -s $CLMGR_SET $CLMGR_MSGS 102 '\nERROR: "%1$s" does not appear to exist!\n\n' "$tiebreaker" 1>&2
                rc=$RC_NOT_FOUND
            else
                typeset -i FOUND=0
                typeset NODE="" DISK_LABEL="" DISK_PVID="" DISK_UUID="" REST=""
                print -- "$IDENTIFIERS" |\
                IFS=: read NODE DISK_LABEL DISK_PVID DISK_UUID REST
                typeset LINE=""
                print -- "$TIEBREAKERS" |\
                while read LINE; do
                    print -- "$LINE" | read TB_NAME TB_PVID REST
                    if [[ $DISK_PVID == ${TB_PVID//[\(\)]/} ]]; then
                        tiebreaker="${TB_PVID//[\(\)]/}"
                        FOUND=1
                        break
                    fi
                done
                if (( ! FOUND )); then
                    dspmsg -s $CLMGR_SET $CLMGR_MSGS 434 '\nERROR: "%1$s" appears to be unavailable.\n\n' "$tiebreaker" 1>&2
                    rc=$RC_INCORRECT_INPUT
                fi
            fi
    
            if (( rc != RC_UNKNOWN )); then
                dspmsg -s $CLMGR_SET $CLMGR_MSGS 153 "Available Physical Volumes:\n\n" 1>&2
                print -u2 -- "$TIEBREAKERS\n"
            fi
        fi
    fi

    if [[ -n $notify_interval ]]; then
        CL=$LINENO verify_is_numeric "$notify_interval" 2 "NOTIFY_INTERVAL"
        (( $? != RC_SUCCESS )) && rc=$RC_INCORRECT_INPUT
    fi

    if [[ -n $maximum_notifications ]]; then
        CL=$LINENO verify_is_numeric "$maximum_notifications" 2 "MAXIMUM_NOTIFICATIONS"
        (( $? != RC_SUCCESS )) && rc=$RC_INCORRECT_INPUT
    fi

    if [[ -n $default_surviving_site ]]; then
        CL=$LINENO KLIB_HACMP_is_known_site "$default_surviving_site" >/dev/null
        cmd_rc=$?
        if (( cmd_rc != RC_SUCCESS )); then
            dspmsg -s $CLMGR_SET $CLMGR_MSGS 102 '\nERROR: "%1$s" does not appear to exist!\n\n' "$default_surviving_site" 1>&2
            dspmsg -s $CLMGR_SET $CLMGR_MSGS 157 "Available Sites:\n\n" 1>&2

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

            rc=$RC_NOT_FOUND
        fi
    fi

    if [[ -n $apply_to_pprc_takeover ]]; then
        CL=$LINENO verify_in_set APPLY_TO_PPRC_TAKEOVER "$apply_to_pprc_takeover" "Yes, No" apply_to_pprc_takeover
        (( $? != RC_SUCCESS )) && rc=$RC_INCORRECT_INPUT
    fi

    if [[ -n $quarantine_policy ]];then
        CL=$LINENO verify_in_set QUARANTINE_POLICY "$quarantine_policy" "disable, node_halt, fencing , halt_with_fencing" quarantine_policy
        (( $? != RC_SUCCESS )) && rc=$RC_INCORRECT_INPUT
    fi

    if [[ -n $cloud_service ]];then
        CL=$LINENO verify_in_set CLOUD_SERVICE "$cloud_service" "ibm,aws" cloud_service 
        (( $? != RC_SUCCESS )) && rc=$RC_INCORRECT_INPUT
    fi

    if [[ -n $use_existing_bucket ]];then
        CL=$LINENO verify_in_set USE_EXISTING_BUCKET "$use_existing_bucket" "yes,no" use_existing_bucket 
        (( $? != RC_SUCCESS )) && rc=$RC_INCORRECT_INPUT
    fi

    typeset anhp="" scsi="" disable_policy=""

    if [[ -n $quarantine_policy ]];then
       if [[ $quarantine_policy == "node_halt" ]];then
             anhp="Yes"
             scsi="No"
       elif [[ $quarantine_policy == "fencing" ]];then
             scsi="Yes"
             anhp="No"
       elif [[ $quarantine_policy == "halt_with_fencing" ]];then
             anhp="Yes"
             scsi="Yes"
       elif [[ $quarantine_policy == "disable" ]];then
             disable_policy="Yes"
       fi
    fi

    if (( rc == RC_UNKNOWN )); then
        #================================================================
        : No obvious input errors were detected. Attempt the operation.
        #================================================================
        typeset aOpt="" iOpt="" mOpt="" nOpt="" sOpt=""
        typeset tOpt="" vOpt="" wOpt="" xOpt="" rOpt=""
        typeset kOpt="" gOpt="" pOpt="" bOpt="" dOpt=""
        typeset eOpt="" NOpt="" BOpt="" COpt="" uOpt=""

        [[ -n $merge_policy           ]] && mOpt=" -m $merge_policy"
        [[ -n $split_policy           ]] && sOpt=" -s $split_policy"
        [[ -n $nfs_quorum_server       ]] && kOpt=" -k $nfs_quorum_server"
        [[ -n $local_quorum_directory  ]] && gOpt=" -g $local_quorum_directory"
        [[ -n $remote_quorum_directory ]] && pOpt=" -p $remote_quorum_directory"
        [[ -n $anhp                   ]] && eOpt=" -e $anhp"
        [[ -n $scsi                   ]] && dOpt=" -d $scsi"
        [[ -n $critical_rg            ]] && bOpt=" -b $critical_rg"
        [[ -n $action_plan            ]] && aOpt=" -a $action_plan"
        [[ -n $tiebreaker             ]] && tOpt=" -t $tiebreaker"
        [[ -n $notify_method          ]] && nOpt=" -n $notify_method"
        [[ -n $notify_interval        ]] && iOpt=" -i $notify_interval"
        [[ -n $maximum_notifications  ]] && xOpt=" -x $maximum_notifications"
        [[ -n $default_surviving_site ]] && vOpt=" -v $default_surviving_site"
        [[ -n $apply_to_pprc_takeover ]] && rOpt=" -r $apply_to_pprc_takeover"
        [[ -n $disable_policy         ]] && NOpt=" -N"
        [[ -n $bucket_name         ]] && BOpt=" -B $bucket_name"
        [[ -n $cloud_service         ]] && COpt=" -C $cloud_service"
        [[ -n $use_existing_bucket   ]] && uOpt=" -u $use_existing_bucket"

        print -- "$0()[$LINENO]($SECONDS): cl_sm $wOpt$sOpt$mOpt$kOpt$gOpt$pOpt$eOpt$dOpt$bOpt$aOpt$tOpt$nOpt$iOpt$xOpt$vOpt$rOpt$NOpt$BOpt$COpt$uOpt" >>$CLMGR_TMPLOG
        cl_sm $wOpt$sOpt$mOpt$kOpt$gOpt$pOpt$eOpt$dOpt$bOpt$aOpt$tOpt$nOpt$iOpt$xOpt$vOpt$rOpt$NOpt$BOpt$COpt$uOpt

        rc=$?
        (( $rc == 255 )) && rc=1
        print -- "$0()[$LINENO]($SECONDS): cl_sm RC: $rc" >>$CLMGR_TMPLOG
    fi

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


#============================================================================
#
# Name:        KLIB_HACMP_modify_cluster
#
# Description: This is the main, FPATH function that is invoked by clmgr
#              to modify a cluster's properties.
#
# Inputs:      Too many to list! Please refer to the detailed listing, and
#              associated descriptions, in the "ARGUMENTS" section of the
#              "devDoc()" function, above.
#
# Outputs:     The properties hash is populated. The only other outputs are
#              any error messages that might be needed.
#
# Returns:     Zero if no errors are detected. Otherwise, an appropriate
#              non-zero value is returned. Refer to the "RETURN" section
#              of the "devDoc()" function, above, for the standard return\
#              code values/meanings for clmgr.
#
#============================================================================
function KLIB_HACMP_modify_cluster {
    . $HALIBROOT/log_entry "$0()" "$CL"
    : version=@(#)  03a409f 43haes/lib/ksh93/hacmp/KLIB_HACMP_modify_cluster.sh, 726, 2147A_aha726, May 19 2021 03:11 PM
    : INPUTS: $*

    typeset -n properties=$1
    # Remove the properties from the list of arguments
    shift

    typeset    new_name=${1//\"/}
    typeset    fc_sync_interval=${2//\"/}
    typeset    rg_settling_time=${3//\"/}
    typeset -l rg_dist_policy=${4//\"/}
    typeset    max_event_time=${5//\"/}
    typeset    max_rg_processing_time=${6//\"/}
    typeset -l faction=${7//\"/}
    typeset    nmethod=${8//\"/}

    typeset -l autover=${9//\"/}
    typeset    autover_node=${10//\"/}
    typeset    autover_hour=${11//\"/}
    typeset -l autover_debug=${12//\"/}

    typeset    repositories=${13//\"/}
               repositories=${repositories//,/ }
    typeset    cluster_ip=${14//\"/}
    typeset    heartbeat=${15//\"/}
    typeset    node_down_delay=${16//\"/}
    typeset    site_heartbeat_cycle=${17//\"/}
    typeset    site_grace_period=${18//\"/}
    typeset -u type=${19//\"/}
    typeset -l heartbeat_type=${20//\"/}
    typeset -l temp_hostname=${21//\"/}

    : Split-merge inputs
    typeset -l split_policy=${22//\"/}
    typeset -l merge_policy=${23//\"/}
    typeset    nfs_quorum_server=${24//\"/}
    typeset    local_quorum_directory=${25//\"/}
    typeset    remote_quorum_directory=${26//\"/}
    typeset    quarantine_policy=${27//\"/}
    typeset    critical_rg=${28//\"/}
    typeset -l action_plan=${29//\"/}
    typeset    tiebreaker=${30//\"/}
    typeset    notify_method=${31//\"/}
    typeset    notify_interval=${32//\"/}
    typeset    maximum_notifications=${33//\"/}
    typeset    default_surviving_site=${34//\"/}
    typeset -l apply_to_pprc_takeover=${35//\"/}

    typeset    nodes=${36//\"/}
               nodes=${nodes//,/ }
    typeset -l lpm_policy=${37//\"/}
    typeset    lpm_heartbeat=${38//\"/}
    typeset    network_fdt=${39//\"/}
    typeset    caa_auto_start_dr=${40//\"/}
    typeset    caa_repos_mode=${41//\"/}
    typeset -l caa_config_timeout=${42//\"/}
    typeset    lvm_preferred_read=${43//\"/}
    typeset    crit_daemon_restart_grace_period=${44//\"/}
    typeset    skip_events_on_manage=${45//\"/}
    typeset    bucket_name=${46//\"/}
    typeset    cloud_service=${47//\"/}
    typeset    use_existing_bucket=${48//\"/}

    [[ $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 cmd_rc=$RC_UNKNOWN
    typeset OUTPUT= name=
    typeset -A clattrs
    typeset -i caa_cluster_exists=0
    typeset skip=""
    typeset -i HeartbeatLowValue=0 HeartbeatHighValue=0
    typeset -i NodeDownDelayLowValue=0 NodeDownDelayHighValue=0
    typeset -i NetworkLowValue=0 NetworkHighValue=0

     #====================================
    : Check for a split-merge operation
    #====================================
    if [[ "$split_policy$merge_policy$nfs_quorum_server$local_quorum_directory$remote_quorum_directory$quarantine_policy$critical_rg$action_plan\
                                       $tiebreaker$notify_method$notify_interval$maximum_notifications$default_surviving_site$apply_to_pprc_takeover$bucket_name$cloud_service$use_existing_bucket" != *([[:space:]]) ]]
    then
        handle_split_merge "$split_policy"           \
                           "$merge_policy"           \
                           "$nfs_quorum_server"       \
                           "$local_quorum_directory"  \
                           "$remote_quorum_directory" \
                           "$quarantine_policy"      \
                           "$critical_rg"            \
                           "$action_plan"            \
                           "$tiebreaker"             \
                           "$notify_method"          \
                           "$notify_interval"        \
                           "$maximum_notifications"  \
                           "$default_surviving_site" \
                           "$apply_to_pprc_takeover" \
                           "$bucket_name" \
                           "$cloud_service" \
                           "$use_existing_bucket" 
        rc=$?
    fi

    # get some general cluster attributes for later checks
    CL=$LINENO isEnterprise
    typeset -i ENTERPRISE_EDITION=$?
    CL=$LINENO CLMGR_VERBOSE=0 KLIB_HACMP_get_cluster_attributes clattrs

    # Check for AIX 71 TL4 or later versions of AIX to see if we can set
    # the network_fdt tunable
    typeset -i FV FR FM FF VR
    typeset -i network_fdt_capable=0
    lslpp -lcqOr bos.cluster.rte | cut -f3 -d':' | IFS=. read FV FR FM FF
    VR=$FV$FR
    
    if (( $VR > 71 )) || (( $VR == 71 && $FM > 3 ))
    then
        # CAA is capable
        network_fdt_capable=1;
    fi

    #=================
    : Validate inputs
    #=================
    if [[ "$*" == *([[:space:]]) ]]; then
        cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 401 "\nERROR: no valid modifications were specified for \"%1\$s\".\n\n" "$(cllsclstr -cS | cut -d: -f2)" 1>&2
        rc=$RC_MISSING_INPUT

    elif [[ -n $new_name && -n "${new_name//[a-zA-Z0-9_]/}" ]]; then
        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_name" "${new_name//[a-zA-Z0-9_]/}" 1>&2
        rc=$RC_INCORRECT_INPUT
    fi

    if [[ -n $heartbeat_type ]]; then
        if [[ -z $LANG || $LANG=@(C|en|En|EN)* ]]; then
            CL=$LINENO verify_in_set HEARTBEAT_TYPE "$heartbeat_type" "unicast, uc, multicast, mc" heartbeat_type
            if (( $? != RC_SUCCESS )); then
                rc=RC_INCORRECT_INPUT
            else
                [[ $heartbeat_type == u* ]] && heartbeat_type="unicast" \
                                            || heartbeat_type="multicast"
            fi
        else # Convert other languages to English, for internal processing
            typeset -l UC=$(dspmsg -s 64 cluster.cat 4 "Unicast")
            typeset -l MC=$(dspmsg -s 64 cluster.cat 5 "Multicast")
            if [[ $UC == $heartbeat_type* ]]; then
                heartbeat_type="unicast"
            elif [[ $MC == $heartbeat_type* ]]; then
                heartbeat_type="multicast"
            fi
        fi

    elif [[ $CLMGR_STACK == *KLIB_HACMP_add_cluster* ]]; then
        # Only need to set a default heartbeating
        # type during an "add cluster" operation.
        heartbeat_type="unicast"
    fi

    typeset -u HBT=""
    if [[ $heartbeat_type == "unicast" ]]; then
        HBT="U"
        if ! cl_migcheck ANY 2>>$CLMGR_TMPLOG
        then
            print "\nERROR: one or more nodes in the cluster is not reachable through a tcpip connection,\nand cannot be reconfigured for unicast capability.  Please perform the necessary updates\non all nodes to allow a unicast-based cluster.\n\n" 1>&2
            rc=$RC_INCORRECT_INPUT
        fi

        if [[ -n $cluster_ip ]]; then
            #
            : If both unicast was selected, and an IP address provided,
            : the user is confused. Unicast takes precedence.
            #
            cl_dspmsg -s 64 cluster.cat 1 'A cluster IP address for heartbeat is not required with unicast heartbeating. The entered cluster IP address will be ignored.\n'
            cluster_ip=""
        fi

    elif [[ $heartbeat_type == "multicast" ]]; then
        [[ -n $cluster_ip ]] && HBT="C" || HBT="M"
        if [[ $CLMGR_STACK == *KLIB_HACMP_add_cluster* && \
              $HBT == "M" ]]
        then
            # Only need to display this during an "add cluster" operation
            cl_dspmsg -s 64 cluster.cat 8 'A default multicast IP address will be assigned during synchronization\n'
        fi
    fi

    if [[ -n $rg_dist_policy ]]; then
        CL=$LINENO verify_in_set RG_DIST_POLICY "$rg_dist_policy" "node, network" rg_dist_policy
        (( $? != RC_SUCCESS )) && rc=RC_INCORRECT_INPUT
    fi

    if [[ -n $faction ]]; then
        CL=$LINENO verify_in_set SITE_POLICY_FAILURE_ACTION "$faction" "fallover, notify" faction
        (( $? != RC_SUCCESS )) && rc=RC_INCORRECT_INPUT
    fi

   # Check whether CAA cluster exists
    /usr/lib/cluster/incluster 2>/dev/null
    (( $? == RC_SUCCESS )) && caa_cluster_exists=1

    #=============================================================================================
    : The default value of lpm_heartbeat should be set to 600 only during "add cluster" operation
    #=============================================================================================
    if [[ -z $lpm_heartbeat && $CLMGR_STACK == *KLIB_HACMP_add_cluster* ]]; then
         lpm_heartbeat=600
    fi 

    if [[ -n $heartbeat || -n $lpm_heartbeat ]]; then
        typeset DESC="HEARTBEAT_FREQUENCY"
        if (( caa_cluster_exists )); then
            print "$0()[$LINENO]($SECONDS): LC_ALL=C clctrl -tune -L node_timeout" >>$CLMGR_TMPLOG
            LC_ALL=C clctrl -tune -L node_timeout | grep node_timeout | read skip skip HeartbeatLowValue HeartbeatHighValue skip
            cmd_rc=$?
            print "$0()[$LINENO]($SECONDS): clctrl RC: $cmd_rc" >>$CLMGR_TMPLOG
            if (( $cmd_rc == 0 )); then
                (( HeartbeatLowValue /= 1000 ))
                (( HeartbeatHighValue /= 1000 ))
                if [[ -n $heartbeat ]]; then
                   typeset DESC="HEARTBEAT_FREQUENCY"
                   [[ -n $CLMGR_GUI ]] && DESC=$(dspmsg -s 63 cluster.cat 33 "Node Failure Detection Timeout")
                   CL=$LINENO verify_numeric_range "$heartbeat" $HeartbeatLowValue $HeartbeatHighValue "$DESC"
                   (( $? != RC_SUCCESS )) && rc=$RC_INCORRECT_INPUT
                fi
                if [[ -n $lpm_heartbeat ]]; then
                   # Set a default value if 0 has been given
                   if (( $lpm_heartbeat == 0 )); then
                       cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1181 "\nWARNING: The value passed for Node Failure Detection Timeout during LPM is 0, updating it to default value 600\n" 1>&2
                       lpm_heartbeat=600
                   fi
                   typeset DESC="HEARTBEAT_FREQUENCY_DURING_LPM"
                   [[ -n $CLMGR_GUI ]] && DESC=$(dspmsg -s 63 cluster.cat 56 "Node Failure Detection Timeout during LPM")
                   CL=$LINENO verify_numeric_range "$lpm_heartbeat" $HeartbeatLowValue $HeartbeatHighValue "$DESC"
                   (( $? != RC_SUCCESS )) && rc=$RC_INCORRECT_INPUT
                fi
            fi 
        fi
    fi

    if [[ -n $node_down_delay ]]; then
        typeset DESC="GRACE_PERIOD"
        if (( caa_cluster_exists )); then
            [[ -n $CLMGR_GUI ]] && DESC=$(dspmsg -s 63 cluster.cat 34 "Failure Indication Grace Time")
            print "$0()[$LINENO]($SECONDS): LC_ALL=C clctrl -tune -L node_down_delay" >>$CLMGR_TMPLOG
            LC_ALL=C clctrl -tune -L node_down_delay | grep node_down_delay | read skip skip NodeDownDelayLowValue NodeDownDelayHighValue skip
            cmd_rc=$?
            print "$0()[$LINENO]($SECONDS): clctrl RC: $cmd_rc" >>$CLMGR_TMPLOG
            if (( $cmd_rc == 0 )); then
                (( NodeDownDelayLowValue /= 1000))
                (( NodeDownDelayHighValue /= 1000))
                CL=$LINENO verify_numeric_range "$node_down_delay" $NodeDownDelayLowValue $NodeDownDelayHighValue "$DESC"
                (( $? != RC_SUCCESS )) && rc=$RC_INCORRECT_INPUT
            fi
        fi
    fi

    # validate network fdt input
    if (( $network_fdt_capable == 1 ));then
       if [[ -n $network_fdt ]];then
           typeset DESC="NETWORK_FAILURE_DETECTION_TIME"
           if (( caa_cluster_exists )); then
              [[ -n $CLMGR_GUI ]] && DESC=$(dspmsg -s 63 cluster.cat 61 "Network Failure Detection Time")
              if [[ -n $heartbeat ]];then
                 typeset -i network_max_value=($heartbeat-10)
                  if (( $network_fdt < 5 && $network_fdt > 0 ));then
                       print "$0()[$LINENO]($SECONDS): Network Failure Detection value should be at least 5 seconds or 0 (unset)." >> $CLMGR_TMPLOG
                       cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1141 'ERROR: Network Failure Detection value should be at least 5 seconds or 0 (unset).\n\n' 1>&2
                       rc=$RC_INCORRECT_INPUT
                 fi
                 if (( $network_fdt > $network_max_value ));then
                       print "$0()[$LINENO]($SECONDS): Given Network Failure Detection TimeOut is not at least 10 seconds less than Node Failure Detection Time(Heartbeat frequency)$heartbeat sec" >>$CLMGR_TMPLOG
		       cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1140 'ERROR: The Given Network Failure Detection TimeOut is not at least 10 seconds less than the Node Failure Detection Time(Heartbeat frequency)%1$s seconds.\nThe Network Failure Detection TimeOut value can be set within the range 5 to %2$s seconds based on the current Node Failure Detection Time value.\n\n' "$heartbeat" "$network_max_value" 1>&2

                       rc=$RC_INCORRECT_INPUT
                 fi
              else
                 typeset -i caa_heartbeat=$(clctrl -tune -o node_timeout | awk -F "=" '{print $2}')
                 (( caa_heartbeat /=1000 ))
                 typeset -i network_max=($caa_heartbeat-10)
                  if (( $network_fdt < 5 && $network_fdt > 0 ));then
                       print "$0()[$LINENO]($SECONDS): Network Failure Detection value should be at least 5 seconds or 0 (unset)" >> $CLMGR_TMPLOG
                       cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1141 'ERROR: Network Failure Detection value should be at least 5 seconds or 0 (unset).\n\n' 1>&2
                       rc=$RC_INCORRECT_INPUT
                 fi
                 if (( $network_fdt > $network_max ));then
                    print "$0()[$LINENO]($SECONDS): Given Network Failure Detection TimeOut is not at least 10 seconds less than Node Failure Detection Time(Heartbeat frequency)$caa_heartbeat sec" >>$CLMGR_TMPLOG
		    cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1140 'ERROR: The Given Network Failure Detection TimeOut is not at least 10 seconds less than the Node Failure Detection Time(Heartbeat frequency)%1$s seconds.\nThe Network Failure Detection TimeOut value can be set within the range 5 to %2$s seconds based on the current Node Failure Detection Time value.\n\n' "$caa_heartbeat" "$network_max" 1>&2
                    rc=$RC_INCORRECT_INPUT
                 fi
              fi
              print "$0()[$LINENO]($SECONDS): LC_ALL=C clctrl -tune -L network_fdt" >>$CLMGR_TMPLOG
              LC_ALL=C clctrl -tune -L network_fdt | grep network_fdt | read skip skip NetworkLowValue NetworkHighValue skip
              cmd_rc=$?
              print "$0()[$LINENO]($SECONDS):  clctrl RC: $cmd_rc" >>$CLMGR_TMPLOG
              if (( $cmd_rc == 0 )); then
                 (( NetworkLowValue /=1000 ))
                 (( NetworkHighValue /=1000 ))
                 CL=$LINENO verify_numeric_range "$network_fdt" $NetworkLowValue $NetworkHighValue "$DESC"
                 (( $? != RC_SUCCESS )) && rc=$RC_INCORRECT_INPUT
              fi
           fi
       fi
    else
        # network_fdt_capable is 0 - AIX level does not support network fdt
        if [[ -n $network_fdt ]]
        then
            cl_dspmsg -s 63 cluster.cat 72 '\nNetwork failure detection time is not modified as PowerHA supports this tunable only from AIX 71 TL4 version.\n'
            rc=$RC_INCORRECT_INPUT
        fi

    fi

    if [[ -n $site_heartbeat_cycle ]]; then
        typeset DESC="SITE_HEARTBEAT_CYCLE"
        [[ -n $CLMGR_GUI ]] && DESC=$(dspmsg -s 63 cluster.cat 10 "Site Heartbeat Cycle")
        CL=$LINENO verify_numeric_range "$site_heartbeat_cycle" 1 10 "$DESC"
        (( $? != RC_SUCCESS )) && rc=$RC_INCORRECT_INPUT
    fi

    if [[ -n $site_grace_period ]]; then
        typeset DESC="SITE_GRACE_PERIOD"
        [[ -n $CLMGR_GUI ]] && DESC=$(dspmsg -s 63 cluster.cat 35 "Link Failure Detection Timeout")
        CL=$LINENO verify_numeric_range "$site_grace_period" 5 30 "$DESC"
        (( $? != RC_SUCCESS )) && rc=$RC_INCORRECT_INPUT
    fi

    #
    :  Before validating critical daemon restart grace period, verifing 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

    typeset -i skip_events_flag
    if [[ -n $skip_events_on_manage ]]; then
        CL=$LINENO verify_in_set SKIP_EVENT_PROCESSING_MANAGE_MODE "$skip_events_on_manage" "true, false" skip_events_on_manage
        if (( $? == RC_SUCCESS )); then
            [[ $skip_events_on_manage == @(t)* ]] && skip_events_flag=1
            [[ $skip_events_on_manage == @(f)* ]] && skip_events_flag=0
        else
            rc=$RC_INCORRECT_INPUT
        fi
    fi

    if [[ $temp_hostname != *([[:space:]]) ]]; then
        CL=$LINENO verify_in_set TEMP_HOSTNAME "$temp_hostname" "allow, yes, true, 1, disallow, no, false, 0" temp_hostname
        if (( $? == RC_SUCCESS )); then
            value=0
            [[ $temp_hostname == @(a|y|t|1)* ]] && value=1
            print "HACMPcluster: honorTempHostNameChanges = $value" | odmchange -o HACMPcluster
            if (( $(clodmget -n -f honorTempHostNameChanges HACMPcluster) != $value )); then
                cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 435 '\nERROR: unable to update the non-persistent hostname change support on node "%1$s".\n\n' "$LOCAL_NODE" 1>&2
                rc=$RC_ERROR
            else
                cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 189 'This change will go into effect on all nodes after the cluster is synchronized.\n'
                print "HACMPcluster: handle = 0" | odmchange -o HACMPcluster
            fi
        else
            rc=$RC_INCORRECT_INPUT
        fi
    fi

    #=============================================================================================
    : The default value of lpm_policy should be set to "manage" only during "add cluster" operation
    #=============================================================================================
    if [[ -z $lpm_policy && $CLMGR_STACK == *KLIB_HACMP_add_cluster* ]]; then
        lpm_policy="manage"
    fi

    if [[ -n $lpm_policy ]]; then
        CL=$LINENO verify_in_set LPM_POLICY "$lpm_policy" "manage, unmanage" lpm_policy
        (( $? != RC_SUCCESS )) && rc=$RC_INCORRECT_INPUT
    fi

    typeset -i dr_enable
    if [[ -n $caa_auto_start_dr ]]; then
        CL=$LINENO verify_in_set CAA_AUTO_START_DR "$caa_auto_start_dr" "enabled, disabled" caa_auto_start_dr
        if (( $? == RC_SUCCESS )); then
            [[ $caa_auto_start_dr  == @(e)* ]] && dr_enable=1
            [[ $caa_auto_start_dr  == @(d)* ]] && dr_enable=0
        else
            rc=$RC_INCORRECT_INPUT
        fi
    fi

    #=============================================================================================
    : The default value of repos_mode should be set to "event" only during "add cluster" operation
    #=============================================================================================
    if [[ -z $caa_repos_mode && $CLMGR_STACK == *KLIB_HACMP_add_cluster* ]]; then
        caa_repos_mode="event"
    fi

    typeset -i repos
    if [[ -n $caa_repos_mode ]]; then
        CL=$LINENO verify_in_set CAA_REPOS_MODE "$caa_repos_mode" "assert, event" caa_repos_mode
        if (( $? == RC_SUCCESS )); then
            [[ $caa_repos_mode == @(a)* ]] && repos=0
            [[ $caa_repos_mode == @(e)* ]] && repos=1
        else
            rc=$RC_INCORRECT_INPUT
        fi
    fi

    #=============================================================================================
    : The default value of lvm_preferred_read should be set to "roundrobin" 
    #=============================================================================================
    if [[ -n "$lvm_preferred_read" ]]; then
        if [[ $CLUSTER_TYPE != "NSC" ]]; then
           # siteaffinity option is available only for site based cluster.
           CL=$LINENO verify_in_set LVM_PREFERRED_READ "$lvm_preferred_read" "roundrobin, favorcopy, siteaffinity" lvm_preferred_read
        else
           CL=$LINENO verify_in_set LVM_PREFERRED_READ "$lvm_preferred_read" "roundrobin, favorcopy" lvm_preferred_read
        fi
        if (( $? != RC_SUCCESS )); then
            rc=$RC_INCORRECT_INPUT
        fi
    else
        lvm_preferred_read="roundrobin"
    fi

    #=============================================================================================
    : The default value of config_timeout should be set to 240 only during "add cluster" operation
    #=============================================================================================
    if [[ -z $caa_config_timeout && $CLMGR_STACK == *KLIB_HACMP_add_cluster* ]]; then
          caa_config_timeout=240
    fi

    if [[ -n $caa_config_timeout ]]; then
        typeset DESC="CONFIG_TIMEOUT"
        [[ -n $CLMGR_GUI ]] && DESC=$(dspmsg -s 63 cluster.cat 73 "Config timeout")
        CL=$LINENO verify_numeric_range "$caa_config_timeout" 0 2147483647 "$DESC"
        (( $? != RC_SUCCESS )) && rc=$RC_INCORRECT_INPUT
    fi
   
    #==================================================================
    # Verify the cluster type to set the site grace period 
    #==================================================================
    if [[ $CLUSTER_TYPE == "NSC" || $CLUSTER_TYPE == "SC" ]] && [[ -n $site_grace_period ]]; then
        cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1484 'ERROR: Site grace period can only be changed in linked cluster.\n\n' 1>&2
        rc=$RC_INCORRECT_INPUT
    fi
 
    #=================================
    # Tune the cluster, if requested
    #=================================
    if (( $rc == RC_UNKNOWN || $rc == RC_SUCCESS )); then
        if [[ -n $heartbeat ]]; then
            #=========================================
            : Setting node heartbeat to "$heartbeat"
            #=========================================
            print "HACMPcluster:
node_timeout=$heartbeat" | odmchange -o HACMPcluster
            typeset VAL=$(clodmget -n -f node_timeout HACMPcluster)
            (( $VAL == $heartbeat )) && rc=$RC_SUCCESS || rc=$RC_ERROR
        fi
    fi
    if (( $rc == RC_UNKNOWN || $rc == RC_SUCCESS )); then
        if [[ -n $node_down_delay ]]; then
            #==================================================
            : Setting node grace period to "$node_down_delay"
            #==================================================
            print "HACMPcluster:
node_down_delay=$node_down_delay" | odmchange -o HACMPcluster
            typeset VAL=$(clodmget -n -f node_down_delay HACMPcluster)
            (( $VAL == $node_down_delay )) && rc=$RC_SUCCESS || rc=$RC_ERROR
        fi
    fi
    if (( $rc == RC_UNKNOWN || $rc == RC_SUCCESS )); then
       if (( $network_fdt_capable == 1 ));then
          if [[ -n $network_fdt ]]; then
             #==================================================
             : Setting network failure detection time to "$network_fdt"
             #==================================================
              print "HACMPcluster:
network_fdt=$network_fdt" | odmchange -o HACMPcluster
              typeset VAL=$(clodmget -n -f network_fdt HACMPcluster)
              (( $VAL == $network_fdt )) && rc=$RC_SUCCESS || rc=$RC_ERROR
          fi
       fi
    fi

    if (( $rc == RC_UNKNOWN || $rc == RC_SUCCESS )); then
        if [[ -n $site_grace_period ]]; then
            #====================================================
            : Setting site grace period to "$site_grace_period"
            #====================================================
            print "HACMPcluster:
link_timeout=$site_grace_period" | odmchange -o HACMPcluster
            typeset VAL=$(clodmget -n -f link_timeout HACMPcluster)
            (( $VAL == $site_grace_period )) && rc=$RC_SUCCESS || rc=$RC_ERROR
        fi
    fi
    if (( $rc == RC_UNKNOWN || $rc == RC_SUCCESS )); then
        if [[ -n $site_heartbeat_cycle ]]; then
            #==========================================================
            : Setting site heartbeat cycle to "$site_heartbeat_cycle"
            #==========================================================
            print "$0()[$LINENO]($SECONDS): odmchange -o HACMPcluster ==> remote_HB_factor=$site_heartbeat_cycle" >>$CLMGR_TMPLOG
            print "HACMPcluster:
remote_HB_factor=$site_heartbeat_cycle" | odmchange -o HACMPcluster
            typeset VAL=$(clodmget -n -f remote_HB_factor HACMPcluster)
            (( $VAL == $site_heartbeat_cycle )) && rc=$RC_SUCCESS || rc=$RC_ERROR
        fi
    fi

    if (( $rc == RC_UNKNOWN || $rc == RC_SUCCESS )); then
        if [[ -n $HBT ]]; then
            #============================================================
            : Update the heartbeat type to "$HBT", for "$hearbeat_type"
            #============================================================
            print "$0()[$LINENO]($SECONDS): odmchange -o HACMPcluster ==> handle=0, heartbeattype=$HBT" >>$CLMGR_TMPLOG
            print "HACMPcluster:
handle=0
heartbeattype=$HBT" | odmchange -o HACMPcluster
            if [[ "$(clodmget -n -f handle HACMPcluster)" == "0" && \
                  "$(clodmget -n -f heartbeattype HACMPcluster)" == "$HBT" ]]
            then
                rc=$RC_SUCCESS
            else
                rc=$RC_ERROR
            fi
            print "$0()[$LINENO]($SECONDS): odmchange RC: $rc" >>$CLMGR_TMPLOG
        fi
    fi

    if (( $rc == RC_UNKNOWN || $rc == RC_SUCCESS )); then
        if (( caa_cluster_exists )) && [[ -n $new_name ]]; then
            cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 439 '\nERROR: the CAA cluster already exists, so the cluster name (%1$s) cannot be changed.\n\n' "${clattrs[CLUSTER_NAME]}" 1>&2
            rc=$RC_INCORRECT_INPUT
        elif [[ -n $new_name ]]; then
            #==============================================
            : Establish the new cluster name, "$new_name"
            #==============================================
            print "$0()[$LINENO]($SECONDS): clmodclstr -n $new_name" >>$CLMGR_TMPLOG  # Always log commands
            OUTPUT=$(clmodclstr -n $new_name 2>&1)
            rc=$?
            print "$0()[$LINENO]($SECONDS): clmodclstr RC: $rc; OUTPUT == \"$OUTPUT\"" >>$CLMGR_TMPLOG  # Always log command result
            if (( $rc != RC_SUCCESS )); then
                print -- "$OUTPUT" 1>&2
                rc=$RC_ERROR
            fi
        fi
    fi

    if (( $rc == RC_UNKNOWN || $rc == RC_SUCCESS )); then
        if [[ -n $fc_sync_interval ]]; then
            if [[ $fc_sync_interval == +([[:digit:]]) ]]; then
                #=======================================================
                : File collection automatic propagation check interval
                #=======================================================
                print "$0()[$LINENO]($SECONDS): clfilecollection -o time -c $fc_sync_interval" >>$CLMGR_TMPLOG  # Always log commands
                clfilecollection -o time -c $fc_sync_interval
                rc=$?
                print "$0()[$LINENO]($SECONDS): clfilecollection RC: $rc" >>$CLMGR_TMPLOG  # Always log command result
                (( $rc != RC_SUCCESS )) && rc=$RC_ERROR

                print "$0()[$LINENO]($SECONDS): clodmget -q 'name=file_collections_auto_prop' -f period HACMPtimersvc" >>$CLMGR_TMPLOG  # Always log commands
                typeset PERIOD_STR=$(clodmget -q 'name=file_collections_auto_prop' -f period HACMPtimersvc)
                print "$0()[$LINENO]($SECONDS): clodmget RC: $?; PERIOD_STR == \"$PERIOD_STR\"" >>$CLMGR_TMPLOG  # Always log command result
                if [[ $PERIOD_STR == +([[:digit:]]) ]]; then
                    typeset -i PERIOD
                    (( PERIOD = PERIOD_STR / 60 ))  # Convert to minutes
                    print "fc_sync_interval = $PERIOD"
                fi
            else
                dspmsg -s $CLMGR_SET $CLMGR_MSGS 111 "\nERROR: \"%1\$s\" requires a positive, integer value.\n\n" FC_SYNC_INTERVAL 1>&2
                rc=$RC_INCORRECT_INPUT
            fi
        fi
    fi

    if (( $rc == RC_UNKNOWN || $rc == RC_SUCCESS )); then
        if [[ -n $rg_settling_time ]]; then
            if [[ $rg_settling_time == +([[:digit:]]) ]]; then
                #=======================================================
                : Adjust the cluster-wide resource group settling time
                #=======================================================
                print "$0()[$LINENO]($SECONDS): clsettlingtime change $rg_settling_time" >>$CLMGR_TMPLOG  # Always log commands
                clsettlingtime change $rg_settling_time
                rc=$?
                print "$0()[$LINENO]($SECONDS): clsettlingtime RC: $rc" >>$CLMGR_TMPLOG  # Always log command result
                (( $rc != RC_SUCCESS )) && rc=$RC_ERROR
            else
                dspmsg -s $CLMGR_SET $CLMGR_MSGS 111 "\nERROR: \"%1\$s\" requires a positive, integer value.\n\n" RG_SETTLING_TIME 1>&2
                rc=$RC_INCORRECT_INPUT
            fi
        fi
    fi

    if (( $rc == RC_UNKNOWN || $rc == RC_SUCCESS )); then
        if [[ -n $rg_dist_policy ]]; then
            #=============================================================
            : Adjust the cluster-wide resource group distribution policy
            #=============================================================
            print "$0()[$LINENO]($SECONDS): clsetdistpolicy change $rg_dist_policy" >>$CLMGR_TMPLOG  # Always log commands
            clsetdistpolicy change $rg_dist_policy
            rc=$?
            print "$0()[$LINENO]($SECONDS): clsetdistpolicy RC: $rc" >>$CLMGR_TMPLOG  # Always log command result
            (( $rc != RC_SUCCESS )) && rc=$RC_ERROR
        fi
    fi

    if (( $rc == RC_UNKNOWN || $rc == RC_SUCCESS )); then
        if [[ -n $max_event_time || -n $max_rg_processing_time ]]; then
            #=======================================
            : Timers controlling "config_too_long"
            #=======================================
            if [[ -z $max_event_time ]]; then
                max_event_time=${clattrs[MAX_EVENT_TIME]}
            elif [[ -z $max_max_rg_processing_time ]]; then
                max_rg_processing_time=${clattrs[MAX_RG_PROCESSING_TIME]}
            fi

            if [[ $max_event_time == +([[:digit:]]) &&
                  $max_rg_processing_time != +([[:digit:]]) ]]
            then
                dspmsg -s $CLMGR_SET $CLMGR_MSGS 111 "\nERROR: \"%1\$s\" requires a positive, integer value.\n\n" MAX_RG_PROCESSING_TIME 1>&2
                rc=$RC_INCORRECT_INPUT

            elif [[ $max_event_time != +([[:digit:]]) &&
                    $max_rg_processing_time == +([[:digit:]]) ]]
            then
                dspmsg -s $CLMGR_SET $CLMGR_MSGS 111 "\nERROR: \"%1\$s\" requires a positive, integer value.\n\n" MAX_EVENT_TIME 1>&2
                rc=$RC_INCORRECT_INPUT

            elif (( max_event_time <= 0 || max_rg_processing_time <= 0 ))
            then
                dspmsg -s $CLMGR_SET $CLMGR_MSGS 111 "\nERROR: \"%1\$s\" requires a positive, integer value.\n\n" MAX_EVENT_TIME 1>&2
                dspmsg -s $CLMGR_SET $CLMGR_MSGS 111 "\nERROR: \"%1\$s\" requires a positive, integer value.\n\n" MAX_RG_PROCESSING_TIME 1>&2
                rc=$RC_INCORRECT_INPUT

            else
                print "$0()[$LINENO]($SECONDS): clchmsgtimer -e$max_event_time -g$max_rg_processing_time" >>$CLMGR_TMPLOG  # Always log commands
                clchmsgtimer -e$max_event_time \
                                      -g$max_rg_processing_time
                rc=$?
                print "$0()[$LINENO]($SECONDS): clchmsgtimer RC: $rc" >>$CLMGR_TMPLOG  # Always log command result
                (( $rc != RC_SUCCESS )) && rc=$RC_ERROR

                # verify the results
                if (( rc == RC_SUCCESS ))
                then
                    if (( $(clodmget -f reserved1 HACMPcluster) != $max_event_time ||
                          $(clodmget -f reserved2 HACMPcluster) != $max_rg_processing_time ))
                    then
                        dspmsg -s 4 verify.cat 8186 "An internal error occurred while checking clchmsgtimer.\nPlease report this problem to IBM support.\n" "clchmsgtimer"
                        print "$0()[$LINENO]: clchmsgtimer failed to update the odm with the supplied values." >>$CLMGR_TMPLOG  
                        print "max_event_time: $max_event_time reserved1: $(clodmget -f reserved1 HACMPcluster)" >>$CLMGR_TMPLOG  
                        print "max_rg_processing_time: $max_rg_processing_time reserved2: $(clodmget -f reserved2 HACMPcluster)" >>$CLMGR_TMPLOG  
                    fi
                fi
            fi
        fi
    fi

    if (( $rc == RC_UNKNOWN || $rc == RC_SUCCESS )); then
        if [[ -n $faction || -n $nmethod ]]; then
            #============================
            : Set the cross-site policy
            #============================
            [[ -z $faction ]] && faction=${clattrs[SITE_POLICY_FAILURE_ACTION]}
            [[ -z $nmethod ]] && nmethod=${clattrs[SITE_POLICY_NOTIFY_METHOD]}

            print "$0()[$LINENO]($SECONDS): clchappmon resource_group= name=CROSS_SITE_RG_MOVE FAILURE_ACTION=\"$faction\" NOTIFY_METHOD=\"$nmethod\"" >>$CLMGR_TMPLOG  # Always log commands
            clchappmon resource_group= \
                                name=CROSS_SITE_RG_MOVE \
                                FAILURE_ACTION="$faction" \
                                NOTIFY_METHOD="$nmethod"
            rc=$?
            print "$0()[$LINENO]($SECONDS): clchappmon RC: $rc" >>$CLMGR_TMPLOG  # Always log command result
            (( $rc != RC_SUCCESS )) && rc=$RC_ERROR
        fi
    fi

    if (( $rc == RC_UNKNOWN || $rc == RC_SUCCESS )); then
        if [[ -n "$autover$autover_node$autover_hour$autover_debug" ]]; then
            #===============================================================
            : Update the automatic, daily verification settings, if needed
            #===============================================================
            typeset autover_flag=
            if [[ -n $autover ]]; then
                [[ $autover == @(d|f|n|0)* ]] && autover_flag="-d" \
                                              || autover_flag="-e"
            else
                autover="-e"
                [[ ${clattrs[DAILY_VERIFICATION]} == @(d|D)* ]] && autover_flag="-d"
            fi

            typeset -u autover_node_uc=
            typeset -u DEFAULT=$(dspmsg -s 1 cluster.cat 860 Default)
            if [[ -n $autover_node ]]; then
                autover_node_uc=$autover_node
                [[ $DEFAULT == $autover_node_uc* ]] && unset autover_node \
                                                    || autover_node="-n $autover_node"
            else
                autover_node_uc=${clattrs[VERIFICATION_NODE]}
                autover_node="-n Default"
                [[ $DEFAULT == $autover_node_uc* ]] && unset autover_node \
                                                    || autover_node="-n ${clattrs[VERIFICATION_NODE]}"
            fi

            if [[ -n $autover_hour ]]; then
                autover_hour="-h $autover_hour"
            else
                autover_hour="-h ${clattrs[VERIFICATION_HOUR]}"
            fi

            typeset autover_debug_flag=
            if [[ -n $autover_debug ]]; then
                [[ $autover_debug == @(d|f|n|0)* ]] && autover_debug_flag="" \
                                                    || autover_debug_flag="-D"
            else
                autover_debug_flag="-D"
                [[ ${clattrs[DAILY_VERIFICATION]} == @(d|D)* ]] && autover_debug_flag=""
            fi

            print "$0()[$LINENO]($SECONDS): clautoconfigmonitor $autover_flag $autover_node $autover_hour $autover_debug_flag" >>$CLMGR_TMPLOG  # Always log commands
            clautoconfigmonitor $autover_flag $autover_node $autover_hour $autover_debug_flag
            rc=$?
            print "$0()[$LINENO]($SECONDS): clautoconfigmonitor RC: $rc" >>$CLMGR_TMPLOG  # Always log command result
        fi
    fi

    if (( $rc == RC_UNKNOWN || $rc == RC_SUCCESS )); then
        #===============================
        : Get the current cluster name
        #===============================
        print "$0()[$LINENO]($SECONDS): cllsclstr -cn | awk -F: '(NR==2) {print $2}'" >>$CLMGR_TMPLOG  # Always log commands
        name=$(cllsclstr -cn | awk -F: '(NR==2) {print $2}')
        print "$0()[$LINENO]($SECONDS): cllsclstr RC: $?; name == \"$name\"" >>$CLMGR_TMPLOG  # Always log command result
    fi

    if (( caa_cluster_exists )) && [[ -n $type ]]; then
        cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1482 'Cluster TYPE changed to %1$s. Proceed with next steps to complete cluster conversion.' "$type" 1>&2
    elif [[ -n $type ]]; then
        typeset SITES=$(clodmget -n -f name HACMPsite)
        if [[ $type == "NSC" && -n $SITES ]]; then
            cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 432 '\nERROR: the current cluster configuration contains sites, so its type cannot be set to "NSC".\n\n' 1>&2
            rc=$RC_INCORRECT_INPUT
        fi
    fi

    if [[ -n $repositories && $CLUSTER_TYPE == "LC" ]]; then
        cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 436 '\nERROR: repositories must be specified per site in a linked cluster.\n\n' 1>&2
        rc=$RC_INCORRECT_INPUT
    fi


    #
    typeset -i NB_NEW_BACKUP_REPOS=$(print $repositories | wc -w)
    [[ -z $NB_NEW_BACKUP_REPOS ]] && NB_NEW_BACKUP_REPOS=0 || (( NB_NEW_BACKUP_REPOS-=1))
    if (( $NB_NEW_BACKUP_REPOS > $MAX_NB_OF_BACKUP_REPOSITORIES )); then
        dspmsg -s $CLMGR_SET $CLMGR_MSGS 1002 "\nERROR: a no-site cluster or a stretched cluster cannot get more than \"%1\$s\" backup repositories (there were \"%2\$s\" backup repositories, and you want to add \"%3\$s\" backup repositories).\n\n" "$MAX_NB_OF_BACKUP_REPOSITORIES" "0" "${NB_NEW_BACKUP_REPOS}" 1>&2
        rc=$RC_INCORRECT_INPUT
    fi

    if (( $rc == RC_UNKNOWN || $rc == RC_SUCCESS )); then
        if [[ -n $cluster_ip ]]; then
            #=========================================
            : Validate the cluster multicast address
            #=========================================
            CL=$LINENO verify_is_multicast_address $cluster_ip
            (( $? != RC_SUCCESS )) && rc=RC_INCORRECT_INPUT

            if (( $rc == RC_UNKNOWN || $rc == RC_SUCCESS )); then
                #==============================================
                : Looks like "$cluster_ip" is a valid address
                #==============================================
                rm -f $MCIP_ERROR_FILE

                #===============================================
                : If the CAA cluster has not been created yet,
                : manually clean up any previous IP entry.
                #===============================================
                if (( ! caa_cluster_exists )); then
                    print "$0()[$LINENO]($SECONDS): clodmget -n -f ip_address HACMPsircol" >>$CLMGR_TMPLOG  # Always log commands
                    typeset existing_clusterip=$(clodmget -n -f ip_address HACMPsircol 2>/dev/null)
                    print "$0()[$LINENO]($SECONDS): clodmget RC: $?; existing_clusterip == \"$existing_clusterip\"" >>$CLMGR_TMPLOG  # Always log command result

                    if [[ $existing_clusterip == [[:digit:]]* ]]; then
                        #===========================================
                        : We have one defined and should delete it
                        #===========================================
                        typeset sircolname=
                        print "$0()[$LINENO]($SECONDS): clodmget -n -f name HACMPsircol" >>$CLMGR_TMPLOG  # Always log commands
                        sircolname=$(clodmget -n -f name HACMPsircol)
                        print "$0()[$LINENO]($SECONDS): clodmget RC: $?; sircolname == \"$sircolname\"" >>$CLMGR_TMPLOG  # Always log command result

                        print "$0()[$LINENO]($SECONDS): odmget -q \"name = $sircolname\" HACMPsircol" >>$CLMGR_TMPLOG  # Always log commands
                        odmget -q "name = $sircolname" HACMPsircol >$TMPDIR/clmgr.KHmc.sircol.old.$$
                        print "$0()[$LINENO]($SECONDS): odmget RC: $?" >>$CLMGR_TMPLOG  # Always log command result
                        sed 's/ip_address = .*/ip_address =\"\"/' $TMPDIR/clmgr.KHmc.sircol.old.$$ >$TMPDIR/clmgr.KHmc.sircol.chg.$$

                        print "$0()[$LINENO]($SECONDS): odmchange -o HACMPsircol -q \"name = $sircolname\"" >>$CLMGR_TMPLOG  # Always log commands
                        odmchange -o HACMPsircol -q "name = $sircolname" $TMPDIR/clmgr.KHmc.sircol.chg.$$
                        print "$0()[$LINENO]($SECONDS): odmchange RC: $?" >>$CLMGR_TMPLOG  # Always log command result

                        rm -rf $TMPDIR/clmgr.KHmc.sircol.old.$$ 2>/dev/null
                        rm -rf $TMPDIR/clmgr.KHmc.sircol.chg.$$ 2>/dev/null
                    fi
                fi

                #=====================================================
                : Setting cluster multicast address to "$cluster_ip"
                #=====================================================
                print -- "$0()[$LINENO]($SECONDS): odmchange -o HACMPcluster... ip_address=$cluster_ip" >>$CLMGR_TMPLOG
                print "HACMPsircol:
ip_address=$cluster_ip" | odmchange -o HACMPsircol
                rc=$?
                print -- "$0()[$LINENO]($SECONDS): odmchange RC: $rc" >>$CLMGR_TMPLOG
                typeset VAL=$(clodmget -n -f ip_address HACMPsircol)
                [[ $VAL == $cluster_ip ]] && rc=$RC_SUCCESS || rc=$RC_ERROR
            fi
        fi

        if (( $rc == RC_UNKNOWN || $rc == RC_SUCCESS )); then
            [[ -z $type ]] && type=$CLUSTER_TYPE
            typeset -i multi_site_lc=-1
            case $type in
                SC)   multi_site_lc=0  ;;  # Stretched cluster
                STR*) multi_site_lc=0  ;;  # Stretched cluster
                LC)   multi_site_lc=1  ;;  # Linked cluster
                LI*)  multi_site_lc=1  ;;  # Linked cluster
                *)    multi_site_lc=-1 ;;  # Non-site cluster
            esac

            #=============================================================
            : Setting cluster type to "$multi_site_lc", for TYPE="$type"
            #=============================================================
            print -- "$0()[$LINENO]($SECONDS): odmchange -o HACMPcluster... multi_site_lc=$multi_site_lc" >>$CLMGR_TMPLOG
            print "HACMPcluster:
multi_site_lc=$multi_site_lc" | odmchange -o HACMPcluster
            rc=$?
            print -- "$0()[$LINENO]($SECONDS): odmchange RC: $rc" >>$CLMGR_TMPLOG
            typeset VAL=$(clodmget -n -f multi_site_lc HACMPcluster)
            [[ $VAL == $multi_site_lc ]] && rc=$RC_SUCCESS || rc=$RC_ERROR

            # We are going to convert the cluster to a Linked type.
            # To change CAA cluster, dr_enabled tunable should be reset to 0.
            if (( caa_cluster_exists )) && [[ $VAL == 1 ]]; then
                print -- "$0()[$LINENO]($SECONDS): To enable cluster conversion to Linked type, resetting dr_enabled tunable to 0." >>$CLMGR_TMPLOG
                print "HACMPcluster: dr_enabled=0" | /usr/bin/odmchange -o HACMPcluster

                print "$0()[$LINENO]($SECONDS): LC_ALL=C clctrl -tune -o dr_enabled=0" >>$CLMGR_TMPLOG
                LC_ALL=C clctrl -tune -o dr_enabled=0
                cmd_rc=$?
                print "$0()[$LINENO]($SECONDS): clctrl RC: $cmd_rc" >>$CLMGR_TMPLOG
            fi
        fi

        #===================================================
        # This code is to preserve backwards compatibility
        #===================================================
        if (( $rc == RC_UNKNOWN || $rc == RC_SUCCESS )); then
            if [[ -n $repositories ]]; then
                if (( ! caa_cluster_exists )); then
                    typeset -A arprops
                    KLIB_HACMP_add_repository arprops "$repositories"
                    rc=$?
                elif [[ ${repositories//,/} != *([[:space:]]) ]]; then
                    KLIB_HACMP_replace_repository ${repositories%% *}
                    rc=$?
                fi
            fi
        fi
    fi

    if (( $rc == RC_UNKNOWN || $rc == RC_SUCCESS )) && \
       [[ -n $nodes ]]
    then
        #==================================================================
        : If the NODES input is provided, this list is considered to be
        : the desired new complete list of nodes for the cluster. So any
        : nodes specified that are not currently in the cluster are to
        : be added as new cluster nodes. And any nodes that are currently
        : in the cluster that are *not* specified in the new list are to
        : be removed from the cluster.
        : NOTE: if the local node is not in the node list, the operation
        :       cannot succeed, and an error message will be emitted.
        #==================================================================
        typeset current_nodes=$(clnodename)
                current_nodes=${current_nodes//+([[:space:]])/ }

        typeset node="" add_nodes="" keepers=""
        for node in $nodes; do
            if [[ " $current_nodes " == *\ $node\ * ]]; then
                [[ -n $keepers ]] && keepers="$keepers "
                keepers="$keepers$node"
            else
                [[ -n $add_nodes ]] && add_nodes="$add_nodes "
                add_nodes="$add_nodes$node"
            fi
        done

        typeset remove_nodes=""
        for node in $current_nodes; do
            if [[ " $nodes " != *\ $node\ * ]]; then
                [[ -n $remove_nodes ]] && remove_nodes="$remove_nodes "
                remove_nodes="$remove_nodes$node"
            fi
        done

        if [[ -n $remove_nodes && \
              " $remove_nodes " == *\ $LOCAL_NODE\ * && \
              -n $keepers ]]
        then
            cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 444 '\nERROR: the specified node list (%1$s) does not contain the local node, "%2$s". It is not possible to remove "%2$s" from the cluster while actively running a cluster configuration operation on it. Either add "%2$s" to the provided node list, or perform this operation on a different cluster node (%3$s).\n\n' "\"${nodes// /\", \"}\"" "$LOCAL_NODE" "\"${keepers// /\", \"}\"" 1>&2
            rc=$RC_INCORRECT_INPUT
        elif [[ -z $keepers ]]; then
            cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 445 '\nERROR: the specified node list (%1$s) does not contain any of the current cluster nodes (%3$s). This operation is not appropriate for deleting the entire cluster. Either add one or more of the current cluster nodes to the provided node list, or perform a standard cluster deletion on "%2$s", followed by a standard cluster creation on one of the new nodes.\n\n' "\"${nodes// /\", \"}\"" "$LOCAL_NODE" "\"${current_nodes// /\", \"}\"" 1>&2
            rc=$RC_INCORRECT_INPUT
        elif [[ -z "$add_nodes$remove_nodes" ]]; then
            cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 446 '\nERROR: the specified node list (%1$s) does not contain any changes from the current cluster nodes (%2$s).\n\n' "\"${nodes// /\", \"}\"" "\"${current_nodes// /\", \"}\"" 1>&2
            rc=$RC_MISSING_INPUT
        fi

        typeset clmgr_cmd=""

        if (( $rc == RC_UNKNOWN || $rc == RC_SUCCESS )); then
            if [[ -n $remove_nodes ]]; then
                CL=$LINENO KLIB_HACMP_delete_node ${remove_nodes// /,}
                rc=$?

                if (( rc == RC_SUCCESS )); then
                    CL=$LINENO isClusterDefined 2>>$CLMGR_TMPLOG 1>&2
                    if (( $? == RC_SUCCESS )); then
                        : Indicate that the cluster has been changed
                        print "HACMPcluster: handle=0" | odmchange -o HACMPcluster

                        #==================================================
                        : Update the clevents file with formatted event and
                        : send an event upstream to the GUI server, if the
                        : node has a running GUI agent on it
                        #==================================================
                        clmgr_cmd="clmgr delete node"
                        print "$0()[$LINENO]($SECONDS): cl_send_ui_event NODE \"$LOCAL_NODE\" CHANGE \"delete node $remove_nodes\" PASSED \"A cluster configuration change was performed on cluster \\\"\$(CL=$LINENO KLIB_HACMP_get_cluster_name)\\\" : $clmgr_cmd $remove_nodes\"" >>$CLMGR_TMPLOG
                        cl_send_ui_event NODE "$LOCAL_NODE" CHANGE "delete node $remove_nodes" PASSED "A cluster configuration change was performed on cluster \"$(CL=$LINENO KLIB_HACMP_get_cluster_name)\" : $clmgr_cmd $remove_nodes"
                        print "$0()[$LINENO]($SECONDS): cl_send_ui_event RC: $?" >>$CLMGR_TMPLOG
                    fi
                fi
            fi
        fi

        if (( $rc == RC_UNKNOWN || $rc == RC_SUCCESS )); then
            integer added=0
            for node in $add_nodes; do
                CL=$LINENO KLIB_HACMP_add_node null $node "" true
                rc=$?

                (( $rc != RC_SUCCESS )) && break
                (( added++ ))
            done

            if (( added )); then
                CL=$LINENO isClusterDefined 2>>$CLMGR_TMPLOG 1>&2
                if (( $? == RC_SUCCESS )); then
                    : Indicate that the cluster has been changed
                    print "HACMPcluster: handle=0" | odmchange -o HACMPcluster
                    #==================================================
                    : Update the clevents file with formatted event and
                    : send an event upstream to the GUI server, if the
                    : node has a running GUI agent on it
                    #==================================================
                    clmgr_cmd="clmgr add node"
                    print "$0()[$LINENO]($SECONDS): cl_send_ui_event NODE \"$LOCAL_NODE\" CHANGE \"add node $add_nodes\" PASSED \"A cluster configuration change was performed on cluster \\\"\$(CL=$LINENO KLIB_HACMP_get_cluster_name)\\\" : $clmgr_cmd $add_nodes\"" >>$CLMGR_TMPLOG
                    cl_send_ui_event NODE "$LOCAL_NODE" CHANGE "add node $add_nodes" PASSED "A cluster configuration change was performed on cluster \"$(CL=$LINENO KLIB_HACMP_get_cluster_name)\" : $clmgr_cmd $add_nodes"
                    print "$0()[$LINENO]($SECONDS): cl_send_ui_event RC: $?" >>$CLMGR_TMPLOG
             
                fi
            fi
        fi

        if (( $rc == RC_SUCCESS )) && [[ -n $add_nodes || -n $remove_nodes ]]
        then
            cl_dspmsg -s 32 scripts 6 "The configuration must be synchronized to make this change known across the cluster.\n"
        fi
    fi

    if (( $rc == RC_UNKNOWN || $rc == RC_SUCCESS )) && \
       [[ -n $lpm_policy ]]
    then
        #=======================================================
        : Setting LPM policy during LPM to "$lpm_policy"
        #=======================================================
        print "$0()[$LINENO]($SECONDS): odmchange -o HACMPcluster ==> lpm_policy=$lpm_policy" >>$CLMGR_TMPLOG
        print "HACMPcluster:
lpm_policy=$lpm_policy" | odmchange -o HACMPcluster
        rc=$?
        print "$0()[$LINENO]($SECONDS): odmchange RC: $rc" >>$CLMGR_TMPLOG
        typeset VAL=$(clodmget -n -f lpm_policy HACMPcluster)
        [[ $VAL == $lpm_policy ]] && rc=$RC_SUCCESS || rc=$RC_ERROR
    fi

    if (( $rc == RC_UNKNOWN || $rc == RC_SUCCESS )) && \
       [[ -n $lpm_heartbeat ]]
    then
        #=======================================================
        : Setting node heartbeat during LPM to "$lpm_heartbeat"
        #=======================================================
        print "$0()[$LINENO]($SECONDS): odmchange -o HACMPcluster ==> lpm_node_timeout=$lpm_heartbeat" >>$CLMGR_TMPLOG
        print "HACMPcluster:
lpm_node_timeout=$lpm_heartbeat" | odmchange -o HACMPcluster
        rc=$?
        print "$0()[$LINENO]($SECONDS): odmchange RC: $rc" >>$CLMGR_TMPLOG
        typeset VAL=$(clodmget -n -f lpm_node_timeout HACMPcluster)
        (( $VAL == $lpm_heartbeat )) && rc=$RC_SUCCESS || rc=$RC_ERROR
    fi

    typeset -i capability=0
    if (( $rc == RC_UNKNOWN || $rc == RC_SUCCESS )) && \
        [[ -n $caa_auto_start_dr ]]
    then
        if [[ $CLUSTER_TYPE != "LC" ]];then
            if caa_dr_capability=$(LC_ALL=C cl_get_capabilities -i CAA_DR 2>&1) \
                && [[ -n $caa_dr_capability ]]
            then
                # If CAA DR capability is defined and globally available, then capability is set to 1
                capability=${caa_dr_capability#*flag:}
            fi
            if (( $capability == 1 ));then
                print "HACMPcluster:
dr_enabled=$dr_enable" | odmchange -o HACMPcluster
                typeset VAL=$(clodmget -n -f dr_enabled HACMPcluster)
                (( $VAL == $dr_enable )) && rc=$RC_SUCCESS || rc=$RC_ERROR
            else
                #Just indicating user that current AIX version do not have support for CAA DR capability 
                cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1180 "\nWARNING: CAA DR capability is not currently available in all nodes across the cluster\n" 1>&2
            fi
        else
            cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1161 "\nERROR:CAA tunable dr_enabled cannot be set in linked cluster\n" 1>&2
            rc=$RC_ERROR
        fi
    fi

    if (( $rc == RC_UNKNOWN || $rc == RC_SUCCESS )); then
        if [[ -n $caa_repos_mode ]]; then
            #====================================================
            : Setting repos mode to "$repos"
            #====================================================
            print "HACMPcluster:
            repos_mode=$repos" | odmchange -o HACMPcluster
            typeset VAL=$(clodmget -n -f repos_mode HACMPcluster)
            (( $VAL == $repos )) && rc=$RC_SUCCESS || rc=$RC_ERROR
        fi
    fi

    if (( $rc == RC_UNKNOWN || $rc == RC_SUCCESS )); then
        if [[ -n $caa_config_timeout ]]; then
            #====================================================
            : Setting config timeout to "$caa_config_timeout"
            #====================================================
            print "HACMPcluster:
            config_timeout=$caa_config_timeout" | odmchange -o HACMPcluster
            typeset VAL=$(clodmget -n -f  config_timeout HACMPcluster)
            (( $VAL == $caa_config_timeout )) && rc=$RC_SUCCESS || rc=$RC_ERROR
        fi
    fi

    if (( $rc == RC_UNKNOWN || $rc == RC_SUCCESS )); then
        if [[ -n $lvm_preferred_read ]]; then
          #====================================================
          : Setting lvm_preferred_read to "$lvm_preferred_read"
          #====================================================
          print "HACMPcluster:
          lvm_preferred_read=$lvm_preferred_read" | odmchange -o HACMPcluster
          typeset VAL=$(clodmget -n -f lvm_preferred_read HACMPcluster)
          [[ $VAL == $lvm_preferred_read ]] && rc=$RC_SUCCESS || rc=$RC_ERROR
        fi
    fi

    if (( $rc == RC_UNKNOWN || $rc == RC_SUCCESS )) && [[ -n $crit_daemon_restart_grace_period ]]; then
        #=====================================================================================
        : Setting critical daemon restart grace period to "$crit_daemon_restart_grace_period"
        #=====================================================================================
        print "HACMPcluster:
crit_daemon_restart_grace_period=$crit_daemon_restart_grace_period" | odmchange -o HACMPcluster
        typeset VAL=$(clodmget -n -f crit_daemon_restart_grace_period HACMPcluster)
        (( $VAL == $crit_daemon_restart_grace_period )) && rc=$RC_SUCCESS || rc=$RC_ERROR
        if (( rc == RC_SUCCESS )); then
            dspmsg -s 63 cluster.cat 79 "Successfully configured the cluster level RSCT Critical Resource Daemon Grace Period.\n\
Tie Breaker and other RSCT services will not work during this time. \n\
And after waiting for %1\$d seconds if daemons are not restarted, cluster nodes will be halted.\n" $crit_daemon_restart_grace_period
        fi  
    fi

    if (( $rc == RC_UNKNOWN || $rc == RC_SUCCESS )); then
        if [[ -n $skip_events_on_manage ]]; then
            #====================================================
            : Setting skip_events_on_manage to "$skip_events_flag"
            #====================================================
            print "HACMPcluster:
            skip_events_on_manage=$skip_events_flag" | odmchange -o HACMPcluster
            typeset VAL=$(clodmget -n -f skip_events_on_manage HACMPcluster)
            (( $VAL == $skip_events_flag )) && rc=$RC_SUCCESS || rc=$RC_ERROR
        fi
    fi


    #===========================================================
    : If output from this operation was requested, retrieve it
    #===========================================================
    if (( $rc == RC_SUCCESS )); then
        [[ -n $new_name ]] && persistent_ip=$new_name
        if (( CLMGR_VERBOSE )) || [[ -n $CLMGR_ATTRS ]]; then
            CL=$LINENO CLMGR_VERBOSE=0 KLIB_HACMP_get_cluster_attributes 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_dspmsg -s $CLMGR_SET $CLMGR_MSGS 104 "For more information about available options and syntax, try\n\"/usr/es/sbin/cluster/utilities/clmgr %1\$s\". As an\nalternative, if the PowerHA SystemMirror man pages have been installed, invoke\n\"/usr/es/sbin/cluster/utilities/clmgr -hv\" (or \"/usr/bin/man clmgr\"),\nsearching for \"%2\$s\" in the displayed text.\n\n" \
        "modify cluster -h" "CLUSTER:" "clmgr" 1>&2
    fi

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

#==============================================================================
# The following, comment block attempts to enforce coding standards when this
# file is edited via emacs or vim. This block _must_ appear at the very end
# of the file, or the editor will not find it, and it will be ignored.
#==============================================================================
# Local Variables:
# indent-tabs-mode: nil
# tab-width: 4
# End:
#==============================================================================
# vim: tabstop=4 shiftwidth=4 expandtab
#==============================================================================
