mirror of
https://github.com/xcat2/xcat-core.git
synced 2025-05-21 19:22:05 +00:00
2206 lines
84 KiB
Perl
2206 lines
84 KiB
Perl
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
|
|
|
package xCAT_plugin::lsslp;
|
|
use lib "/opt/xcat/lib/perl";
|
|
use strict;
|
|
use Getopt::Long;
|
|
use Socket;
|
|
use xCAT::Usage;
|
|
use POSIX "WNOHANG";
|
|
use Storable qw(freeze thaw);
|
|
use Time::HiRes qw(gettimeofday);
|
|
use xCAT::SvrUtils qw/sendmsg/;
|
|
use IO::Select;
|
|
use XML::Simple;
|
|
$XML::Simple::PREFERRED_PARSER = 'XML::Parser';
|
|
use xCAT::PPCdb;
|
|
use xCAT::NodeRange;
|
|
use xCAT::Utils;
|
|
use xCAT::MacMap;
|
|
use xCAT::IMMUtils;
|
|
use xCAT_plugin::blade;
|
|
use xCAT::SLP;
|
|
require xCAT::data::ibmhwtypes;
|
|
|
|
|
|
my $mpahash;
|
|
my $defaultbladeuser;
|
|
my $defaultbladepass;
|
|
my $currentbladepass;
|
|
my $currentbladeuser;
|
|
my %nodebymp;
|
|
my $macmap;
|
|
my %chassisbyuuid;
|
|
my %flexchassisuuid;
|
|
my %flexchassismap;
|
|
my %passwordmap;
|
|
my %doneaddrs;
|
|
my %btresult;
|
|
my $option_s;
|
|
|
|
#######################################
|
|
# Constants
|
|
#######################################
|
|
use constant {
|
|
HARDWARE_SERVICE => "service:management-hardware.IBM",
|
|
SOFTWARE_SERVICE => "service:management-software.IBM",
|
|
WILDCARD_SERVICE => "service:management-*",
|
|
SERVICE_FSP => "cec-service-processor",
|
|
SERVICE_BPA => "bulk-power-controller",
|
|
SERVICE_CEC => "cec-service-processor",
|
|
SERVICE_FRAME => "bulk-power-controller",
|
|
SERVICE_HMC => "hardware-management-console",
|
|
SERVICE_IVM => "integrated-virtualization-manager",
|
|
SERVICE_MM => "management-module",
|
|
SERVICE_CMM => "chassis-management-module",
|
|
SERVICE_IMM2 => "integrated-management-module2",
|
|
SERVICE_RSA => "remote-supervisor-adapter",
|
|
SERVICE_RSA2 => "remote-supervisor-adapter-2",
|
|
|
|
#SLP_CONF => "/usr/local/etc/slp.conf",
|
|
#SLPTOOL => "/usr/local/bin/slptool",
|
|
TYPE_MM => "mm",
|
|
TYPE_CMM => "cmm",
|
|
TYPE_IMM2 => "imm2",
|
|
TYPE_RSA => "rsa",
|
|
TYPE_BPA => "bpa",
|
|
TYPE_HMC => "hmc",
|
|
TYPE_IVM => "ivm",
|
|
TYPE_FSP => "fsp",
|
|
TYPE_CEC => "cec",
|
|
TYPE_FRAME => "frame",
|
|
IP_ADDRESSES => 4,
|
|
TEXT => 0,
|
|
FORMAT => 1,
|
|
SUCCESS => 0,
|
|
RC_ERROR => 1,
|
|
};
|
|
|
|
#######################################
|
|
# Globals
|
|
#######################################
|
|
my %service_slp = (
|
|
@{ [SERVICE_FSP] } => TYPE_FSP,
|
|
@{ [SERVICE_BPA] } => TYPE_BPA,
|
|
@{ [SERVICE_CEC] } => TYPE_CEC,
|
|
@{ [SERVICE_FRAME] } => TYPE_FRAME,
|
|
@{ [SERVICE_HMC] } => TYPE_HMC,
|
|
@{ [SERVICE_IVM] } => TYPE_IVM,
|
|
@{ [SERVICE_MM] } => TYPE_MM,
|
|
@{ [SERVICE_CMM] } => TYPE_CMM,
|
|
@{ [SERVICE_IMM2] } => TYPE_IMM2,
|
|
@{ [SERVICE_RSA] } => TYPE_RSA,
|
|
@{ [SERVICE_RSA2] } => TYPE_RSA
|
|
);
|
|
|
|
#######################################
|
|
# SLP display header
|
|
#######################################
|
|
my @header = (
|
|
[ "device", "%-8s" ],
|
|
[ "type-model", "%-12s" ],
|
|
[ "serial-number", "%-15s" ],
|
|
[ "side", "%-6s" ],
|
|
[ "ip-addresses", "placeholder" ],
|
|
[ "hostname", "%s" ]
|
|
);
|
|
my %headertoattr = (
|
|
"device" => "type",
|
|
"type-model" => "mtm",
|
|
"serial-number" => "serial",
|
|
"side" => "side",
|
|
"ip-addresses" => "ip",
|
|
"hostname" => "hostname",
|
|
);
|
|
|
|
#######################################
|
|
# Invalid IP address list
|
|
#######################################
|
|
my @invalidiplist = (
|
|
"192.168.2.144",
|
|
"192.168.2.145",
|
|
"192.168.2.146",
|
|
"192.168.2.147",
|
|
"192.168.2.148",
|
|
"192.168.2.149",
|
|
"192.168.3.144",
|
|
"192.168.3.145",
|
|
"192.168.3.146",
|
|
"192.168.3.147",
|
|
"192.168.3.148",
|
|
"192.168.3.149",
|
|
"169.254.",
|
|
"127.0.0.0",
|
|
"127",
|
|
0,
|
|
);
|
|
|
|
#######################################
|
|
# Power methods
|
|
#######################################
|
|
|
|
|
|
my %globalopt;
|
|
|
|
#these globals are only used in mn
|
|
my %ip_addr = ();
|
|
|
|
|
|
|
|
#my $macmap;
|
|
my @filternodes;
|
|
my $TRACE = 0;
|
|
my $DEBUG_MATCH = 0;
|
|
|
|
my %globalhwtype = (
|
|
fsp => $::NODETYPE_FSP,
|
|
bpa => $::NODETYPE_BPA,
|
|
lpar => $::NODETYPE_LPAR,
|
|
hmc => $::NODETYPE_HMC,
|
|
ivm => $::NODETYPE_IVM,
|
|
frame => $::NODETYPE_FRAME,
|
|
cec => $::NODETYPE_CEC,
|
|
cmm => $::NODETYPE_CMM,
|
|
imm2 => $::NODETYPE_IMM2,
|
|
pbmc => "pbmc",
|
|
);
|
|
my %globalnodetype = (
|
|
fsp => $::NODETYPE_PPC,
|
|
bpa => $::NODETYPE_PPC,
|
|
cec => $::NODETYPE_PPC,
|
|
frame => $::NODETYPE_PPC,
|
|
hmc => $::NODETYPE_PPC,
|
|
ivm => $::NODETYPE_PPC,
|
|
cmm => $::NODETYPE_MP,
|
|
lpar => "$::NODETYPE_PPC,$::NODETYPE_OSI",
|
|
pbmc => $::NODETYPE_MP,
|
|
);
|
|
my %globalmgt = (
|
|
fsp => "fsp",
|
|
bpa => "bpa",
|
|
cec => "fsp",
|
|
frame => "bpa",
|
|
mm => "blade",
|
|
ivm => "ivm",
|
|
rsa => "blade",
|
|
cmm => "blade",
|
|
imm2 => "blade",
|
|
hmc => "hmc",
|
|
pbmc => "ipmi",
|
|
);
|
|
my %globalid = (
|
|
fsp => "cid",
|
|
cec => "cid",
|
|
bpa => "fid",
|
|
frame => "fid"
|
|
);
|
|
##########################################################################
|
|
# Command handler method from tables
|
|
##########################################################################
|
|
sub handled_commands {
|
|
|
|
return ({ lsslp => "lsslp" });
|
|
}
|
|
|
|
##########################################################################
|
|
# Invokes the callback with the specified message
|
|
##########################################################################
|
|
sub send_msg {
|
|
|
|
my $request = shift;
|
|
my $ecode = shift;
|
|
my $msg = shift;
|
|
my %output;
|
|
|
|
#################################################
|
|
# Called from child process - send to parent
|
|
#################################################
|
|
if (exists($request->{pipe})) {
|
|
my $out = $request->{pipe};
|
|
|
|
$output{errorcode} = $ecode;
|
|
$output{data} = \@_;
|
|
print $out freeze([ \%output ]);
|
|
print $out "\nENDOFFREEZE6sK4ci\n";
|
|
}
|
|
#################################################
|
|
# Called from parent - invoke callback directly
|
|
#################################################
|
|
elsif (exists($request->{callback})) {
|
|
my $callback = $request->{callback};
|
|
$output{errorcode} = $ecode;
|
|
$output{data} = $msg;
|
|
$callback->(\%output);
|
|
}
|
|
}
|
|
|
|
|
|
##########################################################################
|
|
# Parse the command line options and operands
|
|
##########################################################################
|
|
sub parse_args {
|
|
|
|
my $request = shift;
|
|
my $args = $request->{arg};
|
|
my $cmd = $request->{command};
|
|
my %opt;
|
|
my %services = (
|
|
HMC => SOFTWARE_SERVICE . ":" . SERVICE_HMC . ":",
|
|
IVM => SOFTWARE_SERVICE . ":" . SERVICE_IVM . ":",
|
|
BPA => HARDWARE_SERVICE . ":" . SERVICE_BPA,
|
|
FSP => HARDWARE_SERVICE . ":" . SERVICE_FSP,
|
|
CEC => HARDWARE_SERVICE . ":" . SERVICE_CEC,
|
|
FRAME => HARDWARE_SERVICE . ":" . SERVICE_FRAME,
|
|
RSA => HARDWARE_SERVICE . ":" . SERVICE_RSA . ":",
|
|
CMM => HARDWARE_SERVICE . ":" . SERVICE_CMM,
|
|
IMM2 => HARDWARE_SERVICE . ":" . SERVICE_IMM2,
|
|
MM => HARDWARE_SERVICE . ":" . SERVICE_MM . ":",
|
|
PBMC => HARDWARE_SERVICE . ":" . SERVICE_FSP
|
|
);
|
|
#############################################
|
|
# Responds with usage statement
|
|
#############################################
|
|
local *usage = sub {
|
|
my $usage_string = xCAT::Usage->getUsage($cmd);
|
|
return ([ $_[0], $usage_string ]);
|
|
};
|
|
#############################################
|
|
# No command-line arguments - use defaults
|
|
#############################################
|
|
if (!defined($args)) {
|
|
return (0);
|
|
}
|
|
#############################################
|
|
# 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");
|
|
|
|
#############################################
|
|
# Process command-line flags
|
|
#############################################
|
|
if (!GetOptions(\%opt,
|
|
qw(h|help V|verbose v|version i=s x z w r s=s e=s t=s m c n C=s T=s I u range=s flexdiscover updatehosts vpdtable))) {
|
|
return (usage());
|
|
}
|
|
|
|
#############################################
|
|
# Check for node range
|
|
#############################################
|
|
if (scalar(@ARGV) == 1) {
|
|
my @nodes = xCAT::NodeRange::noderange(@ARGV);
|
|
foreach (@nodes) {
|
|
push @filternodes, $_;
|
|
}
|
|
unless (@filternodes) {
|
|
return (usage("Invalid Argument: $ARGV[0]"));
|
|
}
|
|
} elsif (scalar(@ARGV) > 1) {
|
|
return (usage("Invalid flag, please check and retry."));
|
|
}
|
|
|
|
#############################################
|
|
# Option -V for verbose output
|
|
#############################################
|
|
if (exists($opt{V})) {
|
|
$globalopt{verbose} = 1;
|
|
}
|
|
|
|
#############################################
|
|
# Check for mutually-exclusive formatting
|
|
#############################################
|
|
if ((exists($opt{r}) + exists($opt{x}) + exists($opt{z}) + exists($opt{vpdtable})) > 1) {
|
|
return (usage());
|
|
}
|
|
#############################################
|
|
# Command tries
|
|
#############################################
|
|
if (exists($opt{t})) {
|
|
$globalopt{maxtries} = $opt{t};
|
|
|
|
if ($globalopt{maxtries} !~ /^\d+$/) {
|
|
return (usage("Invalid command tries (1-9)"));
|
|
}
|
|
}
|
|
|
|
#############################################
|
|
# Check for unsupported service type
|
|
#############################################
|
|
if (exists($opt{s})) {
|
|
if (!exists($services{ $opt{s} })) {
|
|
return (usage("Invalid service: $opt{s}"));
|
|
}
|
|
$option_s = $opt{s};
|
|
$globalopt{service} = $services{ $opt{s} };
|
|
}
|
|
#############################################
|
|
# Check the validation of -T option
|
|
#############################################
|
|
if (exists($opt{T})) {
|
|
$globalopt{T} = $opt{T};
|
|
if ($globalopt{T} !~ /^\d+$/) {
|
|
return (usage("Invalid timeout value, should be number"));
|
|
}
|
|
|
|
#if (!exists( $opt{C} )) {
|
|
# return ( usage( "-T should be used with -C" ));
|
|
#}
|
|
}
|
|
|
|
#############################################
|
|
# Check the validation of -C option
|
|
#############################################
|
|
if (exists($opt{C})) {
|
|
$globalopt{C} = $opt{C};
|
|
|
|
if ($globalopt{C} !~ /^\d+$/) {
|
|
return (usage("Invalid expect entries, should be number"));
|
|
}
|
|
if (!exists($opt{i})) {
|
|
return (usage("-C should be used with -i"));
|
|
}
|
|
}
|
|
|
|
#############################################
|
|
# Check the validation of -i option
|
|
#############################################
|
|
if (exists($opt{i})) {
|
|
foreach (split /,/, $opt{i}) {
|
|
my $ip = $_;
|
|
###################################
|
|
# Length for IPv4 addresses
|
|
###################################
|
|
my (@octets) = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/;
|
|
if (scalar(@octets) != 4) {
|
|
return (usage("Invalid IP address: $ip"));
|
|
}
|
|
foreach my $octet (@octets) {
|
|
if (($octet < 0) or ($octet > 255)) {
|
|
return (usage("Invalid IP address: $ip"));
|
|
}
|
|
}
|
|
}
|
|
$globalopt{i} = $opt{i};
|
|
}
|
|
|
|
#############################################
|
|
# write to the database
|
|
#############################################
|
|
if (exists($opt{w})) {
|
|
$globalopt{w} = 1;
|
|
}
|
|
|
|
#############################################
|
|
# list the raw information
|
|
#############################################
|
|
if (exists($opt{r})) {
|
|
$globalopt{r} = 1;
|
|
}
|
|
|
|
#############################################
|
|
# list the xml formate data
|
|
#############################################
|
|
if (exists($opt{x})) {
|
|
$globalopt{x} = 1;
|
|
}
|
|
|
|
#############################################
|
|
# list the stanza formate data
|
|
#############################################
|
|
if (exists($opt{z})) {
|
|
$globalopt{z} = 1;
|
|
}
|
|
|
|
#############################################
|
|
# match vpd table
|
|
#############################################
|
|
if (exists($opt{vpdtable})) {
|
|
$globalopt{vpdtable} = 1;
|
|
}
|
|
#########################################################
|
|
# only list the nodes that discovered for the first time
|
|
#########################################################
|
|
if (exists($opt{n})) {
|
|
$globalopt{n} = 1;
|
|
}
|
|
##############################################
|
|
# unicast
|
|
##############################################
|
|
if (exists($opt{u})) {
|
|
$globalopt{u} = 1;
|
|
unless (exists($opt{s}) and exists($opt{range})) {
|
|
return (usage("-u should be used with -s and --range"));
|
|
}
|
|
$globalopt{range} = $opt{range};
|
|
}
|
|
if (exists($opt{range})) {
|
|
unless (exists($opt{u})) {
|
|
return (usage("range is used in unicast mode"));
|
|
}
|
|
}
|
|
|
|
##############################################
|
|
# warn for no discovered nodes in database
|
|
##############################################
|
|
if (exists($opt{I})) {
|
|
$globalopt{I} = 1;
|
|
}
|
|
|
|
##############################################
|
|
# do slp and setup for cmm
|
|
##############################################
|
|
if (exists($opt{flexdiscover})) {
|
|
$globalopt{flexdiscover} = 1;
|
|
}
|
|
|
|
return (0);
|
|
}
|
|
|
|
|
|
##########################################################################
|
|
# Verbose mode (-V)
|
|
##########################################################################
|
|
sub trace {
|
|
|
|
my $request = shift;
|
|
my $msg = shift;
|
|
my $sig = shift;
|
|
|
|
if ($sig) {
|
|
if ($TRACE) {
|
|
my ($sec, $min, $hour, $mday, $mon, $yr, $wday, $yday, $dst) = localtime(time);
|
|
my $msg = sprintf "%02d:%02d:%02d %5d %s", $hour, $min, $sec, $$, $msg;
|
|
send_msg($request, 0, $msg);
|
|
}
|
|
} else {
|
|
if ($globalopt{verbose}) {
|
|
my ($sec, $min, $hour, $mday, $mon, $yr, $wday, $yday, $dst) = localtime(time);
|
|
my $msg = sprintf "%02d:%02d:%02d %5d %s", $hour, $min, $sec, $$, $msg;
|
|
send_msg($request, 0, $msg);
|
|
}
|
|
}
|
|
}
|
|
##########################################################################
|
|
# Forks a process to run the slp command (1 per adapter)
|
|
##########################################################################
|
|
sub fork_cmd {
|
|
|
|
my $request = shift;
|
|
|
|
#######################################
|
|
# Pipe childs output back to parent
|
|
#######################################
|
|
my $parent;
|
|
my $child;
|
|
pipe $parent, $child;
|
|
my $pid = xCAT::Utils->xfork();
|
|
|
|
if (!defined($pid)) {
|
|
###################################
|
|
# Fork error
|
|
###################################
|
|
send_msg($request, 1, "Fork error: $!");
|
|
return undef;
|
|
}
|
|
elsif ($pid == 0) {
|
|
###################################
|
|
# Child process
|
|
###################################
|
|
close($parent);
|
|
$request->{pipe} = $child;
|
|
|
|
invoke_dodiscover($request);
|
|
########################################
|
|
# Pass result array back to parent
|
|
########################################
|
|
my @results = ("FORMATDATA6sK4ci");
|
|
my $out = $request->{pipe};
|
|
|
|
print $out freeze(\@results);
|
|
print $out "\nENDOFFREEZE6sK4ci\n";
|
|
exit(0);
|
|
}
|
|
else {
|
|
###################################
|
|
# Parent process
|
|
###################################
|
|
close($child);
|
|
return ($parent);
|
|
}
|
|
return (0);
|
|
}
|
|
##########################################################################
|
|
# Run the forked command and send reply to parent
|
|
##########################################################################
|
|
sub invoke_dodiscover {
|
|
|
|
my $request = shift;
|
|
|
|
########################################
|
|
# SLP command
|
|
########################################
|
|
my $services;
|
|
my $maxt;
|
|
if ($globalopt{service}) {
|
|
$services = $globalopt{service};
|
|
} else {
|
|
$services = [ WILDCARD_SERVICE, HARDWARE_SERVICE, SOFTWARE_SERVICE, SERVICE_IMM2 ];
|
|
}
|
|
|
|
#efix for hmc bug
|
|
if ($services =~ /hardware-management-console/) {
|
|
$services = [SOFTWARE_SERVICE];
|
|
}
|
|
|
|
if ($globalopt{maxtries}) {
|
|
$maxt = $globalopt{maxtries};
|
|
} else {
|
|
$maxt = 0;
|
|
}
|
|
|
|
|
|
my %arg;
|
|
if ($globalopt{flexdiscover}) { #we do two SLP passes, one to hopefully catch the less numerous management modules reliably, a separate one to best-effort catch imms
|
|
$arg{SrvTypes} = [qw/service:management-hardware.IBM:chassis-management-module service:management-hardware.IBM:management-module/];
|
|
my ($searchmacsref, $sendcount, $rsp) = xCAT::SLP::dodiscover(SrvTypes => $arg{SrvTypes}, Callback => \&bt_handle_new_slp_entity);
|
|
$arg{SrvTypes} = [qw/service:management-hardware.IBM:integrated-management-module2/];
|
|
my ($newsearchmacsref, $newsendcount, $newrsp) = xCAT::SLP::dodiscover(SrvTypes => $arg{SrvTypes}, Callback => \&bt_handle_new_slp_entity);
|
|
foreach (keys %$newsearchmacsref) {
|
|
$searchmacsref->{$_} = $newsearchmacsref->{$_};
|
|
}
|
|
$sendcount += $newsendcount;
|
|
$rsp += $newrsp;
|
|
return ($searchmacsref, $sendcount, $rsp);
|
|
}
|
|
$arg{SrvTypes} = $services;
|
|
|
|
#$arg{Callback} = \&handle_new_slp_entity;
|
|
$arg{Ip} = $globalopt{i} if ($globalopt{i});
|
|
$arg{Retry} = $maxt;
|
|
$arg{Count} = $globalopt{C} if ($globalopt{C});
|
|
$arg{Time} = $globalopt{T} if ($globalopt{T});
|
|
$arg{nomsg} = 1 if ($globalopt{z} or $globalopt{x});
|
|
$arg{reqcallback} = $request->{callback} if ($request->{callback});
|
|
if ($globalopt{u}) {
|
|
$arg{unicast} = 1;
|
|
$arg{range} = $globalopt{range};
|
|
}
|
|
my ($searchmacsref, $sendcount, $rsp) = xCAT::SLP::dodiscover(%arg);
|
|
|
|
|
|
#########################################
|
|
## Need to check if the result is enough
|
|
#########################################
|
|
#if ( $request->{C} != 0) {
|
|
# send_msg( $request, 0, "\n Begin to try again, this may takes long time \n" );
|
|
# my %val_tmp = %$values;
|
|
# my %found_cec;
|
|
# for my $v (keys %val_tmp) {
|
|
# $v =~ /type=([^\)]+)\)\,\(serial-number=([^\)]+)\)\,\(machinetype-model=([^\)]+)\)\,/;
|
|
# if ( $found_cec{$2.'*'.$3} ne 1 and $1 eq SERVICE_FSP) {
|
|
# $found_cec{$2.'*'.$3} = 1;
|
|
# }
|
|
# }
|
|
#
|
|
# my $rlt;
|
|
# my $val;
|
|
# my $start_time = Time::HiRes::gettimeofday();
|
|
# my $elapse;
|
|
# my $found = scalar(keys %found_cec);
|
|
# while ( $found < $globalopt{C} ) {
|
|
# $rlt = xCAT::SLP::dodiscover(SrvTypes=>$services,Callback=>sub { print Dumper(@_) });
|
|
# $val = @$rlt[1];
|
|
# for my $v (keys %$val) {
|
|
# $v =~ /type=([^\)]+)\)\,\(serial-number=([^\)]+)\)\,\(machinetype-model=([^\)]+)\)\,/;
|
|
# if ( $found_cec{$2.'*'.$3} ne 1 and $1 eq SERVICE_FSP) {
|
|
# $found_cec{$2.'*'.$3} = 1;
|
|
# $val_tmp{$v} = 1;
|
|
# }
|
|
# }
|
|
# $found = scalar(keys %val_tmp);
|
|
# $elapse = Time::HiRes::gettimeofday() - $start_time;
|
|
# if ( $elapse > $globalopt{time_out} ) {
|
|
# send_msg( $request, 0, "Time out, Force return.\n" );
|
|
# last;
|
|
# }
|
|
# }
|
|
# send_msg( $request, 0, "Discovered $found nodes \n" );
|
|
# $values = \%val_tmp;
|
|
#}
|
|
|
|
return ($searchmacsref, $sendcount, $rsp);
|
|
}
|
|
|
|
|
|
##########################################################################
|
|
# Formats slp responses
|
|
##########################################################################
|
|
sub format_output {
|
|
|
|
my $request = shift;
|
|
my $searchmacsref = shift;
|
|
my %searchmacs = %$searchmacsref;
|
|
my $length = length($header[IP_ADDRESSES][TEXT]);
|
|
my $result;
|
|
|
|
###########################################
|
|
# No responses
|
|
###########################################
|
|
if (keys %searchmacs == 0) {
|
|
send_msg($request, 0, "No responses");
|
|
return;
|
|
}
|
|
|
|
###########################################
|
|
# Check -C -T
|
|
###########################################
|
|
if ($globalopt{C}) {
|
|
if (scalar(keys %searchmacs) ne $globalopt{C}) {
|
|
send_msg($request, 0, "Timeout...Fource to return");
|
|
}
|
|
}
|
|
###########################################
|
|
# Read table to get exists data
|
|
###########################################
|
|
unless ($globalopt{service} =~ /hardware-management-console/) {
|
|
my $errcode = read_from_table();
|
|
if ($errcode) {
|
|
send_msg($request, 0, "Can't open $errcode table");
|
|
return;
|
|
}
|
|
}
|
|
###########################################
|
|
# Parse responses and add to hash
|
|
###########################################
|
|
my $outhash = parse_responses($request, \$length, $searchmacsref);
|
|
|
|
#hmc bug efix
|
|
#my $newouthash;
|
|
#if ($globalopt{service} =~ /hardware-management-console/) {
|
|
# for my $en ( keys %$outhash ) {
|
|
# if (${$outhash->{$en}}{type} eq 'hmc') {
|
|
# $newouthash->{$en} = $outhash->{$en};
|
|
# }
|
|
# }
|
|
# $outhash = $newouthash;
|
|
#}
|
|
|
|
###########################################
|
|
# filter the result in the same vlan
|
|
###########################################
|
|
if (exists($globalopt{i})) {
|
|
my $outhash1 = filtersamevlan($outhash);
|
|
$outhash = $outhash1;
|
|
}
|
|
|
|
# filter the result and keep the specified nodes
|
|
###########################################
|
|
if (scalar(@filternodes)) {
|
|
my $outhash1 = filter($outhash);
|
|
$outhash = $outhash1;
|
|
}
|
|
|
|
###########################################
|
|
# -w flag for write to xCat database
|
|
###########################################
|
|
if ($globalopt{w}) {
|
|
send_msg($request, 0, "Begin to write into Database, this may change node name");
|
|
xCATdB($outhash);
|
|
}
|
|
|
|
|
|
|
|
###########################################
|
|
# -r flag for raw response format
|
|
###########################################
|
|
my %rawhash;
|
|
if ($globalopt{r}) {
|
|
foreach (keys %$outhash) {
|
|
my $raw = ${ $outhash->{$_} }{url};
|
|
$rawhash{$raw} = 1;
|
|
}
|
|
foreach my $en (keys %rawhash) {
|
|
if ($en =~ /(\(type.*\))/) {
|
|
$result .= "$1\n";
|
|
}
|
|
}
|
|
|
|
send_msg($request, 0, $result);
|
|
return;
|
|
}
|
|
###########################################
|
|
# -x flag for xml format
|
|
###########################################
|
|
if ($globalopt{x}) {
|
|
send_msg($request, 0, format_xml($outhash));
|
|
return;
|
|
}
|
|
###########################################
|
|
# -z flag for stanza format
|
|
###########################################
|
|
if ($globalopt{z}) {
|
|
send_msg($request, 0, format_stanza($outhash));
|
|
return;
|
|
}
|
|
|
|
###########################################
|
|
# -T flag for vpd table format
|
|
###########################################
|
|
if ($globalopt{vpdtable}) {
|
|
send_msg($request, 0, format_table($outhash));
|
|
return;
|
|
}
|
|
|
|
###########################################
|
|
# Get longest IP for formatting purposes
|
|
###########################################
|
|
my $format = sprintf "%%-%ds", ($length + 2);
|
|
$header[IP_ADDRESSES][FORMAT] = $format;
|
|
|
|
###########################################
|
|
# Display header
|
|
###########################################
|
|
foreach (@header) {
|
|
$result .= sprintf @$_[1], @$_[0];
|
|
}
|
|
$result .= "\n";
|
|
|
|
###########################################
|
|
# Display response attributes
|
|
###########################################
|
|
foreach my $nameentry (sort keys %$outhash) {
|
|
my $hostname = ${ $outhash->{$nameentry} }{hostname};
|
|
|
|
foreach (@header) {
|
|
my $attr = $headertoattr{ @$_[0] };
|
|
$result .= sprintf @$_[1], ${ $outhash->{$nameentry} }{$attr};
|
|
|
|
}
|
|
$result .= "\n";
|
|
}
|
|
send_msg($request, 0, $result);
|
|
}
|
|
|
|
##########################################################################
|
|
# Read the table and cache the data that will be used frequently
|
|
##########################################################################
|
|
sub read_from_table {
|
|
my %vpdhash;
|
|
my @nodelist;
|
|
my %ppchash;
|
|
my %iphash;
|
|
|
|
if (!(%::OLD_DATA_CACHE))
|
|
{
|
|
#find out all the existed nodes
|
|
my $nodelisttab = xCAT::Table->new('nodelist');
|
|
if ($nodelisttab) {
|
|
my @typeentries = $nodelisttab->getAllNodeAttribs(['node']);
|
|
for my $typeentry (@typeentries) {
|
|
push @nodelist, $typeentry->{node};
|
|
}
|
|
} else {
|
|
return "nodelist";
|
|
}
|
|
|
|
#find out all the existed nodes
|
|
my $hoststab = xCAT::Table->new('hosts');
|
|
if ($hoststab) {
|
|
my @hostsentries = $hoststab->getAllNodeAttribs([ 'node', 'ip' ]);
|
|
for my $hostsentry (@hostsentries) {
|
|
$iphash{ $hostsentry->{node} } = $hostsentry->{ip};
|
|
}
|
|
} else {
|
|
return "hosts";
|
|
}
|
|
|
|
#find out all the existed nodes' type
|
|
my $typehashref = xCAT::DBobjUtils->getnodetype(\@nodelist);
|
|
|
|
# find out all the existed nodes' mtms and side
|
|
my $vpdtab = xCAT::Table->new('vpd');
|
|
if ($vpdtab) {
|
|
my @vpdentries = $vpdtab->getAllNodeAttribs([ 'node', 'mtm', 'serial', 'side' ]);
|
|
for my $entry (@vpdentries) {
|
|
@{ $vpdhash{ $entry->{node} } }[0] = $entry->{mtm};
|
|
@{ $vpdhash{ $entry->{node} } }[1] = $entry->{serial};
|
|
@{ $vpdhash{ $entry->{node} } }[2] = $entry->{side};
|
|
}
|
|
} else {
|
|
return "vpd";
|
|
}
|
|
|
|
# find out all the existed nodes' attributes
|
|
my $ppctab = xCAT::Table->new('ppc');
|
|
if ($ppctab) {
|
|
my @identries = $ppctab->getAllNodeAttribs([ 'node', 'id', 'parent' ]);
|
|
for my $entry (@identries) {
|
|
next if ($entry->{nodetype} =~ /lpar/);
|
|
@{ $ppchash{ $entry->{node} } }[0] = $entry->{id}; #id
|
|
@{ $ppchash{ $entry->{node} } }[1] = $entry->{parent}; #parent
|
|
}
|
|
} else {
|
|
return "ppc";
|
|
}
|
|
|
|
foreach my $node (@nodelist) {
|
|
my $type = $$typehashref{$node};
|
|
my $mtm = @{ $vpdhash{$node} }[0];
|
|
my $sn = @{ $vpdhash{$node} }[1];
|
|
my $side = @{ $vpdhash{$node} }[2];
|
|
my $id = $ppchash{$node}[0];
|
|
my $parent = $ppchash{$node}[1];
|
|
my $pmtm = @{ $vpdhash{$parent} }[0];
|
|
my $psn = @{ $vpdhash{$parent} }[1];
|
|
my $ip = $iphash{$node};
|
|
if ($type =~ /frame/) {
|
|
$::OLD_DATA_CACHE{ "frame*" . $mtm . "*" . $sn } = $node if (defined $mtm and defined $sn);
|
|
} elsif ($type =~ /cec/) {
|
|
$::OLD_DATA_CACHE{ "cec*" . $mtm . "*" . $sn } = $node if (defined $mtm and defined $sn);
|
|
my $iid = int($id);
|
|
$parent = 'Server-' . $pmtm . '-SN' . $psn;
|
|
$::OLD_DATA_CACHE{ "cec*" . $parent . "*" . $iid } = $node if (defined $parent and defined $id);
|
|
} elsif ($type =~ /^fsp|bpa$/) {
|
|
$::OLD_DATA_CACHE{ $type . "*" . $mtm . "*" . $sn . "*" . $side } = $node if (defined $mtm and defined $sn);
|
|
} elsif ($type =~ /hmc/) {
|
|
$::OLD_DATA_CACHE{ "hmc*" . $ip } = $node if (defined $ip);
|
|
} else {
|
|
$::OLD_DATA_CACHE{ $type . "*" . $mtm . "*" . $sn } = $node if (defined $mtm and defined $sn);
|
|
}
|
|
}
|
|
}
|
|
return undef;
|
|
}
|
|
##########################################################################
|
|
# Makesure the ip in SLP URL is valid
|
|
# return 1 if valid, 0 if invalid
|
|
##########################################################################
|
|
sub check_ip {
|
|
my $myip = shift;
|
|
$myip =~ s/^(\d+)\..*/$1/;
|
|
if ($myip >= 224 and $myip <= 239) {
|
|
return 0;
|
|
}
|
|
foreach (@invalidiplist) {
|
|
if ($myip =~ /^($_)/) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
##########################################################################
|
|
# Get hostname from SLP URL response
|
|
##########################################################################
|
|
sub get_host_from_url {
|
|
|
|
my $request = shift;
|
|
my $attr = shift;
|
|
my $vip;
|
|
my $host;
|
|
|
|
#######################################
|
|
# Extract IP from URL
|
|
#######################################
|
|
my $nets = xCAT::NetworkUtils::my_nets();
|
|
my $inc = $globalopt{i};
|
|
my @ips = (exists $attr->{'ip-address'}) ? @{ $attr->{'ip-address'} } : @{ $attr->{'ipv4-address'} };
|
|
|
|
my @ips2 = split /,/, $inc;
|
|
my @validip;
|
|
if ($inc) {
|
|
for my $net (keys %$nets) {
|
|
my $fg = 1;
|
|
for my $einc (@ips2) {
|
|
if ($nets->{$net} eq $einc) {
|
|
$fg = 0;
|
|
}
|
|
}
|
|
delete $nets->{$net} if ($fg);
|
|
}
|
|
}
|
|
#######################################
|
|
# Check if valid IP
|
|
#######################################
|
|
for my $tip (@ips) {
|
|
next if ($tip =~ /:/); #skip IPV6 addresses
|
|
for my $net (keys %$nets) {
|
|
my ($n, $m) = split /\//, $net;
|
|
if ( #xCAT::NetworkUtils::isInSameSubnet($n, $tip, $m, 1) and
|
|
xCAT::NetworkUtils::isPingable($tip) and (length(inet_aton($tip)) == 4)) {
|
|
push @validip, $tip;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
if (scalar(@validip) == 0) {
|
|
trace($request, "Invalid IP address in URL");
|
|
return undef;
|
|
}
|
|
|
|
|
|
#######################################
|
|
# Get Factory Hostname
|
|
#######################################
|
|
if (${ $attr->{'hostname'} }[0]) {
|
|
$host = ${ $attr->{'hostname'} }[0];
|
|
|
|
} else {
|
|
$host = "Server-" . ${ $attr->{'machinetype-model'} }[0] . "-SN" . ${ $attr->{'serial-number'} }[0];
|
|
foreach my $ip (@validip) {
|
|
my $hname = gethostbyaddr(inet_aton($ip), AF_INET);
|
|
if ($hname) {
|
|
$host = $hname;
|
|
$vip = $ip;
|
|
last;
|
|
|
|
}
|
|
}
|
|
foreach my $ip (@validip) {
|
|
my $hoststab = xCAT::Table->new('hosts');
|
|
my @entries = $hoststab->getAllNodeAttribs([ 'node', 'ip' ]);
|
|
foreach my $entry (@entries) {
|
|
if ($entry->{ip} and $entry->{ip} eq $ip) {
|
|
$host = $entry->{node};
|
|
$vip = $ip;
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if ($host =~ /([^\.]+)\./) {
|
|
$host = $1;
|
|
}
|
|
return $host;
|
|
|
|
}
|
|
|
|
##########################################################################
|
|
#
|
|
#########################################################################
|
|
sub parse_responses {
|
|
|
|
my $request = shift;
|
|
my $length = shift;
|
|
my $searchmacsref = shift;
|
|
my $matchflag;
|
|
my %outhash;
|
|
my $host;
|
|
my @matchnode;
|
|
my @cmmnodes;
|
|
my %searchmacs = %$searchmacsref;
|
|
|
|
#get networks information for defining HMC
|
|
my %net;
|
|
my %addr;
|
|
my $nettab = xCAT::Table->new('networks');
|
|
my @nets = $nettab->getAllAttribs('netname', 'net', 'mask', 'mgtifname');
|
|
if (scalar(@nets) == 0) {
|
|
send_msg($request, 0, "Can't get networks information from networks table");
|
|
} else {
|
|
foreach my $enet (@nets) {
|
|
next if ($enet->{'net'} =~ /:/);
|
|
$net{ $enet->{'mgtifname'} }{subnet} = $enet->{'net'};
|
|
$net{ $enet->{'mgtifname'} }{netmask} = $enet->{'mask'};
|
|
}
|
|
}
|
|
my $netref = xCAT::NetworkUtils->get_nic_ip();
|
|
for my $entry (keys %$netref) {
|
|
$addr{ $netref->{$entry} }{subnet} = $net{$entry}{subnet};
|
|
$addr{ $netref->{$entry} }{netmask} = $net{$entry}{netmask};
|
|
}
|
|
|
|
trace($request, "Now lsslp begin to parse its response...");
|
|
foreach my $rsp (keys(%searchmacs)) {
|
|
###########################################
|
|
# attribute not found
|
|
###########################################
|
|
if (!exists(${ $searchmacs{$rsp} }{attributes})) {
|
|
trace($request, "Attribute not found for $rsp");
|
|
next;
|
|
}
|
|
###########################################
|
|
# Valid service-type attribute
|
|
###########################################
|
|
my $attributes = ${ $searchmacs{$rsp} }{attributes};
|
|
my $type = ${ $attributes->{'type'} }[0];
|
|
if (!exists($service_slp{$type})) {
|
|
trace($request, "Discarding unsupported type $type");
|
|
next;
|
|
}
|
|
|
|
|
|
###########################################
|
|
# Define nodes
|
|
###########################################
|
|
my %atthash;
|
|
if (($type eq SERVICE_RSA) or ($type eq SERVICE_RSA2) or
|
|
($type eq SERVICE_MM) or ($type eq SERVICE_IMM2)) {
|
|
$atthash{type} = $service_slp{$type};
|
|
$atthash{mtm} = ${ $attributes->{'enclosure-machinetype-model'} }[0];
|
|
$atthash{serial} = ${ $attributes->{'enclosure-serial-number'} }[0];
|
|
$atthash{slot} = int(${ $attributes->{'slot'} }[0]);
|
|
if ($type eq SERVICE_IMM2) { $atthash{ip} = ${ $attributes->{'ipv4-address'} }[0]; }
|
|
else { $atthash{ip} = ${ $attributes->{'ip-address'} }[0]; }
|
|
$atthash{mac} = $rsp;
|
|
$atthash{hostname} = get_host_from_url($request, $attributes);
|
|
$atthash{otherinterfaces} = ${ $attributes->{'ip-address'} }[0];
|
|
$atthash{url} = ${ $searchmacs{$rsp} }{payload};
|
|
$outhash{ 'Server-' . $atthash{mtm} . '-SN' . $atthash{serial} } = \%atthash;
|
|
$$length = length($atthash{ip}) if (length($atthash{ip}) > $$length);
|
|
trace($request, "Discover node $atthash{hostname}: type is $atthash{type}, \
|
|
mtm is $atthash{mtm}, sn is $atthash{serial}, slot is $atthash{slot}, \
|
|
ip is $atthash{ip}, mac is $atthash{mac}, otherinterfaces is $atthash{otherinterfaces}");
|
|
|
|
} elsif ($type eq SERVICE_CMM) {
|
|
$atthash{type} = $service_slp{$type};
|
|
$atthash{mtm} = ${ $attributes->{'enclosure-mtm'} }[0];
|
|
$atthash{serial} = ${ $attributes->{'enclosure-serial-number'} }[0];
|
|
$atthash{side} = int(${ $attributes->{'slot'} }[0]);
|
|
$atthash{ip} = ${ $attributes->{'ipv4-address'} }[0];
|
|
$atthash{mac} = $rsp;
|
|
$atthash{mname} = ${ $attributes->{'mm-name'} }[0];
|
|
$atthash{url} = ${ $searchmacs{$rsp} }{payload};
|
|
$atthash{hostname} = get_host_from_url($request, $attributes);
|
|
$atthash{mpa} = $atthash{hostname};
|
|
$atthash{otherinterfaces} = ${ $attributes->{'ipv4-address'} }[0];
|
|
$outhash{ 'Server-' . $atthash{mtm} . '-SN' . $atthash{serial} } = \%atthash;
|
|
$$length = length($atthash{ip}) if (length($atthash{ip}) > $$length);
|
|
|
|
if (exists($::OLD_DATA_CACHE{ "mp*" . $atthash{mtm} . "*" . $atthash{serial} })) {
|
|
$atthash{hostname} = $::OLD_DATA_CACHE{ "mp*" . $atthash{mtm} . "*" . $atthash{serial} };
|
|
push @matchnode, 'Server-' . $atthash{mtm} . '-SN' . $atthash{serial};
|
|
}
|
|
push @cmmnodes, 'Server-' . $atthash{mtm} . '-SN' . $atthash{serial};
|
|
trace($request, "Discover node $atthash{hostname}: type is $atthash{type}, \
|
|
mtm is $atthash{mtm}, sn is $atthash{serial}, side is $atthash{side}, \
|
|
ip is $atthash{ip}, mac is $atthash{mac}, mname is $atthash{mname},\
|
|
mpa is $atthash{mpa}, otherinterfaces is $atthash{otherinterfaces}");
|
|
|
|
} elsif ($type eq SERVICE_HMC) {
|
|
$atthash{type} = $service_slp{$type};
|
|
$atthash{mtm} = ${ $attributes->{'machinetype-model'} }[0];
|
|
$atthash{serial} = ${ $attributes->{'serial-number'} }[0];
|
|
$atthash{ip} = ${ $attributes->{'ip-address'} }[0];
|
|
$atthash{hostname} = get_host_from_url($request, $attributes);
|
|
my @ips = @{ $attributes->{'ip-address'} };
|
|
foreach my $tmpip (@ips) {
|
|
if (exists($::OLD_DATA_CACHE{ "hmc*" . $tmpip })) {
|
|
$atthash{hostname} = $::OLD_DATA_CACHE{ "hmc*" . $tmpip };
|
|
push @matchnode, 'Server-' . $atthash{mtm} . '-SN' . $atthash{serial};
|
|
$atthash{ip} = $tmpip;
|
|
}
|
|
}
|
|
$atthash{mac} = $rsp;
|
|
$atthash{url} = ${ $searchmacs{$rsp} }{payload};
|
|
$atthash{otherinterfaces} = ${ $attributes->{'ip-address'} }[0];
|
|
$outhash{ 'Server-' . $atthash{mtm} . '-SN' . $atthash{serial} } = \%atthash;
|
|
$$length = length($atthash{ip}) if (length($atthash{ip}) > $$length);
|
|
trace($request, "Discover node $atthash{hostname}: type is $atthash{type},\
|
|
mtm is $atthash{mtm},sn is $atthash{serial}, ip is $atthash{ip},\
|
|
mac is $atthash{mac}, otherinterfaces is $atthash{otherinterfaces}");
|
|
} elsif ($type eq SERVICE_IVM) {
|
|
$atthash{type} = $service_slp{$type};
|
|
$atthash{mtm} = ${ $attributes->{'machinetype-model'} }[0];
|
|
$atthash{serial} = ${ $attributes->{'serial-number'} }[0];
|
|
$atthash{id} = ${ $attributes->{'lparid'} }[0];
|
|
$atthash{ip} = ${ $attributes->{'ip-address'} }[0];
|
|
$atthash{hostname} = get_host_from_url($request, $attributes);
|
|
$atthash{hostname} =~ s/^Server/ivm/;
|
|
my @ips = @{ $attributes->{'ip-address'} };
|
|
|
|
foreach my $tmpip (@ips) {
|
|
if (exists($::OLD_DATA_CACHE{ "ivm*" . $atthash{mtm} . "*" . $atthash{serial} })) {
|
|
$atthash{hostname} = $::OLD_DATA_CACHE{ "ivm*" . $atthash{mtm} . "*" . $atthash{serial} };
|
|
push @matchnode, 'Server-' . $atthash{mtm} . '-SN' . $atthash{serial};
|
|
$atthash{ip} = $tmpip;
|
|
}
|
|
}
|
|
$atthash{mac} = $rsp;
|
|
$atthash{url} = ${ $searchmacs{$rsp} }{payload};
|
|
$atthash{otherinterfaces} = ${ $attributes->{'ip-address'} }[0];
|
|
$outhash{ 'Server-' . $atthash{mtm} . '-SN' . $atthash{serial} } = \%atthash;
|
|
$$length = length($atthash{ip}) if (length($atthash{ip}) > $$length);
|
|
trace($request, "Discover node $atthash{hostname}: type is $atthash{type},\
|
|
mtm is $atthash{mtm},sn is $atthash{serial}, ip is $atthash{ip},\
|
|
mac is $atthash{mac}, otherinterfaces is $atthash{otherinterfaces}");
|
|
} elsif (($type eq SERVICE_FSP) && ($option_s eq "PBMC")) {
|
|
my %tmphash;
|
|
$atthash{type} = "pbmc";
|
|
$atthash{mtm} = ${ $attributes->{'machinetype-model'} }[0];
|
|
$atthash{serial} = ${ $attributes->{'serial-number'} }[0];
|
|
$atthash{ip} = ${ $searchmacs{$rsp} }{peername};
|
|
$atthash{url} = ${ $searchmacs{$rsp} }{payload};
|
|
$atthash{hostname} = 'Server-' . $atthash{mtm} . '-SN' . $atthash{serial};
|
|
if (exists($::OLD_DATA_CACHE{ "mp*" . $atthash{mtm} . "*" . $atthash{serial} })) {
|
|
$atthash{hostname} = $::OLD_DATA_CACHE{ "mp*" . $atthash{mtm} . "*" . $atthash{serial} };
|
|
push @matchnode, 'Server-' . $atthash{mtm} . '-SN' . $atthash{serial};
|
|
}
|
|
$outhash{ 'Server-' . $atthash{mtm} . '-SN' . $atthash{serial} } = \%atthash;
|
|
|
|
} elsif (($type eq SERVICE_FSP) && (${ $attributes->{'machinetype-model'} }[0] =~ /^7895|1457|7954/)) {
|
|
|
|
# Skip this entry if "-s CEC" was specified - we do not list FSP entries for Flex when only CECs were requested
|
|
next unless ($option_s ne "CEC");
|
|
|
|
#begin to define fsp and bpa
|
|
my %tmphash;
|
|
$tmphash{type} = ($type eq SERVICE_BPA) ? TYPE_BPA : TYPE_FSP;
|
|
$tmphash{mtm} = ${ $attributes->{'machinetype-model'} }[0];
|
|
$tmphash{serial} = ${ $attributes->{'serial-number'} }[0];
|
|
$tmphash{ip} = ${ $searchmacs{$rsp} }{peername};
|
|
my $loc = ($tmphash{ip} =~ ${ $attributes->{'ip-address'} }[0]) ? 0 : 1; #every entry has two ip-addresses
|
|
$tmphash{side} = (int(${ $attributes->{'slot'} }[0]) == 0) ? 'B-' . $loc : 'A-' . $loc;
|
|
$tmphash{mac} = $rsp;
|
|
$tmphash{parent} = 'Server-' . $tmphash{mtm} . '-SN' . $tmphash{serial};
|
|
$tmphash{hostname} = $tmphash{ip};
|
|
$tmphash{url} = ${ $searchmacs{$rsp} }{payload};
|
|
$tmphash{otherinterfaces} = ${ $searchmacs{$rsp} }{peername};
|
|
$tmphash{bpcmtm} = ${ $attributes->{'bpc-machinetype-model'} }[0];
|
|
$tmphash{bpcsn} = ${ $attributes->{'bpc-serial-number'} }[0];
|
|
$tmphash{fid} = int(${ $attributes->{'frame-number'} }[0]);
|
|
$tmphash{cid} = int(${ $attributes->{'cage-number'} }[0]);
|
|
$outhash{ $tmphash{ip} } = \%tmphash;
|
|
$$length = length($tmphash{ip}) if (length($tmphash{ip}) > $$length);
|
|
trace($request, "Discover node $tmphash{hostname}:type is $tmphash{type}, mtm is $tmphash{mtm}, \
|
|
sn is $tmphash{serial}, side is $tmphash{side},parent is $tmphash{parent},ip is $tmphash{ip}, \
|
|
cec id is $tmphash{cid} , frame id is $tmphash{fid},mac is $tmphash{mac}, \
|
|
otherinterfaces is $tmphash{otherinterfaces}");
|
|
|
|
#####################################################################
|
|
#define another side to fix the issue that the result is imcomplete
|
|
#####################################################################
|
|
my %tmphash1;
|
|
$tmphash1{ip} = (${ $searchmacs{$rsp} }{peername} =~ ${ $attributes->{'ip-address'} }[0]) ? ${ $attributes->{'ip-address'} }[1] : ${ $attributes->{'ip-address'} }[0];
|
|
unless ($outhash{ $tmphash1{ip} }) {
|
|
my $validflag = 1;
|
|
foreach (@invalidiplist) {
|
|
if ($tmphash1{ip} =~ /^($_)/) {
|
|
$validflag = 0;
|
|
last;
|
|
}
|
|
}
|
|
if ($validflag == 1) {
|
|
$tmphash1{type} = ($type eq SERVICE_BPA) ? TYPE_BPA : TYPE_FSP;
|
|
$tmphash1{mtm} = ${ $attributes->{'machinetype-model'} }[0];
|
|
$tmphash1{serial} = ${ $attributes->{'serial-number'} }[0];
|
|
my $loc = ($tmphash1{ip} =~ ${ $attributes->{'ip-address'} }[0]) ? 0 : 1; #every entry has two ip-addresses
|
|
$tmphash1{side} = (int(${ $attributes->{'slot'} }[0]) == 0) ? 'B-' . $loc : 'A-' . $loc;
|
|
$tmphash1{mac} = xCAT::SLP::get_mac_for_addr($tmphash1{ip});
|
|
$tmphash1{parent} = 'Server-' . $tmphash1{mtm} . '-SN' . $tmphash1{serial};
|
|
$tmphash1{hostname} = $tmphash1{ip};
|
|
$tmphash1{otherinterfaces} = ${ $searchmacs{$rsp} }{peername};
|
|
$tmphash1{bpcmtm} = ${ $attributes->{'bpc-machinetype-model'} }[0];
|
|
$tmphash1{bpcsn} = ${ $attributes->{'bpc-serial-number'} }[0];
|
|
$tmphash1{fid} = int(${ $attributes->{'frame-number'} }[0]);
|
|
$tmphash1{cid} = int(${ $attributes->{'cage-number'} }[0]);
|
|
$outhash{ $tmphash1{ip} } = \%tmphash1;
|
|
$$length = length($tmphash1{ip}) if (length($tmphash1{ip}) > $$length);
|
|
trace($request, "Discover another node $tmphash1{hostname}:type is $tmphash1{type}, mtm is $tmphash1{mtm}, \
|
|
sn is $tmphash1{serial}, side is $tmphash1{side},parent is $tmphash1{parent},ip is $tmphash1{ip}, \
|
|
cec id is $tmphash1{cid} , frame id is $tmphash1{fid},mac is $tmphash1{mac}, \
|
|
otherinterfaces is $tmphash1{otherinterfaces}");
|
|
}
|
|
}
|
|
} else {
|
|
|
|
#begin to define fsp and bpa
|
|
my %tmphash;
|
|
$tmphash{type} = ($type eq SERVICE_BPA) ? TYPE_BPA : TYPE_FSP;
|
|
$tmphash{mtm} = ${ $attributes->{'machinetype-model'} }[0];
|
|
$tmphash{serial} = ${ $attributes->{'serial-number'} }[0];
|
|
$tmphash{ip} = ${ $searchmacs{$rsp} }{peername};
|
|
my $loc = ($tmphash{ip} =~ ${ $attributes->{'ip-address'} }[0]) ? 0 : 1; #every entry has two ip-addresses
|
|
$tmphash{side} = (int(${ $attributes->{'slot'} }[0]) == 0) ? 'B-' . $loc : 'A-' . $loc;
|
|
$tmphash{mac} = $rsp;
|
|
$tmphash{parent} = 'Server-' . $tmphash{mtm} . '-SN' . $tmphash{serial};
|
|
$tmphash{hostname} = $tmphash{ip};
|
|
$tmphash{otherinterfaces} = ${ $searchmacs{$rsp} }{peername};
|
|
$tmphash{bpcmtm} = ${ $attributes->{'bpc-machinetype-model'} }[0];
|
|
$tmphash{bpcsn} = ${ $attributes->{'bpc-serial-number'} }[0];
|
|
$tmphash{fid} = int(${ $attributes->{'frame-number'} }[0]);
|
|
$tmphash{cid} = int(${ $attributes->{'cage-number'} }[0]);
|
|
$outhash{ $tmphash{ip} } = \%tmphash;
|
|
$$length = length($tmphash{ip}) if (length($tmphash{ip}) > $$length);
|
|
trace($request, "Discover node $tmphash{hostname}:type is $tmphash{type}, mtm is $tmphash{mtm}, \
|
|
sn is $tmphash{serial}, side is $tmphash{side},parent is $tmphash{parent},ip is $tmphash{ip}, \
|
|
cec id is $tmphash{cid} , frame id is $tmphash{fid},mac is $tmphash{mac}, \
|
|
otherinterfaces is $tmphash{otherinterfaces}");
|
|
|
|
#####################################################################
|
|
#define another side to fix the issue that the result is imcomplete
|
|
#####################################################################
|
|
my %tmphash1;
|
|
$tmphash1{ip} = (${ $searchmacs{$rsp} }{peername} =~ ${ $attributes->{'ip-address'} }[0]) ? ${ $attributes->{'ip-address'} }[1] : ${ $attributes->{'ip-address'} }[0];
|
|
unless ($outhash{ $tmphash1{ip} }) {
|
|
my $validflag = 1;
|
|
foreach (@invalidiplist) {
|
|
if ($tmphash1{ip} =~ /^($_)/) {
|
|
$validflag = 0;
|
|
last;
|
|
}
|
|
}
|
|
if ($validflag == 1) {
|
|
$tmphash1{type} = ($type eq SERVICE_BPA) ? TYPE_BPA : TYPE_FSP;
|
|
$tmphash1{mtm} = ${ $attributes->{'machinetype-model'} }[0];
|
|
$tmphash1{serial} = ${ $attributes->{'serial-number'} }[0];
|
|
my $loc = ($tmphash1{ip} =~ ${ $attributes->{'ip-address'} }[0]) ? 0 : 1; #every entry has two ip-addresses
|
|
$tmphash1{side} = (int(${ $attributes->{'slot'} }[0]) == 0) ? 'B-' . $loc : 'A-' . $loc;
|
|
$tmphash1{mac} = xCAT::SLP::get_mac_for_addr($tmphash1{ip});
|
|
$tmphash1{parent} = 'Server-' . $tmphash1{mtm} . '-SN' . $tmphash1{serial};
|
|
$tmphash1{hostname} = $tmphash1{ip};
|
|
$tmphash1{otherinterfaces} = ${ $searchmacs{$rsp} }{peername};
|
|
$tmphash1{bpcmtm} = ${ $attributes->{'bpc-machinetype-model'} }[0];
|
|
$tmphash1{bpcsn} = ${ $attributes->{'bpc-serial-number'} }[0];
|
|
$tmphash1{fid} = int(${ $attributes->{'frame-number'} }[0]);
|
|
$tmphash1{cid} = int(${ $attributes->{'cage-number'} }[0]);
|
|
$outhash{ $tmphash1{ip} } = \%tmphash1;
|
|
$$length = length($tmphash1{ip}) if (length($tmphash1{ip}) > $$length);
|
|
trace($request, "Discover another node $tmphash1{hostname}:type is $tmphash1{type}, mtm is $tmphash1{mtm}, \
|
|
sn is $tmphash1{serial}, side is $tmphash1{side},parent is $tmphash1{parent},ip is $tmphash1{ip}, \
|
|
cec id is $tmphash1{cid} , frame id is $tmphash1{fid},mac is $tmphash1{mac}, \
|
|
otherinterfaces is $tmphash1{otherinterfaces}");
|
|
}
|
|
}
|
|
|
|
# this part of code is used to avoid two messages sent from different ports of fsp give different info. Although this hasn't showed.
|
|
#else {
|
|
# ${$outhash{$tmphash1{ip}}{fid} = int(${$attributes->{'frame-number'}}[0]) if(int(${$attributes->{'frame-number'}}[0]) != 0);
|
|
# ${$outhash{$tmphash1{ip}}{cid} = int(${$attributes->{'cage-number'}}[0]) if(int(${$attributes->{'cage-number'}}[0]) != 0);
|
|
# trace( $request, "change frame id to ${$outhash{$tmphash1{ip}}{fid}, change cec id to ${$outhash{$tmphash1{ip}}{cid} \n");
|
|
#}
|
|
######################################################################
|
|
|
|
#begin to define frame and cec
|
|
$atthash{type} = $service_slp{$type};
|
|
$atthash{mtm} = ${ $attributes->{'machinetype-model'} }[0];
|
|
$atthash{serial} = ${ $attributes->{'serial-number'} }[0];
|
|
my $name = 'Server-' . $atthash{mtm} . '-SN' . $atthash{serial};
|
|
unless (exists $outhash{$name}) {
|
|
$atthash{slot} = '';
|
|
$atthash{ip} = '';
|
|
$atthash{hostname} = 'Server-' . $atthash{mtm} . '-SN' . $atthash{serial};
|
|
$atthash{mac} = "";
|
|
$atthash{bpcmtm} = ${ $attributes->{'bpc-machinetype-model'} }[0];
|
|
$atthash{bpcsn} = ${ $attributes->{'bpc-serial-number'} }[0];
|
|
$atthash{fid} = int(${ $attributes->{'frame-number'} }[0]);
|
|
$atthash{cid} = int(${ $attributes->{'cage-number'} }[0]);
|
|
$atthash{parent} = 'Server-' . $atthash{bpcmtm} . '-SN' . $atthash{bpcsn} if ($type eq SERVICE_FSP);
|
|
$atthash{children} = ${ $attributes->{'ip-address'} }[0] . "," . ${ $attributes->{'ip-address'} }[1];
|
|
$atthash{url} = ${ $searchmacs{$rsp} }{payload};
|
|
$outhash{ 'Server-' . $atthash{mtm} . '-SN' . $atthash{serial} } = \%atthash;
|
|
trace($request, "Discover node $atthash{hostname}: type is $atthash{type}, mtm is $atthash{mtm},\
|
|
sn is $atthash{serial}, mac is $atthash{mac}, children is $atthash{children}, frame id is $atthash{fid}, \
|
|
cec id is $atthash{cid}, otherinterfaces is $atthash{otherinterfaces}, parent is $atthash{parent}");
|
|
} else {
|
|
|
|
#update frameid and cageid to fix the firmware mistake
|
|
${ $outhash{$name} }{fid} = int(${ $attributes->{'frame-number'} }[0]) if (int(${ $attributes->{'frame-number'} }[0]) != 0);
|
|
${ $outhash{$name} }{cid} = int(${ $attributes->{'cage-number'} }[0]) if (int(${ $attributes->{'cage-number'} }[0]) != 0);
|
|
${ $outhash{$name} }{bpcmtm} = ${ $attributes->{'bpc-machinetype-model'} }[0] if (int(${ $attributes->{'bpc-machinetype-model'} }[0]) != 0);
|
|
${ $outhash{$name} }{bpcsn} = ${ $attributes->{'bpc-serial-number'} }[0] if (int(${ $attributes->{'bpc-serial-number'} }[0]) != 0);
|
|
$atthash{parent} = 'Server-' . ${ $outhash{$name} }{bpcmtm} . '-SN' . ${ $outhash{$name} }{bpcsn} if ($type eq SERVICE_FSP);
|
|
$outhash{$name}{children} .= "," . ${ $attributes->{'ip-address'} }[0] . "," . ${ $attributes->{'ip-address'} }[1]; # at most save 8 ips and have redendant
|
|
trace($request, "adjust frame id to ${$outhash{$name}}{fid}, cec id to ${$outhash{$name}}{cid}, children to $outhash{$name}{children},\
|
|
bpcmtm to ${$outhash{$name}}{bpcmtm}, bpcsn to ${$outhash{$name}}{bpcsn}");
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
###########################################################
|
|
# find frame's hostname first, then use find the cec's parent
|
|
# until then can begin with finding cec's hostname
|
|
# the order of finding PPC nodes' hostname can't be wrong
|
|
# and can't be done together
|
|
###########################################################
|
|
my $newhostname;
|
|
trace($request, "\n\n\nBegin to find find frame's hostname");
|
|
foreach my $h (keys %outhash) {
|
|
if (${ $outhash{$h} }{type} eq TYPE_FRAME) {
|
|
$newhostname = $::OLD_DATA_CACHE{ "frame*" . ${ $outhash{$h} }{mtm} . "*" . ${ $outhash{$h} }{serial} };
|
|
if ($newhostname) {
|
|
${ $outhash{$h} }{hostname} = $newhostname;
|
|
trace($request, "$h found hostname $newhostname");
|
|
push @matchnode, $h;
|
|
}
|
|
}
|
|
}
|
|
trace($request, "\n\n\nBegin to find cec's parent");
|
|
foreach my $h (keys %outhash) {
|
|
next unless (${ $outhash{$h} }{type} eq TYPE_CEC);
|
|
my $parent;
|
|
|
|
#find parent in the discovered nodes
|
|
foreach my $h1 (keys %outhash) {
|
|
if (${ $outhash{$h1} }{type} eq "frame" and ${ $outhash{$h} }{bpcmtm} eq ${ $outhash{$h1} }{mtm} and ${ $outhash{$h} }{bpcsn} eq ${ $outhash{$h1} }{serial}) {
|
|
$parent = ${ $outhash{$h1} }{hostname};
|
|
last;
|
|
}
|
|
}
|
|
|
|
#find parent in database
|
|
if (!defined($parent)) {
|
|
my $existing_node = $::OLD_DATA_CACHE{ "frame*" . ${ $outhash{$h} }{bpcmtm} . '*' . ${ $outhash{$h} }{bpcsn} };
|
|
$parent = $existing_node if ($existing_node);
|
|
}
|
|
${ $outhash{$h} }{parent} = $parent;
|
|
trace($request, "$h found parent $parent") if ($parent);
|
|
}
|
|
|
|
trace($request, "\n\n\nBegin to find cec hostname");
|
|
foreach my $h (keys %outhash) {
|
|
if (${ $outhash{$h} }{type} eq TYPE_CEC) {
|
|
my $newhostname1 = $::OLD_DATA_CACHE{ "cec*" . ${ $outhash{$h} }{mtm} . '*' . ${ $outhash{$h} }{serial} };
|
|
if ($newhostname1) {
|
|
trace($request, "$h found hostname $newhostname1 with mtms");
|
|
${ $outhash{$h} }{hostname} = $newhostname1;
|
|
push @matchnode, $h;
|
|
}
|
|
my $tp = 'Server-' . ${ $outhash{$h} }{bpcmtm} . '-SN' . ${ $outhash{$h} }{bpcsn};
|
|
trace($request, "$h begin to find hostname with parent $tp and id ${$outhash{$h}}{cid}");
|
|
my $newhostname2 = $::OLD_DATA_CACHE{ "cec*" . $tp . '*' . ${ $outhash{$h} }{cid} };
|
|
if ($newhostname2) {
|
|
${ $outhash{$h} }{hostname} = $newhostname2;
|
|
trace($request, "$h found hostname $newhostname2 with parent and id");
|
|
push @matchnode, $h;
|
|
}
|
|
}
|
|
}
|
|
|
|
trace($request, "\n\n\nBegin to find fsp/bpa's hostname and parent");
|
|
foreach my $h (keys %outhash) {
|
|
|
|
# Added a skip if processing Flex blades
|
|
if (${ $outhash{$h} }{type} eq TYPE_FSP or ${ $outhash{$h} }{type} eq TYPE_BPA) {
|
|
$newhostname = $::OLD_DATA_CACHE{ ${ $outhash{$h} }{type} . "*" . ${ $outhash{$h} }{mtm} . '*' . ${ $outhash{$h} }{serial} . '*' . ${ $outhash{$h} }{side} };
|
|
if ($newhostname) {
|
|
${ $outhash{$h} }{hostname} = $newhostname;
|
|
trace($request, "$h found hostname $newhostname");
|
|
push @matchnode, $h;
|
|
}
|
|
my $ptmp = ${ $outhash{$h} }{parent};
|
|
${ $outhash{$h} }{parent} = ${ $outhash{$ptmp} }{hostname} unless ((${ $outhash{$h} }{type} eq TYPE_FSP) && ${ $outhash{$h} }{mtm} =~ /^7895|1457|7954/);
|
|
trace($request, "$h found parent ${$outhash{$ptmp}}{hostname}");
|
|
|
|
#check if fsp/bpa's ip is valid
|
|
my $vip = check_ip(${ $outhash{$h} }{ip});
|
|
unless ($vip) { #which means the ip is a valid one
|
|
delete $outhash{$h};
|
|
}
|
|
}
|
|
}
|
|
trace($request, "\n\n\nBegin to adjust fsp/bpa's id");
|
|
foreach my $h (keys %outhash) {
|
|
if (${ $outhash{$h} }{type} eq TYPE_CEC or ${ $outhash{$h} }{type} eq TYPE_FRAME) {
|
|
my @children = split /,/, ${ $outhash{$h} }{children};
|
|
foreach my $child (@children) {
|
|
${ $outhash{$child} }{fid} = ${ $outhash{$h} }{fid};
|
|
${ $outhash{$child} }{cid} = ${ $outhash{$h} }{cid};
|
|
trace($request, "child is $child, fid is ${$outhash{$child}}{fid}, cid is ${$outhash{$child}}{cid}");
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
|
|
trace($request, "\n\n\nBegin to find cmm hostname in switch table");
|
|
$macmap = xCAT::MacMap->new();
|
|
$macmap->refresh_table();
|
|
foreach my $cmmnode (@cmmnodes) {
|
|
my $macvalue = ${ $outhash{$cmmnode} }{mac};
|
|
my $hostn = $macmap->find_mac($macvalue, 1);
|
|
if ($hostn) {
|
|
${ $outhash{$cmmnode} }{hostname} = $hostn;
|
|
trace($request, "cmmnode $cmmnode find hostname $hostn");
|
|
}
|
|
}
|
|
|
|
|
|
|
|
##########################################################
|
|
# If there is -n flag, skip the matched nodes
|
|
##########################################################
|
|
if (exists($globalopt{n})) {
|
|
trace($request, "\n\n\nThere is -n flag, skip these nodes:\n");
|
|
for my $matchednode (@matchnode) {
|
|
if ($outhash{$matchednode}) {
|
|
trace($request, "skip the node $matchednode\n");
|
|
delete $outhash{$matchednode};
|
|
}
|
|
}
|
|
}
|
|
if (exists($globalopt{I})) {
|
|
my %existsnodes;
|
|
my $nodelisttab = xCAT::Table->new('nodelist');
|
|
unless ($nodelisttab) {
|
|
return ("Error opening 'nodelisttable'");
|
|
}
|
|
my @nodes = $nodelisttab->getAllNodeAttribs([qw(node)]);
|
|
my $notdisnode;
|
|
for my $enode (@nodes) {
|
|
for my $mnode (@matchnode) {
|
|
if ($enode->{node} eq ${ $outhash{$mnode} }{hostname}) {
|
|
$existsnodes{ $enode->{node} } = 1;
|
|
last;
|
|
}
|
|
}
|
|
}
|
|
|
|
for my $enode (@nodes) {
|
|
unless ($existsnodes{ $enode->{node} }) {
|
|
$notdisnode .= $enode->{node} . ",";
|
|
}
|
|
}
|
|
send_msg($request, 0, "These nodes defined in database but can't be discovered: $notdisnode \n");
|
|
}
|
|
foreach my $no (keys %outhash) {
|
|
delete $outhash{$no} unless (${ $outhash{$no} }{hostname});
|
|
}
|
|
return \%outhash;
|
|
}
|
|
##########################################################################
|
|
# Write result to xCat database
|
|
##########################################################################
|
|
sub xCATdB {
|
|
my $outhash = shift;
|
|
|
|
########################################
|
|
# Begin to collect attributes for each node
|
|
########################################
|
|
my %nodelisthash;
|
|
my %ppchash;
|
|
my %vpdhash;
|
|
my %nodehmhash;
|
|
my %nodetypehash;
|
|
my %ppcdirecthash;
|
|
my %hostshash;
|
|
my %machash;
|
|
my %mphash;
|
|
my %ipmihash;
|
|
|
|
foreach my $nodeentry (keys %$outhash) {
|
|
my $type = ${ $outhash->{$nodeentry} }{type};
|
|
my $model = ${ $outhash->{$nodeentry} }{mtm};
|
|
my $serial = ${ $outhash->{$nodeentry} }{serial};
|
|
my $side = ${ $outhash->{$nodeentry} }{side};
|
|
my $ip = ${ $outhash->{$nodeentry} }{ip};
|
|
my $frameid = ${ $outhash->{$nodeentry} }{fid};
|
|
my $cageid = ${ $outhash->{$nodeentry} }{cid};
|
|
my $parent = ${ $outhash->{$nodeentry} }{parent};
|
|
my $mac = ${ $outhash->{$nodeentry} }{mac};
|
|
my $otherif = ${ $outhash->{$nodeentry} }{otherinterfaces};
|
|
my $hostname = ${ $outhash->{$nodeentry} }{hostname};
|
|
|
|
my $id = ($type =~ /bpa|frame/) ? $frameid : $cageid;
|
|
my $hidden = ($type =~ /bpa|fsp/) ? 1 : 0;
|
|
my $groups = lc($type) . ",all";
|
|
my $tmp_pre = xCAT::data::ibmhwtypes::parse_group($model);
|
|
if (defined($tmp_pre)) {
|
|
$groups .= ",$tmp_pre";
|
|
}
|
|
########################################
|
|
# Write result to every tables,
|
|
########################################
|
|
if ($type =~ /^bpa|fsp|cec|frame$/) {
|
|
|
|
#$nodelisthash{$hostname} = {groups=>"$type,all", hidden=>$hidden};
|
|
$nodelisthash{$hostname} = { groups => $groups, hidden => $hidden };
|
|
$ppchash{$hostname} = { id => $id, parent => $parent, hcp => $hostname, nodetype => $globalhwtype{$type} };
|
|
$vpdhash{$hostname} = { mtm => $model, serial => $serial, side => $side };
|
|
$nodehmhash{$hostname} = { mgt => $globalmgt{$type} };
|
|
$nodetypehash{$hostname} = { nodetype => $globalnodetype{$type} };
|
|
$hostshash{$hostname} = { otherinterfaces => $otherif } if ($type =~ /fsp|bpa/);
|
|
$machash{$hostname} = { mac => $mac } if ($type =~ /^fsp|bpa$/);
|
|
} elsif ($type =~ /^pbmc$/) {
|
|
$nodelisthash{$hostname} = { groups => $groups, hidden => $hidden };
|
|
$mphash{$hostname} = { nodetype => $globalhwtype{$type} };
|
|
$vpdhash{$hostname} = { mtm => $model, serial => $serial };
|
|
$nodehmhash{$hostname} = { mgt => $globalmgt{$type} };
|
|
$nodetypehash{$hostname} = { nodetype => $globalnodetype{$type} };
|
|
$ipmihash{$hostname} = { bmc => $ip };
|
|
} elsif ($type =~ /^(rsa|mm)$/) {
|
|
my @data = ($type, $model, $serial, $side, $ip, $frameid, $cageid, $parent, $mac);
|
|
xCAT::PPCdb::add_systemX($type, $hostname, \@data);
|
|
} elsif ($type =~ /^(hmc|ivm)$/) {
|
|
$nodelisthash{$hostname} = { groups => $groups, hidden => $hidden };
|
|
$ppchash{$hostname} = { nodetype => $globalhwtype{$type} };
|
|
$vpdhash{$hostname} = { mtm => $model, serial => $serial };
|
|
$nodetypehash{$hostname} = { nodetype => $globalnodetype{$type} };
|
|
$nodehmhash{$hostname} = { mgt => $globalmgt{$type} };
|
|
$hostshash{$hostname} = { ip => $ip };
|
|
$machash{$hostname} = { mac => $mac };
|
|
} elsif ($type =~ /^cmm$/) {
|
|
$nodelisthash{$hostname} = { groups => $groups, hidden => $hidden };
|
|
$vpdhash{$hostname} = { mtm => $model, serial => $serial, side => $side };
|
|
$nodetypehash{$hostname} = { nodetype => $globalnodetype{$type} };
|
|
$nodehmhash{$hostname} = { mgt => "blade" };
|
|
$mphash{$hostname} = { nodetype => $globalhwtype{$type}, mpa => $hostname };
|
|
$hostshash{$hostname} = { otherinterfaces => $otherif };
|
|
}
|
|
}
|
|
########################################
|
|
# Update database
|
|
########################################
|
|
my %dbhash;
|
|
$dbhash{nodelist} = \%nodelisthash, if (%nodelisthash);
|
|
$dbhash{ppc} = \%ppchash, if (%ppchash);
|
|
$dbhash{vpd} = \%vpdhash, if (%vpdhash);
|
|
$dbhash{nodehm} = \%nodehmhash, if (%nodehmhash);
|
|
$dbhash{nodetype} = \%nodetypehash, if (%nodetypehash);
|
|
$dbhash{ppcdirect} = \%ppcdirecthash, if (%ppcdirecthash);
|
|
$dbhash{hosts} = \%hostshash, if (%hostshash);
|
|
$dbhash{mac} = \%machash, if (%machash);
|
|
$dbhash{mp} = \%mphash, if (%mphash);
|
|
$dbhash{ipmi} = \%ipmihash, if (%ipmihash);
|
|
|
|
for my $tab (keys %dbhash) {
|
|
my $db = xCAT::Table->new($tab);
|
|
if (!$db) {
|
|
return ("Error opening $db");
|
|
}
|
|
$db->setNodesAttribs($dbhash{$tab});
|
|
$db->close();
|
|
}
|
|
}
|
|
##########################################################################
|
|
# Stanza formatting
|
|
##########################################################################
|
|
sub format_stanza {
|
|
|
|
my $outhash = shift;
|
|
my $result;
|
|
#####################################
|
|
# Write attributes
|
|
#####################################
|
|
foreach my $name (keys %$outhash) {
|
|
my $hostname = ${ $outhash->{$name} }{hostname};
|
|
my $ip = ${ $outhash->{$name} }{ip};
|
|
if ($hostname =~ /^([^\(]+)\(([^\)]+)\)$/) {
|
|
$hostname = $1;
|
|
$ip = $2;
|
|
}
|
|
my $type = ${ $outhash->{$name} }{type};
|
|
my $groups = "$type,all";
|
|
my $tmp_pre = xCAT::data::ibmhwtypes::parse_group(${ $outhash->{$name} }{mtm});
|
|
if (defined($tmp_pre)) {
|
|
$groups .= ",$tmp_pre";
|
|
}
|
|
|
|
#################################
|
|
# Node attributes
|
|
#################################
|
|
$result .= "$hostname:\n\tobjtype=node\n";
|
|
if ($type =~ /^cmm$/) {
|
|
$result .= "\tmpa=${$outhash->{$name}}{hostname}\n";
|
|
} elsif ($type =~ /^pbmc$/) {
|
|
$result .= "\tbmc=${$outhash->{$name}}{ip}\n";
|
|
} else {
|
|
$result .= "\thcp=${$outhash->{$name}}{hostname}\n";
|
|
}
|
|
$result .= "\tnodetype=$globalnodetype{$type}\n";
|
|
$result .= "\tmtm=${$outhash->{$name}}{mtm}\n";
|
|
$result .= "\tserial=${$outhash->{$name}}{serial}\n";
|
|
if ($type =~ /^fsp|bpa|cmm$/) {
|
|
$result .= "\tside=${$outhash->{$name}}{side}\n";
|
|
}
|
|
|
|
#$result .= "\tgroups=$type,all\n";
|
|
$result .= "\tgroups=$groups\n";
|
|
$result .= "\tmgt=$globalmgt{$type}\n";
|
|
if ($type =~ /^fsp|bpa|frame|cec$/) {
|
|
$result .= "\tid=${$outhash->{$name}}{$globalid{$type}}\n";
|
|
}
|
|
if ($type =~ /^fsp|bpa|cec$/ and exists(${ $outhash->{$name} }{parent})) {
|
|
$result .= "\tparent=${$outhash->{$name}}{parent}\n";
|
|
}
|
|
unless ($type =~ /^frame|cec$/ or !exists(${ $outhash->{$name} }{mac})) {
|
|
$result .= "\tmac=${$outhash->{$name}}{mac}\n";
|
|
}
|
|
if ($type =~ /^fsp|bpa$/) {
|
|
$result .= "\thidden=1\n";
|
|
} else {
|
|
$result .= "\thidden=0\n";
|
|
}
|
|
|
|
#unless ($type =~ /^cmm$/) {
|
|
# $result .= "\tip=$ip\n";
|
|
#}
|
|
if ($type =~ /^fsp|bpa|cmm$/) {
|
|
$result .= "\totherinterfaces=${$outhash->{$name}}{otherinterfaces}\n";
|
|
}
|
|
if ($type eq "ivm") {
|
|
$result .= "\tip=${$outhash->{$name}}{ip}\n";
|
|
}
|
|
$result .= "\thwtype=$globalhwtype{$type}\n";
|
|
}
|
|
return ($result);
|
|
}
|
|
|
|
|
|
|
|
##########################################################################
|
|
# XML formatting
|
|
##########################################################################
|
|
sub format_xml {
|
|
|
|
my $outhash = shift;
|
|
my $xml;
|
|
|
|
my $result = format_stanza($outhash);
|
|
my @nodeentry = split 'objtype=', $result;
|
|
foreach my $entry (@nodeentry) {
|
|
my $href = {
|
|
Node => {}
|
|
};
|
|
my @attr = split '\\n\\t', $entry;
|
|
$href->{Node}->{node} = $attr[0];
|
|
for (my $i = 1 ; $i < scalar(@attr) ; $i++) {
|
|
if ($attr[$i] =~ /(\w+)\=(.*)/) {
|
|
$href->{Node}->{$1} = $2;
|
|
}
|
|
}
|
|
$xml .= XMLout($href,
|
|
NoAttr => 1,
|
|
KeyAttr => [],
|
|
RootName => undef);
|
|
}
|
|
return ($xml);
|
|
}
|
|
|
|
##########################################################################
|
|
# VPD table formatting
|
|
##########################################################################
|
|
sub format_table {
|
|
|
|
my $outhash = shift;
|
|
my $result;
|
|
|
|
#####################################
|
|
# Create XML formatted attributes
|
|
#####################################
|
|
foreach my $name (keys %$outhash) {
|
|
my $type = ${ $outhash->{$name} }{type};
|
|
next if ($type =~ /^(fsp|bpa)$/);
|
|
$result .= "${$outhash->{$name}}{hostname}:\n";
|
|
$result .= "\tobjtype=node\n";
|
|
$result .= "\tmtm=${$outhash->{$name}}{mtm}\n";
|
|
$result .= "\tserial=${$outhash->{$name}}{serial}\n";
|
|
}
|
|
return ($result);
|
|
}
|
|
|
|
##########################################################################
|
|
# Collect output from the child processes
|
|
##########################################################################
|
|
sub child_response {
|
|
|
|
my $callback = shift;
|
|
my $fds = shift;
|
|
my @ready_fds = $fds->can_read(1);
|
|
|
|
foreach my $rfh (@ready_fds) {
|
|
my $data = <$rfh>;
|
|
|
|
#################################
|
|
# Read from child process
|
|
#################################
|
|
if (defined($data)) {
|
|
while ($data !~ /ENDOFFREEZE6sK4ci/) {
|
|
$data .= <$rfh>;
|
|
}
|
|
my $responses = thaw($data);
|
|
|
|
#############################
|
|
# Formatted SLP results
|
|
#############################
|
|
if (@$responses[0] =~ /^FORMATDATA6sK4ci$/) {
|
|
my $result = @$responses[1];
|
|
foreach (keys %$result) {
|
|
|
|
#$slp_result{$_} = 1;
|
|
}
|
|
next;
|
|
}
|
|
|
|
#############################
|
|
# Message or verbose trace
|
|
#############################
|
|
foreach (@$responses) {
|
|
$callback->($_);
|
|
}
|
|
next;
|
|
}
|
|
#################################
|
|
# Done - close handle
|
|
#################################
|
|
$fds->remove($rfh);
|
|
close($rfh);
|
|
}
|
|
}
|
|
|
|
#############################################################################
|
|
# Preprocess request from xCAT daemon and send request to service nodes
|
|
#############################################################################
|
|
sub preprocess_request {
|
|
|
|
my $req = shift;
|
|
if ($req->{_xcatpreprocessed}->[0] == 1) { return [$req]; }
|
|
my $callback = shift;
|
|
my @requests;
|
|
|
|
my $command = $req->{command}->[0];
|
|
my $extrargs = $req->{arg};
|
|
my @exargs = ($req->{arg});
|
|
if (ref($extrargs)) {
|
|
@exargs = @$extrargs;
|
|
}
|
|
my $usage_string = xCAT::Usage->parseCommand($command, @exargs);
|
|
if ($usage_string) {
|
|
$callback->({ data => [$usage_string] });
|
|
$req = {};
|
|
return;
|
|
}
|
|
###########################################
|
|
# find all the service nodes for xCAT cluster
|
|
# build an individual request for each service node
|
|
###########################################
|
|
my %sv_hash = ();
|
|
|
|
#my @all = xCAT::Utils::getAllSN();
|
|
#foreach (@all) {
|
|
# $sv_hash{$_}=1;
|
|
#}
|
|
###########################################
|
|
# build each request for each service node
|
|
###########################################
|
|
my @result = ();
|
|
my $mncopy = {%$req};
|
|
push @result, $mncopy;
|
|
|
|
#foreach my $sn (keys (%sv_hash)) {
|
|
# my $reqcopy = {%$req};
|
|
# $reqcopy->{_xcatdest} = $sn;
|
|
# $reqcopy->{_xcatpreprocessed}->[0] = 1;
|
|
# push @result, $reqcopy;
|
|
#}
|
|
return \@result;
|
|
}
|
|
|
|
##########################################################################
|
|
# Process request from xCat daemon
|
|
##########################################################################
|
|
sub process_request {
|
|
|
|
my $req = shift;
|
|
my $callback = shift;
|
|
|
|
#unless ($macmap) { $macmap = xCAT::MacMap->new(); }
|
|
|
|
###########################################
|
|
# Build hash to pass around
|
|
###########################################
|
|
my %request;
|
|
$request{arg} = $req->{arg};
|
|
$request{callback} = $callback;
|
|
$request{command} = $req->{command}->[0];
|
|
|
|
####################################
|
|
# Process command-specific options
|
|
####################################
|
|
my $result = parse_args(\%request);
|
|
|
|
####################################
|
|
# Return error
|
|
####################################
|
|
if (ref($result) eq 'ARRAY') {
|
|
send_msg(\%request, 1, @$result);
|
|
return (1);
|
|
}
|
|
|
|
#######################################
|
|
# Write header for trace
|
|
#######################################
|
|
my $tm = localtime(time);
|
|
my $msg = "\n-------- $tm\nTime PID";
|
|
trace(\%request, $msg);
|
|
|
|
|
|
###########################################
|
|
# Record begin time
|
|
###########################################
|
|
my $start = Time::HiRes::gettimeofday();
|
|
############################################
|
|
## Fork one process per adapter
|
|
############################################
|
|
#my $children = 0;
|
|
#$SIG{CHLD} = sub {
|
|
# my $rc_bak = $?;
|
|
# while (waitpid(-1, WNOHANG) > 0) { $children--; }
|
|
# $? = $rc_bak;
|
|
#};
|
|
#my $fds = new IO::Select;
|
|
#
|
|
#foreach ( keys %ip_addr ) {
|
|
# my $pipe = fork_cmd( $req, $_);
|
|
# if ( $pipe ) {
|
|
# $fds->add( $pipe );
|
|
# $children++;
|
|
# }
|
|
#}
|
|
############################################
|
|
## Process slp responses from children
|
|
############################################
|
|
#while ( $children > 0 ) {
|
|
# child_response( $callback, $fds );
|
|
#}
|
|
#while (child_response($callback,$fds)) {}
|
|
|
|
my ($searchmacsref, $sendcount, $rspc) = invoke_dodiscover(\%request);
|
|
|
|
if ($globalopt{flexdiscover}) {
|
|
bt_process($req, $callback, $searchmacsref);
|
|
return (SUCCESS);
|
|
}
|
|
###########################################
|
|
# Record ending time
|
|
###########################################
|
|
|
|
my $elapsed = Time::HiRes::gettimeofday() - $start;
|
|
my $msg2 = sprintf("Total SLP Time: %.3f sec\n", $elapsed);
|
|
trace(\%request, $msg2);
|
|
###########################################
|
|
# Combined responses from all children
|
|
###########################################
|
|
my $num = keys %$searchmacsref;
|
|
my $min;
|
|
if ($num < 500) {
|
|
$min = "0-1";
|
|
} elsif (500 < $num and $num < 1000) {
|
|
$min = "1-2";
|
|
} else {
|
|
$min = "more than 2";
|
|
}
|
|
|
|
#my $start1 = Time::HiRes::gettimeofday();
|
|
send_msg(\%request, 0, "$sendcount requests with $rspc responses. Now processing responses. This will take $min minutes...") unless ($globalopt{x} or $globalopt{z});
|
|
format_output(\%request, $searchmacsref);
|
|
|
|
#my $elapsed1 = Time::HiRes::gettimeofday() - $start1;
|
|
#send_msg( \%request, 0, "$num nodes takes $elapsed1");
|
|
return (SUCCESS);
|
|
}
|
|
|
|
|
|
|
|
##########################################################################
|
|
# Filter nodes the user specified
|
|
##########################################################################
|
|
sub filter {
|
|
my $oldhash = shift;
|
|
my $newhash;
|
|
|
|
# find HMC/CEC/Frame that the user want to find
|
|
foreach my $n (@filternodes) {
|
|
for my $foundnode (keys %$oldhash) {
|
|
if (${ $oldhash->{$foundnode} }{hostname} =~ /^(\w+)\(.*\)/) {
|
|
if ($1 eq $n) {
|
|
$newhash->{$foundnode} = $oldhash->{$foundnode};
|
|
if (${ $oldhash->{$foundnode} }{type} eq TYPE_CEC or ${ $oldhash->{$foundnode} }{type} eq TYPE_FRAME) {
|
|
my @ips = split /,/, ${ $oldhash->{$foundnode} }{children};
|
|
for (my $i = 0 ; $i < scalar(@ips) ; $i++) {
|
|
$newhash->{ $ips[$i] } = $oldhash->{ $ips[$i] };
|
|
}
|
|
}
|
|
}
|
|
} elsif (${ $oldhash->{$foundnode} }{hostname} eq $n) {
|
|
$newhash->{$foundnode} = $oldhash->{$foundnode};
|
|
if (${ $oldhash->{$foundnode} }{type} eq TYPE_CEC or ${ $oldhash->{$foundnode} }{type} eq TYPE_FRAME) {
|
|
my @ips = split /,/, ${ $oldhash->{$foundnode} }{children};
|
|
for (my $i = 0 ; $i < scalar(@ips) ; $i++) {
|
|
$newhash->{ $ips[$i] } = $oldhash->{ $ips[$i] };
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return $newhash;
|
|
}
|
|
##########################################################################
|
|
# Filter nodes not in the user specified vlan
|
|
##########################################################################
|
|
sub filtersamevlan {
|
|
my $oldhash = shift;
|
|
my $newhash;
|
|
my $nets = xCAT::NetworkUtils::my_nets();
|
|
my $validnets;
|
|
for my $net (keys %$nets) {
|
|
for my $nic (split /,/, $globalopt{i}) {
|
|
if ($nets->{$net} eq $nic) {
|
|
$validnets->{$net} = $nic;
|
|
}
|
|
}
|
|
}
|
|
foreach my $name (keys %$oldhash) {
|
|
if (${ $oldhash->{$name} }{type} =~ /^(fsp|bpa)$/) {
|
|
my $ip = ${ $oldhash->{$name} }{ip};
|
|
for my $net (keys %$validnets) {
|
|
my ($n, $m) = split /\//, $net;
|
|
if (xCAT::NetworkUtils::isInSameSubnet($n, $ip, $m, 1)) { #and xCAT::NetworkUtils::isPingable( $ip)) {
|
|
$newhash->{$name} = $oldhash->{$name};
|
|
}
|
|
}
|
|
} else {
|
|
$newhash->{$name} = $oldhash->{$name};
|
|
}
|
|
}
|
|
return $newhash;
|
|
}
|
|
##########################################################################
|
|
# This is the function that merged in from slpdiscover
|
|
##########################################################################
|
|
sub bt_process {
|
|
my $request = shift;
|
|
my $callback = shift;
|
|
my $searef = shift;
|
|
|
|
|
|
|
|
my $mpatab = xCAT::Table->new("mpa", -create => 0);
|
|
my @mpaentries;
|
|
$mpahash = {};
|
|
if (ref $request->{environment} and ref $request->{environment}->[0]->{XCAT_CURRENTPASS}) {
|
|
$currentbladepass = $request->{environment}->[0]->{XCAT_CURRENTPASS}->[0];
|
|
} else {
|
|
$currentbladepass = "PASSW0RD";
|
|
}
|
|
if (ref $request->{environment} and ref $request->{environment}->[0]->{XCAT_CURRENTUSER}) {
|
|
$currentbladeuser = $request->{environment}->[0]->{XCAT_CURRENTUSER}->[0];
|
|
} else {
|
|
$currentbladeuser = "USERID";
|
|
}
|
|
if ($mpatab) {
|
|
@mpaentries = $mpatab->getAllNodeAttribs([qw/mpa username password/]);
|
|
foreach (@mpaentries) {
|
|
$mpahash->{ $_->{mpa} } = $_;
|
|
}
|
|
}
|
|
my $passwdtab = xCAT::Table->new("passwd", -create => 0);
|
|
$defaultbladeuser = "USERID";
|
|
$defaultbladepass = "";
|
|
if ($passwdtab) {
|
|
my @ents = $passwdtab->getAttribs({ key => 'blade' }, 'username', 'password');
|
|
foreach (@ents) {
|
|
if ($_->{username} eq "HMC") { next; }
|
|
if ($_->{username}) { $defaultbladeuser = $_->{username}; }
|
|
if ($_->{password}) { $defaultbladepass = $_->{password}; }
|
|
}
|
|
}
|
|
my $mactab = xCAT::Table->new("mac");
|
|
my %machash;
|
|
my %node2machash;
|
|
my %macuphash;
|
|
my @maclist = $mactab->getAllNodeAttribs([qw/node mac/]);
|
|
foreach (@maclist) {
|
|
$machash{ $_->{node} } = $_->{mac};
|
|
$node2machash{ $_->{mac} } = $_->{node};
|
|
}
|
|
|
|
|
|
|
|
my $mptab = xCAT::Table->new('mp');
|
|
my $nodecandidates;
|
|
if ($mptab) {
|
|
my @mpents = $mptab->getAllNodeAttribs([ 'node', 'mpa', 'id' ]);
|
|
foreach (@mpents) {
|
|
$nodebymp{ $_->{mpa} }->{ $_->{id} } = $_->{node};
|
|
}
|
|
}
|
|
|
|
$macmap = xCAT::MacMap->new();
|
|
$macmap->refresh_table();
|
|
my @toconfig;
|
|
foreach my $mac (keys(%btresult)) {
|
|
my $node = $macmap->find_mac($mac, 1);
|
|
unless ($node) {
|
|
if (defined $node2machash{$mac}) {
|
|
$node = $node2machash{$mac};
|
|
} else {
|
|
next;
|
|
}
|
|
}
|
|
my $data = $btresult{$mac};
|
|
$data->{nodename} = $node;
|
|
$data->{macaddress} = $mac;
|
|
$chassisbyuuid{ $data->{attributes}->{"enclosure-uuid"}->[0] } = $node;
|
|
push @toconfig, $data;
|
|
}
|
|
|
|
foreach my $data (@toconfig) {
|
|
my $mac = $data->{macaddress};
|
|
my $nodename = $data->{nodename};
|
|
my $addr = $data->{peername}; #todo, use sockaddr and remove the 427 port from it instead?
|
|
if ($addr =~ /^fe80/) { #Link local address requires scope index
|
|
$addr .= "%" . $data->{scopeid};
|
|
}
|
|
$flexchassisuuid{$nodename} = $data->{attributes}->{"enclosure-uuid"}->[0];
|
|
|
|
if ($data->{SrvType} eq "service:management-hardware.IBM:chassis-management-module") {
|
|
sendmsg(":Found " . $data->{SrvType} . " at address $addr", $callback, $nodename);
|
|
|
|
setup_cmm_pass($nodename);
|
|
if ($machash{$nodename} =~ /$mac/i) { #ignore prospects already known to mac table
|
|
configure_hosted_elements($nodename, $callback);
|
|
next;
|
|
}
|
|
|
|
unless (do_blade_setup($data, $callback, curraddr => $addr)) {
|
|
next;
|
|
}
|
|
configure_hosted_elements($nodename, $callback);
|
|
unless (do_blade_setup($data, $callback, curraddr => $addr, pass2 => 1)) {
|
|
next;
|
|
}
|
|
sendmsg(":Configuration complete, configuration may take a few minutes to take effect", $callback, $nodename);
|
|
$macuphash{$nodename} = { mac => $mac };
|
|
}
|
|
}
|
|
$mactab->setNodesAttribs(\%macuphash);
|
|
}
|
|
|
|
|
|
sub configure_hosted_elements {
|
|
my $cmm = shift;
|
|
my $callback = shift;
|
|
my $uuid = $flexchassisuuid{$cmm};
|
|
my $node;
|
|
my $immdata;
|
|
my $slot;
|
|
my $user = $passwordmap{$cmm}->{username};
|
|
my $pass = $passwordmap{$cmm}->{password};
|
|
foreach $immdata (values %{ $flexchassismap{$uuid} }) {
|
|
$slot = $immdata->{attributes}->{slot}->[0];
|
|
if (defined $immdata->{attributes}->{'chassis-sub-slot'}) {
|
|
$slot .= ":" . $immdata->{attributes}->{'chassis-sub-slot'}->[0];
|
|
}
|
|
if ($node = $nodebymp{$cmm}->{$slot}) {
|
|
my $addr = $immdata->{peername}; #todo, use sockaddr and remove the 427 port from it instead?
|
|
if ($addr =~ /^fe80/) { #Link local address requires scope index
|
|
$addr .= "%" . $immdata->{scopeid};
|
|
}
|
|
if ($doneaddrs{$node}) { next; }
|
|
$doneaddrs{$node} = 1;
|
|
xCAT::IMMUtils::setupIMM($node, nodedata => $immdata, curraddr => $addr, cliusername => $user, clipassword => $pass, callback => $callback);
|
|
} else {
|
|
sendmsg(": Ignoring target in bay $slot, no node found with mp.mpa/mp.id matching", $callback, $cmm);
|
|
}
|
|
|
|
}
|
|
while (wait() > 0) { }
|
|
}
|
|
|
|
sub setup_cmm_pass {
|
|
my $nodename = shift;
|
|
my $localuser = $defaultbladeuser;
|
|
my $localpass = $defaultbladepass;
|
|
if ($mpahash->{$nodename}) {
|
|
if ($mpahash->{$nodename}->{username}) {
|
|
$localuser = $mpahash->{$nodename}->{username};
|
|
}
|
|
if ($mpahash->{$nodename}->{password}) {
|
|
$localpass = $mpahash->{$nodename}->{password};
|
|
}
|
|
}
|
|
$passwordmap{$nodename}->{username} = $localuser;
|
|
$passwordmap{$nodename}->{password} = $localpass;
|
|
}
|
|
|
|
sub do_blade_setup {
|
|
my $data = shift;
|
|
my $callback = shift;
|
|
my %args = @_;
|
|
my $addr = $args{curraddr};
|
|
my $nodename = $data->{nodename};
|
|
my $localuser = $passwordmap{$nodename}->{username};
|
|
my $localpass = $passwordmap{$nodename}->{password};
|
|
if (not $localpass or $localpass eq "PASSW0RD") {
|
|
sendmsg([ 1, ":Password for blade must be specified in either mpa or passwd tables, and it must not be PASSW0RD" ], $callback, $nodename);
|
|
return 0;
|
|
}
|
|
require xCAT_plugin::blade;
|
|
my @cmds;
|
|
my %exargs;
|
|
if ($args{pass2}) {
|
|
@cmds = qw/initnetwork=*/;
|
|
%exargs = (nokeycheck => 1); #still not at the 'right' ip, so the known hosts shouldn't be bothered
|
|
} else {
|
|
@cmds = qw/snmpcfg=enable sshcfg=enable textid=*/; # initnetwork=*/; defer initnetwork until after chassis members have been configured
|
|
%exargs = (curruser => $currentbladeuser, currpass => $currentbladepass);
|
|
}
|
|
my $result;
|
|
$@ = "";
|
|
my $rc = eval { $result = xCAT_plugin::blade::clicmds(
|
|
$nodename,
|
|
$localuser,
|
|
$localpass,
|
|
$nodename,
|
|
0,
|
|
curraddr => $addr,
|
|
%exargs,
|
|
cmds => \@cmds);
|
|
1;
|
|
};
|
|
my $errmsg = $@;
|
|
if ($errmsg) {
|
|
if ($errmsg =~ /Incorrect Password/) {
|
|
sendmsg([ 1, "Failed to set up Management module due to Incorrect Password (You may try the environment variables XCAT_CURRENTUSER and/or XCAT_CURRENTPASS to try a different value)" ], $callback, $nodename);
|
|
} else {
|
|
sendmsg([ 1, "Failed to set up Management module due to $errmsg" ], $callback, $nodename);
|
|
}
|
|
return 0;
|
|
}
|
|
if ($result) {
|
|
if ($result->[0]) {
|
|
if ($result->[2] =~ /Incorrect Password/) {
|
|
sendmsg([ 1, "Failed to set up Management module due to Incorrect Password (You may try the environment variables XCAT_CURRENTUSER and/or XCAT_CURRENTPASS to try a different value)" ], $callback, $nodename);
|
|
return 0;
|
|
}
|
|
my $errors = $result->[2];
|
|
if (ref $errors) {
|
|
foreach my $error (@$errors) {
|
|
sendmsg([ $result->[0], $error ], $callback, $nodename);
|
|
}
|
|
} else {
|
|
sendmsg([ $result->[0], $result->[2] ], $callback, $nodename);
|
|
}
|
|
return 0;
|
|
}
|
|
}
|
|
return $rc;
|
|
}
|
|
|
|
sub bt_handle_new_slp_entity {
|
|
my $data = shift;
|
|
delete $data->{sockaddr}; #won't need it
|
|
my $mac = xCAT::SLP::get_mac_for_addr($data->{peername});
|
|
if ($data->{SrvType} eq "service:management-hardware.IBM:integrated-management-module2" and $data->{attributes}->{"enclosure-form-factor"}->[0] eq "BC2") {
|
|
$data->{macaddress} = $mac;
|
|
|
|
#this is a Flex ITE, don't go mac searching for it, but remember the chassis UUID for later
|
|
if ($flexchassismap{ $data->{attributes}->{"chassis-uuid"}->[0] }->{$mac} and $data->{peername} !~ /fe80/) {
|
|
return;
|
|
}
|
|
$flexchassismap{ $data->{attributes}->{"chassis-uuid"}->[0] }->{$mac} = $data;
|
|
return;
|
|
}
|
|
unless ($mac) { return; }
|
|
$btresult{$mac} = $data;
|
|
}
|
|
1;
|
|
|
|
|