#!/bin/ksh # IBM_PROLOG_BEGIN_TAG # This is an automatically generated prolog. # # 61haes_r721 src/43haes/usr/sbin/cluster/utilities/cldump.sh 1.26.2.3 # # Licensed Materials - Property of IBM # # COPYRIGHT International Business Machines Corp. 2003,2016 # 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 # @(#)60 1.26.2.3 src/43haes/usr/sbin/cluster/utilities/cldump.sh, hacmp.utils, 61haes_r721, 1607A_hacmp721 1/28/16 18:13:31 ############################################################################### # # COMPONENT_NAME: UTILITIES # # FUNCTIONS: usage # cldump # print_address_info # print_address_info6 # print_network_info # print_node_info # print_cluster_info # ############################################################################### # # Name: cldump # # Dumps the state of the cluster via the clstrmgr, HA's snmp smux agent # # Arguments: None # # Returns: 0 on success # 1 on failure # # Environment: # ############################################################################### ############################################################################### # # Name: get_formatted_ip_address # # Returns the formatted ip(v4/v6) addresses. The formatted entries for # ip addresses are not available in MIBs. Hence a transformation from "raw" # ip entries to "formatted" addresses is necessary. Example: # 20:08:00:00:00:00:00:00:00:00:00:00:00:00:00:01 => 2008::1 # 00:00:00:0a:00:00:01:00:00:00:00:a3:bc:a0:00:00 => ::a:0:100:0:a3:bca0:0 # c0:a8:01:05 => 192.168.1.5 # # Arguments: (Refer 'src/43haes/usr/sbin/cluster/clsmuxpd/hacmp.my' for a # detailed listing of the 'enum' of inet family supported) # inet_family: 1 = AF_INET, 2 = AF_INET6 # # Returns: Formatted ip address # # # Environment: # ############################################################################### get_formatted_ip_address() { typeset PS4_FUNC="get_formatted_ip_address" [[ "$VERBOSE_LOGGING" = "high" ]] && set -x inet_family="$1" unformatted_addr="$2" case $inet_family in 1) formatted_addr=$(echo $unformatted_addr | awk -F: '{\ dNum=("0x" $1)+0; \ ip=dNum; \ for(i=2;i<=NF;i++) \ {\ dNum=("0x" $i)+0; ip=ip "." dNum;\ }\ } END {print ip}') ;; 2) #The objective of this parsing is to replace four digit #group '0000' with two colons ('::') as long as #only one double colon appears in the address. #'flag' maintains the state while parsing: # state 0: No '0000' found. '::' isn't placed in the o/p yet. # state 1: '0000' found. Skip until non zero octet found. # state 2: '0000' found and replaced by '::'. formatted_addr=$(echo $unformatted_addr | awk -F: '{ dNum=("0x" $1 $2)+0; xNum=sprintf("%x", dNum); if(int(dNum)) ip=xNum; else flag = 1; for(i=3;i<=NF;i+=2) { dNum=("0x" $i $(i+1))+0; xNum=sprintf("%x", dNum); if(int(dNum)) { if(flag == 1) { ip=ip ":" ":" xNum; flag = 2; } else ip=ip ":" xNum; } else if(flag == 2) ip=ip ":" xNum; else flag=1; } } END { if(flag==1) print ip "::"; else print ip; }') ;; esac echo $formatted_addr } ############################################################################### # # Name: usage # # This routine displays the usage message for the cldump utility, # then exits. # # Arguments: none # Usage: usage # Returns: 1 - exit with error # Environment: # ############################################################################### usage() { typeset PS4_FUNC="usage" dspmsg scripts.cat 10603 "Usage: $PROGNAME [-h]\n" 1>&2 exit 1 } ############################################################################### # # Name: smux_error # # This routine checks for an error code and exists if found # # Arguments: Return Code, Return Value # Usage: smux_error return_code return_value # Returns: 0 - if return code is 0 AND return_value is not empty # Exits if error # Environment: # # # ############################################################################### smux_error() { typeset PS4_FUNC="smux_error" [[ "$VERBOSE_LOGGING" = "high" ]] && set -x RC="$1" RV="$2" # If there is a smux/snmp error, exit if [[ $RC -ne 0 || -z $RV ]] then dspmsg scripts.cat 9622 "\n$PROGNAME: Error obtaining information via SNMP. Exiting.\n" $PROGNAME 1>&2 exit 1 fi } ############################################################################### # # Name: print_address_info # # Prints the address information for the node and network given in the # environment # # Arguments: none # # Usage: print_address_info # # Returns: 0 Success # 1 Failure # # Environment: # ############################################################################### print_address_info() { typeset PS4_FUNC="print_address_info" [[ "$VERBOSE_LOGGING" = "high" ]] && set -x # Get key (IP addresses) from MIB addresses=$(echo "$ADDRESS_MIB_FUNC" | grep -w "$ADDRESS_IP.$node_id"| uniq | sort | cut -f3 -d" ") # Get the active Node for each IP address for address in $addresses do address_net_id=$(echo "$ADDRESS_MIB_FUNC" | grep -w "$ADDRESS_NET.$node_id.$address" | cut -f3 -d" ") if [[ "$PRINT_IP_ADDRESS" = "true" ]] then formatted_address=$(echo "$address" | awk '{printf "%-15s", $1}') else formatted_address=" " fi if [[ "$address_net_id" = "$net_id" ]] then active_node=$(echo "$ADDRESS_MIB_FUNC" | grep -w "$ADDRESS_ACTIVE_NODE.$node_id.$address" | cut -f3 -d" ") if [[ "$active_node" = $node_id ]] then address_label=$(echo "$ADDRESS_MIB_FUNC" | grep -w "$ADDRESS_LABEL.$node_id.$address" | cut -f2 -d\") address_state=$(echo "$ADDRESS_MIB_FUNC" | grep -w "$ADDRESS_STATE.$node_id.$address" | cut -f3 -d" ") formatted_label=$(echo "$address_label" | awk '{printf "%-18s", $1}') dspmsg scripts.cat 9610 " Address: $formatted_address Label: $formatted_label State: " "$formatted_address" "$formatted_label" case $address_state in 2) dspmsg scripts.cat 9601 "UP\n" ;; 4) dspmsg scripts.cat 9602 "DOWN\n" ;; 8) dspmsg scripts.cat 9603 "UNKNOWN\n" ;; esac fi fi done } ############################################################################### # # Name: print_address_info6 # # Prints the address information for the node and network given in the # environment, this an upgrated function of "print_address_info". # used to print address6 mib entres and only used for cluster version 10 # and above. # # Arguments: none # # Usage: print_address_info6 # # Returns: 0 Success # 1 Failure # # Environment: # ############################################################################### print_address_info6() { typeset PS4_FUNC="print_address_info6" [[ "$VERBOSE_LOGGING" = "high" ]] && set -x # Get key (IP addresses) from MIB addresses=$(echo "$ADDRESS_MIB_FUNC" | grep -w "$ADDRESS6_IP.$node_id"| uniq | sort | awk -F"($ADDRESS6_IP.$node_id.)|=" '{print $2}') # Get the active Node for each IP address for address in $addresses do address_net_id=$(echo "$ADDRESS_MIB_FUNC" | grep -w "$ADDRESS6_NET.$node_id.$address" | cut -f3 -d" ") if [[ "$PRINT_IP_ADDRESS" = "true" ]] then ip_address=$(echo "$ADDRESS_MIB_FUNC" | grep -w "$ADDRESS6_IP.$node_id.$address" | cut -f3 -d" ") inet_family=$(echo "$address" | awk -F. '{print $1}') formatted_address=$(get_formatted_ip_address $inet_family $ip_address) formatted_address=$(echo "$formatted_address" | awk '{printf "%-15s", $1}') else formatted_address=" " fi if [[ "$address_net_id" = "$net_id" ]] then active_node=$(echo "$ADDRESS_MIB_FUNC" | grep -w "$ADDRESS6_ACTIVE_NODE.$node_id.$address" | cut -f3 -d" ") if [[ "$active_node" = $node_id ]] then address_label=$(echo "$ADDRESS_MIB_FUNC" | grep -w "$ADDRESS6_LABEL.$node_id.$address" | cut -f2 -d\") address_state=$(echo "$ADDRESS_MIB_FUNC" | grep -w "$ADDRESS6_STATE.$node_id.$address" | cut -f3 -d" ") formatted_label=$(echo "$address_label" | awk '{printf "%-18s", $1}') dspmsg scripts.cat 9610 " Address: $formatted_address Label: $formatted_label State: " "$formatted_address" "$formatted_label" case $address_state in 2) dspmsg scripts.cat 9601 "UP\n" ;; 4) dspmsg scripts.cat 9602 "DOWN\n" ;; 8) dspmsg scripts.cat 9603 "UNKNOWN\n" ;; esac fi fi done } ############################################################################### # # Name: print_network_info # # Prints the network information for the node given in the environment # # Arguments: none # # Usage: print_network_info # # Returns: 0 Success # 1 Failure # # Environment: # ############################################################################### print_network_info() { typeset PS4_FUNC="print_network_info" [[ "$VERBOSE_LOGGING" = "high" ]] && set -x # Get network IDs network_ids=$(echo "$NETWORK_MIB_FUNC" | grep -w "$NETWORK_ID.$node_id" | cut -f3 -d" " | uniq | sort -n ) # Get states for these networks on this node for net_id in $network_ids do network_name=$(echo "$NETWORK_MIB_FUNC" | grep -w "$NETWORK_NAME.$node_id.$net_id" | cut -f2 -d\") network_attribute=$(echo "$NETWORK_MIB_FUNC" | grep -w "$NETWORK_ATTRIBUTE.$node_id.$net_id" | cut -f3 -d" ") network_state=$(echo "$NETWORK_MIB_FUNC" | grep -w "$NETWORK_STATE.$node_id.$net_id" | cut -f3 -d" ") formatted_network_name=$(echo "$network_name" | awk '{printf "%-18s", $1}') echo "" dspmsg scripts.cat 9611 " Network Name: $formatted_network_name State: " "$formatted_network_name" case $network_state in 2) dspmsg scripts.cat 9601 "UP\n" ;; 4) dspmsg scripts.cat 9602 "DOWN\n" ;; 32) dspmsg scripts.cat 9604 "JOINING\n" ;; 64) dspmsg scripts.cat 9605 "LEAVING\n" ;; esac echo "" PRINT_IP_ADDRESS="true" # If serial type network, then don't attempt to print IP Address [[ $network_attribute -eq 4 ]] && PRINT_IP_ADDRESS="false" # Mixed version cluster # since, ADDRESS6 is new MIB group that was introduced from HACMP550 onwards # ADDRESS6 info is used only if the cluster version 10 and above. if [[ $MIXVER -lt 10 ]] then print_address_info else print_address_info6 fi done } ############################################################################### # # Name: print_node_info # # Prints the node information for each node found in the MIB # # Arguments: none # # Usage: print_node_info # # Returns: 0 Success # 1 Failure # # # Environment: # ############################################################################### print_node_info() { typeset PS4_FUNC="print_node_info" [[ "$VERBOSE_LOGGING" = "high" ]] && set -x NODE_ID_COUNTER=0 while [[ $cluster_num_nodes -ne 0 ]] do # Get node information for each node node_id=$(echo "$NODE_MIB" | grep -w "$NODE_ID.$NODE_ID_COUNTER" | cut -f3 -d " ") let NODE_ID_COUNTER=NODE_ID_COUNTER+1 # Node ids may not be contiguous if [[ -z "$node_id" ]] then continue fi node_state=$(echo "$NODE_MIB" | grep -w "$NODE_STATE.$node_id" | cut -f3 -d" ") node_num_if=$(echo "$NODE_MIB" | grep -w "$NODE_NUM_IF.$node_id" | cut -f3 -d" ") node_name=$(echo "$NODE_MIB" | grep -w "$NODE_NAME.$node_id" | cut -f2 -d\") formatted_node_name=$(echo "$node_name" | awk '{printf "%-20s", $1}') echo "" dspmsg scripts.cat 9612 "Node Name: $formatted_node_name State: " "$formatted_node_name" case $node_state in 2) dspmsg scripts.cat 9601 "UP\n" ;; 4) dspmsg scripts.cat 9602 "DOWN\n" ;; 32) dspmsg scripts.cat 9604 "JOINING\n" ;; 64) dspmsg scripts.cat 9605 "LEAVING\n" ;; esac NETWORK_MIB_FUNC=$(echo "$NETWORK_MIB" | grep -w "$NETWORK_BRANCH\..\.$node_id") # Mixed version cluster # since, ADDRESS6 is new MIB group that was introduced from HACMP550 onwards # ADDRESS6 info is used only if the cluster version 10 and above. if [[ $MIXVER -lt 10 ]] then ADDRESS_MIB_FUNC=$(echo "$ADDRESS_MIB" | grep -w "$ADDRESS_BRANCH\..\{1,2\}\.$node_id") else ADDRESS_MIB_FUNC=$(echo "$ADDRESS_MIB" | grep -w "$ADDRESS6_BRANCH\..\{1,2\}\.$node_id") fi print_network_info let cluster_num_nodes=cluster_num_nodes-1 done } ############################################################################### # # Name: print_cluster_info # # Prints the cluster information for the cluster found in the MIB of which # this node is a member. # # Arguments: none # # Usage: print_cluster_info # # Returns: 0 Success # 1 Failure # # Environment: # ############################################################################### print_cluster_info() { typeset PS4_FUNC="print_cluster_info" [[ "$VERBOSE_LOGGING" = "high" ]] && set -x echo "" dspmsg scripts.cat 9615 "Obtaining information via SNMP from Node: $ACTIVE_NODE...\n" $ACTIVE_NODE echo "" cluster_name=$(echo "$CLUSTER_MIB" | grep -w "$CLUSTER_NAME\.0" | cut -f2 -d\") echo "_____________________________________________________________________________" dspmsg scripts.cat 9616 "Cluster Name: $cluster_name\n" $cluster_name cluster_state=$(echo "$CLUSTER_MIB" | grep -w "$CLUSTER_STATE\.0" | cut -f3 -d" ") dspmsg scripts.cat 9617 "Cluster State: " case $cluster_state in 2) dspmsg scripts.cat 9601 "UP\n" ;; 4) dspmsg scripts.cat 9602 "DOWN\n" ;; esac cluster_substate=$(echo "$CLUSTER_MIB" | grep -w "$CLUSTER_SUBSTATE\.0" | cut -f3 -d" ") dspmsg scripts.cat 9618 "Cluster Substate: " case $cluster_substate in 4) dspmsg scripts.cat 9602 "DOWN\n" ;; 8) dspmsg scripts.cat 9603 "UNKNOWN\n" ;; 16) dspmsg scripts.cat 9606 "UNSTABLE\n" ;; 2 | 32) dspmsg scripts.cat 9607 "STABLE\n" ;; 64) dspmsg scripts.cat 9608 "ERROR\n" ;; 128) dspmsg scripts.cat 9609 "RECONFIG\n" ;; esac cluster_num_nodes=$(echo "$CLUSTER_MIB" | grep -w "$CLUSTER_NUM_NODES\.0" | cut -f3 -d" ") echo "_____________________________________________________________________________" print_node_info } ############################################################################### # Main starts here ############################################################################### PROGNAME=$(basename ${0}) export PATH=$(/usr/es/sbin/cluster/utilities/cl_get_path all) eval export $(cllsparam -x) [[ "$VERBOSE_LOGGING" = "high" ]] && set -x [[ "$VERBOSE_LOGGING" = "high" ]] && version='1.26.2.3 $Source: 61haes_r711 43haes/usr/sbin/cluster/utilities/cldump.sh 1$' HA_DIR="$(cl_get_path)" helpFileName="/usr/es/sbin/cluster/etc/clstat_cldump.help" #--------------------------------------------- # - use getopts to gather command line options #--------------------------------------------- while getopts "h" optionName do case "$optionName" in h) #------------------------- # - if help file exists # - cat the help file # else # - indicate an error #------------------------- if [ -f "$helpFileName" ] then cat "$helpFileName" if [ $? = 0 ] then exit 0 else exit 1 fi else dspmsg scripts.cat 10604 "\n\nThe %s help file could not be opened.\n\n" $helpFileName exit 1 fi ;; *) #-------------------------------------- # - call the usage function to generate # the Usage statement and exit #-------------------------------------- usage ;; esac done DCD="/etc/${HA_DIR}/objrepos" SCD="/usr/${HA_DIR}/sbin/cluster/etc/objrepos/stage" ACD="/usr/${HA_DIR}/sbin/cluster/etc/objrepos/active" # set up some global variables with SNMP branch info # # cluster CLUSTER_BRANCH="1.3.6.1.4.1.2.3.1.2.1.5.1" CLUSTER_NAME="$CLUSTER_BRANCH.2" CLUSTER_STATE="$CLUSTER_BRANCH.4" CLUSTER_SUBSTATE="$CLUSTER_BRANCH.8" CLUSTER_NUM_NODES="$CLUSTER_BRANCH.11" # node NODE_BRANCH="1.3.6.1.4.1.2.3.1.2.1.5.2.1.1" NODE_ID="$NODE_BRANCH.1" NODE_STATE="$NODE_BRANCH.2" NODE_NUM_IF="$NODE_BRANCH.3" NODE_NAME="$NODE_BRANCH.4" # network NETWORK_BRANCH="1.3.6.1.4.1.2.3.1.2.1.5.4.1.1" NETWORK_ID="$NETWORK_BRANCH.2" NETWORK_NAME="$NETWORK_BRANCH.3" NETWORK_ATTRIBUTE="$NETWORK_BRANCH.4" NETWORK_STATE="$NETWORK_BRANCH.5" # address6 ADDRESS6_BRANCH="1.3.6.1.4.1.2.3.1.2.1.5.13.1.1" ADDRESS6_IP="$ADDRESS6_BRANCH.4" ADDRESS6_LABEL="$ADDRESS6_BRANCH.6" ADDRESS6_NET="$ADDRESS6_BRANCH.8" ADDRESS6_STATE="$ADDRESS6_BRANCH.9" ADDRESS6_ACTIVE_NODE="$ADDRESS6_BRANCH.10" # address ADDRESS_BRANCH="1.3.6.1.4.1.2.3.1.2.1.5.3.1.1" ADDRESS_IP="$ADDRESS_BRANCH.2" ADDRESS_LABEL="$ADDRESS_BRANCH.3" ADDRESS_NET="$ADDRESS_BRANCH.5" ADDRESS_STATE="$ADDRESS_BRANCH.6" ADDRESS_ACTIVE_NODE="$ADDRESS_BRANCH.7" # Check the runtime level MIXVER=`/usr/es/sbin/cluster/utilities/clmixver` RGINFO="/usr/es/sbin/cluster/utilities/clRGinfo -v" FOUND="false" # Use local snmp smux agent, csltrmgr, if available CLSMUXAGENT_ACTIVE=`LC_ALL=C lssrc -ls clstrmgrES | egrep "Current state" | egrep -v "ST_INIT|NOT_CONFIGURED"` if [[ -n "$CLSMUXAGENT_ACTIVE" ]] then # Save local node name. LOCALNODENAME=`ODMDIR=$ACD get_local_nodename` if [[ -z "$LOCALNODENAME" ]] then dspmsg scripts.cat 9619 "\n$PROGNAME: Unable to discover the name of the local node.\n\ Please check the cluster configuration.\n" $PROGNAME 1>&2 exit 1 fi FOUND_NODES=$LOCALNODENAME FOUND="true" else # Use any active clstrmgr. Note the ACD may not exist, or be invalid, so use DCD NODES=`ODMDIR=$DCD odmget HACMPnode | fgrep name | awk -F \" {'print$2'} | sort | uniq` # Ensure at least one node is defined in the DCD if [ -z "$NODES" ] then dspmsg scripts.cat 9619 "\n$PROGNAME: Unable to discover the name of the local node.\n\ Please check the cluster configuration.\n" $PROGNAME 1>&2 exit 1 fi for node in $NODES do FOUND_NODES=`clgetactivenodes -n $node` RC="$?" if [[ $RC -gt 0 && $RC -lt 254 ]] then FOUND="true" break fi done fi # Exit if no active node is found if [[ "$FOUND" = "true" ]] then ACTIVE_NODE=`echo $FOUND_NODES | cut -f1 -d" "` else dspmsg scripts.cat 9620 "\n$PROGNAME: Unable to determine any nodes with active cluster services.\n" $PROGNAME 1>&2 exit 1 fi # Gather info from active node. Obtain only what # is needed, so as not to exceed the environment limit GET_MIB_INFO="/usr/sbin/cluster/utilities/clrexec $ACTIVE_NODE SNMPINFO" # Ensure the clstrmgr can return information before continuing RETRY=10 CLUSTER_MIB=`$GET_MIB_INFO cluster` RC="$?" if [[ $RC -ne 0 || -z $CLUSTER_MIB || $CLUSTER_MIB = "No response" ]] then dspmsg scripts.cat 9679 "\n$PROGNAME: Waiting for the Cluster SMUX peer (clstrmgrES)\n\ to stabilize..." $PROGNAME while [[ ($RC -ne 0 || -z $CLUSTER_MIB || $CLUSTER_MIB = "No response") && $RETRY -gt 0 ]] do sleep 3 echo ".\c" RETRY=`expr $RETRY - 1` CLUSTER_MIB=`$GET_MIB_INFO cluster` RC="$?" done echo "" # if we make it through that loop and still have no info, quit if [[ $RC -ne 0 || -z $CLUSTER_MIB || $CLUSTER_MIB = "No response" ]] then dspmsg utilities.cat 125 "Failed retrieving cluster information.\n\n\ There are a number of possible causes:\n\ clinfoES or snmpd subsystems are not active.\n\ snmp is unresponsive.\n\ snmp is not configured correctly.\n\ Cluster services are not active on any nodes.\n\n\ Refer to the HACMP Administration Guide for more information.\n" 1>&2 exit 1 fi fi NODE_MIB=`$GET_MIB_INFO node` smux_error $? $NODE_MIB NETWORK_MIB=`$GET_MIB_INFO network` smux_error $? $NETWORK_MIB # Mixed version cluster # since, ADDRESS6 is new MIB group that was introduced from HACMP550 onwards # ADDRESS6 info is used only if the cluster version 10 and above. if [[ $MIXVER -lt 10 ]] then ADDRESS_MIB=`$GET_MIB_INFO address` else ADDRESS_MIB=`$GET_MIB_INFO address6` fi smux_error $? $ADDRESS_MIB # Print Topology Information print_cluster_info # Print Resource Group Information # Ensure at least one resource group is defined in the DCD RGS=`ODMDIR=$DCD odmget HACMPgroup` if [[ -n "$RGS" ]] then echo "" cl_rsh $ACTIVE_NODE $RGINFO fi exit 0