#!/bin/ksh93 # ALTRAN_PROLOG_BEGIN_TAG # This is an automatically generated prolog. # # Copyright (C) Altran ACT S.A.S. 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_modify_mirror_group.sh 1.18 # # 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 # @(#) 030993e 43haes/lib/ksh93/hacmp/KLIB_HACMP_modify_mirror_group.sh, 726, 2147A_aha726, Sep 09 2021 08:37 AM # 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_modify_mirror_group =head1 SYNOPSIS : HyperSwap "user" mirror groups clmgr modify mirror_group \ [ NAME= ] \ [ VOLUME_GROUPS=[,,...] ] \ [ DISKS=[,,...] ] \ [ STORAGE_SYSTEMS=[,,...] ] \ [ HYPERSWAP_ENABLED={no|yes} ] \ [ CONSISTENT={yes|no} ] \ [ UNPLANNED_HS_TIMEOUT=## ] \ [ HYPERSWAP_PRIORITY={medium|high} ] \ [ RECOVERY={auto|manual} ] \ [ RESYNC={auto|manual} ] \ [ ATTRIBUTES=@[,@,...] ] : HyperSwap "system" mirror groups clmgr modify mirror_group \ [ NAME= ] \ [ VOLUME_GROUPS=[,,...] ] \ [ DISKS=[,,...] ] \ [ NODE= ] \ [ STORAGE_SYSTEMS=[,,...] ] \ [ HYPERSWAP_ENABLED={no|yes} ] \ [ CONSISTENT={yes|no} ] \ [ UNPLANNED_HS_TIMEOUT=## ] \ [ HYPERSWAP_PRIORITY={medium|high} ] \ [ ATTRIBUTES=@[,@,...] ] : HyperSwap "repository" mirror groups clmgr modify mirror_group \ [ NAME= ] \ [ SITE= ] \ [ NON_HS_DISK= ] \ [ HS_DISK= ] \ [ STORAGE_SYSTEMS=[,,...] ] \ [ HYPERSWAP_ENABLED={no|yes} ] \ [ CONSISTENT={yes|no} ] \ [ UNPLANNED_HS_TIMEOUT=## ] \ [ HYPERSWAP_PRIORITY={medium|high} ] \ [ RESYNC={auto|manual} ] \ [ ATTRIBUTES=@[,@,...] ] : DS8000 Global Mirror and XIV mirror groups clmgr modify mirror_group \ [ NAME= ] \ [ MODE={sync|async} ] \ [ RECOVERY={auto|manual} ] \ [ STORAGE_SYSTEMS=[,,...] ] \ [ VENDOR_ID= ] \ [ ATTRIBUTES=@[,@,...] ] : SVC mirror groups clmgr modify mirror_group \ [ NAME= ] \ [ STORAGE_SYSTEMS=, ] \ [ MIRROR_PAIRS=[,,...] ] \ [ MODE={sync|async} ] \ [ RECOVERY={auto|manual} ] : Hitachi mirror groups clmgr modify mirror_group \ [ NAME= ] \ [ VENDOR_ID= ] \ [ HORCM_INSTANCE= ] \ [ MODE={sync|async} ] \ [ RECOVERY={auto|manual} ] \ [ HORCM_TIMEOUT=### ] \ [ PAIR_EVENT_TIMEOUT=### ] : EMC mirror groups clmgr modify mirror_group \ [ NAME= ] \ [ 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 modify the specified mirror group to conform to the provided specifications. =head1 ARGUMENTS 1. properties [REQUIRED] [hash ref] An associative array within which data about the created object can be returned to the caller. 2. mirror_group [REQUIRED] [string] The label of the mirror group to be modified. 3. new_name [OPTIONAL] [string] The new mirror group name. The name must be system- wide unique and can range from 1-64 characters. 4. mode [OPTIONAL] [set] The mode of the mirroring: synchronous or asynchronous 5. recovery [OPTIONAL] [set] Indicates the action to be taken in case of a site fallover. Valid values include: auto: No manual intervention required manual: Manual Intervention required 6. storage_systems [OPTIONAL] [string] The storage systems that are associated with the volume groups and raw disks. 7. mirror_pairs [OPTIONAL] [string] One or more mirror pairs to include. 8. device_groups [OPTIONAL] [string] One of more device groups to include. 9. consistent [OPTIONAL] [boolean] Enables/Disables consistency groups. 10. vendor_id [OPTIONAL] [string] Vendor-specific identifier. 11. attributes [OPTIONAL] [string] Vendor-specific, opaque attributes. 12. horcm_instance [OPTIONAL] [string] The HORCM instance. All nodes in the cluster must use same HORCM instance. 13. horcm_timeout [OPTIONAL] [posint] The maximum amount of time, in seconds (defaulting to 300), to wait for a takeover to complete. 14. pair_event_timeout [OPTIONAL] [posint] The maximum amount of time, in seconds (defaulting to 3600), to wait for the pair event waiting command (pairevtwait) to complete. The pairevtwait command is used to check the status of pair creation and and pair resynchronization while waiting for their completion. It waits until the paired volume status becomes identical to a specified status, then completes (i.e. returns; stops waiting/sleeping). 15. volume_groups [OPTIONAL] [string] The volume group(s) used for the replication setup. 16. disks [OPTIONAL] [string] The raw disk(s) used for the replication setup. 17. hs_enabled [OPTIONAL] [boolean] Enables/Disables Hyperswap. 18. hs_priority [OPTIONAL] [set] The priority for the Hyperswap operation. Valid values: medium, high 19. unpl_hs_timeout [OPTIONAL] [posint] The number of seconds for the unplanned hyperswap operation. The default is 60 seconds. 20. node [OPTIONAL] [string] The node used for the replication setup. 21. site [OPTIONAL] [string] The site for the cluster repository mirror group. There will be more than one site name if the cluster is a stretched cluster. For a linked cluster you will need to add cluster repository mirror group details for each site separately. 22. non_hs_disk [OPTIONAL] [string] The non-HyperSwap disk for the cluster repository mirror group. Please note that this disk will be available for use by the mirror group when HyperSwap is *not* enabled. 23. hs_disk [OPTIONAL] [string] The HyperSwap disk for the cluster repository mirror group. Please note that this disk will be available for use by the mirror group when HyperSwap *is* enabled. 24. mg_type [OPTIONAL] [set] The type of EMC mirror group to set: composite or device. 25. 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_modify_mirror_group # # Description: This is the main, FPATH function that is invoked by clmgr # to modify mirror groups in 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_modify_mirror_group { . $HALIBROOT/log_entry "$0()" "$CL" : version=@(#) 030993e 43haes/lib/ksh93/hacmp/KLIB_HACMP_modify_mirror_group.sh, 726, 2147A_aha726, Sep 09 2021 08:37 AM : INPUTS: $* typeset -n properties=$1 typeset mirror_group=${2//\"/} typeset new_name=${3//\"/} typeset mode=${4//\"/} typeset recovery=${5//\"/} typeset storage_systems=${6//\"/} typeset mirror_pairs=${7//\"/} typeset device_groups=${8//\"/} typeset consistent=${9//\"/} typeset vendor_id=${10//\"/} typeset attributes=${11//\"/} typeset horcm_instance=${12//\"/} typeset horcm_timeout=${13//\"/} typeset pair_event_timeout=${14//\"/} typeset volume_groups=${15//\"/} typeset disks=${16//\"/} typeset -l hs_enabled=${17//\"/} typeset -l hs_priority=${18//\"/} typeset unpl_hs_timeout=${19//\"/} typeset node=${20//\"/} typeset site=${21//\"/} typeset non_hs_disk=${22//\"/} typeset hs_disk=${23//\"/} typeset mg_type=${24//\"/} typeset -l resync=${25//\"/} [[ $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 -A mgAttrs typeset type="" value="" typeset -l lc_val="" #================= : Validate input #================= if [[ -z $mirror_group ]]; 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_get_mirror_group_attributes "$mirror_group" mgAttrs if (( $? != RC_SUCCESS )); then log_return_msg "$rc" "$0()" "$LINENO" return $? else type=${mgAttrs[TYPE]} if [[ -n $mg_type ]]; then if [[ $type == "emc" ]]; then case $mg_type in @(c|C)*) mg_type="CompGroup" ;; @(d|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 elif [[ $type != "ds8k_inband_mm" ]]; then /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 fi else # HyperSwap if [[ -z $LANG || $LANG=@(C|en|En|EN)* ]]; then : 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") : Perform a case-insensitive comparison lc_val=${mgAttrs[MG_TYPE]} if [[ $UTYPE == $lc_val ]]; then mg_type="user" elif [[ $STYPE == $lc_val ]]; then mg_type="system" elif [[ $RTYPE == $lc_val ]]; then mg_type="repository" fi else mg_type=${mgAttrs[MG_TYPE]} fi fi fi fi if [[ $mode != *([[:space:]]) ]]; then #============================================= : Validating the specified MODE value: $mode #============================================= if [[ $type == @(emc|hitachi|xiv_rm|svc) ]]; then case $mode in @(a|A)*) mode="async" [[ $type == @(emc|hitachi) ]] && mode="ASYNC" ;; @(s|S)*) mode="sync" [[ $type == @(emc|hitachi) ]] && 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_i* ]]; then if [[ -n $mode && $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 fi if [[ $consistent != *([[:space:]]) ]]; then #========================================================= : Validating the specified CONSISTENT value: $consistent #========================================================= 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 fi if [[ $storage_systems != *([[:space:]]) ]]; then #=================================================================== : Validating the specified STORAGE_SYSTEMS value: $storage_systems #=================================================================== if [[ $type == @(svc|xiv_rm|ds8k_gm|ds8k_inband_mm) ]]; then 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 else /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 [[ $mirror_pairs != *([[:space:]]) ]]; then #============================================================= : Validating the specified MIRROR_PAIRS value: $mirror_pairs #============================================================= if [[ $type == "svc" ]]; 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 elif [[ -n $type ]]; 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 if [[ $hs_enabled != *([[:space:]]) ]]; then #========================================================= : Validating the specified HS_ENABLED value: $hs_enabled #========================================================= if [[ $type == "ds8k_inband_mm" ]]; 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 else /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 45 '\nERROR: "%1$s" may only be used with "%2$s".\n\n' HS_ENABLED "TYPE=ds8k_inband_mm" 1>&2 rc=$RC_INCORRECT_INPUT fi fi if [[ $hs_priority != *([[:space:]]) ]]; then #=========================================================== : Validating the specified HS_PRIORITY value: $hs_priority #=========================================================== if [[ $type == "ds8k_inband_mm" ]]; 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 else /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 45 '\nERROR: "%1$s" may only be used with "%2$s".\n\n' HS_PRIORITY "TYPE=ds8k_inband_mm" 1>&2 rc=$RC_INCORRECT_INPUT fi fi if [[ $hs_unpl_timeout != *([[:space:]]) ]]; then #======================================================================== : Validating the specified UNPLANNED_HS_TIMEOUT value: $hs_unpl_timeout #======================================================================== if [[ $type == "ds8k_inband_mm" ]]; then CL=$LINENO verify_is_numeric "$hs_unpl_timeout" 2 UNPLANNED_HS_TIMEOUT (( $? != RC_SUCCESS )) && rc=$RC_INCORRECT_INPUT else /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 45 '\nERROR: "%1$s" may only be used with "%2$s".\n\n' UNPLANNED_HS_TIMEOUT "TYPE=ds8k_inband_mm" 1>&2 rc=$RC_INCORRECT_INPUT fi fi if [[ $volume_groups != *([[:space:]]) ]]; then #=============================================================== : Validating the specified VOLUME_GROUPS value: $volume_groups #=============================================================== if [[ $type == "ds8k_inband_mm" ]]; then if [[ $mg_type == "repository" ]]; 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 else 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 else /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 45 '\nERROR: "%1$s" may only be used with "%2$s".\n\n' VOLUME_GROUPS "TYPE=ds8k_inband_mm" 1>&2 rc=$RC_INCORRECT_INPUT fi fi if [[ $disks != *([[:space:]]) ]]; then #=================================================== : Validating the specified RAW_DISKS value: $disks #=================================================== if [[ $type == "ds8k_inband_mm" ]]; then if [[ $mg_type == "repository" ]]; 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 else typeset new_disks="" if [[ -n $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 ${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 $pv:${diskMap[$pv]}" break elif [[ ${diskMap[$pv]} == $disk ]]; then new_disks="$new_disks $pv:${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 disks=${new_disks# } fi fi fi else /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 45 '\nERROR: "%1$s" may only be used with "%2$s".\n\n' RAW_DISKS "TYPE=ds8k_inband_mm" 1>&2 rc=$RC_INCORRECT_INPUT fi fi if [[ $node != *([[:space:]]) ]]; then #============================================= : Validating the specified NODE value: $node #============================================= if [[ $type == "ds8k_inband_mm" ]]; then if [[ $mg_type != "system" ]]; 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 else 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 fi else /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 45 '\nERROR: "%1$s" may only be used with "%2$s".\n\n' NODE "TYPE=ds8k_inband_mm" 1>&2 rc=$RC_INCORRECT_INPUT fi fi if [[ $site != *([[:space:]]) ]]; then #============================================= : Validating the specified SITE value: $site #============================================= if [[ $type == "ds8k_inband_mm" ]]; then if [[ $mg_type != "repository" ]]; 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 else 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 fi else /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 45 '\nERROR: "%1$s" may only be used with "%2$s".\n\n' SITE "TYPE=ds8k_inband_mm" 1>&2 rc=$RC_INCORRECT_INPUT fi fi if [[ $non_hs_disk != *([[:space:]]) ]]; then #=========================================================== : Validating the specified NON_HS_DISK value: $non_hs_disk #=========================================================== if [[ $type == "ds8k_inband_mm" ]]; then if [[ $mg_type != "repository" ]]; 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 else 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 fi else /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 45 '\nERROR: "%1$s" may only be used with "%2$s".\n\n' NON_HS_DISK "TYPE=ds8k_inband_mm" 1>&2 rc=$RC_INCORRECT_INPUT fi fi if [[ $hs_disk != *([[:space:]]) ]]; then #=================================================== : Validating the specified HS_DISK value: $hs_disk #=================================================== if [[ $type == "ds8k_inband_mm" ]]; then if [[ $mg_type != "repository" ]]; 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 else 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 1>&2 print -u2 "" fi fi else /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 45 '\nERROR: "%1$s" may only be used with "%2$s".\n\n' HS_DISK "TYPE=ds8k_inband_mm" 1>&2 rc=$RC_INCORRECT_INPUT fi 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 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 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 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 #===================================================== : Validating the specified RECOVERY value: $recovery #===================================================== if [[ $type == "ds8k_inband_mm" && $mg_type == "user" ]] || \ [[ $type == @(ds8k_gm|emc|hitachi|svc|xiv_rm) ]] then case $recovery in @(a|A)*) recovery="auto" [[ $type == @(emc|hitachi) ]] && recovery="AUTO" ;; @(m|M)*) recovery="manual" [[ $type == @(emc|hitachi) ]] && 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 elif [[ $type == "ds8k_inband_mm" ]]; 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 /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 45 '\nERROR: "%1$s" may only be used with "%2$s".\n\n' RECOVERY "TYPE={ds8k_inband_mm|ds8k_gm|emc|svc|xiv_rm}" 1>&2 rc=$RC_INCORRECT_INPUT 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" 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 thus far, load up any values from : the specified mirror group that have not been overridden. This is : required by the underlying XD utility. #==================================================================== if (( $rc == RC_UNKNOWN )); then typeset value="" internal="" typeset -u external="" for PAIR in consistent horcm_instance horcm_timeout \ storage_systems hs_enabled:HYPERSWAP_ENABLED \ hs_priority:HYPERSWAP_PRIORITY \ unpl_hs_timeout:UNPLANNED_HS_TIMEOUT \ hs_disk:REPOSITORY_MG_HS_DISK \ non_hs_disk:REPOSITORY_MG_NONHS_DISK resync \ mode pair_event_timeout recovery site:REPOSITORY_MG_SITES \ node:SYS_MG_NODE vendor_id volume_groups disks:RAW_DISKS do internal=${PAIR%%:*} external=${PAIR##*:} [[ -z $external ]] && external=$internal eval "value=\$$internal" if [[ -z $value && -n ${mgAttrs[$external]} ]]; then eval "$internal=\"${mgAttrs[$external]}\"" fi done fi #================================================================ : Modify the mirror group if no input errors have been detected #================================================================ if (( $rc == RC_UNKNOWN )); then typeset SOpts="" vOpt="" oOpts="" pOpts="" gOpt="" typeset IOpt="" HOpt="" POpt="" NOpt="" mOpt="" rOpt="" aOpts="" typeset lOpts="" xOpt="" tOpt="" pOpt="" eOpt="" iOpt="" typeset wOpt="" dOpt="" YOpt="" yOpt="" ROpt="" [[ -n $new_name ]] && NOpt=" -N $new_name" 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 $mode ]] && mOpt=" -m $mode" [[ -n $recovery ]] && rOpt=" -r $recovery" [[ -n $resync ]] && ROpt=" -R $resync" [[ -n $horcm_instance ]] && IOpt=" -I $horcm_instance" [[ -n $horcm_timeout ]] && HOpt=" -H $horcm_timeout" [[ -n $pair_event_timeout ]] && POpt=" -P $pair_event_timeout" [[ -n $hs_enabled ]] && xOpt=" -x $hs_enabled" [[ -n $unpl_hs_timeout ]] && tOpt=" -t $unpl_hs_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" [[ -n $mg_type ]] && yOpt=" -y $mg_type" 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 $disks ]]; then for value in ${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_change_mg_director -n $mirror_group -s $type$yOpt$NOpt$mOpt$rOpt$ROpt$SOpts$vOpt$pOpts$gOpt$IOpt$HOpt$POpt$oOpts$lOpts$aOpts$iOpt$eOpt$wOpt$dOpt$xOpt$tOpt$YOpt" >>$CLMGR_TMPLOG # Always log commands $HAXDWIZ/clxd_change_mg_director -n $mirror_group -s $type$yOpt$NOpt$mOpt$rOpt$ROpt$SOpts$vOpt$pOpts$gOpt$IOpt$HOpt$POpt$oOpts$lOpts$aOpts$iOpt$eOpt$wOpt$dOpt$xOpt$tOpt$YOpt rc=$? print "$0()[$LINENO]($SECONDS): clxd_change_mg_director RC: $rc" >>$CLMGR_TMPLOG # Always log command result if (( $rc != RC_SUCCESS )); then /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 400 '\nERROR: failed to modify "%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_modify_mirror_group()" #================================================ # The following, commented line enforces coding # standards when this file is edited via vim. #================================================ # vim:tabstop=4:shiftwidth=4:expandtab:smarttab #================================================