#!/bin/ksh # 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/events/clinfo.rc.sh 1.24.1.1 # # Licensed Materials - Property of IBM # # COPYRIGHT International Business Machines Corp. 1990,2013 # 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/events/clinfo.rc.sh, 726, 2147A_aha726, Feb 05 2021 09:50 PM ############################################################################## # This shell script may run either on cluster nodes or on client systems # that are running the clinfo daemon. The shell script is invoked by # the clinfo daemon in response to certain cluster events. See the clinfo.rc # man page for documentation of the parameters passed to the shell script and # the events that will cause it to be invoked. # # Please note that cluster nodes must be running the clinfo daemon in order # for this shell script to be invoked automatically in response to cluster # events. # # The local ARP cache on clients not running clinfo can be updated by # pinging the client from a cluster node. Add the IP label or IP address of # clients you want to notify to the PING_CLIENT_LIST, or to a similar # shell variable in /etc/cluster/ping_client_list. # # All addresses in the ping client list must be on the same logical subnet as # some cluster node service address for their ARP caches to be updated. # Please note that IP routers are, in some sense, clients of the # cluster, and their IP addresses should be added to PING_CLIENT_LIST, but # only if they are on the same logical subnet as a cluster node. # # Those addresses that are not on the same logical subnet as another # service address will still be pinged, but this operation will not # update their ARP cache entry for the cluster node service address, and may # generate unnecessary network traffic and script processing. ############################################################################## # # Example: # # PING_CLIENT_LIST="host_a host_b 1.1.1.3" # PING_CLIENT_LIST="" TOTAL_CLIENT_LIST="${PING_CLIENT_LIST}" if [[ -s /etc/cluster/ping_client_list ]] ; then # # The file "/etc/cluster/ping_client_list" should contain only a line # setting the variable "PING_CLIENT_LIST" in the form given # in the example above. This allows the client list to be # kept in a file that is not altered when maintenance is # applied to clinfo.rc. # . /etc/cluster/ping_client_list TOTAL_CLIENT_LIST="${TOTAL_CLIENT_LIST} ${PING_CLIENT_LIST}" fi # # WARNING!!! For this shell script to work properly, ALL entries in # the TOTAL_CLIENT_LIST must resolve properly to IP addresses or hostnames # (must be found in /etc/hosts, DNS, or NIS). This is crucial. # # Implementation notes: # # 1. When clinfo spawns multiple copies of clinfo.rc (one for each interface # whose status has changed) as it usually does, standard out from all copies # is directed to file /var/hacmp/log/clinfo.rc.out. As a result, this file # can be corrupted. This shell script has been implemented such that, when # logging is enabled by uncommenting the line that defines the logfile # environment variable, it synchronizes execution with all other copies of # itself and prevents the /var/hacmp/log/clinfo.rc.out file from becoming # corrupted. # PROGNAME=${0##*/} export PATH="$(/usr/es/sbin/cluster/utilities/cl_get_path all)" [[ "$VERBOSE_LOGGING" = "high" ]] && { set -x version='%I%' } # # Get name of this shell script and parameters passed to it # scrname=$(basename ${0}) event=$1 # Event that occurred (join, fail, or swap) label=$2 # Service adapter IP label for which event occurred if [ -z "$label" ] then print -u2 "$scrname: Second parameter is null!" echo "$scrname: Second parameter is null!" >/dev/console errlogger "$scrname: Second parameter is null!" exit 1 fi cllsif -Sn $label | \ read adaptername adaprole adapnet nettype pubpriv adapnode adapipaddr rest # # these network types are no longer supported but they can show up in # the config for a short time during migration, so we leave the check in place # if [ "$nettype" = "rs232" -o "$nettype" = "tmscsi" -o "$nettype" = "tmssa" -o "$nettype" = "diskhb" -o "$nettype" = "diskhbmulti" ] then exit 0; fi # # Define useful variables # outfile=/var/hacmp/log/$scrname.out # Log captured each time clinfo.rc runs # # Uncomment the following line to enable logging. Please note that the # resulting /var/hacmp/log/clinfo.rc.log file will grow without limit and # must be periodically pruned to avoid filling up the /var filesystem. # This may be helpful if for some reason the arp cache on # non-clinfo clients is not updated to reflect the new adapter # hardware address after a takeover event has occurred. # # # If logging is enabled, log start and wait for our turn to run # if [ -n "$logfile" ] then echo "$(date +"%b %d at %T"): $scrname invoked with parms $*." >>$logfile # # Wait until we are child process with smallest process ID number # while true do sleep 1 # Let all children get started or wait for one to finish ps -eo pid,ppid,args | grep $PPID | sort -nrk1 | \ while read pid ppid args do if [ $ppid != $PPID ] then continue fi echo "$args" | read shell shcmd rest if [ $shcmd != $0 ] then if [ $pid = $$ ] then echo "Process $pid (child of $ppid) is running shell script $shcmd, not $0!" >>$logfile else echo "Ignoring process $pid (child of $ppid) running command '$args'." >>$logfile continue fi fi lastpid=$pid done if [ "$lastpid" = $$ ] then break # We are child process with smallest process ID number fi done echo "$(date +"%b %d at %T"): $scrname running with parms $*." >>$logfile cp /dev/null $outfile # Prune log file fi # # Uncomment to turn on debugging. # #set -x # # If clgetif is executable, then the # cluster.es.server.utils fileset is installed, and we can assume we are # running on a cluster node. # if [ -x /usr/es/sbin/cluster/utilities/clgetif ] then # # Get affected adapter's IP address, role, and subnet mask # cllsif -Sn $label | \ read adaptername adaprole adapnet nettype pubpriv adapnode adapipaddr rest if [ "$pubpriv" = "serial" ] then exit 0; fi netmask=$(clgetif -n $adapipaddr 2>/dev/null) # # If netmask is not null (so affected adapter is on our system) and # if adapter is a service adapter, then ping clients # if [ -n "$netmask" ] && [ "$adaprole" = "service" ] then # # Get address of network affected adapter is on and get adapter interface # adapnetwork=$(clgetnet $adapipaddr $netmask) interface=$(clgetif -a $adapipaddr 2>/dev/null) # # Ping clients that are on the same logical subnet as the affected adapter # for host in $TOTAL_CLIENT_LIST do # # Get IP address associated with client host name # clientipaddr=$(host $host) if [ $? -eq 1 ] then print -u2 "ERROR: Client $host cannot be resolved." echo "ERROR: Client $host cannot be resolved." >/dev/console errlogger "Client $host: cannot be resolved." continue; fi clientipaddr=${clientipaddr%%,*} clientipaddr=${clientipaddr##* } # # Get address of network client is on # clientnetwork=$(clgetnet $clientipaddr $netmask) # # If affected adapter and client are not on same network, # just ping the client # if [ "$adapnetwork" != "$clientnetwork" ] then echo "client $host is not on the same subnet as affected adapter" ping -c1 $host continue fi # # If affected adapter ip address is in TOTAL_CLIENT_LIST, skip this # client. With ATM this is unavoidable because on a failover the local # service address needs to be pinged by the newly failed over service # address in which case the adapter ip address will be different. # However when cluster services are started or a node is reintegrated # then the following case will be true. # if [ $adapipaddr = $clientipaddr ] then echo "IP addr $adapipaddr is on local interface $interface. Skipping." continue fi # # Add temporary route so ping flows through affected adapter # route add -host $clientipaddr -interface $adapipaddr # # Delete any ARP cache entry for the client, including any "hip-pocket" # entries kept in the network interfaces # arp -d $clientipaddr # # Ping the client twice # echo "Pinging client $host..." ping -c2 $host # # Remove temporary route # route delete -host $clientipaddr -interface $adapipaddr done # # If logging is enabled, append log file to clinfo.rc log file. # if [ -n "$logfile" ] then cat $outfile >>$logfile fi # # Affected IP address is on our system, so there is nothing more to be done. # exit 0 fi fi # # If control reaches this point, we are on a system that either does not have # the cluster.es.server.utils fileset installed or does not have the # affected IP address assigned to a network interface, so all we need to do is # flush the ARP cache. While there is no need to ping anything as long as ARP # cache is flushed, this logic has been retained solely for compatibility with # prior releases. # # # Delete ARP cache entry for affected host # # WARNING!!! For the logic below to work properly on clinfo clients, the # service adapter IP label passed as the second parameter to this shell script # must resolve properly to an IP address on this host (must be found in # /etc/hosts, DNS, or NIS). # arp -d $label # # Ping all hosts in TOTAL_CLIENT_LIST # Note that this is not necessary in order to update the client's arp # cache, as flushing the arp cache has already been done to force an # arp cahe update. This logic has been retained solely for compatibility # with prior releases. # for host in $TOTAL_CLIENT_LIST do echo "Ping client $host once..." ping -c1 $host done # # If logging is enabled, append log file to clinfo.rc log file. # if [ -n "$logfile" ] then cat $outfile >>$logfile fi