[prev in list] [next in list] [prev in thread] [next in thread]
List: aix-l
Subject: Re: p570 LPARs and PCI Slot Assignments
From: Robert Binkley <leebinkley () YAHOO ! COM>
Date: 2004-12-30 19:26:58
Message-ID: 20041230192659.20585.qmail () web54402 ! mail ! yahoo ! com
[Download RAW message or body]
SYNTAX:
lparLsCfgsIO.pl [-o <outFile>] [-hmc <hmcHost>] [-u
<hmcUser>]
[-m <managedSys>] [-h]
where
<outFile> : File to store its output
<hmcHost> : Hostname of the HMC
<hmcUser> : Login-name on the HMC which was
setup
for unattended remote ssh command
execution
<managedSys>: Name of the Managed System (SMP).
See HMC Operations Guide for more
details.
-h : Prints this syntax help; cannot be used with
other flags.
E.g.: lparLsCfgsIO.pl -o outFile -hmc p5hmc -u hscroot
-m Power5
[para@drgrm:/opt/dlparToolset/bin] . setEnv.p570
#############################################
# PURPOSE: To set up environment variables before
using the DLPAR Toolset,
# for ksh or sh users.
# TO INVOKE from ksh or sh, type: . ./setEnv
# If the subdirectory containing this file
is in your PATH,
# then you only need to type: . setEnv
# TO VIEW settings, type: env | grep
DR_
# COMPANION file: unsetEnv
# COMPONENT OF: IBM pSeries DLPAR Toolset 2.0.2.0,
September 2004.
# COPYRIGHT: IBM Corporation, 2002,2003,2004. All
rights reserved.
# Author: Joefon Jann 2003/3/31.
# Last updated: 2004/8/31.
export DR_REMOTE_SHELL=rsh # To connect
to AIX hosts (rsh or ssh)
export DR_TS_DIR=/opt/dlparToolset/bin
export DR_HMC_HOST=curie.watson.ibm.com
export DR_HMC_USER=hscroot
export DR_MANAGED_SYS=p570Curie
export DR_HOST_LIST=$DR_TS_DIR/hostList.p570 # Used
in directories 1,2,5
# For lparLsCfgs.pl:
export DR_OUTFILE_LSCFG=~/lparLsCfgs.outFile
# For lparLsCfgsAll.pl:
export DR_OUTFILE_LSCFG_ALL=~/lparLsCfgsAll.outFile
# For lparLsCfgsIO.pl:
export DR_OUTFILE_LSCFG_IO=~/lparLsCfgsIO.outFile
# For lparLsCfgs.pl:
export DR_INTVLSECS_LSLOAD=2 # Seconds.
export DR_HISTCNT_LSLOAD=5 # Number of historical
snapshots.
export DR_HISTOUT_LSLOAD=~/lparLsLoads.histOut
# For lparLoadRM.pl:
export DR_HOSTS_WTS=$DR_TS_DIR/hostsWts.p570 #
Defines an LPAR group.
export DR_INTVLSECS_LOADRM=4 # Seconds.
export DR_HISTCNT_LOADRM=5 # Number of historical
snapshots.
export DR_TRGR_CPU_LOAD=98 # Integer Percentage of
non-idle CPU time.
export DR_TRGR_RQ_DEPTH=1 # Integer Number of
threads/CPU/sec waiting
# for CPU
service.
export DR_TRGR_MEM_LOAD=85 # Integer Percentage of
non-free real memory.
export DR_TRGR_PGSTEALS=0 # Integer Number of
page-steals/LMB/sec.
# For moveSlot.pl:
export DR_IO_SLOT=21020003 # For Pwr4 systems, set
this to the PhysicalLocation
# attribute of an IO
slot.
# For Pwr5 systems, set
this to a DRC Index.
# Other environment variables that may be rarely
changed:
export DR_RSVD_FREP_CPUS=0
# Reserved CPUs in the Free Pool. This number of CPUs
will always be left in
# the Free Pool of the SMP by the lparLoadRM.pl and
lparSetCfgs.pl scripts.
# To disable the use of the CPUs in the Free Pool by
lparLoadRM.pl or
# lparSetCfgs.pl, specify a value that is greater
than or equal
# to the total number of CPUs in the SMP, e.g.
99999
export DR_RSVD_FREP_LMBS=0
# Reserved LMBs in the Free Pool. This number of LMBs
will always be left in
# the Free Pool of the SMP by the lparLoadRM.pl and
lparSetCfgs.pl scripts.
# To disable the use of the LMBs in the Free Pool by
lparLoadRM.pl or
# lparSetCfgs.pl, specify a value which is greater
than or equal
# to the total number of LMBs in the SMP, e.g.
99999
export DR_DEBUG_LVL=0
# Debug level to be used by "chhwres" command.
# Possible values are integers from 0 to 5,
indicating
# minimal to maximal amounts of debug info
respectively.
# To display the sorted values on the screen:
env | grep DR_ | sort
###
#! /usr/bin/perl
# PURPOSE: To print the min, current, and max #CPUs
and #LMBs of a list of LPARs
# with hostnames are given in a
customer-provided hostList file.
# SYNTAX:
# lparLsCfgs.pl [-o <outFile>] [-f <hostList>]
# [-hmc <hmcHost>] [-u <hmcUser>] [-m
<managedSys>] [-h]
# See subroutine syntax() for the details.
#
# COMPONENT OF: IBM pSeries DLPAR Toolset 2.0.2.0,
September 2004.
# COPYRIGHT: IBM Corporation, 2002,2003,2004. All
rights reserved.
# SUBROUTINES IN THIS FILE
# main
# 1 read_arguments
# 2 syntax
# 3 check_hmc
# 4 check_managed_system_p4hmc
# 5 check_managed_system_p5hmc
# 6 get_lpar_info
# 7 get_lpar_info_p4hmc
# 8 get_lpar_info_p4hmc
# 9 read_hostlist
# 10 check_lpar
# 11 get_current_config
# 12 get_current_config_p4hmc
# 13 get_current_config_p5hmc
#
# AUTHORs: Yorktown team: J. Jann, R. Burugula, N.
Dubey 9/2002
# CHANGELOG: Last updated 2004/08/24.
@hmc_lpars=(); # Array of LPAR names of all the
LPARs of the input <managedSys>
# as reported by the HMC.
@aix_lpars=(); # Array of LPAR names of LPARs with
the following features.
# - The associated hostName is
found in <hostList>,
# - The associated host is running
AIX as an OS.
# - The associated host is
rsh|ssh'able from the current Host.
%aix_hosts=(); # List of hostnames for each
LPAR in @aix_lpars
%dlpar=(); # To check whether the LPAR is
DLPAR'able or not.
$HSC_CMD_PATH = ""; # Needed if restricted bash shell
is not available
$hmc_type = ""; # POWER4 or POWER5 HMC
$hmc_version = ""; # To store Release and Version of
HMC
$hmc_bash = ""; # Restricted or Non-Restricted
Bash Shell
%min_cpus=();# min_cpus for a given lparName, used for
POWER5 HMC only
%cur_cpus=();# cur_cpus for a given lparName, used for
POWER5 HMC only
%max_cpus=();# max_cpus for a given lparName, used for
POWER5 HMC only
%min_lmbs=();# min_lmbs for a given lparName, used for
POWER5 HMC only
%cur_lmbs=();# cur_lmbs for a given lparName, used for
POWER5 HMC only
%max_lmbs=();# max_lmbs for a given lparName, used for
POWER5 HMC only
$free_cpus = 0; # Free CPUs available in the Free
Pool.
$free_lmbs = 0; # Free LMBs available in the Free
Pool.
$lmb_size = 0;
$cur_host_name =`/usr/bin/hostname`;
chomp($cur_host_name);
$cur_host =`/usr/bin/hostname -s `;
chomp($cur_host);
$cur_user = $ENV{"USER"} ;
$lsres = ""; # HMC command lshwres
$lssys = ""; # HMC command lssyscfg
#=============================================================================
# MAIN ROUTINE -- This main routine calls 4
subroutines, which call others.
# A) Read the arguments
&read_arguments(@ARGV);
# B) Check the status of the HMC, the HMC user, and
the Managed System
&check_hmc;
# C) Read the input <hostList> file
print "Reading the file $hostList .....\n";
&read_hostlist;
# D) Getting the current configurations
print "Retrieving the current configuration from
HMC .....\n";
print "NOTE: It takes roughly 30 to 45 seconds to
get the current\n";
print " configuration of each LPAR from the
HMC.\n\n";
&get_current_config;
exit (0);
# 1
--------------------------------------------------------------------------
sub read_arguments
# Parse the input arguments
{
undef $outFile;
undef $hostList;
undef $hmcHost;
undef $hmcUser;
undef $cec;
while (@_)
{
my $option = shift;
if ($option eq "-h")
{
&syntax;
}
elsif ($option eq "-o")
{
$outFile = shift;
}
elsif ($option eq "-f")
{
$hostList = shift;
}
elsif ($option eq "-hmc")
{
$hmcHost = shift;
}
elsif ($option eq "-u")
{
$hmcUser = shift;
}
elsif ($option eq "-m")
{
$cec = shift;
}
else
{
&syntax;
}
}
if ((! defined $outFile) && (defined
$ENV{"DR_OUTFILE_LSCFG"}))
{
$outFile = $ENV{"DR_OUTFILE_LSCFG"};
}
if ((! defined $hostList) && (defined
$ENV{"DR_HOST_LIST"}))
{
$hostList = $ENV{"DR_HOST_LIST"};
}
if ((! defined $hmcHost) && (defined
$ENV{"DR_HMC_HOST"}))
{
$hmcHost = $ENV{"DR_HMC_HOST"};
}
if ((! defined $hmcUser) && (defined
$ENV{"DR_HMC_USER"}))
{
$hmcUser = $ENV{"DR_HMC_USER"};
}
if ((! defined $cec) && (defined
$ENV{"DR_MANAGED_SYS"}))
{
$cec = $ENV{"DR_MANAGED_SYS"};
}
if (! defined $hostList)
{
print "ERROR: <hostList> file was not
specified.\n";
print " You can specify this as -f
<hostList> argument\n";
print " or as DR_HOST_LIST environment
variable\n";
&syntax;
}
if (! defined $hmcHost)
{
print "ERROR: <hmcHost> was not specified.\n";
print " You can specify this as -hmc
<hmcHost> argument\n";
print " or as DR_HMC_HOST environment
variable\n";
&syntax;
}
if (! defined $hmcUser)
{
print "ERROR: <hmcUser> was not specified.\n";
print " You can specify this as -u
<hmcUser> argument\n";
print " or as DR_HMC_USER environment
variable\n";
&syntax;
}
if (! defined $cec)
{
print "ERROR: <managedSys> was not
specified.\n";
print " You can specify this as -m
<managedSys> argument\n";
print " or as DR_MANAGED_SYS environment
variable\n";
&syntax;
}
if ($ENV{"DR_REMOTE_SHELL"} eq "ssh")
{
$remShell = "ssh";
$remShellCmd = "/usr/bin/ssh"
}
else
{
$remShell = "rsh"; # The default shell
$remShellCmd = "/usr/bin/rsh";
}
# Clear the screen
system "/usr/bin/clear";
printf "This script is being run by user \"%s\" on
host \"%s\".\n",
$cur_user, $cur_host;
print "INPUT:\n";
print " Host list = ",
$hostList, "\n";
print " hmcHost = ",
$hmcHost, "\n";
print " hmcUser = ",
$hmcUser, "\n";
print " Managed System = ", $cec,
"\n";
print " RemoteShell for AIX hosts = ",
$remShell, "\n";
if (defined $outFile)
{
open (FHANDLE, "> $outFile") || die "Cannot
create the file $outFile: $! \n";
print " output File = ",
$outFile, "\n";
}
open (HSTLST, "<", $hostList) or die "Cannot open
$hostList for reading: $!\n";
}
# 2
--------------------------------------------------------------------------
sub syntax
# PURPOSE: Print the syntax of this script
{
print "\nSYNTAX:\n";
print "lparLsCfgs.pl [-o <outFile>] [-f
<hostList>] \n";
print " [-hmc <hmcHost>] [-u
<hmcUser>] [-m <managedSys>] [-h]\n";
print " where \n";
print " <outFile> : File to store its
output\n";
print " <hostList> : File containing hostnames
of the LPAR group.\n";
print " \n";
print " <hmcHost> : Hostname of the HMC\n";
print " <hmcUser> : Login-name on the HMC
which was setup\n";
print " for unattended remote ssh
command execution\n";
print " <managedSys>: Name of the Managed
System (SMP).\n";
print " See HMC Operations Guide
for more details.\n";
print " -h : Prints this syntax help; cannot be
used with other flags.\n";
print "E.g.: $0 -o outFile -f hostList -hmc
hmc.mydomain.com -u grm_ssh -m DR\n\n";
exit;
}
# 3
--------------------------------------------------------------------------
sub check_hmc
# PURPOSE: To check the status of the HMC, the HMC SSH
user, and the Managed System.
{
# Check whether HMC is up or not
printf "\nChecking ping and ssh to %s.....\n",
$hmcHost;
system "/usr/sbin/ping $hmcHost 1 1 2>/dev/null
1>&2";
if ( $? != 0)
{
printf "The hmcHost \"%s\" is not ping'able
!\n", $hmcHost;
exit (1);
}
system "/usr/bin/ssh $hmcUser\@$hmcHost date
2>/dev/null 1>&2";
if ( $? != 0)
{
print "SSH connection from $cur_user\@$cur_host to
$hmcUser\@$hmcHost failed!\n";
exit (1);
}
# Check if the restricted bash shell is set.
my $hmcInfo =`/usr/bin/ssh $hmcUser\@$hmcHost "
lshmc -v " 2>&1`;
if ( $hmcInfo =~ /bash:/ ) # If restricted shell
is not set.
{
$HSC_CMD_PATH = "/opt/hsc/bin/";
$hmc_bash = "Non-Restricted Bash shell";
$hmcInfo = `/usr/bin/ssh $hmcUser\@$hmcHost "
${HSC_CMD_PATH}lshmc -v " 2>&1`;
}
else
{
$hmc_bash = "Restricted Bash shell";
}
my @tmpHmc = split (/\n/,$hmcInfo);
for (my $i=0; $i <= $#tmpHmc; $i++)
{
if ($tmpHmc[$i] =~ /RM\s+(\S+)/)
{
$hmc_version = $1;
}
}
chomp($hmc_version);
# Check the HMC Type
if ($hmc_version =~ /V(\d)/)
{
if ($1 le "3")
{
$hmc_type = "POWER4 HMC";
}
else # i.e. if ($1 eq "4" )
{
$hmc_type = "POWER5 HMC";
}
}
print "HMC Commands are running under $hmc_bash on
$hmc_type ($hmc_version).....\n";
$lssys = "/usr/bin/ssh $hmcUser\@$hmcHost
${HSC_CMD_PATH}lssyscfg -m $cec";
$lsres = "/usr/bin/ssh $hmcUser\@$hmcHost
${HSC_CMD_PATH}lshwres -m $cec";
if ( $hmc_type eq "POWER4 HMC")
{
if (&check_managed_system_p4hmc != 0) #If the
managed system is not operating.
{
exit (1);
}
}
else
{
if (&check_managed_system_p5hmc != 0) #If the
managed system is not operating.
{
exit (1);
}
}
&get_lpar_info;
}
# 4
--------------------------------------------------------------------------
sub check_managed_system_p4hmc
# PURPOSE: Check managed system on POWER5 HMC
{
if ( $hmc_version ge "R3V2.4") # Only if the HMC
has Release and Version >= R3V2.4
{
my $cmd = "";
$cmd = "$lssys -r sys --all -Fname:state:lmb_size |";
open (TEMPCMD, $cmd);
while($line = <TEMPCMD>)
{
chomp($line);
my ($sysName, $sysState, $lmbSize)=
split(/:/,$line);
if ($sysName eq $cec)
{
if ( $sysState eq Ready )
{
close (TEMPCMD);
$lmb_size =$lmbSize;
return (0);
}
printf "The managed system \"%s\" is not in the
\"Ready\" state!\n", $cec;
close (TEMPCMD);
return (-1);
}
}
print "The HMC command \"lssyscfg\" does not show
$cec as a \"Ready\" managed system!\n";
close (TEMPCMD);
return (-1);
}
else
{
my $cecstr = "";
$cecstr = `/usr/bin/ssh $hmcUser\@$hmcHost "
${HSC_CMD_PATH}get_cec_state -m $cec " 2>&1`;
chomp($cecstr);
# Check if the Managed System is not in the Ready
state.
if ( !($cecstr =~ /Ready/) )
{
print "The HMC command \"
${HSC_CMD_PATH}get_cec_state\" does not show";
print " $cec as a \"Ready\" managed system!\n";
return (-1);
}
$lmb_size = 256;
return (0);
}
}
# 5
--------------------------------------------------------------------------
sub check_managed_system_p5hmc
# PURPOSE: Check managed system on POWER5 HMC
{
my $cmd = "$lssys -r sys -Fname:state |";
open (TEMPCMD, $cmd);
while($line = <TEMPCMD>)
{
chomp($line);
my ($sysName, $sysState)= split(/:/,$line);
if ($sysName eq $cec)
{
if ( $sysState eq Operating )
{
close (TEMPCMD);
$lmb_size = `$lsres -r mem --level sys
-Fmem_region_size`;
chomp($lmb_size);
return (0);
}
printf "The managed system \"%s\" is not in the
\"Operating\" state!\n", $cec;
close (TEMPCMD);
return (-1);
}
}
print "The HMC command \"lssyscfg\" does not show
$cec as an \"Operating\" managed system!\n";
close (TEMPCMD);
return (-1);
}
# 6
---------------------------------------------------------------------------
sub get_lpar_info
# PURPOSE: Get name, dlpar'ability of LPARs of the
given managed system
{
if ( $hmc_type eq "POWER4 HMC")
{
&get_lpar_info_p4hmc;
}
else
{
&get_lpar_info_p5hmc;
}
}
# 7
---------------------------------------------------------------------------
sub get_lpar_info_p4hmc
# PURPOSE: Get name, dlpar'ability of LPARs of the
given managed system on POWER4 HMC
{
if ( $hmc_version ge "R3V2.4") # Only if the HMC
has Release and Version >= R3V2.4
{
my $cmd = "$lssys -r lpar --all
-Fname:state:dlpar_capability |";
open (TEMPCMD, $cmd);
while($line = <TEMPCMD>)
{
chomp($line);
my ($name, $state, $dr)= split(/:/,$line);
if ( $state eq "Running")
{
push (@hmc_lpars,$name);
$dlpar{$name} = $dr;
}
}
close (TEMPCMD);
}
else
{
# Get the all partition names on HMC for given
<managedSys>
my $lparstr = `/usr/bin/ssh $hmcUser\@$hmcHost "
${HSC_CMD_PATH}query_partition_names -m $cec "
2>/dev/null`;
@hmc_lpars = split (/\n/, $lparstr);
# Remove the first 2 entries, which are
# "Logical Partitions :" and "--------------------"
shift (@hmc_lpars);
shift (@hmc_lpars);
}
}
# 8
---------------------------------------------------------------------------
sub get_lpar_info_p5hmc
# PURPOSE: Get name, dlpar'ability of LPARs of the
given managed system on POWER5 HMC
{
my $cmd = "$lssys -r lpar -Fname:lpar_id:state
|";
my %lpar_id2name=();
open (TEMPCMD, $cmd);
while($line = <TEMPCMD>)
{
chomp($line);
my ($name, $id , $state)= split(/:/,$line);
if ( $state eq "Running")
{
push (@hmc_lpars,$name);
}
$lpar_id2name{$id} = $name;
}
close (TEMPCMD);
# Now check the dlpar'ability
my $part_id ;
my $dcaps;
my $cmd1 = "/usr/bin/ssh $hmcUser\@$hmcHost
lspartition -dlpar |";
open (TEMPCMD1, $cmd1);
while($line = <TEMPCMD1>)
{
chomp($line);
if ($line =~ m/Partition:\<(\d+)\,\s+/)
{
$part_id = $1;
$part_id =~ s/\s+//; # Remove white space
character if any
}
if ($line =~ m/\s*DCaps:\<(\w+)\>\s*/)
{
$dcaps = $1;
$dcaps =~ s/\s+//; # Remove white space
character if any
if ($dcaps =~ /f$/) # Dcaps should 'f' at the
end
{
$dlpar{$lpar_id2name{$part_id}} = "YES"
}
else
{
$dlpar{$lpar_id2name{$part_id}} = "NO"
}
}
}
close (TEMPCMD1);
}
# 9
---------------------------------------------------------------------------
sub read_hostlist
# PURPOSE: To read the <hostList> file &
# to get the hostname & LPARname of each
active LPAR via rsh|ssh.
{
my $lparInfo = "";
my $OSName = "";
my $OSLevel = "";
LOOP1:
while (<HSTLST>)
{
# Skip the comment lines (beginning with '#')
if (/^\#/) { next LOOP1; }
$_ =~ s/\s+/ /g; # Remove extra white space
characters
$_ =~ s/^ //; # Remove the first character
if it is a "space".
# This is required for split function to work
properly.
if (/^ *$/) { next LOOP1; } # Blank line
if (/(\S+)\s*/)
{
my $hosti = $1;
$hosti =~ s/\s+//;
if (($hosti ne $cur_host) && ($hosti ne
$cur_host_name))
{
print "Checking ping and $remShell to
$hosti.....\n";
# Check the ping result to hosti
system "/usr/sbin/ping $hosti 1 1 2>/dev/null 1>&2";
if ( $? != 0)
{
print " The host $hosti is not ping'able!\n";
next;
}
# Check ability to rsh/ssh to hosti
system " $remShellCmd $hosti /usr/bin/date
2>/dev/null 1>&2";
if ( $? != 0)
{
print " The host $hosti is not
$remShell\'able!\n";
next;
}
$OSName = `$remShellCmd $hosti "/usr/bin/uname"
2>/dev/null`;
$lparInfo = `$remShellCmd $hosti "/usr/bin/uname -L"
2>/dev/null`;
$OSLevel = `$remShellCmd $hosti "/usr/bin/oslevel"
2>/dev/null`;
}
else # For the Current Host
{
$OSName = `/usr/bin/uname 2>/dev/null`;
$lparInfo = `/usr/bin/uname -L 2>/dev/null`;
$OSLevel = `/usr/bin/oslevel 2>/dev/null`;
}
# Make sure that the host is running AIX as an
operating system.
chomp($OSName);
if ($OSName ne "AIX") #If NOT AIX Host Name
{
printf " The command \"uname\" shows
that the host %s is not running \"AIX\"!\n", $hosti;
next;
}
# Now make sure that the lpar_name exists
on the given managed system.
chomp($lparInfo);
$lparInfo =~ s/^\s+//;
my ($lparId, $lparName) = split(/
+/,$lparInfo,2);
if (&check_lpar($lparName) != 0) #If
LPAR name does not match
{
printf " Partition name of host %s
does not match partitions managed by HMC!\n", $hosti;
next;
}
push(@aix_lpars, $lparName);
$aix_hosts{$lparName}=$hosti;
if ( ( $hmc_type eq "POWER4 HMC") &&
($hmc_version lt "R3V2.4" ))
{
chomp($OSLevel);
$dlpar{$lparName} =($OSLevel ge
"5.2.0.0") ? "YES" : " NO";
}
}
}
close (HSTLST);
if ($#aix_lpars < 0)
{
print "No $remShell\'able AIX Hosts with valid
LPAR names in $hostList!\n";
exit (-1);
}
}
# 10
---------------------------------------------------------------------------
sub check_lpar
# PURPOSE: To check the validity of the LPAR name for
the given host
{
my ($lparName) = shift;
for ($i=0; $i <= $#hmc_lpars; $i++)
{
if ($hmc_lpars[$i] eq $lparName)
{
return (0);
}
}
return (-1);
}
# 11
---------------------------------------------------------------------------
sub get_current_config
# NOTE: The current configuration should be obtained
only for those
# LPARs which are active (i.e. rsh|ssh'able).
{
if (defined $outFile)
{
open (STDOUT, "| tee $outFile") ;
}
print STDOUT " Hostname LPARname
CPUmin CPUcur CPUmax LMBmin LMBcur LMBmax DLPAR\n";
print STDOUT "============ ==================
====== ====== ====== ====== ====== ====== =====\n";
if ( $hmc_type eq "POWER4 HMC")
{
&get_current_config_p4hmc;
}
else
{
&get_current_config_p5hmc;
}
printf STDOUT "Available (=unreserved) #CPUs in
the Free Pool = %d \n", $free_cpus;
printf STDOUT "Available (=unreserved) #LMBs in
the Free Pool = %d\n", $free_lmbs;
printf STDOUT "NOTE: 1 LMB of Memory = %d MB \n",
$lmb_size;
if (defined $outFile)
{
close (STDOUT);
close (FHANDLE);
}
}
# 12
-------------------------------------------------------------------------
sub get_current_config_p4hmc
# PURPOSE: Get current CPU and Memory configuration on
POWER4 HMC
{
foreach $lpar (@aix_lpars)
{
my $line;
my $cnt=0;
my ($minCpus,$curCpus,$maxCpus);
my ($minLmbs,$curLmbs,$maxLmbs);
my $cmd = "$lsres -r ALL -p $lpar
-Fmin:allocated:max:free -y sys |";
open (TEMPCMD, $cmd);
while($line = <TEMPCMD>)
{
chomp($line);
if ($line =~ m/(\d+):(\d+):(\d+):(\d+)/)
{
$cnt++;
if ($cnt == 1) # CPU configurations
{
($minCpus,$curCpus,$maxCpus,$free_cpus) = split(/:/,
$line);
}
if ($cnt == 2) # Memory
configurations
{
($minLmbs,$curLmbs,$maxLmbs,$free_lmbs) = split(/:/,
$line);
}
}
}
close (TEMPCMD);
printf STDOUT "%-12s %-18s %6d %6d %6d %6d %6d
%6d %5s\n",
substr($aix_hosts{$lpar},0,12),substr($lpar,0,18),
$minCpus, $curCpus, $maxCpus,
$minLmbs, $curLmbs, $maxLmbs, $dlpar{$lpar};
}
}
# 13
-------------------------------------------------------------------------
sub get_current_config_p5hmc
# PURPOSE: Get current CPU and Memory configuration on
POWER5 HMC
{
my $cmd1 = "$lsres -r proc --level lpar
-Flpar_name:curr_min_procs:curr_procs:curr_max_procs
|";
my $cmd2 = "$lsres -r mem --level lpar
-Flpar_name:curr_min_mem:curr_mem:curr_max_mem |";
open (TEMPCMD, $cmd1);
while($line = <TEMPCMD>)
{
chomp($line);
my ($name,$minCpus,$curCpus,$maxCpus) = split(/:/,
$line);
$min_cpus{$name} = $minCpus;
$cur_cpus{$name} = $curCpus;
$max_cpus{$name} = $maxCpus;
}
close (TEMPCMD);
open (TEMPCMD, $cmd2);
while($line = <TEMPCMD>)
{
chomp($line);
my ($name,$minMems,$curMems,$maxMems) = split(/:/,
$line);
$min_lmbs{$name} = $minMems / $lmb_size;
$cur_lmbs{$name} = $curMems / $lmb_size;
$max_lmbs{$name} = $maxMems / $lmb_size;
}
close (TEMPCMD);
foreach $lpar (@aix_lpars)
{
printf STDOUT "%-12s %-18s %6d %6d %6d %6d %6d %6d
%5s\n",
substr($aix_hosts{$lpar},0,12),substr($lpar,0,18),
$min_cpus{$lpar}, $cur_cpus{$lpar},
$max_cpus{$lpar},
$min_lmbs{$lpar}, $cur_lmbs{$lpar},
$max_lmbs{$lpar},$dlpar{$lpar};
}
$free_cpus = `$lsres -r proc --level sys
-Fcurr_avail_sys_proc_units`;
my $freeMems = `$lsres -r mem --level sys
-Fcurr_avail_sys_mem`;
$free_lmbs = $freeMems / $lmb_size;
}
--- Raj Atwal <atwalrs@YAHOO.COM> wrote:
> I had a look at book albeit quickly and I will look
> at it again tonight, but can you be specific of any
> special LPAR PCI assignment rules?
>
> Thanks
>
> JOSEPH KREMBLAS <JKREMBLAS@REDHEARTGIFTS.COM> wrote:
> Raj,
>
> You're consultant is telling you right. You must
> read, study,
> learn, draw pictures, and understand the PLANNING
> guide for the P570.
> The systems are different (for some reason) and you
> will be punished for
> your sins or transgressions if you don't understand
> the rules.
>
> --joseph
>
> -----Original Message-----
> From: IBM AIX Discussion List
> [mailto:aix-l@Princeton.EDU] On Behalf Of
> Raj Atwal
> Sent: Wednesday, December 29, 2004 8:48 AM
> To: aix-l@Princeton.EDU
> Subject: p570 LPARs and PCI Slot Assignments
>
>
> Hi all,
>
> I have two p570s made up of 3 system drawers and 2
> D20s I/O drawers
> each. I am still awaiting delivery of these servers
> but I have began the
> planning of the installs. I will be configuring
> multiple LPARs.
>
> A senior consultant at my company has told me that
> there are special
> rules on p570 regarding PCI Adapter assignments to
> LPARs. I have looked
> at the p570 Technical Guide and many of the p5
> redbooks and I cannot
> find any special rules for the p570 compared to
> other Regatta systems.
>
> I have calculated a total of 32 PCI slot per p570.
> We do not have the
> additinal RIO card, and therefore slot 6 is open on
> the system drawers.
> I calculate 6 PCI slots per system drawer (6*3 =18)
> and 7 PCI slots per
> D20 (7*2 =14), for a total of 32 (18 + 14 =32) . Do
> you concur?
>
> Secon question and more importantly, I believe I
> could carve a single
> LPAR and assign one PCI slot to that single LPAR
> from each of the system
> drawers and each of the D20s (total of 5 PCI-X
> slots) without
> restriction. But this other guy is making me second
> guess myself. Is
> what I am saying correct or are there indeed PCI-X
> assignment
> limitations when using multiple system drawers and a
> couple of D20s?
>
> I look forward to any opinions and experiences. TIA
>
>
> ______________________________
> Raj Atwal
>
> ______________________________
>
>
> Do you Yahoo!?
> Jazz up your holiday email with celebrity designs.
> Learn more.
>
>
> ______________________________
> Raj Atwal
>
> ______________________________
>
> ---------------------------------
> Do you Yahoo!?
> Yahoo! Mail - Helps protect you from nasty viruses.
["lparSetCfgs.pl" (application/octet-stream)]
#! /usr/bin/perl
# PURPOSE: To change the real resources in a given set of LPARs into the target
# configurations as specified in the input <targetCfgs> file.
# SYNTAX:
# lparSetCfgs.pl -f <targetCfgs> [-hmc <hmcHost>]
# [-u <hmcUser>] [-m <managedSys>] [-h]
# See subroutine syntax() for the details.
#
# COMPONENT OF: IBM pSeries DLPAR Toolset 2.0.2.0, September 2004.
# COPYRIGHT: IBM Corporation, 2002,2003,2004. All rights reserved.
#
# SUBROUTINES IN THIS FILE
# main
# 1 read_arguments
# 2 syntax
# 3 check_hmc
# 4 check_managed_system_p4hmc
# 5 check_managed_system_p5hmc
# 6 get_lpar_info
# 7 get_lpar_info_p4hmc
# 8 get_lpar_info_p5hmc
# 9 read_target_config
# 10 check_lpar
# 11 get_current_config
# 12 get_current_config_p4hmc
# 13 get_current_config_p5hmc
# 14 update_target_arrays
# 15 print_target_config
# 16 check_target_config
# 17 generate_commands
# 18 min
# 19 execute_commands
# 20 print_final_config
# 21 get_current_cpus_lmbs
#
# AUTHORS: R.S. Burugula, J. Jann, IBM Yorktown.
# CHANGELOG: 2004/08/24 by Dubey.
# --------------------------------------------------------------------------
@hmc_lpars=(); # Array of LPAR names of all the LPARs of the input <managedSys>
# as reported by the HMC.
@aix_lpars=(); # Array of LPAR names of LPARs with the following features.
# - The associated hostName is found in <targetCfg>,
# - The associated host is running AIX as an OS.
# - The associated host is rsh|ssh'able from the current Host.
%aix_hosts=(); # List of hostnames for each LPAR in @aix_lpars
%dlpar=(); # To check whether the LPAR is DLPAR'able or not.
$HSC_CMD_PATH = ""; # Needed if restricted bash shell is not available
$hmc_type = ""; # POWER4 or POWER5 HMC
$hmc_version = ""; # To store Release and Version of HMC
$hmc_bash = ""; # Restricted or Non-Restricted Bash Shell
@cmds=();
%cur_cpus=(); # Associative arrays to maintain current, minimum and maximum
%min_cpus=(); # number of CPUs for each LPAR. The "key" for all these 3
%max_cpus=(); # arrays is the LPAR name.
%cur_lmbs=(); # Associative arrays to maintain current, minimum and maximum
%min_lmbs=(); # number of LMBs for each LPAR. The "key" for all these 3
%max_lmbs=(); # arrays is the LPAR name.
%tgt_cpus=(); # Associative array containing the desired number of CPUs and
%tgt_lmbs=(); # LMBs for each LPAR. The "key" for both arrays is the LPAR name.
%diff_cpus=(); # Assoc. arrays containing (target value - current value) for
%diff_lmbs=(); # CPUs and LMBs. The key is lpar name. The value can be any
# integer.
$free_cpus=0; # Number of CPUs in the free pool.
$free_lmbs=0; # Number of LMBs in the free pool.
# Reserved resources in the free pool are the resources that are not
# available for DR-adds to the DLPAR group; they are kept aside to
# enable the dynamic Activation of additional LPARs in the future.
$rsvd_freC = 0; # Number of reserved CPUs in the Free pool
$rsvd_freM = 0; # Number of reserved LMBs in the Free pool
# Related enviornment variables are: DR_RSVD_FREP_CPUS, DR_RSVD_FREP_LMBS.
$numNoDLPAR=0; # Number of LPARs that need resource changes but are not
# DLPAR capable (AIX level < 5.2.0.0).
$DEBUG_LVL=0; # Debug level(-d option) for chhwres command. Valid values: 0-5.
$lmb_size = 0;
$cur_host_name =`/usr/bin/hostname`;
chomp($cur_host_name);
$cur_host =`/usr/bin/hostname -s `;
chomp($cur_host);
$cur_user = $ENV{"USER"} ;
$lssys = ""; # HMC command lssyscfg
$lsres = ""; # HMC command lshwres
$chres = ""; # HMC command chhwres
$logFile = "/tmp/$ENV{\"USER\"}.lparSetCfgs.pl.out";
#=============================================================================
# MAIN ROUTINE:
# A) Read the arguments
&read_arguments(@ARGV);
# B) Check the status of the HMC, the HMC user, and the Managed System
&check_hmc;
# C) Read the input <targetCfgs>
print "Reading the Target Configurations from file $targetCfg .....\n";
&read_target_config;
# D) Get the current config.; update & print the target-config arrays.
print "Retrieving the current configuration from HMC .....\n";
print "NOTE: It takes roughly 30 to 45 seconds to get the current\n";
print " configuration of each LPAR from the HMC.\n\n";
&get_current_config;
&update_target_arrays;
&print_target_config;
# E) Check if the transition from the current configurations to the target
# configurations is possible.
print "Checking if the target configurations are possible .....\n";
$rc = &check_target_config;
if ($rc == -1)
{
exit (-1);
}
if ($rc == 1)
{
print "Final Configurations:\n";
print " DLPAR is not required!\n";
if ($numNoDLPAR > 0)
{
print "NOTE: The resources for the LPARs that cannot be dynamically\n";
print " reconfigured (DLPAR != YES) must be changed manually \
\n";
print " using the HMC GUI, and require a reboot of the LPAR. \n";
}
exit (0);
}
# F) Generate the sequence of commands to be executed to reach the target configs
&generate_commands;
# Execute the commands generated above.
print "Changing to the target configurations ..... please wait.\n";
&execute_commands;
close (LOGFILE);
# G) Display the configuration achieved
&print_final_config;
exit (0);
# 1 --------------------------------------------------------------------------
sub read_arguments
# PURPOSE: Parse the input arguments
{
undef $targetCfg;
undef $hmcHost;
undef $hmcUser;
undef $cec;
while (@_)
{
my $option = shift;
if ($option eq "-h")
{
&syntax;
}
elsif ($option eq "-f")
{
$targetCfg = shift; # Target configurations file
}
elsif ($option eq "-hmc")
{
$hmcHost = shift;
}
elsif ($option eq "-u")
{
$hmcUser = shift;
}
elsif ($option eq "-m")
{
$cec = shift;
}
else
{
&syntax;
}
}
if ((! defined $hmcHost) && (defined $ENV{"DR_HMC_HOST"}))
{
$hmcHost = $ENV{"DR_HMC_HOST"};
}
if ((! defined $hmcUser) && (defined $ENV{"DR_HMC_USER"}))
{
$hmcUser = $ENV{"DR_HMC_USER"};
}
if ((! defined $cec) && (defined $ENV{"DR_MANAGED_SYS"}))
{
$cec = $ENV{"DR_MANAGED_SYS"};
}
# The following 3 env. variables do not have corresponding input flags:
if (defined $ENV{"DR_DEBUG_LVL"})
{ $DEBUG_LVL = $ENV{"DR_DEBUG_LVL"};
}
if (defined $ENV{"DR_RSVD_FREP_CPUS"})
{ $rsvd_freC = $ENV{"DR_RSVD_FREP_CPUS"};
}
if (defined $ENV{"DR_RSVD_FREP_LMBS"})
{ $rsvd_freM = $ENV{"DR_RSVD_FREP_LMBS"};
}
if (! defined $targetCfg)
{
print "ERROR: <targetCfgs> file was not specified.\n";
print " You can specify this as -f <targetCfgs> argument\n";
&syntax;
}
if (! defined $hmcHost)
{
print "ERROR: <hmcHost> was not specified.\n";
print " You can specify this as -hmc <hmcHost> argument\n";
print " or as DR_HMC_HOST environment variable\n";
&syntax;
}
if (! defined $hmcUser)
{
print "ERROR: <hmcUser> was not specified.\n";
print " You can specify this as -u <hmcUser> argument\n";
print " or as DR_HMC_USER environment variable\n";
&syntax;
}
if (! defined $cec)
{
print "ERROR: <managedSys> was not specified.\n";
print " You can specify this as -m <managedSys> argument\n";
print " or as DR_MANAGED_SYS environment variable\n";
&syntax;
}
if ($ENV{"DR_REMOTE_SHELL"} eq "ssh")
{
$remShell = "ssh";
$remShellCmd = "/usr/bin/ssh"
}
else
{
$remShell = "rsh"; # The default shell
$remShellCmd = "/usr/bin/rsh";
}
# Clear the screen
system "/usr/bin/clear";
printf "This script is being run by user \"%s\" on host \"%s\".\n",
$cur_user, $cur_host;
print "INPUT:\n";
print " Target configurations file = ", $targetCfg, "\n";
print " hmcHost = ", $hmcHost, "\n";
print " hmcUser = ", $hmcUser, "\n";
print " Managed System = ", $cec, "\n";
print " RemoteShell for AIX hosts = ", $remShell, "\n";
print " Reserved #CPUs in the Free Pool = ", $rsvd_freC, "\n";
print " Reserved #LMBs in the Free Pool = ", $rsvd_freM, "\n";
open (TGTCFG, "<", $targetCfg) or die "Cannot open $targetCfg for reading: $!\n";
# Create a new file to store the output and error messages of the chhwres \
command. open (LOGFILE, "> $logFile") or print "Can not write to file $logFile: $!";
}
# 2 ---------------------------------------------------------------------------
sub syntax
# PURPOSE: To print the syntax of this script
{
print "\nSYNTAX:\n";
print "lparSetCfgs.pl -f <targetCfgs> [-hmc <hmcHost>] \n";
print " [-u <hmcUser>] [-m <managedSys>] [-h]\n";
print " where \n";
print " <targetCfgs>: File containing the desired target LPAR configs.\n";
print " <hmcHost> : Hostname of the HMC\n";
print " <hmcUser> : Login-name on the HMC which was setup\n";
print " for unattended remote ssh command execution\n";
print " <managedSys>: Name of the Managed System (SMP).\n";
print " See HMC Operations Guide for more details.\n";
print " -h : Prints this syntax help; cannot be used with other flags.\n";
print "E.g.: $0 -f targetCfg -hmc hmc.mydomain.com -u grm_ssh -m DR\n\n";
exit;
}
# 3 --------------------------------------------------------------------------
sub check_hmc
# PURPOSE: To check the status of the HMC, the HMC SSH user, and the Managed System.
{
# Check whether HMC is up or not
printf "\nChecking ping and ssh to %s.....\n", $hmcHost;
system "/usr/sbin/ping $hmcHost 1 1 2>/dev/null 1>&2";
if ( $? != 0)
{
printf "The hmcHost \"%s\" is not ping'able !\n", $hmcHost;
exit (1);
}
system "/usr/bin/ssh $hmcUser\@$hmcHost date 2>/dev/null 1>&2";
if ( $? != 0)
{
print "SSH connection from $cur_user\@$cur_host to $hmcUser\@$hmcHost failed!\n";
exit (1);
}
# Check if the restricted bash shell is set.
my $hmcInfo =`/usr/bin/ssh $hmcUser\@$hmcHost " lshmc -v " 2>&1`;
if ( $hmcInfo =~ /bash:/ ) # If restricted shell is not set.
{
$HSC_CMD_PATH = "/opt/hsc/bin/";
$hmc_bash = "Non-Restricted Bash shell";
$hmcInfo = `/usr/bin/ssh $hmcUser\@$hmcHost " ${HSC_CMD_PATH}lshmc -v " 2>&1`;
}
else
{
$hmc_bash = "Restricted Bash shell";
}
my @tmpHmc = split (/\n/,$hmcInfo);
for (my $i=0; $i <= $#tmpHmc; $i++)
{
if ($tmpHmc[$i] =~ /RM\s+(\S+)/)
{
$hmc_version = $1;
}
}
chomp($hmc_version);
# Check the HMC Type
if ($hmc_version =~ /V(\d)/)
{
if ($1 le "3")
{
$hmc_type = "POWER4 HMC";
}
else # i.e. if ($1 eq "4" )
{
$hmc_type = "POWER5 HMC";
}
}
print "HMC Commands are running under $hmc_bash on $hmc_type \
($hmc_version).....\n"; $lssys = "/usr/bin/ssh $hmcUser\@$hmcHost \
${HSC_CMD_PATH}lssyscfg -m $cec"; $lsres = "/usr/bin/ssh $hmcUser\@$hmcHost \
${HSC_CMD_PATH}lshwres -m $cec"; $chres = "/usr/bin/ssh $hmcUser\@$hmcHost \
${HSC_CMD_PATH}chhwres -m $cec -d $DEBUG_LVL";
if ( $hmc_type eq "POWER4 HMC")
{
if (&check_managed_system_p4hmc != 0) #If the managed system is not Ready.
{
exit (1);
}
}
else
{
if (&check_managed_system_p5hmc != 0) #If the managed system is not operating.
{
exit (1);
}
}
&get_lpar_info;
}
# 4 --------------------------------------------------------------------------
sub check_managed_system_p4hmc
# PURPOSE: Check managed system on POWER5 HMC
{
if ( $hmc_version ge "R3V2.4") # Only if the HMC has Release and Version >= \
R3V2.4 {
my $cmd = "";
$cmd = "$lssys -r sys --all -Fname:state:lmb_size |";
open (TEMPCMD, $cmd);
while($line = <TEMPCMD>)
{
chomp($line);
my ($sysName, $sysState, $lmbSize)= split(/:/,$line);
if ($sysName eq $cec)
{
if ( $sysState eq Ready )
{
close (TEMPCMD);
$lmb_size =$lmbSize;
return (0);
}
printf "The managed system \"%s\" is not in the \"Ready\" state!\n", $cec;
close (TEMPCMD);
return (-1);
}
}
print "The HMC command \"lssyscfg\" does not show $cec as a \"Ready\" managed \
system!\n"; close (TEMPCMD);
return (-1);
}
else
{
my $cecstr = "";
$cecstr = `/usr/bin/ssh $hmcUser\@$hmcHost " ${HSC_CMD_PATH}get_cec_state -m $cec " \
2>&1`; chomp($cecstr);
# Check if the Managed System is not in the Ready state.
if ( !($cecstr =~ /Ready/) )
{
print "The HMC command \" ${HSC_CMD_PATH}get_cec_state\" does not show";
print " $cec as a \"Ready\" managed system!\n";
return (-1);
}
$lmb_size = 256;
return (0);
}
}
# 5 --------------------------------------------------------------------------
sub check_managed_system_p5hmc
# PURPOSE: Check managed system on POWER5 HMC
{
my $cmd = "$lssys -r sys -Fname:state |";
open (TEMPCMD, $cmd);
while($line = <TEMPCMD>)
{
chomp($line);
my ($sysName, $sysState)= split(/:/,$line);
if ($sysName eq $cec)
{
if ( $sysState eq Operating )
{
close (TEMPCMD);
$lmb_size = `$lsres -r mem --level sys -Fmem_region_size`;
chomp($lmb_size);
return (0);
}
printf "The managed system \"%s\" is not in the \"Operating\" state!\n", $cec;
close (TEMPCMD);
return (-1);
}
}
print "The HMC command \"lssyscfg\" does not show $cec as an \"Operating\" \
managed system!\n"; close (TEMPCMD);
return (-1);
}
# 6 ---------------------------------------------------------------------------
sub get_lpar_info
# PURPOSE: Get name, dlpar'ability of LPARs of the given managed system
{
if ( $hmc_type eq "POWER4 HMC")
{
&get_lpar_info_p4hmc;
}
else
{
&get_lpar_info_p5hmc;
}
}
# 7 ---------------------------------------------------------------------------
sub get_lpar_info_p4hmc
# PURPOSE: Get name, dlpar'ability of LPARs of the given managed system on POWER4 HMC
{
if ( $hmc_version ge "R3V2.4") # Only if the HMC has Release and Version >= \
R3V2.4 {
my $cmd = "$lssys -r lpar --all -Fname:state:dlpar_capability |";
open (TEMPCMD, $cmd);
while($line = <TEMPCMD>)
{
chomp($line);
my ($name, $state, $dr)= split(/:/,$line);
if ( $state eq "Running")
{
push (@hmc_lpars,$name);
$dlpar{$name} = $dr;
}
}
close (TEMPCMD);
}
else
{
# Get the all partition names on HMC for given <managedSys>
my $lparstr = `/usr/bin/ssh $hmcUser\@$hmcHost " \
${HSC_CMD_PATH}query_partition_names -m $cec " 2>/dev/null`; @hmc_lpars = split \
(/\n/, $lparstr); # Remove the first 2 entries, which are
# "Logical Partitions :" and "--------------------"
shift (@hmc_lpars);
shift (@hmc_lpars);
}
}
# 8 ---------------------------------------------------------------------------
sub get_lpar_info_p5hmc
# PURPOSE: Get name, dlpar'ability of LPARs of the given managed system on POWER5 HMC
{
my $cmd = "$lssys -r lpar -Fname:lpar_id:state |";
my %lpar_id2name=();
open (TEMPCMD, $cmd);
while($line = <TEMPCMD>)
{
chomp($line);
my ($name, $id , $state)= split(/:/,$line);
if ( $state eq "Running")
{
push (@hmc_lpars,$name);
}
$lpar_id2name{$id} = $name;
}
close (TEMPCMD);
# Now check the dlpar'ability
my $part_id ;
my $dcaps;
my $cmd1 = "/usr/bin/ssh $hmcUser\@$hmcHost lspartition -dlpar |";
open (TEMPCMD1, $cmd1);
while($line = <TEMPCMD1>)
{
chomp($line);
if ($line =~ m/Partition:\<(\d+)\,\s+/)
{
$part_id = $1;
$part_id =~ s/\s+//; # Remove white space character if any
}
if ($line =~ m/\s*DCaps:\<(\w+)\>\s*/)
{
$dcaps = $1;
$dcaps =~ s/\s+//; # Remove white space character if any
if ($dcaps =~ /f$/) # Dcaps should 'f' at the end
{
$dlpar{$lpar_id2name{$part_id}} = "YES"
}
else
{
$dlpar{$lpar_id2name{$part_id}} = "NO"
}
}
}
close (TEMPCMD1);
}
# 9 ---------------------------------------------------------------------------
sub read_target_config
# PURPOSE: To read the input target configurations file.
{
my $lparInfo = "";
my $OSName = "";
my $OSLevel = "";
LOOP1:
while (<TGTCFG>)
{
# Skip the comment lines (beginning with '#')
if (/^\#/) { next LOOP1; }
$_ =~ s/\s+/ /g; # Remove extra white space characters
$_ =~ s/^ //; # Remove the first character if it is a "space".
# This is required for split function to work properly.
if (/^ *$/) { next LOOP1; } # Blank line
if (/(\S+)\s*/)
{
# Each line of the input <targetCfgs> file has the format: HostName CPUs LMBs
my ($hosti, $cpu, $lmb) = split(/ /);
if (($hosti ne $cur_host) && ($hosti ne $cur_host_name))
{
print "Checking ping and $remShell to $hosti.....\n";
# Check the ping result to hosti
system "/usr/sbin/ping $hosti 1 1 2>/dev/null 1>&2";
if ( $? != 0)
{
print " The host $hosti is not ping'able!\n";
next;
}
# Check ability to rsh/ssh to hosti
system " $remShellCmd $hosti /usr/bin/date 2>/dev/null 1>&2";
if ( $? != 0)
{
print " The host $hosti is not $remShell\'able!\n";
next;
}
$OSName = `$remShellCmd $hosti "/usr/bin/uname" 2>/dev/null`;
$lparInfo = `$remShellCmd $hosti "/usr/bin/uname -L" 2>/dev/null`;
$OSLevel = `$remShellCmd $hosti "/usr/bin/oslevel" 2>/dev/null`;
}
else # For the Current Host
{
$OSName = `/usr/bin/uname 2>/dev/null`;
$lparInfo = `/usr/bin/uname -L 2>/dev/null`;
$OSLevel = `/usr/bin/oslevel 2>/dev/null`;
}
# Make sure that the host is running AIX as an operating system.
chomp($OSName);
if ($OSName ne "AIX") #If NOT AIX Host Name
{
printf " The command \"uname\" shows that the host %s is not running \
\"AIX\"!\n", $hosti; exit (-1);
}
# Now make sure that the lpar_name exists on the given managed system.
chomp($lparInfo);
$lparInfo =~ s/^\s+//;
my ($lparId, $lparName) = split(/ +/,$lparInfo,2);
if (&check_lpar($lparName) != 0) #If LPAR name does not match
{
printf " Partition name of host %s does not match partitions managed \
by HMC!\n", $hosti; exit (-1);
}
push(@aix_lpars, $lparName);
$aix_hosts{$lparName}=$hosti;
if ( ( $hmc_type eq "POWER4 HMC") && ($hmc_version lt "R3V2.4" ))
{
chomp($OSLevel);
$dlpar{$lparName} =($OSLevel ge "5.2.0.0") ? "YES" : " NO";
}
# Any non-digit characters in the #CPUs or #LMBs column
# will be treated as "No change needed in the configuration".
if ($cpu =~ /^\d+$/)
{
$tgt_cpus{$lparName} = $cpu;
}
else
{
if ($cpu =~ /^\+(\d+)$/) { $diff_cpus{$lparName} = $1; }
elsif ($cpu =~ /^\-(\d+)$/) { $diff_cpus{$lparName} = -1 * $1; }
$tgt_cpus{$lparName} = -1;
}
if ($lmb =~ /^\d+$/)
{
$tgt_lmbs{$lparName} = $lmb;
}
else
{
if ($lmb =~ /^\+(\d+)$/) { $diff_lmbs{$lparName} = $1; }
elsif ($lmb =~ /^\-(\d+)$/) { $diff_lmbs{$lparName} = -1 * $1; }
$tgt_lmbs{$lparName} = -1;
}
}
}
close (TGTCFG);
if ($#aix_lpars < 0)
{
print "No $remShell\'able AIX Hosts with valid LPAR names in $targetCfg!\n";
exit (-1);
}
}
# 10 ---------------------------------------------------------------------------
sub check_lpar
# PURPOSE: To check the validity of the LPAR name for the given host
{
my ($lparName) = shift;
for ($i=0; $i <= $#hmc_lpars; $i++)
{
if ($hmc_lpars[$i] eq $lparName)
{
return (0);
}
}
return (-1);
}
# 11 ---------------------------------------------------------------------------
sub get_current_config
# NOTE: The current configuration should be obtained only for those
# LPARs which are active (i.e. rsh|ssh'able).
{
print "----------------------------------------------------------------\n";
print "CURRENT CONFIGURATIONs:\n";
printf "%14s%20s%10s%10s%10s\n","Hostname","LPARname","#CPUs","#LMBs","DLPAR";
printf "%14s%20s%10s%10s%10s\n","--------","--------","-----","-----","-----";
if ( $hmc_type eq "POWER4 HMC")
{
&get_current_config_p4hmc;
}
else
{
&get_current_config_p5hmc;
}
printf "Available (=unreserved) #CPUs in the Free Pool = %d \n", $free_cpus;
printf "Available (=unreserved) #LMBs in the Free Pool = %d\n", $free_lmbs;
printf "NOTE: 1 LMB of Memory = %d MB \n", $lmb_size;
}
# 12 -------------------------------------------------------------------------
sub get_current_config_p4hmc
# PURPOSE: Get current CPU and Memory configuration on POWER4 HMC
{
foreach $lpar (@aix_lpars)
{
my $cmd = "$lsres -r ALL -p $lpar -Fmin:allocated:max:free -y sys |";
my $line;
my $cnt=0;
my ($minCpus,$curCpus,$maxCpus);
my ($minLmbs,$curLmbs,$maxLmbs);
open (TEMPCMD, $cmd);
while($line = <TEMPCMD>)
{
chomp($line);
if ($line =~ m/(\d+):(\d+):(\d+):(\d+)/)
{
$cnt++;
if ($cnt == 1) # CPU configurations
{
($minCpus,$curCpus,$maxCpus,$free_cpus) = split(/:/, $line);
$cur_cpus{$lpar} = $curCpus;
$min_cpus{$lpar} = $minCpus;
$max_cpus{$lpar} = $maxCpus;
}
if ($cnt == 2) # Memory configurations
{
($minLmbs,$curLmbs,$maxLmbs,$free_lmbs) = split(/:/, $line);
$cur_lmbs{$lpar} = $curLmbs;
$min_lmbs{$lpar} = $minLmbs;
$max_lmbs{$lpar} = $maxLmbs;
}
}
}
close (TEMPCMD);
printf STDOUT "%14s%20s%10s%10s%10s\n",
substr($aix_hosts{$lpar},0,12),substr($lpar,0,18),
$cur_cpus{$lpar},$cur_lmbs{$lpar},$dlpar{$lpar};
}
$free_cpus = ($free_cpus > $rsvd_freC) ? ($free_cpus - $rsvd_freC) : 0;
$free_lmbs = ($free_lmbs > $rsvd_freM) ? ($free_lmbs - $rsvd_freM) : 0;
}
# 13 -------------------------------------------------------------------------
sub get_current_config_p5hmc
# PURPOSE: Get current CPU and Memory configuration on POWER5 HMC
{
my $line;
my $cmd1 = "$lsres -r proc --level lpar \
-Flpar_name:curr_min_procs:curr_procs:curr_max_procs |"; my $cmd2 = "$lsres -r mem \
--level lpar -Flpar_name:curr_min_mem:curr_mem:curr_max_mem |"; open (TEMPCMD, \
$cmd1); while($line = <TEMPCMD>)
{
chomp($line);
my ($name,$minCpus,$curCpus,$maxCpus) = split(/:/, $line);
$min_cpus{$name} = $minCpus;
$cur_cpus{$name} = $curCpus;
$max_cpus{$name} = $maxCpus;
}
close (TEMPCMD);
open (TEMPCMD, $cmd2);
while($line = <TEMPCMD>)
{
chomp($line);
my ($name,$minMems,$curMems,$maxMems) = split(/:/, $line);
$min_lmbs{$name} = $minMems / $lmb_size;
$cur_lmbs{$name} = $curMems / $lmb_size;
$max_lmbs{$name} = $maxMems / $lmb_size;
}
close (TEMPCMD);
foreach $lpar (@aix_lpars)
{
printf STDOUT "%14s%20s%10s%10s%10s\n",
substr($aix_hosts{$lpar},0,12),substr($lpar,0,18),
$cur_cpus{$lpar},$cur_lmbs{$lpar},$dlpar{$lpar};
}
$free_cpus = `$lsres -r proc --level sys -Fcurr_avail_sys_proc_units`;
my $freeMems = `$lsres -r mem --level sys -Fcurr_avail_sys_mem`;
$free_lmbs = $freeMems / $lmb_size;
$free_cpus = ($free_cpus > $rsvd_freC) ? ($free_cpus - $rsvd_freC) : 0;
$free_lmbs = ($free_lmbs > $rsvd_freM) ? ($free_lmbs - $rsvd_freM) : 0;
}
# 14 --------------------------------------------------------------------------
sub update_target_arrays
# PURPOSE: If there are any -1's the in tgt_cpus or tgt_lmbs arrays,
# then set them to the current values of #cpus and #lmbs.
{
foreach $lpar (@aix_lpars)
{
if ($tgt_cpus{$lpar} == -1)
{
$tgt_cpus{$lpar} = $cur_cpus{$lpar};
if (defined $diff_cpus{$lpar})
{
$tgt_cpus{$lpar} += $diff_cpus{$lpar};
delete $diff_cpus{$lpar};
}
}
if ($tgt_lmbs{$lpar} == -1)
{
$tgt_lmbs{$lpar} = $cur_lmbs{$lpar};
if (defined $diff_lmbs{$lpar})
{
$tgt_lmbs{$lpar} += $diff_lmbs{$lpar};
delete $diff_lmbs{$lpar};
}
}
}
}
# 15 -------------------------------------------------------------------------
sub print_target_config
# PURPOSE: To print the target configurations
{
print "----------------------------------------------------------------\n";
print "TARGET CONFIGURATIONs:\n";
printf "%14s%20s%10s%10s%10s\n","Hostname","LPARname","#CPUs","#LMBs","DLPAR";
printf "%14s%20s%10s%10s%10s\n","--------","--------","-----","-----","-----";
foreach $lpar (@aix_lpars)
{
printf STDOUT "%14s%20s%10s%10s%10s\n",
substr($aix_hosts{$lpar},0,12),substr($lpar,0,18),
$tgt_cpus{$lpar}, $tgt_lmbs{$lpar}, $dlpar{$lpar};
}
printf "NOTE: 1 LMB of Memory = %d MB \n", $lmb_size;
print "----------------------------------------------------------------\n";
}
# 16 --------------------------------------------------------------------------
sub check_target_config
# PURPOSE: To calculate the delta #CPUs and delta #LMBs after transition to the
# target config. Both numbers should be 0 or more.
{
$cpusum = 0;
$lmbsum = 0;
$dlparNeeded = 0; # To check if DLPAR is needed on a DLPAR'able partition.
LOOP1:
foreach $lpar (@aix_lpars)
{
# Skip if the lpar is not DLPAR'able.
if ( ( $dlpar{$lpar} ne "YES" )
&& ( ($tgt_cpus{$lpar} != $cur_cpus{$lpar})
|| ($tgt_lmbs{$lpar} != $cur_lmbs{$lpar})
)
)
{
$numNoDLPAR = 1;
next LOOP1;
}
# Check that #target CPUs for an LPAR falls within [min,max]
# for this LPAR.
if (($tgt_cpus{$lpar} > $max_cpus{$lpar})
|| ($tgt_cpus{$lpar} < $min_cpus{$lpar}))
{
print "ERROR: Desired #CPUss(=$tgt_cpus{$lpar}) is invalid on the host \
\"$aix_hosts{$lpar}\"\n";
print " which can have #CPUs in the range of \
[$min_cpus{$lpar},$max_cpus{$lpar}]!\n"; return (-1);
}
$diff_cpus{$lpar} = $tgt_cpus{$lpar} - $cur_cpus{$lpar};
$cpusum += $diff_cpus{$lpar};
# Check that #target LMBs for an LPAR falls within [min,max]
# for this LPAR.
if (($tgt_lmbs{$lpar} > $max_lmbs{$lpar})
|| ($tgt_lmbs{$lpar} < $min_lmbs{$lpar}))
{
print "ERROR: Desired #LMBs(=$tgt_lmbs{$lpar}) is invalid on the host \
\"$aix_hosts{$lpar}\"\n";
print " which can have #LMBs in the range of \
[$min_lmbs{$lpar},$max_lmbs{$lpar}]!\n"; return (-1);
}
$diff_lmbs{$lpar} = $tgt_lmbs{$lpar} - $cur_lmbs{$lpar};
$lmbsum += $diff_lmbs{$lpar};
if ( ($diff_cpus{$lpar} != 0 ) || ($diff_lmbs{$lpar} != 0) )
# DLPAR is needed.
{
$dlparNeeded = 1;
}
}
# Print the Requested Changes in the total #CPUs & LMBs for the whole LPAR group.
# print "Requested Delta #CPUs for all the LPARs = ", $cpusum, "\n";
# print "Requested Delta #LMBs for all the LPARs = ", $lmbsum, "\n";
if ($cpusum > $free_cpus)
{
print "ERROR: Total Desired #CPUs(=$cpusum) > Total Available \
#CPUs(=$free_cpus)!\n"; return (-1);
}
if ($lmbsum > $free_lmbs)
{
print "ERROR: Total Desired LMBs(=$lmbsum) > Total Available \
#LMBs(=$free_lmbs)!\n"; return (-1);
}
if ( $dlparNeeded == 0 )
{
return (1);
}
return (0);
}
# 17 -------------------------------------------------------------------------
sub generate_commands
{
my %cr=(); # cpus to remove; key = LPARname, value = number of cpus
my %ca=(); # cpus to add; key = LPARname, value = number of cpus
my %lr=(); # lmbs to remove; key = LPARname, value = number of lmbs
my %la=(); # lmbs to add; key = LPARname, value = number of lmbs
my $max_r, $max_a;
my $max_r_lpar, $max_a_lpar;
my $n = 0;
my $cmd, $src, $dst;
LOOP1:
# Initialize the %cr, %ca, %lr, and %la arrays
foreach $lpar (@aix_lpars)
{
if ($diff_cpus{$lpar} < 0) { $cr{$lpar} = (-1 * $diff_cpus{$lpar}); }
if ($diff_cpus{$lpar} > 0) { $ca{$lpar} = ( $diff_cpus{$lpar}); }
if ($diff_lmbs{$lpar} < 0) { $lr{$lpar} = (-1 * $diff_lmbs{$lpar}); }
if ($diff_lmbs{$lpar} > 0) { $la{$lpar} = ( $diff_lmbs{$lpar}); }
}
# Generate the CPU commands - - - - - - - - - - - - - - - - - - - -
# FIRST do the "MOVE" commands.
do
{
$max_r_lpar=""; $max_r = 0;
foreach $lpar (keys %cr)
{
if ($cr{$lpar} > $max_r)
{
$max_r = $cr{$lpar};
$max_r_lpar = $lpar;
}
}
$max_a_lpar=""; $max_a = 0;
foreach $lpar (keys %ca)
{
if ($ca{$lpar} > $max_a)
{
$max_a = $ca{$lpar};
$max_a_lpar = $lpar;
}
}
$n = 0;
if (($max_r != 0) && ($max_a != 0))
{
$src = $max_r_lpar;
$dst = $max_a_lpar;
$n = &min($max_r, $max_a);
if ( $hmc_type eq "POWER4 HMC")
{
$cmd = "$chres -r cpu -o m -p $src -t $dst -q $n ";
}
else # POWER5 HMC
{
$cmd = "$chres -r proc -o m -p $src -t $dst --procs $n ";
}
push (@cmds, $cmd);
$cr{$max_r_lpar} -= $n;
$ca{$max_a_lpar} -= $n;
if ($cr{$max_r_lpar} == 0) { delete $cr{$max_r_lpar}; }
if ($ca{$max_a_lpar} == 0) { delete $ca{$max_a_lpar}; }
}
} while ($n > 0);
# SECONDLY, do the "REMOVE" commands.
foreach $lpar (keys %cr)
{
if ( $hmc_type eq "POWER4 HMC")
{
$cmd = "$chres -r cpu -o r -p $lpar -q $cr{$lpar} ";
}
else # POWER5 HMC
{
$cmd = "$chres -r proc -o r -p $lpar --procs $cr{$lpar} ";
}
push (@cmds, $cmd);
}
# THIRDLY, do the "ADD" commands.
foreach $lpar (keys %ca)
{
if ( $hmc_type eq "POWER4 HMC")
{
$cmd = "$chres -r cpu -o a -p $lpar -q $ca{$lpar} ";
}
else # POWER5 HMC
{
$cmd = "$chres -r proc -o a -p $lpar --procs $ca{$lpar} ";
}
push (@cmds, $cmd);
}
# Generate the LMB commands - - - - - - - - - - - - - - - - - - -
# FIRST do the "MOVE" commands.
do
{
$max_r_lpar=""; $max_r = 0;
foreach $lpar (keys %lr)
{
if ($lr{$lpar} > $max_r)
{
$max_r = $lr{$lpar};
$max_r_lpar = $lpar;
}
}
$max_a_lpar=""; $max_a = 0;
foreach $lpar (keys %la)
{
if ($la{$lpar} > $max_a)
{
$max_a = $la{$lpar};
$max_a_lpar = $lpar;
}
}
$n = 0;
if (($max_r != 0) && ($max_a != 0))
{
$src = $max_r_lpar;
$dst = $max_a_lpar;
$n = &min($max_r, $max_a);
if ( $hmc_type eq "POWER4 HMC")
{
$cmd = "$chres -r mem -o m -p $src -t $dst -q $n ";
}
else # POWER5 HMC
{
my $megaByte = $n * $lmb_size;
$cmd = "$chres -r mem -o m -p $src -t $dst -q $megaByte ";
}
push (@cmds, $cmd);
$lr{$max_r_lpar} -= $n;
$la{$max_a_lpar} -= $n;
if ($lr{$max_r_lpar} == 0) { delete $lr{$max_r_lpar}; }
if ($la{$max_a_lpar} == 0) { delete $la{$max_a_lpar}; }
}
} while ($n > 0);
# SECONDLY, do the "REMOVE" commands.
foreach $lpar (keys %lr)
{
if ( $hmc_type eq "POWER4 HMC")
{
$cmd = "$chres -r mem -o r -p $lpar -q $lr{$lpar} ";
}
else # POWER5 HMC
{
my $megaByte = $lr{$lpar} * $lmb_size;
$cmd = "$chres -r mem -o r -p $lpar -q $megaByte ";
}
push (@cmds, $cmd);
}
# THIRDLY, do the "ADD" commands.
foreach $lpar (keys %la)
{
if ( $hmc_type eq "POWER4 HMC")
{
$cmd = "$chres -r mem -o a -p $lpar -q $la{$lpar} ";
}
else # POWER5 HMC
{
my $megaByte = $la{$lpar} * $lmb_size;
$cmd = "$chres -r mem -o a -p $lpar -q $megaByte ";
}
push (@cmds, $cmd);
}
}
# 18 -------------------------------------------------------------------------
sub min
{
my ($a, $b) = @_;
if ($a < $b) { return $a; }
else { return $b; }
}
# 19 -------------------------------------------------------------------------
sub execute_commands
{
foreach $cmd (@cmds)
{
print "$cmd\n";
print LOGFILE "$cmd\n";
if ( ( $hmc_type eq "POWER4 HMC") && ($hmc_version lt "R3V2.4" ))
{
my $rc = 0;
my $cfgCmd = $cmd . " |";
open (TEMPCMD, $cfgCmd);
while ($line = <TEMPCMD>)
{
print LOGFILE $line;
chomp ($line);
# NOTE: We are currently identifying that the "chhwres" command
# has failed, by looking for a special string "rtn: n" (n>0).
# This mechanism has to be revalidated for each new release of HMC.
if ($line =~ m/^rtn: (\d+)/ )
{
if ($1 != 0) { $rc = $1; }
}
}
close (TEMPCMD);
if ($rc != 0)
{
print "ERROR: The above chhwres did not succeed!\n";
}
}
else
{
system "$cmd >>$logFile 2>&1";
if ( $? != 0)
{
print "ERROR: The above chhwres did not succeed!\n";
}
}
}
print "\nNOTE: You can view the file $logFile for \n";
print " detailed information about the execution of the above commands.\n";
}
# 20 -------------------------------------------------------------------------
sub print_final_config
# PURPOSE: To print the achieved configurations
{
&get_current_cpus_lmbs;
print "----------------------------------------------------------------\n";
print "TARGET CONFIGURATIONs ACHIEVED:\n";
printf "%14s%20s%10s%10s%10s\n","Hostname","LPARname","#CPUs","#LMBs","DLPAR";
printf "%14s%20s%10s%10s%10s\n","--------","--------","-----","-----","-----";
foreach $lpar (@aix_lpars)
{
printf STDOUT "%14s%20s%10s%10s%10s\n",
substr($aix_hosts{$lpar},0,12),substr($lpar,0,18),
$cur_cpus{$lpar}, $cur_lmbs{$lpar}, $dlpar{$lpar};
}
printf "NOTE: 1 LMB of Memory = %d MB \n", $lmb_size;
print "----------------------------------------------------------------\n";
if ($numNoDLPAR > 0)
{
print "NOTE: The resources for the LPARs that cannot be dynamically\n";
print " reconfigured (DLPAR != YES) must be changed manually \n";
print " using the HMC GUI, and require a reboot of the LPAR. \n";
}
}
# 21 ---------------------------------------------------------------------------
sub get_current_cpus_lmbs
# PURPOSE: To get the current #CPUs and #LMBs using rsh|ssh
{
foreach $lpar (@aix_lpars)
{
my $cmd1 = "";
my $cmd2 = "";
my $hosti = $aix_hosts{$lpar};
if (($hosti ne $cur_host) && ($hosti ne $cur_host_name))
{
$cmd1 = "$remShellCmd $hosti /usr/sbin/lsdev -Cc processor -S a |";
$cmd2 = "$remShellCmd $hosti /usr/sbin/lsattr -El sys0 |";
}
else # Do not rsh|ssh if hosti is current host
{
$cmd1 = "/usr/sbin/lsdev -Cc processor -S a |";
$cmd2 = "/usr/sbin/lsattr -El sys0 |";
}
# $cmd1 gets the number of available CPUs on the host.
my $cnt1 = 0;
open (TEMPCMD1,$cmd1);
while($line1 = <TEMPCMD1>)
{
chomp($line1);
if( ($line1 =~ m/Available/) && ($line1 =~ m/Processor/) )
{
$cnt1 = $cnt1 + 1;
}
}
$cur_cpus{$lpar} = $cnt1;
close (TEMPCMD1);
# $cmd2 gets the number of available LMBs (Logical Memory Blocks).
my $cnt2 = 0;
open (TEMPCMD2,$cmd2);
while($line2 = <TEMPCMD2>)
{
chomp($line2);
if( ($line2 =~ /^realmem(\s*)(\d+)\s/))
{
$cnt2 = $2;
}
}
$cur_lmbs{$lpar} = $cnt2/(1024 * $lmb_size);
close (TEMPCMD2);
}
}
["lparLsLoads.pl" (application/octet-stream)]
#!/usr/bin/perl
# PURPOSE:
# To display the CPU Load and Memory Load of all the LPARs (running AIX 5.1
# and above) whose hostnames are listed in the input <hostList> file.
# Both current loads and past load are displayed.
# SYNTAX:
# lparLsLoads.pl [-f <hostList>] [-t <intvlSecs_lsLoads>]
# [-last <histCnt_lsLoads>] [-o <histOut>]
# [-hmc <hmcHost>] [-u <hmcUser] [-m <managedSys>] [-h]
# See subroutine syntax() for the details.
#
# COMPONENT OF: IBM pSeries DLPAR Toolset 2.0.2.0, September 2004.
# COPYRIGHT: IBM Corporation, 2002,2003,2004. All rights reserved.
#
# DEFINITIONs of CPU Load and Memory Load of an LPAR:
# 1) CPU Load (in %) is defined as (100% - CPU-idle-percentage).
# 2) Memory Load (in %) is defined as
# the percentage of non-free pages in the AIX instance
# =: ( (#RealPages - #FreePages) / #RealPages ) * 100 %.
#
# SUBROUTINES IN THIS FILE
# main
# 1 read_arguments
# 2 syntax
# 3 check_hmc
# 4 check_managed_system_p4hmc
# 5 check_managed_system_p5hmc
# 6 read_hostlist
# 7 check_ping_remShell
# 8 calculate_loads
# 9 update_histRunThrds
# 10 update_histCpuLoad
# 11 update_histPgStl
# 12 update_histMemLoad
# 13 result
# 14 hist_result
# 15 update_histOut
# 16 round
#
# AUTHORs: N. Dubey, J. Jann, IBM Yorktown 2002/9/1.
# CHANGE LOG: Last updated on 2004/08/24
# ---------------------------------------------------------------------
$lmb_size = 0;
$PAGE_SIZE = 4; # Number of KBs per page.
$nHosts = 0; # Number of hosts (= AIX instances)
$histCnt = 0; # Number of past snapshots/readings which were
# taken <intvlSecs_lsLoads> seconds apart.
@aix_hosts = ("")x @aix_hosts;# List of the rsh|ssh'able AIX hostnames in \
<hostList> @remShellTries = (0) x @remShellTries; # Number of failed attempts to \
rsh|ssh to the host @nCPUs = (1) x @nCPUs; # Number of CPUs
@runThrds = (0) x @runThrds; # Number of runnable threads
@cpuLoad = (0) x @cpuLoad; # CPU load of the AIX instance
@histRunThrds = ([]);
@sumHistRunThrds = 0 x @sumHistRunThrds;
@histCpuLoad = ([]);
@sumHistCpuLoad = (0) x @sumHistCpuLoad;
@nLMBs = (0) x @nLMBs; # Number of LMBs
@freeMem = (0) x @freeMem; # Free Memory (in KB) on hosts
@pgstl = (0) x @pgstl; # Current number of page steals
# i.e. 'fr' column from vmstat.
@memLoad = (0) x @memLoad; # Memory Load of the AIX instance
@histPgStl = ([]);
@sumHistPgStl= (0) x @sumHistPgStl;
@histMemLoad = ([]);
@sumHistMemLoad = (0) x @sumHistMemLoad;
$loop = 0;
$last_check = 0; # The value of "$loop" when we checked last time
# for dead (non-rsh|ssh'able) hosts.
$nCols = 10;
$scale = $nCols/100; # 10 columns for 100% load.
# DEFAULT PARAMETER VALUES set in this script:
# NOTE that the PARAMETER OVERRIDING RULE is:
# 1) An input flag (e.g. -t) value OVERRIDEs
# 2) the corresponding environment variable value, which in turn OVERRIDES
# 3) the corresponding default value set in this script.
$DEF_INTVLSECS_LSLOAD = 5;
$DEF_HISTCNT_LSLOAD = 10;
$DEF_TRGR_CPU_LOAD = 98; # Value (in %) of the CPU load above which CPU Dynamic
# Resource Movement Evaluation will be triggered.
$DEF_TRGR_MEM_LOAD = 85; # Value (in %) of the Memory load above which Memory
# Resource Movement Evaluation will be triggered.
$cur_host_name =`/usr/bin/hostname`;
chomp($cur_host_name);
$cur_host =`/usr/bin/hostname -s `;
chomp($cur_host);
$cur_user = $ENV{"USER"} ;
$cur_user=`/usr/bin/whoami`;
chomp($cur_user);
#=============================================================================
# MAIN ROUTINE: Calculate & print current & historical CPU loads and Memory
# loads of the LPARs whose hostnames are listed in the <hostList> file.
# A) Read the arguments
&read_arguments(@ARGV);
# B) This step is needed to get the LMB size from HMC
&check_hmc;
# C) Read the <hostList> file
&read_hostlist;
# D) MAIN FOR-LOOP: Calculate current & hist. CPU & Memory loads
print "\nReading the data .....\n";
for(;;)
{
if ((($loop - $last_check) * $intvlSecs) >= 300)
# Check every five minutes whether dead hosts came alive.
{
&check_ping_remShell;
$last_check = $loop;
}
&calculate_loads;
system "/usr/bin/clear";
# Print the result
&result;
$loop++;
# Display the load average over the last <histCnt> number of readings
if ($loop >= $histCnt )
{
&hist_result;
}
else
{ printf "\nPlease wait for %d more refreshes to view the avg. load in the past %d \
snapshots.\n", ($histCnt - $loop), $histCnt;
}
print "For definitions of the headings, see the DEFs file in the DOC/ \
subdirectory.\n"; print "Press Control-C to exit!\n";
# Sleep for <intvlSecs> seconds
sleep $intvlSecs;
} # end FOR-loop
# 1 ------------------------------------------------------------------------
sub read_arguments
# PURPOSE: To parse the input arguments
{
undef $hostList;
undef $histOut;
undef $intvlSecs;
undef $histCnt;
undef $hmcHost;
undef $hmcUser;
undef $cec;
while(@ARGV)
{
my $option = shift @ARGV;
if ($option eq "-h")
{
&syntax;
}
elsif ($option eq "-f")
{
$hostList= shift @ARGV;
}
elsif ($option eq "-t")
{
$intvlSecs= shift @ARGV;
}
elsif ($option eq "-last")
{
$histCnt = shift @ARGV;
}
elsif ($option eq "-o")
{
$histOut = shift @ARGV;
}
elsif ($option eq "-hmc")
{
$hmcHost = shift;
}
elsif ($option eq "-u")
{
$hmcUser = shift;
}
elsif ($option eq "-m")
{
$cec = shift;
}
else
{
&syntax;
}
}
if ((! defined $hostList) && (defined $ENV{"DR_HOST_LIST"}))
{
$hostList = $ENV{"DR_HOST_LIST"};
}
if ((! defined $intvlSecs) && (defined $ENV{"DR_INTVLSECS_LSLOAD"}))
{
$intvlSecs = $ENV{"DR_INTVLSECS_LSLOAD"};
}
if ((! defined $histCnt) && (defined $ENV{"DR_HISTCNT_LSLOAD"}))
{
$histCnt = $ENV{"DR_HISTCNT_LSLOAD"};
}
if ((! defined $histOut) && (defined $ENV{"DR_HISTOUT_LSLOAD"}))
{
$histOut = $ENV{"DR_HISTOUT_LSLOAD"};
}
if ((! defined $hmcHost) && (defined $ENV{"DR_HMC_HOST"}))
{
$hmcHost = $ENV{"DR_HMC_HOST"};
}
if ((! defined $hmcUser) && (defined $ENV{"DR_HMC_USER"}))
{
$hmcUser = $ENV{"DR_HMC_USER"};
}
if ((! defined $cec) && (defined $ENV{"DR_MANAGED_SYS"}))
{
$cec = $ENV{"DR_MANAGED_SYS"};
}
if ( (defined $ENV{"DR_TRGR_CPU_LOAD"}) )
{
$trgrCpuLoad = $ENV{"DR_TRGR_CPU_LOAD"};
}
if ( (defined $ENV{"DR_TRGR_MEM_LOAD"}) )
{
$trgrMemLoad = $ENV{"DR_TRGR_MEM_LOAD"};
}
if (! defined $hostList)
{
print "ERROR: <hostList> file was not specified.\n";
print " You can specify this as -f <hostList> argument\n";
print " or as DR_HOST_LIST environment variable\n";
&syntax;
}
if (! defined $hmcHost)
{
print "ERROR: <hmcHost> was not specified.\n";
print " You can specify this as -hmc <hmcHost> argument\n";
print " or as DR_HMC_HOST environment variable\n";
&syntax;
}
if (! defined $hmcUser)
{
print "ERROR: <hmcUser> was not specified.\n";
print " You can specify this as -u <hmcUser> argument\n";
print " or as DR_HMC_USER environment variable\n";
&syntax;
}
if (! defined $cec)
{
print "ERROR: <managedSys> was not specified.\n";
print " You can specify this as -m <managedSys> argument\n";
print " or as DR_MANAGED_SYS environment variable\n";
&syntax;
}
if (! defined $intvlSecs) { $intvlSecs = $DEF_INTVLSECS_LSLOAD; }
if (! defined $histCnt) { $histCnt = $DEF_HISTCNT_LSLOAD; }
if (! defined $trgrCpuLoad) { $trgrCpuLoad = $DEF_TRGR_CPU_LOAD; }
if (! defined $trgrMemLoad) { $trgrMemLoad = $DEF_TRGR_MEM_LOAD; }
if (defined $histOut)
{
open (HOUT, ">", $histOut) or die "Cannot create $histOut for writing: $!\n";
close(HOUT);
}
if ($intvlSecs <= 0 || $histCnt <= 0)
{
&syntax;
}
## $histLines = $histCnt; # Number of history lines to be averaged.
if ($histCnt == 1)
{
print "NOTE1: <histCnt_lsLoads> must be greater than 1.\n";
exit;
}
if ($ENV{"DR_REMOTE_SHELL"} eq "ssh")
{
$remShell = "ssh";
$remShellCmd = "/usr/bin/ssh"
}
else
{
$remShell = "rsh"; # The default shell
$remShellCmd = "/usr/bin/rsh";
}
# Clear the screen
system "/usr/bin/clear";
printf "This script is being run by user \"%s\" on host \"%s\".\n",
$cur_user, $cur_host;
printf "INPUT:\n";
printf " Host List = %s\n", $hostList;
print " hmcHost = ", $hmcHost, "\n";
print " hmcUser = ", $hmcUser, "\n";
print " Managed System = ", $cec, "\n";
if (defined $histOut)
{
printf " History OutPut File = %s\n", $histOut;
}
printf " RemoteShell for AIX hosts = %s\n", $remShell;
printf " Refresh interval = %5d seconds \n", $intvlSecs;
printf " Show history data for the past = %5d snapshots \n", $histCnt;
}
# 2 ---------------------------------------------------------------------------
# Syntax of this script
sub syntax
{
print "\nSYNTAX:\n";
print "lparLsLoads.pl [-f <hostList>] [-t <intvlSecs_lsLoads>] \n";
print " [-last <histCnt_lsLoads>] [-o histOut]\n";
print " [-hmc <hmcHost>] [-u <hmcUser] [-m <managedSys>] [-h]\n";
print " where\n";
print " <hostList> : Filename of the file containing the \
hostnames.\n"; print " <intvlSecs_lsLoads>: Number of secs. between snapshots of \
the loads.\n"; print " <histCnt_lsLoads> : Number of seconds in the past, over \
which the \n"; print " historical loads are averaged.\n";
print " <histOut> : filename of the file containing history data.\n";
print " <hmcHost> : Hostname of the HMC\n";
print " <hmcUser> : Login-name on the HMC which was setup\n";
print " for unattended remote ssh command execution\n";
print " <managedSys> : Name of the Managed System.\n";
print " See HMC Operations Guide for more details.\n";
print " -h : Prints this syntax help; cannot be used with other flags.\n";
print " NOTE1: <histCnt_lsLoads> must be an integer greater than 1.\n";
print " E.g.: \n";
print " $0 -f hostList -t 4 -last 5 -hmc hmc.mydomain.com -u grm_ssh -m DR\n\n";
exit;
}
# 3 --------------------------------------------------------------------------
sub check_hmc
# PURPOSE: To check the status of the HMC, the HMC SSH user, and the Managed System.
{
# Check whether HMC is up or not
printf "\nChecking ping and ssh to %s.....\n", $hmcHost;
system "/usr/sbin/ping $hmcHost 1 1 2>/dev/null 1>&2";
if ( $? != 0)
{
printf "The hmcHost \"%s\" is not ping'able !\n", $hmcHost;
exit (1);
}
system "/usr/bin/ssh $hmcUser\@$hmcHost date 2>/dev/null 1>&2";
if ( $? != 0)
{
print "SSH connection from $cur_user\@$cur_host to $hmcUser\@$hmcHost failed!\n";
exit (1);
}
# Check if the restricted bash shell is set.
my $hmcInfo =`/usr/bin/ssh $hmcUser\@$hmcHost " lshmc -v " 2>&1`;
if ( $hmcInfo =~ /bash:/ ) # If restricted shell is not set.
{
$HSC_CMD_PATH = "/opt/hsc/bin/";
$hmc_bash = "Non-Restricted Bash shell";
$hmcInfo = `/usr/bin/ssh $hmcUser\@$hmcHost " ${HSC_CMD_PATH}lshmc -v " 2>&1`;
}
else
{
$hmc_bash = "Restricted Bash shell";
}
my @tmpHmc = split (/\n/,$hmcInfo);
for (my $i=0; $i <= $#tmpHmc; $i++)
{
if ($tmpHmc[$i] =~ /RM\s+(\S+)/)
{
$hmc_version = $1;
}
}
chomp($hmc_version);
# Check the HMC Type
if ($hmc_version =~ /V(\d)/)
{
if ($1 le "3")
{
$hmc_type = "POWER4 HMC";
}
else # i.e. if ($1 eq "4" )
{
$hmc_type = "POWER5 HMC";
}
}
print "HMC Commands are running under $hmc_bash on $hmc_type \
($hmc_version).....\n"; $lssys = "/usr/bin/ssh $hmcUser\@$hmcHost \
${HSC_CMD_PATH}lssyscfg -m $cec"; $lsres = "/usr/bin/ssh $hmcUser\@$hmcHost \
${HSC_CMD_PATH}lshwres -m $cec"; $chres = "/usr/bin/ssh $hmcUser\@$hmcHost \
${HSC_CMD_PATH}chhwres -m $cec -d $DEBUG_LVL"; if ( $hmc_type eq "POWER4 HMC")
{
if (&check_managed_system_p4hmc != 0) #If the managed system is not Ready.
{
exit (1);
}
}
else
{
if (&check_managed_system_p5hmc != 0) #If the managed system is not operating.
{
exit (1);
}
}
}
# 4 --------------------------------------------------------------------------
sub check_managed_system_p4hmc
# PURPOSE: Check managed system on POWER5 HMC
{
if ( $hmc_version ge "R3V2.4") # Only if the HMC has Release and Version >= \
R3V2.4 {
my $cmd = "";
$cmd = "$lssys -r sys --all -Fname:state:lmb_size |";
open (TEMPCMD, $cmd);
while($line = <TEMPCMD>)
{
chomp($line);
my ($sysName, $sysState, $lmbSize)= split(/:/,$line);
if ($sysName eq $cec)
{
if ( $sysState eq Ready )
{
close (TEMPCMD);
$lmb_size =$lmbSize;
return (0);
}
printf "The managed system \"%s\" is not in the \"Ready\" state!\n", $cec;
close (TEMPCMD);
return (-1);
}
}
print "The HMC command \"lssyscfg\" does not show $cec as a \"Ready\" managed \
system!\n"; close (TEMPCMD);
return (-1);
}
else
{
my $cecstr = "";
$cecstr = `/usr/bin/ssh $hmcUser\@$hmcHost " ${HSC_CMD_PATH}get_cec_state -m $cec " \
2>&1`; chomp($cecstr);
# Check if the Managed System is not in the Ready state.
if ( !($cecstr =~ /Ready/) )
{
print "The HMC command \" ${HSC_CMD_PATH}get_cec_state\" does not show";
print " $cec as a \"Ready\" managed system!\n";
return (-1);
}
$lmb_size = 256;
return (0);
}
}
# 5 --------------------------------------------------------------------------
sub check_managed_system_p5hmc
# PURPOSE: Check managed system on POWER5 HMC
{
my $cmd = "$lssys -r sys -Fname:state |";
open (TEMPCMD, $cmd);
while($line = <TEMPCMD>)
{
chomp($line);
my ($sysName, $sysState)= split(/:/,$line);
if ($sysName eq $cec)
{
if ( $sysState eq Operating )
{
close (TEMPCMD);
$lmb_size = `$lsres -r mem --level sys -Fmem_region_size`;
chomp($lmb_size);
return (0);
}
printf "The managed system \"%s\" is not in the \"Operating\" state!\n", $cec;
close (TEMPCMD);
return (-1);
}
}
print "The HMC command \"lssyscfg\" does not show $cec as an \"Operating\" \
managed system!\n"; close (TEMPCMD);
return (-1);
}
# 6 -------------------------------------------------------------------------
sub read_hostlist
{
my $hosti = "";
my $OSName = "";
my $OSLevel = "";
# Open the input <hostList> file to get the hostnames
open (TEMP_FILE, $hostList) || die "Cannot open $hostList: $!\n";
LOOP1:
while(<TEMP_FILE>)
{
# Skip the comment lines (beginning with '#')
if (/^\#/) { next LOOP1; }
$_ =~ s/\s+/ /g; # Remove extra white space characters
$_ =~ s/^ //; # Remove the first character if it is a "space".
# This is required for split function to work properly.
if (/^ *$/) { next LOOP1; } # Blank line
if (/(\S+)\s*/)
{
$hosti = $1;
$hosti =~ s/\s+//;
if (($hosti ne $cur_host) && ($hosti ne $cur_host_name))
{
print "Checking ping and $remShell to $hosti.....\n";
# Check the ping result to hosti
system "/usr/sbin/ping $hosti 1 1 2>/dev/null 1>&2";
if ( $? != 0)
{
print " The host $hosti is not ping'able!\n";
next;
}
# Check ability to rsh/ssh to hosti
system " $remShellCmd $hosti /usr/bin/date 2>/dev/null 1>&2";
if ( $? != 0)
{
print " The host $hosti is not $remShell\'able!\n";
next;
}
$OSName = `$remShellCmd $hosti "/usr/bin/uname" 2>/dev/null`;
$OSLevel = `$remShellCmd $hosti "/usr/bin/oslevel" 2>/dev/null`;
}
else # For Current Host
{
$OSName = `/usr/bin/uname 2>/dev/null`;
$OSLevel = `/usr/bin/oslevel 2>/dev/null`;
}
# Make sure that the host is running AIX as an operating system.
chomp($OSName);
if ($OSName ne "AIX") #If NOT AIX Host Name
{
printf " The command \"uname\" shows that the host %s is not running \
\"AIX\"!\n", $hosti; next;
}
chomp($OSLevel);
if ($OSLevel lt "5.0.0.0")
{
printf "This script is not supported on the host %s !\n", $hosti;
next;
}
$aix_hosts[$nHosts]=$hosti;
$nHosts++;
}
}
close (TEMP_FILE);
if ($nHosts <= 0)
{
print "No $remShell\'able AIX Host available in $hostList!\n";
exit (-1);
}
}
# 7 ----------------------------------------------------------------------------
sub check_ping_remShell
# PURPOSE: To check if all the hosts in the @aix_hosts array is ping'able & \
rsh|ssh'able. {
for ($i = 0; $i < $nHosts ; $i++)
{
my $hosti = $aix_hosts[$i];
if (($hosti ne $cur_host) && ($hosti ne $cur_host_name))
{
if ($remShellTries[$i] >= 2)
{
print "Checking ping and $remShell to $hosti.....\n";
# Check the ping result to hosti
system "/usr/sbin/ping $hosti 1 1 2>/dev/null 1>&2";
if ( $? != 0)
{
print " The host $hosti is not ping'able!\n";
next;
}
# Check ability to rsh/ssh to hosti
system " $remShellCmd $hosti /usr/bin/date 2>/dev/null 1>&2";
if ( $? != 0)
{
print " The host $hosti is not $remShell\'able!\n";
next;
}
}
$remShellTries[$i] = 0;
}
}
}
# 8 -------------------------------------------------------------------------
sub calculate_loads
# PURPOSE: To calculate the CPU load and Memory load on each LPAR
# listed in <hostList> using rsh|ssh.
{
my $i;
my ($cmd1, $cmd2, $cmd3);
my ($cnt1, $cnt2, $cnt3);
my ($line1, $line2, $line3);
my @tmp3;
LOOP1:
for ($i=0; $i < $nHosts; $i++)
{
# Skip the host if rsh|ssh is not working
if ($remShellTries[$i] >= 2) { next LOOP1; }
$cmd1 = ""; $cmd2 = ""; $cmd3 = "";
if (($aix_hosts[$i] ne $cur_host) && ($aix_hosts[$i] ne $cur_host_name))
{
$cmd1 = "$remShellCmd $aix_hosts[$i] /usr/sbin/lsdev -Cc processor -S a \
|";
$cmd2 = "$remShellCmd $aix_hosts[$i] /usr/sbin/lsattr -El sys0 |";
$cmd3 = "$remShellCmd $aix_hosts[$i] /usr/bin/vmstat 1 2 |";
}
else
{
$cmd1 = "/usr/sbin/lsdev -Cc processor -S a |";
$cmd2 = "/usr/sbin/lsattr -El sys0 |";
$cmd3 = "/usr/bin/vmstat 1 2 |";
}
# $cmd1 gets the number of available CPUs on the host.
$cnt1 = 0;
open (TEMPCMD1,$cmd1);
while($line1 = <TEMPCMD1>)
{
chomp($line1);
if( ($line1 =~ m/Available/) && ($line1 =~ m/Processor/) )
{
$cnt1 = $cnt1 + 1;
}
}
if ($cnt1 <= 0)
{
# Host not reachable by rsh|ssh
$remShellTries[$i]++;
print "Host $aix_hosts[$i] is not reachable by $remShell!\n";
close (TEMPCMD1);
next LOOP1;
}
$nCPUs[$i] = $cnt1;
# $cmd2 gets the number of available LMBs (Logical Memory Blocks).
$cnt2 = 0;
open (TEMPCMD2,$cmd2);
while($line2 = <TEMPCMD2>)
{
chomp($line2);
if( ($line2 =~ /^realmem(\s*)(\d+)\s/))
{
$cnt2 = $2;
}
}
if ($cnt2 <= 0)
{
# Host not reachable by rsh|ssh
$remShellTries[$i]++;
print "Host $aix_hosts[$i] is not reachable by $remShell!\n";
close(TEMPCMD1); close(TEMPCMD2);
next LOOP1;
}
$nLMBs[$i] = $cnt2/(1024 * $lmb_size);
# $cmd3 gets the # of runnable threads, CPU Load,
# Free Real memory, and page steals on the host
@tmp3 = (0) x @tmp3;
$cnt3 = 0;
open (TEMPCMD3, $cmd3);
while($line3 = <TEMPCMD3>)
{
$line3 =~ s/^\s+//; # Remove the first character if it is a "space".
chomp($line3);
if ( $line3 =~ /^\d+\s+(\d+\s+){10}/ )
{
$cnt3 += 1;
if ($cnt3 == 2)
{
# Remove the leading blanks so that split works correctly.
$line3 =~ s/^\s+//;
@tmp3 = split(/\s+/,$line3);
}
}
}
if ($cnt3 <= 1)
{
# Host not reachable by rsh|ssh
$remShellTries[$i]++;
print "Host $aix_hosts[$i] is not reachable by $remShell!\n";
close(TEMPCMD1); close(TEMPCMD2); close(TEMPCMD3);
next LOOP1;
}
$runThrds[$i] = $tmp3[0]; # Number of runnable Threads
$cpuLoad[$i] = 100 - $tmp3[15]; # CPU load = 100% - idle%
$pgstl[$i] = $tmp3[7]; # Total page steals
$freeMem[$i] = $tmp3[3] * $PAGE_SIZE; # Free Real memory in KB
$memLoad[$i] = 100 - (100 * $freeMem[$i])/$cnt2;
# Memory Load
# Number of Runnable threads in past
&update_histRunThrds($i, $loop,$runThrds[$i]);
# CPU Load in the past
&update_histCpuLoad( $i, $loop,$cpuLoad[$i]);
# Number of page steals in past
&update_histPgStl($i, $loop,$pgstl[$i]);
# Memory Load in the past
&update_histMemLoad($i,$loop,$memLoad[$i]);
close(TEMPCMD1); close(TEMPCMD2); close(TEMPCMD3);
} # end FOR-loop
}
# 9 ----------------------------------------------------------------------------
sub update_histRunThrds
# PURPOSE: To update the # runnable-threads in the historical data.
{
local($host, $loop, $rth) = @_;
my $ii;
if ($loop < $histCnt)
{
$histRunThrds[$host]->[$loop] = $rth;
$sumHistRunThrds[$host] += $rth;
}
else
{
$sumHistRunThrds[$host] += $rth - $histRunThrds[$host]->[0];
for ($ii = 0; $ii < $histCnt - 1 ; $ii++)
{
$histRunThrds[$host]->[$ii] = $histRunThrds[$host]->[$ii+1];
}
$histRunThrds[$host]->[$ii] = $rth;
}
}
# 10 ----------------------------------------------------------------------------
sub update_histCpuLoad
# PURPOSE: To update the CPU load entries in the historical data
{
local($host, $loop, $load) = @_;
my $ii;
if ($loop < $histCnt)
{
$histCpuLoad[$host]->[$loop] = $load;
$sumHistCpuLoad[$host] += $load;
}
else
{
$sumHistCpuLoad[$host] += $load - $histCpuLoad[$host]->[0];
for ($ii = 0; $ii < $histCnt - 1 ; $ii++)
{
$histCpuLoad[$host]->[$ii] = $histCpuLoad[$host]->[$ii+1];
}
$histCpuLoad[$host]->[$ii] = $load;
}
}
# 11 ----------------------------------------------------------------------------
sub update_histPgStl
# PURPOSE: To update the #pageSteals in the historical data.
{
local($host, $loop, $pp) = @_;
my $ii;
if ($loop < $histCnt)
{
$histPgStl[$host]->[$loop] = $pp;
$sumHistPgStl[$host] += $pp;
}
else
{
$sumHistPgStl[$host] += $pp - $histPgStl[$host]->[0];
for ($ii = 0; $ii < $histCnt - 1 ; $ii++)
{
$histPgStl[$host]->[$ii] = $histPgStl[$host]->[$ii+1];
}
$histPgStl[$host]->[$ii] = $pp;
}
}
# 12 ----------------------------------------------------------------------------
sub update_histMemLoad
# PURPOSE: To update the memLoads in the historical data.
{
local($host, $loop, $load) = @_;
my $ii;
if ($loop < $histCnt)
{
$histMemLoad[$host]->[$loop] = $load;
$sumHistMemLoad[$host] += $load;
}
else
{
$sumHistMemLoad[$host] += $load - $histMemLoad[$host]->[0];
for ($ii = 0; $ii < $histCnt - 1 ; $ii++)
{
$histMemLoad[$host]->[$ii] = $histMemLoad[$host]->[$ii+1];
}
$histMemLoad[$host]->[$ii] = $load;
}
}
# 13 ----------------------------------------------------------------------------
sub result
# PURPOSE: To print the current loads (result)
{
my $nHashCpu = 0;
my $nHashMem = 0;
my $cpuLoadj = 0;
my $memLoadj = 0;
my $j;
system "/usr/bin/clear";
printf "CURRENT LOADs (CPU, MEMORY) -- snapshot taken every %d seconds.\n", \
$intvlSecs; print "______________ __________________________ \
_____________________________________\n"; print "| Hostname| |#P|#RTh/P| % CPU \
Load | |#LMB| #MB| #FR/s/L| % Memory Load|\n"; print "|------------| \
|--|------|---|----------| |----|------|--------|---|----------|\n"; LOOP1:
for ($j = 0; $j < $nHosts ; $j++)
{
# If rsh|ssh was not working, we did not collect any load;
# so skip this host.
if ($remShellTries[$j] >= 2) { next LOOP1; }
#Display the data on the screen
printf "|%12s| |%2d|%6.3f|",
substr($aix_hosts[$j],0,12),$nCPUs[$j],$runThrds[$j]/$nCPUs[$j];
$cpuLoadj = $scale * $cpuLoad[$j];
$nHashCpu = &round ($cpuLoadj);
printf "%3d",&round($cpuLoad[$j]);
print "|";
print "#" x $nHashCpu;
print " " x ($nCols - $nHashCpu);
printf "| |%4d|%6d|%8.3f|",$nLMBs[$j],($nLMBs[$j] * $lmb_size ), \
$pgstl[$j]/$nLMBs[$j]; $memLoadj = $scale * $memLoad[$j];
$nHashMem = &round ($memLoadj);
printf "%3d",&round($memLoad[$j]);
print "|";
print "#" x $nHashMem;
print " " x ($nCols - $nHashMem);
print "|\n";
}
print "|____________| |__|______|___|__________| \
|____|______|________|___|__________|\n"; printf "NOTE: 1 LMB of Memory = %d \
MB\n",$lmb_size;
}
# 14 ----------------------------------------------------------------------------
sub hist_result
# PURPOSE: To print the averaged historical loads (hist_result)
{
my $nHashHistCpu = 0;
my $nHashHistMem = 0;
my $histCpuLoadj = 0;
my $histMemLoadj = 0;
my $j;
printf "HISTORICAL LOADs -- averaged over the last %d snapshots.\n",$histCnt , \
$intvlSecs; print "_____________ ______________________________ \
_______________________________\n"; print "| Hostname||avg #RTh/P|% cpuLoad \
Hist|freP| |freL|Avg#FR/s/L|% memLoad Hist|\n"; print \
"|------------||----------|---|----------|----| |----|----------|---|----------|\n"; \
if (defined $histOut) {
# Update the histOut file
open (HOUT, ">", $histOut) or die "Cannot create $histOut: $!\n";
&update_histOut;
}
LOOP1:
for ($j = 0; $j < $nHosts ; $j++)
{
# If rsh|ssh was not working, we did not collect any load;
# so skip this host.
if ($remShellTries[$j] >= 2) { next LOOP1; }
#Display the historical data on the screen
$histRqDepthj = $sumHistRunThrds[$j]/($nCPUs[$j] * $histCnt);
printf "|%12s||%10.3f|",substr($aix_hosts[$j],0,12),$histRqDepthj;
$histCpuLoadj = $sumHistCpuLoad[$j] / $histCnt;
$nHashHistCpu = &round ($scale * $histCpuLoadj);
printf "%3d",&round($sumHistCpuLoad[$j]/$histCnt);
print "|";
print "#" x $nHashHistCpu;
print " " x ($nCols - $nHashHistCpu);
if ($histCpuLoadj < $trgrCpuLoad)
{
$freP = int(($trgrCpuLoad - $histCpuLoadj) *
$nCPUs[$j] / $trgrCpuLoad);
}
else { $freP = 0; }
printf "|%4d|", $freP;
$histMemLoadj = $sumHistMemLoad[$j]/$histCnt;
if ($histMemLoadj < $trgrMemLoad)
{
$freL = int (($trgrMemLoad - $histMemLoadj) *
$nLMBs[$j] / $trgrMemLoad);
}
else { $freL = 0; }
printf " |%4d", $freL;
printf "|%10.3f|",$sumHistPgStl[$j]/($nLMBs[$j] * $histCnt);
$nHashHistMem = &round ($scale * $histMemLoadj);
printf "%3d",&round($sumHistMemLoad[$j]/$histCnt);
print "|";
print "#" x $nHashHistMem;
print " " x ($nCols - $nHashHistMem);
print "|\n";
#Update the file histOut
if (defined $histOut)
{
printf HOUT "%12s\t%10.3f %10.3f %4d %4d %10.3f %10.3f\n",
substr($aix_hosts[$j],0,12),
$sumHistRunThrds[$j]/($nCPUs[$j] * $histCnt),
$sumHistCpuLoad[$j]/$histCnt,
$freP,
$freL,
$sumHistPgStl[$j]/($nLMBs[$j] * $histCnt),
$sumHistMemLoad[$j]/($histCnt);
}
}
if (defined $histOut)
{
printf HOUT "\nNOTE: 1 LMB of Memory = %d MB\n",$lmb_size;
close (HOUT);
}
print "|____________||__________|___|__________|____| \
|____|__________|___|__________|\n";
}
# 15 ----------------------------------------------------------------------------
sub update_histOut
# PURPOSE: To update the <histOut> history file.
{
printf HOUT "Average Loads over the last %d snapshots:\n", $histCnt;
printf HOUT "========================================\n";
printf HOUT "Snapshots are taken at every %d seconds.\n", $intvlSecs;
printf HOUT "Avg#RTh/P : Avg # runnable threads per CPU, averaged over \
history. \n"; printf HOUT "CPU Load Hist: 100% - CPU-idle-percentage, averaged \
over history \n"; print HOUT "freP : # of excess(unused/freeable) CPUs in \
the LPAR available for DR.\n"; print HOUT "freL : # of \
excess(unused/freeable) LMBs in the LPAR available for DR.\n"; printf HOUT \
"Avg#FR/s/L : Avg # Pages FReed by Page Replacements per sec per LMB, averaged \
over history.\n"; printf HOUT "Mem Load Hist: the % of non-free pages in the AIX \
instance, averaged over history.\n\n"; printf HOUT " Hostname\t Avg#RTh/P cpuLoad \
Hist freP freL Avg#FR/s/L MemLoad Hist\n"; printf HOUT " --------\t --------- \
------------ ---- ---- ---------- ------------\n"; }
# 16 ----------------------------------------------------------------------------
sub round
# PURPOSE: To calculate the rounding up of a floating point value.
{
my ($var) = shift;
if (($var - int($var)) >= 0.5) { return (int($var) + 1); }
else { return (int($var)); }
}
["setEnv.p570" (text/plain)]
# PURPOSE: To set up environment variables before using the DLPAR Toolset,
# for ksh or sh users.
# TO INVOKE from ksh or sh, type: . ./setEnv
# If the subdirectory containing this file is in your PATH,
# then you only need to type: . setEnv
# TO VIEW settings, type: env | grep DR_
# COMPANION file: unsetEnv
# COMPONENT OF: IBM pSeries DLPAR Toolset 2.0.2.0, September 2004.
# COPYRIGHT: IBM Corporation, 2002,2003,2004. All rights reserved.
# Author: Joefon Jann 2003/3/31.
# Last updated: 2004/8/31.
export DR_REMOTE_SHELL=rsh # To connect to AIX hosts (rsh or ssh)
export DR_TS_DIR=/opt/dlparToolset/bin
export DR_HMC_HOST=curie.watson.ibm.com
export DR_HMC_USER=hscroot
export DR_MANAGED_SYS=p570Curie
export DR_HOST_LIST=$DR_TS_DIR/hostList.p570 # Used in directories 1,2,5
# For lparLsCfgs.pl:
export DR_OUTFILE_LSCFG=~/lparLsCfgs.outFile
# For lparLsCfgsAll.pl:
export DR_OUTFILE_LSCFG_ALL=~/lparLsCfgsAll.outFile
# For lparLsCfgsIO.pl:
export DR_OUTFILE_LSCFG_IO=~/lparLsCfgsIO.outFile
# For lparLsCfgs.pl:
export DR_INTVLSECS_LSLOAD=2 # Seconds.
export DR_HISTCNT_LSLOAD=5 # Number of historical snapshots.
export DR_HISTOUT_LSLOAD=~/lparLsLoads.histOut
# For lparLoadRM.pl:
export DR_HOSTS_WTS=$DR_TS_DIR/hostsWts.p570 # Defines an LPAR group.
export DR_INTVLSECS_LOADRM=4 # Seconds.
export DR_HISTCNT_LOADRM=5 # Number of historical snapshots.
export DR_TRGR_CPU_LOAD=98 # Integer Percentage of non-idle CPU time.
export DR_TRGR_RQ_DEPTH=1 # Integer Number of threads/CPU/sec waiting
# for CPU service.
export DR_TRGR_MEM_LOAD=85 # Integer Percentage of non-free real memory.
export DR_TRGR_PGSTEALS=0 # Integer Number of page-steals/LMB/sec.
# For moveSlot.pl:
export DR_IO_SLOT=21020003 # For Pwr4 systems, set this to the PhysicalLocation
# attribute of an IO slot.
# For Pwr5 systems, set this to a DRC Index.
# Other environment variables that may be rarely changed:
export DR_RSVD_FREP_CPUS=0
# Reserved CPUs in the Free Pool. This number of CPUs will always be left in
# the Free Pool of the SMP by the lparLoadRM.pl and lparSetCfgs.pl scripts.
# To disable the use of the CPUs in the Free Pool by lparLoadRM.pl or
# lparSetCfgs.pl, specify a value that is greater than or equal
# to the total number of CPUs in the SMP, e.g. 99999
export DR_RSVD_FREP_LMBS=0
# Reserved LMBs in the Free Pool. This number of LMBs will always be left in
# the Free Pool of the SMP by the lparLoadRM.pl and lparSetCfgs.pl scripts.
# To disable the use of the LMBs in the Free Pool by lparLoadRM.pl or
# lparSetCfgs.pl, specify a value which is greater than or equal
# to the total number of LMBs in the SMP, e.g. 99999
export DR_DEBUG_LVL=0
# Debug level to be used by "chhwres" command.
# Possible values are integers from 0 to 5, indicating
# minimal to maximal amounts of debug info respectively.
# To display the sorted values on the screen:
env | grep DR_ | sort
["unsetEnv" (text/plain)]
# PURPOSE: To unset DR_ environment variables previously set for the
# DLPAR Toolset, for ksh or sh users.
# COMPANION file: setEnv
# TO INVOKE from ksh or sh, type: . ./unsetEnv
# If the subdirectory containing this file is in your PATH,
# then you only need to type: . unsetEnv
# TO VERIFY settings, type: env | grep DR_
# COMPONENT OF: IBM pSeries DLPAR Toolset 2.0.2.0, September 2004.
# COPYRIGHT: IBM Corporation, 2002,2003,2004. All rights reserved.
# Author: Joefon Jann 2003/3/31
unset DR_REMOTE_SHELL
unset DR_TS_DIR
unset DR_HMC_HOST
unset DR_HMC_USER
unset DR_MANAGED_SYS
unset DR_HOST_LIST
unset DR_OUTFILE_LSCFG
unset DR_OUTFILE_LSCFG_ALL
unset DR_OUTFILE_LSCFG_IO
unset DR_INTVLSECS_LSLOAD
unset DR_HISTCNT_LSLOAD
unset DR_HISTOUT_LSLOAD
unset DR_HOSTS_WTS
unset DR_INTVLSECS_LOADRM
unset DR_HISTCNT_LOADRM
unset DR_TRGR_CPU_LOAD
unset DR_TRGR_RQ_DEPTH
unset DR_TRGR_MEM_LOAD
unset DR_TRGR_PGSTEALS
unset DR_IO_SLOT
unset DR_RSVD_FREP_CPUS
unset DR_RSVD_FREP_LMBS
unset DR_DEBUG_LVL
# For verification:
env | grep DR_ | sort
["lparLsCfgs.pl" (application/octet-stream)]
#! /usr/bin/perl
# PURPOSE: To print the min, current, and max #CPUs and #LMBs of a list of LPARs
# with hostnames are given in a customer-provided hostList file.
# SYNTAX:
# lparLsCfgs.pl [-o <outFile>] [-f <hostList>]
# [-hmc <hmcHost>] [-u <hmcUser>] [-m <managedSys>] [-h]
# See subroutine syntax() for the details.
#
# COMPONENT OF: IBM pSeries DLPAR Toolset 2.0.2.0, September 2004.
# COPYRIGHT: IBM Corporation, 2002,2003,2004. All rights reserved.
# SUBROUTINES IN THIS FILE
# main
# 1 read_arguments
# 2 syntax
# 3 check_hmc
# 4 check_managed_system_p4hmc
# 5 check_managed_system_p5hmc
# 6 get_lpar_info
# 7 get_lpar_info_p4hmc
# 8 get_lpar_info_p4hmc
# 9 read_hostlist
# 10 check_lpar
# 11 get_current_config
# 12 get_current_config_p4hmc
# 13 get_current_config_p5hmc
#
# AUTHORs: Yorktown team: J. Jann, R. Burugula, N. Dubey 9/2002
# CHANGELOG: Last updated 2004/08/24.
@hmc_lpars=(); # Array of LPAR names of all the LPARs of the input <managedSys>
# as reported by the HMC.
@aix_lpars=(); # Array of LPAR names of LPARs with the following features.
# - The associated hostName is found in <hostList>,
# - The associated host is running AIX as an OS.
# - The associated host is rsh|ssh'able from the current Host.
%aix_hosts=(); # List of hostnames for each LPAR in @aix_lpars
%dlpar=(); # To check whether the LPAR is DLPAR'able or not.
$HSC_CMD_PATH = ""; # Needed if restricted bash shell is not available
$hmc_type = ""; # POWER4 or POWER5 HMC
$hmc_version = ""; # To store Release and Version of HMC
$hmc_bash = ""; # Restricted or Non-Restricted Bash Shell
%min_cpus=();# min_cpus for a given lparName, used for POWER5 HMC only
%cur_cpus=();# cur_cpus for a given lparName, used for POWER5 HMC only
%max_cpus=();# max_cpus for a given lparName, used for POWER5 HMC only
%min_lmbs=();# min_lmbs for a given lparName, used for POWER5 HMC only
%cur_lmbs=();# cur_lmbs for a given lparName, used for POWER5 HMC only
%max_lmbs=();# max_lmbs for a given lparName, used for POWER5 HMC only
$free_cpus = 0; # Free CPUs available in the Free Pool.
$free_lmbs = 0; # Free LMBs available in the Free Pool.
$lmb_size = 0;
$cur_host_name =`/usr/bin/hostname`;
chomp($cur_host_name);
$cur_host =`/usr/bin/hostname -s `;
chomp($cur_host);
$cur_user = $ENV{"USER"} ;
$lsres = ""; # HMC command lshwres
$lssys = ""; # HMC command lssyscfg
#=============================================================================
# MAIN ROUTINE -- This main routine calls 4 subroutines, which call others.
# A) Read the arguments
&read_arguments(@ARGV);
# B) Check the status of the HMC, the HMC user, and the Managed System
&check_hmc;
# C) Read the input <hostList> file
print "Reading the file $hostList .....\n";
&read_hostlist;
# D) Getting the current configurations
print "Retrieving the current configuration from HMC .....\n";
print "NOTE: It takes roughly 30 to 45 seconds to get the current\n";
print " configuration of each LPAR from the HMC.\n\n";
&get_current_config;
exit (0);
# 1 --------------------------------------------------------------------------
sub read_arguments
# Parse the input arguments
{
undef $outFile;
undef $hostList;
undef $hmcHost;
undef $hmcUser;
undef $cec;
while (@_)
{
my $option = shift;
if ($option eq "-h")
{
&syntax;
}
elsif ($option eq "-o")
{
$outFile = shift;
}
elsif ($option eq "-f")
{
$hostList = shift;
}
elsif ($option eq "-hmc")
{
$hmcHost = shift;
}
elsif ($option eq "-u")
{
$hmcUser = shift;
}
elsif ($option eq "-m")
{
$cec = shift;
}
else
{
&syntax;
}
}
if ((! defined $outFile) && (defined $ENV{"DR_OUTFILE_LSCFG"}))
{
$outFile = $ENV{"DR_OUTFILE_LSCFG"};
}
if ((! defined $hostList) && (defined $ENV{"DR_HOST_LIST"}))
{
$hostList = $ENV{"DR_HOST_LIST"};
}
if ((! defined $hmcHost) && (defined $ENV{"DR_HMC_HOST"}))
{
$hmcHost = $ENV{"DR_HMC_HOST"};
}
if ((! defined $hmcUser) && (defined $ENV{"DR_HMC_USER"}))
{
$hmcUser = $ENV{"DR_HMC_USER"};
}
if ((! defined $cec) && (defined $ENV{"DR_MANAGED_SYS"}))
{
$cec = $ENV{"DR_MANAGED_SYS"};
}
if (! defined $hostList)
{
print "ERROR: <hostList> file was not specified.\n";
print " You can specify this as -f <hostList> argument\n";
print " or as DR_HOST_LIST environment variable\n";
&syntax;
}
if (! defined $hmcHost)
{
print "ERROR: <hmcHost> was not specified.\n";
print " You can specify this as -hmc <hmcHost> argument\n";
print " or as DR_HMC_HOST environment variable\n";
&syntax;
}
if (! defined $hmcUser)
{
print "ERROR: <hmcUser> was not specified.\n";
print " You can specify this as -u <hmcUser> argument\n";
print " or as DR_HMC_USER environment variable\n";
&syntax;
}
if (! defined $cec)
{
print "ERROR: <managedSys> was not specified.\n";
print " You can specify this as -m <managedSys> argument\n";
print " or as DR_MANAGED_SYS environment variable\n";
&syntax;
}
if ($ENV{"DR_REMOTE_SHELL"} eq "ssh")
{
$remShell = "ssh";
$remShellCmd = "/usr/bin/ssh"
}
else
{
$remShell = "rsh"; # The default shell
$remShellCmd = "/usr/bin/rsh";
}
# Clear the screen
system "/usr/bin/clear";
printf "This script is being run by user \"%s\" on host \"%s\".\n",
$cur_user, $cur_host;
print "INPUT:\n";
print " Host list = ", $hostList, "\n";
print " hmcHost = ", $hmcHost, "\n";
print " hmcUser = ", $hmcUser, "\n";
print " Managed System = ", $cec, "\n";
print " RemoteShell for AIX hosts = ", $remShell, "\n";
if (defined $outFile)
{
open (FHANDLE, "> $outFile") || die "Cannot create the file $outFile: $! \n";
print " output File = ", $outFile, "\n";
}
open (HSTLST, "<", $hostList) or die "Cannot open $hostList for reading: $!\n";
}
# 2 --------------------------------------------------------------------------
sub syntax
# PURPOSE: Print the syntax of this script
{
print "\nSYNTAX:\n";
print "lparLsCfgs.pl [-o <outFile>] [-f <hostList>] \n";
print " [-hmc <hmcHost>] [-u <hmcUser>] [-m <managedSys>] [-h]\n";
print " where \n";
print " <outFile> : File to store its output\n";
print " <hostList> : File containing hostnames of the LPAR group.\n";
print " \n";
print " <hmcHost> : Hostname of the HMC\n";
print " <hmcUser> : Login-name on the HMC which was setup\n";
print " for unattended remote ssh command execution\n";
print " <managedSys>: Name of the Managed System (SMP).\n";
print " See HMC Operations Guide for more details.\n";
print " -h : Prints this syntax help; cannot be used with other flags.\n";
print "E.g.: $0 -o outFile -f hostList -hmc hmc.mydomain.com -u grm_ssh -m \
DR\n\n"; exit;
}
# 3 --------------------------------------------------------------------------
sub check_hmc
# PURPOSE: To check the status of the HMC, the HMC SSH user, and the Managed System.
{
# Check whether HMC is up or not
printf "\nChecking ping and ssh to %s.....\n", $hmcHost;
system "/usr/sbin/ping $hmcHost 1 1 2>/dev/null 1>&2";
if ( $? != 0)
{
printf "The hmcHost \"%s\" is not ping'able !\n", $hmcHost;
exit (1);
}
system "/usr/bin/ssh $hmcUser\@$hmcHost date 2>/dev/null 1>&2";
if ( $? != 0)
{
print "SSH connection from $cur_user\@$cur_host to $hmcUser\@$hmcHost failed!\n";
exit (1);
}
# Check if the restricted bash shell is set.
my $hmcInfo =`/usr/bin/ssh $hmcUser\@$hmcHost " lshmc -v " 2>&1`;
if ( $hmcInfo =~ /bash:/ ) # If restricted shell is not set.
{
$HSC_CMD_PATH = "/opt/hsc/bin/";
$hmc_bash = "Non-Restricted Bash shell";
$hmcInfo = `/usr/bin/ssh $hmcUser\@$hmcHost " ${HSC_CMD_PATH}lshmc -v " 2>&1`;
}
else
{
$hmc_bash = "Restricted Bash shell";
}
my @tmpHmc = split (/\n/,$hmcInfo);
for (my $i=0; $i <= $#tmpHmc; $i++)
{
if ($tmpHmc[$i] =~ /RM\s+(\S+)/)
{
$hmc_version = $1;
}
}
chomp($hmc_version);
# Check the HMC Type
if ($hmc_version =~ /V(\d)/)
{
if ($1 le "3")
{
$hmc_type = "POWER4 HMC";
}
else # i.e. if ($1 eq "4" )
{
$hmc_type = "POWER5 HMC";
}
}
print "HMC Commands are running under $hmc_bash on $hmc_type \
($hmc_version).....\n"; $lssys = "/usr/bin/ssh $hmcUser\@$hmcHost \
${HSC_CMD_PATH}lssyscfg -m $cec"; $lsres = "/usr/bin/ssh $hmcUser\@$hmcHost \
${HSC_CMD_PATH}lshwres -m $cec"; if ( $hmc_type eq "POWER4 HMC")
{
if (&check_managed_system_p4hmc != 0) #If the managed system is not operating.
{
exit (1);
}
}
else
{
if (&check_managed_system_p5hmc != 0) #If the managed system is not operating.
{
exit (1);
}
}
&get_lpar_info;
}
# 4 --------------------------------------------------------------------------
sub check_managed_system_p4hmc
# PURPOSE: Check managed system on POWER5 HMC
{
if ( $hmc_version ge "R3V2.4") # Only if the HMC has Release and Version >= \
R3V2.4 {
my $cmd = "";
$cmd = "$lssys -r sys --all -Fname:state:lmb_size |";
open (TEMPCMD, $cmd);
while($line = <TEMPCMD>)
{
chomp($line);
my ($sysName, $sysState, $lmbSize)= split(/:/,$line);
if ($sysName eq $cec)
{
if ( $sysState eq Ready )
{
close (TEMPCMD);
$lmb_size =$lmbSize;
return (0);
}
printf "The managed system \"%s\" is not in the \"Ready\" state!\n", $cec;
close (TEMPCMD);
return (-1);
}
}
print "The HMC command \"lssyscfg\" does not show $cec as a \"Ready\" managed \
system!\n"; close (TEMPCMD);
return (-1);
}
else
{
my $cecstr = "";
$cecstr = `/usr/bin/ssh $hmcUser\@$hmcHost " ${HSC_CMD_PATH}get_cec_state -m $cec " \
2>&1`; chomp($cecstr);
# Check if the Managed System is not in the Ready state.
if ( !($cecstr =~ /Ready/) )
{
print "The HMC command \" ${HSC_CMD_PATH}get_cec_state\" does not show";
print " $cec as a \"Ready\" managed system!\n";
return (-1);
}
$lmb_size = 256;
return (0);
}
}
# 5 --------------------------------------------------------------------------
sub check_managed_system_p5hmc
# PURPOSE: Check managed system on POWER5 HMC
{
my $cmd = "$lssys -r sys -Fname:state |";
open (TEMPCMD, $cmd);
while($line = <TEMPCMD>)
{
chomp($line);
my ($sysName, $sysState)= split(/:/,$line);
if ($sysName eq $cec)
{
if ( $sysState eq Operating )
{
close (TEMPCMD);
$lmb_size = `$lsres -r mem --level sys -Fmem_region_size`;
chomp($lmb_size);
return (0);
}
printf "The managed system \"%s\" is not in the \"Operating\" state!\n", $cec;
close (TEMPCMD);
return (-1);
}
}
print "The HMC command \"lssyscfg\" does not show $cec as an \"Operating\" \
managed system!\n"; close (TEMPCMD);
return (-1);
}
# 6 ---------------------------------------------------------------------------
sub get_lpar_info
# PURPOSE: Get name, dlpar'ability of LPARs of the given managed system
{
if ( $hmc_type eq "POWER4 HMC")
{
&get_lpar_info_p4hmc;
}
else
{
&get_lpar_info_p5hmc;
}
}
# 7 ---------------------------------------------------------------------------
sub get_lpar_info_p4hmc
# PURPOSE: Get name, dlpar'ability of LPARs of the given managed system on POWER4 HMC
{
if ( $hmc_version ge "R3V2.4") # Only if the HMC has Release and Version >= \
R3V2.4 {
my $cmd = "$lssys -r lpar --all -Fname:state:dlpar_capability |";
open (TEMPCMD, $cmd);
while($line = <TEMPCMD>)
{
chomp($line);
my ($name, $state, $dr)= split(/:/,$line);
if ( $state eq "Running")
{
push (@hmc_lpars,$name);
$dlpar{$name} = $dr;
}
}
close (TEMPCMD);
}
else
{
# Get the all partition names on HMC for given <managedSys>
my $lparstr = `/usr/bin/ssh $hmcUser\@$hmcHost " \
${HSC_CMD_PATH}query_partition_names -m $cec " 2>/dev/null`; @hmc_lpars = split \
(/\n/, $lparstr); # Remove the first 2 entries, which are
# "Logical Partitions :" and "--------------------"
shift (@hmc_lpars);
shift (@hmc_lpars);
}
}
# 8 ---------------------------------------------------------------------------
sub get_lpar_info_p5hmc
# PURPOSE: Get name, dlpar'ability of LPARs of the given managed system on POWER5 HMC
{
my $cmd = "$lssys -r lpar -Fname:lpar_id:state |";
my %lpar_id2name=();
open (TEMPCMD, $cmd);
while($line = <TEMPCMD>)
{
chomp($line);
my ($name, $id , $state)= split(/:/,$line);
if ( $state eq "Running")
{
push (@hmc_lpars,$name);
}
$lpar_id2name{$id} = $name;
}
close (TEMPCMD);
# Now check the dlpar'ability
my $part_id ;
my $dcaps;
my $cmd1 = "/usr/bin/ssh $hmcUser\@$hmcHost lspartition -dlpar |";
open (TEMPCMD1, $cmd1);
while($line = <TEMPCMD1>)
{
chomp($line);
if ($line =~ m/Partition:\<(\d+)\,\s+/)
{
$part_id = $1;
$part_id =~ s/\s+//; # Remove white space character if any
}
if ($line =~ m/\s*DCaps:\<(\w+)\>\s*/)
{
$dcaps = $1;
$dcaps =~ s/\s+//; # Remove white space character if any
if ($dcaps =~ /f$/) # Dcaps should 'f' at the end
{
$dlpar{$lpar_id2name{$part_id}} = "YES"
}
else
{
$dlpar{$lpar_id2name{$part_id}} = "NO"
}
}
}
close (TEMPCMD1);
}
# 9 ---------------------------------------------------------------------------
sub read_hostlist
# PURPOSE: To read the <hostList> file &
# to get the hostname & LPARname of each active LPAR via rsh|ssh.
{
my $lparInfo = "";
my $OSName = "";
my $OSLevel = "";
LOOP1:
while (<HSTLST>)
{
# Skip the comment lines (beginning with '#')
if (/^\#/) { next LOOP1; }
$_ =~ s/\s+/ /g; # Remove extra white space characters
$_ =~ s/^ //; # Remove the first character if it is a "space".
# This is required for split function to work properly.
if (/^ *$/) { next LOOP1; } # Blank line
if (/(\S+)\s*/)
{
my $hosti = $1;
$hosti =~ s/\s+//;
if (($hosti ne $cur_host) && ($hosti ne $cur_host_name))
{
print "Checking ping and $remShell to $hosti.....\n";
# Check the ping result to hosti
system "/usr/sbin/ping $hosti 1 1 2>/dev/null 1>&2";
if ( $? != 0)
{
print " The host $hosti is not ping'able!\n";
next;
}
# Check ability to rsh/ssh to hosti
system " $remShellCmd $hosti /usr/bin/date 2>/dev/null 1>&2";
if ( $? != 0)
{
print " The host $hosti is not $remShell\'able!\n";
next;
}
$OSName = `$remShellCmd $hosti "/usr/bin/uname" 2>/dev/null`;
$lparInfo = `$remShellCmd $hosti "/usr/bin/uname -L" 2>/dev/null`;
$OSLevel = `$remShellCmd $hosti "/usr/bin/oslevel" 2>/dev/null`;
}
else # For the Current Host
{
$OSName = `/usr/bin/uname 2>/dev/null`;
$lparInfo = `/usr/bin/uname -L 2>/dev/null`;
$OSLevel = `/usr/bin/oslevel 2>/dev/null`;
}
# Make sure that the host is running AIX as an operating system.
chomp($OSName);
if ($OSName ne "AIX") #If NOT AIX Host Name
{
printf " The command \"uname\" shows that the host %s is not running \
\"AIX\"!\n", $hosti; next;
}
# Now make sure that the lpar_name exists on the given managed system.
chomp($lparInfo);
$lparInfo =~ s/^\s+//;
my ($lparId, $lparName) = split(/ +/,$lparInfo,2);
if (&check_lpar($lparName) != 0) #If LPAR name does not match
{
printf " Partition name of host %s does not match partitions managed \
by HMC!\n", $hosti; next;
}
push(@aix_lpars, $lparName);
$aix_hosts{$lparName}=$hosti;
if ( ( $hmc_type eq "POWER4 HMC") && ($hmc_version lt "R3V2.4" ))
{
chomp($OSLevel);
$dlpar{$lparName} =($OSLevel ge "5.2.0.0") ? "YES" : " NO";
}
}
}
close (HSTLST);
if ($#aix_lpars < 0)
{
print "No $remShell\'able AIX Hosts with valid LPAR names in $hostList!\n";
exit (-1);
}
}
# 10 ---------------------------------------------------------------------------
sub check_lpar
# PURPOSE: To check the validity of the LPAR name for the given host
{
my ($lparName) = shift;
for ($i=0; $i <= $#hmc_lpars; $i++)
{
if ($hmc_lpars[$i] eq $lparName)
{
return (0);
}
}
return (-1);
}
# 11 ---------------------------------------------------------------------------
sub get_current_config
# NOTE: The current configuration should be obtained only for those
# LPARs which are active (i.e. rsh|ssh'able).
{
if (defined $outFile)
{
open (STDOUT, "| tee $outFile") ;
}
print STDOUT " Hostname LPARname CPUmin CPUcur CPUmax LMBmin LMBcur \
LMBmax DLPAR\n"; print STDOUT "============ ================== ====== ====== ====== \
====== ====== ====== =====\n";
if ( $hmc_type eq "POWER4 HMC")
{
&get_current_config_p4hmc;
}
else
{
&get_current_config_p5hmc;
}
printf STDOUT "Available (=unreserved) #CPUs in the Free Pool = %d \n", \
$free_cpus; printf STDOUT "Available (=unreserved) #LMBs in the Free Pool = %d\n", \
$free_lmbs; printf STDOUT "NOTE: 1 LMB of Memory = %d MB \n", $lmb_size;
if (defined $outFile)
{
close (STDOUT);
close (FHANDLE);
}
}
# 12 -------------------------------------------------------------------------
sub get_current_config_p4hmc
# PURPOSE: Get current CPU and Memory configuration on POWER4 HMC
{
foreach $lpar (@aix_lpars)
{
my $line;
my $cnt=0;
my ($minCpus,$curCpus,$maxCpus);
my ($minLmbs,$curLmbs,$maxLmbs);
my $cmd = "$lsres -r ALL -p $lpar -Fmin:allocated:max:free -y sys |";
open (TEMPCMD, $cmd);
while($line = <TEMPCMD>)
{
chomp($line);
if ($line =~ m/(\d+):(\d+):(\d+):(\d+)/)
{
$cnt++;
if ($cnt == 1) # CPU configurations
{
($minCpus,$curCpus,$maxCpus,$free_cpus) = split(/:/, $line);
}
if ($cnt == 2) # Memory configurations
{
($minLmbs,$curLmbs,$maxLmbs,$free_lmbs) = split(/:/, $line);
}
}
}
close (TEMPCMD);
printf STDOUT "%-12s %-18s %6d %6d %6d %6d %6d %6d %5s\n",
substr($aix_hosts{$lpar},0,12),substr($lpar,0,18),
$minCpus, $curCpus, $maxCpus,
$minLmbs, $curLmbs, $maxLmbs, $dlpar{$lpar};
}
}
# 13 -------------------------------------------------------------------------
sub get_current_config_p5hmc
# PURPOSE: Get current CPU and Memory configuration on POWER5 HMC
{
my $cmd1 = "$lsres -r proc --level lpar \
-Flpar_name:curr_min_procs:curr_procs:curr_max_procs |"; my $cmd2 = "$lsres -r mem \
--level lpar -Flpar_name:curr_min_mem:curr_mem:curr_max_mem |"; open (TEMPCMD, \
$cmd1); while($line = <TEMPCMD>)
{
chomp($line);
my ($name,$minCpus,$curCpus,$maxCpus) = split(/:/, $line);
$min_cpus{$name} = $minCpus;
$cur_cpus{$name} = $curCpus;
$max_cpus{$name} = $maxCpus;
}
close (TEMPCMD);
open (TEMPCMD, $cmd2);
while($line = <TEMPCMD>)
{
chomp($line);
my ($name,$minMems,$curMems,$maxMems) = split(/:/, $line);
$min_lmbs{$name} = $minMems / $lmb_size;
$cur_lmbs{$name} = $curMems / $lmb_size;
$max_lmbs{$name} = $maxMems / $lmb_size;
}
close (TEMPCMD);
foreach $lpar (@aix_lpars)
{
printf STDOUT "%-12s %-18s %6d %6d %6d %6d %6d %6d %5s\n",
substr($aix_hosts{$lpar},0,12),substr($lpar,0,18),
$min_cpus{$lpar}, $cur_cpus{$lpar}, $max_cpus{$lpar},
$min_lmbs{$lpar}, $cur_lmbs{$lpar}, $max_lmbs{$lpar},$dlpar{$lpar};
}
$free_cpus = `$lsres -r proc --level sys -Fcurr_avail_sys_proc_units`;
my $freeMems = `$lsres -r mem --level sys -Fcurr_avail_sys_mem`;
$free_lmbs = $freeMems / $lmb_size;
}
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic