#!/bin/ksh93 # ALTRAN_PROLOG_BEGIN_TAG # This is an automatically generated prolog. # # Copyright (C) Altran ACT S.A.S. 2017,2018,2019,2021. All rights reserved. # # ALTRAN_PROLOG_END_TAG # # IBM_PROLOG_BEGIN_TAG # This is an automatically generated prolog. # # 61haes_r721 src/43haes/lib/ksh93/hacmp/KLIB_HACMP_add_volume_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 # @(#) 7b36ae1 43haes/lib/ksh93/hacmp/KLIB_HACMP_add_volume_group.sh, 726, 2147A_aha726, Sep 08 2021 09:17 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_volume_group =head1 SYNOPSIS clmgr add volume_group [ ] \ NODES=",[,...>]" \ PHYSICAL_VOLUMES="[,,...]" \ [ TYPE={original|big|scalable|legacy} ] \ [ RESOURCE_GROUP= ] \ [ PPART_SIZE={4|1|2|8|16|32|64|128|256|512|1024} ] \ [ MAJOR_NUMBER=## ] \ [ ACTIVATE_ON_RESTART={false|true} ] \ [ QUORUM_NEEDED={true|false} ] \ [ LTG_SIZE=### ] \ [ MIGRATE_FAILED_DISKS={false|one|pool|remove} ] \ [ MAX_PHYSICAL_PARTITIONS={32|64|128|256| 512|768|1024} ] \ [ MAX_LOGICAL_VOLUMES={256|512|1024|2048} ] \ [ STRICT_MIRROR_POOLS={no|yes|super} ] \ [ MIRROR_POOL_NAME="" ] \ [ CRITICAL={false|true} ] \ [ FAILUREACTION={halt|notify|fence| stoprg|moverg} ] \ [ NOTIFYMETHOD= ] \ [ LVM_PREFERRED_READ= ] \ [ ENABLE_LV_ENCRYPTION={yes|no} ] NOTE: "MAX_PHYSICAL_PARTITIONS", "MAX_LOGICAL_VOLUMES", "MIRROR_POOL_NAME", and "MP_STRICTNESS", only apply to "scalable" volume groups. NOTE: specifying the volume group major number may result in the command being unable to execute successfully on a node that does not have the major number currently available. Please check for a commonly available major number on all nodes before changing this setting. NOTE: an alias for "volume_group" is "vg". =head1 DESCRIPTION Attempts to add a new volume 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. volume_group [OPTIONAL] [string] The label that is to be applied to this volume group. If not provided, a default label will be used (i.e. "vg01"). 3. nodes [REQUIRED] [string] One or more nodes to create this volume group on. 4. disks [REQUIRED] [string] One or more shared (between the specified nodes) disks that are to be added to this volume group. 5. type [OPTIONAL] [string] The type of volume group to create, defaulting to "Original". TYPE={Original,Big,Scalable,Legacy} 6. rg [OPTIONAL] [string] A resource group to add this volume group to, or to create, if needed. By default "CONCURRENT_ACCESS" is "true" so the resource group is being created by this command will be created as a concurrent resource group (i.e. with a startup policy of OAAN). 7. ppart_size [OPTIONAL] [integer] The size of the physical partitions used within the volume group, defaulting to 4 MB. PPARTITION_SIZE={4,1,2,8,16,32,64,128,256,512,1024} 8. major [OPTIONAL] [integer] The major number to assign to this volume group. 9. activate [OPTIONAL] [boolean] Indicates if the volume group should be activated after the system is restarted. 10. quorum [OPTIONAL] [boolean] Indicates whether or not a quorum of the disks in the volume group are needed to keep the volume group online. 11. ltg_size [OPTIONAL] [integer] Sets the logical track group size, in number of kilobytes. 12. migrate [OPTIONAL] [string] Indicates whether or not to automatically migrate failed disks. Accepted values: false|one|pool|remove 13. max_pparts [OPTIONAL] [integer] For "Scalable" volume group types only, this setting indicates the the maximum number of physical partitions for the volume group, using units of 1024. Defaults to 32 (32 * 1024 = 32768 partitions). 14. max_lvs [OPTIONAL] [integer] For "Scalable" volume group types only, this setting indicates the the maximum number of logical volumes for the volume group. Defaults to 256. 15. mp_name [OPTIONAL] [string] The name of the mirror pool to create. 16. mp_strictness [OPTIONAL] [string] Mirror pool strictness, which can be used to enforce tighter restrictions on mirror pool use. Mirror pool strictness can have one of the following three values: off, on, super. 17. critical [OPTIONAL] [boolean] Indicates if this is a critical volume group. Used to satisfy the quorum requirements of Oracle RAC. Defaults to "false", or "no". 18. failure_action [OPTIONAL] [boolean] Defines the action to take upon loss of access to the volume group. Valid values are: halt, notify, fence, stoprg, moverg 19. notify_method [OPTIONAL] [string] Defines the full path to an executable file that will be run whenever any failure action is triggered. 20. LVM_PREFERRED_READ [OPTIONAL] [string] This attribute controls LVM read operations when there are mirror pools. This option decides which copy should be used for reading the data. Supported options are roundrobin, favorcopy or siteaffinity. favorcopy - Choose if you would like to read from Flash storage. siteaffinity - Choose if you would like to read from local storage path always based on the resource group location. siteaffinity option is available only for site based clusters. 21. ENABLE_LV_ENCRYPTION [OPTIONAL] [boolean] Enables the data encryption option in the volume group. Default value is "yes". =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_volume_group # # Description: This is the main, FPATH function that is invoked by clmgr # to add a volume group to the specified cluster nodes. # # 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_volume_group { . $HALIBROOT/log_entry "$0()" "$CL" : version=@(#) 7b36ae1 43haes/lib/ksh93/hacmp/KLIB_HACMP_add_volume_group.sh, 726, 2147A_aha726, Sep 08 2021 09:17 PM : INPUTS: $* typeset -n properties=$1 typeset volume_group=${2//\"/} shift; shift typeset nodes=${1//\"/} nodes=${nodes//+([[:space:]])/,} typeset disks=${2//\"/} disks=${disks//,/ } typeset type=${3//\"/} typeset rg=${4//\"/} typeset ppart_size=${5//\"/} typeset major=${6//\"/} typeset -l activate=${7//\"/} typeset -l quorum=${8//\"/} typeset ltg_size=${9//\"/} typeset migrate=${10//\"/} typeset max_pparts=${11//\"/} typeset max_lvs=${12//\"/} typeset mp_name=${13//\"/} typeset -l mp_strictness=${14//\"/} typeset -l critical=${15//\"/} typeset -l failure_action=${16//\"/} typeset notify_method=${17//\"/} typeset preferred_read=${18//\"/} typeset -l encryption=${19//\"/} [[ $CLMGR_LOGGING == 'med' ]] && set +x # Only trace param values #=================================== : Declare and initialize variables #=================================== typeset -i rc=$RC_UNKNOWN typeset typeOpt= rOpt= yOpt= OOpt= POpt= vOpt= pOpt= typeset MOpt= hOpt= sOpt= QOpt= aOpt= typeset INPUT= ATTR= VALUE= ORDER= PVIDs= typeset rg_startup_pref="-E" typeset cur_oslevel=$(oslevel -r|sed 's/-//g') typeset -i min_req_ver=730000 typeset LEGACY= ORIGINAL= BIG= SCALABLE= REM= typeset LINE=$(dspmsg -s 43 cspoc.cat 40 "Legacy Original Big Scalable") print -- "$LINE" |read LEGACY ORIGINAL BIG SCALABLE REM typeset -l ORIGINAL_LC=$ORIGINAL typeset -l BIG_LC=$BIG typeset -l SCALABLE_LC=$SCALABLE typeset -l LEGACY_LC=$LEGACY if [[ $LANG == @(|C|en_US) ]]; then ORIGINAL_LC=o BIG_LC=b SCALABLE_LC=s LEGACY_LC=l fi [[ -z $_CSPOC_CALLED_FROM_SMIT ]] && _CSPOC_CALLED_FROM_SMIT=true export _CSPOC_CALLED_FROM_SMIT typeset existing CL=$LINENO KLIB_HACMP_list_volume_groups existing 2>>$CLMGR_TMPLOG #========================================== : Make sure the system requisites are met #========================================== lslpp -lc bos.clvm.enh >>$CLMGR_TMPLOG 2>&1 if (( $? != RC_SUCCESS )); then dspmsg -s $CLMGR_SET $CLMGR_MSGS 59 '\nERROR: missing requisite fileset: "%1$s"\n' bos.clvm.enh 1>&2 rc=$RC_MISSING_DEPENDENCY fi #================= : Validate input #================= if [[ -n $type ]]; then typeset -l type_lc=$type case $type_lc in $ORIGINAL_LC*) typeOpt="" ;; $BIG_LC*) typeOpt="-B" ;; $SCALABLE_LC*) typeOpt="-S" ;; $LEGACY_LC*) typeOpt="-I" ;; *) dspmsg -s $CLMGR_SET $CLMGR_MSGS 110 "\nERROR: invalid value specified for \"%1\$s\": \"%2\$s\"\n" TYPE "$type" 1>&2 dspmsg -s $CLMGR_SET $CLMGR_MSGS 3 "Valid values: %1\$s\n\n" "$ORIGINAL, $BIG, $SCALABLE, $LEGACY" 1>&2 rc=$RC_INCORRECT_INPUT ;; esac elif [[ $cur_oslevel -ge $min_req_ver ]];then typeOpt="-S" fi if [[ -z $nodes ]]; 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 typeset node= typeset -i invalid_nodes=0 for node in ${nodes//,/ }; do CL=$LINENO KLIB_HACMP_is_known_node $node >/dev/null if (( $? != RC_SUCCESS )); then (( invalid_nodes++ )) dspmsg -s $CLMGR_SET $CLMGR_MSGS 102 "\nERROR: \"%1\$s\" does not appear to exist!\n\n" "$node" 1>&2 rc=$RC_NOT_FOUND fi done if (( invalid_nodes > 0 )); 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 $volume_group && " ${existing[*]} " == *\ $volume_group\ * ]]; then dspmsg -s $CLMGR_SET $CLMGR_MSGS 229 "\nERROR: the specified object already exists: \"%1\$s\"\n\n" "$volume_group" 1>&2 rc=$RC_INCORRECT_INPUT fi if [[ -z $disks ]]; then dspmsg -s $CLMGR_SET $CLMGR_MSGS 101 "\nERROR: this operation requires the \"%1\$s\" attribute.\n\n" PHYSICAL_VOLUMES 1>&2 rc=$RC_MISSING_INPUT else #======================================================== : Attempt to validate all provided disks, attempting to : convert them into PVID form, if needed. #======================================================== typeset free_disks=$(LANG=C LC_ALL=C $HACSPOC/cllspvids -O -n $nodes) for disk in $disks; do typeset node= if [[ $disk == *@* ]]; then print -- "$disk" | IFS=@ read disk node else if [[ " ${nodes//,/ } " == *\ $LOCAL_NODE\ * ]]; then node=$LOCAL_NODE else node=${nodes%%,*} fi fi #================================================================== # "$free_disks" format is: # # pvid ( on node [at site ]) # # Or, if the same hdisk name is used on multiple nodes: # # pvid ( on nodes node1[,node2,...] [at site ]) # # Or, if the hdisk name is the same across the given list of nodes: # # pvid (hdisk_name on all cluster nodes) # #================================================================== typeset LINE= PVID= : See if $disk is already a PVID print -- "$free_disks" |\ while read LINE; do if [[ $LINE == $disk\ * ]]; then PVID=$disk break fi done if [[ -z $PVID ]]; then typeset site_list=$(/usr/es/sbin/cluster/utilities/clodmget -f name -n HACMPsite) if [[ -n $site_list ]]; then for site in $site_list do nodelist=$(/usr/es/sbin/cluster/utilities/clodmget -q "name = $site" -f nodelist -n HACMPsite) if [[ -n $(print -- "$nodelist" | /usr/bin/grep -w "$node") ]]; then LINE=$(print -- "$free_disks" | \ /usr/bin/grep -w "$disk" | \ /usr/bin/grep -we "$node" -we "$site" -we "on all") break fi done else LINE=$(print -- "$free_disks" | \ /usr/bin/grep -w "$disk" | \ /usr/bin/grep -we "$node" -we "on all") fi [[ -n $LINE ]] && PVID=${LINE%%[[:space:]]*} fi if [[ -n $PVID ]]; then PVIDs="$PVIDs $PVID" else : Use $disk as-is CL=$LINENO cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 243 "\nWarning: unable to verify that \"%1\$s\" is free/available, and shared between the specified nodes, \"%2\$s\".\n" "$disk" "$nodes" 1>&2 PVIDs="$PVIDs $disk" fi done fi #=================================================================== : If a resource group was given, it may be an existing group, or : it may be a new group. So we can only check for well-formedness. #=================================================================== if [[ $rg != *([[:space:]]) ]]; then if [[ -n "${rg//[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 includeletters, numbers, and underscores only.\n\n" "$rg" "${rg//[a-zA-Z0-9_]/} " 1>&2 rc=$RC_INCORRECT_INPUT fi fi if [[ $mp_strictness != *([[:space:]]) ]]; then case $mp_strictness in @(n|f)*) mp_strictness="" ;; @(y|t)*) mp_strictness="y" ;; s*) mp_strictness="s" ;; *) dspmsg -s $CLMGR_SET $CLMGR_MSGS 110 "\nERROR: invalid value specified for \"%1\$s\": \"%2\$s\".\n" "MP_STRICTNESS" "$mp_strictness" 1>&2 dspmsg -s $CLMGR_SET $CLMGR_MSGS 3 "Valid values: %1\$s\n\n" "no, yes, super" 1>&2 rc=$RC_INCORRECT_INPUT ;; esac fi if [[ $failure_action != *([[:space:]]) ]]; then case $failure_action in h*) failure_action="halt" ;; n*) failure_action="notify" ;; f*) failure_action="fence" ;; s*) failure_action="shutdown" ;; m*) failure_action="fallover" ;; *) dspmsg -s $CLMGR_SET $CLMGR_MSGS 110 "\nERROR: invalid value specified for \"%1\$s\": \"%2\$s\".\n" "FAILURE_ACTION" "$failure_action" 1>&2 dspmsg -s $CLMGR_SET $CLMGR_MSGS 3 "Valid values: %1\$s\n\n" "halt, notify, fence, stoprg, moverg" 1>&2 rc=$RC_INCORRECT_INPUT ;; esac fi if [[ $migrate != *([[:space:]]) ]]; then case $migrate in @(f|n)*) migrate="n" ;; @(o|1)*) migrate="y" ;; y) migrate="y" ;; @(p|P)*) migrate="Y" ;; Y) migrate="Y" ;; @(r|R)*) migrate="r" ;; *) dspmsg -s $CLMGR_SET $CLMGR_MSGS 110 "\nERROR: invalid value specified for \"%1\$s\": \"%2\$s\".\n" "MIGRATE_FAILED_DISKS" "$migrate" 1>&2 dspmsg -s $CLMGR_SET $CLMGR_MSGS 3 "Valid values: %1\$s\n\n" "false, one, pool, remove" 1>&2 rc=$RC_INCORRECT_INPUT ;; esac fi #============================== : Validate the integer inputs #============================== for INPUT in MAJOR_NUMBER@$major \ LTG_SIZE@$ltg_size \ PPART_SIZE@$ppart_size \ MAX_PHYSICAL_PARTITIONS@$max_pparts \ MAX_LOGICAL_VOLUMES@$max_lvs do print -- "$INPUT" | IFS=@ read ATTR VALUE if [[ -n $VALUE && $VALUE != +([[:digit:]]) ]]; then dspmsg -s $CLMGR_SET $CLMGR_MSGS 111 "\nERROR: \"%1\$s\" requires a positive, integer value.\n\n" "$ATTR" 1>&2 rc=$RC_INCORRECT_INPUT fi done #============================== : Validate the boolean inputs #============================== for INPUT in ACTIVATE@$activate@false,true \ QUORUM@$quorum@true,false \ CRITICAL@$critical@false,true \ ENABLE_LV_ENCRYPTION@$encryption@no,yes do print -- "$INPUT" | IFS=@ read ATTR VALUE ORDER if [[ -n $VALUE && $VALUE != @(y|t|n|f)* ]]; then dspmsg -s $CLMGR_SET $CLMGR_MSGS 110 "\nERROR: invalid value specified for \"%1\$s\": \"%2\$s\".\n" "$ATTR" "$VALUE" 1>&2 dspmsg -s $CLMGR_SET $CLMGR_MSGS 3 "Valid values: %1\$s\n\n" "$ORDER" 1>&2 rc=$RC_INCORRECT_INPUT fi done #=============================================================== : check for aix version 7.3 if lvm encryption option is provided #=============================================================== if [[ $encryption == @(y|t)* ]];then hdcrypt_version=$(LC_ALL=C lslpp -L | grep -w hdcrypt | awk '{print $2}') if [[ -z $hdcrypt_version || $cur_oslevel < $min_req_ver ]] then dspmsg -s $CLMGR_SET $CLMGR_MSGS 1480 "\nERROR: Installed AIX level %1\$s is not supported to use LVM Encryption,\n\ minimum level required to use AIX LVM Encryption is AIX %2\$s.\n\n" "$cur_oslevel" "$min_req_ver" 1>&2 rc=$RC_MISSING_DEPENDENCY fi fi #============================================================== : Check for options that apply only to Scalable volume groups #============================================================== if [[ $typeOpt != "-S" ]]; then for INPUT in MAX_PHYSICAL_PARTITIONS@$max_pparts \ MAX_LOGICAL_VOLUMES@$max_lvs \ STRICT_MIRROR_POOLS@$mp_strictness \ MIRROR_POOL_NAME@$mp_name \ LVM_PREFERRED_READ@$preferred_read do print -- "$INPUT" | IFS=@ read ATTR VALUE if [[ -n $VALUE ]]; then CL=$LINENO cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 37 "\nERROR: option \"%1\$s\" is required when any of the following option(s) are used: %2\$s\n\n" "TYPE=$SCALABLE" "$ATTR" 1>&2 rc=$RC_INCORRECT_INPUT fi done fi if [[ $notify_method != *([[:space:]]) && ! -e $notify_method ]]; then CL=$LINENO cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 107 '\nERROR: the specified path/file does not appear to exist on "%2$s": %1$s\n\n' "$notify_method" "$LOCAL_NODE" 1>&2 rc=$RC_NOT_FOUND fi if [[ $notify_method != *([[:space:]]) ]] && [[ -z $critical || $critical == @(f|n)* ]] then CL=$LINENO cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 37 "\nERROR: option \"%1\$s\" is required when any of the following option(s) are used: %2\$s\n\n" "CRITICAL=true" NOTIFY_METHOD 1>&2 rc=$RC_INCORRECT_INPUT fi if [[ $failure_action != *([[:space:]]) ]] && [[ -z $critical || $critical == @(f|n)* ]] then CL=$LINENO cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 37 "\nERROR: option \"%1\$s\" is required when any of the following option(s) are used: %2\$s\n\n" "CRITICAL=true" FAILURE_ACTION 1>&2 rc=$RC_INCORRECT_INPUT fi if [[ -n $rg ]]; then typeset RG_STARTUP_POLICY=$($HAUTILS/clodmget -q "group=$rg" -n -f startup_pref HACMPgroup) if [[ $RG_STARTUP_POLICY == "OAAN" ]]; then # concurrent Resource Group. rg_startup_pref="-C" fi fi #================================================================================================ : Verify preferred read option is valid or not, if any value is specified. #================================================================================================ if [[ ${preferred_read} != *([[:space:]]) ]]; then if [[ $CLUSTER_TYPE == "NSC" ]]; then CL=$LINENO verify_in_set LVM_PREFERRED_READ "$preferred_read" "roundrobin, favorcopy" preferred_read else # siteaffinity option is available only for site based cluster. CL=$LINENO verify_in_set LVM_PREFERRED_READ "$preferred_read" "roundrobin, favorcopy, siteaffinity" preferred_read fi if (( $? != RC_SUCCESS )); then rc=$RC_INCORRECT_INPUT fi fi #==================================================================== : If no errors have been detect in the input, perform the operation #==================================================================== if (( $rc == RC_UNKNOWN )); then [[ $rg != *([[:space:]]) ]] && rOpt="-r $rg" [[ $volume_group != *([[:space:]]) ]] && yOpt="-y $volume_group" [[ $major == *([[:space:]]) ]] && major=$($HACSPOC/cl_getmajor) [[ $max_pparts == +([[:digit:]]) ]] && POpt="-P $max_pparts" [[ $max_lvs == +([[:digit:]]) ]] && vOpt="-v $max_lvs" [[ $critical == @(y|t)* ]] && OOpt="-O" [[ -n $ppart_size ]] && sOpt="-s $ppart_size" [[ $mp_name != *([[:space:]]) ]] && pOpt="-p $mp_name" [[ -n $encryption && $encryption == @(y|t)* ]] && kOpt="-k y" [[ -n $encryption && $encryption == @(n|f)* ]] && kOpt="-k n" if [[ $mp_strictness != *([[:space:]]) && $mp_strictness != "no" ]] then MOpt="-M $mp_strictness" fi #===================================================== : Make sure there are no duplicates in the PVID list #===================================================== PVIDs=$(print "${PVIDs//+([[:space:]])/$NL}" | sort -u) PVIDs=${PVIDs//+([[:space:]])/ } print -- "$0()[$LINENO]($SECONDS): $HASBIN/cl_mkvg -f -n $typeOpt -cspoc \"-n $nodes\" $rOpt $yOpt $sOpt -V\"$major\" $OOpt $MOpt $pOpt -l false $rg_startup_pref $POpt $vOpt $kOpt $PVIDs" >>$CLMGR_TMPLOG # Always log commands $HASBIN/cl_mkvg -f -n $typeOpt \ -cspoc "-n $nodes" \ $rOpt \ $yOpt \ $sOpt \ -V"$major" \ $OOpt \ $MOpt \ $pOpt \ -l false \ $rg_startup_pref \ $POpt \ $vOpt \ $kOpt \ $PVIDs > $TMPDIR/clmgr.KHav.addvg.$$ rc=$? print "$0()[$LINENO]($SECONDS): cl_mkvg RC: $rc" >>$CLMGR_TMPLOG # Always log command result cat $TMPDIR/clmgr.KHav.addvg.$$ #=============================================================== : If no volume group name was explicitly specified, attempt to : determine the automatically assigned name of the new VG. #=============================================================== if [[ $volume_group == *([[:space:]]) ]]; then typeset DATA=$(/usr/bin/cat $TMPDIR/clmgr.KHav.addvg.$$ 2>>$CLMGR_TMPLOG) DATA=${DATA##*\ vg} DATA=${DATA%%[\ \.]*} if [[ $DATA != *([[:space:]]) ]]; then volume_group="vg$DATA" fi fi /usr/bin/rm -f $TMPDIR/clmgr.KHav.addvg.$$ if (( $rc != RC_SUCCESS )); then if [[ $volume_group == *([[:space:]]) ]]; then volume_group="vg##" fi rc=$RC_ERROR #=================================================================== : Some options require the cl_chvg command. If any were specified, : and the call to cl_mkvg was successful, construct/invoke the : command here. #=================================================================== elif [[ -n "$ltg_size$quorum$activate$migrate$preferred_read" ]]; then LOpt="" QOpt="" aOpt="" hOpt="" [[ -n $ltg_size ]] && LOpt="-L $ltg_size" [[ $quorum == @(y|t)* ]] && QOpt="-Q y" || QOpt="-Q n" [[ $activate == @(y|t)* ]] && aOpt="-a y" || aOpt="-a n" [[ -n $migrate ]] && hOpt="-h $migrate" [[ -n $preferred_read ]] && rOpt="-r $preferred_read" print -- "$0()[$LINENO]($SECONDS): $HASBIN/cl_chvg -cspoc \"-n $nodes\" $LOpt $QOpt $hOpt $rOpt $volume_group" >>$CLMGR_TMPLOG # Always log commands $HASBIN/cl_chvg -cspoc "-n $nodes" \ $LOpt \ $QOpt \ $hOpt \ $rOpt \ $volume_group rc=$? print "$0()[$LINENO]($SECONDS): cl_chvg RC: $rc" >>$CLMGR_TMPLOG # Always log command result fi if (( $rc != RC_SUCCESS )); then rc=$RC_ERROR elif [[ -n $failure_action || -n $notify_method ]]; then typeset fa= nm= [[ -n $failure_action ]] && fa="FAILURE_ACTION=$failure_action" [[ -n $notify_method ]] && nm="NOTIFY_METHOD=$notify_method" print -- "$0()[$LINENO]($SECONDS): $HAUTILS/clchappmon MONITOR_TYPE=selective_fallover $fa $nm name=$volume_group" >>$CLMGR_TMPLOG # Always log commands $HAUTILS/clchappmon MONITOR_TYPE=selective_fallover $fa $nm name=$volume_group rc=$? print "cl_chvg RC: $rc" >>$CLMGR_TMPLOG # Always log command result fi if (( $rc != RC_SUCCESS )); then dspmsg -s $CLMGR_SET $CLMGR_MSGS 201 "\nERROR: failed to create \"%1\$s\".\n\n" "$volume_group" 1>&2 rc=$RC_ERROR #=========================================================== : If output from this operation was requested, retrieve it #=========================================================== else if (( CLMGR_VERBOSE )) || [[ -n $CLMGR_ATTRS ]]; then CL=$LINENO KLIB_HACMP_get_volume_group_attributes "$volume_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 volume_group -h" "VOLUME GROUP:" "$CLMGR_PROGNAME" 1>&2 fi log_return_msg "$rc" "$0()" "$LINENO" return $? } # End of "KLIB_HACMP_add_volume_group()" #================================================ # The following, commented line enforces coding # standards when this file is edited via vim. #================================================ # vim:tabstop=4:shiftwidth=4:expandtab:smarttab #================================================