#!/bin/ksh93 # IBM_PROLOG_BEGIN_TAG # This is an automatically generated prolog. # # 61haes_r714 src/43haes/lib/ksh93/hacmp/KLIB_HACMP_add_dependency.sh 1.4 # # Licensed Materials - Property of IBM # # COPYRIGHT International Business Machines Corp. 1990,2010 # All Rights Reserved # # US Government Users Restricted Rights - Use, duplication or # disclosure restricted by GSA ADP Schedule Contract with IBM Corp. # # IBM_PROLOG_END_TAG # @(#)09 1.4 src/43haes/lib/ksh93/hacmp/KLIB_HACMP_add_dependency.sh, hacmp.assist, 61haes_r714 8/6/13 16:54:48 #================================================ # The following, commented line enforces coding # standards when this file is edited via vim. #================================================ # vim:tabstop=4:shiftwidth=4:expandtab:smarttab #================================================ # Start of POD-formatted documentation. Viewing suggestions: # perldoc # pod2text -c # pod2text -c --code # pod2html function devDoc { : <<'=cut' >/dev/null 2>&1 =head1 NAME KLIB_HACMP_add_dependency =head1 VERSION Version Number: 1.4 Last Extracted: 1/31/14 04:41:52 Last Changed: 8/6/13 16:54:48 Path, Component, Release(, Level): src/43haes/lib/ksh93/hacmp/KLIB_HACMP_add_dependency.sh, hacmp.assist, 61haes_r714 =head1 SYNOPSIS Temporal Dependency (parent ==> child) clmgr add dependency \ PARENT= \ CHILD="[,,...]" Temporal Dependency (start/stop after) clmgr add dependency \ {STOP|START}= \ AFTER= Location Dependency (colocation) clmgr add dependency \ SAME={NODE|SITE} \ GROUPS=",[,...]" Location Dependency (anti-colocation) clmgr add dependency \ TYPE=DIFFERENT_NODES \ HIGH=",,..." \ INTERMEDIATE=",,..." \ LOW=",,..." Acquisition/Release Order clmgr add dependency \ TYPE={ACQUIRE|RELEASE} \ { SERIAL="{,,...|ALL}" | PARALLEL="{,,...|ALL}" } NOTE: the alias for "dependency" is "de". =head1 DESCRIPTION Creates a new resource group dependency within the cluster: Temporal Dependency: (i.e. startup order matters) Parent/Child, Parent/Children Start/Stop After, Aquire/Release Location Dependency: (i.e. node location matters most) CoLocation: same node, same site Anti-CoLocation: different node (startup order can also be specified) =head1 ARGUMENTS 1. parent [OPTIONAL] {string] The label of a resource group that will be a parent. 2. children [OPTIONAL] {string] The labels of one or more resource groups that will be children of the specified parent resource group. 3. same [OPTIONAL] {string] An indicator of whether or not to create a "same node" or a "same site" colocation dependency. 4. groups [OPTIONAL] {string] The labels of one or more resource groups to include in the colocation dependency 5. high [OPTIONAL] {string] The labels of one or more resource groups to include in an anti-colocation dependency, and give the highest startup priority. 6. intermediate [OPTIONAL] {string] The labels of one or more resource groups to include in an anti-colocation dependency, and give intermediate startup priority. 7. low [OPTIONAL] {string] The labels of one or more resource groups to include in an anti-colocation dependency, and give the lowest startup priority. 8. stop [OPTIONAL] {string] The label of a resource group that will be stopped after the specified "AFTER" resource group. 9. start [OPTIONAL] {string] The label of a resource group that will be started after the specified "AFTER" resource group. 10. after [OPTIONAL] {string] The label of a resource group that will be stopped or started *before* the list of other resource groups provided via "STOP" or "START". 11. type [OPTIONAL] {string} The type of dependency to create. This is totally optional for all true dependency types, which can be easily inferred from the provided arguments. However, type is required for setting the resource group processing order. 12. serial [OPTIONAL] {string} The labels of one or more resource groups that are to be aquired/release serially, in the order specified. Any groups not specified here will continue to be acquired/released in parallel (the default behavior). 13. parallel [OPTIONAL] {string} The labels of one or more resource groups that are to be aquired/release in parallel (i.e. at the same time). Any groups not specified here will be acquired/released serially, in the order previously specified. =head1 RETURN 0: no errors were detected; the operation appears to have been successful 1: a general error has occurred 2: a specified resource does not exist, or could not be found 3: some required input was missing 4: some detected input was incorrect in some way 5: a required dependency does not exist 6: a specified search failed to match any data =head1 COPYRIGHT COPYRIGHT International Business Machines Corp. 2005,2010 All Rights Reserved =cut } # End of POD-formatted documentation. function KLIB_HACMP_add_dependency { LINENO=2 . $HALIBROOT/log_entry "$0()" "$CL" : version=1.4, src/43haes/lib/ksh93/hacmp/KLIB_HACMP_add_dependency.sh, hacmp.assist, 61haes_r714 : INPUTS: $* typeset parent=${1//\"/} typeset children=${2//\"/} typeset -u same=${3//\"/} typeset groups=${4//\"/} typeset high=${5//\"/} high=${high//,/ } typeset intermediate=${6//\"/} intermediate=${intermediate//,/ } typeset low=${7//\"/} low=${low//,/ } typeset -i i=0 for (( i=0; i<7; i++ )); do (( $# == 0 )) && break shift done typeset stop=${1//\"/} typeset start=${2//\"/} typeset after=${3//\"/} typeset type=${4//\"/} typeset serial=${5//\"/} typeset parallel=${6//\"/} [[ $CLMGR_LOGGING == 'med' ]] && set +x # Only trace param values #=================================== : Declare and initialize variables #=================================== typeset -i rc=$RC_UNKNOWN typeset -u TYPE=$type if [[ -n $serial ]]; then serial=${serial//,/ } serial=${serial//+([[:space:]])/ } serial=${serial#+([[:space:]])} serial=${serial%+([[:space:]])} fi if [[ -n $parallel ]]; then parallel=${parallel//,/ } parallel=${parallel//+([[:space:]])/ } parallel=${parallel#+([[:space:]])} parallel=${parallel%+([[:space:]])} fi if [[ -n $parent ]]; then parent=${parent//,/ } parent=${parent//+([[:space:]])/ } parent=${parent#+([[:space:]])} parent=${parent%+([[:space:]])} fi if [[ -n $children ]]; then children=${children//,/ } children=${children//+([[:space:]])/ } children=${children#+([[:space:]])} children=${children%+([[:space:]])} fi if [[ -n $groups ]]; then groups=${groups//,/ } groups=${groups//+([[:space:]])/ } groups=${groups#+([[:space:]])} groups=${groups%+([[:space:]])} fi if [[ -n $high ]]; then high=${high//,/ } high=${high//+([[:space:]])/ } high=${high#+([[:space:]])} high=${high%+([[:space:]])} fi if [[ -n $intermediate ]]; then intermediate=${intermediate//,/ } intermediate=${intermediate//+([[:space:]])/ } intermediate=${intermediate#+([[:space:]])} intermediate=${intermediate%+([[:space:]])} fi if [[ -n $low ]]; then low=${low//,/ } low=${low//+([[:space:]])/ } low=${low#+([[:space:]])} low=${low%+([[:space:]])} fi if [[ -n $stop ]]; then stop=${stop//,/ } stop=${stop//+([[:space:]])/ } stop=${stop#+([[:space:]])} stop=${stop%+([[:space:]])} fi if [[ -n $start ]]; then start=${start//,/ } start=${start//+([[:space:]])/ } start=${start#+([[:space:]])} start=${start%+([[:space:]])} fi if [[ -n $after ]]; then after=${after//,/ } after=${after//+([[:space:]])/ } after=${after#+([[:space:]])} after=${after%+([[:space:]])} fi if [[ -n $parent || -n $children ]]; then TYPE="PARENT_CHILD" elif [[ -n $same || -n $groups ]]; then case $same in *NODE*) TYPE="NODECOLLOCATION" ;; *SITE*) TYPE="SITECOLLOCATION" ;; esac elif [[ -n $high || -n $intermediate || -n $low ]]; then TYPE="ANTICOLLOCATION" elif [[ -n $after ]]; then TYPE="AFTER" if [[ -n $stop ]]; then TYPE="STOP_AFTER" elif [[ -n $start ]]; then TYPE="START_AFTER" fi fi #================================================================ : Check for a defined cluster. No need to continue without one. #================================================================ CL=$LINENO isClusterDefined if (( $? != RC_SUCCESS )); then rc=$RC_MISSING_DEPENDENCY #================= : Validate input #================= elif [[ -z $TYPE && -n "$serial$parallel" ]]; then /usr/bin/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" TYPE "SERIAL, PARALLEL" 1>&2 /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 3 "Valid values: %1\$s\n\n" "ACQUIRE, RELEASE" 1>&2 rc=$RC_MISSING_INPUT fi if [[ -n $serial && -n $parallel ]]; then /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 36 "\nERROR: conflicting options were provided, \"%1\$s\" versus \"%2\$s\".\n\n" "SERIAL" "PARALLEL" 1>&2 rc=$RC_MISSING_INPUT fi if [[ -n $TYPE && -n "$serial$parallel" && $TYPE != @(A|R)* ]]; then /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 110 "\nERROR: invalid value specified for \"%1\$s\": \"%2\$s\"\n\n" TYPE "$TYPE" 1>&2 /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 3 "Valid values: %1\$s\n\n" "ACQUIRE, RELEASE" 1>&2 rc=$RC_MISSING_INPUT fi if [[ $TYPE == "PARENT_CHILD" && -z $parent ]]; then /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 101 "\nERROR: this operation requires the \"%1\$s\" attribute.\n\n" PARENT 1>&2 rc=$RC_MISSING_INPUT fi if [[ $TYPE == "PARENT_CHILD" && -z $children ]]; then /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 101 "\nERROR: this operation requires the \"%1\$s\" attribute.\n\n" CHILD 1>&2 rc=$RC_MISSING_INPUT fi if [[ -n $parent && $parent == *[[:space:]]* ]]; then /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 210 "\nERROR: only one resource group may be specified as the parent in a\n \"parent/child\" dependency: PARENT=\"%1\$s\"\n\n" "$parent" 1>&2 rc=$RC_INCORRECT_INPUT fi if [[ $TYPE == *AFTER ]] && [[ -z $stop && -z $start ]]; then /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 101 "\nERROR: this operation requires the \"%1\$s\" attribute.\n\n" STOP/START 1>&2 rc=$RC_MISSING_INPUT fi if [[ -n $after && $after == *[[:space:]]* ]]; then /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 210 "\nERROR: only one resource group may be specified as the primary resource group\n in a \"STOP_AFTER\" dependency: AFTER=\"%1\$s\"\n\n" "$after" 1>&2 rc=$RC_INCORRECT_INPUT fi if [[ -n $same && $same != *@(NODE|SITE)* ]]; then /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 110 "\nERROR: invalid value specified for \"%1\$s\": \"%2\$s\"\n\n" SAME "$same" 1>&2 /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 3 "Valid values: %1\$s\n\n" "NODE, SITE" 1>&2 rc=$RC_INCORRECT_INPUT fi if [[ -n $same || -n $groups ]] && \ [[ -n $TYPE && $TYPE != @(NODE|SITE)COLLOCATION ]] then /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 211 "\nERROR: a dependency of type \"%1\$s\" has already been specified.\n It will not be possible to also define a \"same node/site\" dependency\n in the same operation.\n\n" "$TYPE" 1>&2 rc=$RC_ERROR fi if [[ -n $same && -z $groups ]] || [[ -z $same && -n $groups ]]; then /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 212 "\nERROR: to establish a \"same site/node\" dependency, the type of the\n dependency must be specified via the SAME attribute, and two\n or more resource groups must be specified via the GROUPS attribute.\n\n" 1>&2 rc=$RC_MISSING_INPUT fi if [[ -n $groups && $groups != *[[:space:]]* ]]; then /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 101 "\nERROR: this operation requires the \"%1\$s\" attribute.\n\n" GROUPS 1>&2 rc=$RC_MISSING_INPUT fi if [[ -n $high || -n $intermediate || -n $low ]] && \ [[ $TYPE != "ANTICOLLOCATION" ]] then /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 213 "\nERROR: a dependency of type \"%1\$s\" has already been specified.\n It will not be possible to also define a \"different nodes\" dependency\n in the same operation.\n\n" "$TYPE" 1>&2 rc=$RC_INCORRECT_INPUT fi if [[ "$parent $child $high $intermediate $low $groups $start $stop $after" != *([[:space:]]) ]] then typeset allRGs="$parent $child $high $intermediate $low $groups $start $stop $after" typeset -i all_rgs_found=1 for rg in ${allRGs//,/ }; do CL=$LINENO KLIB_HACMP_is_known_rg "$rg" if (( $? != RC_SUCCESS )); then rc=$RC_INCORRECT_INPUT all_rgs_found=0 /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 102 "\nERROR: \"%1\$s\" does not appear to exist!\n\n" "$rg" 1>&2 fi done if (( ! all_rgs_found )); then /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 154 "Available Resource Groups:\n\n" 1>&2 typeset available CL=$LINENO KLIB_HACMP_list_resourcegroups available for (( i=0; i<${#available[*]}; i++ )); do if [[ ${available[$i]} != *([[:space:]]) ]]; then print -u2 "\t${available[$i]}" fi done print -u2 "" fi fi #============================================================== : Create the dependency if no input errors have been detected #============================================================== if (( $rc == RC_UNKNOWN )); then case $TYPE in AC*) typeset depList CL=$LINENO KLIB_HACMP_list_dependencies depList for (( i=0; i<${#depList[*]}; i++ )); do [[ ${depList[$i]} != *RELEASE_SERIALLY* ]] && continue break done typeset release=${depList[$i]} release=${release%%+([[:space:]])*} release=${release//,/ } if [[ -n $parallel ]]; then serial= typeset rgList CL=$LINENO KLIB_HACMP_list_resourcegroups rgList for (( i=0; i<${#rgList[*]}; i++ )); do if [[ " ${parallel//,/ } " != *\ ${rgList[$i]}\ * ]] then [[ -n $serial ]] && serial="$serial " serial="$serial${rgList[$i]}" fi done fi print -- "$0()[$LINENO]($SECONDS): $HAUTILS/clrgorder -c -a \"${serial//,/ }\" -r \"$release\"" >>$CLMGR_TMPLOG # Always log commands $HAUTILS/clrgorder -c -a "${serial//,/ }" -r "$release" rc=$? print "clrgorder RC: $rc" >>$CLMGR_TMPLOG # Always log command result ;; R*) typeset depList CL=$LINENO KLIB_HACMP_list_dependencies depList for (( i=0; i<${#depList[*]}; i++ )); do [[ ${depList[$i]} != *ACQUIRE_SERIALLY* ]] && continue break done typeset acquire=${depList[$i]} acquire=${acquire%%+([[:space:]])*} acquire=${acquire//,/ } if [[ -n $parallel ]]; then serial= typeset rgList CL=$LINENO KLIB_HACMP_list_resourcegroups rgList for (( i=0; i<${#rgList[*]}; i++ )); do if [[ " ${parallel//,/ } " != *\ ${rgList[$i]}\ * ]] then [[ -n $serial ]] && serial="$serial " serial="$serial${rgList[$i]}" fi done fi print -- "$0()[$LINENO]($SECONDS): $HAUTILS/clrgorder -c -a \"$acquire\" -r \"${serial//,/ }\"" >>$CLMGR_TMPLOG # Always log commands $HAUTILS/clrgorder -c -a "$acquire" -r "${serial//,/ }" rc=$? print "clrgorder RC: $rc" >>$CLMGR_TMPLOG # Always log command result ;; "PARENT_CHILD") print -- "$0()[$LINENO]($SECONDS): $HAUTILS/clrgdependency -t \"$TYPE\" -a -p \"$parent\" -c \"$children\"" >>$CLMGR_TMPLOG # Always log commands $HAUTILS/clrgdependency -t "$TYPE" -a -p "$parent" -c "$children" rc=$? print "clrgdependency RC: $rc" >>$CLMGR_TMPLOG # Always log command result (( $rc != RC_SUCCESS )) && rc=$RC_ERROR ;; "STOP_AFTER") print -- "$0()[$LINENO]($SECONDS): $HAUTILS/clrgdependency -t \"$TYPE\" -a -p \"$stop\" -c \"$after\"" >>$CLMGR_TMPLOG # Always log commands $HAUTILS/clrgdependency -t "$TYPE" -a -p "$stop" -c "$after" rc=$? print "clrgdependency RC: $rc" >>$CLMGR_TMPLOG # Always log command result (( $rc != RC_SUCCESS )) && rc=$RC_ERROR ;; "START_AFTER") print -- "$0()[$LINENO]($SECONDS): $HAUTILS/clrgdependency -t \"$TYPE\" -a -c \"$start\" -p \"$after\"" >>$CLMGR_TMPLOG # Always log commands $HAUTILS/clrgdependency -t "$TYPE" -a -c "$start" -p "$after" rc=$? print "clrgdependency RC: $rc" >>$CLMGR_TMPLOG # Always log command result (( $rc != RC_SUCCESS )) && rc=$RC_ERROR ;; @(NODE|SITE)COLLOCATION) print -- "$0()[$LINENO]($SECONDS): $HAUTILS/clrgdependency -t \"$TYPE\" -a -l \"$groups\"" >>$CLMGR_TMPLOG # Always log commands $HAUTILS/clrgdependency -t "$TYPE" -a -l "$groups" rc=$? print "clrgdependency RC: $rc" >>$CLMGR_TMPLOG # Always log command result (( $rc != RC_SUCCESS )) && rc=$RC_ERROR ;; "ANTICOLLOCATION") # IMPORTANT NOTE: the clrgdependency options "-hp", "-ip" and # "-lc" require *no* space between them and # their argument values! So don't "correct" # that, below! print -- "$0()[$LINENO]($SECONDS): $HAUTILS/clrgdependency -t \"$TYPE\" -u -hp\"$high\" -ip\"$intermediate\" -lp\"$low\"" >>$CLMGR_TMPLOG # Always log commands $HAUTILS/clrgdependency -t "$TYPE" -u -hp"$high" -ip"$intermediate" -lp"$low" rc=$? print "clrgdependency RC: $rc" >>$CLMGR_TMPLOG # Always log command result (( $rc != RC_SUCCESS )) && rc=$RC_ERROR ;; *) /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 33 "\nERROR: invalid dependency attributes were specified.\n\n" 1>&2 rc=$RC_MISSING_INPUT ;; esac (( $rc == RC_ERROR )) && /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 109 "\nERROR: the operation appears to have failed.\n\n" 1>&2 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 dependency -h" "DEPENDENCY:" "$CLMGR_PROGNAME" 1>&2 fi log_return_msg "$rc" "$0()" "$LINENO" return $? } # End of "KLIB_HACMP_add_dependency()"