# 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",0]; 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)",0]; next; } ################################# # Temperatures not available ################################# if ( @$d[4] !~ /^(fsp|cec|lpar)$/ ) { my $text = "$prefix Only available for CEC/LPAR"; push @result, [$name,$text,0]; next; } ################################# # Error - No frame ################################# if ( $mtms eq "0" ) { push @result, [$name,"$prefix Not available (No BPA)",0]; 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;