#!/bin/ksh93 # ALTRAN_PROLOG_BEGIN_TAG # This is an automatically generated prolog. # # Copyright (C) Altran ACT S.A.S. 2021. All rights reserved. # # ALTRAN_PROLOG_END_TAG # # IBM_PROLOG_BEGIN_TAG # This is an automatically generated prolog. # # 61haes_r720 src/43haes/lib/ksh93/hacmp/KLIB_HACMP_add_site.sh 1.16.1.5 # # Licensed Materials - Property of IBM # # COPYRIGHT International Business Machines Corp. 1990,2010 # All Rights Reserved # # US Government Users Restricted Rights - Use, duplication or # disclosure restricted by GSA ADP Schedule Contract with IBM Corp. # # IBM_PROLOG_END_TAG # @(#) e5cc82a 43haes/lib/ksh93/hacmp/KLIB_HACMP_add_site.sh, 726, 2147A_aha726, Jul 09 2021 03:04 PM #================================================ # The following, commented line enforces coding # standards when this file is edited via vim. #================================================ # vim:tabstop=4:shiftwidth=4:expandtab:smarttab #================================================ # Start of POD-formatted documentation. Viewing suggestions: # perldoc # pod2text -c # pod2text -c --code # pod2html function devDoc { : <<'=cut' >/dev/null 2>&1 =head1 NAME KLIB_HACMP_add_site =head1 VERSION Version Number: 1.11 Last Extracted: 4/28/13 08:50:01 Last Changed: 7/7/12 16:16:32 Path, Component, Release(, Level): src/43haes/lib/ksh93/hacmp/KLIB_HACMP_add_site.sh, hacmp.assist, 61haes_r713 =head1 SYNOPSIS clmgr add site \ NODES=[,,...] \ [ SITE_IP= ] \ [ RECOVERY_PRIORITY={MANUAL|1|2} ] \ [ REPOSITORIES=[,,...] ] NOTE: "SITE_IP" may only be used with a cluster type of "LC" ("Linked Clusters"). NOTE: "REPOSITORIES" may only be used with a cluster type of "LC". No more than MAX_NB_OF_BACKUP_REPOSITORIES backup repository disks may be defined per site of a "LC" cluster. =head1 DESCRIPTION Attempts to create a new site object within the cluster that conforms to the provided specifications. =head1 ARGUMENTS 1. properties [REQUIRED] [hash ref] An associative array within which data about the created object can be returned to the caller. 2. sitename [REQUIRED] [string] The label that is to be applied to the new site object. 3. nodelist [REQUIRED] [string] The list of nodes that will be governed by the new site. 4. site_ip [OPTIONAL] [string] A multicast IP address to use for the new site. 5. recovery_priority [OPTIONAL] [string] If the sites become sundered, when the communication problem is corrected, this setting dicates how CAA will know which site should be the main/recovery site. A numeric priority is assigned to each site. By default, though, the priority is set to zero, and the site with the largest number of active nodes is recovered. In the case of a tie (same number of active nodes), then the site with the lowest node ID "wins". 6. repositories [OPTIONAL] [string] One or more disks that will be added as repository disks within the site. First disk is the active repository, and following ones are backup repositories. Nor more than MAX_NB_OF_BACKUP_REPOSITORIES backup repositories are accepted per site. =head1 RETURN 0: no errors were detected; the operation appears to have been successful 1: a general error has occurred 2: a specified resource does not exist, or could not be found 3: some required input was missing 4: some detected input was incorrect in some way 5: a required dependency does not exist 6: a specified search failed to match any data =head1 COPYRIGHT COPYRIGHT International Business Machines Corp. 2005,2010 All Rights Reserved =cut } # End of POD-formatted documentation. # Function to verify the current mode of the cluster policy # If it is set to single node swap mode, should not allow multiple site configuration # exit function verify_clstr_singlenode_config { [[ $CLMGR_LOGGING == 'med' ]] && set +x integer current_mode=0 current_mode=$(clodmget -f single_node_swap HACMPcluster) if [[ $current_mode == 1 ]] then dspmsg -s $CLMGR_SET $CLMGR_MSGS 290 \ "\nERROR: No sites will be supported when cluster policy is set to single node swap mode.\n\n" 1>&2 exit 1 fi } #============================================================================ # # Name: KLIB_HACMP_add_site # # Description: This is the main, FPATH function that is invoked by clmgr # to add a site contianing the specified cluster nodes. If # a site is added to a standard cluster, it is automatically # converted to a stretched cluster, with an appropriate # notification message. If no recovery priority is provided, # it is established as either 1 or 2, as appropriate. # # Inputs: Refer to 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_add_site { LINENO=2 . $HALIBROOT/log_entry "$0()" "$CL" : version=@(#) e5cc82a 43haes/lib/ksh93/hacmp/KLIB_HACMP_add_site.sh, 726, 2147A_aha726, Jul 09 2021 03:04 PM : INPUTS: $* verify_clstr_singlenode_config typeset -n properties=$1 typeset sitename=${2//\"/} typeset nodelist=${3//\"/} nodelist=${nodelist//,/ } typeset site_ip=${4//\"/} typeset recovery_priority=${5//\"/} typeset repositories=${6//\"/} repositories=${repositories//,/ } [[ $CLMGR_LOGGING == 'med' ]] && set +x # Only trace param values #=================================== : Declare and initialize variables #=================================== typeset -i rc=$RC_UNKNOWN typeset node= typeset reposOpt="" # Variable to hold new repository for new site during cluster conversion to linked type. typeset existing CL=$LINENO KLIB_HACMP_list_sites existing 2>>$CLMGR_TMPLOG #================================================================ : Check for a defined cluster. No need to continue without one. #================================================================ CL=$LINENO isClusterDefined if (( $? != RC_SUCCESS )); then rc=$RC_MISSING_DEPENDENCY #================= : Validate input #================= elif [[ -z $sitename ]]; then dspmsg -s $CLMGR_SET $CLMGR_MSGS 100 "\nERROR: a name/label must be provided.\n\n" 1>&2 rc=$RC_MISSING_INPUT elif [[ " ${existing[*]} " == *\ $sitename\ * ]]; then dspmsg -s $CLMGR_SET $CLMGR_MSGS 229 "\nERROR: the specified object already exists: \"%1\$s\"\n\n" "$sitename" 1>&2 rc=$RC_INCORRECT_INPUT elif [[ -n $sitename && -n "${sitename//[a-zA-Z0-9_]/}" ]]; then dspmsg -s $CLMGR_SET $CLMGR_MSGS 105 "\nERROR: one or more invalid characters were detected in \"%1\$s\" (\"%2\$s\").\n\nValid characters include letters, numbers, and underscores only.\n\n" "$sitename" "${sitename//[a-zA-Z0-9_]/}" 1>&2 rc=$RC_INCORRECT_INPUT fi if (( ${#existing[*]} > 1 )); then dspmsg -s $CLMGR_SET $CLMGR_MSGS 218 "\nERROR: two sites are already configured within this cluster,\n \"%1\$s\" and \"%2\$s\".\n\n" "${existing[0]}" "${existing[1]}" 1>&2 rc=$RC_ERROR fi # : If nodes were specified, verify that they are known nodes. # if [[ $nodelist == *([[:space:]]) ]]; then dspmsg -s $CLMGR_SET $CLMGR_MSGS 101 '\nERROR: this operation requires the "%1$s" attribute.\n\n' NODES 1>&2 rc=$RC_MISSING_INPUT elif (( $rc == $RC_UNKNOWN )); then # If no validation errors so far typeset -i new_node_added=0 for node in $nodelist; do CL=$LINENO KLIB_HACMP_is_known_node "${node%%\.*}" >/dev/null 2>&1 if (( $? != RC_SUCCESS )); then : Node $node does not exist. Try to create it. typeset -A nodeAttrs if (( $new_node_added == 1 )); then : Already one new node is added to PowerHA config. : Cannnot add another new node until cluster verify and sync operation is done. : Skipping node $node from supplied nodelist. continue fi # : If cluster type in PowerHA is LC and CAA cluster exists and it has only single site, : then that means cluster type conversion is in progress to linked cluster. : To make ADD_NODE success, we require new_site, new_repos and new_node. : Create a temporary new_site with new_repos_disk to enable communication. # if [[ $CLUSTER_TYPE == "LC" ]] && (( $(LC_ALL=C lscluster -c 2>/dev/null | grep "Multicast for site" | wc -l) == 1 )); then if [[ $repositories == *([[:space:]]) ]]; then dspmsg -s $CLMGR_SET $CLMGR_MSGS 101 '\nERROR: this operation requires the "%1$s" attribute.\n\n' REPOSITORIES 1>&2 rc=$RC_MISSING_INPUT break fi # If more repositories are provided, proceed with only one by ignoring others. if (( $(echo "$repositories" | wc -w) > 1 )); then repositories=$(echo $repositories | cut -d' ' -f1) dspmsg -s $CLMGR_SET $CLMGR_MSGS 1490 '\nINFO: Multiple repositories are provided. Since we are in the process of converting the cluster type, \nproceeding with only one repository %1$s for creating remote site by ignoring the other repositories. \nYou can add additional repositories as backup repositories once the cluster conversion process is completed.\n' $repositories 1>&2 fi # Add new site temporarily using supplied hdisk as repository. # merge_priority as 0 is an indication. print -- "$0()[$LINENO]($SECONDS): claddsite -s \"$sitename\" -r \"$repositories\" -P 0" >>$CLMGR_TMPLOG claddsite -s "$sitename" -r "$repositories" -P 0 rc=$? print "$0()[$LINENO]($SECONDS): claddsite RC: $rc" >>$CLMGR_TMPLOG # Always log command result if (( $rc != RC_SUCCESS )); then dspmsg -s $CLMGR_SET $CLMGR_MSGS 201 "\nERROR: failed to create \"%1\$s\".\n\n" "$sitename" 1>&2 rc=$RC_ERROR fi fi if (( $rc != $RC_ERROR )); then CL=$LINENO KLIB_HACMP_add_node nodeAttrs ${node%%\.*} rc=$? fi if (( $rc != RC_SUCCESS )); then CL=$LINENO cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 201 '\nERROR: failed to create "%1$s".\n\n' "$node" 1>&2 rc=$RC_ERROR fi # One new node is added to PowerHA config. Cannot add another new node until we verify and syncronize the cluster new_node_added=1 # Code for handling cluster conversion from standard to linked type if [[ $CLUSTER_TYPE == "LC" ]] && [[ -n $(clodmget -q "name=$sitename and merge_priority=0" HACMPsite) ]]; then # : As we are in cluster type conversion, remove the temporarily created new_site. # # Collect the resolved new site repos pvid before removing temp site. reposOpt=$(clodmget -q "name=${sitename}_sircol" -n -f repository HACMPsircol) print -- "$0()[$LINENO]($SECONDS): new_site=$sitename; new_site_repos_pvid=$reposOpt" >>$CLMGR_TMPLOG reposOpt=" -r $reposOpt" print -- "$0()[$LINENO]($SECONDS): claddsite -d -s \"$sitename\"" >>$CLMGR_TMPLOG claddsite -d -s "$sitename" rc=$? print "$0()[$LINENO]($SECONDS): claddsite RC: $rc" >>$CLMGR_TMPLOG # Always log command result if (( $rc != RC_SUCCESS )); then rc=$RC_ERROR fi fi fi done fi if [[ -n $recovery_priority ]]; then if [[ $recovery_priority == @(M|m)* ]]; then recovery_priority=0 # Manual recovery elif [[ $recovery_priority != @(0|1|2) ]]; then CL=$LINENO cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 110 '\nERROR: invalid value specified for "%1$s": "%2$s".\n' RECOVERY_PRIORITY "$recovery_priority" 1>&2 dspmsg -s $CLMGR_SET $CLMGR_MSGS 3 "Valid values: %1\$s\n\n" "MANUAL, 1, 2" 1>&2 rc=$RC_INCORRECT_INPUT fi else recovery_priority=1 if [[ -n $(clodmget -n -f merge_priority -q "merge_priority = 1" HACMPsite) ]] then recovery_priority=2 fi fi if [[ -n $site_ip ]]; then if [[ $CLUSTER_TYPE != "LC" ]]; then CL=$LINENO cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 260 '\nERROR: a site-specific multicast IP address is only valid for linked clusters. This cluster was defined as a "%1%s" cluster, which only utilizes a single multicast IP address defined at the cluster level.\n\n' "$site_ip" 1>&2 rc=$RC_INCORRECT_INPUT else # Validate the site multicast address CL=$LINENO verify_is_multicast_address $site_ip (( $? != RC_SUCCESS )) && rc=RC_INCORRECT_INPUT fi fi if [[ -n $repositories && -z $nodelist ]]; then cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1004 '\nERROR: repositories may only be specified if nodes are specified.\n\n' 1>&2 rc=$RC_INCORRECT_INPUT fi if [[ -n $repositories && $CLUSTER_TYPE != "LC" ]]; then cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 437 '\nERROR: repositories may only 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 1001 "\nERROR: a linked cluster cannot get more than \"%1\$s\" backup repositories per site (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 #======================================================== : Create the site if no input errors have been detected #======================================================== if (( $rc == RC_UNKNOWN || $rc == RC_SUCCESS )); then typeset iOpt="" POpt="" [[ -n $site_ip ]] && iOpt=" -i $site_ip" [[ -n $recovery_priority ]] && POpt=" -P $recovery_priority" #============================================================ : If this is a standard/NSC cluster, then warn that it will : be automatically converted to a stretched cluster. #============================================================ if [[ $CLUSTER_TYPE == "NSC" ]] then cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1014 " Warning: this cluster is currently defined as a standard, no-sites cluster. Since a site (\"%1\$s\") is being added to it, it will be automatically converted to a stretched cluster.\n" "$sitename" sleep 5 # Provide a little Ctrl+C time fi if [[ -n $nodelist ]]; then print -- "$0()[$LINENO]($SECONDS): claddsite -s \"$sitename\" -n \"$nodelist\"$reposOpt$iOpt$POpt" >>$CLMGR_TMPLOG # Always log commands claddsite -s "$sitename" -n "$nodelist"$reposOpt$iOpt$POpt 1>&2 rc=$? print "$0()[$LINENO]($SECONDS): claddsite RC: $rc" >>$CLMGR_TMPLOG # Always log command result if (( $rc != RC_SUCCESS )); then dspmsg -s $CLMGR_SET $CLMGR_MSGS 201 "\nERROR: failed to create \"%1\$s\".\n\n" "$sitename" 1>&2 rc=$RC_ERROR fi else print -- "$0()[$LINENO]($SECONDS): claddsite -s \"$sitename\"$iOpt$POpt" >>$CLMGR_TMPLOG # Always log commands claddsite -s "$sitename"$iOpt$POpt 1>&2 rc=$? print "$0()[$LINENO]($SECONDS): claddsite RC: $rc" >>$CLMGR_TMPLOG # Always log command result if (( $rc != RC_SUCCESS )); then dspmsg -s $CLMGR_SET $CLMGR_MSGS 201 "\nERROR: failed to create \"%1\$s\".\n\n" "$sitename" 1>&2 rc=$RC_ERROR fi fi if (( rc == RC_SUCCESS )) && [[ $CLUSTER_TYPE == "NSC" ]] then #============================================================= : The site was successfully added to this standard cluster. : Change the cluster type to stretched to reflect that sites : are now defined. #============================================================= print "$0()[$LINENO]($SECONDS): multi_site_lc == $(clodmget -f multi_site_lc HACMPcluster)" >>$CLMGR_TMPLOG print "$0()[$LINENO]($SECONDS): echo \"HACMPcluster: multi_site_lc=0\" | odmchange -o HACMPcluster" >>$CLMGR_TMPLOG print "HACMPcluster: multi_site_lc=0" | odmchange -o HACMPcluster print "$0()[$LINENO]($SECONDS): multi_site_lc == $(clodmget -f multi_site_lc HACMPcluster)" >>$CLMGR_TMPLOG cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1013 "\nNote: now that a site has been added to the cluster, the cluster type has been automatically changed from standard to stretched.\n" fi #===================================== # Modify repositories, if applicable #===================================== if (( $rc == RC_UNKNOWN || $rc == RC_SUCCESS )); then # Skip repository handling(add/replace), if reposOpt is set if [[ -n $repositories && -z $reposOpt ]]; then if (( ! incluster )); then typeset -A arprops CL=$LINENO KLIB_HACMP_add_repository arprops "$repositories" "$sitename" rc=$? elif [[ ${repositories//,/} != *([[:space:]]) ]]; then CL=$LINENO KLIB_HACMP_replace_repository "${repositories%% *}" "$sitename" rc=$? fi fi fi #=========================================================== : If output from this operation was requested, retrieve it #=========================================================== if (( $rc == RC_SUCCESS )); then if (( CLMGR_VERBOSE )) || [[ -n $CLMGR_ATTRS ]]; then CL=$LINENO KLIB_HACMP_get_site_attributes "$sitename" properties fi fi fi #======================================================================= : If a user input error was detected, provide some helpful suggestions #======================================================================= if (( $rc == RC_MISSING_INPUT || $rc == RC_INCORRECT_INPUT )) && \ [[ $CLMGR_GUI == *([[:space:]]) ]] then CL=$LINENO cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 104 "For more information about available options and syntax, try\n\"$HAUTILS/clmgr %1\$s\". As an\nalternative, if the PowerHA SystemMirror man pages have been installed, invoke\n\"$HAUTILS/clmgr -hv\" (or \"/usr/bin/man clmgr\"),\nsearching for \"%2\$s\" in the displayed text.\n\n" \ "add site -h" "SITE:" "$CLMGR_PROGNAME" 1>&2 fi log_return_msg "$rc" "$0()" "$LINENO" return $? } # End of "KLIB_HACMP_add_site()"