xcat-core/perl-xCAT/xCAT/PPCvitals.pm

393 lines
12 KiB
Perl

# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
package xCAT::PPCvitals;
use strict;
use Getopt::Long;
use xCAT::PPCcli qw(SUCCESS EXPECT_ERROR RC_ERROR NR_ERROR);
use xCAT::PPCpower;
use xCAT::Usage;
##########################################################################
# Parse the command line for options and operands
##########################################################################
sub parse_args {
my $request = shift;
my $command = $request->{command};
my $args = $request->{arg};
my %opt = ();
my @rvitals = qw(temp voltage power lcds state rackenv all);
#############################################
# Responds with usage statement
#############################################
local *usage = sub {
my $usage_string = xCAT::Usage->getUsage($command);
return( [ $_[0], $usage_string] );
};
#############################################
# 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" );
if ( !GetOptions( \%opt, qw(V|Verbose) )) {
return( usage() );
}
####################################
# Check for "-" with no option
####################################
if ( grep(/^-$/, @ARGV )) {
return(usage( "Missing option: -" ));
}
####################################
# Unsupported command
####################################
my ($cmd) = grep(/^$ARGV[0]$/, @rvitals );
if ( !defined( $cmd )) {
return(usage( "Invalid command: $ARGV[0]" ));
}
if($ARGV[0] =~ /^rackenv$/) {
if($request->{hwtype} =~ /^hmc$/) {
return(usage( "Command $ARGV[0] is not valid when the nodes' hcp is hmc" ));
}
}
####################################
# 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 Frame voltages/currents
##########################################################################
sub enumerate_volt {
my $exp = shift;
my $d = shift;
my $mtms = @$d[2];
my $volt = xCAT::PPCcli::lshwinfo( $exp, "frame", $mtms );
my $Rc = shift(@$volt);
####################################
# Return error
####################################
if ( $Rc != SUCCESS ) {
return( [RC_ERROR, @$volt[0]] );
}
####################################
# Success - return voltages
####################################
return( [SUCCESS, @$volt[0]] );
}
##########################################################################
# Returns cage temperatures
##########################################################################
sub enumerate_temp {
my $exp = shift;
my $frame = shift;
my %outhash = ();
####################################
# Get cage information for frame
####################################
my $filter = "type_model_serial_num,temperature";
my $cages = xCAT::PPCcli::lshwinfo( $exp, "sys", $frame, $filter );
my $Rc = shift(@$cages);
####################################
# Expect error
####################################
if ( $Rc == EXPECT_ERROR || $Rc == RC_ERROR ) {
return( [$Rc,@$cages[0]] );
}
####################################
# Save frame by CEC MTMS in cage
####################################
foreach ( @$cages ) {
my ($mtms,$temp) = split /,/;
$outhash{$mtms} = $temp;
}
return( [SUCCESS,\%outhash] );
}
##########################################################################
# Returns refcode
##########################################################################
sub enumerate_lcds {
my $exp = shift;
my $d = shift;
my $mtms = @$d[2];
my $Rc = undef;
my $value = undef;
my $nodetype = @$d[4];
my $lpar_id = @$d[0];
my @refcode = ();
my $values = xCAT::PPCcli::lsrefcode($exp, $nodetype, $mtms, $lpar_id);
foreach $value (@$values){
#Return error
$Rc = shift @$value;
if( @$value[0] =~ /refcode=(\w*)/){
my $code = $1;
if ( ! $code)
{
push @refcode, [$Rc, "blank"];
}
else
{
push @refcode, [$Rc, $code] ;
}
}
}
return \@refcode;
}
##########################################################################
# Returns voltages/currents
##########################################################################
sub voltage {
my $request = shift;
my $hash = shift;
my $exp = shift;
my $hwtype = @$exp[2];
my @result = ();
my $text = "Frame Voltages: ";
my @prefix = (
"Frame Voltage (Vab): %sV",
"Frame Voltage (Vbc): %sV",
"Frame Voltage (Vca): %sV",
"Frame Current (Ia): %sA",
"Frame Current (Ib): %sA",
"Frame Current (Ic): %sA",
);
while (my ($mtms,$h) = each(%$hash) ) {
while (my ($name,$d) = each(%$h) ) {
#################################
# No frame command on IVM
#################################
if ( $hwtype eq "ivm" ) {
push @result, [$name,"$text Not available",1];
next;
}
#################################
# Voltages available in frame
#################################
if ( @$d[4] ne "bpa" ) {
push @result, [$name,"$text Only available for BPA",1];
next;
}
my $volt = enumerate_volt( $exp, $d );
my $Rc = shift(@$volt);
#################################
# Output error
#################################
if ( $Rc != SUCCESS ) {
push @result, [$name,"$text @$volt[0]",$Rc];
next;
}
#################################
# Output value
#################################
my @values = split /,/, @$volt[0];
my $i = 0;
foreach ( @prefix ) {
my $value = sprintf($_, $values[$i++]);
push @result, [$name,$value,$Rc];
}
}
}
return( \@result );
}
##########################################################################
# Returns temperatures for CEC
##########################################################################
sub temp {
my $request = shift;
my $hash = shift;
my $exp = shift;
my $hwtype = @$exp[2];
my @result = ();
my %frame = ();
my $prefix = "System Temperature:";
#########################################
# Group by frame
#########################################
while (my ($mtms,$h) = each(%$hash) ) {
while (my ($name,$d) = each(%$h) ) {
my $mtms = @$d[5];
#################################
# No frame commands for IVM
#################################
if ( $hwtype eq "ivm" ) {
push @result, [$name,"$prefix Not available (No BPA)",1];
next;
}
#################################
# Temperatures not available
#################################
if ( @$d[4] !~ /^(fsp|cec|lpar)$/ ) {
my $text = "$prefix Only available for CEC/LPAR";
push @result, [$name,$text,1];
next;
}
#################################
# Error - No frame
#################################
if ( $mtms eq "0" ) {
push @result, [$name,"$prefix Not available (No BPA)",1];
next;
}
#################################
# Save node
#################################
$frame{$mtms}{$name} = $d;
}
}
while (my ($mtms,$h) = each(%frame) ) {
#################################
# Get temperatures this frame
#################################
my $temp = enumerate_temp( $exp, $mtms );
my $Rc = shift(@$temp);
my $data = @$temp[0];
while (my ($name,$d) = each(%$h) ) {
my $mtms = @$d[2];
#############################
# Output error
#############################
if ( $Rc != SUCCESS ) {
push @result, [$name,"$prefix $data",$Rc];
next;
}
#############################
# CEC not in frame
#############################
if ( !exists( $data->{$mtms} )) {
push @result, [$name,"$prefix CEC '$mtms' not found",1];
next;
}
#############################
# Output value
#############################
my $cel = $data->{$mtms};
my $fah = ($cel * 1.8) + 32;
my $value = "$prefix $cel C ($fah F)";
push @result, [$name,$value,$Rc];
}
}
return( \@result );
}
##########################################################################
# Returns system power status (on or off)
##########################################################################
sub power {
return( xCAT::PPCpower::state(@_,"Current Power Status: ",1));
}
##########################################################################
# Returns system state
##########################################################################
sub state {
return( xCAT::PPCpower::state(@_,"System State: "));
}
###########################################################################
# Returns system LCD status (LCD1, LCD2)
##########################################################################
sub lcds {
my $request = shift;
my $hash = shift;
my $exp = shift;
my $hwtype = @$exp[2];
my @result = ();
my $text = "Current LCD:";
my $prefix = "Current LCD%d: %s";
my $rcode = undef;
my $refcodes = undef;
my $Rc = undef;
my $num = undef;
my $value = undef;
while (my ($mtms,$h) = each(%$hash) ) {
while(my ($name, $d) = each(%$h) ){
#Support HMC only
if($hwtype ne 'hmc'){
push @result, [$name, "$text Not available(NO HMC)", 1];
next;
}
$refcodes = enumerate_lcds($exp, $d);
$num = 1;
foreach $rcode (@$refcodes){
$Rc = shift(@$rcode);
$value = sprintf($prefix, $num, @$rcode[0]);
push @result, [$name, $value, $Rc];
$num = $num + 1;
}
}
}
return \@result;
}
##########################################################################
# Returns all vitals
##########################################################################
sub all {
my @values = (
@{temp(@_)},
@{voltage(@_)},
@{state(@_)},
@{power(@_)},
@{lcds(@_)},
);
my @sorted_values = sort {$a->[0] cmp $b->[0]} @values;
return( \@sorted_values );
}
1;