#!/usr/bin/ksh93 # ALTRAN_PROLOG_BEGIN_TAG # This is an automatically generated prolog. # # Copyright (C) Altran ACT S.A.S. 2017,2021. All rights reserved. # # ALTRAN_PROLOG_END_TAG # # IBM_PROLOG_BEGIN_TAG # This is an automatically generated prolog. # # 61haes_r714 src/43haes/usr/sbin/cluster/sa/db2/sbin/cl_db2smadd.sh 1.10 # # Licensed Materials - Property of IBM # # Restricted Materials of IBM # # COPYRIGHT International Business Machines Corp. 2005,2008 # 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/usr/sbin/cluster/sa/db2/sbin/cl_db2smadd.sh, 726, 2147A_aha726, Feb 05 2021 09:50 PM ## ## NAME: cl_db2smadd ## ## DESCRIPTION: This script is called when the user adds a new DB2 ## instance to the cluster definition. This script ## calls the discovery routine on each specified node ## and performs pre-verification to ensure the ## discovered DB2 instances are available and accessible ## on the remote nodes. ## ## Note: This script is only called via SMIT ## ## ARGUMENTS: ## -D turn debugging on (set -x) ## ## -n where each node is separated by ':' ## The list of nodes to run discovery on ## ## -F flush discovery file, remove the discovery file ## ## -f use the specified discovery file name (not in use) ## ## -v Turn verbose logging on for console discovery logging, ## otherwise this script will output information useful ## for SMIT cmd_to_discover (header / values output) ## ## -M add nodes for mutual takeover (requires the user to enter ## two nodes, and discovery must have two nodes discovered) ## ## -A add nodes for add a single instance, must have one instance ## discovered, and only one node can be entered. ## ## -N diable summary reporting, this flag only has meaning if ## used in combination with the -v flag. ## ## ## RETURN: ## 0 on success ## 1 or higher on failure ## ## ## Internal Functions: ## ## run_discovery ## prevalidation ## dump_discovery_info ## check_db2_software_levels ## ## KLIB Functions: ## ## KLIB_DB2_disc_get_instance_value ## ## KLIB_UTIL_word_count ## KLIB_UTIL_LIST_unique_key_list ## KLIB_UTIL_LIST_hasharray_datadumper ## ## KLIB_AIX_get_fs_freespace ## ## KLIB_HACMP_is_known_node ## KLIB_HACMP_discover_nodes ## ##---------------------------------------------------------------------------- . /usr/es/lib/ksh93/func_include version='1.10' function run_discovery { typeset -n nodelist=$1 typeset -n flags=$2 typeset filename=$3 unset PID2NODE typeset -A PID2NODE for node in $nodelist; do address=$(clgetaddr $node) # If we were unable to contact the node, abort discovery [[ -z $address ]] && { echo echo abort 10 $node } if [[ -n "$DSE_INSTALL_DIR" ]]; then cl_rsh $node $DB2SA_BIN_DIR/cl_db2discovery $flags -p $DSE_INSTALL_DIR > $DB2_ETC_PATH/$node.$$ 2>/dev/null & else cl_rsh $node $DB2SA_BIN_DIR/cl_db2discovery $flags > $DB2_ETC_PATH/$node.$$ 2>/dev/null & fi RC=$? PID=$! PIDS="$PIDS $PID" PID2NODE[$PID]=$node done # # Wait for discovery to complete on all available nodes # typeset -i count=0 for pid in $PIDS; do typeset alive=$(/bin/ps -ef | grep $pid | grep -v grep) while [[ -n $alive ]]; do alive=$(/bin/ps -ef | grep $pid | grep -v grep) $VERBOSE && print -n "." sleep 4 (( count=$count + 1 )) # If we've waiting for 2 minutes for this node, then abort discovery just on this node # its likely that the other nodes have already completed. (( $count == 30 )) && alive="ENDTHIS" done done if $FLUSH_DISCOVERY_FILE && [[ -f $filename ]]; then rm -f $filename fi # # Append the discovery information to the local discovery file # for node in $nodelist; do echo "CLUSTER_NODE=\"$node\"" >> $filename cat $DB2_ETC_PATH/$node.$$ >> $filename rm -f $DB2_ETC_PATH/$node.$$ done return 0 } # # Name: prevalidation # # Description: This script will validate the various components of DB2 # to ensure the DB2 instance meets the following criteria # # 1. DB2 Instance Home Directory Must reside on a filesystem # that is on shared storage (shared VG) # # 2. The node must have DB2 installed either 8.1 or 8.2 # # 3. Shared volume groups must be accessible on all nodes # where a particular instance might reside in the cluster # This requires all hdisks for the instance VG(s) to exist # on all participating nodes. # # 4. DB2 Instance Users & Groups must be consistent across # the participating nodes in the cluster. The UID & GIDs # must be identical across all participating nodes. # # Arguments: None # # Returns: calls abort, and exits this script with an errorcode == dspmsg # number # function prevalidation { # Check to ensure the software levels of all the DB2 discovered # instances are running at the same levels, abort and report # the error if the level is incorrect # check_db2_software_levels if (( $? != 0 )); then abort 5 fi # Check to ensure we have at least one DB2 instance available for # the user to select from if [[ -z $DB2_INSTANCES ]]; then echo abort 6 !DISCOVERY_NODES fi } # # Name: rewrite_discovery_file # # Description: This function rewrites the discovery file, joining # current discovery data together from all of the nodes # specified to this command. # # Arguments: None # # Returns: None # function dump_discovery_info { typeset DATE typeset key typeset instance typeset NEW_INST_LIST typeset insthome DATE=$(date +"%m/%d/%y %H:%M:%S") echo "#\n# This ksh93 source file was generated on $DATE" echo "# Do NOT alter the content of this file\n#" # # Remove those instances that don't have available collected information # for instance in $DB2_INSTANCES; do insthome=$(KLIB_DB2_disc_get_instance_value $instance "INSTHOME") if [[ -n $insthome ]]; then NEW_INST_LIST="$NEW_INST_LIST $instance" fi done DB2_INSTANCES=$NEW_INST_LIST # # Remove duplicate instance keys from DB2_INSTANCES # KLIB_UTIL_LIST_unique_key_list DB2_INSTANCES $DB2_INSTANCES # Iterate over all the variables that start with DB2 for key in ${!DB2*}; do # # Remove duplicate nodes from the list of nodes in the nodes # for each instance array. # if [[ ${key:0:10} == "DB2_NODES_" ]]; then typeset -n array=$key KLIB_UTIL_LIST_unique_key_list array $array fi # # If the variable is not an instance associative array, # then print out the value # if [[ "${key:0:13}" != "DB2_INSTANCE_" && "${key:0:11}" != "DB2_ERRORS_" ]]; then echo "$key=\"$(eval echo \$$key)\"" fi done # Dump each of the DB2 instance gathered from the nodes # the last copy will overwrite the pre-existing copy for instance in $DB2_INSTANCES; do KLIB_UTIL_LIST_hasharray_datadumper "DB2_INSTANCE_$instance" done # Dump the volume group info from lspv from all cluster nodes # into one hash table AIX_DISKS # Save off the old discovery info typeset -A AIX_DISKS_OLD for key in ${!AIX_DISKS[*]}; do AIX_DISKS_OLD[$key]="${AIX_DISKS[$key]}" done unset AIX_DISKS typeset -A AIX_DISKS for variable in ${!AIX_DISKS_*}; do typeset -n disks=$variable for key in ${!disks[*]}; do AIX_DISKS[$key]="${disks[$key]}" done unset disks done # Dump the list of AIX_DISKS generated above for all # discovered instances KLIB_UTIL_LIST_hasharray_datadumper AIX_DISKS # Dump the DB2_ERRORS that occurred during the prevalidation phase KLIB_UTIL_LIST_hasharray_datadumper DB2_ERRORS } # # Name: check_db2_software_levels # # Description: Check the discovered software levels on all of the instances # discovered. This verifies that all instances are running # the same software level of DB2. Verify and sync will validate # that each node in the cluster runs the same level of DB2 software. # # Arguments: None (uses the discovery information sourced into our environment) # # Returns: 0 - if successfully validated same levels of DB2 on all nodes # 1 - if unsuccessful # function check_db2_software_levels { typeset instance typeset tmpLevel typeset level='' for instance in $DB2_INSTANCES; do tmpLevel=$(KLIB_DB2_disc_get_instance_value $instance "SOFTWARE_LEVEL") if [[ -z $level ]]; then level=$tmpLevel fi if [[ "$level" != "$tmpLevel" ]]; then return 1 fi done return 0 } ######### # MAIN ######### # Read in the message catalog entries . /usr/es/sbin/cluster/sa/db2/cat/cl_db2smadd # Read in the init functions, abort, require, errmsg, etc. . /usr/es/lib/ksh93/common_functions.ksh93 # Read in the DB2 definitions . /usr/es/sbin/cluster/sa/db2/etc/db2_definitions umask -S u=rw,g=,o= # Set the FPATH for all DB2 / HACMP functions FLIB=/usr/es/lib/ksh93 FPATH=$FLIB/utils:$FLIB/hacmp:$FLIB/db2:$FLIB/db2/vg:$FLIB/util:$FLIB/util/list:$FLIB/aix/:$FLIB/aix/odm/ PATH=$PATH:/usr/es/sbin/cluster/sa/db2/sbin/:/usr/es/sbin/cluster/utilities/:/usr/es/sbin/cluster/ DB2SA_BIN_DIR=/usr/es/sbin/cluster/sa/db2/sbin MUTUAL_TAKEOVER=false typeset -i MAXNODES=32 typeset -i MINNODES=1 DB2_ETC_PATH=/usr/es/sbin/cluster/sa/db2/etc DISCOVERY_FILE=$DB2_ETC_PATH/db2.disc FLUSH_DISCOVERY_FILE=false VERBOSE=false DISC_FLAGS= RUN_DISCOVERY=true SUMMARY_REPORTING=true typeset -i ncount=0 while getopts vDAMcFNf:n:m option do case $option in v) VERBOSE=true DISC_FLAGS=-v RUN_DISCOVERY=true ;; D) VERBOSE_LOGGING=high ;; F) FLUSH_DISCOVERY_FILE=true ;; f) DISCOVERY_FILE=$OPTARG ;; n) DISCOVERY_NODES=$(echo $OPTARG | sed -e "s/\:/ /g") for node in $DISCOVERY_NODES; do (( ncount=$ncount+1 )) done ;; A) # -A tells us we're adding a single instance, only one # node should be specified. ACTION=add_single MINNODES=1 MAXNODES=1 ;; M) # -M tells us the user is performing a SMIT mutual takeover # add ACTION=mutual_takeover MINNODES=2 MAXNODES=2 ;; N) # Disable summary reporting, default is enabled SUMMARY_REPORTING=false ;; m) DISC_FLAGS="$DISC_FLAGS -q" ;; esac done [[ "$VERBOSE_LOGGING" == "high" ]] && set -x # Verifiy there is sufficient space (4MB) in the following filesystems # /var, /usr, /tmp prior to allowing the user to run this command typeset -i SF for fs in /tmp /var /usr; do SF=$(KLIB_AIX_get_fs_freespace $fs) (( $SF < 4 )) && abort 11 $fs $SF done # # If the user is attempting to add too many nodes or too few # abort # if (( $ncount > $MAXNODES || $ncount < $MINNODES )); then if (( $MINNODES == $MAXNODES )); then abort 1 $MINNODES else nodes_present=false odmget HACMPnode | while read line; do nodes_present=true done $nodes_present && abort 2 $MINNODES $MAXNODES !DISCOVERY_NODES $nodes_present || abort 12 fi fi # # Check each cluster node name against the current cluster configuration, # if we find that a specified node isn't in the list, assume its a communication # path and use clmodclstr to add the node to the cluster configuration. # for node in $DISCOVERY_NODES; do KLIB_HACMP_is_known_node $node RC=$? # If we don't know this node, run discovery if (( $RC != 0 )); then RUN_DISCOVERY=true break fi done $RUN_DISCOVERY || { typeset -i inst_count=0 # Determine the number of currently defined instances DB2_INSTANCES=$(cl_db2smdisc -i) # Count the number of instances discovered KLIB_UTIL_word_count inst_count $DB2_INSTANCES # If the number of currently discovered DB2 instances is less than # 2 and we're attempting to configure mutual takeover, run discovery [[ "$ACTION" == "mutual_takeover" ]] && (( $inst_count < 2 )) && RUN_DISCOVERY=true # If the number of discovered instances is less than 1, then run discovery # if the user is attempting to add a new instance to the HACMP configuration # [[ "$ACTION" == "add_single" ]] && (( $inst_count < 1 )) && RUN_DISCOVERY=true # If there are no DB2 instances discovered, run discovery (( $inst_count == 0 )) && RUN_DISCOVERY=true } CLUSTER_NODES=$(KLIB_HACMP_discover_nodes $DB2_DEFAULT_CLUSTER_NAME DISCOVERY_NODES) # # If we were unable to add one or more specified nodes, or the list of nodes # provided didn't exist in the cluster configuration then report an error # if (( ${#CLUSTER_NODES[@]} == 0 || ${#CLUSTER_NODES[@]} != ${#DISCOVERY_NODES[@]} )); then abort 3 DISCOVERY_NODES fi $RUN_DISCOVERY && { $VERBOSE && errmsg 8 !DISCOVERY_NODES run_discovery DISCOVERY_NODES DISC_FLAGS $DISCOVERY_FILE } # # Source the discovery info into our environment, then # redump the discovery info back into the discovery file # this removes duplicate entries # [[ -f $DISCOVERY_FILE ]] && . $DISCOVERY_FILE dump_discovery_info > $DISCOVERY_FILE # Perform validation on the accessible instances prevalidation instances=$(cl_db2smdisc -i) if [[ -z $instances ]]; then abort 4 fi KLIB_UTIL_word_count inst_count $instances KLIB_UTIL_word_count node_count $CLUSTER_NODES $VERBOSE && { echo echo instances=$(eval echo $instances) errmsg 9 !instances $inst_count !CLUSTER_NODES } # If there are an insufficient number of instances for the number # of nodes specified (mutual takeover requires 2 instances) # then abort and report an error # if [[ "$ACTION" == "mutual_takeover" ]]; then if (( $inst_count < 2 )); then abort 7 fi fi # If verbose logging is enabled, and summary if $VERBOSE; then # # If summary reporting is enabled, then print a summary of # each DB2 instance as its been discovered. # $SUMMARY_REPORTING && { for instance in $DB2_INSTANCES; do cl_db2smdisc -s $instance done } else echo "#firstnode:takeovernode" echo $CLUSTER_NODES | read first rest echo "$first:$rest" fi exit 0