[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