#!/usr/bin/perl # IBM_PROLOG_BEGIN_TAG # This is an automatically generated prolog. # # # # Licensed Materials - Property of IBM # # (C) COPYRIGHT International Business Machines Corp. 2001,2019 # 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 # # sccsid = "@(#)14 1.12 src/rsct/cfg_access/cfgmgr/ct_topology_info.perl, cfg.access, rsct_rady, rady2035a 11/12/15 16:43:38" # # Usage: ct_topology_info [-l] [-w] # -l to get the data from the local repository (no-use) # -w to set the data to the repository (input from stdin) # This will give the topology info use Getopt::Std; my %opts = (); &getopts(':lw',\%opts); my $mmsetting=(defined($opts{w}) ? 1 : 0); $RSCTBIN="/opt/rsct/bin"; $CHCOMG = "/opt/rsct/bin/chcomg"; ($dir,$progname) = $0 =~ /(.*\/)?(.*)/; # get basename of $0 # # ValidKeys: list of all acceptable keys (either canset or not). # In other words, the input keys must be in the list. # Otherwise, an error will be issued. $NON_SETTABLE = 0; $SETTABLE = 1; %ValidKeys = ( "NETWORK_NAME" => $NON_SETTABLE, "NETWORK_TYPE" => $NON_SETTABLE, "NETWORK_FREQ" => $SETTABLE, "NETWORK_GRACE" => $SETTABLE, "NETWORK_SENS" => $SETTABLE, "NETWORK_NIM_EXEC" => $SETTABLE, "NETWORK_NIM_PAR" => $SETTABLE, "NETWORK_SRC_ROUTING" => $SETTABLE, "NETWORK_BCAST" => $SETTABLE, "NETWORK_USE_FOR_NODE_MEMBERSHIP" => $SETTABLE, "ADAPTER" => $NON_SETTABLE, "NON_IP_INTERFACE" => $NON_SETTABLE ); # main starts here if($mmsetting) { #write the data to the repository &set_data_to_repository(); } else { my $outcnt = &get_data_from_repository(); if($outcnt == 0) { # No output &print_errmsg("EMSG107 $progname"); exit(1); } } exit(0); #-------- functions ----------------------------------- # print_dbgmsg(list) sub print_dbgmsg { my @args = @_; if(!defined($ccal_log_inited)) { my $outfile = $ENV{"HA_CCAL_LOG"}; $ccal_log_inited = 0; if(defined($outfile) && open(LOGOUT, ">>$outfile")) { $ccal_log_inited = 1; select LOGOUT; $| = 1; # unbuffered select STDOUT; } } if($ccal_log_inited) { my $dstr = scalar(localtime); my $msg = "$dstr $progname: " . join(" ", @args); print LOGOUT $msg, "\n" ; } } sub print_errmsg { $msgcmd = "$RSCTBIN/hadspmsg cfgaccess ha_com.cat ". join(" ",@_); system($msgcmd); } #----------------------------------------------------- # GET DATA from the repository sub get_data_from_repository { $CLSTNAME=`$RSCTBIN/ct_clusterinfo -c`; chomp($CLSTNAME); # chop '\n' if exists if( !defined($CLSTNAME) || $CLSTNAME eq "" ) { # No cluster name found. &print_errmsg("EMSG105 $progname $CLSTNAME"); exit(1); } $got_instance_number = 0; # not instance number obtained yet # get the topology_info file name $topology_info=$ENV{'CT_TOPOLOGY_INFO_FILE'}; if( !defined($topology_info) || ($topology_info eq "") ) { $topology_info="/var/ct/$CLSTNAME/cfg/machine.lst"; if( ! -e $topology_info) { $topology_info="/var/ct/$CLSTNAME/cfg/topology.info"; } } if(!open(TOPOCFG,$topology_info)) { # Error on opening $topology_info &print_errmsg("EMSG108 $progname $topology_info"); exit(1); } # read TOPOLCFG local(@topoContents) = ; close TOPOCFG; local($net_started) = 0; local($net_name)=""; my $network_type; foreach $topoLine (@topoContents) { chomp($topoLine); # chop '\n' &print_dbgmsg("$topoLine"); my(@tks) = split(" ", $topoLine); # separate ' =' if( $tks[0] eq "Network" && $tks[1] eq "Name" ) { $net_started = 1; $net_name = $tks[2]; $freq_value = 0; print "NETWORK_NAME $net_name\n"; } elsif( $tks[0] eq "NETWORK_NAME" ) { $net_started = 1; $net_name = $tks[1]; print "NETWORK_NAME $net_name\n"; } elsif($tks[0] eq "Network" && $tks[1] eq "Type") { print "NETWORK_TYPE $tks[2]\n"; $network_type = $tks[2]; } elsif($tks[0] =~ /\*InstanceNumber/) { @tks = split("=", $topoLine); if($tks[0] eq "*InstanceNumber") { print "CONFIG_INST $tks[1]\n"; $got_instance_number = 1; } else { # ignore } } elsif($net_started && ($tks[0] =~ /\*!TS_/ || $tks[0] =~ /\*!NIM_/) ) { @tks = split("=", $topoLine); if($tks[0] eq "*!TS_Frequency") { # stage value of frequency, since we may get it in 2 pieces: # TS_Frequency and TS_FrequencyFraction $freq_value = $tks[1]; } elsif($tks[0] eq "*!TS_FrequencyFraction") { $freq_value += $tks[1] / 1000000; } elsif($tks[0] eq "*!TS_Sensitivity") { # by now we should have got a value for the frequency. So # print that before printing the value of the sensitivity print "NETWORK_FREQ $freq_value\n"; print "NETWORK_SENS $tks[1]\n"; } elsif($tks[0] eq "*!TS_PingGracePeriodMilliSec") { # 148964: grace period is in millisec in the machines.lst file # but in (potentially fractional) secs in the output of # ct_topology_info if($tks[1] != -1) { $grace_val = $tks[1] / 1000; } else { $grace_val = $tks[1]; } print "NETWORK_GRACE $grace_val\n"; } elsif($tks[0] eq "*!NIM_Src_Routing") { print "NETWORK_SRC_ROUTING $tks[1]\n"; } elsif($tks[0] eq "*!NIM_Broadcast") { print "NETWORK_BCAST $tks[1]\n"; } elsif($tks[0] eq "*!TS_UseForNodeMembership") { print "NETWORK_USE_FOR_NODE_MEMBERSHIP $tks[1]\n"; } } elsif($net_started && $tks[0] =~ /^[0-9]/) { if ("diskhb" eq $network_type) { print "NON_IP_INTERFACE $tks[2] $tks[1] $tks[0] $net_name\n"; } else { print "ADAPTER $tks[2] $tks[1] $tks[0] $net_name\n"; } } elsif( ($tks[0] eq "NETWORK_TYPE") || ($tks[0] eq "CONFIG_INST") || ($tks[0] eq "NETWORK_FREQ") || ($tks[0] eq "NETWORK_SENS") || ($tks[0] eq "NETWORK_GRACE") || ($tks[0] eq "NETWORK_SRC_ROUTING") || ($tks[0] eq "NETWORK_BCAST") || ($tks[0] eq "NETWORK_NIM_EXEC") || ($tks[0] eq "NETWORK_NIM_PAR") || ($tks[0] eq "NETWORK_USE_FOR_NODE_MEMBERSHIP") || ($tks[0] eq "ADAPTER") || ($tks[0] eq "NON_IP_INTERFACE") ) { # print joined @tks to remove white blanks print join(" ",@tks), "\n"; } else { # ignore } } return 1; # many lines } # SET DATA to the repository sub set_data_to_repository { my $count = 0; my %kvFields = (); my @fields; my ($key, $val, $canset); my $netname = ""; my $mmInStr=""; my $kvStr = ""; my @mmInList = (); while( ) { @fields = split " "; # split input $key = $fields[0]; $val = join(" ",@fields[1..$#fields]); next if(!defined($key) || ($key eq "") || ($key =~ /^#/)); $key = uc $key; # upper case $canset = $ValidKeys{$key}; if(defined($canset)) { if($key eq "NETWORK_NAME") { #flush the current saved paramters if(scalar(@mmInList) > 0 && $netname ne "") { # update the network info $mmInStr = join(" ",@mmInList); `$CHCOMG $mmInStr $netname`; $rc = $?; &print_dbgmsg("Update: $CHCOMG $mmInStr $netname rc=$rc"); $count++; } #new network starts @mmInList = (); # make it empty $netname = $val; } elsif($key eq "NETWORK_FREQ") { $kvStr = "-p $val"; push @mmInList, ( $kvStr ); } elsif($key eq "NETWORK_SENS") { $kvStr = "-s $val"; push @mmInList, ( $kvStr ); } elsif($key eq "NETWORK_GRACE") { # use -g option of chcomg. Value '-1' is special, and requires # the use of the -g d option if($val == -1) { $kvStr = "-g d"; } else { $kvStr = "-g $val"; } push @mmInList, ( $kvStr ); } elsif($key eq "NETWORK_NIM_EXEC") { $kvStr = "-n \"$val\""; push @mmInList, ( $kvStr ); } elsif($key eq "NETWORK_NIM_PAR") { $kvStr = "-m \"$val\""; push @mmInList, ( $kvStr ); } elsif($key eq "NETWORK_SRC_ROUTING") { if( $val eq "0" ) { $kvStr = "-x r"; } else { $kvStr = "-r"; } push @mmInList, ( $kvStr ); } elsif($key eq "NETWORK_BCAST") { if( $val eq "0" ) { $kvStr = "-x b"; } else { $kvStr = "-b"; } push @mmInList, ( $kvStr ); } elsif ($key eq "NETWORK_USE_FOR_NODE_MEMBERSHIP") { if ( $val eq "0" ) { $kvStr = "-N 0"; } else { $kvStr = "-N 1"; } push @mmInList, ( $kvStr ); } else { &print_dbgmsg("Unsettable field: $key $val"); } } else { # not defined...unknown key &print_dbgmsg("Unknown field: $key $val"); } } #flush the current saved paramters if(scalar(@mmInList) > 0 && $netname ne "") { # update the network info $mmInStr = join(" ",@mmInList); `$CHCOMG $mmInStr $netname`; $rc = $?; &print_dbgmsg("Update: $CHCOMG $mmInStr $netname rc=$rc"); if($rc != 0) { # error in chcomg (probably no quorum): exit with # error. An error msg will have been produced by # chcomg. exit(1); } $count++; } return $count; }