2007-11-16 19:47:00 +00:00
|
|
|
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
|
|
|
|
|
|
|
package xCAT::PPCinv;
|
|
|
|
use strict;
|
|
|
|
use Getopt::Long;
|
|
|
|
use xCAT::PPCcli qw(SUCCESS EXPECT_ERROR RC_ERROR NR_ERROR);
|
2008-04-12 14:53:11 +00:00
|
|
|
use xCAT::Usage;
|
2007-11-16 19:47:00 +00:00
|
|
|
|
|
|
|
|
|
|
|
##########################################################################
|
|
|
|
# Parse the command line for options and operands
|
|
|
|
##########################################################################
|
|
|
|
sub parse_args {
|
|
|
|
|
|
|
|
my $request = shift;
|
2008-04-12 14:53:11 +00:00
|
|
|
my $command = $request->{command};
|
2007-11-16 19:47:00 +00:00
|
|
|
my $args = $request->{arg};
|
|
|
|
my %opt = ();
|
|
|
|
my @rinv = qw(bus config model serial all);
|
|
|
|
|
|
|
|
#############################################
|
|
|
|
# Responds with usage statement
|
|
|
|
#############################################
|
|
|
|
local *usage = sub {
|
2008-04-12 14:53:11 +00:00
|
|
|
my $usage_string=xCAT::Usage->getUsage($command);
|
|
|
|
return( [ $_[0], $usage_string]);
|
2007-11-16 19:47:00 +00:00
|
|
|
};
|
|
|
|
#############################################
|
|
|
|
# Process command-line arguments
|
|
|
|
#############################################
|
|
|
|
if ( !defined( $args )) {
|
|
|
|
return(usage( "No command specified" ));
|
|
|
|
}
|
|
|
|
#############################################
|
|
|
|
# Checks case in GetOptions, allows opts
|
|
|
|
# to be grouped (e.g. -vx), and terminates
|
|
|
|
# at the first unrecognized option.
|
|
|
|
#############################################
|
|
|
|
@ARGV = @$args;
|
|
|
|
$Getopt::Long::ignorecase = 0;
|
|
|
|
Getopt::Long::Configure( "bundling" );
|
|
|
|
|
2008-04-12 14:53:11 +00:00
|
|
|
if ( !GetOptions( \%opt, qw(V|Verbose) )) {
|
2007-11-16 19:47:00 +00:00
|
|
|
return( usage() );
|
|
|
|
}
|
|
|
|
####################################
|
|
|
|
# Check for "-" with no option
|
|
|
|
####################################
|
|
|
|
if ( grep(/^-$/, @ARGV )) {
|
|
|
|
return(usage( "Missing option: -" ));
|
|
|
|
}
|
|
|
|
####################################
|
|
|
|
# Unsupported command
|
|
|
|
####################################
|
|
|
|
my ($cmd) = grep(/^$ARGV[0]$/, @rinv );
|
|
|
|
if ( !defined( $cmd )) {
|
|
|
|
return(usage( "Invalid command: $ARGV[0]" ));
|
|
|
|
}
|
|
|
|
####################################
|
|
|
|
# Check for an extra argument
|
|
|
|
####################################
|
|
|
|
shift @ARGV;
|
|
|
|
if ( defined( $ARGV[0] )) {
|
|
|
|
return(usage( "Invalid Argument: $ARGV[0]" ));
|
|
|
|
}
|
|
|
|
####################################
|
|
|
|
# Set method to invoke
|
|
|
|
####################################
|
|
|
|
$request->{method} = $cmd;
|
|
|
|
return( \%opt );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
##########################################################################
|
|
|
|
# Returns VPD (model-type,serial-number)
|
|
|
|
##########################################################################
|
|
|
|
sub enumerate_vpd {
|
|
|
|
|
|
|
|
my $exp = shift;
|
|
|
|
my $mtms = shift;
|
|
|
|
my $hash = shift;
|
2008-03-06 14:46:13 +00:00
|
|
|
my $filter = "type_model,serial_num";
|
2007-11-16 19:47:00 +00:00
|
|
|
my @vpd;
|
|
|
|
|
|
|
|
my ($name) = keys %{$hash->{$mtms}};
|
|
|
|
my $type = @{$hash->{$mtms}->{$name}}[4];
|
|
|
|
|
2008-03-06 14:46:13 +00:00
|
|
|
##################################
|
2007-11-16 19:47:00 +00:00
|
|
|
# BPAs
|
2008-03-06 14:46:13 +00:00
|
|
|
##################################
|
|
|
|
if ( $type =~ /^bpa$/ ) {
|
2007-11-16 19:47:00 +00:00
|
|
|
my $filter = "type_model,serial_num";
|
|
|
|
my $frame = xCAT::PPCcli::lssyscfg( $exp, $type, $mtms, $filter );
|
|
|
|
my $Rc = shift(@$frame);
|
|
|
|
|
|
|
|
##############################
|
|
|
|
# Return error
|
|
|
|
##############################
|
|
|
|
if ( $Rc != SUCCESS ) {
|
|
|
|
return( [$Rc,@$frame[0]] );
|
|
|
|
}
|
|
|
|
##############################
|
|
|
|
# Success
|
|
|
|
##############################
|
|
|
|
@vpd = split /,/, @$frame[0];
|
|
|
|
}
|
2008-03-06 14:46:13 +00:00
|
|
|
##################################
|
2007-11-16 19:47:00 +00:00
|
|
|
# CECs and LPARs
|
2008-03-06 14:46:13 +00:00
|
|
|
##################################
|
2007-11-16 19:47:00 +00:00
|
|
|
else {
|
|
|
|
##############################
|
|
|
|
# Send command for CEC only
|
|
|
|
##############################
|
|
|
|
my $cec = xCAT::PPCcli::lssyscfg( $exp, "fsp", $mtms, $filter );
|
|
|
|
my $Rc = shift(@$cec);
|
|
|
|
|
|
|
|
##############################
|
|
|
|
# Return error
|
|
|
|
##############################
|
|
|
|
if ( $Rc != SUCCESS ) {
|
|
|
|
return( [$Rc,@$cec[0]] );
|
|
|
|
}
|
|
|
|
##############################
|
|
|
|
# Success
|
|
|
|
##############################
|
|
|
|
@vpd = split /,/, @$cec[0];
|
|
|
|
}
|
|
|
|
my %outhash = (
|
|
|
|
model => $vpd[0],
|
|
|
|
serial => $vpd[1]
|
|
|
|
);
|
|
|
|
return( [SUCCESS,\%outhash] );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
##########################################################################
|
|
|
|
# Returns memory/processor information for CEC/LPARs
|
|
|
|
##########################################################################
|
|
|
|
sub enumerate_cfg {
|
|
|
|
|
|
|
|
my $exp = shift;
|
|
|
|
my $mtms = shift;
|
|
|
|
my $hash = shift;
|
|
|
|
my %outhash = ();
|
|
|
|
my $sys = 0;
|
|
|
|
my @cmds = (
|
|
|
|
[ "sys", "proc", "installed_sys_proc_units" ],
|
|
|
|
[ "sys", "mem", "installed_sys_mem" ],
|
2008-03-06 14:46:13 +00:00
|
|
|
[ "lpar","proc", "lpar_id,curr_procs" ],
|
|
|
|
[ "lpar","mem", "lpar_id,curr_mem" ]
|
2007-11-16 19:47:00 +00:00
|
|
|
);
|
2008-03-06 14:46:13 +00:00
|
|
|
my $cec;
|
2007-11-16 19:47:00 +00:00
|
|
|
my ($name) = keys %{$hash->{$mtms}};
|
|
|
|
my $type = @{$hash->{$mtms}->{$name}}[4];
|
|
|
|
|
|
|
|
######################################
|
|
|
|
# Invalid target hardware
|
|
|
|
######################################
|
|
|
|
if ( $type !~ /^fsp|lpar$/ ) {
|
|
|
|
return( [RC_ERROR,"Information only available for CEC/LPAR"] );
|
|
|
|
}
|
|
|
|
######################################
|
|
|
|
# Check for CECs in list
|
|
|
|
######################################
|
|
|
|
while (my ($name,$d) = each(%{$hash->{$mtms}}) ) {
|
|
|
|
if ( @$d[4] eq "fsp" ) {
|
2008-03-06 14:46:13 +00:00
|
|
|
$cec = $name;
|
2007-11-16 19:47:00 +00:00
|
|
|
last;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
######################################
|
|
|
|
# No CECs - Skip command for CEC
|
|
|
|
######################################
|
2008-03-06 14:46:13 +00:00
|
|
|
if ( !defined( $cec )) {
|
2007-11-16 19:47:00 +00:00
|
|
|
shift @cmds;
|
|
|
|
shift @cmds;
|
|
|
|
}
|
|
|
|
######################################
|
|
|
|
# No LPARs - Skip command for LPAR
|
|
|
|
######################################
|
|
|
|
if (( keys %{$hash->{$mtms}} == 1 ) and ( scalar(@cmds) == 4 )) {
|
|
|
|
pop @cmds;
|
|
|
|
pop @cmds;
|
|
|
|
}
|
2008-03-06 14:46:13 +00:00
|
|
|
|
2007-11-16 19:47:00 +00:00
|
|
|
foreach my $cmd( @cmds ) {
|
|
|
|
my $result = xCAT::PPCcli::lshwres( $exp, $cmd, $mtms );
|
|
|
|
my $Rc = shift(@$result);
|
|
|
|
|
|
|
|
##################################
|
|
|
|
# Expect error
|
|
|
|
##################################
|
|
|
|
if ( $Rc != SUCCESS ) {
|
|
|
|
return( [$Rc,@$result[0]] );
|
|
|
|
}
|
|
|
|
##################################
|
|
|
|
# Success...
|
|
|
|
# lshwres does not return CEC name
|
|
|
|
##################################
|
|
|
|
if ( @$cmd[0] eq "sys" ) {
|
|
|
|
foreach ( @$result[0] ) {
|
2008-03-06 14:46:13 +00:00
|
|
|
s/(.*)/0,$1/;
|
2007-11-16 19:47:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
##################################
|
2008-03-06 14:46:13 +00:00
|
|
|
# Save by CEC/LPAR id
|
2007-11-16 19:47:00 +00:00
|
|
|
##################################
|
|
|
|
foreach ( @$result ) {
|
2008-03-06 14:46:13 +00:00
|
|
|
my ($id,$value) = split /,/;
|
|
|
|
push @{$outhash{$id}}, $value;
|
2007-11-16 19:47:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return( [SUCCESS,\%outhash] );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
##########################################################################
|
|
|
|
# Returns I/O bus information
|
|
|
|
##########################################################################
|
|
|
|
sub enumerate_bus {
|
|
|
|
|
|
|
|
my $exp = shift;
|
|
|
|
my $mtms = shift;
|
|
|
|
my $hash = shift;
|
|
|
|
my %outhash = ();
|
|
|
|
my @res = qw(lpar);
|
2008-03-06 14:46:13 +00:00
|
|
|
my $filter = "drc_name,bus_id,description";
|
2007-11-16 19:47:00 +00:00
|
|
|
my @cmds = (
|
|
|
|
undef,
|
|
|
|
"io --rsubtype slot",
|
|
|
|
$filter
|
|
|
|
);
|
2008-03-06 14:46:13 +00:00
|
|
|
my $cec;
|
2007-11-16 19:47:00 +00:00
|
|
|
my ($name) = keys %{$hash->{$mtms}};
|
|
|
|
my $type = @{$hash->{$mtms}->{$name}}[4];
|
|
|
|
|
|
|
|
##################################
|
|
|
|
# Invalid target hardware
|
|
|
|
##################################
|
|
|
|
if ( $type !~ /^fsp|lpar$/ ) {
|
|
|
|
return( [RC_ERROR,"Bus information only available for CEC/LPAR"] );
|
|
|
|
}
|
|
|
|
##################################
|
|
|
|
# Send command for CEC only
|
|
|
|
##################################
|
|
|
|
my $cecs = xCAT::PPCcli::lshwres( $exp, \@cmds, $mtms );
|
|
|
|
my $Rc = shift(@$cecs);
|
|
|
|
|
|
|
|
##################################
|
|
|
|
# Return error
|
|
|
|
##################################
|
|
|
|
if ( $Rc != SUCCESS ) {
|
|
|
|
return( [$Rc,@$cecs[0]] );
|
|
|
|
}
|
|
|
|
##################################
|
|
|
|
# Success
|
|
|
|
##################################
|
|
|
|
my @bus = @$cecs;
|
|
|
|
|
|
|
|
##################################
|
|
|
|
# Check for CECs in list
|
|
|
|
##################################
|
|
|
|
foreach ( keys %{$hash->{$mtms}} ) {
|
|
|
|
if ( @{$hash->{$mtms}->{$_}}[4] eq "fsp" ) {
|
2008-03-06 14:46:13 +00:00
|
|
|
$cec = $_;
|
2007-11-16 19:47:00 +00:00
|
|
|
last;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
##################################
|
2008-03-06 14:46:13 +00:00
|
|
|
# Get LPAR ids
|
2007-11-16 19:47:00 +00:00
|
|
|
##################################
|
2008-03-06 14:46:13 +00:00
|
|
|
my $lpars = xCAT::PPCcli::lssyscfg( $exp, "lpar", $mtms, "lpar_id" );
|
2007-11-16 19:47:00 +00:00
|
|
|
$Rc = shift(@$lpars);
|
|
|
|
|
|
|
|
##################################
|
|
|
|
# Return error
|
|
|
|
##################################
|
|
|
|
if ( $Rc != SUCCESS ) {
|
|
|
|
return( [$Rc,@$lpars[0]] );
|
|
|
|
}
|
|
|
|
##################################
|
2008-03-06 14:46:13 +00:00
|
|
|
# Save LPARs by id
|
2007-11-16 19:47:00 +00:00
|
|
|
##################################
|
|
|
|
foreach ( @$lpars ) {
|
|
|
|
$outhash{$_} = \@bus;
|
|
|
|
}
|
|
|
|
##################################
|
2008-03-06 14:46:13 +00:00
|
|
|
# Save CEC by id
|
2007-11-16 19:47:00 +00:00
|
|
|
##################################
|
2008-03-06 14:46:13 +00:00
|
|
|
if ( defined( $cec )) {
|
|
|
|
$outhash{"0"} = \@bus;
|
2007-11-16 19:47:00 +00:00
|
|
|
}
|
|
|
|
return( [SUCCESS,\%outhash] );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
##########################################################################
|
|
|
|
# Returns I/O bus information
|
|
|
|
##########################################################################
|
|
|
|
sub bus {
|
|
|
|
|
|
|
|
my $request = shift;
|
|
|
|
my $hash = shift;
|
|
|
|
my $exp = shift;
|
|
|
|
my @result = ();
|
|
|
|
|
|
|
|
while (my ($mtms,$h) = each(%$hash) ) {
|
|
|
|
#####################################
|
|
|
|
# Get information for this CEC
|
|
|
|
#####################################
|
2008-03-06 14:46:13 +00:00
|
|
|
my $bus = enumerate_bus( $exp, $mtms, $hash );
|
2007-11-16 19:47:00 +00:00
|
|
|
my $Rc = shift(@$bus);
|
|
|
|
my $data = @$bus[0];
|
|
|
|
|
2008-03-06 14:46:13 +00:00
|
|
|
while (my ($name,$d) = each(%$h) ) {
|
|
|
|
##################################
|
|
|
|
# Look up by lparid
|
|
|
|
##################################
|
|
|
|
my $type = @$d[4];
|
|
|
|
my $id = ($type=~/^fsp$/) ? 0 : @$d[0];
|
|
|
|
|
2007-11-16 19:47:00 +00:00
|
|
|
#################################
|
|
|
|
# Output header
|
|
|
|
#################################
|
|
|
|
push @result, [$name,"I/O Bus Information"];
|
|
|
|
|
|
|
|
#################################
|
|
|
|
# Output error
|
|
|
|
#################################
|
|
|
|
if ( $Rc != SUCCESS ) {
|
2008-03-05 19:05:09 +00:00
|
|
|
push @result, [$name,@$bus[0],$Rc];
|
2007-11-16 19:47:00 +00:00
|
|
|
next;
|
|
|
|
}
|
|
|
|
#################################
|
|
|
|
# Node not found
|
|
|
|
#################################
|
2008-03-06 14:46:13 +00:00
|
|
|
if ( !exists( $data->{$id} )) {
|
2008-03-05 19:05:09 +00:00
|
|
|
push @result, [$name,"Node not found",1];
|
2007-11-16 19:47:00 +00:00
|
|
|
next;
|
|
|
|
}
|
|
|
|
#################################
|
|
|
|
# Output values
|
|
|
|
#################################
|
2008-03-06 14:46:13 +00:00
|
|
|
foreach ( @{$data->{$id}} ) {
|
2007-11-16 19:47:00 +00:00
|
|
|
s/,/:/;
|
2008-03-05 19:05:09 +00:00
|
|
|
push @result, [$name,$_,$Rc];
|
2007-11-16 19:47:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return( \@result );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
##########################################################################
|
|
|
|
# Returns VPD information
|
|
|
|
##########################################################################
|
|
|
|
sub vpd {
|
|
|
|
|
|
|
|
my $request = shift;
|
|
|
|
my $hash = shift;
|
|
|
|
my $exp = shift;
|
|
|
|
my @cmds = $request->{method};
|
|
|
|
my @result = ();
|
|
|
|
my %prefix = (
|
|
|
|
model => ["Machine Type/Model",0],
|
|
|
|
serial => ["Serial Number", 1]
|
|
|
|
);
|
|
|
|
|
|
|
|
#########################################
|
|
|
|
# Convert "all"
|
|
|
|
#########################################
|
|
|
|
if ( $cmds[0] eq "all" ) {
|
|
|
|
@cmds = qw( model serial );
|
|
|
|
}
|
|
|
|
|
|
|
|
while (my ($mtms,$h) = each(%$hash) ) {
|
|
|
|
#####################################
|
|
|
|
# Get information for this CEC
|
|
|
|
#####################################
|
2008-03-06 14:46:13 +00:00
|
|
|
my $vpd = enumerate_vpd( $exp, $mtms, $hash );
|
2007-11-16 19:47:00 +00:00
|
|
|
my $Rc = shift(@$vpd);
|
|
|
|
my $data = @$vpd[0];
|
|
|
|
|
|
|
|
while (my ($name) = each(%$h) ) {
|
|
|
|
foreach ( @cmds ) {
|
|
|
|
#############################
|
|
|
|
# Output error
|
|
|
|
#############################
|
|
|
|
if ( $Rc != SUCCESS ) {
|
2008-03-05 19:05:09 +00:00
|
|
|
push @result, [$name,"@{$prefix{$_}}[0]: @$vpd[0]",$Rc];
|
2007-11-16 19:47:00 +00:00
|
|
|
next;
|
|
|
|
}
|
|
|
|
#############################
|
|
|
|
# Output value
|
|
|
|
#############################
|
|
|
|
my $value = "@{$prefix{$_}}[0]: $data->{$_}";
|
2008-03-05 19:05:09 +00:00
|
|
|
push @result, [$name,$value,$Rc];
|
2007-11-16 19:47:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return( \@result );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
##########################################################################
|
|
|
|
# Returns memory/processor information
|
|
|
|
##########################################################################
|
|
|
|
sub config {
|
|
|
|
|
|
|
|
my $request = shift;
|
|
|
|
my $hash = shift;
|
|
|
|
my $exp = shift;
|
|
|
|
my @result = ();
|
|
|
|
my @prefix = (
|
|
|
|
"Number of Processors: %s",
|
|
|
|
"Total Memory (MB): %s"
|
|
|
|
);
|
|
|
|
|
|
|
|
while (my ($mtms,$h) = each(%$hash) ) {
|
|
|
|
#####################################
|
|
|
|
# Get information for this CEC
|
|
|
|
#####################################
|
|
|
|
my $cfg = enumerate_cfg( $exp, $mtms, $hash );
|
|
|
|
my $Rc = shift(@$cfg);
|
|
|
|
my $data = @$cfg[0];
|
|
|
|
|
2008-03-06 14:46:13 +00:00
|
|
|
while (my ($name,$d) = each(%$h) ) {
|
|
|
|
##################################
|
|
|
|
# Look up by lparid
|
|
|
|
##################################
|
|
|
|
my $type = @$d[4];
|
|
|
|
my $id = ($type=~/^fsp$/) ? 0 : @$d[0];
|
|
|
|
|
2007-11-16 19:47:00 +00:00
|
|
|
#################################
|
|
|
|
# Output header
|
|
|
|
#################################
|
|
|
|
push @result, [$name,"Machine Configuration Info"];
|
|
|
|
my $i;
|
|
|
|
|
|
|
|
foreach ( @prefix ) {
|
|
|
|
#############################
|
|
|
|
# Output error
|
|
|
|
#############################
|
|
|
|
if ( $Rc != SUCCESS ) {
|
|
|
|
my $value = sprintf( "$_", $data );
|
2008-03-05 19:05:09 +00:00
|
|
|
push @result, [$name,$value,$Rc];
|
2007-11-16 19:47:00 +00:00
|
|
|
next;
|
|
|
|
}
|
|
|
|
#############################
|
|
|
|
# Node not found
|
|
|
|
#############################
|
2008-03-06 14:46:13 +00:00
|
|
|
if (!exists( $data->{$id} )) {
|
2008-03-05 19:05:09 +00:00
|
|
|
push @result, [$name,"Node not found",1];
|
2007-11-16 19:47:00 +00:00
|
|
|
next;
|
|
|
|
}
|
|
|
|
#############################
|
|
|
|
# Output value
|
|
|
|
#############################
|
2008-03-06 14:46:13 +00:00
|
|
|
my $value = sprintf( $_, @{$data->{$id}}[$i++] );
|
2008-03-05 19:05:09 +00:00
|
|
|
push @result, [$name,$value,$Rc];
|
2007-11-16 19:47:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return( \@result );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
##########################################################################
|
|
|
|
# Returns serial-number
|
|
|
|
##########################################################################
|
|
|
|
sub serial {
|
|
|
|
return( vpd(@_) );
|
|
|
|
}
|
|
|
|
|
|
|
|
##########################################################################
|
|
|
|
# Returns machine-type-model
|
|
|
|
##########################################################################
|
|
|
|
sub model {
|
|
|
|
return( vpd(@_) );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
##########################################################################
|
|
|
|
# Returns all inventory information
|
|
|
|
##########################################################################
|
|
|
|
sub all {
|
|
|
|
|
|
|
|
my @result = (
|
|
|
|
@{vpd(@_)},
|
|
|
|
@{bus(@_)},
|
|
|
|
@{config(@_)}
|
|
|
|
);
|
|
|
|
return( \@result );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
1;
|
2008-03-05 19:05:09 +00:00
|
|
|
|