582 lines
17 KiB
Perl
582 lines
17 KiB
Perl
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
|
|
|
package xCAT::FSPscan;
|
|
use strict;
|
|
use Getopt::Long;
|
|
use Socket;
|
|
use XML::Simple;
|
|
$XML::Simple::PREFERRED_PARSER='XML::Parser';
|
|
use xCAT::PPCcli qw(SUCCESS EXPECT_ERROR RC_ERROR NR_ERROR);
|
|
use xCAT::PPCdb;
|
|
use xCAT::PPCscan;
|
|
use xCAT::GlobalDef;
|
|
use xCAT::Usage;
|
|
use xCAT::NetworkUtils;
|
|
use xCAT::FSPUtils;
|
|
require xCAT::data::ibmhwtypes;
|
|
#use Data::Dumper;
|
|
|
|
##############################################
|
|
# Globals
|
|
##############################################
|
|
my @header = (
|
|
["type", "%-8s" ],
|
|
["name", "placeholder" ],
|
|
["id", "%-8s" ],
|
|
["type-model", "%-12s" ],
|
|
["serial-number", "%-15s\n" ]);
|
|
#,
|
|
# ["side", "%-8s" ],
|
|
# ["address", "%-20s\n" ]);
|
|
|
|
my @attribs = qw(nodetype node id mtm serial side hcp pprofile parent groups mgt cons hwtype);
|
|
my %globalnodetype = (
|
|
fsp => $::NODETYPE_PPC,
|
|
bpa => $::NODETYPE_PPC,
|
|
cec => $::NODETYPE_PPC,
|
|
frame=> $::NODETYPE_PPC,
|
|
lpar =>"$::NODETYPE_PPC,$::NODETYPE_OSI"
|
|
);
|
|
my %globalhwtype = (
|
|
fsp => $::NODETYPE_FSP,
|
|
bpa => $::NODETYPE_BPA,
|
|
lpar => $::NODETYPE_LPAR,
|
|
cec => $::NODETYPE_CEC,
|
|
frame=> $::NODETYPE_FRAME,
|
|
);
|
|
|
|
|
|
##########################################################################
|
|
# Parse the command line for options and operands
|
|
##########################################################################
|
|
sub parse_args {
|
|
xCAT::PPCscan::parse_args(@_);
|
|
}
|
|
|
|
|
|
|
|
##########################################################################
|
|
# Returns short-hostname given an IP
|
|
##########################################################################
|
|
sub getshorthost {
|
|
|
|
my $ip = shift;
|
|
|
|
my $host = xCAT::NetworkUtils->gethostname($ip);
|
|
if ( $host and !$! ) {
|
|
##############################
|
|
# Get short-hostname
|
|
##############################
|
|
if ( $host =~ /([^\.]+)\./ ) {
|
|
return($1);
|
|
}
|
|
}
|
|
##################################
|
|
# Failed
|
|
##################################
|
|
return undef;
|
|
}
|
|
|
|
|
|
##########################################################################
|
|
# Returns I/O bus information
|
|
##########################################################################
|
|
sub enumerate {
|
|
|
|
my $request = shift;
|
|
my $hash = shift;
|
|
my $exp = shift;
|
|
my $hwtype = ();
|
|
my $server ;
|
|
my @values = ();
|
|
my $cageid;
|
|
my $server;
|
|
my $prof;
|
|
my $fname;
|
|
my %cage = ();
|
|
my %hwconn = ();
|
|
my $Rc;
|
|
my $filter;
|
|
my $data;
|
|
my @output;
|
|
my $ips;
|
|
my $fsp;
|
|
my $model ;
|
|
my $serial;
|
|
my $side;
|
|
my $ips;
|
|
my $line;
|
|
|
|
foreach my $cec_bpa ( keys %$hash)
|
|
{
|
|
|
|
my $node_hash = $hash->{$cec_bpa};
|
|
for my $node_name ( keys %$node_hash)
|
|
{
|
|
my $d = $node_hash->{$node_name};
|
|
if($$d[4] =~ /^lpar$/ || $$d[4] =~ /^bpa$/ || $$d[4] =~ /^frame$/ ) {
|
|
$data = "please check the $node_name; the noderange of rscan couldn't be LPAR or BPA, or frame. ";
|
|
#push @output, [$node_name,$data,$Rc];
|
|
push @values, $data;
|
|
next;
|
|
}
|
|
my $stat = xCAT::FSPUtils::fsp_api_action ($request, $node_name, $d, "query_connection");
|
|
my $Rc = @$stat[2];
|
|
my $data = @$stat[1];
|
|
|
|
##################################
|
|
# Output error
|
|
##################################
|
|
if ( $Rc != SUCCESS ) {
|
|
#push @output, [$node_name,$data,$Rc];
|
|
push @values, $data;
|
|
next;
|
|
}
|
|
my @data_a = split("\n", $data);
|
|
foreach $line(@data_a) {
|
|
if($line !~ "Connected" && $line !~ "LINE UP" ) {
|
|
next;
|
|
}
|
|
|
|
#########################################
|
|
# GET CEC's information
|
|
#########################################
|
|
#$data =~ /state=([\w\s]+),\(type=([\w-]+)\),\(serial-number=([\w]+)\),\(machinetype-model=([\w-]+)\),sp=([\w]+),\(ip-address=([\w.]+),([\w.]+)\)/ ;
|
|
$line =~ /state=([\w\s]+), type=([\w-]+), MTMS=([\w-]+)\*([\w-]+), sp=([\w=]+), slot=([\w]+), ipadd=([\w.]+), alt_ipadd=([\w.]+)/ ;
|
|
#print "parsing: $1,$2,$3,$4,$5,$6,$7,$8\n";
|
|
|
|
$fsp=$node_name;
|
|
$model = $3;
|
|
$serial = $4;
|
|
$side = $6;
|
|
$server = $fsp;
|
|
$fname = $fsp;
|
|
my $ip = $7;
|
|
my $ip_s = $8;
|
|
if(! defined( $ips)) {
|
|
if( $ip_s =~ /unavailable/ ) {
|
|
$ips ="$ip";
|
|
} else {
|
|
$ips ="$ip;$ip_s";
|
|
}
|
|
} else {
|
|
if( $ip_s =~ /unavailable/ ) {
|
|
$ips .=";$ip";
|
|
} else {
|
|
$ips .=";$ip;$ip_s";
|
|
}
|
|
}
|
|
}
|
|
if(!defined($fsp)) {
|
|
my $msg = "please check if the $node_name is coneected to the hardware server";
|
|
push @values, $msg;
|
|
next;
|
|
}
|
|
if($$d[4] =~ /^cec$/) {
|
|
$side="";
|
|
}
|
|
push @values, join( ",",
|
|
$$d[4],$node_name,$cageid,$model,$serial,$side, $server,$prof,$fname);
|
|
#$$d[4],$node_name,$cageid,$model,$serial,$side, $server,$prof,$fname, $ips, $$d[4]);
|
|
# $$d[4],$node_name,$cageid,$model,$serial,$side, $server,$prof,$fname, $7);
|
|
# "fsp",$node_name,$cageid,$model,$serial,$side, $server,$prof,$fname, $7);
|
|
#"fsp",$fsp,$cageid,$model,$serial,$side,$server,$prof,$fname,$ips );
|
|
|
|
#####################################
|
|
# Enumerate LPARs
|
|
#####################################
|
|
$stat = xCAT::FSPUtils::fsp_api_action ($request, $node_name, $d, "get_lpar_info");
|
|
$Rc = @$stat[2];
|
|
$data = @$stat[1];
|
|
|
|
##################################
|
|
# Output error
|
|
##################################
|
|
if ( $Rc != SUCCESS ) {
|
|
#push @output, [$node_name,$data,$Rc];
|
|
push @values, $data;
|
|
next;
|
|
}
|
|
my @list = split(/\n/,$data);
|
|
#print "list\n";
|
|
#print Dumper(\@list);
|
|
foreach my $lpar (@list) {
|
|
$lpar =~ /lparname:\s+([\w\-]+),\s+lparid:\s+(\d+),\s+state:/;
|
|
my $name = $1;
|
|
my $lparid = $2;
|
|
my $prof = ""; # No profile for Power 775
|
|
my $server = $fsp;
|
|
my $ips = "";
|
|
my $port = "";
|
|
# $name =~ s/\-//g;
|
|
# $name =~ tr/A-Z/a-z/;
|
|
|
|
#####################################
|
|
# Save LPAR information
|
|
#####################################
|
|
push @values, join( ",",
|
|
"lpar",$name,$lparid,$model,$serial,$port,$server,$prof,$fsp );
|
|
#"lpar",$name,$lparid,$model,$serial,$port,$server,$prof,$fsp,$ips,"lpar" );
|
|
|
|
}
|
|
|
|
}
|
|
#return(\@values);
|
|
}
|
|
|
|
|
|
return( \@values );
|
|
}
|
|
|
|
|
|
|
|
##########################################################################
|
|
# Format responses
|
|
##########################################################################
|
|
sub format_output {
|
|
|
|
my $request = shift;
|
|
my $exp = shift;
|
|
my $values = shift;
|
|
my $opt = $request->{opt};
|
|
my %output = ();
|
|
my $hwtype = "fsp";
|
|
my $max_length = 0;
|
|
my $result;
|
|
|
|
#print "In format output\n";
|
|
#print Dumper($request);
|
|
#print Dumper($exp);
|
|
#print Dumper($values);
|
|
###########################################
|
|
# -w flag for write to xCat database
|
|
###########################################
|
|
if ( exists( $opt->{w} )) {
|
|
my $server = @$exp[3];
|
|
my $uid = @$exp[4];
|
|
my $pw = @$exp[5];
|
|
|
|
#######################################
|
|
# Strip errors for results
|
|
#######################################
|
|
my @val = grep( !/^#.*: ERROR /, @$values );
|
|
#xCAT::PPCdb::add_ppc( $hwtype, \@val );
|
|
$values = xCAT::PPCdb::update_lpar( $hwtype, \@val, "write");
|
|
}
|
|
|
|
###########################################
|
|
# -u flag for write to xCat database
|
|
###########################################
|
|
if ( exists( $opt->{u} )) {
|
|
#######################################
|
|
# Strip errors for results
|
|
#######################################
|
|
my @val = grep( !/^#.*: ERROR /, @$values );
|
|
#$values = xCAT::PPCdb::update_ppc( $hwtype, \@val );
|
|
$values = xCAT::PPCdb::update_lpar( $hwtype, \@val );
|
|
if ( exists( $opt->{x} ) or exists( $opt->{z} ))
|
|
{
|
|
unshift @$values, "hmc";
|
|
}
|
|
}
|
|
|
|
###########################################
|
|
# -x flag for xml format
|
|
###########################################
|
|
if ( exists( $opt->{x} )) {
|
|
$result .= format_xml( $hwtype, $values );
|
|
}
|
|
###########################################
|
|
# -z flag for stanza format
|
|
###########################################
|
|
elsif ( exists( $opt->{z} )) {
|
|
$result .= format_stanza( $hwtype, $values );
|
|
}
|
|
else {
|
|
$result = sprintf( "#Updated following nodes:\n") if ( exists( $opt->{u}));
|
|
#######################################
|
|
# Get longest name for formatting
|
|
#######################################
|
|
foreach ( @$values ) {
|
|
###################################
|
|
# Skip error message
|
|
###################################
|
|
if ( /^#.*: ERROR / ) {
|
|
next;
|
|
}
|
|
/[^\,]+,([^\,]+),/;
|
|
my $length = length( $1 );
|
|
$max_length = ($length > $max_length) ? $length : $max_length;
|
|
}
|
|
my $format = sprintf( "%%-%ds", ($max_length + 2 ));
|
|
$header[1][1] = $format;
|
|
|
|
#######################################
|
|
# Add header
|
|
#######################################
|
|
foreach ( @header ) {
|
|
$result .= sprintf( @$_[1], @$_[0] );
|
|
}
|
|
#######################################
|
|
# Add node information
|
|
#######################################
|
|
my @errmsg;
|
|
foreach ( @$values ) {
|
|
my @data = split /,/;
|
|
my $i = 0;
|
|
|
|
###################################
|
|
# Save error messages for last
|
|
###################################
|
|
if ( /^#.*: ERROR / ) {
|
|
push @errmsg, $_;
|
|
next;
|
|
}
|
|
foreach ( @header ) {
|
|
my $d = $data[$i++];
|
|
|
|
###############################
|
|
# Use IPs instead of
|
|
# hardware control address
|
|
###############################
|
|
if ( @$_[0] eq "address" ) {
|
|
if ( $data[0] !~ /^(hmc|ivm)$/ ) {
|
|
$d = $data[9];
|
|
}
|
|
}
|
|
$result .= sprintf( @$_[1], $d );
|
|
}
|
|
}
|
|
#######################################
|
|
# Add any error messages
|
|
#######################################
|
|
foreach ( @errmsg ) {
|
|
$result.= "\n$_";
|
|
}
|
|
}
|
|
$output{data} = [$result];
|
|
return( [\%output] );
|
|
}
|
|
|
|
|
|
|
|
##########################################################################
|
|
# Stanza formatting
|
|
##########################################################################
|
|
sub format_stanza {
|
|
|
|
my $hwtype = shift;
|
|
my $values = shift;
|
|
|
|
my $result;
|
|
|
|
#####################################
|
|
# Skip hardware control point
|
|
#####################################
|
|
shift(@$values);
|
|
|
|
foreach ( sort @$values ) {
|
|
my @data = split /,/;
|
|
my $type = $data[0];
|
|
my $i = 0;
|
|
|
|
#################################
|
|
# Skip error message
|
|
#################################
|
|
if ( /^#.*: ERROR / ) {
|
|
next;
|
|
}
|
|
#################################
|
|
# Node attributes
|
|
#################################
|
|
$result .= "$data[1]:\n\tobjtype=node\n";
|
|
|
|
#################################
|
|
# Add each attribute
|
|
#################################
|
|
my $mtm = undef;
|
|
foreach ( @attribs ) {
|
|
my $d = $data[$i++];
|
|
|
|
if ( /^node$/ ) {
|
|
next;
|
|
} elsif ( /^nodetype$/ ) {
|
|
$d = $globalnodetype{$type};
|
|
} elsif ( /^hwtype$/ ) {
|
|
$d = $globalhwtype{$type};
|
|
} elsif ( /^groups$/ ) {
|
|
next;
|
|
#$d = "$type,all";
|
|
} elsif ( /^mgt$/ ) {
|
|
$d = $hwtype;
|
|
} elsif ( /^cons$/ ) {
|
|
if ( $type eq "lpar" ) {
|
|
$d = $hwtype;
|
|
} else {
|
|
$d = undef;
|
|
}
|
|
|
|
} elsif ( /^(mtm|serial)$/ ) {
|
|
if ( $type eq "lpar" ) {
|
|
$d = undef;
|
|
} elsif (/^mtm$/) {
|
|
$mtm = $d;
|
|
}
|
|
} elsif (/^side$/) {
|
|
unless ( $type =~ /^fsp|bpa$/ ) {
|
|
next;
|
|
}
|
|
}
|
|
$result .= "\t$_=$d\n";
|
|
}
|
|
my $tmp_groups = "$type,all";
|
|
if (defined($mtm)) {
|
|
my $tmp_pre = xCAT::data::ibmhwtypes::parse_group($mtm);
|
|
if (defined($tmp_pre)) {
|
|
$tmp_groups .= ",$tmp_pre";
|
|
}
|
|
}
|
|
$result .= "\tgroups=$tmp_groups\n";
|
|
|
|
}
|
|
return( $result );
|
|
}
|
|
|
|
|
|
##########################################################################
|
|
# XML formatting
|
|
##########################################################################
|
|
sub format_xml {
|
|
|
|
my $hwtype = shift;
|
|
my $values = shift;
|
|
my $xml;
|
|
|
|
#####################################
|
|
# Skip hardware control point
|
|
#####################################
|
|
#shift(@$values);
|
|
|
|
#####################################
|
|
# Create XML formatted attributes
|
|
#####################################
|
|
foreach ( @$values ) {
|
|
my @data = split /,/;
|
|
my $type = $data[0];
|
|
my $i = 0;
|
|
|
|
#################################
|
|
# Skip error message
|
|
#################################
|
|
if ( /^#.*: ERROR / ) {
|
|
next;
|
|
}
|
|
#################################
|
|
# Initialize hash reference
|
|
#################################
|
|
my $href = {
|
|
Node => { }
|
|
};
|
|
#################################
|
|
# Add each attribute
|
|
#################################
|
|
my $mtm = undef;
|
|
foreach ( @attribs ) {
|
|
my $d = $data[$i++];
|
|
|
|
if ( /^nodetype$/ ) {
|
|
$d = $globalnodetype{$type};
|
|
} elsif ( /^hwtype$/ ) {
|
|
$d = $globalhwtype{$type};
|
|
} elsif ( /^groups$/ ) {
|
|
next;
|
|
#$d = "$type,all";
|
|
} elsif ( /^mgt$/ ) {
|
|
$d = $hwtype;
|
|
} elsif ( /^cons$/ ) {
|
|
if ( $type eq "lpar" ) {
|
|
$d = $hwtype;
|
|
} else {
|
|
$d = undef;
|
|
}
|
|
} elsif ( /^(mtm|serial)$/ ) {
|
|
if ( $type eq "lpar" ) {
|
|
$d = undef;
|
|
} elsif (/^mtm$/) {
|
|
$mtm = $d;
|
|
}
|
|
} elsif (/^side$/) {
|
|
unless ( $type =~ /^fsp|bpa$/ ) {
|
|
next;
|
|
}
|
|
}
|
|
$href->{Node}->{$_} = $d;
|
|
}
|
|
my $tmp_groups = "$type,all";
|
|
if (defined($mtm)) {
|
|
my $tmp_pre = xCAT::data::ibmhwtypes::parse_group($mtm);
|
|
if (defined($tmp_pre)) {
|
|
$tmp_groups .= ",$tmp_pre";
|
|
}
|
|
}
|
|
$href->{Node}->{groups}=$tmp_groups;
|
|
|
|
#print Dumper($href);
|
|
#################################
|
|
# XML encoding
|
|
#################################
|
|
$xml.= XMLout($href,
|
|
NoAttr => 1,
|
|
KeyAttr => [],
|
|
RootName => undef );
|
|
}
|
|
return( $xml );
|
|
}
|
|
|
|
|
|
|
|
##########################################################################
|
|
# Returns I/O bus information
|
|
##########################################################################
|
|
sub rscan {
|
|
|
|
my $request = shift;
|
|
my $hash = shift;
|
|
my $exp = shift;
|
|
my $args = $request->{arg};
|
|
my $server = @$exp[3];
|
|
|
|
#print "in rscan,";
|
|
#print Dumper($request);
|
|
#print Dumper($hash);
|
|
#print Dumper($exp);
|
|
|
|
###################################
|
|
# Enumerate all the hardware
|
|
###################################
|
|
my $values = enumerate($request, $hash );
|
|
#print "In rscan:\n";
|
|
#print Dumper($values);
|
|
if ( ref($values) ne 'ARRAY' ) {
|
|
return( [[$server,$values,1]] );
|
|
}
|
|
###################################
|
|
# Success
|
|
###################################
|
|
my $result = format_output( $request, $exp, $values );
|
|
unshift @$result, "FORMATDATA6sK4ci";
|
|
return( $result );
|
|
|
|
}
|
|
|
|
|
|
|
|
1;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|