#!/bin/ksh93 # ALTRAN_PROLOG_BEGIN_TAG # This is an automatically generated prolog. # # Copyright (C) Altran ACT S.A.S. 2017,2018,2019,2020,2021. All rights reserved. # # ALTRAN_PROLOG_END_TAG # # @(#) 7d4c34b 43haes/lib/ksh93/hacmp/KLIB_HACMP_add_resourcegroup.sh, 726, 2147A_aha726, Feb 05 2021 09:50 PM #============================================================================ # # Name: KLIB_HACMP_add_resourcegroup # # Description: This is the main, FPATH function that is invoked by clmgr # to add a resource group to the specified cluster nodes. # # Inputs: See the "devDoc()" function, below. # # 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, below, for the standard return # code values/meanings for clmgr. # #============================================================================ function KLIB_HACMP_add_resourcegroup { LINENO=2 . $HALIBROOT/log_entry "$0()" "$CL" : version=@(#) 7d4c34b 43haes/lib/ksh93/hacmp/KLIB_HACMP_add_resourcegroup.sh, 726, 2147A_aha726, Feb 05 2021 09:50 PM : INPUTS: $* typeset -n properties=$1 typeset rgnames=${2//\"/} shift; shift typeset -n nodes=$1 [[ -n $2 ]] && typeset -n rg_behavior=$2 || typeset -A rg_behavior [[ -n $3 ]] && typeset -n attributes=$3 || typeset -A attributes typeset site_policy=${4//\"/} typeset mirror_group=${5//\"/} [[ $CLMGR_LOGGING == 'med' ]] && set +x # Only trace param values #================================================================ : Check for a defined cluster. No need to continue without one. #================================================================ CL=$LINENO isClusterDefined if (( $? != RC_SUCCESS )); then log_return_msg "$RC_MISSING_DEPENDENCY" "$0()" "$LINENO" return $? fi #=================================== : Declare and initialize variables #=================================== typeset -i rc=$RC_UNKNOWN typeset -u uc_text= typeset rgname= typeset -A startup fallover fallback startup=( [0]="OHN" [OHN]="OHN" [OFAN]="OFAN" [OAAN]="OAAN" [OUDP]="OUDP" ) fallback=( [0]="FBHPN" [NFB]="NFB" [FBHPN]="FBHPN" ) fallover=( [0]="FNPN" [FNPN]="FNPN" [FUDNP]="FUDNP" [BO]="BO" ) #================================================================= : If any of the concurrent resource group policies are specified : incompletely, fill in the missing policies for the customer. #================================================================= if [[ "${rg_behavior[startup]}:${rg_behavior[fallover]}:${rg_behavior[fallback]}" == "OAAN::" ]] then rg_behavior[fallover]="BO" rg_behavior[fallback]="NFB" elif [[ "${rg_behavior[startup]}:${rg_behavior[fallover]}:${rg_behavior[fallback]}" == ":BO:" ]] then rg_behavior[startup]="OAAN" rg_behavior[fallback]="NFB" fi if [[ -z "${startup[${rg_behavior[startup]}]}" ]]; then rg_behavior[startup]=${startup[0]} else uc_text=${rg_behavior[startup]} rg_behavior[startup]=$uc_text fi if [[ -z "${fallback[${rg_behavior[fallback]}]}" ]]; then rg_behavior[fallback]=${fallback[0]} else uc_text=${rg_behavior[fallback]} rg_behavior[fallback]=$uc_text fi if [[ -z "${fallover[${rg_behavior[fallover]}]}" ]]; then rg_behavior[fallover]=${fallover[0]} else uc_text=${rg_behavior[fallover]} rg_behavior[fallover]=$uc_text fi #=============================================== : Check for compatibility between the fallback : policy and the fallback timer setting. #=============================================== if [[ ${rg_behavior[fallback]} == "NFB" && \ -n ${attributes[FALLBACK_AT]} ]] then cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 36 '\nERROR: conflicting options were provided, "%1$s" versus "%2$s".\n\n' "TIMER=${attributes[FALLBACK_AT]}" "FALLBACK=NFB" 1>&2 rc=$RC_INCORRECT_INPUT fi nodes[nodes]=${nodes[nodes]//,/ } nodes[primary]=${nodes[primary]//,/ } if [[ -n ${nodes[primary]} ]]; then for node in ${nodes[nodes]}; do [[ " ${nodes[primary]} " == *\ $node\ * ]] && continue nodes[primary]="${nodes[primary]} $node" done else nodes[primary]="${nodes[nodes]}" fi nodes[secondary]=${nodes[secondary]//,/ } typeset nodelist="${nodes[nodes]} ${nodes[primary]} ${nodes[secondary]}" nodelist=$(echo ${nodelist//+([[:space:]])/\\n} | sort -u) nodelist=$(echo ${nodelist//$NL/ }) typeset existing CL=$LINENO KLIB_HACMP_list_resourcegroups existing 2>>$CLMGR_TMPLOG #================= : Validate input #================= if [[ -z $rgnames ]]; then dspmsg -s $CLMGR_SET $CLMGR_MSGS 100 "\nERROR: a name/label must be provided.\n\n" 1>&2 rc=$RC_MISSING_INPUT fi if [[ -n ${rg_behavior[startup]} && \ ${rg_behavior[startup]} != @(OHN|OFAN|OAAN|OUDP) ]] then dspmsg -s $CLMGR_SET $CLMGR_MSGS 110 '\nERROR: invalid value specified for "%1$s": "%2$s".\n' STARTUP "${rg_behavior[startup]}" 1>&2 dspmsg -s $CLMGR_SET $CLMGR_MSGS 3 "Valid values: %1\$s\n\n" "OHN, OFAN, OAAN, OUDP" 1>&2 rc=$RC_INCORRECT_INPUT fi if [[ -n ${rg_behavior[fallback]} && \ ${rg_behavior[fallback]} != @(NFB|FBHPN) ]] then dspmsg -s $CLMGR_SET $CLMGR_MSGS 110 '\nERROR: invalid value specified for "%1$s": "%2$s".\n' FALLBACK "${rg_behavior[fallback]}" 1>&2 dspmsg -s $CLMGR_SET $CLMGR_MSGS 3 "Valid values: %1\$s\n\n" "NFB, FBHPN" 1>&2 rc=$RC_INCORRECT_INPUT fi if [[ -n ${rg_behavior[fallover]} && \ ${rg_behavior[fallover]} != @(FNPN|FUDNP|BO) ]] then dspmsg -s $CLMGR_SET $CLMGR_MSGS 110 '\nERROR: invalid value specified for "%1$s": "%2$s".\n' FALLOVER "${rg_behavior[fallover]}" 1>&2 dspmsg -s $CLMGR_SET $CLMGR_MSGS 3 "Valid values: %1\$s\n\n" "FNPN, FUDNP, BO" 1>&2 rc=$RC_INCORRECT_INPUT fi 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 else # : If nodes were specified, verify that they are known nodes. # typeset -i all_nodes_found=1 for node in $nodelist; do CL=$LINENO KLIB_HACMP_is_known_node "$node" >/dev/null 2>&1 if (( $? != RC_SUCCESS )); then rc=$RC_INCORRECT_INPUT all_nodes_found=0 dspmsg -s $CLMGR_SET $CLMGR_MSGS 102 '\nERROR: "%1$s" does not appear to exist!\n\n' "$node" 1>&2 fi done if (( ! all_nodes_found )); then dspmsg -s $CLMGR_SET $CLMGR_MSGS 151 "Available Nodes:\n\n" 1>&2 typeset available CL=$LINENO KLIB_HACMP_list_nodes available for (( i=0; i<${#available[*]}; i++ )); do if [[ ${available[$i]} != *([[:space:]]) ]]; then print -u2 "\t${available[$i]}" fi done print -u2 "" fi fi if [[ -n $site_policy || -n ${nodes[secondary]} ]]; then print "$0()[$LINENO]($SECONDS): cllssite" >>$CLMGR_TMPLOG # Always log commands cllssite >/dev/null 2>>$CLMGR_TMPLOG cmd_rc=$? print "$0()[$LINENO]($SECONDS): cllssite RC: $cmd_rc" >>$CLMGR_TMPLOG # Always log command result if (( $cmd_rc != RC_SUCCESS )); then dspmsg -s $CLMGR_SET $CLMGR_MSGS 220 "\nERROR: site-specific attributes were specified,\n but sites are not defined in this cluster.\n\n" 1>&2 rc=$RC_INCORRECT_INPUT elif [[ -n $site_policy ]]; then case $site_policy in ignore) ;; primary) site_policy=PPS ;; either) site_policy=OES ;; both) site_policy=OBS ;; *) dspmsg -s $CLMGR_SET $CLMGR_MSGS 110 '\nERROR: invalid value specified for "%1$s": "%2$s".\n' SITE_POLICY "$site_policy" 1>&2 dspmsg -s $CLMGR_SET $CLMGR_MSGS 3 "Valid values: %1\$s\n\n" "ignore, primary, either, both" 1>&2 rc=$RC_INCORRECT_INPUT ;; esac fi fi # : If service IPS were specified, verify that they are known service IPs. # if [[ ${attributes[SERVICE_LABEL]} != *([[:space:]]) ]]; then typeset sip="" sips=${attributes[SERVICE_LABEL]} sips=${sips//,/ } typeset -i all_sips_found=1 typeset FINAL_SIPS="" for sip in $sips; do typeset LABEL="" CL=$LINENO KLIB_HACMP_is_known_service_ip "$sip" LABEL >/dev/null 2>&1 if (( $? != RC_SUCCESS )); then dspmsg -s $CLMGR_SET $CLMGR_MSGS 102 '\nERROR: "%1$s" does not appear to exist!\n\n' "$sip" 1>&2 rc=$RC_INCORRECT_INPUT all_sips_found=0 elif [[ -n $LABEL && $sip != $LABEL ]]; then [[ -n $FINAL_SIPS ]] && FINAL_SIPS="$FINAL_SIPS " FINAL_SIPS="$FINAL_SIPS$LABEL" else [[ -n $FINAL_SIPS ]] && FINAL_SIPS="$FINAL_SIPS " FINAL_SIPS="$FINAL_SIPS$sip" fi done if (( ! all_sips_found )); then dspmsg -s $CLMGR_SET $CLMGR_MSGS 156 "Available Service IPs:\n\n" 1>&2 typeset available CL=$LINENO KLIB_HACMP_list_service_ip available for (( i=0; i<${#available[*]}; i++ )); do if [[ ${available[$i]} != *([[:space:]]) ]]; then print -u2 "\t${available[$i]}" fi done print -u2 "" elif [[ -n $FINAL_SIPS ]]; then integer VALID_SI=1 typeset SI_RG="" attr="" for sip in $FINAL_SIPS; do #============================================ : Make sure that service IP $sip is not : assigned to more than one resource group. #============================================ print "$0()[$LINENO]($SECONDS): clodmget -q \"name=SERVICE_LABEL AND value=$sip\" -f group -n HACMPresource" >>$CLMGR_TMPLOG # Always log commands SI_RG=$(clodmget -q "name=SERVICE_LABEL AND value=$sip" -f group -n HACMPresource 2>>$CLMGR_TMPLOG) print "$0()[$LINENO]($SECONDS): RG for $sip: \"$SI_RG\"" >>$CLMGR_TMPLOG # Always log command result if [[ -n $SI_RG ]]; then cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1124 '\nERROR: the specified service label, "%1$s", is already in use by resource group "%2$s".\n\n' "$sip" "$SI_RG" 1>&2 rc=$RC_INCORRECT_INPUT VALID_SI=0 fi done (( VALID_SI )) && attributes[SERVICE_LABEL]=${FINAL_SIPS// /,} unset VALID_SI SI_RG attr fi fi # : If application controllers were specified, verify that they are : known application controllers. # if [[ ${attributes[APPLICATIONS]} != *([[:space:]]) ]]; then typeset app= apps=${attributes[APPLICATIONS]} apps=${apps//,/ } typeset -i all_apps_found=1 typeset -i app_count=0 typeset -i appmon_per_app_count=0 typeset -i appmon_count=0 for app in $apps; do appmon_per_app_count=0 CL=$LINENO KLIB_HACMP_is_known_appserver "$app" >/dev/null 2>&1 if (( $? != RC_SUCCESS )); then dspmsg -s $CLMGR_SET $CLMGR_MSGS 102 '\nERROR: "%1$s" does not appear to exist!\n\n' "$app" 1>&2 rc=$RC_INCORRECT_INPUT all_apps_found=0 else appmon_per_app_count=$(clodmget -q "name = RESOURCE_TO_MONITOR AND value = $app" -f monitor HACMPmonitor | wc -l) (( appmon_count += appmon_per_app_count )) (( app_count++ )) fi done if (( ! all_apps_found )); then dspmsg -s $CLMGR_SET $CLMGR_MSGS 140 "Available Application Controllers:\n\n" 1>&2 typeset available CL=$LINENO KLIB_HACMP_list_appservers available for (( i=0; i<${#available[*]}; i++ )); do if [[ ${available[$i]} != *([[:space:]]) ]]; then print -u2 "\t${available[$i]}" fi done print -u2 "" fi if (( $app_count > $MAX_USER_RESOURCES )) then #=========================================================================== : This check is added to stop the user if he adds more than specified limit : for application controllers in a resource group. The same code is used in : KLIB_HACMP_modify_resourcegroup.sh. Any modifications here should also be : replicated in KLIB_HACMP_modify_resourcegroup.sh. #=========================================================================== cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1444 "\nERROR: The number of configured %1\$s resources(%2\$d)\n\ has exceeded its maximum limit(%3\$d) per resource group.\n" "APPLICATION_CONTROLLER" "$app_count" "$MAX_USER_RESOURCES" rc=$RC_INCORRECT_INPUT fi if (( $appmon_count > $MAX_USER_RESOURCES )) then #=========================================================================== : This check is added to stop the user if he adds more than specified limit : for application monitors in a resource group. The same code is used in : KLIB_HACMP_modify_resourcegroup.sh. Any modifications here should also be : replicated in KLIB_HACMP_modify_resourcegroup.sh. #=========================================================================== cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1444 "\nERROR: The number of configured %1\$s resources(%2\$d)\n\ has exceeded its maximum limit(%3\$d) per resource group.\n" "APPLICATION_MONITOR" "$appmon_count" "$MAX_USER_RESOURCES" rc=$RC_INCORRECT_INPUT fi fi # : If volume groups were specified, verify that they are : known volume groups. # if [[ ${attributes[VOLUME_GROUP]} != *([[:space:]]) ]]; then typeset vg= vgs=${attributes[VOLUME_GROUP]//,/ } typeset -i all_vgs_found=1 typeset -i vg_count=0 for vg in $vgs; do CL=$LINENO KLIB_HACMP_is_known_volume_group "$vg" >/dev/null 2>&1 if (( $? != RC_SUCCESS )); then dspmsg -s $CLMGR_SET $CLMGR_MSGS 102 '\nERROR: "%1$s" does not appear to exist!\n\n' "$vg" 1>&2 rc=$RC_INCORRECT_INPUT all_vgs_found=0 else (( vg_count++ )) fi done if (( ! all_vgs_found )); then dspmsg -s $CLMGR_SET $CLMGR_MSGS 160 "Available Volume Groups:\n\n" 1>&2 typeset available CL=$LINENO KLIB_HACMP_list_volume_groups available for (( i=0; i<${#available[*]}; i++ )); do if [[ ${available[$i]} != *([[:space:]]) ]]; then print -u2 "\t${available[$i]}" fi done print -u2 "" else #==================================================== : Make sure the correct VG type is used for this RG #==================================================== typeset vg_type="VOLUME_GROUP" [[ $startup == "OAAN" ]] && vg_type="CONCURRENT_VOLUME_GROUP" attributes[CONCURRENT_VOLUME_GROUP]="" attributes[VOLUME_GROUP]="" for vg in $vgs; do if [[ " ${attributes[$vg_type]} " != *\ $vg\ * ]]; then if [[ -n ${attributes[$vg_type]} ]]; then attributes[$vg_type]="${attributes[$vg_type]} " fi attributes[$vg_type]="${attributes[$vg_type]}$vg" fi done fi if (( $vg_count > $MAX_USER_RESOURCES )); then #=========================================================================== : This check is added to stop the user if he adds more than specified limit : for volume groups in a resource group. The same code is used in : KLIB_HACMP_modify_resourcegroup.sh. Any modifications here should also be : replicated in KLIB_HACMP_modify_resourcegroup.sh. #=========================================================================== cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1444 "\nERROR: The number of configured %1\$s resources(%2\$d)\n\ has exceeded its maximum limit(%3\$d) per resource group.\n" "VOLUME_GROUP" "$vg_count" "$MAX_USER_RESOURCES" rc=$RC_INCORRECT_INPUT fi fi # : If file systems were specified, parse them and verify max limit # if [[ ${attributes[FILESYSTEM]} != *([[:space:]]) ]]; then typeset -i fs_count=0 fs_dup=0 typeset fs= fs_list= fs_type="FILESYSTEM" # convert comma separated list into space separated one fs_list=${attributes[$fs_type]//,/ } # Parse the provided FS list to find total FS count excluding duplicates(if any) # And, fill attributes[FILESYSTEM] with valid filesystems only attributes[$fs_type]="" for fs in $fs_list; do if [[ " ${attributes[$fs_type]} " != *\ $fs\ * ]]; then if [[ -n ${attributes[$fs_type]} ]]; then attributes[$fs_type]="${attributes[$fs_type]} " fi attributes[$fs_type]="${attributes[$fs_type]}$fs" (( fs_count++ )) else (( fs_dup++ )) fi done if (( $fs_dup > 0 )); then cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1442 "\nINFO: Found %1\$d duplicate entries in %2\$s list. Excluding them.\n" "$fs_dup" "$fs_type" fi if (( $fs_count > $MAX_USER_RESOURCES )); then #=========================================================================== : This check is added to stop the user if he adds more than specified limit : for file systems in a resource group. The same code is used in : KLIB_HACMP_modify_resourcegroup.sh. Any modifications here should also be : replicated in KLIB_HACMP_modify_resourcegroup.sh. #=========================================================================== cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1444 "\nERROR: The number of configured %1\$s resources(%2\$d)\n\ has exceeded its maximum limit(%3\$d) per resource group.\n" "$fs_type" "$fs_count" "$MAX_USER_RESOURCES" rc=$RC_INCORRECT_INPUT fi fi #================================================ : If a node priority policy has been specified, : makes sure a compatible fallover policy has : also been set. #================================================ if [[ ${attributes[NODE_PRIORITY_POLICY]} != *([[:space:]]) && \ ${attributes[NODE_PRIORITY_POLICY]} != "default" && \ ${fallover[${rg_behavior[fallover]}]} != "FUDNP" ]] then dspmsg -s $CLMGR_SET $CLMGR_MSGS 230 '\nERROR: a node priority policy may only be used with a fallover policy\n of "FUDNP" ("Fallover Using Dynamic Node Priority").\n\n' 1>&2 rc=$RC_INCORRECT_INPUT fi #================================================ : If a node priority policy script has been specified, : make sure a compatible fallover policy has : also been set. #================================================ if [[ ${attributes[NODE_PRIORITY_POLICY_SCRIPT]} != *([[:space:]]) && \ ${fallover[${rg_behavior[fallover]}]} != "FUDNP" ]] then dspmsg -s $CLMGR_SET $CLMGR_MSGS 1177 '\nERROR: Node priority policy script is only used with a fallover policy\nof "FUDNP" ("Fallover Using Dynamic Node Priority").\n\n' 1>&2 rc=$RC_INCORRECT_INPUT fi #================================================ : If a node priority policy timeout has been specified, : make sure a compatible fallover policy has : also been set. #================================================ if [[ ${attributes[NODE_PRIORITY_POLICY_TIMEOUT]} != *([[:space:]]) && \ ${fallover[${rg_behavior[fallover]}]} != "FUDNP" ]] then dspmsg -s $CLMGR_SET $CLMGR_MSGS 1178 '\nERROR: Node priority policy timeout is only used with a fallover policy\nof "FUDNP" ("Fallover Using Dynamic Node Priority").\n\n' 1>&2 rc=$RC_INCORRECT_INPUT fi #===================================================================== : If a node priority policy of "least" or "most" has been specified, : makes sure a valid policy script has also been specified. #===================================================================== if [[ ${attributes[NODE_PRIORITY_POLICY]} != *([[:space:]]) && \ ${attributes[NODE_PRIORITY_POLICY]} == @(least|most) ]] then if [[ ${attributes[NODE_PRIORITY_POLICY_SCRIPT]} == *([[:space:]]) || \ ! -f ${attributes[NODE_PRIORITY_POLICY_SCRIPT]} ]] then dspmsg -s $CLMGR_SET $CLMGR_MSGS 231 '\nERROR: a node priority policy of "least" or "most" requires\n an associated, valid script to be specified using the\n "NODE_PRIORITY_POLICY_SCRIPT" option.\n\n' 1>&2 rc=$RC_INCORRECT_INPUT fi fi if (( $rc == RC_UNKNOWN )); then for rgname in ${rgnames//,/ }; do [[ -z $rgname ]] && continue if [[ " ${existing[*]} " == *\ $rgname\ * ]]; then dspmsg -s $CLMGR_SET $CLMGR_MSGS 229 '\nERROR: the specified object already exists: "%1$s"\n\n' "$rgname" 1>&2 rc=$RC_INCORRECT_INPUT elif [[ -n $rgname && -n "${rgname//[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' "$rgname" "${rgname//[a-zA-Z0-9_]/}" 1>&2 rc=$RC_INCORRECT_INPUT elif (( ${#rgname} > $MAX_NAME_LENGTH )); then dspmsg -s $CLMGR_SET $CLMGR_MSGS 1464 '\nERROR: Resource Group name %1$s should not be more than %2$d characters.\n' "$rgname" "$MAX_NAME_LENGTH" 1>&2 rc=$RC_INCORRECT_INPUT fi #================================================================== : If a WPAR was specified, its name must match the name of the RG #================================================================== if (( $rc == RC_UNKNOWN )); then if [[ ${attributes[WPAR_NAME]} != *([[:space:]]) ]]; then if [[ ${attributes[WPAR_NAME]} != $rgname ]]; then cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1125 '\nERROR: the specified WPAR_NAME, "%1$s", does not match the resource group name, "%2$s".\n\n' "${attributes[WPAR_NAME]}" "$rgname" 1>&2 rc=$RC_INCORRECT_INPUT fi fi fi #================================================================== : Create the resource group if no input errors have been detected #================================================================== if (( $rc == RC_UNKNOWN )); then if [[ -n $site_policy || -n ${nodes[secondary]} ]]; then [[ -z $site_policy ]] && site_policy=ignore print "$0()[$LINENO]($SECONDS): claddgrp -g \"$rgname\" -y \"${nodes[primary]}\" -z \"${nodes[secondary]}\" -S \"${startup[${rg_behavior[startup]}]}\" -O \"${fallover[${rg_behavior[fallover]}]}\" -B \"${fallback[${rg_behavior[fallback]}]}\" -s \"$site_policy\"" >>$CLMGR_TMPLOG # Always log commands claddgrp -g "$rgname" \ -y "${nodes[primary]}" \ -z "${nodes[secondary]}" \ -S "${startup[${rg_behavior[startup]}]}" \ -O "${fallover[${rg_behavior[fallover]}]}" \ -B "${fallback[${rg_behavior[fallback]}]}" \ -s "$site_policy" else typeset nodeList=${nodes[primary]} if [[ -n $nodeList && -n ${nodes[secondary]} ]]; then nodeList="$nodeList ${nodes[secondary]}" fi print "$0()[$LINENO]($SECONDS): claddgrp -g \"$rgname\" -n \"$nodeList\" -S \"${startup[${rg_behavior[startup]}]}\" -O \"${fallover[${rg_behavior[fallover]}]}\" -B \"${fallback[${rg_behavior[fallback]}]}\"" >>$CLMGR_TMPLOG # Always log commands claddgrp -g "$rgname" \ -n "$nodeList" \ -S "${startup[${rg_behavior[startup]}]}" \ -O "${fallover[${rg_behavior[fallover]}]}" \ -B "${fallback[${rg_behavior[fallback]}]}" fi rc=$? print "$0()[$LINENO]($SECONDS): claddgrp RC: $rc" >>$CLMGR_TMPLOG # Always log command result if (( $rc != RC_SUCCESS )); then rc=$RC_ERROR dspmsg -s $CLMGR_SET $CLMGR_MSGS 201 '\nERROR: failed to create "%1$s".\n\n' "$rgname" 1>&2 : Clean up any partially created/configured resource group CL=$LINENO KLIB_HACMP_delete_resourcegroup "$rgname" >/dev/null 2>&1 else #========================================================= : If any other resource group parameters were specified, : call the resource group modification script to attempt : to set them. This avoids having duplicate code in that : script *and* this one. #========================================================= if [[ "${!attributes[*]}$mirror_group" != *([[:space:]]) ]]; then CL=$LINENO KLIB_HACMP_modify_resourcegroup properties "$rgname" attributes "$mirror_group" rc=$? if (( $rc != RC_SUCCESS )); then rc=$RC_ERROR dspmsg -s $CLMGR_SET $CLMGR_MSGS 201 '\nERROR: failed to create "%1$s".\n\n' "$rgname" 1>&2 : Clean up the partially configured resource group CL=$LINENO KLIB_HACMP_delete_resourcegroup "$rgname" >/dev/null 2>&1 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_rg_attributes "$rgname" properties fi fi fi (( $rc != RC_SUCCESS )) && break || rc=$RC_UNKNOWN # Reset done (( $rc == RC_UNKNOWN )) && rc=$RC_SUCCESS 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"$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 resource_group -h" "RESOURCE GROUP:" "$CLMGR_PROGNAME" 1>&2 fi log_return_msg "$rc" "$0()" "$LINENO" return $? } # End of "KLIB_HACMP_add_resourcegroup()" #============================================================================ # # 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 # pod2text -c # pod2text -c --code # pod2html # # 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_add_resourcegroup =head1 VERSION Version Number: 1.2 Last Extracted: 02/02/17 14:30:00 Last Changed: 02/02/17 16:45:00 Path, Component, Release(, Level): src/43haes/lib/ksh93/hacmp/KLIB_HACMP_add_resourcegroup.sh, hacmp.assist, 61aha_r722, 1439A_hacmp722 =head1 SYNOPSIS clmgr add resource_group [,,...] \ NODES=[,,...] \ [ SECONDARYNODES=[,,...] ] \ [ SITE_POLICY={ignore|primary|either|both} ] \ [ STARTUP={OHN|OFAN|OAAN|OUDP} ] \ [ FALLOVER={FNPN|FUDNP|BO} ] \ [ FALLBACK={NFB|FBHPN} ] \ [ NODE_PRIORITY_POLICY={default|mem|cpu| \ disk|least|most} ] \ [ NODE_PRIORITY_POLICY_SCRIPT= ] \ [ NODE_PRIORITY_POLICY_TIMEOUT=### ] \ [ SERVICE_LABEL=service_ip#1[,service_ip#2,...] ] \ [ APPLICATIONS=appctlr#1[,appctlr#2,...] ] \ [ SHARED_TAPE_RESOURCES=[,,...] ] \ [ VOLUME_GROUP=[,,...] ] \ [ FORCED_VARYON={true|false} ] \ [ VG_AUTO_IMPORT={true|false} ] \ [ FILESYSTEM=/file_system#1[,/file_system#2,...] ] \ [ DISK=[,,...] ] \ [ FS_BEFORE_IPADDR={true|false} ] \ [ WPAR_NAME="wpar_name" ] \ [ EXPORT_FILESYSTEM=/expfs#1[,/expfs#2,...] ] \ [ EXPORT_FILESYSTEM_V4=/expfs#1[,/expfs#2,...] ] \ [ STABLE_STORAGE_PATH="/fs3" ] \ [ NFS_NETWORK="nfs_network" ] \ [ MOUNT_FILESYSTEM=/nfs_fs1;/expfs1,/nfs_fs2;,... ] \ [ MIRROR_GROUP= ] \ [ FALLBACK_AT= ] NOTE: the FALLBACK_AT parameter is only valid if the FALLBACK policy is not "NFB". An alias of "TIMER" may be used. STARTUP: OHN ----- Online Home Node (default value) OFAN ---- Online on First Available Node OAAN ---- Online on All Available Nodes (concurrent) OUDP ---- Online Using Node Distribution Policy FALLBACK: NFB ----- Never Fallback FBHPN --- Fallback to Higher Priority Node (default value) FALLOVER: FNPN ---- Fallover to Next Priority Node (default value) FUDNP --- Fallover Using Dynamic Node Priority BO ------ Bring Offline (On Error Node Only) NODE_PRIORITY_POLICY: NOTE: this policy may only be established if if the FALLOVER policy has been set to "FUDNP". default - next node in the NODES list mem ----- node with most available memory disk ---- node with least disk activity cpu ----- node with most available CPU cycles least --- node where the dynamic node priority script returns the lowest value most ---- node where the dynamic node priority script returns the highest value SITE_POLICY: ignore -- Ignore primary - Prefer Primary Site either -- Online On Either Site both ---- Online On Both Sites NOTE: "SECONDARYNODES" and "SITE_POLICY" only apply when sites are configured within the cluster. NOTE: the "SITE" and "SECONDARY" attributes are only applicable when sites are configured in the cluster. NOTE: the "SECONDARY" attribute defaults to "false". NOTE: the alias for "resource_group" is "rg". =head1 DESCRIPTION Attempts to create a new resource group 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. rgnames [REQUIRED] [string] The labels to apply to the new resource groups. 3. nodes [REQUIRED] [hash ref] The list of nodes that the resource group will be operated on. 4. rg_behavior [OPTIONAL] [hash ref] An associative array that indicates the startup, fallover, and fallback policy that this resource group should adhere to. 5. attributes [OPTIONAL] [hash ref] An associative array that contains post-creation modification parameters for the resource group, similar to what would be provided to "modify resource_group". 6. site_policy [OPTIONAL] [string] An indicator of the site policy to be applied to this resource group. 7. mirror_group [OPTIONAL] [string] A replicated resource that is to be managed by this resource group. =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 "devDoc()" #============================================================================== # 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 #==============================================================================