2008-06-03 19:09:21 +00:00
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
2009-10-20 13:37:44 +00:00
package xCAT_plugin::lsslp ;
2011-05-23 09:47:25 +00:00
use lib "/opt/xcat/lib/perl" ;
2008-06-03 19:09:21 +00:00
use strict ;
use Getopt::Long ;
use Socket ;
2012-02-19 16:09:21 +00:00
use xCAT::Usage ;
2009-10-20 13:37:44 +00:00
use POSIX "WNOHANG" ;
use Storable qw( freeze thaw ) ;
use Time::HiRes qw( gettimeofday ) ;
2012-12-21 09:15:24 +00:00
use xCAT::SvrUtils qw/sendmsg/ ;
2009-10-20 13:37:44 +00:00
use IO::Select ;
use XML::Simple ;
$ XML:: Simple:: PREFERRED_PARSER = 'XML::Parser' ;
use xCAT::PPCdb ;
2011-03-21 09:25:16 +00:00
use xCAT::NodeRange ;
2011-09-18 14:38:15 +00:00
use xCAT::Utils ;
2012-12-21 09:15:24 +00:00
use xCAT::MacMap ;
use xCAT::IMMUtils ;
use xCAT_plugin::blade ;
use xCAT::SLP ;
2013-08-16 03:10:50 +00:00
require xCAT::data::ibmhwtypes ;
2012-12-21 09:15:24 +00:00
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 ;
2013-03-13 19:21:41 +00:00
my $ option_s ;
2009-10-20 13:37:44 +00:00
#######################################
# 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" ,
2011-04-18 02:11:32 +00:00
SERVICE_CEC = > "cec-service-processor" ,
SERVICE_FRAME = > "bulk-power-controller" ,
2009-10-20 13:37:44 +00:00
SERVICE_HMC = > "hardware-management-console" ,
SERVICE_IVM = > "integrated-virtualization-manager" ,
SERVICE_MM = > "management-module" ,
2011-12-21 02:25:14 +00:00
SERVICE_CMM = > "chassis-management-module" ,
2013-03-01 22:01:04 +00:00
SERVICE_IMM2 = > "integrated-management-module2" ,
2009-10-20 13:37:44 +00:00
SERVICE_RSA = > "remote-supervisor-adapter" ,
SERVICE_RSA2 = > "remote-supervisor-adapter-2" ,
2012-07-12 17:58:10 +00:00
#SLP_CONF => "/usr/local/etc/slp.conf",
#SLPTOOL => "/usr/local/bin/slptool",
2012-04-26 10:22:30 +00:00
TYPE_MM = > "mm" ,
TYPE_CMM = > "cmm" ,
2013-03-01 22:01:04 +00:00
TYPE_IMM2 = > "imm2" ,
2012-04-26 10:22:30 +00:00
TYPE_RSA = > "rsa" ,
TYPE_BPA = > "bpa" ,
TYPE_HMC = > "hmc" ,
TYPE_IVM = > "ivm" ,
TYPE_FSP = > "fsp" ,
TYPE_CEC = > "cec" ,
TYPE_FRAME = > "frame" ,
2009-12-28 08:10:42 +00:00
IP_ADDRESSES = > 4 ,
2009-10-20 13:37:44 +00:00
TEXT = > 0 ,
FORMAT = > 1 ,
SUCCESS = > 0 ,
2012-04-26 10:22:30 +00:00
RC_ERROR = > 1 ,
2009-10-20 13:37:44 +00:00
} ;
#######################################
# Globals
#######################################
my % service_slp = (
2010-12-07 05:47:07 +00:00
@ { [ SERVICE_FSP ] } = > TYPE_FSP ,
@ { [ SERVICE_BPA ] } = > TYPE_BPA ,
@ { [ SERVICE_CEC ] } = > TYPE_CEC ,
2010-12-29 10:32:22 +00:00
@ { [ SERVICE_FRAME ] } = > TYPE_FRAME ,
2010-12-07 05:47:07 +00:00
@ { [ SERVICE_HMC ] } = > TYPE_HMC ,
@ { [ SERVICE_IVM ] } = > TYPE_IVM ,
@ { [ SERVICE_MM ] } = > TYPE_MM ,
2011-12-21 02:25:14 +00:00
@ { [ SERVICE_CMM ] } = > TYPE_CMM ,
2013-03-01 22:01:04 +00:00
@ { [ SERVICE_IMM2 ] } = > TYPE_IMM2 ,
2010-12-07 05:47:07 +00:00
@ { [ SERVICE_RSA ] } = > TYPE_RSA ,
@ { [ SERVICE_RSA2 ] } = > TYPE_RSA
2009-10-20 13:37:44 +00:00
) ;
#######################################
# SLP display header
#######################################
my @ header = (
[ "device" , "%-8s" ] ,
[ "type-model" , "%-12s" ] ,
[ "serial-number" , "%-15s" ] ,
2009-12-28 08:10:42 +00:00
[ "side" , "%-6s" ] ,
2009-10-20 13:37:44 +00:00
[ "ip-addresses" , "placeholder" ] ,
[ "hostname" , "%s" ]
) ;
2012-04-26 10:22:30 +00:00
my % headertoattr = (
"device" = > "type" ,
"type-model" = > "mtm" ,
"serial-number" = > "serial" ,
"side" = > "side" ,
"ip-addresses" = > "ip" ,
"hostname" = > "hostname" ,
) ;
2009-10-20 13:37:44 +00:00
2011-01-24 16:11:56 +00:00
#######################################
# 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" ,
2011-02-22 07:22:35 +00:00
"169.254." ,
2011-01-24 16:11:56 +00:00
"127.0.0.0" ,
"127" ,
0 ,
) ;
2009-10-20 13:37:44 +00:00
#######################################
# Power methods
#######################################
2012-04-26 10:22:30 +00:00
2012-05-03 06:36:27 +00:00
my % globalopt ;
2012-04-26 10:22:30 +00:00
#these globals are only used in mn
2009-10-20 13:37:44 +00:00
my % ip_addr = ( ) ;
2012-04-26 10:22:30 +00:00
#my $macmap;
2011-03-04 01:54:43 +00:00
my @ filternodes ;
2011-05-24 09:27:41 +00:00
my $ TRACE = 0 ;
2011-09-14 13:57:31 +00:00
my $ DEBUG_MATCH = 0 ;
2012-04-26 10:22:30 +00:00
my % globalhwtype = (
2011-07-15 09:10:54 +00:00
fsp = > $ ::NODETYPE_FSP ,
bpa = > $ ::NODETYPE_BPA ,
lpar = > $ ::NODETYPE_LPAR ,
hmc = > $ ::NODETYPE_HMC ,
ivm = > $ ::NODETYPE_IVM ,
frame = > $ ::NODETYPE_FRAME ,
cec = > $ ::NODETYPE_CEC ,
2011-12-21 02:25:14 +00:00
cmm = > $ ::NODETYPE_CMM ,
2013-03-01 22:01:04 +00:00
imm2 = > $ ::NODETYPE_IMM2 ,
2011-07-15 09:10:54 +00:00
) ;
2011-07-15 09:23:56 +00:00
my % globalnodetype = (
2011-12-21 02:25:14 +00:00
fsp = > $ ::NODETYPE_PPC ,
bpa = > $ ::NODETYPE_PPC ,
cec = > $ ::NODETYPE_PPC ,
frame = > $ ::NODETYPE_PPC ,
hmc = > $ ::NODETYPE_PPC ,
ivm = > $ ::NODETYPE_PPC ,
2011-12-28 10:00:27 +00:00
cmm = > $ ::NODETYPE_MP ,
2012-04-26 10:22:30 +00:00
lpar = > "$::NODETYPE_PPC,$::NODETYPE_OSI" ,
) ;
my % globalmgt = (
fsp = > "fsp" ,
bpa = > "bpa" ,
cec = > "fsp" ,
frame = > "bpa" ,
mm = > "blade" ,
ivm = > "ivm" ,
rsa = > "blade" ,
cmm = > "blade" ,
2013-03-01 22:01:04 +00:00
imm2 = > "blade" ,
2012-04-26 10:22:30 +00:00
hmc = > "hmc" ,
) ;
my % globalid = (
fsp = > "cid" ,
cec = > "cid" ,
bpa = > "fid" ,
frame = > "fid"
2011-07-15 09:23:56 +00:00
) ;
2009-10-20 13:37:44 +00:00
##########################################################################
# Command handler method from tables
##########################################################################
sub handled_commands {
return ( { lsslp = > "lsslp" } ) ;
2008-06-03 19:09:21 +00:00
}
2009-10-20 13:37:44 +00:00
##########################################################################
# Invokes the callback with the specified message
##########################################################################
sub send_msg {
my $ request = shift ;
my $ ecode = shift ;
2012-05-04 01:40:45 +00:00
my $ msg = shift ;
2009-10-20 13:37:44 +00:00
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 ;
2012-05-04 01:40:45 +00:00
$ output { data } = $ msg ;
2009-10-20 13:37:44 +00:00
$ callback - > ( \ % output ) ;
}
}
##########################################################################
# Parse the command line options and operands
##########################################################################
sub parse_args {
my $ request = shift ;
my $ args = $ request - > { arg } ;
my $ cmd = $ request - > { command } ;
2012-04-26 10:22:30 +00:00
my % opt ;
2009-10-20 13:37:44 +00:00
my % services = (
2010-12-07 05:47:07 +00:00
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 ,
2011-01-24 16:11:56 +00:00
FRAME = > HARDWARE_SERVICE . ":" . SERVICE_FRAME ,
2010-12-07 05:47:07 +00:00
RSA = > HARDWARE_SERVICE . ":" . SERVICE_RSA . ":" ,
2011-12-21 06:57:08 +00:00
CMM = > HARDWARE_SERVICE . ":" . SERVICE_CMM ,
2013-03-01 22:01:04 +00:00
IMM2 = > HARDWARE_SERVICE . ":" . SERVICE_IMM2 ,
2010-12-07 05:47:07 +00:00
MM = > HARDWARE_SERVICE . ":" . SERVICE_MM . ":"
2009-10-20 13:37:44 +00:00
) ;
#############################################
# 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 ,
2013-12-13 09:19:04 +00:00
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 ) ) ) {
2009-10-20 13:37:44 +00:00
return ( usage ( ) ) ;
}
2011-01-24 16:11:56 +00:00
2011-03-21 09:25:16 +00:00
#############################################
# Check for node range
#############################################
if ( scalar ( @ ARGV ) eq 1 ) {
my @ nodes = xCAT::NodeRange:: noderange ( @ ARGV ) ;
foreach ( @ nodes ) {
push @ filternodes , $ _ ;
}
2011-08-03 10:04:51 +00:00
unless ( @ filternodes ) {
return ( usage ( "Invalid Argument: $ARGV[0]" ) ) ;
}
2011-03-21 09:25:16 +00:00
} elsif ( scalar ( @ ARGV ) > 1 ) {
2011-06-02 01:59:20 +00:00
return ( usage ( "Invalid flag, please check and retry." ) ) ;
2009-10-20 13:37:44 +00:00
}
2011-06-02 01:59:20 +00:00
2009-10-20 13:37:44 +00:00
#############################################
# Option -V for verbose output
#############################################
if ( exists ( $ opt { V } ) ) {
2012-05-03 06:36:27 +00:00
$ globalopt { verbose } = 1 ;
2009-10-20 13:37:44 +00:00
}
2012-04-26 10:22:30 +00:00
2009-10-20 13:37:44 +00:00
#############################################
# Check for mutually-exclusive formatting
#############################################
2010-02-08 15:56:18 +00:00
if ( ( exists ( $ opt { r } ) + exists ( $ opt { x } ) + exists ( $ opt { z } ) + exists ( $ opt { vpdtable } ) ) > 1 ) {
2009-10-20 13:37:44 +00:00
return ( usage ( ) ) ;
}
#############################################
# Command tries
#############################################
if ( exists ( $ opt { t } ) ) {
2012-05-03 06:36:27 +00:00
$ globalopt { maxtries } = $ opt { t } ;
2009-10-20 13:37:44 +00:00
2012-08-24 01:35:32 +00:00
if ( $ globalopt { maxtries } !~ /^\d+$/ ) {
2009-10-20 13:37:44 +00:00
return ( usage ( "Invalid command tries (1-9)" ) ) ;
}
}
2012-04-26 10:22:30 +00:00
2009-10-20 13:37:44 +00:00
#############################################
# Check for unsupported service type
#############################################
if ( exists ( $ opt { s } ) ) {
if ( ! exists ( $ services { $ opt { s } } ) ) {
return ( usage ( "Invalid service: $opt{s}" ) ) ;
}
2013-03-13 19:21:41 +00:00
$ option_s = $ opt { s } ;
2012-05-03 06:36:27 +00:00
$ globalopt { service } = $ services { $ opt { s } } ;
2009-10-20 13:37:44 +00:00
}
2010-12-29 10:32:22 +00:00
#############################################
# Check the validation of -T option
#############################################
if ( exists ( $ opt { T } ) ) {
2012-05-21 05:50:06 +00:00
$ globalopt { T } = $ opt { T } ;
if ( $ globalopt { T } !~ /^\d+$/ ) {
2010-12-29 10:32:22 +00:00
return ( usage ( "Invalid timeout value, should be number" ) ) ;
2011-01-24 16:11:56 +00:00
}
2012-05-18 03:07:48 +00:00
#if (!exists( $opt{C} )) {
# return ( usage( "-T should be used with -C" ));
#}
2010-12-29 10:32:22 +00:00
}
2011-01-24 16:11:56 +00:00
2010-12-29 10:32:22 +00:00
#############################################
# Check the validation of -C option
#############################################
if ( exists ( $ opt { C } ) ) {
2012-05-03 06:36:27 +00:00
$ globalopt { C } = $ opt { C } ;
2011-01-24 16:11:56 +00:00
2012-05-03 06:36:27 +00:00
if ( $ globalopt { C } !~ /^\d+$/ ) {
2010-12-29 10:32:22 +00:00
return ( usage ( "Invalid expect entries, should be number" ) ) ;
}
if ( ! exists ( $ opt { i } ) ) {
2011-01-24 16:11:56 +00:00
return ( usage ( "-C should be used with -i" ) ) ;
2010-12-29 10:32:22 +00:00
}
2011-01-24 16:11:56 +00:00
}
2012-04-26 10:22:30 +00:00
#############################################
# 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 ( [ 1 , "Invalid IP address: $ip" ] ) ;
}
foreach my $ octet ( @ octets ) {
if ( ( $ octet < 0 ) or ( $ octet > 255 ) ) {
return ( usage ( "Invalid IP address: $ip" ) ) ;
}
}
}
2012-05-03 06:36:27 +00:00
$ globalopt { i } = $ opt { i } ;
2012-04-26 10:22:30 +00:00
}
2009-10-20 13:37:44 +00:00
2012-04-26 10:22:30 +00:00
#############################################
# write to the database
#############################################
if ( exists ( $ opt { w } ) ) {
2012-05-03 06:36:27 +00:00
$ globalopt { w } = 1 ;
2012-04-26 10:22:30 +00:00
}
2009-10-20 13:37:44 +00:00
2012-04-26 10:22:30 +00:00
#############################################
# list the raw information
#############################################
if ( exists ( $ opt { r } ) ) {
2012-05-03 06:36:27 +00:00
$ globalopt { r } = 1 ;
2012-04-26 10:22:30 +00:00
}
2009-10-20 13:37:44 +00:00
2012-04-26 10:22:30 +00:00
#############################################
# list the xml formate data
#############################################
if ( exists ( $ opt { x } ) ) {
2012-05-03 06:36:27 +00:00
$ globalopt { x } = 1 ;
2012-04-26 10:22:30 +00:00
}
2009-10-20 13:37:44 +00:00
2012-04-26 10:22:30 +00:00
#############################################
# list the stanza formate data
#############################################
if ( exists ( $ opt { z } ) ) {
2012-05-03 06:36:27 +00:00
$ globalopt { z } = 1 ;
2012-04-26 10:22:30 +00:00
}
2009-10-20 13:37:44 +00:00
2012-04-26 10:22:30 +00:00
#############################################
# match vpd table
#############################################
if ( exists ( $ opt { vpdtable } ) ) {
2012-05-03 06:36:27 +00:00
$ globalopt { vpdtable } = 1 ;
2012-04-26 10:22:30 +00:00
}
#########################################################
# only list the nodes that discovered for the first time
#########################################################
if ( exists ( $ opt { n } ) ) {
2012-05-03 06:36:27 +00:00
$ globalopt { n } = 1 ;
2009-10-20 13:37:44 +00:00
}
2013-12-13 09:19:04 +00:00
##############################################
# 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" ) ) ;
}
}
2009-10-20 13:37:44 +00:00
2012-04-26 10:22:30 +00:00
##############################################
# warn for no discovered nodes in database
##############################################
2012-04-26 11:45:50 +00:00
if ( exists ( $ opt { I } ) ) {
2012-05-03 06:36:27 +00:00
$ globalopt { I } = 1 ;
2009-10-20 13:37:44 +00:00
}
2012-12-21 09:15:24 +00:00
##############################################
# do slp and setup for cmm
##############################################
if ( exists ( $ opt { flexdiscover } ) ) {
$ globalopt { flexdiscover } = 1 ;
}
2012-05-03 06:36:27 +00:00
return ( 0 ) ;
2009-10-20 13:37:44 +00:00
}
##########################################################################
# Verbose mode (-V)
##########################################################################
sub trace {
my $ request = shift ;
my $ msg = shift ;
2011-05-24 09:27:41 +00:00
my $ sig = shift ;
2009-10-20 13:37:44 +00:00
2011-05-24 09:27:41 +00:00
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 ) ;
}
2011-06-02 01:59:20 +00:00
} else {
2012-05-18 03:07:48 +00:00
if ( $ globalopt { verbose } ) {
2011-05-24 09:27:41 +00:00
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 ) ;
}
2011-06-02 01:59:20 +00:00
}
2009-10-20 13:37:44 +00:00
}
##########################################################################
# 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 ;
2010-10-14 03:47:05 +00:00
my $ pid = xCAT::Utils - > xfork ( ) ;
2009-10-20 13:37:44 +00:00
if ( ! defined ( $ pid ) ) {
###################################
# Fork error
###################################
send_msg ( $ request , 1 , "Fork error: $!" ) ;
return undef ;
}
elsif ( $ pid == 0 ) {
###################################
# Child process
###################################
close ( $ parent ) ;
$ request - > { pipe } = $ child ;
2012-04-26 10:22:30 +00:00
invoke_dodiscover ( $ request ) ;
########################################
# Pass result array back to parent
########################################
my @ results = ( "FORMATDATA6sK4ci" ) ;
my $ out = $ request - > { pipe } ;
print $ out freeze ( \ @ results ) ;
print $ out "\nENDOFFREEZE6sK4ci\n" ;
2009-10-20 13:37:44 +00:00
exit ( 0 ) ;
}
else {
###################################
# Parent process
###################################
close ( $ child ) ;
return ( $ parent ) ;
}
return ( 0 ) ;
}
##########################################################################
# Run the forked command and send reply to parent
##########################################################################
2012-04-26 10:22:30 +00:00
sub invoke_dodiscover {
2009-10-20 13:37:44 +00:00
my $ request = shift ;
########################################
# SLP command
########################################
2012-05-03 06:36:27 +00:00
my $ services ;
my $ maxt ;
if ( $ globalopt { service } ) {
$ services = $ globalopt { service } ;
} else {
2013-10-28 14:27:29 +00:00
$ services = [ WILDCARD_SERVICE , HARDWARE_SERVICE , SOFTWARE_SERVICE , SERVICE_IMM2 ] ;
2012-05-03 06:36:27 +00:00
}
2012-05-17 08:29:27 +00:00
#efix for hmc bug
if ( $ services =~ /hardware-management-console/ ) {
2012-08-24 01:35:32 +00:00
$ services = [ SOFTWARE_SERVICE ] ;
2012-05-17 08:29:27 +00:00
}
2012-05-03 06:36:27 +00:00
if ( $ globalopt { maxtries } ) {
$ maxt = $ globalopt { maxtries } ;
} else {
$ maxt = 0 ;
}
2012-05-04 01:40:45 +00:00
2012-05-07 07:45:45 +00:00
2012-05-03 06:36:27 +00:00
my % arg ;
2013-06-18 15:35:07 +00:00
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/ ] ;
2012-12-21 09:15:24 +00:00
my ( $ searchmacsref , $ sendcount , $ rsp ) = xCAT::SLP:: dodiscover ( SrvTypes = > $ arg { SrvTypes } , Callback = > \ & bt_handle_new_slp_entity ) ;
2013-06-18 15:35:07 +00:00
$ 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 ) {
2013-06-18 15:39:56 +00:00
$ searchmacsref - > { $ _ } = $ newsearchmacsref - > { $ _ } ;
2013-06-18 15:35:07 +00:00
}
$ sendcount += $ newsendcount ;
$ rsp += $ newrsp ;
2012-12-21 09:15:24 +00:00
return ( $ searchmacsref , $ sendcount , $ rsp ) ;
}
2012-05-03 06:36:27 +00:00
$ arg { SrvTypes } = $ services ;
2012-07-23 07:40:51 +00:00
#$arg{Callback} = \&handle_new_slp_entity;
2012-05-03 06:36:27 +00:00
$ arg { Ip } = $ globalopt { i } if ( $ globalopt { i } ) ;
$ arg { Retry } = $ maxt ;
2012-05-04 01:40:45 +00:00
$ arg { Count } = $ globalopt { C } if ( $ globalopt { C } ) ;
$ arg { Time } = $ globalopt { T } if ( $ globalopt { T } ) ;
2013-03-15 06:02:37 +00:00
$ arg { nomsg } = 1 if ( $ globalopt { z } or $ globalopt { x } ) ;
2012-08-11 06:56:45 +00:00
$ arg { reqcallback } = $ request - > { callback } if ( $ request - > { callback } ) ;
2013-12-13 09:19:04 +00:00
if ( $ globalopt { u } ) {
$ arg { unicast } = 1 ;
$ arg { range } = $ globalopt { range } ;
}
2012-08-11 06:56:45 +00:00
my ( $ searchmacsref , $ sendcount , $ rsp ) = xCAT::SLP:: dodiscover ( % arg ) ;
2009-10-20 13:37:44 +00:00
2011-03-17 09:39:31 +00:00
2012-04-26 10:22:30 +00:00
#########################################
## 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);
2012-05-03 06:36:27 +00:00
# while ( $found < $globalopt{C} ) {
2012-04-26 10:22:30 +00:00
# $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;
2012-05-03 06:36:27 +00:00
# if ( $elapse > $globalopt{time_out} ) {
2012-04-26 10:22:30 +00:00
# send_msg( $request, 0, "Time out, Force return.\n" );
# last;
# }
# }
# send_msg( $request, 0, "Discovered $found nodes \n" );
# $values = \%val_tmp;
#}
2012-07-23 07:40:51 +00:00
2012-08-11 06:56:45 +00:00
return ( $ searchmacsref , $ sendcount , $ rsp ) ;
2009-10-20 13:37:44 +00:00
}
##########################################################################
2012-04-26 10:22:30 +00:00
# Formats slp responses
2009-10-20 13:37:44 +00:00
##########################################################################
2012-04-26 10:22:30 +00:00
sub format_output {
2009-10-20 13:37:44 +00:00
2012-04-26 10:22:30 +00:00
my $ request = shift ;
2012-07-23 07:40:51 +00:00
my $ searchmacsref = shift ;
my % searchmacs = %$ searchmacsref ;
2012-04-26 10:22:30 +00:00
my $ length = length ( $ header [ IP_ADDRESSES ] [ TEXT ] ) ;
my $ result ;
2012-05-07 07:45:45 +00:00
2012-05-04 01:40:45 +00:00
###########################################
# No responses
###########################################
if ( keys % searchmacs == 0 ) {
send_msg ( $ request , 0 , "No responses" ) ;
return ;
}
2011-08-03 10:04:51 +00:00
2012-05-04 01:40:45 +00:00
###########################################
# Check -C -T
###########################################
if ( $ globalopt { C } ) {
if ( scalar ( keys % searchmacs ) ne $ globalopt { C } ) {
send_msg ( $ request , 0 , "Timeout...Fource to return" ) ;
2012-05-07 07:45:45 +00:00
}
2012-05-04 01:40:45 +00:00
}
###########################################
# Read table to get exists data
###########################################
2012-08-27 06:11:39 +00:00
unless ( $ globalopt { service } =~ /hardware-management-console/ ) {
my $ errcode = read_from_table ( ) ;
if ( $ errcode ) {
send_msg ( $ request , 0 , "Can't open $errcode table" ) ;
return ;
}
}
2012-04-26 10:22:30 +00:00
###########################################
# Parse responses and add to hash
###########################################
2012-07-23 07:40:51 +00:00
my $ outhash = parse_responses ( $ request , \ $ length , $ searchmacsref ) ;
2012-05-04 01:40:45 +00:00
2012-05-17 08:29:27 +00:00
#hmc bug efix
2012-08-27 06:11:39 +00:00
#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;
#}
2012-05-17 08:29:27 +00:00
2012-04-26 10:22:30 +00:00
###########################################
2012-08-11 06:23:35 +00:00
# filter the result in the same vlan
###########################################
if ( exists ( $ globalopt { i } ) ) {
my $ outhash1 = filtersamevlan ( $ outhash ) ;
$ outhash = $ outhash1 ;
}
2012-04-26 10:22:30 +00:00
# filter the result and keep the specified nodes
###########################################
if ( scalar ( @ filternodes ) ) {
my $ outhash1 = filter ( $ outhash ) ;
$ outhash = $ outhash1 ;
}
2011-08-03 10:04:51 +00:00
2009-10-20 13:37:44 +00:00
###########################################
# -w flag for write to xCat database
###########################################
2012-05-03 06:36:27 +00:00
if ( $ globalopt { w } ) {
2011-01-27 08:40:33 +00:00
send_msg ( $ request , 0 , "Begin to write into Database, this may change node name" ) ;
2011-01-11 15:12:52 +00:00
xCATdB ( $ outhash ) ;
2009-10-20 13:37:44 +00:00
}
2009-11-13 12:56:37 +00:00
2012-04-26 11:45:50 +00:00
2011-01-27 08:40:33 +00:00
2009-10-20 13:37:44 +00:00
###########################################
# -r flag for raw response format
###########################################
2012-04-26 10:22:30 +00:00
my % rawhash ;
2012-05-03 06:36:27 +00:00
if ( $ globalopt { r } ) {
2009-10-20 13:37:44 +00:00
foreach ( keys %$ outhash ) {
2012-04-26 10:22:30 +00:00
my $ raw = $ { $ outhash - > { $ _ } } { url } ;
2011-02-11 06:18:52 +00:00
$ rawhash { $ raw } = 1 ;
2009-10-20 13:37:44 +00:00
}
2012-09-03 07:39:45 +00:00
foreach my $ en ( keys % rawhash ) {
if ( $ en =~ /(\(type.*\))/ ) {
$ result . = "$1\n" ;
}
2011-02-11 06:18:52 +00:00
}
2011-06-02 01:59:20 +00:00
2009-10-20 13:37:44 +00:00
send_msg ( $ request , 0 , $ result ) ;
return ;
}
###########################################
# -x flag for xml format
###########################################
2012-05-03 06:36:27 +00:00
if ( $ globalopt { x } ) {
2009-10-20 13:37:44 +00:00
send_msg ( $ request , 0 , format_xml ( $ outhash ) ) ;
2009-10-20 11:31:17 +00:00
return ;
2008-06-03 19:09:21 +00:00
}
2009-10-20 13:37:44 +00:00
###########################################
# -z flag for stanza format
###########################################
2012-05-03 06:36:27 +00:00
if ( $ globalopt { z } ) {
2009-10-20 13:37:44 +00:00
send_msg ( $ request , 0 , format_stanza ( $ outhash ) ) ;
return ;
}
2010-02-06 14:00:25 +00:00
###########################################
# -T flag for vpd table format
###########################################
2012-05-03 06:36:27 +00:00
if ( $ globalopt { vpdtable } ) {
2010-02-06 14:00:25 +00:00
send_msg ( $ request , 0 , format_table ( $ outhash ) ) ;
return ;
}
2009-10-20 13:37:44 +00:00
###########################################
# 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
###########################################
2012-04-26 10:22:30 +00:00
foreach my $ nameentry ( sort keys %$ outhash ) {
my $ hostname = $ { $ outhash - > { $ nameentry } } { hostname } ;
2009-10-20 13:37:44 +00:00
foreach ( @ header ) {
2012-04-26 10:22:30 +00:00
my $ attr = $ headertoattr { @$ _ [ 0 ] } ;
$ result . = sprintf @$ _ [ 1 ] , $ { $ outhash - > { $ nameentry } } { $ attr } ;
2009-10-20 13:37:44 +00:00
}
$ result . = "\n" ;
}
send_msg ( $ request , 0 , $ result ) ;
}
2011-01-27 08:40:33 +00:00
2009-10-20 13:37:44 +00:00
##########################################################################
2012-04-26 10:22:30 +00:00
# Read the table and cache the data that will be used frequently
2009-10-20 13:37:44 +00:00
##########################################################################
2011-09-14 13:57:31 +00:00
sub read_from_table {
my % vpdhash ;
2012-04-26 10:22:30 +00:00
my @ nodelist ;
my % ppchash ;
my % iphash ;
2012-11-30 09:11:34 +00:00
if ( ! ( % ::OLD_DATA_CACHE ) )
2011-09-14 13:57:31 +00:00
{
2012-04-26 10:22:30 +00:00
#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 } ;
2011-09-14 13:57:31 +00:00
}
} else {
2012-04-26 10:22:30 +00:00
return "nodelist" ;
2011-09-14 13:57:31 +00:00
}
2009-10-20 13:37:44 +00:00
2012-04-26 10:22:30 +00:00
#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 } ;
2011-09-14 13:57:31 +00:00
}
} else {
2012-04-26 10:22:30 +00:00
return "hosts" ;
2011-09-14 13:57:31 +00:00
}
2012-04-26 10:22:30 +00:00
#find out all the existed nodes' type
2012-05-07 07:45:45 +00:00
my $ typehashref = xCAT::DBobjUtils - > getnodetype ( \ @ nodelist ) ;
2012-04-26 10:22:30 +00:00
2011-09-14 13:57:31 +00:00
# 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 } ;
2012-04-26 10:22:30 +00:00
@ { $ vpdhash { $ entry - > { node } } } [ 1 ] = $ entry - > { serial } ;
2011-09-14 13:57:31 +00:00
@ { $ vpdhash { $ entry - > { node } } } [ 2 ] = $ entry - > { side } ;
}
} else {
2012-04-26 10:22:30 +00:00
return "vpd" ;
2011-09-14 13:57:31 +00:00
}
2012-04-26 10:22:30 +00:00
2011-09-14 13:57:31 +00:00
# find out all the existed nodes' attributes
my $ ppctab = xCAT::Table - > new ( 'ppc' ) ;
if ( $ ppctab ) {
2012-04-26 10:22:30 +00:00
my @ identries = $ ppctab - > getAllNodeAttribs ( [ 'node' , 'id' , 'parent' ] ) ;
2011-09-14 13:57:31 +00:00
for my $ entry ( @ identries ) {
2011-09-18 14:38:15 +00:00
next if ( $ entry - > { nodetype } =~ /lpar/ ) ;
2012-04-26 10:22:30 +00:00
@ { $ ppchash { $ entry - > { node } } } [ 0 ] = $ entry - > { id } ; #id
@ { $ ppchash { $ entry - > { node } } } [ 1 ] = $ entry - > { parent } ; #parent
2011-01-24 16:11:56 +00:00
}
2011-05-25 09:33:58 +00:00
} else {
2012-04-26 10:22:30 +00:00
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 ] ;
2012-07-27 14:11:12 +00:00
my $ pmtm = @ { $ vpdhash { $ parent } } [ 0 ] ;
my $ psn = @ { $ vpdhash { $ parent } } [ 1 ] ;
2012-04-26 10:22:30 +00:00
my $ ip = $ iphash { $ node } ;
if ( $ type =~ /frame/ ) {
2012-07-27 14:11:12 +00:00
$ ::OLD_DATA_CACHE { "frame*" . $ mtm . "*" . $ sn } = $ node if ( defined $ mtm and defined $ sn ) ;
2012-04-26 10:22:30 +00:00
} elsif ( $ type =~ /cec/ ) {
2012-07-27 14:11:12 +00:00
$ ::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 ) ;
2012-04-26 10:22:30 +00:00
} elsif ( $ type =~ /^fsp|bpa$/ ) {
2012-07-27 14:11:12 +00:00
$ ::OLD_DATA_CACHE { $ type . "*" . $ mtm . "*" . $ sn . "*" . $ side } = $ node if ( defined $ mtm and defined $ sn ) ; ;
2012-04-26 10:22:30 +00:00
} elsif ( $ type =~ /hmc/ ) {
2012-07-27 14:11:12 +00:00
$ ::OLD_DATA_CACHE { "hmc*" . $ ip } = $ node if ( defined $ ip ) ;
2012-04-26 10:22:30 +00:00
} else {
2012-07-27 14:11:12 +00:00
$ ::OLD_DATA_CACHE { $ type . "*" . $ mtm . "*" . $ sn } = $ node if ( defined $ mtm and defined $ sn ) ; ;
2012-04-26 10:22:30 +00:00
}
2011-01-24 16:11:56 +00:00
}
}
2012-04-26 10:22:30 +00:00
return undef ;
2011-01-24 16:11:56 +00:00
}
##########################################################################
# Makesure the ip in SLP URL is valid
# return 1 if valid, 0 if invalid
##########################################################################
sub check_ip {
my $ myip = shift ;
2012-04-26 10:22:30 +00:00
$ myip =~ s/^(\d+)\..*/$1/ ;
if ( $ myip >= 224 and $ myip <= 239 ) {
2011-01-24 16:11:56 +00:00
return 0 ;
}
2012-04-26 10:22:30 +00:00
foreach ( @ invalidiplist ) {
if ( $ myip =~ /^($_)/ ) {
2011-01-24 16:11:56 +00:00
return 0 ;
}
}
return 1 ;
}
2009-10-20 13:37:44 +00:00
##########################################################################
# Get hostname from SLP URL response
##########################################################################
2012-04-26 10:22:30 +00:00
sub get_host_from_url {
2009-10-20 13:37:44 +00:00
my $ request = shift ;
2012-04-26 10:22:30 +00:00
my $ attr = shift ;
my $ vip ;
2010-02-04 08:12:33 +00:00
my $ host ;
2009-10-20 13:37:44 +00:00
#######################################
# Extract IP from URL
#######################################
2012-08-09 04:07:40 +00:00
my $ nets = xCAT::NetworkUtils:: my_nets ( ) ;
2012-05-03 06:36:27 +00:00
my $ inc = $ globalopt { i } ;
2012-05-15 13:53:16 +00:00
my @ ips = ( exists $ attr - > { 'ip-address' } ) ? @ { $ attr - > { 'ip-address' } } : @ { $ attr - > { 'ipv4-address' } } ;
2009-10-20 13:37:44 +00:00
2012-04-26 10:22:30 +00:00
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 ) ;
2009-10-20 13:37:44 +00:00
}
}
#######################################
2012-04-26 10:22:30 +00:00
# Check if valid IP
2009-10-20 13:37:44 +00:00
#######################################
2012-04-26 10:22:30 +00:00
for my $ tip ( @ ips ) {
next if ( $ tip =~ /:/ ) ; #skip IPV6 addresses
for my $ net ( keys %$ nets ) {
my ( $ n , $ m ) = split /\// , $ net ;
2012-08-09 04:07:40 +00:00
if ( #xCAT::NetworkUtils::isInSameSubnet($n, $tip, $m, 1) and
2012-08-14 11:55:48 +00:00
xCAT::NetworkUtils:: isPingable ( $ tip ) and ( length ( inet_aton ( $ tip ) ) == 4 ) ) {
2012-04-26 10:22:30 +00:00
push @ validip , $ tip ;
}
2009-07-31 19:45:28 +00:00
}
2009-10-20 13:37:44 +00:00
}
2010-02-04 08:12:33 +00:00
2012-04-26 10:22:30 +00:00
if ( scalar ( @ validip ) == 0 ) {
2012-05-18 03:07:48 +00:00
trace ( $ request , "Invalid IP address in URL" ) ;
return undef ;
}
2010-02-04 08:12:33 +00:00
2009-10-20 13:37:44 +00:00
#######################################
2012-04-26 10:22:30 +00:00
# Get Factory Hostname
2011-01-24 16:11:56 +00:00
#######################################
2012-04-26 10:22:30 +00:00
if ( $ { $ attr - > { 'hostname' } } [ 0 ] ) {
$ host = $ { $ attr - > { 'hostname' } } [ 0 ] ;
2009-10-20 13:37:44 +00:00
2012-04-26 10:22:30 +00:00
} 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 ) {
2012-05-15 13:53:16 +00:00
$ host = $ hname ;
$ vip = $ ip ;
last ;
2012-04-26 10:22:30 +00:00
2012-05-15 13:53:16 +00:00
}
2012-04-26 10:22:30 +00:00
}
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 ;
2010-02-04 08:12:33 +00:00
2012-04-26 10:22:30 +00:00
}
2010-02-04 08:12:33 +00:00
}
}
2009-10-20 13:37:44 +00:00
}
2012-04-26 10:22:30 +00:00
if ( $ host =~ /([^\.]+)\./ ) {
$ host = $ 1 ;
2010-02-04 08:12:33 +00:00
}
2012-04-26 10:22:30 +00:00
return $ host ;
2010-02-04 08:12:33 +00:00
}
2009-10-20 13:37:44 +00:00
2010-02-04 08:12:33 +00:00
##########################################################################
2012-04-26 10:22:30 +00:00
#
#########################################################################
sub parse_responses {
2010-02-05 16:36:16 +00:00
2012-04-26 10:22:30 +00:00
my $ request = shift ;
my $ length = shift ;
2012-07-23 07:40:51 +00:00
my $ searchmacsref = shift ;
2012-04-26 10:22:30 +00:00
my $ matchflag ;
my % outhash ;
my $ host ;
my @ matchnode ;
2013-04-22 10:13:45 +00:00
my @ cmmnodes ;
2012-07-23 07:40:51 +00:00
my % searchmacs = %$ searchmacsref ;
2009-10-20 13:37:44 +00:00
2012-04-26 10:22:30 +00:00
#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 ) {
2012-05-18 03:07:48 +00:00
send_msg ( $ request , 0 , "Can't get networks information from networks table" ) ;
2012-04-26 10:22:30 +00:00
} else {
foreach my $ enet ( @ nets ) {
next if ( $ enet - > { 'net' } =~ /:/ ) ;
$ net { $ enet - > { 'mgtifname' } } { subnet } = $ enet - > { 'net' } ;
$ net { $ enet - > { 'mgtifname' } } { netmask } = $ enet - > { 'mask' } ;
2009-10-20 13:37:44 +00:00
}
}
2012-04-26 10:22:30 +00:00
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 } ;
2009-10-20 13:37:44 +00:00
}
2010-02-09 08:58:10 +00:00
2012-05-18 03:07:48 +00:00
trace ( $ request , "Now lsslp begin to parse its response..." ) ;
2012-04-26 10:22:30 +00:00
foreach my $ rsp ( keys ( % searchmacs ) ) {
###########################################
# attribute not found
###########################################
if ( ! exists ( $ { $ searchmacs { $ rsp } } { attributes } ) ) {
2012-05-18 03:07:48 +00:00
trace ( $ request , "Attribute not found for $rsp" ) ;
2012-04-26 10:22:30 +00:00
next ;
2010-02-09 08:58:10 +00:00
}
2012-04-26 10:22:30 +00:00
###########################################
# Valid service-type attribute
###########################################
my $ attributes = $ { $ searchmacs { $ rsp } } { attributes } ;
my $ type = $ { $ attributes - > { 'type' } } [ 0 ] ;
if ( ! exists ( $ service_slp { $ type } ) ) {
2012-05-18 03:07:48 +00:00
trace ( $ request , "Discarding unsupported type $type" ) ;
2012-04-26 10:22:30 +00:00
next ;
2010-03-23 08:33:08 +00:00
}
2012-05-18 03:07:48 +00:00
2009-10-20 13:37:44 +00:00
###########################################
2012-04-26 10:22:30 +00:00
# Define nodes
2009-10-20 13:37:44 +00:00
###########################################
2012-04-26 10:22:30 +00:00
my % atthash ;
2009-10-20 13:37:44 +00:00
if ( ( $ type eq SERVICE_RSA ) or ( $ type eq SERVICE_RSA2 ) or
2013-03-01 22:01:04 +00:00
( $ type eq SERVICE_MM ) or ( $ type eq SERVICE_IMM2 ) ) {
2012-04-26 10:22:30 +00:00
$ 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 ] ) ;
2013-03-01 22:01:04 +00:00
if ( $ type eq SERVICE_IMM2 ) { $ atthash { ip } = $ { $ attributes - > { 'ipv4-address' } } [ 0 ] ; }
else { $ atthash { ip } = $ { $ attributes - > { 'ip-address' } } [ 0 ] ; }
2012-04-26 10:22:30 +00:00
$ atthash { mac } = $ rsp ;
$ atthash { hostname } = get_host_from_url ( $ request , $ attributes ) ;
$ atthash { otherinterfaces } = $ { $ attributes - > { 'ip-address' } } [ 0 ] ;
2012-05-15 13:53:16 +00:00
$ atthash { url } = $ { $ searchmacs { $ rsp } } { payload } ;
2012-04-26 10:22:30 +00:00
$ outhash { 'Server-' . $ atthash { mtm } . '-SN' . $ atthash { serial } } = \ % atthash ;
$$ length = length ( $ atthash { ip } ) if ( length ( $ atthash { ip } ) > $$ length ) ;
2012-05-18 03:07:48 +00:00
trace ( $ request , " Discover node $ atthash { hostname } : type is $ atthash { type } , \
mtm is $ atthash { mtm } , sn is $ atthash { serial } , slot is $ atthash { slot } , \
2012-05-30 08:56:43 +00:00
ip is $ atthash { ip } , mac is $ atthash { mac } , otherinterfaces is $ atthash { otherinterfaces } " ) ;
2012-05-18 03:07:48 +00:00
2011-12-21 02:25:14 +00:00
} elsif ( $ type eq SERVICE_CMM ) {
2012-04-26 10:22:30 +00:00
$ atthash { type } = $ service_slp { $ type } ;
2012-05-15 13:53:16 +00:00
$ atthash { mtm } = $ { $ attributes - > { 'enclosure-mtm' } } [ 0 ] ;
2012-04-26 10:22:30 +00:00
$ atthash { serial } = $ { $ attributes - > { 'enclosure-serial-number' } } [ 0 ] ;
2012-05-16 03:16:49 +00:00
$ atthash { side } = int ( $ { $ attributes - > { 'slot' } } [ 0 ] ) ;
2012-05-15 13:53:16 +00:00
$ atthash { ip } = $ { $ attributes - > { 'ipv4-address' } } [ 0 ] ;
2012-04-26 10:22:30 +00:00
$ atthash { mac } = $ rsp ;
$ atthash { mname } = $ { $ attributes - > { 'mm-name' } } [ 0 ] ;
2012-05-15 13:53:16 +00:00
$ atthash { url } = $ { $ searchmacs { $ rsp } } { payload } ;
2012-04-26 10:22:30 +00:00
$ atthash { hostname } = get_host_from_url ( $ request , $ attributes ) ;
2012-05-15 13:53:16 +00:00
$ atthash { mpa } = $ atthash { hostname } ;
$ atthash { otherinterfaces } = $ { $ attributes - > { 'ipv4-address' } } [ 0 ] ;
2012-04-26 10:22:30 +00:00
$ outhash { 'Server-' . $ atthash { mtm } . '-SN' . $ atthash { serial } } = \ % atthash ;
$$ length = length ( $ atthash { ip } ) if ( length ( $ atthash { ip } ) > $$ length ) ;
2013-04-09 07:13:18 +00:00
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 } ;
}
2013-04-22 10:13:45 +00:00
push @ cmmnodes , 'Server-' . $ atthash { mtm } . '-SN' . $ atthash { serial } ;
2012-05-18 03:07:48 +00:00
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 } , \
2012-05-30 08:56:43 +00:00
mpa is $ atthash { mpa } , otherinterfaces is $ atthash { otherinterfaces } " ) ;
2012-05-18 03:07:48 +00:00
2011-12-21 02:25:14 +00:00
} elsif ( $ type eq SERVICE_HMC ) {
2012-04-26 10:22:30 +00:00
$ 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 ) ;
2012-05-15 13:53:16 +00:00
my @ ips = @ { $ attributes - > { 'ip-address' } } ;
foreach my $ tmpip ( @ ips ) {
2012-04-26 10:22:30 +00:00
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 ;
2011-04-13 05:29:20 +00:00
}
2012-05-15 13:53:16 +00:00
}
2012-04-26 10:22:30 +00:00
$ atthash { mac } = $ rsp ;
2012-05-15 13:53:16 +00:00
$ atthash { url } = $ { $ searchmacs { $ rsp } } { payload } ;
2012-04-26 10:22:30 +00:00
$ atthash { otherinterfaces } = $ { $ attributes - > { 'ip-address' } } [ 0 ] ;
$ outhash { 'Server-' . $ atthash { mtm } . '-SN' . $ atthash { serial } } = \ % atthash ;
$$ length = length ( $ atthash { ip } ) if ( length ( $ atthash { ip } ) > $$ length ) ;
2012-05-18 03:07:48 +00:00
trace ( $ request , " Discover node $ atthash { hostname } : type is $ atthash { type } , \
mtm is $ atthash { mtm } , sn is $ atthash { serial } , ip is $ atthash { ip } , \
2012-05-30 08:56:43 +00:00
mac is $ atthash { mac } , otherinterfaces is $ atthash { otherinterfaces } " ) ;
2013-03-21 17:33:18 +00:00
} elsif ( ( $ type eq SERVICE_FSP ) && ( $ { $ attributes - > { 'machinetype-model' } } [ 0 ] =~ /^7895|1457|7954/ ) ) {
2013-03-13 19:21:41 +00:00
# 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" ) ;
2013-03-01 22:01:04 +00:00
#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 } ;
2013-03-13 19:21:41 +00:00
$ tmphash { url } = $ { $ searchmacs { $ rsp } } { payload } ;
2013-03-01 22:01:04 +00:00
$ 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 {
2012-04-26 10:22:30 +00:00
#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 ) ;
2012-05-30 08:56:43 +00:00
trace ( $ request , " Discover node $ tmphash { hostname } : type is $ tmphash { type } , mtm is $ tmphash { mtm } , \
2012-05-18 03:07:48 +00:00
sn is $ tmphash { serial } , side is $ tmphash { side } , parent is $ tmphash { parent } , ip is $ tmphash { ip } , \
2012-05-30 08:56:43 +00:00
cec id is $ tmphash { cid } , frame id is $ tmphash { fid } , mac is $ tmphash { mac } , \
otherinterfaces is $ tmphash { otherinterfaces } " ) ;
2012-05-25 08:44:05 +00:00
#####################################################################
#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 ;
2012-07-23 07:40:51 +00:00
$ tmphash1 { mac } = xCAT::SLP:: get_mac_for_addr ( $ tmphash1 { ip } ) ;
2012-05-25 08:44:05 +00:00
$ 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 ) ;
2012-07-27 14:11:12 +00:00
trace ( $ request , " Discover another node $ tmphash1 { hostname } : type is $ tmphash1 { type } , mtm is $ tmphash1 { mtm } , \
2012-05-25 08:44:05 +00:00
sn is $ tmphash1 { serial } , side is $ tmphash1 { side } , parent is $ tmphash1 { parent } , ip is $ tmphash1 { ip } , \
2012-05-30 08:56:43 +00:00
cec id is $ tmphash1 { cid } , frame id is $ tmphash1 { fid } , mac is $ tmphash1 { mac } , \
otherinterfaces is $ tmphash1 { otherinterfaces } " ) ;
2012-05-25 08:44:05 +00:00
}
}
2012-05-30 08:56:43 +00:00
# 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");
#}
2012-05-25 08:44:05 +00:00
######################################################################
2012-04-26 10:22:30 +00:00
#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 } ; ;
2012-05-30 08:56:43 +00:00
$ atthash { mac } = "" ;
2012-04-26 10:22:30 +00:00
$ 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 ;
2012-07-27 14:11:12 +00:00
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 } " ) ;
2012-05-07 07:45:45 +00:00
} 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 ) ;
2012-07-27 14:11:12 +00:00
$ { $ 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 ) ;
2012-05-30 08:56:43 +00:00
$ outhash { $ name } { children } . = "," . $ { $ attributes - > { 'ip-address' } } [ 0 ] . "," . $ { $ attributes - > { 'ip-address' } } [ 1 ] ; # at most save 8 ips and have redendant
2012-07-27 14:11:12 +00:00
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 } " ) ;
2012-04-26 10:22:30 +00:00
}
2012-07-27 14:11:12 +00:00
2013-03-15 07:46:16 +00:00
}
}
2012-04-26 10:22:30 +00:00
###########################################################
# 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
###########################################################
2011-09-14 13:57:31 +00:00
my $ newhostname ;
2012-05-18 03:07:48 +00:00
trace ( $ request , "\n\n\nBegin to find find frame's hostname" ) ;
2010-12-07 05:47:07 +00:00
foreach my $ h ( keys % outhash ) {
2012-04-26 10:22:30 +00:00
if ( $ { $ outhash { $ h } } { type } eq TYPE_FRAME ) {
$ newhostname = $ ::OLD_DATA_CACHE { "frame*" . $ { $ outhash { $ h } } { mtm } . "*" . $ { $ outhash { $ h } } { serial } } ;
2011-09-14 13:57:31 +00:00
if ( $ newhostname ) {
2012-04-26 10:22:30 +00:00
$ { $ outhash { $ h } } { hostname } = $ newhostname ;
2013-03-13 19:21:41 +00:00
trace ( $ request , "$h found hostname $newhostname" ) ;
2012-04-26 10:22:30 +00:00
push @ matchnode , $ h ;
2011-01-11 15:12:52 +00:00
}
2012-04-26 10:22:30 +00:00
}
}
2012-05-18 03:07:48 +00:00
trace ( $ request , "\n\n\nBegin to find cec's parent" ) ;
2012-04-26 10:22:30 +00:00
foreach my $ h ( keys % outhash ) {
next unless ( $ { $ outhash { $ h } } { type } eq TYPE_CEC ) ;
my $ parent ;
#find parent in the discovered nodes
2010-12-07 05:47:07 +00:00
foreach my $ h1 ( keys % outhash ) {
2012-04-26 10:22:30 +00:00
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 } ;
2010-12-29 10:32:22 +00:00
last ;
2010-02-09 08:58:10 +00:00
}
}
2012-04-26 10:22:30 +00:00
#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 ) ;
2011-05-10 07:37:01 +00:00
}
2012-04-26 10:22:30 +00:00
$ { $ outhash { $ h } } { parent } = $ parent ;
2013-03-13 19:21:41 +00:00
trace ( $ request , "$h found parent $parent" ) if ( $ parent ) ;
2012-05-18 03:07:48 +00:00
}
2011-05-10 07:37:01 +00:00
2012-05-18 03:07:48 +00:00
trace ( $ request , "\n\n\nBegin to find cec hostname" ) ;
2011-09-14 13:57:31 +00:00
foreach my $ h ( keys % outhash ) {
2012-04-26 10:22:30 +00:00
if ( $ { $ outhash { $ h } } { type } eq TYPE_CEC ) {
my $ newhostname1 = $ ::OLD_DATA_CACHE { "cec*" . $ { $ outhash { $ h } } { mtm } . '*' . $ { $ outhash { $ h } } { serial } } ;
if ( $ newhostname1 ) {
2013-03-13 19:21:41 +00:00
trace ( $ request , "$h found hostname $newhostname1 with mtms" ) ;
2012-04-26 10:22:30 +00:00
$ { $ outhash { $ h } } { hostname } = $ newhostname1 ;
push @ matchnode , $ h ;
2011-09-14 13:57:31 +00:00
}
2012-07-27 14:11:12 +00:00
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 } } ;
2012-04-26 10:22:30 +00:00
if ( $ newhostname2 ) {
$ { $ outhash { $ h } } { hostname } = $ newhostname2 ;
2013-03-13 19:21:41 +00:00
trace ( $ request , "$h found hostname $newhostname2 with parent and id" ) ;
2012-04-26 10:22:30 +00:00
push @ matchnode , $ h ;
2011-12-07 10:27:06 +00:00
}
}
2012-04-26 10:22:30 +00:00
}
2011-09-14 13:57:31 +00:00
2012-05-18 03:07:48 +00:00
trace ( $ request , "\n\n\nBegin to find fsp/bpa's hostname and parent" ) ;
2012-04-26 10:22:30 +00:00
foreach my $ h ( keys % outhash ) {
2013-03-01 22:01:04 +00:00
# Added a skip if processing Flex blades
2013-03-15 07:46:16 +00:00
if ( $ { $ outhash { $ h } } { type } eq TYPE_FSP or $ { $ outhash { $ h } } { type } eq TYPE_BPA ) {
2012-04-26 10:22:30 +00:00
$ newhostname = $ ::OLD_DATA_CACHE { $ { $ outhash { $ h } } { type } . "*" . $ { $ outhash { $ h } } { mtm } . '*' . $ { $ outhash { $ h } } { serial } . '*' . $ { $ outhash { $ h } } { side } } ;
if ( $ newhostname ) {
$ { $ outhash { $ h } } { hostname } = $ newhostname ;
2013-03-13 19:21:41 +00:00
trace ( $ request , "$h found hostname $newhostname" ) ;
2012-04-26 10:22:30 +00:00
push @ matchnode , $ h ;
}
my $ ptmp = $ { $ outhash { $ h } } { parent } ;
2013-03-21 17:33:18 +00:00
$ { $ outhash { $ h } } { parent } = $ { $ outhash { $ ptmp } } { hostname } unless ( ( $ { $ outhash { $ h } } { type } eq TYPE_FSP ) && $ { $ outhash { $ h } } { mtm } =~ /^7895|1457|7954/ ) ;
2013-03-13 19:21:41 +00:00
trace ( $ request , "$h found parent ${$outhash{$ptmp}}{hostname}" ) ;
2012-04-26 10:22:30 +00:00
#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 } ;
}
2011-12-07 10:27:06 +00:00
}
2011-09-14 13:57:31 +00:00
}
2012-08-15 13:52:26 +00:00
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}" ) ;
}
2012-04-26 10:22:30 +00:00
2013-04-22 10:13:45 +00:00
}
}
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" ) ;
}
}
2013-03-01 22:01:04 +00:00
2011-09-14 13:57:31 +00:00
##########################################################
# If there is -n flag, skip the matched nodes
##########################################################
2012-05-03 06:36:27 +00:00
if ( exists ( $ globalopt { n } ) ) {
2012-05-18 03:07:48 +00:00
trace ( $ request , "\n\n\nThere is -n flag, skip these nodes:\n" ) ;
2012-04-26 10:22:30 +00:00
for my $ matchednode ( @ matchnode ) {
if ( $ outhash { $ matchednode } ) {
2012-05-18 03:07:48 +00:00
trace ( $ request , "skip the node $matchednode\n" ) ;
2012-04-26 10:22:30 +00:00
delete $ outhash { $ matchednode } ;
2011-09-14 13:57:31 +00:00
}
2011-06-02 01:59:20 +00:00
}
2012-05-07 07:45:45 +00:00
}
if ( exists ( $ globalopt { I } ) ) {
my % existsnodes ;
2012-05-18 03:07:48 +00:00
my $ nodelisttab = xCAT::Table - > new ( 'nodelist' ) ;
unless ( $ nodelisttab ) {
return ( "Error opening 'nodelisttable'" ) ;
2012-04-26 11:45:50 +00:00
}
2012-05-18 03:07:48 +00:00
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 ;
}
2012-05-07 07:45:45 +00:00
}
2012-05-18 03:07:48 +00:00
}
for my $ enode ( @ nodes ) {
unless ( $ existsnodes { $ enode - > { node } } ) {
$ notdisnode . = $ enode - > { node } . "," ;
2012-05-07 07:45:45 +00:00
}
2012-05-18 03:07:48 +00:00
}
send_msg ( $ request , 0 , "These nodes defined in database but can't be discovered: $notdisnode \n" ) ;
2012-05-07 07:45:45 +00:00
}
2013-03-15 07:46:16 +00:00
foreach my $ no ( keys % outhash ) {
delete $ outhash { $ no } unless ( $ { $ outhash { $ no } } { hostname } ) ;
}
2012-04-26 10:22:30 +00:00
return \ % outhash ;
2009-10-20 13:37:44 +00:00
}
##########################################################################
# Write result to xCat database
##########################################################################
sub xCATdB {
my $ outhash = shift ;
2012-04-26 10:22:30 +00:00
2011-12-21 10:46:17 +00:00
########################################
2012-08-24 07:13:47 +00:00
# Begin to collect attributes for each node
2011-12-21 10:46:17 +00:00
########################################
2012-08-24 07:13:47 +00:00
my % nodelisthash ;
my % ppchash ;
my % vpdhash ;
my % nodehmhash ;
my % nodetypehash ;
my % ppcdirecthash ;
my % hostshash ;
my % machash ;
my % mphash ;
2012-04-26 10:22:30 +00:00
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 ;
2013-08-16 03:10:50 +00:00
my $ groups = lc ( $ type ) . ",all" ;
my $ tmp_pre = xCAT::data::ibmhwtypes:: parse_group ( $ model ) ;
if ( defined ( $ tmp_pre ) ) {
$ groups . = ",$tmp_pre" ;
}
2010-12-07 05:47:07 +00:00
########################################
# Write result to every tables,
2011-01-24 16:11:56 +00:00
########################################
2012-04-26 10:22:30 +00:00
if ( $ type =~ /^bpa|fsp|cec|frame$/ ) {
2013-08-16 03:10:50 +00:00
#$nodelisthash{$hostname} = {groups=>"$type,all", hidden=>$hidden};
$ nodelisthash { $ hostname } = { groups = > $ groups , hidden = > $ hidden } ;
2012-08-24 07:13:47 +00:00
$ 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$/ ) ;
2012-04-26 10:22:30 +00:00
} 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)$/ ) {
2013-08-16 03:10:50 +00:00
$ nodelisthash { $ hostname } = { groups = > $ groups , hidden = > $ hidden } ;
2012-08-24 07:13:47 +00:00
$ 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 } ;
2012-04-26 10:22:30 +00:00
} elsif ( $ type =~ /^cmm$/ ) {
2013-08-16 03:10:50 +00:00
$ nodelisthash { $ hostname } = { groups = > $ groups , hidden = > $ hidden } ;
2013-10-16 09:31:38 +00:00
$ vpdhash { $ hostname } = { mtm = > $ model , serial = > $ serial , side = > $ side } ;
2012-08-24 07:13:47 +00:00
$ nodetypehash { $ hostname } = { nodetype = > $ globalnodetype { $ type } } ;
$ nodehmhash { $ hostname } = { mgt = > "blade" } ;
2013-10-16 09:31:38 +00:00
$ mphash { $ hostname } = { nodetype = > $ globalhwtype { $ type } , mpa = > $ hostname } ;
2012-08-24 07:13:47 +00:00
$ hostshash { $ hostname } = { otherinterfaces = > $ otherif } ;
2011-04-18 08:21:03 +00:00
}
2009-10-20 13:37:44 +00:00
}
2012-08-24 07:13:47 +00:00
########################################
# 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 ) ;
for my $ tab ( keys % dbhash ) {
my $ db = xCAT::Table - > new ( $ tab ) ;
if ( ! $ db ) {
return ( "Error opening $db" ) ;
}
$ db - > setNodesAttribs ( $ dbhash { $ tab } ) ;
$ db - > close ( ) ;
}
2009-10-20 13:37:44 +00:00
}
##########################################################################
2012-04-26 10:22:30 +00:00
# Stanza formatting
2009-10-20 13:37:44 +00:00
##########################################################################
2012-04-26 10:22:30 +00:00
sub format_stanza {
2009-10-20 13:37:44 +00:00
2012-04-26 10:22:30 +00:00
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 ;
2008-10-14 07:07:38 +00:00
}
2012-04-26 10:22:30 +00:00
my $ type = $ { $ outhash - > { $ name } } { type } ;
2013-08-16 03:10:50 +00:00
my $ groups = "$type,all" ;
my $ tmp_pre = xCAT::data::ibmhwtypes:: parse_group ( $ { $ outhash - > { $ name } } { mtm } ) ;
if ( defined ( $ tmp_pre ) ) {
$ groups . = ",$tmp_pre" ;
}
2009-10-20 13:37:44 +00:00
2012-04-26 10:22:30 +00:00
#################################
# Node attributes
#################################
$ result . = "$hostname:\n\tobjtype=node\n" ;
if ( $ type =~ /^cmm$/ ) {
$ result . = "\tmpa=${$outhash->{$name}}{hostname}\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" ;
}
2013-08-16 03:10:50 +00:00
#$result .= "\tgroups=$type,all\n";
$ result . = "\tgroups=$groups\n" ;
2012-04-26 10:22:30 +00:00
$ 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$/ ) {
$ 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" ;
2009-10-20 13:37:44 +00:00
}
2012-04-26 10:22:30 +00:00
$ result . = "\thwtype=$globalhwtype{$type}\n" ;
2008-10-14 07:07:38 +00:00
}
2012-04-26 10:22:30 +00:00
return ( $ result ) ;
2009-10-20 11:31:17 +00:00
}
2008-10-14 07:07:38 +00:00
2009-10-20 13:37:44 +00:00
2012-04-26 10:22:30 +00:00
2009-10-20 13:37:44 +00:00
##########################################################################
2012-04-26 10:22:30 +00:00
# XML formatting
2009-10-20 13:37:44 +00:00
##########################################################################
2012-04-26 10:22:30 +00:00
sub format_xml {
2009-10-20 13:37:44 +00:00
2012-04-26 10:22:30 +00:00
my $ outhash = shift ;
my $ xml ;
2008-06-03 19:09:21 +00:00
2012-04-26 10:22:30 +00:00
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 ) ;
2009-10-20 13:37:44 +00:00
}
2012-04-26 10:22:30 +00:00
return ( $ xml ) ;
}
2009-10-20 13:37:44 +00:00
2012-04-26 10:22:30 +00:00
##########################################################################
# VPD table formatting
##########################################################################
sub format_table {
2009-10-20 13:37:44 +00:00
2012-04-26 10:22:30 +00:00
my $ outhash = shift ;
my $ result ;
2009-10-20 13:37:44 +00:00
2012-04-26 10:22:30 +00:00
#####################################
# Create XML formatted attributes
#####################################
foreach my $ name ( keys %$ outhash ) {
my $ type = $ { $ outhash - > { $ name } } { type } ;
next if ( $ type =~ /^(fsp|bpa)$/ ) ;
$ result . = "${$outhash->{$name}}{hostname}:\n" ;
2012-04-26 11:45:50 +00:00
$ result . = "\tobjtype=node\n" ;
2012-04-26 10:22:30 +00:00
$ result . = "\tmtm=${$outhash->{$name}}{mtm}\n" ;
$ result . = "\tserial=${$outhash->{$name}}{serial}\n" ;
2009-10-20 13:37:44 +00:00
}
2012-04-26 10:22:30 +00:00
return ( $ result ) ;
2009-10-20 13:37:44 +00:00
}
##########################################################################
# 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$/ ) {
2010-03-23 02:57:06 +00:00
my $ result = @$ responses [ 1 ] ;
foreach ( keys %$ result ) {
2012-04-26 10:22:30 +00:00
#$slp_result{$_} = 1;
2009-06-02 09:52:10 +00:00
}
2009-10-20 13:37:44 +00:00
next ;
2009-06-02 09:52:10 +00:00
}
2009-10-20 13:37:44 +00:00
#############################
# Message or verbose trace
#############################
foreach ( @$ responses ) {
$ callback - > ( $ _ ) ;
}
next ;
2008-10-14 07:07:38 +00:00
}
2009-10-20 13:37:44 +00:00
#################################
# Done - close handle
#################################
$ fds - > remove ( $ rfh ) ;
close ( $ rfh ) ;
2009-10-20 11:31:17 +00:00
}
2009-10-20 13:37:44 +00:00
}
#############################################################################
2012-04-26 10:22:30 +00:00
# Preprocess request from xCAT daemon and send request to service nodes
2009-10-20 13:37:44 +00:00
#############################################################################
sub preprocess_request {
my $ req = shift ;
if ( $ req - > { _xcatpreprocessed } - > [ 0 ] == 1 ) { return [ $ req ] ; }
my $ callback = shift ;
my @ requests ;
2009-10-20 11:31:17 +00:00
2009-10-20 13:37:44 +00:00
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 = ( ) ;
2011-02-17 03:14:59 +00:00
#my @all = xCAT::Utils::getAllSN();
#foreach (@all) {
# $sv_hash{$_}=1;
#}
2009-10-20 13:37:44 +00:00
###########################################
# build each request for each service node
###########################################
my @ result = ( ) ;
my $ mncopy = { %$ req } ;
push @ result , $ mncopy ;
2011-02-17 03:14:59 +00:00
#foreach my $sn (keys (%sv_hash)) {
# my $reqcopy = {%$req};
# $reqcopy->{_xcatdest} = $sn;
# $reqcopy->{_xcatpreprocessed}->[0] = 1;
# push @result, $reqcopy;
#}
2009-10-20 13:37:44 +00:00
return \ @ result ;
2009-10-20 11:31:17 +00:00
}
2009-10-20 13:37:44 +00:00
##########################################################################
# Process request from xCat daemon
##########################################################################
sub process_request {
2008-06-03 19:09:21 +00:00
2009-10-20 13:37:44 +00:00
my $ req = shift ;
my $ callback = shift ;
2012-04-26 10:22:30 +00:00
#unless ($macmap) { $macmap = xCAT::MacMap->new(); }
2008-06-03 19:09:21 +00:00
2009-10-20 13:37:44 +00:00
###########################################
# Build hash to pass around
###########################################
my % request ;
$ request { arg } = $ req - > { arg } ;
$ request { callback } = $ callback ;
$ request { command } = $ req - > { command } - > [ 0 ] ;
2008-06-17 17:18:02 +00:00
2009-10-20 13:37:44 +00:00
####################################
# Process command-specific options
####################################
my $ result = parse_args ( \ % request ) ;
2008-11-04 16:55:59 +00:00
2009-10-20 13:37:44 +00:00
####################################
# Return error
####################################
if ( ref ( $ result ) eq 'ARRAY' ) {
send_msg ( \ % request , 1 , @$ result ) ;
return ( 1 ) ;
2008-11-04 16:55:59 +00:00
}
2010-02-05 16:36:16 +00:00
2012-05-18 03:07:48 +00:00
#######################################
# Write header for trace
#######################################
my $ tm = localtime ( time ) ;
my $ msg = "\n-------- $tm\nTime PID" ;
trace ( \ % request , $ msg ) ;
2009-10-20 13:37:44 +00:00
2008-06-03 19:09:21 +00:00
2012-04-26 10:22:30 +00:00
###########################################
# Record begin time
###########################################
2012-05-18 03:07:48 +00:00
my $ start = Time::HiRes:: gettimeofday ( ) ;
2012-04-26 10:22:30 +00:00
############################################
## 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)) {}
2009-12-28 08:10:42 +00:00
2012-08-11 06:56:45 +00:00
my ( $ searchmacsref , $ sendcount , $ rspc ) = invoke_dodiscover ( \ % request ) ;
2009-12-28 08:10:42 +00:00
2012-12-21 09:15:24 +00:00
if ( $ globalopt { flexdiscover } ) {
bt_process ( $ req , $ callback , $ searchmacsref ) ;
return ( SUCCESS ) ;
}
2012-04-26 10:22:30 +00:00
###########################################
# Record ending time
###########################################
2012-05-18 03:07:48 +00:00
my $ elapsed = Time::HiRes:: gettimeofday ( ) - $ start ;
my $ msg2 = sprintf ( "Total SLP Time: %.3f sec\n" , $ elapsed ) ;
trace ( \ % request , $ msg2 ) ;
2012-04-26 10:22:30 +00:00
###########################################
# Combined responses from all children
###########################################
2012-08-11 06:56:45 +00:00
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();
2013-03-15 06:02:37 +00:00
send_msg ( \ % request , 0 , "$sendcount requests with $rspc responses. Now processing responses. This will take $min minutes..." ) unless ( $ globalopt { x } or $ globalopt { z } ) ;
2012-07-23 07:40:51 +00:00
format_output ( \ % request , $ searchmacsref ) ;
2012-08-11 06:56:45 +00:00
#my $elapsed1 = Time::HiRes::gettimeofday() - $start1;
#send_msg( \%request, 0, "$num nodes takes $elapsed1");
2012-04-26 10:22:30 +00:00
return ( SUCCESS ) ;
2009-12-28 08:10:42 +00:00
}
2011-06-02 01:59:20 +00:00
2012-04-26 10:22:30 +00:00
2011-03-04 01:54:43 +00:00
##########################################################################
# Filter nodes the user specified
##########################################################################
sub filter {
my $ oldhash = shift ;
my $ newhash ;
2011-03-23 01:05:13 +00:00
# find HMC/CEC/Frame that the user want to find
2011-03-21 09:25:16 +00:00
foreach my $ n ( @ filternodes ) {
2011-03-23 01:05:13 +00:00
for my $ foundnode ( keys %$ oldhash ) {
2012-04-26 10:22:30 +00:00
if ( $ { $ oldhash - > { $ foundnode } } { hostname } =~ /^(\w+)\(.*\)/ ) {
2011-03-23 01:05:13 +00:00
if ( $ 1 eq $ n ) {
$ newhash - > { $ foundnode } = $ oldhash - > { $ foundnode } ;
2012-05-07 07:45:45 +00:00
if ( $ { $ oldhash - > { $ foundnode } } { type } eq TYPE_CEC or $ { $ oldhash - > { $ foundnode } } { type } eq TYPE_FRAME ) {
my @ ips = split /,/ , $ { $ oldhash - > { $ foundnode } } { children } ;
2012-05-30 08:56:43 +00:00
for ( my $ i = 0 ; $ i < scalar ( @ ips ) ; $ i + + ) {
$ newhash - > { $ ips [ $ i ] } = $ oldhash - > { $ ips [ $ i ] } ;
}
2012-05-07 07:45:45 +00:00
}
2011-03-23 01:05:13 +00:00
}
2012-04-26 10:22:30 +00:00
} elsif ( $ { $ oldhash - > { $ foundnode } } { hostname } eq $ n ) {
2011-03-21 09:25:16 +00:00
$ newhash - > { $ foundnode } = $ oldhash - > { $ foundnode } ;
2012-05-07 07:45:45 +00:00
if ( $ { $ oldhash - > { $ foundnode } } { type } eq TYPE_CEC or $ { $ oldhash - > { $ foundnode } } { type } eq TYPE_FRAME ) {
my @ ips = split /,/ , $ { $ oldhash - > { $ foundnode } } { children } ;
2012-05-30 08:56:43 +00:00
for ( my $ i = 0 ; $ i < scalar ( @ ips ) ; $ i + + ) {
$ newhash - > { $ ips [ $ i ] } = $ oldhash - > { $ ips [ $ i ] } ;
}
2012-05-07 07:45:45 +00:00
}
2011-03-04 01:54:43 +00:00
}
2011-06-02 01:59:20 +00:00
}
2011-03-23 01:05:13 +00:00
}
2011-06-02 01:59:20 +00:00
return $ newhash ;
2011-03-04 01:54:43 +00:00
}
2011-06-30 02:36:39 +00:00
##########################################################################
# Filter nodes not in the user specified vlan
##########################################################################
sub filtersamevlan {
my $ oldhash = shift ;
my $ newhash ;
2012-08-09 04:07:40 +00:00
my $ nets = xCAT::NetworkUtils:: my_nets ( ) ;
2011-06-30 02:36:39 +00:00
my $ validnets ;
for my $ net ( keys %$ nets ) {
2012-05-03 06:36:27 +00:00
for my $ nic ( split /,/ , $ globalopt { i } ) {
2011-06-30 02:36:39 +00:00
if ( $ nets - > { $ net } eq $ nic ) {
$ validnets - > { $ net } = $ nic ;
}
}
2012-04-26 10:22:30 +00:00
}
2011-06-30 02:36:39 +00:00
foreach my $ name ( keys %$ oldhash ) {
2012-08-11 06:23:35 +00:00
if ( $ { $ oldhash - > { $ name } } { type } =~ /^(fsp|bpa)$/ ) {
my $ ip = $ { $ oldhash - > { $ name } } { ip } ;
2011-06-30 02:36:39 +00:00
for my $ net ( keys %$ validnets ) {
my ( $ n , $ m ) = split /\// , $ net ;
2012-08-14 11:55:48 +00:00
if ( xCAT::NetworkUtils:: isInSameSubnet ( $ n , $ ip , $ m , 1 ) ) { #and xCAT::NetworkUtils::isPingable( $ip)) {
2012-08-11 06:23:35 +00:00
$ newhash - > { $ name } = $ oldhash - > { $ name } ;
2011-06-30 02:36:39 +00:00
}
}
} else {
$ newhash - > { $ name } = $ oldhash - > { $ name } ;
}
}
return $ newhash ;
}
2012-12-21 09:15:24 +00:00
##########################################################################
# 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 ] ;
2013-06-18 17:07:46 +00:00
if ( defined $ immdata - > { attributes } - > { 'chassis-sub-slot' } ) {
$ slot . = ":" . $ immdata - > { attributes } - > { 'chassis-sub-slot' } - > [ 0 ] ;
}
2012-12-21 09:15:24 +00:00
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 ;
}
2012-07-23 07:40:51 +00:00
1 ;
2013-10-28 14:27:29 +00:00