#!/bin/ksh93 # ALTRAN_PROLOG_BEGIN_TAG # This is an automatically generated prolog. # # Copyright (C) Altran ACT S.A.S. 2017,2019,2021. All rights reserved. # # ALTRAN_PROLOG_END_TAG # # IBM_PROLOG_BEGIN_TAG # This is an automatically generated prolog. # # 61haes_r714 src/43haes/lib/ksh93/hacmp/KLIB_HACMP_add_mirror_group.sh 1.20 # # Licensed Materials - Property of IBM # # COPYRIGHT International Business Machines Corp. 2011 # All Rights Reserved # # US Government Users Restricted Rights - Use, duplication or # disclosure restricted by GSA ADP Schedule Contract with IBM Corp. # # IBM_PROLOG_END_TAG # @(#) 7d4c34b 43haes/lib/ksh93/hacmp/KLIB_HACMP_add_mirror_group.sh, 726, 2147A_aha726, Feb 05 2021 09:50 PM # 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_mirror_group =head1 SYNOPSIS clmgr add mirror_group \ TYPE=ds8k_inband_mm \ MG_TYPE=user \ VOLUME_GROUPS=[,,...] \ DISKS=[,,...] \ [ HYPERSWAP_ENABLED={no|yes} ] \ [ CONSISTENT={yes|no} ] \ [ UNPLANNED_HS_TIMEOUT=## ] \ [ HYPERSWAP_PRIORITY={medium|high} ] \ [ RECOVERY={auto|manual} ] \ [ RESYNC={auto|manual} ] \ [ ATTRIBUTES=@[,@,...] ] clmgr add mirror_group \ TYPE=ds8k_inband_mm \ MG_TYPE=system \ VOLUME_GROUPS=[,,...] \ DISKS=[,,...] \ NODE= \ HYPERSWAP_ENABLED={no|yes} \ [ CONSISTENT={yes|no} ] \ [ UNPLANNED_HS_TIMEOUT=## ] \ [ HYPERSWAP_PRIORITY={medium|high} ] \ [ ATTRIBUTES=@[,@,...] ] clmgr add mirror_group \ TYPE=ds8k_inband_mm \ MG_TYPE=repository \ SITE= \ NON_HS_DISK= \ HS_DISK= \ [ HYPERSWAP_ENABLED={no|yes} ] \ [ CONSISTENT={yes|no} ] \ [ UNPLANNED_HS_TIMEOUT=## ] \ [ HYPERSWAP_PRIORITY={medium|high} ] \ [ RESYNC={auto|manual} ] \ [ ATTRIBUTES=@[,@,...] ] clmgr add mirror_group \ TYPE=ds8k_gm \ RECOVERY={auto|manual} \ STORAGE_SYSTEMS=[,,...] \ VENDOR_ID= \ [ ATTRIBUTES=@[,@,...] ] clmgr add mirror_group \ TYPE=xiv_rm \ MODE={sync|async} \ RECOVERY={auto|manual} \ STORAGE_SYSTEMS=[,,...] \ VENDOR_ID= \ [ ATTRIBUTES=@[,@,...] ] clmgr add mirror_group \ TYPE=svc \ STORAGE_SYSTEMS=, \ [ MIRROR_PAIRS=[,,...] ] \ [ MODE={sync|async} ] \ [ RECOVERY={auto|manual} ] clmgr add mirror_group \ TYPE=hitachi \ VENDOR_ID= \ HORCM_INSTANCE= \ [ MODE={sync|async} ] \ [ RECOVERY={auto|manual} ] \ [ HORCM_TIMEOUT=### ] \ [ PAIR_EVENT_TIMEOUT=### ] clmgr add mirror_group \ TYPE=emc \ [ MG_TYPE={composite|device} ] \ [ MODE={sync|async} ] \ [ RECOVERY={auto|manual} ] \ [ CONSISTENT={yes|no} ] \ [ VENDOR_ID= ] NOTE: the alias for "mirror_group" is "mig". =head1 DESCRIPTION Attempts to create a new mirror group. =head1 ARGUMENTS 1. properties [REQUIRED] [hash ref] An associative array within which data about the created object can be returned to the caller. 2. mirror_group [REQUIRED] [string] The label that is to be applied to this mirror group. 3. type [REQUIRED] [set] The type of storage technology that this storage agent will be working with, from the set ds8k_gm, ds8k_inband_mm, emc, hitachi, svc, xiv_rm. 4. mode [REQUIRED] [set] The mode of the mirroring: synchronous or asynchronous 5. recovery [REQUIRED] [set] The recovery policy indicating the action to be taken in case of a site fallover. Valid values include: automatic: No manual intervention required manual: Manual Intervention required 6. storage_systems [OPTIONAL] [string] Storage systems. 7. mirror_pairs [OPTIONAL] [string] One or more mirror pairs to include. 8. consistent [OPTIONAL] [boolean] 9. vendor_id [OPTIONAL] [string] Vendor-specific identifier. 10. horcm_instance [OPTIONAL] [string] 11. horcm_timeout [OPTIONAL] [posint] 12. pair_event_timeout [OPTIONAL] [posint] 13. volume_groups [OPTIONAL] [string] Hyperswap-only. Required if raw disks are not specified. 14. raw_disks [OPTIONAL] [string] Hyperswap-only. Required if volume are not specified. 15. hs_enabled [OPTIONAL] [boolean] 16. hs_priority [OPTIONAL] [set] Valid values: medium, high 17. hs_unpl_timeout [OPTIONAL] [posint] 18. mg_type [REQUIRED] [set] The type of HyperSwap or EMC mirror group to create. HyperSwap valid values: user, system, repository EMC valid values: composite, device 19. node [OPTIONAL] [string] A node name. Required with ds8k_inband_mm, and type "system". 20. site [OPTIONAL] [string] A site name. Required with ds8k_inband_mm, and type "repository". 21. non_hs_disk [OPTIONAL] [string] A disk. Required with ds8k_inband_mm, and type "repository". 22. hs_disk [OPTIONAL] [string] A disk. Required with ds8k_inband_mm, and type "repository". 23. attributes [OPTIONAL] [string] Vendor-specific, opaque attributes. 24. resync [REQUIRED] [set] In case replication volume or path recovers, the HyperSwap function makes sure to perform a re-sync automatically for 'auto'. For 'manual', a user recommended action would be displayed in the errpt log for HyperSwap-enabled mirror groups, and in hacmp.out for HyperSwap-disabled mirror groups. A split and merge policy is recommended to be configured for using 'auto'. Valid values include: automatic manual =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: KLIB_HACMP_add_mirror_group # # Description: This is the main, FPATH function that is invoked by clmgr # to add a mirror group to the cluster configuration. # # Inputs: See 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_mirror_group { . $HALIBROOT/log_entry "$0()" "$CL" : version=@(#) 7d4c34b 43haes/lib/ksh93/hacmp/KLIB_HACMP_add_mirror_group.sh, 726, 2147A_aha726, Feb 05 2021 09:50 PM : INPUTS: $* typeset -n properties=$1 typeset mirror_group=${2//\"/} typeset -l type=${3//\"/} typeset mode=${4//\"/} typeset recovery=${5//\"/} typeset storage_systems=${6//\"/} typeset mirror_pairs=${7//\"/} typeset consistent=${8//\"/} typeset vendor_id=${9//\"/} typeset horcm_instance=${10//\"/} typeset horcm_timeout=${11//\"/} typeset pair_event_timeout=${12//\"/} typeset volume_groups=${13//\"/} typeset raw_disks=${14//\"/} typeset -l hs_enabled=${15//\"/} typeset hs_priority=${16//\"/} typeset hs_unpl_timeout=${17//\"/} typeset -l mg_type=${18//\"/} typeset node=${19//\"/} typeset site=${20//\"/} typeset non_hs_disk=${21//\"/} typeset hs_disk=${22//\"/} typeset attributes=${23//\"/} typeset -l resync=${24//\"/} [[ $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 CL=$LINENO isEnterprise if (( $? != 1 )); then CL=$LINENO cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 184 "\nERROR: this operation requires IBM PowerHA SystemMirror for AIX Enterprise Edition.\n\n" 1>&2 log_return_msg "$RC_MISSING_DEPENDENCY" "$0()" "$LINENO" return $? fi #=================================== : Declare and initialize variables #=================================== typeset -i rc=$RC_UNKNOWN typeset pair="" attr="" value="" #================= : Validate input #================= if [[ $mirror_group == *([[:space:]]) ]]; then /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 100 "\nERROR: a name/label must be provided.\n\n" 1>&2 rc=$RC_MISSING_INPUT else CL=$LINENO KLIB_HACMP_is_known_mirror_group $mirror_group if (( $? == RC_SUCCESS )); then /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 229 "\nERROR: the specified object already exists: \"%1\$s\"\n\n" "$mirror_group" 1>&2 rc=$RC_INCORRECT_INPUT fi fi #============================ : Check the required values #============================ for pair in TYPE:$type do print -- "$pair" | IFS=: read attr value if [[ $value == *([[:space:]]) ]]; then /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 101 "\nERROR: this operation requires the \"%1\$s\" attribute.\n\n" "$attr" 1>&2 rc=$RC_MISSING_INPUT fi done if [[ $type != *([[:space:]]) ]]; then case $type in *8*g*) type=ds8k_gm ;; *8*i*) type=ds8k_inband_mm ;; e*) type=emc ;; h*) type=hitachi ;; s*) type=svc ;; x*) type=xiv_rm ;; *) /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 110 "\nERROR: invalid value specified for \"%1\$s\": \"%2\$s\".\n" TYPE "$type" 1>&2 /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 3 "Valid values: %1\$s\n\n" "ds8k_gm, ds8k_inband_mm, emc, hitachi, svc, xiv_rm" 1>&2 rc=$RC_INCORRECT_INPUT ;; esac fi #====================================== : Validate the specified mode, if any #====================================== if [[ $mode != *([[:space:]]) ]]; then if [[ $type == @(xiv_rm|hitachi|emc|svc) ]]; then case $mode in @(a|A)*) [[ $type == "emc" ]] && mode="ASYNC" || mode="async" ;; @(s|S)*) [[ $type == "emc" ]] && mode="SYNC" || mode="sync" ;; *) /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 110 "\nERROR: invalid value specified for \"%1\$s\": \"%2\$s\".\n" MODE "$mode" 1>&2 /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 3 "Valid values: %1\$s\n\n" "sync, async" 1>&2 rc=$RC_INCORRECT_INPUT ;; esac elif [[ $type == "ds8k_inband_mm" ]]; then if [[ $mode != s* ]]; then CL=$LINENO cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 282 '\nERROR: invalid value specified for "%1$s" ("%2$s") with "%3$s".\n\n' MODE "$mode" "$type" 1>&2 /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 3 "Valid values: %1\$s\n\n" "sync" 1>&2 rc=$RC_INCORRECT_INPUT fi elif [[ -n $type ]]; then /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 283 '\nERROR: "%1$s" does not apply to "%2$s".\n\n' "MODE" "$type" 1>&2 rc=$RC_INCORRECT_INPUT fi elif [[ $type == @(xiv_rm|hitachi) ]]; then mode="sync" # Set a default value for these storage technologies fi if [[ $consistent != *([[:space:]]) ]]; then if [[ $type == @(ds8k_inband_mm|emc) ]]; then if [[ $consistent == @(y|Y|t|T)* ]]; then [[ $type == "emc" ]] && consistent="YES" || consistent="yes" elif [[ $consistent == @(n|N|f|F)* ]]; then [[ $type == "emc" ]] && consistent="NO" || consistent="no" else /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 110 "\nERROR: invalid value specified for \"%1\$s\": \"%2\$s\".\n" CONSISTENT "$consistent" 1>&2 /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 3 "Valid values: %1\$s\n\n" "yes, no" 1>&2 rc=$RC_INCORRECT_INPUT fi elif [[ -n $type ]]; then /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 283 '\nERROR: "%1$s" does not apply to "%2$s".\n\n' "CONSISTENT" "$type" 1>&2 rc=$RC_INCORRECT_INPUT fi elif [[ $type == @(ds8k_inband_mm|emc) ]]; then # Set a default value [[ $type == "emc" ]] && consistent="YES" || consistent="yes" fi #================================== : XIV or Global Mirror validation #================================== if [[ $type == @(xiv_rm|ds8k_gm|svc) ]]; then if [[ -z $storage_systems ]]; then /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 101 "\nERROR: this operation requires the \"%1\$s\" attribute.\n\n" STORAGE_SYSTEMS 1>&2 rc=$RC_MISSING_INPUT else for value in ${storage_systems//,/ }; do [[ $value == *([[:space:]]) ]] && continue CL=$LINENO KLIB_HACMP_is_known_storage_system "$value" if (( $? != RC_SUCCESS )); then /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 102 "\nERROR: \"%1\$s\" does not appear to exist!\n\n" "$value" 1>&2 /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 164 "Available Storage Systems:\n\n" 1>&2 typeset available CL=$LINENO KLIB_HACMP_list_storage_systems available for (( i=0; i<${#available[*]}; i++ )); do if [[ ${available[$i]} != *([[:space:]]) ]]; then print -u2 "\t${available[$i]}" fi done print -u2 "" rc=$RC_INCORRECT_INPUT fi done fi elif [[ -n $type ]]; then if [[ -n $storage_systems ]]; then /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 45 '\nERROR: "%1$s" may only be used with "%2$s".\n\n' STORAGE_SYSTEMS "TYPE={xiv_rm|ds8k_gm}" 1>&2 rc=$RC_INCORRECT_INPUT fi fi if [[ $type == @(xiv_rm|ds8k_gm) ]]; then if [[ -z $vendor_id ]]; then /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 101 "\nERROR: this operation requires the \"%1\$s\" attribute.\n\n" VENDOR_ID 1>&2 rc=$RC_MISSING_INPUT fi fi #========================== : SVC-specific validation #========================== if [[ $type == "svc" ]]; then if [[ $mirror_pairs != *([[:space:]]) ]]; then typeset -i BAD_MIP=0 for value in ${mirror_pairs//,/ }; do [[ $value == *([[:space:]]) ]] && continue CL=$LINENO KLIB_HACMP_is_known_mirror_pair "$value" if (( $? != RC_SUCCESS )); then /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 102 "\nERROR: \"%1\$s\" does not appear to exist!\n\n" "$value" 1>&2 BAD_MIP=1 fi done if (( BAD_MIP )); then /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 166 "Available Mirror Pairs:\n\n" 1>&2 typeset available CL=$LINENO KLIB_HACMP_list_mirror_pairs available for (( i=0; i<${#available[*]}; i++ )); do if [[ ${available[$i]} != *([[:space:]]) ]]; then print -u2 "\t${available[$i]}" fi done print -u2 "" rc=$RC_INCORRECT_INPUT fi fi elif [[ -n $type ]]; then if [[ -n $mirror_pairs ]]; then /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 45 '\nERROR: "%1$s" may only be used with "%2$s".\n\n' MIRROR_PAIRS TYPE=svc 1>&2 rc=$RC_INCORRECT_INPUT fi fi #========================== : Check the MG_TYPE input #========================== if [[ -n $mg_type ]]; then if [[ $type == "ds8k_inband_mm" ]]; then if [[ -z $LANG || $LANG=@(C|en|En|EN)* ]]; then case $mg_type in u*) mg_type="user" ;; s*) mg_type="system" ;; r*) mg_type="repository" ;; *) /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 110 "\nERROR: invalid value specified for \"%1\$s\": \"%2\$s\".\n" MG_TYPE "$mg_type" 1>&2 /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 3 "Valid values: %1\$s\n\n" "user, system, repository" 1>&2 rc=$RC_INCORRECT_INPUT ;; esac else # Convert other languages to English, for internal processing typeset -l UTYPE=$(dspmsg -s 4 genxd.cat 56 "User") typeset -l STYPE=$(dspmsg -s 4 genxd.cat 57 "System") typeset -l RTYPE=$(dspmsg -s 4 genxd.cat 58 "Repositories") if [[ $UTYPE == $mg_type* ]]; then mg_type="user" elif [[ $STYPE == $mg_type* ]]; then mg_type="system" elif [[ $RTYPE == $mg_type* ]]; then mg_type="repository" else dspmsg -s $CLMGR_SET $CLMGR_MSGS 110 "\nERROR: invalid value specified for \"%1\$s\": \"%2\$s\".\n" MG_TYPE "$mg_type" 1>&2 dspmsg -s $CLMGR_SET $CLMGR_MSGS 3 "Valid values: %1\$s\n\n" \ "$(dspmsg -s 4 genxd.cat 56 'User'),\ $(dspmsg -s 4 genxd.cat 57 'System'),\ $(dspmsg -s 4 genxd.cat 58 'Repositories')" 1>&2 rc=$RC_INCORRECT_INPUT fi fi elif [[ $type == "emc" ]]; then case $mg_type in c*) mg_type="CompGroup" ;; d*) mg_type="DevGroup" ;; *) /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 110 "\nERROR: invalid value specified for \"%1\$s\": \"%2\$s\".\n" MG_TYPE "$mg_type" 1>&2 /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 3 "Valid values: %1\$s\n\n" "composite, device" 1>&2 rc=$RC_INCORRECT_INPUT ;; esac else /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 45 '\nERROR: "%1$s" may only be used with "%2$s".\n\n' MG_TYPE "TYPE={ds8k_inband_mm|emc}" 1>&2 rc=$RC_INCORRECT_INPUT fi elif [[ $type == @(ds8k_inband_mm|emc) ]]; then /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 101 "\nERROR: this operation requires the \"%1\$s\" attribute.\n\n" "MG_TYPE" 1>&2 rc=$RC_MISSING_INPUT fi #========================================== : Check the HyperSwap-specific attributes #========================================== if [[ $type == "ds8k_inband_mm" ]]; then if [[ $hs_enabled != *([[:space:]]) ]]; then if [[ $hs_enabled == @(e|y|t)* ]]; then hs_enabled="enabled" elif [[ $hs_enabled == @(d|n|f)* ]]; then hs_enabled="disabled" else /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 110 "\nERROR: invalid value specified for \"%1\$s\": \"%2\$s\".\n" HYPERSWAP_ENABLED "$hs_enabled" 1>&2 /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 3 "Valid values: %1\$s\n\n" "no, yes" 1>&2 rc=$RC_INCORRECT_INPUT fi fi if [[ $hs_priority != *([[:space:]]) ]]; then case $hs_priority in @(m|M)*) hs_priority="Medium" ;; @(h|H)*) hs_priority="High" ;; *) /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 110 "\nERROR: invalid value specified for \"%1\$s\": \"%2\$s\".\n" HYPERSWAP_PRIORITY "$hs_priority" 1>&2 /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 3 "Valid values: %1\$s\n\n" "medium, high" 1>&2 rc=$RC_INCORRECT_INPUT ;; esac fi if [[ $hs_unpl_timeout != *([[:space:]]) ]]; then CL=$LINENO verify_is_numeric "$hs_unpl_timeout" 2 UNPLANNED_HS_TIMEOUT (( $? != RC_SUCCESS )) && rc=$RC_INCORRECT_INPUT fi if [[ $mg_type == @(user|system) ]]; then if [[ -z $volume_groups && -z $raw_disks ]]; then CL=$LINENO cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 284 '\nERROR: "%1$s" requires one of the following options:\n\n' "MG_TYPE=$mg_type" 1>&2 print -u2 "\t\tVOLUME_GROUPS, RAW_DISKS\n" rc=$RC_INCORRECT_INPUT fi elif [[ -n $volume_groups ]]; then /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 45 '\nERROR: "%1$s" may only be used with "%2$s".\n\n' VOLUME_GROUPS "MG_TYPE={user|system}" 1>&2 rc=$RC_INCORRECT_INPUT elif [[ -n $raw_disks ]]; then /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 45 '\nERROR: "%1$s" may only be used with "%2$s".\n\n' RAW_DISKS "MG_TYPE={user|system}" 1>&2 rc=$RC_INCORRECT_INPUT fi if [[ $mg_type == @(user|system) ]]; then if [[ -n $volume_groups ]]; then typeset vg="" typeset -i all_vgs_found=1 for vg in ${volume_groups//,/ }; do if [[ $vg == "rootvg" ]]; then if [[ $mg_type != "system" ]]; then dspmsg -s $CLMGR_SET $CLMGR_MSGS 45 '\nERROR: "%1$s" may only be used with "%2$s".\n\n' "$vg" "MG_TYPE=system" 1>&2 rc=$RC_INCORRECT_INPUT all_vgs_found=0 fi continue # Special case; avoid validation fi CL=$LINENO KLIB_HACMP_is_known_volume_group "$vg" >/dev/null 2>&1 if (( $? != RC_SUCCESS )); then /usr/bin/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 fi done if (( ! all_vgs_found )); then /usr/bin/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 "" fi fi fi if [[ $mg_type == @(user|system) ]]; then typeset new_disks="" if [[ -n $raw_disks ]]; then typeset -i all_disks_found=1 typeset disk="" dname="" duuid="" rem="" typeset -A diskMap LC_ALL=C LANG=C $HAXDCLI/clxd_list_rdisk |\ while read dname duuid rem; do [[ $dname == "Device" ]] && continue [[ $dname == *([[:space:]]) ]] && continue diskMap[$dname]=$duuid done for disk in ${raw_disks//,/ }; do if [[ " ${!diskMap[*]} " != *\ $disk\ * && \ " ${diskMap[*]} " != *\ $disk\ * ]] then /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 285 '\nERROR: "%1$s" either does not exist, or is not a raw disk.\n\n' "$disk" 1>&2 rc=$RC_INCORRECT_INPUT all_disks_found=0 else typeset pv="" for pv in ${!diskMap[*]}; do if [[ $pv == $disk ]]; then new_disks="$new_disks ${diskMap[$pv]}" break elif [[ ${diskMap[$pv]} == $disk ]]; then new_disks="$new_disks ${diskMap[$pv]}" break fi done fi done if (( ! all_disks_found )); then /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 153 "Available Physical Volumes:\n\n" 1>&2 $HAXDCLI/clxd_list_rdisk 1>&2 print -u2 "" else raw_disks=${new_disks# } fi fi fi if [[ $mg_type == "system" ]]; then if [[ -n $node ]]; then CL=$LINENO KLIB_HACMP_is_known_node $node >/dev/null if (( $? != RC_SUCCESS )); then rc=$RC_NOT_FOUND /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 102 "\nERROR: \"%1\$s\" does not appear to exist!\n\n" "$node" 1>&2 /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 151 "Available Nodes:\n\n" 1>&2 typeset available CL=$LINENO KLIB_HACMP_list_nodes available for (( i=0; i<${#available[*]}; i++ )); do if [[ ${available[$i]} != *([[:space:]]) ]]; then print -u2 "\t${available[$i]}" fi done print -u2 "" fi else CL=$LINENO cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 37 '\nERROR: option "%1$s" is required when any of the following option(s)\n are used: %2$s\n\n' NODE "MG_TYPE=system" 1>&2 rc=$RC_INCORRECT_INPUT fi elif [[ -n $node ]]; then /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 45 '\nERROR: "%1$s" may only be used with "%2$s".\n\n' NODE "MG_TYPE=system" 1>&2 rc=$RC_INCORRECT_INPUT fi if [[ $mg_type == "repository" ]]; then if [[ -n $site ]]; then CL=$LINENO KLIB_HACMP_is_known_site $site >/dev/null if (( $? != RC_SUCCESS )); then rc=$RC_NOT_FOUND /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 102 "\nERROR: \"%1\$s\" does not appear to exist!\n\n" "$site" 1>&2 /usr/bin/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 "" fi else CL=$LINENO cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 37 '\nERROR: option "%1$s" is required when any of the following option(s)\n are used: %2$s\n\n' SITE "MG_TYPE=repository" 1>&2 rc=$RC_INCORRECT_INPUT fi elif [[ -n $site ]]; then /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 45 '\nERROR: "%1$s" may only be used with "%2$s".\n\n' SITE "MG_TYPE=repository" 1>&2 rc=$RC_INCORRECT_INPUT fi if [[ $mg_type == "repository" ]]; then if [[ -n $non_hs_disk ]]; then typeset -i found=0 typeset dname="" duuid="" rem="" LC_ALL=C LANG=C $HAXDCLI/clxd_list_rdisk |\ while read dname duuid rem; do [[ $dname == "Device" ]] && continue [[ $dname == *([[:space:]]) ]] && continue if [[ $dname == $non_hs_disk || \ $duuid == $non_hs_disk ]] then non_hs_disk="$duuid" # Convert to UUID found=1 fi done if (( ! found )); then /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 285 '\nERROR: "%1$s" either does not exist, or is not a raw disk.\n\n' "$non_hs_disk" 1>&2 rc=$RC_INCORRECT_INPUT /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 153 "Available Physical Volumes:\n\n" 1>&2 $HAXDCLI/clxd_list_rdisk 1>&2 print -u2 "" fi else CL=$LINENO cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 37 '\nERROR: option "%1$s" is required when any of the following option(s)\n are used: %2$s\n\n' NON_HS_DISK "MG_TYPE=repository" 1>&2 rc=$RC_INCORRECT_INPUT fi elif [[ -n $non_hs_disk ]]; then /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 45 '\nERROR: "%1$s" may only be used with "%2$s".\n\n' NON_HS_DISK "MG_TYPE=repository" 1>&2 rc=$RC_INCORRECT_INPUT fi if [[ $mg_type == "repository" ]]; then if [[ -n $hs_disk ]]; then typeset -i found=0 typeset dname="" duuid="" rem="" LC_ALL=C LANG=C $HAXDCLI/clxd_list_rdisk |\ while read dname duuid rem; do [[ $dname == "Device" ]] && continue [[ $dname == *([[:space:]]) ]] && continue if [[ $dname == $hs_disk || \ $duuid == $hs_disk ]] then hs_disk="$duuid" # Convert to UUID found=1 fi done if (( ! found )); then /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 285 '\nERROR: "%1$s" either does not exist, or is not a raw disk.\n\n' "$hs_disk" 1>&2 rc=$RC_INCORRECT_INPUT /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 153 "Available Physical Volumes:\n\n" 1>&2 $HAXDCLI/clxd_list_rdisk print -u2 "" fi else CL=$LINENO cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 37 '\nERROR: option "%1$s" is required when any of the following option(s)\n are used: %2$s\n\n' HS_DISK "MG_TYPE=repository" 1>&2 rc=$RC_INCORRECT_INPUT fi elif [[ -n $hs_disk ]]; then /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 45 '\nERROR: "%1$s" may only be used with "%2$s".\n\n' HS_DISK "MG_TYPE=repository" 1>&2 rc=$RC_INCORRECT_INPUT fi if [[ $mg_type != "repository" ]]; then typeset PAIR="" attr="" value="" for PAIR in "SITE:$site" \ "NON_HS_DISK:$non_hs_disk" \ "HS_DISK:$hs_disk" do attr=${PAIR%%:*} value=${PAIR#*:} if [[ -n $value ]]; then /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 45 '\nERROR: "%1$s" may only be used with "%2$s".\n\n' "$attr" "MG_TYPE=repository" 1>&2 rc=$RC_INCORRECT_INPUT fi done fi elif [[ -n $type ]]; then typeset PAIR="" attr="" value="" for PAIR in "MG_TYPE:$mg_type" \ "HYPERSWAP_ENABLED:$hs_enabled" \ "HYPERSWAP_PRIORITY:$hs_priority" \ "UNPLANNED_HS_TIMEOUT:$hs_unpl_timeout" \ "NODE:$node" \ "SITE:$site" \ "NON_HS_DISK:$non_hs_disk" \ "HS_DISK:$hs_disk" do attr=${PAIR%%:*} value=${PAIR#*:} if [[ -n $value ]]; then if [[ $attr == "MG_TYPE" && $type == "emc" ]]; then continue fi /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 45 '\nERROR: "%1$s" may only be used with "%2$s".\n\n' "$attr" TYPE=ds8k_inband_mm 1>&2 rc=$RC_INCORRECT_INPUT fi done fi #======================================== : Check the Hitachi-specific attributes #======================================== if [[ -n $horcm_instance && $type != "hitachi" ]]; then /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 45 '\nERROR: "%1$s" may only be used with "%2$s".\n\n' HORCM_INSTANCE TYPE=hitachi 1>&2 rc=$RC_INCORRECT_INPUT fi if [[ -n $horcm_timeout ]]; then if [[ $type != "hitachi" ]]; then /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 45 '\nERROR: "%1$s" may only be used with "%2$s".\n\n' HORCM_TIMEOUT TYPE=hitachi 1>&2 rc=$RC_INCORRECT_INPUT else CL=$LINENO verify_is_numeric "$horcm_timeout" 2 HORCM_TIMEOUT (( $? != RC_SUCCESS )) && rc=$RC_INCORRECT_INPUT fi fi if [[ -n $pair_event_timeout ]]; then if [[ $type != "hitachi" ]]; then /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 45 '\nERROR: "%1$s" may only be used with "%2$s".\n\n' PAIR_EVENT_TIMEOUT TYPE=hitachi 1>&2 rc=$RC_INCORRECT_INPUT else CL=$LINENO verify_is_numeric "$pair_event_timeout" 2 PAIR_EVENT_TIMEOUT (( $? != RC_SUCCESS )) && rc=$RC_INCORRECT_INPUT fi fi if [[ $recovery != *([[:space:]]) ]]; then if [[ $type == "ds8k_inband_mm" && \ $mg_type != u* ]] then /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 45 '\nERROR: "%1$s" may only be used with "%2$s".\n\n' RECOVERY "MG_TYPE=user" 1>&2 rc=$RC_INCORRECT_INPUT else case $recovery in @(a|A)*) recovery="auto" [[ $type == "emc" ]] && recovery="AUTO" ;; @(m|M)*) recovery="manual" [[ $type == "emc" ]] && recovery="MANUAL" ;; *) /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 110 "\nERROR: invalid value specified for \"%1\$s\": \"%2\$s\".\n" RECOVERY "$recovery" 1>&2 /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 3 "Valid values: %1\$s\n\n" "auto, manual" 1>&2 rc=$RC_INCORRECT_INPUT ;; esac fi fi if [[ $resync != *([[:space:]]) ]]; then if [[ $type == "ds8k_inband_mm" && \ $mg_type != @(u|r)* ]] then /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 45 '\nERROR: "%1$s" may only be used with "%2$s".\n\n' RECOVERY "MG_TYPE={user|repository}" 1>&2 rc=$RC_INCORRECT_INPUT else if [[ $resync != *([[:space:]]) ]]; then CL=$LINENO verify_in_set RESYNC "$resync" "manual, automatic" resync (( $? != RC_SUCCESS )) && rc=$RC_INCORRECT_INPUT fi fi fi #======================================================================== : If no errors have been detected yet, set any defaults that are needed #======================================================================== if (( $rc == RC_UNKNOWN )); then case $type in ds8k_inband_mm) [[ -z $mode ]] && mode="sync" [[ -z $hs_enabled ]] && hs_enabled="disabled" [[ -z $consistent ]] && consistent="yes" [[ -z $hs_unpl_timeout ]] && hs_unpl_timeout=60 [[ -z $recovery ]] && recovery="manual" [[ -z $resync ]] && resync="manual" if [[ $mg_type == "user" ]]; then [[ -z $hs_priority ]] && hs_priority="Medium" elif [[ $mg_type == @(system|repository) ]]; then [[ -z $hs_priority ]] && hs_priority="High" fi ;; ds8k_gm) [[ -z $recovery ]] && recovery="automatic" [[ -z $mode ]] && mode="sync" [[ -z $consistent ]] && consistent="yes" ;; hitachi) [[ -z $horcm_timeout ]] && horcm_timeout=300 [[ -z $pair_event_timeout ]] && pair_event_timeout=3600 ;; svc) [[ -z $recovery ]] && recovery="AUTO" [[ -z $mode ]] && mode="sync" ;; xiv*) [[ -z $recovery ]] && recovery="automatic" [[ -z $mode ]] && mode="sync" [[ -z $consistent ]] && consistent="yes" ;; esac fi #================================================================ : Create the mirror group if no input errors have been detected #================================================================ if (( $rc == RC_UNKNOWN )); then typeset value="" SOpts="" vOpt="" oOpts="" pOpts="" gOpt="" typeset IOpt="" HOpt="" POpt="" rOpt="" mOpt="" aOpts="" lOpts="" typeset xOpt="" tOpt="" pOpt="" eOpt="" yOpt="" iOpt="" wOpt="" dOpt="" typeset YOpt="" ROpt="" [[ -n $mode ]] && mOpt=" -m $mode" [[ -n $recovery ]] && rOpt=" -r $recovery" [[ -n $resync ]] && ROpt=" -R $resync" if [[ -n $vendor_id ]]; then case $type in hitachi) vOpt=" -D $vendor_id" ;; emc) vOpt=" -D $vendor_id" ;; *) vOpt=" -v $vendor_id" ;; esac fi [[ -n $consistent ]] && gOpt=" -g $consistent" [[ -n $horcm_instance ]] && IOpt=" -I $horcm_instance" [[ -n $horcm_timeout ]] && HOpt=" -H $horcm_timeout" [[ -n $pair_event_timeout ]] && POpt=" -P $pair_event_timeout" [[ -n $mg_type ]] && yOpt=" -y $mg_type" [[ -n $hs_enabled ]] && xOpt=" -x $hs_enabled" [[ -n $hs_unpl_timeout ]] && tOpt=" -t $hs_unpl_timeout" [[ -n $hs_priority ]] && YOpt=" -Y $hs_priority" [[ -n $node ]] && eOpt=" -e $node" [[ -n $site ]] && iOpt=" -i $site" [[ -n $non_hs_disk ]] && wOpt=" -w $non_hs_disk" [[ -n $hs_disk ]] && dOpt=" -d $hs_disk" if [[ -n $attributes ]]; then for value in ${attributes//,/ }; do oOpts="$oOpts -o${value//@/ }" done fi if [[ -n $storage_systems ]]; then for value in ${storage_systems//,/ }; do SOpts="$SOpts -S $value" done fi if [[ -n $mirror_pairs ]]; then for value in ${mirror_pairs//,/ }; do pOpts="$pOpts -p $value" done fi if [[ -n $raw_disks ]]; then for value in ${raw_disks//,/ }; do aOpts="$aOpts -a $value" done fi if [[ -n $volume_groups ]]; then for value in ${volume_groups//,/ }; do lOpts="$lOpts -l $value" done fi print -- "$0()[$LINENO]($SECONDS): $HAXDWIZ/clxd_create_mg_director -s $type -n $mirror_group$yOpt$lOpts$aOpts$mOpt$rOpt$ROpt$SOpts$vOpt$pOpts$IOpt$HOpt$POpt$iOpt$eOpt$wOpt$dOpt$xOpt$gOpt$tOpt$YOpt$oOpts" >>$CLMGR_TMPLOG $HAXDWIZ/clxd_create_mg_director -s $type -n $mirror_group$yOpt$lOpts$aOpts$mOpt$rOpt$ROpt$SOpts$vOpt$pOpts$IOpt$HOpt$POpt$iOpt$eOpt$wOpt$dOpt$xOpt$gOpt$tOpt$YOpt$oOpts rc=$? print "$0()[$LINENO]($SECONDS): clxd_create_mg_director RC: $rc" >>$CLMGR_TMPLOG if (( $rc != RC_SUCCESS )); then /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 201 "\nERROR: failed to create \"%1\$s\".\n\n" "$mirror_group" 1>&2 rc=$RC_ERROR 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_mirror_group_attributes "$mirror_group" 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 mirror_group -h" "MIRROR GROUP:" "$CLMGR_PROGNAME" 1>&2 fi log_return_msg "$rc" "$0()" "$LINENO" return $? } # End of "KLIB_HACMP_add_mirror_group()" #================================================ # The following, commented line enforces coding # standards when this file is edited via vim. #================================================ # vim:tabstop=4:shiftwidth=4:expandtab:smarttab #================================================