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 ) ;
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 ;
2009-10-20 13:37:44 +00:00
require xCAT::MacMap ;
require xCAT_plugin::blade ;
#######################################
# Constants
#######################################
use constant {
HARDWARE_SERVICE = > "service:management-hardware.IBM" ,
SOFTWARE_SERVICE = > "service:management-software.IBM" ,
WILDCARD_SERVICE = > "service:management-*" ,
P6_SERVICE = > "service:management-hardware.IBM" ,
2011-03-20 10:22:01 +00:00
P7_SERVICE = > "service:management-software.IBM" ,
2009-10-20 13:37:44 +00:00
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" ,
2009-10-20 13:37:44 +00:00
SERVICE_RSA = > "remote-supervisor-adapter" ,
SERVICE_RSA2 = > "remote-supervisor-adapter-2" ,
SLP_CONF = > "/usr/local/etc/slp.conf" ,
SLPTOOL = > "/usr/local/bin/slptool" ,
TYPE_MM = > "MM" ,
2011-12-21 02:25:14 +00:00
TYPE_CMM = > "CMM" ,
2009-10-20 13:37:44 +00:00
TYPE_RSA = > "RSA" ,
TYPE_BPA = > "BPA" ,
TYPE_HMC = > "HMC" ,
TYPE_IVM = > "IVM" ,
TYPE_FSP = > "FSP" ,
2010-12-07 05:47:07 +00:00
TYPE_CEC = > "CEC" ,
2010-12-29 10:32:22 +00:00
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 ,
RC_ERROR = > 1
} ;
#######################################
# 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 ,
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" ]
) ;
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 ,
) ;
2010-12-07 05:47:07 +00:00
########################################
## Hardware specific SLP attributes
########################################
#my %exattr = (
# @{[ SERVICE_FSP ]} => [
# "bpc-machinetype-model",
# "bpc-serial-number",
# "cage-number"
# ],
# @{[ SERVICE_BPA ]} => [
# "frame-number"
# ]
#);
2009-10-20 13:37:44 +00:00
#######################################
# Power methods
#######################################
my % mgt = (
2010-12-07 05:47:07 +00:00
lc ( TYPE_FSP ) = > "fsp" ,
lc ( TYPE_BPA ) = > "bpa" ,
lc ( TYPE_CEC ) = > "cec" ,
2011-01-24 16:11:56 +00:00
lc ( TYPE_FRAME ) = > "frame" ,
2010-12-07 05:47:07 +00:00
lc ( TYPE_MM ) = > "blade" ,
lc ( TYPE_HMC ) = > "hmc" ,
lc ( TYPE_IVM ) = > "ivm" ,
2011-12-21 02:25:14 +00:00
lc ( TYPE_RSA ) = > "blade" ,
lc ( TYPE_CMM ) = > "blade" ,
2009-10-20 13:37:44 +00:00
) ;
2011-07-15 09:10:54 +00:00
my @ attribs = qw( nodetype mtm serial side ip groups mgt id parent mac hidden otherinterfaces hwtype ) ;
2009-10-20 13:37:44 +00:00
my $ verbose = 0 ;
my % ip_addr = ( ) ;
my % slp_result = ( ) ;
my % rsp_result = ( ) ;
my % opt = ( ) ;
my $ maxtries = 1 ;
my $ openSLP = 1 ;
my @ converge ;
my $ macmap ;
2010-12-29 10:32:22 +00:00
my $ expect_ent = 0 ;
my $ time_out = 300 ;
2011-01-24 16:11:56 +00:00
my $ enter_time = 0 ;
2011-03-04 01:54:43 +00:00
my @ filternodes ;
2011-04-18 08:21:03 +00:00
my % otherinterfacehash ;
2011-05-24 09:27:41 +00:00
my $ TRACE = 0 ;
2011-09-14 13:57:31 +00:00
my $ DEBUG_MATCH = 0 ;
2011-07-15 09:10:54 +00:00
my % globlehwtype = (
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 ,
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 ,
2011-12-21 02:25:14 +00:00
lpar = > "$::NODETYPE_PPC,$::NODETYPE_OSI"
2011-07-15 09:23:56 +00:00
) ;
2009-10-20 13:37:44 +00:00
##########################################################################
# Command handler method from tables
##########################################################################
sub handled_commands {
$ macmap = xCAT::MacMap - > new ( ) ;
return ( { lsslp = > "lsslp" } ) ;
2008-06-03 19:09:21 +00:00
}
2009-10-20 11:31:17 +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 ;
my % output ;
#################################################
# Called from child process - send to parent
#################################################
if ( exists ( $ request - > { pipe } ) ) {
my $ out = $ request - > { pipe } ;
$ output { errorcode } = $ ecode ;
$ output { data } = \ @ _ ;
print $ out freeze ( [ \ % output ] ) ;
print $ out "\nENDOFFREEZE6sK4ci\n" ;
}
#################################################
# Called from parent - invoke callback directly
#################################################
elsif ( exists ( $ request - > { callback } ) ) {
my $ callback = $ request - > { callback } ;
$ output { errorcode } = $ ecode ;
$ output { data } = \ @ _ ;
$ callback - > ( \ % output ) ;
}
}
##########################################################################
# Parse the command line options and operands
##########################################################################
sub parse_args {
my $ request = shift ;
my $ args = $ request - > { arg } ;
my $ cmd = $ request - > { command } ;
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 ,
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 ,
2011-01-27 08:40:33 +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 updatehosts makedhcp resetnet vpdtable ) ) ) {
2009-10-20 13:37:44 +00:00
return ( usage ( ) ) ;
}
2011-06-15 15:42:33 +00:00
####################################
# Check for an extra argument
####################################
2011-08-03 10:04:51 +00:00
#if ( defined( $ARGV[0] )) {
# return(usage( "Invalid Argument: $ARGV[0]" ));
#}
2010-02-08 15:56:18 +00:00
2011-01-24 16:11:56 +00:00
2009-10-20 13:37:44 +00:00
#############################################
# Check for switch "-" with no option
#############################################
2011-03-21 09:25:16 +00:00
#if ( grep(/^-$/, @ARGV )) {
# return(usage( "Missing option: -" ));
#}
#############################################
# 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
#############################################
# Set convergence
#############################################
if ( exists ( $ opt { c } ) ) {
#################################
# Use values set in slp.conf
#################################
if ( ! defined ( $ ARGV [ 0 ] ) ) {
@ converge = ( 0 ) ;
}
#################################
# Use new values
#################################
else {
@ converge = split /,/ , $ ARGV [ 0 ] ;
if ( scalar ( @ converge ) > 5 ) {
return ( usage ( "Convergence timeouts limited to 5 maximum" ) ) ;
2008-11-04 16:55:59 +00:00
}
2009-10-20 13:37:44 +00:00
foreach ( @ converge ) {
unless ( /^[1-9]{1}$|^[1-9]{1}[0-9]{1,4}$/ ) {
return ( usage ( "Invalid convergence timeout: $_" ) ) ;
2008-09-10 15:44:45 +00:00
}
2009-10-20 13:37:44 +00:00
}
}
}
#############################################
# Check for an argument
#############################################
2010-12-29 10:32:22 +00:00
#elsif ( defined( $ARGV[0] )) {
# return(usage( "Invalid Argument: $ARGV[0]" ));
#}
2009-10-20 13:37:44 +00:00
#############################################
# Option -V for verbose output
#############################################
if ( exists ( $ opt { V } ) ) {
$ verbose = 1 ;
}
#############################################
# 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 } ) ) {
$ maxtries = $ opt { t } ;
if ( $ maxtries !~ /^0?[1-9]$/ ) {
return ( usage ( "Invalid command tries (1-9)" ) ) ;
}
}
#############################################
# Select SLP command
#############################################
if ( exists ( $ opt { e } ) ) {
if ( $ opt { e } !~ /slptool/ ) {
$ openSLP = 0 ;
}
}
#############################################
# Check for unsupported service type
#############################################
if ( exists ( $ opt { s } ) ) {
if ( ! exists ( $ services { $ opt { s } } ) ) {
return ( usage ( "Invalid service: $opt{s}" ) ) ;
}
$ request - > { service } = $ services { $ opt { s } } ;
}
2010-02-04 08:12:33 +00:00
#############################################
# Check the dependency of makedhcp option
#############################################
if ( exists ( $ opt { makedhcp } ) and ! exists ( $ opt { w } ) ) {
return ( usage ( "'makedhcp' should work with '-w' option" ) ) ;
}
#############################################
# Check the validation of -M option
2011-01-24 16:11:56 +00:00
#############################################
2010-12-07 05:47:07 +00:00
#if ( exists( $opt{M} ) and ($opt{M} !~ /^vpd$/) and ($opt{M} !~ /^switchport$/) ) {
# return( usage("Invalid value for '-M' option. Acceptable value is 'vpd' or 'switchport'") );
#}
2010-02-04 08:12:33 +00:00
2010-12-29 10:32:22 +00:00
#############################################
# Check the validation of -T option
#############################################
if ( exists ( $ opt { T } ) ) {
$ time_out = $ opt { T } ;
if ( $ time_out !~ /^\d+$/ ) {
return ( usage ( "Invalid timeout value, should be number" ) ) ;
2011-01-24 16:11:56 +00:00
}
2010-12-29 10:32:22 +00:00
if ( ! exists ( $ opt { C } ) ) {
return ( usage ( "-T should be used with -C" ) ) ;
}
}
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 } ) ) {
$ expect_ent = $ opt { C } ;
2011-01-24 16:11:56 +00:00
2010-12-29 10:32:22 +00:00
if ( $ expect_ent !~ /^\d+$/ ) {
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
}
2009-10-20 13:37:44 +00:00
return ( 0 ) ;
}
##########################################################################
# Validate comma-seperated list of IPs
##########################################################################
sub validate_ip {
my $ request = shift ;
###########################################
# Option -i not specified (no IPs specified)
###########################################
if ( ! exists ( $ opt { i } ) ) {
#######################################
# Determine interfaces
#######################################
my $ ips = $ openSLP ?
slptool_ifconfig ( $ request ) : slpquery_ifconfig ( $ request ) ;
#######################################
# Command failed
#######################################
if ( @$ ips [ 0 ] ) {
return ( $ ips ) ;
}
return ( [ 0 ] ) ;
}
###########################################
# Option -i specified - validate entries
###########################################
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 ( [ 1 , "Invalid IP address: $ip" ] ) ;
}
}
$ ip_addr { $ ip } = 1 ;
}
return ( [ 0 ] ) ;
}
##########################################################################
# 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 {
2011-05-24 09:27:41 +00:00
if ( $ verbose ) {
my ( $ sec , $ min , $ hour , $ mday , $ mon , $ yr , $ wday , $ yday , $ dst ) = localtime ( time ) ;
my $ msg = sprintf "%02d:%02d:%02d %5d %s" , $ hour , $ min , $ sec , $$ , $ msg ;
send_msg ( $ request , 0 , $ msg ) ;
}
2011-06-02 01:59:20 +00:00
}
2009-10-20 13:37:44 +00:00
}
##########################################################################
# Determine adapters available - slptool always uses adapter IP
##########################################################################
sub slptool_ifconfig {
my $ request = shift ;
my $ cmd = "ifconfig -a" ;
my $ result = `$cmd` ;
my $ mode = "MULTICAST" ;
#############################################
# Display broadcast IPs, but use adapter IP
#############################################
if ( ! exists ( $ opt { m } ) ) {
$ mode = "BROADCAST" ;
}
#############################################
# Error running command
#############################################
if ( ! $ result ) {
return ( [ 1 , "Error running '$cmd': $!" ] ) ;
}
if ( $ verbose ) {
trace ( $ request , $ cmd ) ;
trace ( $ request , "$mode Interfaces:" ) ;
}
if ( xCAT::Utils - > isAIX ( ) ) {
##############################################################
# Should look like this for AIX:
# en0: flags=4e080863,80<UP,BROADCAST,NOTRAILERS,RUNNING,
# SIMPLEX,MULTICAST,GROUPRT,64BIT,PSEG,CHAIN>
# inet 30.0.0.1 netmask 0xffffff00 broadcast 30.0.0.255
# inet 192.168.2.1 netmask 0xffffff00 broadcast 192.168.2.255
# en1: ...
#
##############################################################
my @ adapter = split /\w+\d+:\s+flags=/ , $ result ;
foreach ( @ adapter ) {
if ( ! ( $ _ =~ /LOOPBACK/ ) and
$ _ =~ /UP(,|>)/ and
$ _ =~ /$mode/ ) {
my @ ip = split /\n/ ;
foreach ( @ ip ) {
if ( $ mode eq "BROADCAST" ) {
if ( $ _ =~ /^\s*inet\s+/ and
$ _ =~ /broadcast\s+(\d+\.\d+\.\d+\.\d+)/ ) {
if ( $ verbose ) {
trace ( $ request , "\t\t$1\tUP,$mode" ) ;
}
}
}
if ( $ _ =~ /^\s*inet\s*(\d+\.\d+\.\d+\.\d+)/ ) {
$ ip_addr { $ 1 } = 1 ;
if ( exists ( $ opt { m } ) ) {
trace ( $ request , "\t\t$1\tUP,$mode" ) ;
}
}
2008-06-03 19:09:21 +00:00
}
}
}
}
2009-10-20 13:37:44 +00:00
else {
##############################################################
# Should look like this for Linux:
# eth0 Link encap:Ethernet HWaddr 00:02:55:7B:06:30
# inet addr:9.114.154.193 Bcast:9.114.154.223
# inet6 addr: fe80::202:55ff:fe7b:630/64 Scope:Link
# UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
# RX packets:1280982 errors:0 dropped:0 overruns:0 frame:0
# TX packets:3535776 errors:0 dropped:0 overruns:0 carrier:0
# collisions:0 txqueuelen:1000
# RX bytes:343489371 (327.5 MiB) TX bytes:870969610 (830.6 MiB)
# Base address:0x2600 Memory:fbfe0000-fc0000080
#
# eth1 ...
#
##############################################################
my @ adapter = split /\n{2,}/ , $ result ;
foreach ( @ adapter ) {
if ( ! ( $ _ =~ /LOOPBACK / ) and
$ _ =~ /UP / and
$ _ =~ /$mode / ) {
my @ ip = split /\n/ ;
foreach ( @ ip ) {
if ( $ mode eq "BROADCAST" ) {
if ( $ _ =~ /^\s*inet addr:/ and
$ _ =~ /Bcast:(\d+\.\d+\.\d+\.\d+)/ ) {
if ( $ verbose ) {
trace ( $ request , "\t\t$1\tUP,$mode" ) ;
}
}
}
if ( $ _ =~ /^\s*inet addr:\s*(\d+\.\d+\.\d+\.\d+)/ ) {
$ ip_addr { $ 1 } = 1 ;
if ( exists ( $ opt { m } ) ) {
trace ( $ request , "\t\t$1\tUP,$mode" ) ;
}
}
}
}
}
}
if ( ( keys % ip_addr ) == 0 ) {
return ( [ 1 , "No adapters configured for $mode" ] ) ;
}
#########################
# Log results
#########################
if ( $ verbose ) {
if ( ( keys % ip_addr ) == 0 ) {
trace ( $ request , "$cmd\n$result" ) ;
}
2008-06-03 19:09:21 +00:00
}
2009-10-20 13:37:44 +00:00
return ( [ 0 ] ) ;
2008-06-03 19:09:21 +00:00
}
2009-10-20 13:37:44 +00:00
##########################################################################
# Determine adapters available - slp_query always used broadcast IP
##########################################################################
sub slpquery_ifconfig {
my $ request = shift ;
my $ cmd = "ifconfig -a" ;
my $ result = `$cmd` ;
my $ mode = "BROADCAST" ;
######################################
# Error running command
######################################
if ( ! $ result ) {
return ( [ 1 , "Error running '$cmd': $!" ] ) ;
}
if ( $ verbose ) {
trace ( $ request , $ cmd ) ;
trace ( $ request , "$mode Interfaces:" ) ;
}
if ( xCAT::Utils - > isAIX ( ) ) {
##############################################################
# Should look like this for AIX:
# en0: flags=4e080863,80<UP,BROADCAST,NOTRAILERS,RUNNING,
# SIMPLEX,MULTICAST,GROUPRT,64BIT,PSEG,CHAIN>
# inet 30.0.0.1 netmask 0xffffff00 broadcast 30.0.0.255
# inet 192.168.2.1 netmask 0xffffff00 broadcast 192.168.2.255
# en1: ...
#
##############################################################
my @ adapter = split /\w+\d+:\s+flags=/ , $ result ;
foreach ( @ adapter ) {
if ( ! ( $ _ =~ /LOOPBACK/ ) and
$ _ =~ /UP(,|>)/ and
$ _ =~ /$mode/ ) {
my @ ip = split /\n/ ;
foreach ( @ ip ) {
if ( $ _ =~ /^\s*inet\s+/ and
$ _ =~ /broadcast\s+(\d+\.\d+\.\d+\.\d+)/ ) {
$ ip_addr { $ 1 } = 1 ;
}
}
2009-07-20 18:46:13 +00:00
}
}
2009-10-20 13:37:44 +00:00
}
else {
##############################################################
# Should look like this for Linux:
# eth0 Link encap:Ethernet HWaddr 00:02:55:7B:06:30
# inet addr:9.114.154.193 Bcast:9.114.154.223
# inet6 addr: fe80::202:55ff:fe7b:630/64 Scope:Link
# UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
# RX packets:1280982 errors:0 dropped:0 overruns:0 frame:0
# TX packets:3535776 errors:0 dropped:0 overruns:0 carrier:0
# collisions:0 txqueuelen:1000
# RX bytes:343489371 (327.5 MiB) TX bytes:870969610 (830.6 MiB)
# Base address:0x2600 Memory:fbfe0000-fc0000080
#
# eth1 ...
#
##############################################################
my @ adapter = split /\n{2,}/ , $ result ;
foreach ( @ adapter ) {
if ( ! ( $ _ =~ /LOOPBACK / ) and
$ _ =~ /UP / and
$ _ =~ /$mode / ) {
my @ ip = split /\n/ ;
foreach ( @ ip ) {
if ( $ _ =~ /^\s*inet addr:/ and
$ _ =~ /Bcast:(\d+\.\d+\.\d+\.\d+)/ ) {
$ ip_addr { $ 1 } = 1 ;
}
}
}
}
}
if ( ( keys % ip_addr ) == 0 ) {
return ( [ 1 , "No adapters configured for $mode" ] ) ;
}
#########################
# Log results
#########################
if ( $ verbose ) {
foreach ( keys % ip_addr ) {
trace ( $ request , "\t\t$_\tUP,BROADCAST" ) ;
}
if ( ( keys % ip_addr ) == 0 ) {
trace ( $ request , "$cmd\n$result" ) ;
}
}
return ( [ 0 ] ) ;
}
##########################################################################
# Forks a process to run the slp command (1 per adapter)
##########################################################################
sub fork_cmd {
my $ request = shift ;
my $ ip = shift ;
my $ arg = shift ;
my $ services = 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 ;
invoke_cmd ( $ request , $ ip , $ arg , $ services ) ;
exit ( 0 ) ;
}
else {
###################################
# Parent process
###################################
close ( $ child ) ;
return ( $ parent ) ;
}
return ( 0 ) ;
}
##########################################################################
# Run the forked command and send reply to parent
##########################################################################
sub invoke_cmd {
my $ request = shift ;
my $ ip = shift ;
my $ args = shift ;
my $ services = shift ;
########################################
# Telnet (rspconfig) command
########################################
if ( ! defined ( $ services ) ) {
my $ target_dev = $ args - > { $ ip } ;
my @ cmds ;
my $ result ;
if ( $ verbose ) {
trace ( $ request , "Forked: ($ip)->($target_dev->{args})" ) ;
}
2010-02-05 16:36:16 +00:00
if ( $ target_dev - > { 'type' } eq 'mm' )
2009-10-20 13:37:44 +00:00
{
@ cmds = (
"snmpcfg=enable" ,
"sshcfg=enable" ,
"network_reset=$target_dev->{args}"
) ;
$ result = xCAT_plugin::blade:: telnetcmds (
$ ip ,
$ target_dev - > { username } ,
$ target_dev - > { password } ,
0 ,
@ cmds ) ;
}
2010-02-05 16:36:16 +00:00
elsif ( $ target_dev - > { 'type' } eq 'hmc' )
2009-10-20 13:37:44 +00:00
{
@ cmds = ( "network_reset=$target_dev->{args}" ) ;
trace ( $ request , "sshcmds on hmc $ip" ) ;
$ result = xCAT::PPC:: sshcmds_on_hmc (
$ ip ,
$ target_dev - > { username } ,
$ target_dev - > { password } ,
@ cmds ) ;
2010-02-05 16:36:16 +00:00
}
2009-10-20 13:37:44 +00:00
else #The rest must be fsp or bpa
2009-10-20 11:31:17 +00:00
{
2009-10-20 13:37:44 +00:00
@ cmds = ( "network=$ip,$target_dev->{args}" ) ;
trace ( $ request , "update config on $target_dev->{'type'} $ip" ) ;
$ result = xCAT::PPC:: updconf_in_asm (
$ ip ,
$ target_dev ,
@ cmds ) ;
2009-07-27 16:59:24 +00:00
}
2010-02-04 08:12:33 +00:00
2009-10-20 13:37:44 +00:00
####################################
# Pass result array back to parent
####################################
my @ data = ( "RSPCONFIG6sK4ci" , $ ip , @$ result [ 0 ] , @$ result [ 2 ] ) ;
my $ out = $ request - > { pipe } ;
2009-07-27 16:59:24 +00:00
2009-10-20 13:37:44 +00:00
print $ out freeze ( \ @ data ) ;
print $ out "\nENDOFFREEZE6sK4ci\n" ;
return ;
2009-07-23 20:02:39 +00:00
}
2009-10-20 13:37:44 +00:00
########################################
# SLP command
########################################
my $ result = runslp ( $ args , $ ip , $ services , $ request ) ;
my $ unicast = @$ result [ 0 ] ;
my $ values = @$ result [ 1 ] ;
2010-12-29 10:32:22 +00:00
#prt_result( $request, $values);
2009-10-20 13:37:44 +00:00
########################################
# May have to send additional unicasts
########################################
if ( keys ( %$ unicast ) ) {
foreach my $ url ( keys %$ unicast ) {
my ( $ service , $ addr ) = split "://" , $ url ;
2009-10-22 09:55:42 +00:00
next if ( $ addr =~ /:/ ) ; #skip IPV6
2009-10-20 13:37:44 +00:00
####################################
# Strip off trailing ",lifetime"
####################################
$ addr =~ s/,*\d*$// ;
my $ sockaddr = inet_aton ( $ addr ) ;
$ url =~ s/,*\d*$// ;
####################################
# Make sure can resolve if hostname
####################################
if ( ! defined ( $ sockaddr ) ) {
if ( $ verbose ) {
trace ( $ request , "Cannot convert '$addr' to dot-notation" ) ;
}
next ;
}
$ addr = inet_ntoa ( $ sockaddr ) ;
####################################
# Select command format
####################################
if ( $ openSLP ) {
$ result = runslp ( $ args , $ ip , [ $ url ] , $ request , 1 ) ;
} else {
$ result = runslp ( $ args , $ addr , [ $ service ] , $ request , 1 ) ;
}
my $ data = @$ result [ 1 ] ;
my ( $ attr ) = keys %$ data ;
####################################
# Save results
####################################
if ( defined ( $ attr ) ) {
$ values - > { "URL: $url\n$attr\n" } = 1 ;
prt_result ( $ values ) ;
}
}
2009-07-23 20:02:39 +00:00
}
2009-10-20 13:37:44 +00:00
########################################
2010-12-29 10:32:22 +00:00
# Need to check if the result is enough
########################################
if ( exists ( $ opt { C } ) ) {
2011-01-27 08:40:33 +00:00
send_msg ( $ request , 0 , "\n Begin to try again, this may takes long time \n" ) ;
2010-12-29 10:32:22 +00:00
#my $uni_tmp = $unicast;
2011-01-24 16:11:56 +00:00
my % val_tmp = %$ values ;
2011-03-17 09:39:31 +00:00
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 ;
}
}
2010-12-29 10:32:22 +00:00
my $ rlt ;
my $ val ;
2011-01-24 16:11:56 +00:00
my $ start_time = Time::HiRes:: gettimeofday ( ) ;
2010-12-29 10:32:22 +00:00
my $ elapse ;
2011-03-17 09:39:31 +00:00
my $ found = scalar ( keys % found_cec ) ;
2010-12-29 10:32:22 +00:00
while ( $ found < $ expect_ent ) {
$ rlt = runslp ( $ args , $ ip , $ services , $ request ) ;
$ val = @$ rlt [ 1 ] ;
for my $ v ( keys %$ val ) {
2011-03-17 09:39:31 +00:00
$ v =~ /type=([^\)]+)\)\,\(serial-number=([^\)]+)\)\,\(machinetype-model=([^\)]+)\)\,/ ;
if ( $ found_cec { $ 2 . '*' . $ 3 } ne 1 and $ 1 eq SERVICE_FSP ) {
$ found_cec { $ 2 . '*' . $ 3 } = 1 ;
2010-12-29 10:32:22 +00:00
$ val_tmp { $ v } = 1 ;
}
}
$ found = scalar ( keys % val_tmp ) ;
$ elapse = Time::HiRes:: gettimeofday ( ) - $ start_time ;
if ( $ elapse > $ time_out ) {
send_msg ( $ request , 0 , "Time out, Force return.\n" ) ;
last ;
}
}
send_msg ( $ request , 0 , "Discovered $found nodes \n" ) ;
$ values = \ % val_tmp ;
#my @re = [$uni_tmp, \%val_tmp];
#$result = \@re;
2011-01-24 16:11:56 +00:00
}
2010-12-29 10:32:22 +00:00
prt_result ( $ request , $ values ) ;
########################################
2009-10-20 13:37:44 +00:00
# No valid responses received
########################################
if ( ( keys ( %$ values ) ) == 0 ) {
2009-10-20 11:31:17 +00:00
return ;
2009-07-23 20:02:39 +00:00
}
2009-10-20 13:37:44 +00:00
########################################
# Pass result array back to parent
########################################
my @ results = ( "FORMATDATA6sK4ci" , $ values ) ;
my $ out = $ request - > { pipe } ;
print $ out freeze ( \ @ results ) ;
print $ out "\nENDOFFREEZE6sK4ci\n" ;
}
#########################################################
# print the slp result
#########################################################
sub prt_result
{
my $ request = shift ;
my $ values = shift ;
my $ nets = xCAT::Utils:: my_nets ( ) ;
for my $ v ( keys %$ values )
2009-10-20 11:31:17 +00:00
{
2011-03-23 07:56:21 +00:00
# remove the process of finding ping-able ip to save time.
2011-02-24 09:22:12 +00:00
#if ( $v =~ /ip-address=([^\)]+)/g)
if ( $ v =~ /.*URL: .*\:\/\/(\d+\.\d+\.\d+\.\d+)/ )
2009-10-20 13:37:44 +00:00
{
2011-02-24 09:22:12 +00:00
#my $iplist = $1;
#my $ip = getip_from_iplist( $iplist, $nets, $opt{i});
my $ ip = $ 1 ;
2009-10-20 13:37:44 +00:00
if ( $ ip )
{
2011-01-24 16:11:56 +00:00
#send_msg($request, "Received SLP response from $ip.");
#print "Received SLP response from $ip.\n";
2009-10-20 13:37:44 +00:00
xCAT::MsgUtils - > message ( "I" , "Received SLP response from $ip." , $ ::callback ) ;
}
}
}
}
##########################################################################
# Run the SLP command, process the response, and send to parent
##########################################################################
sub runslp {
my $ slpcmd = shift ;
my $ ip = shift ;
my $ services = shift ;
my $ request = shift ;
my $ attreq = shift ;
my % result = ( ) ;
my % unicast = ( ) ;
my $ cmd ;
foreach my $ type ( @$ services ) {
my $ try = 0 ;
###########################################
# OpenSLP - slptool command
###########################################
if ( $ openSLP ) {
$ cmd = $ attreq ?
"$slpcmd findattrsusingiflist $ip $type" :
"$slpcmd findsrvsusingiflist $ip $type" ;
}
###########################################
# IBM SLP - slp_query command
###########################################
else {
$ cmd = $ attreq ?
"$slpcmd --address=$ip --type=$type" :
"$slpcmd --address=$ip --type=$type --converge=1" ;
}
###########################################
# Run the command
###########################################
while ( $ try + + < $ maxtries ) {
if ( $ verbose ) {
trace ( $ request , $ cmd ) ;
trace ( $ request , "Attempt $try of $maxtries\t( $ip\t$type )" ) ;
}
#######################################
# Serialize transmits out each adapter
#######################################
if ( ! open ( OUTPUT , "$cmd 2>&1 |" ) ) {
send_msg ( $ request , 1 , "Fork error: $!" ) ;
return undef ;
}
###############################
# Get command output
###############################
my $ rsp ;
while ( <OUTPUT> ) {
$ rsp . = $ _ ;
}
close OUTPUT ;
###############################
# No replies
###############################
if ( ! $ rsp ) {
if ( $ verbose ) {
trace ( $ request , ">>>>>> No Response" ) ;
}
next ;
}
###########################################
# For IVM, running AIX 53J (6/07) release,
# there is an AIX SLP bug where IVM will
# respond to SLP service-requests with its
# URL only and not its attributes. An SLP
# unicast to the URL address is necessary
# to acquire the attributes. This was fixed
# in AIX 53L (11/07).
#
###########################################
###########################################
# OpenSLP response format:
# service:management-software.IBM...
# (type=hardware-management-cons...
# (serial-number=KPHHK24),(name=c76v2h...
# 1ab1dd89ca8e0763e),(ip-address=192.1...
# 0CR3*KPHHK24),(web-management-interf...
# 2.ppd.pok.ibm.com:8443),(cimom-port=...
# ...
###########################################
if ( $ openSLP ) {
my @ data = split /\n/ , $ rsp ;
my $ length = scalar ( @ data ) ;
my $ i = 0 ;
while ( $ i < $ length ) {
###################################
# Service-Request response
###################################
if ( $ data [ $ i ] =~
/^service\:management-(software|hardware)\.IBM\:([^\:]+)/ ) {
###############################
# Invalid service-type
###############################
if ( ! exists ( $ service_slp { $ 2 } ) ) {
if ( $ verbose ) {
trace ( $ request , "DISCARDING: $data[$i]" ) ;
}
$ i + + ;
next ;
}
my $ url = $ data [ $ i + + ] ;
my $ attr = $ data [ $ i ] ;
#Give some intermediate output
my ( $ url_ip ) = $ url =~ /:\/\/(\d+\.\d+\.\d+\.\d+)/ ;
if ( ! $ ::DISCOVERED_HOST { $ url_ip } )
{
$ ::DISCOVERED_HOST { $ url_ip } = 1 ;
}
if ( $ verbose ) {
trace ( $ request , ">>>> SrvRqst Response" ) ;
trace ( $ request , "URL: $url" ) ;
}
###############################
# No "ATTR" - have to unicast
###############################
if ( $ attr !~ /^(\(type=.*)$/ ) {
$ unicast { $ url } = $ url ;
}
###############################
# Response has "ATTR" field
###############################
else {
if ( $ verbose ) {
trace ( $ request , "ATTR: $attr\n" ) ;
}
my $ val = "URL: $url\nATTR: $attr" ;
$ result { $ val } = 1 ;
$ i + + ;
}
2009-10-20 11:31:17 +00:00
}
2009-10-20 13:37:44 +00:00
###################################
# Attribute-Request response
###################################
elsif ( $ data [ $ i ] =~ /(\(type=.*)$/ ) {
my $ attr = "ATTR: $data[$i++]" ;
if ( $ verbose ) {
trace ( $ request , ">>>> AttrRqst Response" ) ;
trace ( $ request , $ attr ) ;
}
$ result { $ attr } = 1 ;
}
###################################
# Unrecognized response
###################################
else {
if ( $ verbose ) {
trace ( $ request , "DISCARDING: $data[$i]" ) ;
}
$ i + + ;
}
}
}
###########################################
# IBM SLP response format:
# 0
# 1
# 75
# URL: service:management-software.IBM...
# ATTR: (type=hardware-management-cons...
# (serial-number=KPHHK24),(name=c76v2h...
# 1ab1dd89ca8e0763e),(ip-address=192.1...
# 0CR3*KPHHK24),(web-management-interf...
# 2.ppd.pok.ibm.com:8443),(cimom-port=...
#
# 0
# 1
# 69
# URL:...
# ATTR:..
# ..
###########################################
else {
foreach ( split /\n{2,}/ , $ rsp ) {
if ( $ _ =~ s/(\d+)\n(\d+)\n(\d+)\n// ) {
if ( $ verbose ) {
trace ( $ request , "SrvRqst Response ($1)($2)($3)" ) ;
trace ( $ request , "$_\n" ) ;
}
###############################
# Response has "ATTR" field
###############################
if ( /ATTR: / ) {
$ result { $ _ } = 1 ;
}
###############################
# No "ATTR" - have to unicast
###############################
elsif ( /.*URL: (.*)/ ) {
$ unicast { $ 1 } = $ 1 ;
}
}
elsif ( $ verbose ) {
trace ( $ request , "DISCARDING: $_" ) ;
}
}
}
}
}
return ( [ \ % unicast , \ % result ] ) ;
}
##########################################################################
# Formats slp responses
##########################################################################
sub format_output {
my $ request = shift ;
my $ values = shift ;
my $ length = length ( $ header [ IP_ADDRESSES ] [ TEXT ] ) ;
my $ result ;
###########################################
# Parse responses and add to hash
###########################################
2010-02-04 08:12:33 +00:00
my $ outhash = parse_responses ( $ request , $ values , \ $ length ) ;
2009-10-20 13:37:44 +00:00
2011-06-02 01:59:20 +00:00
2011-03-04 01:54:43 +00:00
###########################################
# filter the result and keep the specified nodes
###########################################
if ( scalar ( @ filternodes ) ) {
my $ outhash1 = filter ( $ outhash ) ;
$ outhash = $ outhash1 ;
}
2011-06-02 01:59:20 +00:00
2011-06-30 02:36:39 +00:00
###########################################
# filter the result in the same vlan
###########################################
if ( exists ( $ opt { i } ) ) {
my $ outhash1 = filtersamevlan ( $ outhash ) ;
$ outhash = $ outhash1 ;
}
2011-08-03 10:04:51 +00:00
###########################################
# No responses
###########################################
if ( ( keys %$ outhash ) == 0 ) {
send_msg ( $ request , 0 , "No responses" ) ;
return ;
}
2009-10-20 13:37:44 +00:00
###########################################
# -w flag for write to xCat database
###########################################
if ( exists ( $ opt { 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
2010-02-04 08:12:33 +00:00
###########################################
# --makedhcp flag to issue xCAT command
# makedhcp internally.
###########################################
if ( exists ( $ opt { makedhcp } ) ) {
2010-02-06 14:00:25 +00:00
do_makedhcp ( $ request , $ outhash ) ;
2010-02-04 08:12:33 +00:00
}
###########################################
2011-01-24 16:11:56 +00:00
# --resetnet flag to reset the network
2010-02-04 08:12:33 +00:00
# interface of the node
###########################################
if ( exists ( $ opt { resetnet } ) ) {
2011-05-23 09:47:25 +00:00
#do_resetnet( $request, $outhash );
2011-06-02 01:59:20 +00:00
send_msg ( $ request , 0 , "the flag --resetnet has been moved to rspconfig, please see the rspconfig man page for more details" ) ;
2010-02-04 08:12:33 +00:00
}
2011-01-27 08:40:33 +00:00
###########################################
# -I flat give the warning message for
# the no-response nodes
###########################################
if ( exists ( $ opt { I } ) ) {
my $ outresult = integrity_check ( $ outhash ) ;
if ( $ outresult )
{
send_msg ( $ request , 0 , $ outresult ) ;
}
}
2009-10-20 13:37:44 +00:00
###########################################
# -r flag for raw response format
###########################################
2011-02-11 06:18:52 +00:00
my % rawhash = ( ) ;
2009-10-20 13:37:44 +00:00
if ( exists ( $ opt { r } ) ) {
foreach ( keys %$ outhash ) {
2011-02-11 06:18:52 +00:00
#$result .= "@{ $outhash->{$_}}[9]\n";
my $ raw = @ { $ outhash - > { $ _ } } [ 9 ] ;
$ rawhash { $ raw } = 1 ;
2009-10-20 13:37:44 +00:00
}
2011-06-02 01:59:20 +00:00
2011-02-11 06:18:52 +00:00
foreach ( keys % rawhash ) {
$ result . = "$_\n" ;
}
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
###########################################
if ( exists ( $ opt { x } ) ) {
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
###########################################
if ( exists ( $ opt { z } ) ) {
send_msg ( $ request , 0 , format_stanza ( $ outhash ) ) ;
return ;
}
2010-02-06 14:00:25 +00:00
###########################################
# -T flag for vpd table format
###########################################
2010-02-08 15:56:18 +00:00
if ( exists ( $ opt { 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
###########################################
2010-02-04 08:12:33 +00:00
foreach my $ hostname ( sort keys %$ outhash ) {
my $ data = $ outhash - > { $ hostname } ;
2009-10-20 13:37:44 +00:00
my $ i = 0 ;
foreach ( @ header ) {
2010-02-04 08:12:33 +00:00
if ( @$ _ [ 0 ] =~ /^hostname$/ ) {
$ result . = sprintf @$ _ [ 1 ] , $ hostname ;
} else {
$ result . = sprintf @$ _ [ 1 ] , @$ data [ $ i + + ] ;
}
2009-10-20 13:37:44 +00:00
}
$ result . = "\n" ;
}
send_msg ( $ request , 0 , $ result ) ;
}
2011-01-27 08:40:33 +00:00
##########################################################################
# Give the warning message for the no-response nodes
##########################################################################
sub integrity_check {
my $ datahash = shift ;
my $ findflag = 0 ;
my $ result ;
foreach my $ existnode ( keys % ::OLD_DATA_CACHE )
{
my $ tmptype = uc ( @ { $ ::OLD_DATA_CACHE { $ existnode } } [ 6 ] ) ;
my $ tmpmtm = @ { $ ::OLD_DATA_CACHE { $ existnode } } [ 0 ] ;
my $ tmpsn = @ { $ ::OLD_DATA_CACHE { $ existnode } } [ 1 ] ;
my $ tmpside = @ { $ ::OLD_DATA_CACHE { $ existnode } } [ 2 ] ;
if ( $ tmptype eq TYPE_CEC or $ tmptype eq TYPE_FRAME or $ tmptype =~ /lpar/ )
{
next ;
}
$ findflag = 0 ;
foreach my $ foundnode ( keys %$ datahash )
{
my $ newdata = $ datahash - > { $ foundnode } ;
my $ newtype = @$ newdata [ 0 ] ;
my $ newmtm = @$ newdata [ 1 ] ;
my $ newsn = @$ newdata [ 2 ] ;
my $ newside = @$ newdata [ 3 ] ;
if ( ! $ foundnode or ! $ newtype or ! $ newtype or ! $ newsn )
{
next ;
}
if ( ( $ newtype eq $ tmptype ) and ( $ tmptype eq TYPE_BPA or $ tmptype eq TYPE_FSP ) )
{
# begin to match fsp/bpa
if ( ( $ newmtm eq $ tmpmtm ) and ( $ newsn eq $ tmpsn ) and ( $ newside eq $ tmpside ) )
{
$ findflag = 1 ;
last ;
}
} elsif ( ( $ newtype eq $ tmptype ) and ( $ tmptype eq TYPE_HMC ) )
{
# begin to match hmc
if ( ( $ newmtm eq $ tmpmtm ) and ( $ newsn eq $ tmpsn ) )
{
$ findflag = 1 ;
last ;
}
}
}
if ( $ findflag eq 0 and $ existnode ne "" )
{
$ result . = "\n Warning: The node $existnode has no response. \n" ;
}
}
return $ result ;
}
2009-10-20 13:37:44 +00:00
##########################################################################
# Get IP from SLP URL response
##########################################################################
sub getip_from_url {
my $ request = shift ;
my $ url = shift ;
######################################################################
# Extract the IP from the URL. Generally, the URL
# should be in the following format (the ":0" port number
# may or may not be present):
# service:management-hardware.IBM:management-module://9.114.113.78:0
# service:management-software.IBM:integrated-virtualization-manager://zd21p1.rchland.ibm.com
######################################################################
if ( ( $ url !~ /service:.*:\/\/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}).*/ ) ) {
return undef ;
}
return ( $ 1 ) ;
}
2011-09-14 13:57:31 +00:00
sub read_from_table {
my % idhash ;
my % typehash ;
my % iphash ;
my % vpdhash ;
if ( ! defined ( % ::OLD_DATA_CACHE ) )
{
# find out all the existed nodes' ipaddresses
my $ hoststab = xCAT::Table - > new ( 'hosts' ) ;
if ( $ hoststab ) {
my @ ipentries = $ hoststab - > getAllNodeAttribs ( [ 'node' , 'ip' ] ) ;
for my $ ipentry ( @ ipentries ) {
$ iphash { $ ipentry - > { node } } = $ ipentry - > { ip } ;
}
} else {
return 1 ;
}
2009-10-20 13:37:44 +00:00
2011-09-14 13:57:31 +00:00
#find out all the existed nodes' type
my $ nodetypetab = xCAT::Table - > new ( 'nodetype' ) ;
if ( $ nodetypetab ) {
my @ typeentries = $ nodetypetab - > getAllNodeAttribs ( [ 'node' , 'nodetype' ] ) ;
for my $ typeentry ( @ typeentries ) {
$ typehash { $ typeentry - > { node } } = $ typeentry - > { nodetype } ;
}
} else {
return 2 ;
}
# find out all the existed nodes' mtms and side
my $ vpdtab = xCAT::Table - > new ( 'vpd' ) ;
if ( $ vpdtab ) {
my @ vpdentries = $ vpdtab - > getAllNodeAttribs ( [ 'node' , 'mtm' , 'serial' , 'side' ] ) ;
for my $ entry ( @ vpdentries ) {
@ { $ vpdhash { $ entry - > { node } } } [ 0 ] = $ entry - > { mtm } ;
@ { $ vpdhash { $ entry - > { node } } } [ 1 ] = $ entry - > { serial } ;
@ { $ vpdhash { $ entry - > { node } } } [ 2 ] = $ entry - > { side } ;
}
} else {
return 3 ;
}
# find out all the existed nodes' attributes
my $ ppctab = xCAT::Table - > new ( 'ppc' ) ;
if ( $ ppctab ) {
my @ identries = $ ppctab - > getAllNodeAttribs ( [ 'node' , 'id' , 'parent' , 'nodetype' ] ) ;
for my $ entry ( @ identries ) {
2011-09-18 14:38:15 +00:00
next if ( $ entry - > { nodetype } =~ /lpar/ ) ;
2011-09-14 13:57:31 +00:00
@ { $ ::OLD_DATA_CACHE { $ entry - > { node } } } [ 0 ] = @ { $ vpdhash { $ entry - > { node } } } [ 0 ] ; #mtm
@ { $ ::OLD_DATA_CACHE { $ entry - > { node } } } [ 1 ] = @ { $ vpdhash { $ entry - > { node } } } [ 1 ] ; #sn
@ { $ ::OLD_DATA_CACHE { $ entry - > { node } } } [ 2 ] = @ { $ vpdhash { $ entry - > { node } } } [ 2 ] ; #side
# find node ip address, check node name first, then check hosts table
my $ ifip = xCAT::Utils - > isIpaddr ( $ entry - > { node } ) ;
if ( $ ifip )
{
@ { $ ::OLD_DATA_CACHE { $ entry - > { node } } } [ 3 ] = $ entry - > { node } ; #ip
} else
{
if ( exists ( $ iphash { $ entry - > { node } } ) ) {
@ { $ ::OLD_DATA_CACHE { $ entry - > { node } } } [ 3 ] = $ iphash { $ entry - > { node } } ; #ip
}
else {
@ { $ ::OLD_DATA_CACHE { $ entry - > { node } } } [ 3 ] = "" ; #ip
}
}
@ { $ ::OLD_DATA_CACHE { $ entry - > { node } } } [ 4 ] = $ entry - > { id } ; #id
@ { $ ::OLD_DATA_CACHE { $ entry - > { node } } } [ 5 ] = $ entry - > { parent } ; #parent
if ( exists $ entry - > { nodetype } ) {
@ { $ ::OLD_DATA_CACHE { $ entry - > { node } } } [ 6 ] = $ entry - > { nodetype } ; #nodetype
} else {
if ( exists ( $ typehash { $ entry - > { node } } ) ) {
@ { $ ::OLD_DATA_CACHE { $ entry - > { node } } } [ 6 ] = $ typehash { $ entry - > { node } } ;
} else {
@ { $ ::OLD_DATA_CACHE { $ entry - > { node } } } [ 6 ] = "" ;
}
}
@ { $ ::OLD_DATA_CACHE { $ entry - > { node } } } [ 7 ] = 1 ;
}
} else
{
return 4 ;
}
}
return 0 ;
}
2009-10-20 13:37:44 +00:00
2011-01-24 16:11:56 +00:00
#############################################################################
# Get hostname from SLP URL response and match databse meanwhile
# used for FSP/BPA redundancy database migration
# if return something, it means it will use the old data name
# or new data name
# if return undef, it means the ip is not invalid and won't make any definition
# the global variable %::OLD_DATA_CACHE contans all the data
# the global variable %::UPDATE_CACHE records the data need to change name
#############################################################################
sub gethost_from_url_or_old {
my $ nodename = shift ;
my $ type = shift ;
my $ mtm = shift ;
my $ sn = shift ;
my $ side = shift ;
my $ ip = shift ;
my $ cage_number = shift ;
my $ parmtm = shift ;
my $ parsn = shift ;
2011-05-05 11:49:51 +00:00
my $ pname = shift ;
2011-09-14 13:57:31 +00:00
my $ flagref = shift ;
2011-01-24 16:11:56 +00:00
2011-03-23 07:56:21 +00:00
#######################################
# Extract IP from URL
#######################################
2011-05-05 11:49:51 +00:00
if ( $ ip )
{
my $ nets = xCAT::Utils:: my_nets ( ) ;
my $ avip = getip_from_iplist ( $ ip , $ nets , $ opt { i } ) ;
#if ( !defined( $ip )) {
# return undef;
#}
}
2011-01-24 16:11:56 +00:00
# get the information of existed nodes to do the migration
2011-05-05 11:49:51 +00:00
if ( ( $ type eq TYPE_BPA or $ type eq TYPE_FSP ) and $ pname )
2011-01-24 16:11:56 +00:00
{
$ enter_time = ( $ enter_time + 1 ) % 2 ;
}
2011-09-14 13:57:31 +00:00
read_from_table ( ) unless ( % ::OLD_DATA_CACHE ) ;
2011-01-24 16:11:56 +00:00
foreach my $ oldnode ( keys % ::OLD_DATA_CACHE )
{
my $ tmpmtm = @ { $ ::OLD_DATA_CACHE { $ oldnode } } [ 0 ] ;
my $ tmpsn = @ { $ ::OLD_DATA_CACHE { $ oldnode } } [ 1 ] ;
my $ tmpside = @ { $ ::OLD_DATA_CACHE { $ oldnode } } [ 2 ] ;
my $ tmpip = @ { $ ::OLD_DATA_CACHE { $ oldnode } } [ 3 ] ;
my $ tmpid = @ { $ ::OLD_DATA_CACHE { $ oldnode } } [ 4 ] ;
my $ tmpparent = @ { $ ::OLD_DATA_CACHE { $ oldnode } } [ 5 ] ;
my $ tmptype = uc ( @ { $ ::OLD_DATA_CACHE { $ oldnode } } [ 6 ] ) ;
my $ unmatched = @ { $ ::OLD_DATA_CACHE { $ oldnode } } [ 7 ] ;
2011-05-05 11:49:51 +00:00
# used to match fsp defined by xcatsetup
# should return fast to save time
2011-05-25 09:33:58 +00:00
if ( ( $ type eq TYPE_BPA or $ type eq TYPE_FSP ) and ( $ tmptype eq $ type ) and $ pname and $ side ) {
if ( $ pname eq $ tmpparent and $ side eq $ tmpside ) {
2011-09-14 13:57:31 +00:00
$$ flagref = 1 ;
print "1 got old name $oldnode \n" if ( $ DEBUG_MATCH eq 1 ) ;
2011-05-25 09:33:58 +00:00
return $ oldnode ;
}
2011-05-05 11:49:51 +00:00
}
2011-06-02 01:59:20 +00:00
2011-01-24 16:11:56 +00:00
# match the existed nodes including old data and user defined data
2011-05-25 09:33:58 +00:00
if ( ( $ type eq TYPE_BPA or $ type eq TYPE_FSP ) and ( $ tmptype eq $ type ) ) {
unless ( $ tmpmtm ) {
2011-01-24 16:11:56 +00:00
next ;
}
2011-05-25 09:33:58 +00:00
if ( $ tmpmtm eq $ mtm and $ tmpsn eq $ sn ) {
2011-01-24 16:11:56 +00:00
my $ ifip = xCAT::Utils - > isIpaddr ( $ oldnode ) ;
2011-05-25 09:33:58 +00:00
if ( $ ifip ) { # which means that the node is defined by the new lsslp
if ( $ tmpside eq $ side ) { # match! which means that node is the same as the new one
if ( $ ip eq $ tmpip ) { #which means that the ip is not changed
2011-01-24 16:11:56 +00:00
# maybe we should check if the ip is invalid and send a warning
2011-09-14 13:57:31 +00:00
$$ flagref = 1 ;
print "2 got old name $ip\n" if ( $ DEBUG_MATCH eq 1 ) ;
2011-01-24 16:11:56 +00:00
return $ ip ;
2011-05-25 09:33:58 +00:00
} else { #which means that the ip is changed
2011-01-24 16:11:56 +00:00
my $ vip = check_ip ( $ ip ) ;
2011-05-25 09:33:58 +00:00
if ( ! $ vip ) { #which means the ip is changed and valid
2011-01-24 16:11:56 +00:00
# maybe we should check if the old ip is invalid and send a warning
# even so we should keep the definition as before
# because this case, we can't put check_ip in the end
2011-09-14 13:57:31 +00:00
$$ flagref = 1 ;
print "3 got old name $oldnode\n" if ( $ DEBUG_MATCH eq 1 ) ;
2011-01-24 16:11:56 +00:00
return $ oldnode ;
2011-05-25 09:33:58 +00:00
} else {
2011-01-24 16:11:56 +00:00
return $ ip ;
}
}
}
}
2011-05-25 09:33:58 +00:00
else { # name is not a ip
2011-01-24 16:11:56 +00:00
$ side =~ /(\w)\-(\w)/ ;
my $ slot = $ 1 ;
2011-05-25 09:33:58 +00:00
if ( $ tmpside and $ tmpside !~ /\-/ ) { # side is like A or B
if ( $ slot eq $ tmpside ) {
if ( $ oldnode =~ /^Server\-/ ) { #judge if need to change node's name
if ( $ ip eq $ tmpip ) {
if ( $ oldnode =~ /\-(A|B)$/ ) {
2011-01-24 16:11:56 +00:00
@ { $ ::OLD_DATA_CACHE { $ oldnode } } [ 7 ] = 0 ;
2011-09-14 13:57:31 +00:00
$$ flagref = 1 ;
print "4 got old name $oldnode\n" if ( $ DEBUG_MATCH eq 1 ) ;
2011-01-24 16:11:56 +00:00
return $ oldnode ;
2011-05-25 09:33:58 +00:00
} else {
2011-01-24 16:11:56 +00:00
@ { $ ::OLD_DATA_CACHE { $ oldnode } } [ 7 ] = 0 ;
#change node name, need to record the node here
2011-02-21 05:50:02 +00:00
$ ::UPDATE_CACHE { $ mtm . '-' . $ sn } = $ oldnode ;
2011-09-14 13:57:31 +00:00
$$ flagref = 1 ;
print "5 got old name $oldnode\n" if ( $ DEBUG_MATCH eq 1 ) ;
2011-01-24 16:11:56 +00:00
return $ oldnode . '-' . $ slot ;
}
2011-05-25 09:33:58 +00:00
} else { # not find a matched definition, but need to use the old node name
if ( $ enter_time eq 0 and $ unmatched ) {
2011-09-14 13:57:31 +00:00
$$ flagref = 1 ;
print "6 got old name $oldnode\n" if ( $ DEBUG_MATCH eq 1 ) ;
2011-01-24 16:11:56 +00:00
return $ oldnode ;
}
}
2011-05-25 09:33:58 +00:00
} elsif ( $ tmpside =~ /\-/ ) { # end of if ( $oldnode =~ /^Server\-/)
if ( $ ip eq $ tmpip ) {
2011-01-24 16:11:56 +00:00
@ { $ ::OLD_DATA_CACHE { $ oldnode } } [ 7 ] = 0 ;
2011-09-14 13:57:31 +00:00
$$ flagref = 1 ;
print "7 got old name $oldnode\n" if ( $ DEBUG_MATCH eq 1 ) ;
2011-01-24 16:11:56 +00:00
return $ oldnode ;
2011-05-25 09:33:58 +00:00
} else {
if ( $ enter_time eq 0 and $ unmatched ) {
2011-09-14 13:57:31 +00:00
$$ flagref = 1 ;
print "8 got old name $oldnode\n" if ( $ DEBUG_MATCH eq 1 ) ;
2011-01-24 16:11:56 +00:00
return $ oldnode ;
}
}
}
}
2011-05-25 09:33:58 +00:00
} elsif ( $ tmpside =~ /\-/ ) {
if ( $ side eq $ tmpside ) {
2011-09-14 13:57:31 +00:00
$$ flagref = 1 ;
print "9 got old name $oldnode\n" if ( $ DEBUG_MATCH eq 1 ) ;
2011-01-24 16:11:56 +00:00
return $ oldnode ;
}
2011-05-25 09:33:58 +00:00
} elsif ( ! $ tmpside ) {
if ( $ oldnode =~ /^Server\-/ ) { #judge if need to change node's name
if ( $ oldnode !~ /\-(A|B)$/ ) {
2011-01-24 16:11:56 +00:00
delete $ ::OLD_DATA_CACHE { $ oldnode } ;
2011-09-14 13:57:31 +00:00
$$ flagref = 1 ;
print "10 got old name $oldnode\n" if ( $ DEBUG_MATCH eq 1 ) ;
2011-01-24 16:11:56 +00:00
return $ oldnode . "-" . $ slot ;
}
}
# if mtms could match but side not defined, we will trate
# it as the result by rscan. And alway use its name.
delete $ ::OLD_DATA_CACHE { $ oldnode } ;
2011-09-14 13:57:31 +00:00
$$ flagref = 1 ;
print "11 got old name $oldnode\n" if ( $ DEBUG_MATCH eq 1 ) ;
2011-01-24 16:11:56 +00:00
return $ oldnode ;
}
}
} # end of if ($tmpmtm eq $mtm and $tmpsn eq $sn)
2011-09-14 13:57:31 +00:00
}
if ( ( $ type eq TYPE_FRAME or $ type eq TYPE_CEC ) and ( $ type eq $ tmptype ) ) {
2011-05-25 09:33:58 +00:00
if ( ! $ tmpmtm and ! $ tmpid ) {
2011-01-24 16:11:56 +00:00
next ;
}
# user may define cec only with parent /id /type
# we should match this situation
2011-05-25 09:33:58 +00:00
if ( ( $ type eq TYPE_CEC ) and $ parmtm and $ parsn and $ cage_number ) {
2011-01-24 16:11:56 +00:00
my $ tpparmtm = @ { $ ::OLD_DATA_CACHE { $ tmpparent } } [ 0 ] ;
my $ tpparsn = @ { $ ::OLD_DATA_CACHE { $ tmpparent } } [ 1 ] ;
2011-05-25 09:33:58 +00:00
if ( ( $ tpparmtm eq $ parmtm ) and ( $ tpparsn eq $ parsn ) and ( $ cage_number eq $ tmpid ) and ( $ type eq $ tmptype ) ) {
2011-09-14 13:57:31 +00:00
$$ flagref = 1 ;
print "12 got old name $oldnode\n" if ( $ DEBUG_MATCH eq 1 ) ;
2011-01-24 16:11:56 +00:00
return $ oldnode ;
}
}
# user may define cec/frame only with mtms
# but what we consider here is just the data in xCAT 2.6
2011-05-25 09:33:58 +00:00
if ( $ tmpmtm eq $ mtm and $ tmpsn eq $ sn and $ tmptype eq $ type ) {
if ( $ oldnode =~ /^Server\-/ ) { #judge if need to change node's name
if ( $ oldnode =~ /(\-A)$/ ) {
2011-01-24 16:11:56 +00:00
$ nodename = s/(\-A)$// ;
# should send a warning here
2011-09-14 13:57:31 +00:00
$$ flagref = 1 ;
print "13 got old name $oldnode\n" if ( $ DEBUG_MATCH eq 1 ) ;
2011-01-24 16:11:56 +00:00
return $ nodename ;
}
2011-05-25 09:33:58 +00:00
else {
2011-09-14 13:57:31 +00:00
$$ flagref = 1 ;
print "14 got old name $oldnode\n" if ( $ DEBUG_MATCH eq 1 ) ;
2011-01-24 16:11:56 +00:00
return $ oldnode ;
}
2011-05-25 09:33:58 +00:00
} else {
2011-09-14 13:57:31 +00:00
$$ flagref = 1 ;
print "15 got old name $oldnode\n" if ( $ DEBUG_MATCH eq 1 ) ;
2011-01-24 16:11:56 +00:00
return $ oldnode ;
}
}
} # end of foreach my $oldnode ( keys %::OLD_DATA_CACHE ), not match
}
# not matched, use the new name
my $ ifip = xCAT::Utils - > isIpaddr ( $ nodename ) ;
2011-05-25 09:33:58 +00:00
unless ( $ ifip ) {
2011-01-24 16:11:56 +00:00
return $ nodename ;
2011-05-25 09:33:58 +00:00
} else {
2011-01-24 16:11:56 +00:00
my $ vip = check_ip ( $ nodename ) ;
2011-05-25 09:33:58 +00:00
if ( $ vip ) { #which means the ip is a valid one
2011-01-24 16:11:56 +00:00
return $ nodename ;
2011-05-25 09:33:58 +00:00
} else {
2011-01-24 16:11:56 +00:00
return undef ;
}
}
}
##########################################################################
# Makesure the ip in SLP URL is valid
# return 1 if valid, 0 if invalid
##########################################################################
sub check_ip {
my $ myip = shift ;
my $ firstoctet = $ myip ;
$ firstoctet =~ s/^(\d+)\..*/$1/ ;
if ( $ firstoctet >= 224 and $ firstoctet <= 239 )
{
return 0 ;
}
foreach ( @ invalidiplist )
{
2011-02-22 07:22:35 +00:00
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
##########################################################################
sub gethost_from_url {
my $ request = shift ;
my $ rsp = shift ;
2011-12-21 10:46:17 +00:00
my $ flag = shift ;
2009-10-20 13:37:44 +00:00
my $ type = shift ;
my $ mtm = shift ;
my $ sn = shift ;
2009-12-28 08:10:42 +00:00
my $ side = shift ;
2009-10-20 13:37:44 +00:00
my $ iplist = shift ;
2010-02-04 08:12:33 +00:00
my $ bpc_machinetype = shift ;
my $ bpc_serial = shift ;
my $ frame_number = shift ;
my $ cage_number = shift ;
my $ host ;
2009-10-20 13:37:44 +00:00
2009-12-28 08:10:42 +00:00
2009-10-20 13:37:44 +00:00
#######################################
# Extract IP from URL
#######################################
my $ nets = xCAT::Utils:: my_nets ( ) ;
my $ ip = getip_from_iplist ( $ iplist , $ nets , $ opt { i } ) ;
if ( ! defined ( $ ip ) ) {
return undef ;
}
#######################################
# Check if valid IP
#######################################
my $ packed = inet_aton ( $ ip ) ;
if ( length ( $ packed ) != 4 ) {
if ( $ verbose ) {
trace ( $ request , "Invalid IP address in URL: $ip" ) ;
}
return undef ;
}
2010-02-04 08:12:33 +00:00
2009-10-20 13:37:44 +00:00
#######################################
2010-02-04 08:12:33 +00:00
# Get hostname from vpd table
2009-10-20 13:37:44 +00:00
#######################################
2011-12-21 10:46:17 +00:00
$ host = match_vpdtable ( $ type , $ mtm , $ sn , $ side , $ bpc_machinetype , $ bpc_serial , $ frame_number , $ cage_number ) ;
2010-02-04 08:12:33 +00:00
if ( ! $ host ) {
2011-12-21 10:46:17 +00:00
$$ flag = 0 ;
2010-02-09 08:58:10 +00:00
$ host = getFactoryHostname ( $ type , $ mtm , $ sn , $ side , $ ip , $ rsp ) ;
2010-02-04 08:12:33 +00:00
#######################################
# Convert hostname to short-hostname
#######################################
if ( $ host =~ /([^\.]+)\./ ) {
$ host = $ 1 ;
2009-07-31 19:45:28 +00:00
}
2011-12-21 10:46:17 +00:00
} else {
$$ flag = 1 ;
2009-10-20 13:37:44 +00:00
}
2010-02-04 08:12:33 +00:00
return ( "$host($ip)" ) ;
}
##########################################################################
# Match hostnames in vpd table
##########################################################################
sub match_vpdtable
{
my $ type = shift ;
my $ mtm = shift ;
my $ sn = shift ;
my $ side = shift ;
my $ bpc_machinetype = shift ;
my $ bpc_serial = shift ;
my $ frame_number = shift ;
my $ cage_number = shift ;
my $ host ;
2009-10-20 13:37:44 +00:00
#######################################
2010-02-04 08:12:33 +00:00
# Cache ppc table
2011-01-24 16:11:56 +00:00
#######################################
2010-12-07 05:47:07 +00:00
#removed by yinle, no use
#if ( !%::PPC_TAB_CACHE) {
# my $ppctab = xCAT::Table->new( 'ppc' );
# my @entries = $ppctab->getAllNodeAttribs(['node','parent','id']);
# for my $entry ( @entries ) {
# if ( $entry->{mtm} and $entry->{serial} and defined( $entry->{side} ) ) {
# }
# }
#}
2009-10-20 13:37:44 +00:00
#######################################
2010-12-07 05:47:07 +00:00
# Cache vpd table, now xCAT support defining Frame and CEC with mtms by user.
2009-10-20 13:37:44 +00:00
#######################################
2010-02-04 08:12:33 +00:00
if ( ! % ::VPD_TAB_CACHE ) {
my $ vpdtab = xCAT::Table - > new ( 'vpd' ) ;
my @ entries = $ vpdtab - > getAllNodeAttribs ( [ 'node' , 'mtm' , 'serial' , 'side' ] ) ;
#Assuming IP is unique in hosts table
for my $ entry ( @ entries ) {
if ( $ entry - > { mtm } and $ entry - > { serial } and defined ( $ entry - > { side } ) ) {
$ ::VPD_TAB_CACHE { $ entry - > { mtm } . '*' . $ entry - > { serial } . '-' . $ entry - > { side } } = $ entry - > { 'node' } ;
}
}
2009-10-20 13:37:44 +00:00
}
2010-02-04 08:12:33 +00:00
if ( exists ( $ ::VPD_TAB_CACHE { $ mtm . '*' . $ sn . '-' . $ side } ) ) {
$ host = $ ::VPD_TAB_CACHE { $ mtm . '*' . $ sn . '-' . $ side } ;
return ( "$host" ) ;
}
}
2009-10-20 13:37:44 +00:00
2010-02-04 08:12:33 +00:00
##########################################################################
# Match hostnames in switch table
##########################################################################
sub match_switchtable
{
2010-02-05 16:36:16 +00:00
my $ ip = shift ;
my $ mac = shift ;
my $ type = shift ;
my $ bpc_model = shift ;
my $ bpc_serial = shift ;
my $ frame_number = shift ;
my $ cage_number = shift ;
my $ side = shift ;
my $ mtm = shift ;
my $ serial = shift ;
my $ name ;
#######################################
# Find the nodenames that match the
# port on switch to their mac
#######################################
my $ names = $ macmap - > find_mac ( $ mac ) ;
if ( $ names =~ /,/ ) {
#######################################
# For High end machines, only BPA have
2011-01-24 16:11:56 +00:00
# connections to switch, FSPs shared the
2010-02-05 16:36:16 +00:00
# port with BPA. So need to distiguish
# the FSPs on the same port
#######################################
$ name = disti_multi_node ( $ names , $ type , $ bpc_model , $ bpc_serial , $ frame_number , $ cage_number , $ side , $ mtm , $ serial ) ;
if ( ! $ name ) {
return undef ;
}
2010-02-06 14:00:25 +00:00
} elsif ( ! $ names ) {
return undef ;
2010-02-05 16:36:16 +00:00
} else {
$ name = $ names ;
}
2010-02-06 14:00:25 +00:00
return $ name ;
2009-10-20 13:37:44 +00:00
}
sub getFactoryHostname
{
my $ type = shift ;
my $ mtm = shift ;
my $ sn = shift ;
2009-12-28 08:10:42 +00:00
my $ side = shift ;
2010-02-09 08:58:10 +00:00
my $ ip = shift ;
2009-10-20 13:37:44 +00:00
my $ rsp = shift ;
my $ host = undef ;
if ( $ rsp =~ /\(name=([^\)]+)/ ) {
$ host = $ 1 ;
###################################
# Convert to short-hostname
###################################
if ( $ host =~ /([^\.]+)\./ ) {
$ host = $ 1 ;
}
}
2010-02-08 15:56:18 +00:00
if ( $ type eq SERVICE_FSP or $ type eq SERVICE_BPA or $ type eq SERVICE_MM )
2009-10-20 13:37:44 +00:00
{
2009-12-28 08:10:42 +00:00
$ host = "Server-$mtm-SN$sn-$side" ;
2009-10-20 13:37:44 +00:00
}
2010-02-09 08:58:10 +00:00
if ( $ ip ) {
my $ hname = gethostbyaddr ( inet_aton ( $ ip ) , AF_INET ) ;
if ( $ hname ) {
$ host = $ hname ;
}
}
2010-03-23 08:33:08 +00:00
if ( ! $ host ) {
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 } ;
}
}
}
2010-02-09 08:58:10 +00:00
2009-10-20 13:37:44 +00:00
return $ host ;
}
##########################################################################
# Get correct IP from ip list in SLP Attr
##########################################################################
sub getip_from_iplist
{
my $ iplist = shift ;
my $ nets = shift ;
my $ inc = shift ;
2011-01-24 16:11:56 +00:00
2009-10-20 13:37:44 +00:00
my @ ips = split /,/ , $ iplist ;
2011-07-21 08:23:52 +00:00
my @ ips2 = split /,/ , $ inc ;
2009-10-20 13:37:44 +00:00
if ( $ inc )
{
for my $ net ( keys %$ nets )
2009-07-31 19:45:28 +00:00
{
2011-07-21 08:23:52 +00:00
my $ flag = 1 ;
for my $ einc ( @ ips2 ) {
if ( $ nets - > { $ net } eq $ einc ) {
$ flag = 0 ;
}
}
delete $ nets - > { $ net } if ( $ flag ) ;
2009-07-31 19:45:28 +00:00
}
2009-10-20 13:37:44 +00:00
}
2011-01-24 16:11:56 +00:00
2011-07-21 08:23:52 +00:00
2009-10-20 13:37:44 +00:00
for my $ ip ( @ ips )
{
2009-10-22 09:55:42 +00:00
next if ( $ ip =~ /:/ ) ; #skip IPV6 addresses
2009-10-20 13:37:44 +00:00
for my $ net ( keys %$ nets )
2009-07-20 18:46:13 +00:00
{
2009-10-20 13:37:44 +00:00
my ( $ n , $ m ) = split /\// , $ net ;
if ( xCAT::Utils:: isInSameSubnet ( $ n , $ ip , $ m , 1 ) and
xCAT::Utils:: isPingable ( $ ip ) )
2009-07-20 18:46:13 +00:00
{
2009-10-20 13:37:44 +00:00
return $ ip ;
2009-07-20 18:46:13 +00:00
}
}
2009-10-20 13:37:44 +00:00
}
return undef ;
}
2010-02-04 08:12:33 +00:00
##########################################################################
# Match IP addresses to MAC in arp table
##########################################################################
sub match_ip_mac
{
my $ ips = shift ;
######################################################
# Cache ARP table entries
######################################################
if ( ! % ::ARP_CACHE ) {
my $ arp ;
if ( $^O eq 'aix' ) {
$ arp = `/usr/sbin/arp -a` ;
} else {
$ arp = `/sbin/arp -n` ;
}
my @ arpents = split /\n/ , $ arp ;
foreach my $ arpent ( @ arpents ) {
my ( $ ip , $ mac ) ;
if ( $^O eq 'aix' && $ arpent =~ /\((\S+)\)\s+at\s+(\S+)/ ) {
( $ ip , $ mac ) = ( $ 1 , $ 2 ) ;
######################################################
# Change mac format to be same as linux. For example:
# '0:d:60:f4:f8:22' to '00:0d:60:f4:f8:22'
######################################################
if ( $ mac ) {
my @ mac_sections = split /:/ , $ mac ;
for ( @ mac_sections ) {
$ _ = "0$_" if ( length ( $ _ ) == 1 ) ;
}
2011-06-21 13:16:59 +00:00
$ mac = join '' , @ mac_sections ;
2010-02-04 08:12:33 +00:00
}
} elsif ( $ arpent =~ /^(\S+)+\s+\S+\s+(\S+)\s/ ) {
( $ ip , $ mac ) = ( $ 1 , $ 2 ) ;
} else {
( $ ip , $ mac ) = ( undef , undef ) ;
}
2011-01-24 16:11:56 +00:00
2010-02-04 08:12:33 +00:00
if ( defined ( $ ip ) and defined ( $ mac ) ) {
$ ::ARP_CACHE { $ ip } = $ mac ;
}
}
}
if ( exists ( $ ::ARP_CACHE { $ ips } ) ) {
return ( $ ::ARP_CACHE { $ ips } ) ;
}
return undef ;
}
2009-10-20 13:37:44 +00:00
##########################################################################
# Example OpenSLP slptool "service-request" output. The following
# attributes can be returned in any order within an SLP response.
#
# service:management-hardware.IBM:management-module://192.20.154.19,48659
# (type=management-module),(level=3),(serial-number= K10WM39916W),
# (fru=73P9297 ),(name=WMN315724834),(ip-address=192.20.154.19),
# (enclosure-serial-number=78AG034),(enclosure-fru=59P6609 ),
# (enclosure-machinetype-model=86772XX),(status=0),(enclosure-uuid=
# \ff\e6\4f\0b\41\de\0d\11\d7\bd\be\b5\3c\ab\f0\46\04),
# (web-url=http://192.20.154.19:80),(snmp-port=161),(slim-port=6090),
# (ssh-port=22),(secure-slim-port=0),(secure-slim-port-enabled=false),
# (firmware-image-info=BRET86P:16:01-29-08,BRBR82A:16:06-01-05),
# (telnet-port=23),(slot=1),0
# ...
#
# Example OpenSLP slptool "attribute-request" output. The following
# attributes can be returned in any order within an SLP response.
#
# (type=integrated-virtualization-manager),(level=3),(machinetype-model=911051A),
# (serial-number=1075ECF),(name=p510ivm.clusters.com)(ip-address=192.168.1.103),
# (web-url=http://p510ivm.clusters.com/),(mtms=911051A*1075ECF),
# (web-management-interface=TRUE),(secure-web-url=https://p510ivm.clusters.com/),
# (cimom-port=5988),(secure-cimom-port=5989),(lparid=1)
# ...
#
#------------------------------------------------------------------------
#
# Example IBM SLP slp_query command "service-request" output. The following
# attributes can be returned in any order within an SLP response.
# Note: The leading 3 numbers preceeding the URL: and ATTR: fields
# represent:
# error code,
# URL count,
# URL length, respectively.
# 0
# 1
# 75
# URL: service:management-software.IBM:hardware-management-console://192.168.1.110
# ATTR: (type=hardware-management-console),(level=3),(machinetype-model=7310CR3),
# (serial-number=KPHHK24),(name=c76v2hmc02.ppd.pok.ibm.com),(uuid=de335adf051eb21
# 1ab1dd89ca8e0763e),(ip-address=192.168.1.110,9.114.47.154),(web-url=),(mtms=731
# 0CR3*KPHHK24),(web-management-interface=true),(secure-web-url=https://c76v2hmc0
# 2.ppd.pok.ibm.com:8443),(cimom-port=),(secure-cimom-port=5989)
#
# 0
# 1
# 69
# ...
#
# Example IBM SLP slp_query command "attribute-request" output. The following
# attributes can be returned in any order within an SLP response.
# Note: The leading 3 numbers preceeding the URL: and ATTR: fields
# represent:
# error code,
# 0, (hardcoded)
# ATTR length, respectively.
# 0
# 0
# 354
# ATTR: (type=integrated-virtualization-manager),(level=3),(machinetype-model=911051A),
# (serial-number=1075ECF),(name=p705ivm.clusters.com),(ip-address=192.168.1.103),
# (web-url=http://p705ivm.clusters.com/),(mtms=911051A*1075ECF),(web-management-
# interface=TRUE),(secure-web-url=https://p705ivm.clusters.com/),(cimom-port=5988),
# (secure-cimom-port=5989),(lparid=1)
#
#########################################################################
sub parse_responses {
my $ request = shift ;
my $ values = shift ;
my $ length = shift ;
2011-09-14 13:57:31 +00:00
my $ matchflag = 0 ;
my % outhash ;
2011-09-18 14:38:15 +00:00
my % net ;
my % addr ;
my $ nettab = xCAT::Table - > new ( 'networks' ) ;
my @ nets = $ nettab - > getAllAttribs ( 'netname' , 'net' , 'mask' , 'mgtifname' ) ;
if ( scalar ( @ nets ) == 0 ) {
trace ( $ request , "Can't get networks information from networks table" , 1 ) ;
} else {
foreach my $ enet ( @ nets ) {
2011-09-18 15:34:09 +00:00
next if ( $ enet - > { 'net' } =~ /:/ ) ;
2011-09-18 14:38:15 +00:00
$ net { $ enet - > { 'mgtifname' } } { subnet } = $ enet - > { 'net' } ;
$ net { $ enet - > { 'mgtifname' } } { netmask } = $ enet - > { 'mask' } ;
}
}
my $ netref = xCAT::NetworkUtils - > get_nic_ip ( ) ;
for my $ entry ( keys %$ netref ) {
$ addr { $ netref - > { $ entry } } { subnet } = $ net { $ entry } { subnet } ;
$ addr { $ netref - > { $ entry } } { netmask } = $ net { $ entry } { netmask } ;
}
2009-10-20 13:37:44 +00:00
my @ attrs = (
2010-02-04 08:12:33 +00:00
"type" ,
"machinetype-model" ,
"serial-number" ,
"slot" ,
"ip-address" ,
"bpc-machinetype-model" ,
"bpc-serial-number" ,
"frame-number" ,
"cage-number" ) ;
2009-10-20 13:37:44 +00:00
#######################################
# RSA/MM Attributes
#######################################
my @ xattrs = (
"type" ,
"enclosure-machinetype-model" ,
"enclosure-serial-number" ,
2009-12-28 08:10:42 +00:00
"slot" ,
2009-10-20 13:37:44 +00:00
"ip-address" ) ;
2011-12-21 02:25:14 +00:00
#######################################
# NGP CMM Attributes
#######################################
my @ cmmattrs = (
"type" ,
"enclosure-mtm" ,
"enclosure-serial-number" ,
"slot" ,
2011-12-21 10:46:17 +00:00
"ipv4-address" ,
"mm-name" ) ;
2011-03-04 01:54:43 +00:00
my % fid1 ;
my % fid2 ;
my % cid ;
2011-10-18 05:41:03 +00:00
my % pmtm ;
my % psn ;
2011-09-14 13:57:31 +00:00
my @ matchnodes ;
2011-06-02 01:59:20 +00:00
trace ( $ request , "Now I will explain how the lsslp parse its response: " , 1 ) ;
2009-10-20 13:37:44 +00:00
foreach my $ rsp ( @$ values ) {
###########################################
# Get service-type from response
###########################################
my @ result = ( ) ;
my $ host ;
###########################################
# service-type attribute not found
###########################################
if ( $ rsp !~ /\(type=([^\)]+)/ ) {
if ( $ verbose ) {
trace ( $ request , "(type) attribute not found: $rsp" ) ;
2008-06-03 19:09:21 +00:00
}
2009-10-20 13:37:44 +00:00
next ;
}
###########################################
# Valid service-type attribute
###########################################
my $ type = $ 1 ;
###########################################
# Unsupported service-type
###########################################
if ( ! exists ( $ service_slp { $ type } ) ) {
if ( $ verbose ) {
trace ( $ request , "Discarding unsupported type: $type" ) ;
2008-06-03 19:09:21 +00:00
}
2009-10-20 13:37:44 +00:00
next ;
2008-06-03 19:09:21 +00:00
}
2009-10-20 13:37:44 +00:00
###########################################
2011-12-21 02:25:14 +00:00
# Extract the attributes
2009-10-20 13:37:44 +00:00
# RSA/MM - slightly different attributes
###########################################
2011-12-21 02:25:14 +00:00
my $ attr ;
2009-10-20 13:37:44 +00:00
if ( ( $ type eq SERVICE_RSA ) or ( $ type eq SERVICE_RSA2 ) or
( $ type eq SERVICE_MM ) ) {
$ attr = \ @ xattrs ;
2011-12-21 02:25:14 +00:00
foreach ( @$ attr ) {
unless ( $ rsp =~ /\($_=([^\)]+)/ ) {
if ( $ verbose ) {
trace ( $ request , "Attribute not found: [$_]->($rsp)" ) ;
}
push @ result , "N/A" ;
next ;
}
my $ val = $ 1 ;
if ( ( $ _ =~ /^slot$/ ) and ( $ val == 0 ) ) {
push @ result , "B" ;
} elsif ( ( $ _ =~ /^slot$/ ) and ( $ val == 1 ) ) {
push @ result , "A" ;
} else {
push @ result , $ val ;
2011-01-24 16:11:56 +00:00
}
}
2011-12-21 02:25:14 +00:00
} elsif ( $ type eq SERVICE_CMM ) {
$ attr = \ @ cmmattrs ;
foreach ( @$ attr ) {
unless ( $ rsp =~ /\($_=([^\)]+)/ ) {
if ( $ verbose ) {
trace ( $ request , "Attribute not found: [$_]->($rsp)" ) ;
}
push @ result , "N/A" ;
next ;
}
my $ val = $ 1 ;
2011-01-24 16:11:56 +00:00
push @ result , $ val ;
2009-12-28 08:10:42 +00:00
}
2011-12-21 02:25:14 +00:00
trace ( $ request , ">>>>>>>>The type is $result[0], en-mtm is $result[1], en-sn is $result[2], slot is $result[3], ip is $result[4]" , 1 ) ;
} else {
$ attr = \ @ attrs ;
foreach ( @$ attr ) {
unless ( $ rsp =~ /\($_=([^\)]+)/ ) {
if ( $ verbose ) {
trace ( $ request , "Attribute not found: [$_]->($rsp)" ) ;
}
push @ result , "N/A" ;
next ;
}
my $ val = $ 1 ;
if ( ( $ _ =~ /^slot$/ ) and ( $ val == 0 ) ) {
push @ result , "B" ;
} elsif ( ( $ _ =~ /^slot$/ ) and ( $ val == 1 ) ) {
push @ result , "A" ;
} else {
push @ result , $ val ;
}
}
trace ( $ request , ">>>>>>>>The type is $result[0], mtm is $result[1], sn is $result[2], side is $result[3], ip is $result[4], parent mtm is $result[5], parent sn is $result[6], frame num is $result[7], cage num is $result[8]." , 1 ) ;
2009-10-20 13:37:44 +00:00
}
2011-01-11 15:12:52 +00:00
# match hosts table
#my %hostip;
#my $hoststab = xCAT::Table->new( 'hosts' );
#my $entry;
#my @entries = $hoststab->getAllNodeAttribs(['node','ip']);
#foreach $entry ( @entries ) {
# $hostip{$entry->{node}} = $entry->{ip};
#}
2011-09-14 13:57:31 +00:00
trace ( $ request , ">>>>>>>>The type is $result[0], mtm is $result[1], sn is $result[2], side is $result[3], ip is $result[4], parent mtm is $result[5], parent sn is $result[6], frame num is $result[7], cage num is $result[8]." , 1 ) ;
2011-05-24 09:27:41 +00:00
2011-01-11 15:12:52 +00:00
# begin to define FSP/BPA/FRAME/CEC
2011-04-18 08:21:03 +00:00
my $ typetp ;
if ( $ type eq SERVICE_BPA )
{
$ typetp = TYPE_BPA ;
}
else
{
$ typetp = TYPE_FSP ;
}
2011-01-24 16:11:56 +00:00
my $ hostname = undef ;
2010-12-07 05:47:07 +00:00
if ( $ type eq SERVICE_BPA or $ type eq SERVICE_FSP ) {
2011-09-14 13:57:31 +00:00
trace ( $ request , "........First define FSP/BPA nodes" , 1 ) ;
2010-12-07 05:47:07 +00:00
###########################################
2011-01-11 15:12:52 +00:00
# begin to define fsp/bpa, use ip as the hostname of the fsp/bpa
# for there are redundancy of fsp/bpa,
# excrete each slp response into two definitions
# put the definitions into %outhash
###########################################
2011-06-02 01:59:20 +00:00
2011-01-11 15:12:52 +00:00
# begin to define fsp/bpa
2010-12-07 05:47:07 +00:00
my ( @ severnode1 , @ severnode2 ) ;
my @ ips = split /,/ , $ result [ 4 ] ;
2011-02-24 09:22:12 +00:00
#keep cage id for the secondary fsp definition
2011-03-04 01:54:43 +00:00
#the cash hash is like $fid{mtm*sn}=cageid
2011-10-18 05:41:03 +00:00
#if ($type eq SERVICE_FSP and $severnode1[3] eq "A")
#{
# $fid1{$severnode1[1]."*".$severnode1[2]} = $severnode1[8];
#}
#if ($type eq SERVICE_FSP and $severnode1[3] eq "B")
#{
# $fid2{$severnode1[1]."*".$severnode1[2]} = $severnode1[8];
#}
if ( ! exists ( $ cid { $ result [ 1 ] . "*" . $ result [ 2 ] } ) || ( $ result [ 8 ] > 0 ) ) {
$ cid { $ result [ 1 ] . "*" . $ result [ 2 ] } = $ result [ 8 ] ;
2011-03-04 01:54:43 +00:00
}
2011-10-18 05:41:03 +00:00
if ( ! exists ( $ pmtm { $ result [ 1 ] . "*" . $ result [ 2 ] } ) || ( $ result [ 5 ] > 0 ) ) {
$ pmtm { $ result [ 1 ] . "*" . $ result [ 2 ] } = $ result [ 5 ] ;
$ psn { $ result [ 1 ] . "*" . $ result [ 2 ] } = $ result [ 6 ] ;
}
foreach ( @ result ) {
push @ severnode1 , $ _ ;
2011-01-24 16:11:56 +00:00
}
2011-05-05 11:49:51 +00:00
2011-01-24 16:11:56 +00:00
$ severnode1 [ 3 ] = $ severnode1 [ 3 ] . '-0' ;
2010-12-07 05:47:07 +00:00
$ severnode1 [ 4 ] = $ ips [ 0 ] ;
2011-04-18 08:21:03 +00:00
$ severnode1 [ 0 ] = $ typetp ;
2010-12-07 05:47:07 +00:00
push @ severnode1 , $ rsp ;
2011-09-14 13:57:31 +00:00
$ matchflag = 0 ;
2011-01-24 16:11:56 +00:00
$ hostname = gethost_from_url_or_old ( $ ips [ 0 ] , $ severnode1 [ 0 ] , $ severnode1 [ 1 ] , $ severnode1 [ 2 ] ,
2011-09-14 13:57:31 +00:00
$ severnode1 [ 3 ] , $ ips [ 0 ] , $ severnode1 [ 8 ] , $ severnode1 [ 5 ] , $ severnode1 [ 6 ] , undef , \ $ matchflag ) ;
trace ( $ request , " The node $ips[0] match the old data and got the new name $hostname, $matchflag" , 1 ) ;
if ( $ hostname ) {
2011-01-24 16:11:56 +00:00
$ outhash { $ hostname } = \ @ severnode1 ;
2011-09-14 13:57:31 +00:00
push @ matchnodes , $ hostname if ( $ matchflag eq 1 ) ;
2011-02-24 11:57:44 +00:00
if ( length ( $ severnode1 [ 4 ] ) > $$ length ) {
$$ length = length ( $ severnode1 [ 4 ] ) ;
}
2011-09-14 13:57:31 +00:00
}
2011-06-02 01:59:20 +00:00
2011-01-11 15:12:52 +00:00
#begin to define another fsp/bpa
2011-02-24 09:22:12 +00:00
$ hostname = undef ;
2010-12-07 05:47:07 +00:00
foreach ( @ result ) {
2010-12-29 10:32:22 +00:00
push @ severnode2 , $ _ ;
2010-12-07 05:47:07 +00:00
}
2011-01-24 16:11:56 +00:00
$ severnode2 [ 3 ] = $ severnode2 [ 3 ] . '-1' ;
2010-12-07 05:47:07 +00:00
$ severnode2 [ 4 ] = $ ips [ 1 ] ;
2011-04-18 08:21:03 +00:00
$ severnode2 [ 0 ] = $ typetp ;
2010-12-07 05:47:07 +00:00
push @ severnode2 , $ rsp ;
2011-09-14 13:57:31 +00:00
$ matchflag = 0 ;
2011-01-24 16:11:56 +00:00
$ hostname = gethost_from_url_or_old ( $ ips [ 1 ] , $ severnode2 [ 0 ] , $ severnode2 [ 1 ] , $ severnode2 [ 2 ] ,
2011-09-14 13:57:31 +00:00
$ severnode2 [ 3 ] , $ ips [ 1 ] , $ severnode2 [ 8 ] , $ severnode2 [ 5 ] , $ severnode2 [ 6 ] , undef , \ $ matchflag ) ;
trace ( $ request , " The node $ips[1] match the old data and got the new name $hostname, $matchflag" , 1 ) ;
if ( $ hostname ) {
2011-01-24 16:11:56 +00:00
$ outhash { $ hostname } = \ @ severnode2 ;
2011-09-14 13:57:31 +00:00
push @ matchnodes , $ hostname if ( $ matchflag eq 1 ) ;
2011-02-24 11:57:44 +00:00
if ( length ( $ severnode2 [ 4 ] ) > $$ length ) {
$$ length = length ( $ severnode2 [ 4 ] ) ;
}
2011-09-14 13:57:31 +00:00
}
2011-05-24 09:27:41 +00:00
###########################################
# begin to define frame and cec
# As default, use Server-$result[1]-SN$result[2] as hostname
# put the definitions into %outhash
###########################################
2011-09-14 13:57:31 +00:00
trace ( $ request , "......Second define frame and cec " , 1 ) ;
2011-05-24 09:27:41 +00:00
$ hostname = undef ;
$ host = "Server-$result[1]-SN$result[2]" ;
unless ( exists ( $ outhash { $ host } ) )
{
if ( $ type eq SERVICE_BPA )
{
$ result [ 0 ] = TYPE_FRAME ;
}
else
{
$ result [ 0 ] = TYPE_CEC ;
}
# IP of frame and cec should be null
$ result [ 3 ] = "" ;
# side of frame and cec should be null
$ result [ 4 ] = "" ;
push @ result , $ rsp ;
2011-09-14 13:57:31 +00:00
$ matchflag = 0 ;
2011-05-24 09:27:41 +00:00
$ hostname = gethost_from_url_or_old ( $ host , $ result [ 0 ] , $ result [ 1 ] , $ result [ 2 ] ,
2011-09-14 13:57:31 +00:00
$ result [ 3 ] , $ result [ 4 ] , $ result [ 8 ] , $ result [ 5 ] , $ result [ 6 ] , undef , \ $ matchflag ) ;
trace ( $ request , " The node $host match the old data and got the new name $hostname, $matchflag" , 1 ) ;
if ( $ hostname ) {
2011-05-24 09:27:41 +00:00
$ outhash { $ hostname } = \ @ result ;
2011-09-14 13:57:31 +00:00
push @ matchnodes , $ hostname if ( $ matchflag eq 1 ) ;
2011-05-24 09:27:41 +00:00
}
2011-09-14 13:57:31 +00:00
2011-05-24 09:27:41 +00:00
}
2011-12-21 02:25:14 +00:00
} elsif ( $ type eq SERVICE_HMC ) {
2011-01-24 16:11:56 +00:00
###########################################
2010-12-07 05:47:07 +00:00
# for HMC
2011-01-24 16:11:56 +00:00
###########################################
2011-09-14 13:57:31 +00:00
trace ( $ request , "......Begin to define hmc " , 1 ) ;
$ matchflag = 0 ;
2011-12-21 10:46:17 +00:00
$ host = gethost_from_url ( $ request , $ rsp , \ $ matchflag , @ result ) ;
2011-09-14 13:57:31 +00:00
trace ( $ request , " The node $host match the old data and got the new name $host, $matchflag" , 1 ) ;
2009-10-20 13:37:44 +00:00
if ( ! defined ( $ host ) ) {
next ;
}
2011-09-14 13:57:31 +00:00
push @ matchnodes , $ host if ( $ matchflag eq 1 ) ;
2010-12-07 05:47:07 +00:00
###########################################
2011-09-18 14:38:15 +00:00
# Find IP for HMC
# 1. If it can match the definintion made by
# xcatsetup, just return the ip matched
# 2. If there is -i flag, return the ip that
# within the same subnet with opt{i}
# 3. If no match and no flag -i, return first
2010-12-07 05:47:07 +00:00
###########################################
2011-06-02 01:59:20 +00:00
2011-04-13 05:32:26 +00:00
# we need to hide ipv6 ip address temporarily
2011-06-02 01:59:20 +00:00
my @ iptmp = split /,/ , $ result [ 4 ] ;
2011-04-13 05:29:20 +00:00
my @ iptmp2 ;
2011-09-18 14:38:15 +00:00
my $ matchhmc = 0 ;
foreach my $ ii ( @ iptmp ) {
if ( $ ii =~ /\d+\.\d+\.\d+\.\d+/ ) {
$ matchflag = 1 ;
my $ newhost = match_ip_defined_by_xcatsetup ( $ ii , \ $ matchflag ) ;
push @ matchnodes , $ host if ( $ matchflag eq 1 ) ;
if ( $ newhost ) {
$ host = $ newhost ;
$ matchhmc = 1 ;
$ result [ 4 ] = $ ii ;
} elsif ( exists ( $ opt { i } ) ) {
2011-10-19 08:58:50 +00:00
my @ userip = split /,/ , $ opt { i } ;
foreach my $ uip ( @ userip ) {
my $ subnet = $ addr { $ uip } { subnet } ;
my $ netmask = $ addr { $ uip } { netmask } ;
if ( xCAT::NetworkUtils - > ishostinsubnet ( $ ii , $ netmask , $ subnet ) ) {
$ matchhmc = 1 ;
$ result [ 4 ] = $ ii ;
next ;
}
2011-09-18 14:38:15 +00:00
}
}
push @ iptmp2 , $ ii ;
2011-04-13 05:29:20 +00:00
}
}
2011-09-18 14:38:15 +00:00
unless ( $ matchhmc ) {
#$result[4] = join( ",", @iptmp2);
$ result [ 4 ] = $ iptmp2 [ 0 ] ;
}
2011-04-13 05:29:20 +00:00
# end of hidden ipv6 ip address
2010-12-07 05:47:07 +00:00
$ result [ 4 ] =~ s/,/ /g ;
my $ ip = $ result [ 4 ] ;
2011-01-24 16:11:56 +00:00
2010-12-07 05:47:07 +00:00
###########################################
# Save longest IP for formatting purposes
###########################################
if ( length ( $ ip ) > $$ length ) {
$$ length = length ( $ ip ) ;
}
2011-01-24 16:11:56 +00:00
2010-12-07 05:47:07 +00:00
push @ result , $ rsp ;
2011-01-24 16:11:56 +00:00
2010-12-07 05:47:07 +00:00
$ result [ 0 ] = $ service_slp { $ type } ;
$ outhash { $ host } = \ @ result ;
2011-01-11 15:12:52 +00:00
2011-12-21 02:25:14 +00:00
} else {
###########################################
# for CMM
###########################################
trace ( $ request , "......Begin to define cmm " , 1 ) ;
$ matchflag = 0 ;
2011-12-21 10:46:17 +00:00
$ host = gethost_from_url ( $ request , $ rsp , \ $ matchflag , @ result ) ;
2011-12-21 02:25:14 +00:00
trace ( $ request , " The node $host match the old data and got the new name $host, $matchflag" , 1 ) ;
2011-12-21 10:46:17 +00:00
if ( ! defined ( $ host ) ) {
$ host = $ result [ 5 ] ;
}
2011-12-21 02:25:14 +00:00
if ( ! defined ( $ host ) ) {
next ;
}
push @ matchnodes , $ host if ( $ matchflag eq 1 ) ;
$ result [ 0 ] = $ service_slp { $ type } ;
if ( $ host =~ /^(\w+)\(.*\)/ ) {
$ host = $ 1 ;
}
$ otherinterfacehash { $ host } { otherinterfaces } = $ result [ 4 ] ;
$ outhash { $ host } = \ @ result ;
}
}
2011-03-04 01:54:43 +00:00
############################################################
# find out the cageid for the cec
2011-06-02 01:59:20 +00:00
############################################################
2011-10-18 05:41:03 +00:00
#trace( $request, "\n\nThe cageid need to be adjust,because some secondary fsp return wrong side value ( always 0)", 1);
#foreach my $idtmp( keys(%fid1) )
#{
# if ($fid1{$idtmp} > 0)
# {
# $cid{$idtmp} = $fid1{$idtmp};
# } elsif ($fid2{$idtmp} > 0)
# {
# $cid{$idtmp} = $fid2{$idtmp};
# } else {
# $cid{$idtmp} = 0;
# }
#}
#foreach ( keys(%fid2) )
#{
# if (!defined($cid{$_}))
# {
# $cid{$_} = $fid2{$_};
# }
#}
2011-06-02 01:59:20 +00:00
2011-01-11 15:12:52 +00:00
############################################################
# -n flag to skip the existing node
2011-01-24 16:11:56 +00:00
############################################################
2011-01-11 15:12:52 +00:00
my % vpd_table_hash ;
my $ vpdtab = xCAT::Table - > new ( 'vpd' ) ;
my @ entries = $ vpdtab - > getAllNodeAttribs ( [ 'node' , 'mtm' , 'serial' , 'side' ] ) ;
for my $ entry ( @ entries ) {
if ( $ entry - > { mtm } and $ entry - > { serial } ) {
$ vpd_table_hash { $ entry - > { mtm } . '*' . $ entry - > { serial } . '-' . $ entry - > { side } } = $ entry - > { 'node' } ;
}
}
2011-01-24 16:11:56 +00:00
2009-10-20 13:37:44 +00:00
##########################################################
2011-01-24 16:11:56 +00:00
# Find the parent and mac and set them as the 10th and 11th
2010-12-07 05:47:07 +00:00
# of the attribute of the server nodes
2011-01-24 16:11:56 +00:00
##########################################################
2011-09-14 13:57:31 +00:00
my % hash ;
2010-12-07 05:47:07 +00:00
my $ mac ;
2011-01-24 16:11:56 +00:00
my $ parent ;
2011-09-14 13:57:31 +00:00
my $ newhostname ;
trace ( $ request , "\n\n\nBegin to find cec's id, parent and hostname, find frame's hostname" , 1 ) ;
2010-12-07 05:47:07 +00:00
foreach my $ h ( keys % outhash ) {
my $ data = $ outhash { $ h } ;
my $ type = @$ data [ 0 ] ;
my $ mtm = @$ data [ 1 ] ;
2011-01-24 16:11:56 +00:00
my $ sn = @$ data [ 2 ] ;
2011-01-11 15:12:52 +00:00
my $ side = @$ data [ 3 ] ;
2011-01-11 16:00:56 +00:00
my $ ip0 ;
if ( $ h =~ /^([^\(]+)\(([^\)]+)\)$/ ) {
$ ip0 = $ 2 ;
} else {
$ ip0 = @$ data [ 4 ] ;
}
2010-12-07 05:47:07 +00:00
my $ bpamtm = @$ data [ 5 ] ;
2011-01-11 15:12:52 +00:00
my $ bpasn = @$ data [ 6 ] ;
2011-01-24 16:11:56 +00:00
my $ cagenum = @$ data [ 8 ] ;
2011-12-21 02:25:14 +00:00
if ( $ type eq TYPE_CMM ) {
$ hash { $ h } = $ data ;
next ;
}
2011-09-14 13:57:31 +00:00
trace ( $ request , "......The node is $h, type is $type, mtm is $mtm, sn is $sn, side is $side, ip is $ip0, bpamtm is $bpamtm, bpasn is $bpasn, cagenum is $cagenum" , 1 ) ;
2011-02-24 09:22:12 +00:00
# find cageid for the secondary fsp node
2011-03-04 01:54:43 +00:00
if ( $ type =~ /^FSP$/ || $ type =~ /^CEC$/ ) {
@$ data [ 8 ] = $ cid { $ mtm . "*" . $ sn } ;
2011-10-18 05:41:03 +00:00
@$ data [ 5 ] = $ pmtm { $ mtm . "*" . $ sn } ;
@$ data [ 6 ] = $ psn { $ mtm . "*" . $ sn } ;
$ bpamtm = @$ data [ 5 ] ;
$ bpasn = @$ data [ 6 ] ;
$ cagenum = @$ data [ 8 ] ;
trace ( $ request , " Adjust cageid to @$data[8], bpamtm to @$data[5], bpasn to @$data[6]" , 1 ) ;
2011-02-24 09:22:12 +00:00
}
2011-06-02 01:59:20 +00:00
2011-01-11 15:12:52 +00:00
# if there is a -n flag, skip the existed nodes
2011-09-14 13:57:31 +00:00
if ( $ type =~ /^HMC$/ ) {
$ matchflag = 0 ;
$ newhostname = match_hosts_defined_by_xcatsetup ( $ h , $ type , $ mtm , $ sn , $ side , $ ip0 , $ cagenum , $ bpamtm , $ bpasn , $ parent , \ $ matchflag ) ;
if ( $ newhostname ) {
$ hash { $ newhostname } = $ data ;
push @ matchnodes , $ newhostname ;
} else {
$ hash { $ h } = $ data ;
2011-01-11 15:12:52 +00:00
}
2011-09-14 13:57:31 +00:00
trace ( $ request , " HMC $h macth the data defined by xcatsetup and got name $newhostname" , 1 ) ;
2011-01-11 15:12:52 +00:00
}
2011-09-14 13:57:31 +00:00
2011-01-11 15:12:52 +00:00
# begin to find parent
2011-09-14 13:57:31 +00:00
next unless ( $ type eq TYPE_CEC or $ type eq TYPE_FRAME ) ;
2011-05-05 11:49:51 +00:00
my $ newname ;
2010-12-07 05:47:07 +00:00
foreach my $ h1 ( keys % outhash ) {
2010-12-29 10:32:22 +00:00
my $ data1 = $ outhash { $ h1 } ;
2010-12-07 05:47:07 +00:00
my $ type1 = @$ data1 [ 0 ] ;
my $ mtm1 = @$ data1 [ 1 ] ;
my $ sn1 = @$ data1 [ 2 ] ;
2011-10-21 15:10:16 +00:00
if ( $ mtm1 eq $ bpamtm and $ sn1 eq $ bpasn and $ type1 eq "frame" ) {
$ parent = $ h1 ; # CEC's parent is Frame
2010-12-29 10:32:22 +00:00
last ;
2010-12-15 08:28:53 +00:00
} else {
2011-01-11 15:12:52 +00:00
$ parent = undef ; # Frame and HMC have no parent
2010-02-09 08:58:10 +00:00
}
}
2011-01-24 16:11:56 +00:00
2011-05-10 07:37:01 +00:00
if ( ! defined ( $ parent ) ) {
if ( exists $ vpd_table_hash { $ bpamtm . '*' . $ bpasn . '-' } ) {
my $ existing_node = $ vpd_table_hash { $ bpamtm . '*' . $ bpasn . '-' } ;
my $ type1 = xCAT::DBobjUtils - > getnodetype ( $ existing_node ) ;
if ( $ type1 eq "frame" and ( $ type eq TYPE_BPA or $ type eq TYPE_CEC ) ) {
$ parent = $ existing_node ;
} elsif ( $ type1 eq "cec" and $ type eq TYPE_FSP ) {
$ parent = $ existing_node ;
}
}
}
2010-12-07 05:47:07 +00:00
push @$ data , $ parent ;
2011-09-14 13:57:31 +00:00
push @$ data , undef ; #This is for $data[9], which is mac address;
trace ( $ request , " $h find the parent $parent." , 1 ) ;
2011-01-24 16:11:56 +00:00
2011-10-23 09:29:32 +00:00
##########################################################
2010-12-07 05:47:07 +00:00
#find the mac address
2011-09-14 13:57:31 +00:00
##########################################################
$ newhostname = match_hosts_defined_by_xcatsetup ( $ h , $ type , $ mtm , $ sn , $ side , $ ip0 , $ cagenum , $ bpamtm , $ bpasn , $ parent , \ $ matchflag ) ;
if ( $ newhostname ) {
$ hash { $ newhostname } = $ data ;
push @ matchnodes , $ newhostname ;
2010-12-07 05:47:07 +00:00
} else {
2011-09-14 13:57:31 +00:00
$ hash { $ h } = $ data ;
2010-02-05 16:36:16 +00:00
}
2011-09-14 13:57:31 +00:00
trace ( $ request , " CEC $h macth the data defined by xcatsetup and got name $newhostname" , 1 ) ;
}
2011-06-02 01:59:20 +00:00
2011-09-14 13:57:31 +00:00
##########################################################
# Find the parent,hostname and mac address for fsp/bpa
# Find mac address for HMC
##########################################################
trace ( $ request , "\n\n\nBegin to find parent and hostname for fsp/bpa: " , 1 ) ;
foreach my $ h ( keys % outhash ) {
my $ data = $ outhash { $ h } ;
my $ type = @$ data [ 0 ] ;
my $ mtm = @$ data [ 1 ] ;
my $ sn = @$ data [ 2 ] ;
my $ side = @$ data [ 3 ] ;
my $ ip0 ;
if ( $ h =~ /^([^\(]+)\(([^\)]+)\)$/ ) {
$ ip0 = $ 2 ;
} else {
$ ip0 = @$ data [ 4 ] ;
2011-06-02 01:59:20 +00:00
}
2011-09-14 13:57:31 +00:00
my $ bpamtm = @$ data [ 5 ] ;
my $ bpasn = @$ data [ 6 ] ;
my $ cagenum = @$ data [ 8 ] ;
2011-06-02 01:59:20 +00:00
2011-12-21 02:25:14 +00:00
next if ( $ type eq TYPE_CMM ) ;
2011-09-14 13:57:31 +00:00
trace ( $ request , "......The node is $h" , 1 ) ;
##########################################################
# begin to find fsp/bpa's parent
##########################################################
2011-12-07 10:27:06 +00:00
if ( $ type eq TYPE_BPA or $ type eq TYPE_FSP ) {
foreach my $ h1 ( keys % hash ) {
my $ data1 = $ hash { $ h1 } ;
my $ type1 = @$ data1 [ 0 ] ;
my $ mtm1 = @$ data1 [ 1 ] ;
my $ sn1 = @$ data1 [ 2 ] ;
if ( ( ( $ type1 eq TYPE_FRAME and $ type eq TYPE_BPA ) or ( $ type1 eq TYPE_CEC and $ type eq TYPE_FSP ) ) and ( $ mtm1 eq $ mtm and $ sn1 eq $ sn ) ) {
$ parent = $ h1 ; # FSP's parent is CEC
last ;
} else {
$ parent = undef ; # HMC have no parent
}
2011-09-14 13:57:31 +00:00
}
2011-12-07 10:27:06 +00:00
push @$ data , $ parent ; #This is for $data[8];
trace ( $ request , " Find the $h parent $parent." , 1 ) ;
} else {
push @$ data , undef ;
2011-05-05 11:49:51 +00:00
}
2011-09-14 13:57:31 +00:00
##########################################################
# match fsp/bpa nodes with the definition made by xcatsetup
# keep the otherinterfaces for the nodes.
##########################################################
2011-12-07 10:27:06 +00:00
if ( $ type eq TYPE_BPA or $ type eq TYPE_FSP ) {
$ newhostname = match_hosts_defined_by_xcatsetup ( $ h , $ type , $ mtm , $ sn , $ side , $ ip0 , $ cagenum , $ bpamtm , $ bpasn , $ parent ) ;
if ( $ newhostname ) {
trace ( $ request , " Find the new hostname $newhostname." , 1 ) ;
$ hash { $ newhostname } = $ data ;
push @ matchnodes , $ newhostname ;
$ otherinterfacehash { $ newhostname } { otherinterfaces } = $ ip0 ;
trace ( $ request , " Keep the node ip $ip0 in $newhostname otherinterfaces" , 1 ) ;
} else {
$ hash { $ h } = $ data ;
$ otherinterfacehash { $ h } { otherinterfaces } = $ ip0 ;
trace ( $ request , " Keep the node ip $ip0 in $h otherinterfaces" , 1 ) ;
}
}
2011-09-14 13:57:31 +00:00
##########################################################
2011-12-07 10:27:06 +00:00
# find the mac address for the fsp/bpa/hmc nodes.
2011-09-14 13:57:31 +00:00
##########################################################
2011-12-07 10:27:06 +00:00
if ( $ type eq TYPE_BPA or $ type eq TYPE_FSP or $ type eq TYPE_HMC ) {
$ mac = match_ip_mac ( $ ip0 ) ;
# This is originally used to check the invalid mac address in AIX, but failed to do it.
#unless ( $mac =~ /\w+\:\w+\:\w+\:\w+\:\w+\:\w+/ ) { $mac = undef;}
push @$ data , $ mac ; #This is for $data[9], which is mac address;
trace ( $ request , " Find the $h mac $mac." , 1 ) ;
} else {
push @$ data , undef ;
}
2011-09-14 13:57:31 +00:00
}
##########################################################
# If there is -n flag, skip the matched nodes
##########################################################
if ( exists ( $ opt { n } ) ) {
trace ( $ request , "\n\n\nThere is -n flag, skip these nodes:\n" , 1 ) ;
for my $ matchednode ( @ matchnodes ) {
if ( $ hash { $ matchednode } ) {
trace ( $ request , "$matchednode," , 1 ) ;
delete $ hash { $ matchednode } ;
}
2011-06-02 01:59:20 +00:00
}
2010-02-04 08:12:33 +00:00
}
2011-01-24 16:11:56 +00:00
2010-02-04 08:12:33 +00:00
return ( \ % hash ) ;
2009-10-20 13:37:44 +00:00
}
##########################################################################
# Write result to xCat database
##########################################################################
sub xCATdB {
my $ outhash = shift ;
my % keyhash = ( ) ;
my % updates = ( ) ;
my % sn_node = ( ) ;
2011-12-21 10:46:17 +00:00
########################################
# Update database if the name changed
########################################
my % db = ( ) ;
my @ tabs = qw( ppc vpd nodehm nodelist nodetype ppcdirect hosts mac mp ) ;
foreach ( @ tabs ) {
$ db { $ _ } = xCAT::Table - > new ( $ _ ) ;
if ( ! $ db { $ _ } ) {
return ( "Error opening '$_'" ) ;
}
}
my @ vpdlist = $ db { vpd } - > getAllNodeAttribs ( [ 'node' , 'serial' , 'mtm' , 'side' ] ) ;
my @ hostslist = $ db { hosts } - > getAllNodeAttribs ( [ 'node' , 'ip' ] ) ;
my @ ppclist = $ db { ppc } - > getAllNodeAttribs ( [ 'node' , 'hcp' , 'id' ,
'pprofile' , 'parent' , 'supernode' ,
'comments' , 'disable' ] ) ;
my @ maclist = $ db { mac } - > getAllNodeAttribs ( [ 'node' , 'mac' ] ) ;
########################################
# Begin to write each node
########################################
2010-02-04 08:12:33 +00:00
foreach my $ hostname ( keys %$ outhash ) {
2010-12-07 05:47:07 +00:00
my $ data = $ outhash - > { $ hostname } ;
my $ name = $ hostname ;
my $ type = @$ data [ 0 ] ;
my $ model = @$ data [ 1 ] ;
my $ serial = @$ data [ 2 ] ;
my $ side = @$ data [ 3 ] ;
my $ ip = @$ data [ 4 ] ;
2011-01-24 16:11:56 +00:00
my $ frameid = @$ data [ 7 ] ;
2010-12-07 05:47:07 +00:00
my $ cageid = @$ data [ 8 ] ;
2011-01-24 16:11:56 +00:00
my $ parent = @$ data [ 10 ] ;
2010-12-07 05:47:07 +00:00
my $ mac = @$ data [ 11 ] ;
2011-04-18 08:21:03 +00:00
my $ otherif = $ otherinterfacehash { $ hostname } { otherinterfaces } ;
2011-01-24 16:11:56 +00:00
my $ prof = "" ;
2010-12-07 05:47:07 +00:00
#######################################
2011-01-11 15:12:52 +00:00
# FSP/BPA don't need to be in host table,
2010-12-07 05:47:07 +00:00
# CEC/FRAME have no ip so don't need neither
# only HMC need to be and could be writen to host table
#######################################
2011-12-21 02:25:14 +00:00
if ( $ hostname =~ /^([^\(]+)\(([^\)]+)\)$/ ) {
2009-10-20 13:37:44 +00:00
$ name = $ 1 ;
2010-02-04 08:12:33 +00:00
$ ip = $ 2 ;
2009-10-20 13:37:44 +00:00
}
2011-01-24 16:11:56 +00:00
2009-12-28 08:10:42 +00:00
########################################
2010-12-07 05:47:07 +00:00
# Update hosts table
2009-12-28 08:10:42 +00:00
########################################
2010-02-04 08:12:33 +00:00
if ( exists ( $ opt { updatehosts } ) ) {
my $ hostip = writehost ( $ name , $ ip ) ;
}
2009-11-13 12:56:37 +00:00
2010-12-07 05:47:07 +00:00
########################################
# Write result to every tables,
# every entry write once, time-consuming!
2011-01-24 16:11:56 +00:00
########################################
2009-10-20 13:37:44 +00:00
if ( $ type =~ /^BPA$/ ) {
2010-12-07 05:47:07 +00:00
########################################
# BPA: name=hostname, id=slotid, mtms=mtms
# side=side, prof=null, frame=parent,
# ip=ip, mac=mac
2011-01-24 16:11:56 +00:00
# we will not write ip to hosts table
########################################
my $ ifip = xCAT::Utils - > isIpaddr ( $ name ) ;
if ( $ ifip ) {
my $ values = join ( "," ,
lc ( $ type ) , $ name , $ frameid , $ model , $ serial , $ side , $ name , $ prof , $ parent , "" , $ mac ) ;
xCAT::PPCdb:: add_ppc ( lc ( $ type ) , [ $ values ] , 0 , 1 ) ;
2011-02-21 05:50:02 +00:00
#if ( exists($::UPDATE_CACHE{$name}))
#{
# xCAT::PPCdb::update_node_attribs(
# "bpa","bpa",$name,$frameid,$model,$serial,$side,"","",$parent,"",\%db, $::UPDATE_CACHE{$name},\@ppclist);
#}
2011-01-24 16:11:56 +00:00
} else
{
my $ values = join ( "," ,
lc ( $ type ) , $ name , $ frameid , $ model , $ serial , $ side , $ name , $ prof , $ parent , $ ip , $ mac ) ;
xCAT::PPCdb:: add_ppc ( lc ( $ type ) , [ $ values ] , 0 , 1 ) ;
2011-02-21 05:50:02 +00:00
#if ( exists($::UPDATE_CACHE{$name}))
#{
# xCAT::PPCdb::update_node_attribs(
# "bpa","bpa",$name,$frameid,$model,$serial,$side,"","",$parent,$ip,\%db, $::UPDATE_CACHE{$name},\@ppclist);
#}
2011-01-24 16:11:56 +00:00
}
2010-02-04 08:12:33 +00:00
} elsif ( $ type =~ /^(HMC|IVM)$/ ) {
2010-12-07 05:47:07 +00:00
########################################
# HMC: name=hostname, ip=ip, mac=mac
2011-01-24 16:11:56 +00:00
########################################
2011-12-07 10:27:06 +00:00
xCAT::PPCdb:: add_ppchcp ( lc ( $ type ) , "$name,$mac,$model,$serial,$ip" , 1 ) ;
2011-12-21 10:46:17 +00:00
} elsif ( $ type =~ /^FSP$/ ) {
2009-10-20 13:37:44 +00:00
########################################
2011-01-24 16:11:56 +00:00
# FSP: name=hostname, id=slotid, mtms=mtms,
# side=side, prof=null, frame=parent,
2010-12-07 05:47:07 +00:00
# ip=ip, mac=mac
2011-01-24 16:11:56 +00:00
# we will not write ip to hosts table
2009-10-20 13:37:44 +00:00
########################################
2011-01-24 16:11:56 +00:00
my $ ifip = xCAT::Utils - > isIpaddr ( $ name ) ;
if ( $ ifip ) {
my $ values = join (
"," , lc ( $ type ) , $ name , $ cageid , $ model , $ serial , $ side , $ name , $ prof , $ parent , "" , $ mac ) ;
xCAT::PPCdb:: add_ppc ( "fsp" , [ $ values ] , 0 , 1 ) ;
2011-02-21 05:50:02 +00:00
#if ( exists($::UPDATE_CACHE{$name}))
#{
# xCAT::PPCdb::update_node_attribs(
# "fsp","fsp",$name,$cageid,$model,$serial,$side,"","",$parent,"",\%db, $::UPDATE_CACHE{$name},\@ppclist);
#}
2011-01-24 16:11:56 +00:00
} else
{
my $ values = join (
"," , lc ( $ type ) , $ name , $ cageid , $ model , $ serial , $ side , $ name , $ prof , $ parent , $ ip , $ mac ) ;
xCAT::PPCdb:: add_ppc ( "fsp" , [ $ values ] , 0 , 1 ) ;
2011-02-21 05:50:02 +00:00
#if ( exists($::UPDATE_CACHE{$name}))
#{
# xCAT::PPCdb::update_node_attribs(
# "fsp","fsp",$name,$cageid,$model,$serial,$side,"","",$parent,$ip,\%db, $::UPDATE_CACHE{$name},\@ppclist);
#}
2011-01-24 16:11:56 +00:00
}
2011-12-21 10:46:17 +00:00
} elsif ( $ type =~ /^(RSA|MM)$/ ) {
2010-02-09 08:58:10 +00:00
xCAT::PPCdb:: add_systemX ( $ type , $ name , $ data ) ;
2011-12-21 10:46:17 +00:00
} elsif ( $ type =~ /^FRAME$/ ) {
2010-12-07 05:47:07 +00:00
########################################
# Frame: type=frame, name=hostname, cageid=0,
# mtms=mtms, side=null, prof=null, frame=itself,
# ip=null, mac=null
########################################
my $ mac = "" ;
my $ side = "" ;
2010-12-07 08:12:36 +00:00
my $ ip = "" ;
2010-12-07 05:47:07 +00:00
my $ values = join ( "," ,
2011-01-24 16:11:56 +00:00
lc ( $ type ) , $ name , $ frameid , $ model , $ serial , $ side , $ name , $ prof , $ parent , $ ip , $ mac ) ;
2011-06-02 01:59:20 +00:00
# we should call update_node_attribs to Frame/CEC
2011-02-21 05:50:02 +00:00
# to make sure the information difined for FSP/BPA
2011-06-02 01:59:20 +00:00
# before can be kept.
2011-02-21 05:50:02 +00:00
if ( exists ( $ ::UPDATE_CACHE { $ model . "-" . $ serial } ) )
2011-01-24 16:11:56 +00:00
{
xCAT::PPCdb:: update_node_attribs ( "frame" , "frame" , $ name , $ frameid , $ model , $ serial , "" , "" , "" , $ parent , "" , \ % db , $ ::UPDATE_CACHE { $ name } , \ @ ppclist ) ;
2011-06-02 01:59:20 +00:00
}
2011-02-21 05:50:02 +00:00
xCAT::PPCdb:: add_ppc ( "frame" , [ $ values ] , 0 , 1 ) ;
#copy passwd for the bpas.
my $ rst = copypasswd ( $ name ) ;
unless ( $ rst )
{
# do something here
2011-06-02 01:59:20 +00:00
}
2011-12-21 10:46:17 +00:00
} elsif ( $ type =~ /^CEC$/ ) {
2010-12-07 05:47:07 +00:00
########################################
# CEC: type=cec, name=hostname, cageid=cageid
2010-12-07 08:12:36 +00:00
# mtms=mtms, side=null, prof=null,frame=parent
# ip=null,mac=mac
2010-12-07 05:47:07 +00:00
########################################
my $ mac = "" ;
2010-12-07 08:12:36 +00:00
my $ ip = "" ;
2010-12-07 05:47:07 +00:00
my $ side = "" ;
my $ values = join ( "," ,
2011-01-24 16:11:56 +00:00
lc ( $ type ) , $ name , $ cageid , $ model , $ serial , $ side , $ name , $ prof , $ parent , $ ip , $ mac ) ;
2011-06-02 01:59:20 +00:00
# we should call update_node_attribs to Frame/CEC
2011-02-21 05:50:02 +00:00
# to make sure the information difined for FSP/BPA
2011-06-02 01:59:20 +00:00
# before can be kept.
2011-02-21 05:50:02 +00:00
if ( exists ( $ ::UPDATE_CACHE { $ model . "-" . $ serial } ) )
2011-01-24 16:11:56 +00:00
{
xCAT::PPCdb:: update_node_attribs ( "cec" , "cec" , $ name , $ cageid , $ model , $ serial , "" , "" , "" , $ parent , "" , \ % db , $ ::UPDATE_CACHE { $ name } , \ @ ppclist ) ;
2011-06-02 01:59:20 +00:00
}
2011-02-21 05:50:02 +00:00
xCAT::PPCdb:: add_ppc ( "cec" , [ $ values ] , 0 , 1 ) ;
#copy passwd for the fsps.
my $ rst = copypasswd ( $ name ) ;
unless ( $ rst )
{
# do something here
2011-06-02 01:59:20 +00:00
}
2011-12-21 10:46:17 +00:00
} elsif ( $ type =~ /^CMM$/ ) {
2011-12-21 02:25:14 +00:00
$ db { nodelist } - > setNodeAttribs ( $ name , { node = > $ name , groups = > "cmm,all" } ) ;
$ db { vpd } - > setNodeAttribs ( $ name , { mtm = > $ model , serial = > $ serial } ) ;
$ db { nodetype } - > setNodeAttribs ( $ name , { nodetype = > "blade" } ) ;
$ db { nodehm } - > setNodeAttribs ( $ name , { mgt = > "blade" } ) ;
2011-12-21 10:46:17 +00:00
$ db { mp } - > setNodeAttribs ( $ name , { nodetype = > "cmm" , mpa = > $ name , id = > $ side } ) ;
2011-04-18 08:21:03 +00:00
}
2009-10-20 13:37:44 +00:00
}
2011-12-21 10:46:17 +00:00
foreach ( @ tabs ) {
$ db { $ _ } - > close ( ) ;
}
########################################
# Write otherinterface to the host table
########################################
my $ hoststab = xCAT::Table - > new ( 'hosts' ) ;
if ( $ hoststab and % otherinterfacehash ) {
$ hoststab - > setNodesAttribs ( \ % otherinterfacehash ) ;
}
$ hoststab - > close ( ) ;
2009-10-20 13:37:44 +00:00
}
2010-02-04 08:12:33 +00:00
##########################################################################
# Run makedhcp internally
##########################################################################
sub do_makedhcp {
2010-02-06 14:00:25 +00:00
my $ request = shift ;
2010-02-04 08:12:33 +00:00
my $ outhash = shift ;
my @ nodes ;
2010-02-06 14:00:25 +00:00
my $ string ;
2010-02-04 08:12:33 +00:00
my @ tabs = qw( hosts mac ) ;
my % db = ( ) ;
2011-01-24 16:11:56 +00:00
2010-02-04 08:12:33 +00:00
foreach ( @ tabs ) {
$ db { $ _ } = xCAT::Table - > new ( $ _ , - create = > 1 , - autocommit = > 1 ) ;
if ( ! $ db { $ _ } ) {
return ( "Error opening '$_'" ) ;
}
}
2010-02-06 14:00:25 +00:00
$ string = "\nStart to do makedhcp..\n" ;
send_msg ( $ request , 0 , $ string ) ;
2010-02-04 08:12:33 +00:00
#####################################
# Collect nodenames
#####################################
foreach my $ name ( keys %$ outhash ) {
if ( $ name =~ /^([^\(]+)\(([^\)]+)\)$/ ) {
$ name = $ 1 ;
}
2011-01-24 16:11:56 +00:00
2010-02-04 08:12:33 +00:00
#####################################
# Check if IP and mac are both
# existing for this node
#####################################
2011-02-11 07:38:02 +00:00
my $ ifip = xCAT::Utils - > isIpaddr ( $ name ) ;
2011-06-02 01:59:20 +00:00
unless ( $ ifip )
2011-02-11 07:38:02 +00:00
{
my ( $ hostsent ) = $ db { hosts } - > getNodeAttribs ( $ name , [ qw( ip ) ] ) ;
if ( ! $ hostsent or ! $ hostsent - > { ip } ) {
$ string = "Cannot find IP address for node $name during makedhcp, skip" ;
send_msg ( $ request , 0 , $ string ) ;
next ;
}
2010-02-04 08:12:33 +00:00
}
my ( $ macent ) = $ db { mac } - > getNodeAttribs ( $ name , [ qw( mac ) ] ) ;
if ( ! $ macent or ! $ macent - > { mac } ) {
2010-02-06 14:00:25 +00:00
$ string = "Cannot find MAC address for node $name during makedhcp, skip" ;
send_msg ( $ request , 0 , $ string ) ;
2010-02-04 08:12:33 +00:00
next ;
}
push @ nodes , $ name ;
}
my $ node = join "," , @ nodes ;
2010-02-06 14:00:25 +00:00
2010-06-22 03:04:56 +00:00
$ string = "Adding following nodes to dhcp server: \n$node\n" ;
2010-02-06 14:00:25 +00:00
send_msg ( $ request , 0 , $ string ) ;
2010-06-22 07:06:38 +00:00
my $ line = `/opt/xcat/sbin/makedhcp $node 2>&1` ;
2010-06-22 03:04:56 +00:00
send_msg ( $ request , 0 , $ line ) ;
2010-02-04 08:12:33 +00:00
2010-02-06 14:00:25 +00:00
send_msg ( $ request , 0 , "\nMakedhcp finished.\n" ) ;
2010-02-04 08:12:33 +00:00
return undef ;
}
##########################################################################
# Reset the network interfraces if necessary
##########################################################################
sub do_resetnet {
my $ req = shift ;
my $ outhash = shift ;
2010-02-05 16:36:16 +00:00
my $ reset_all = 1 ;
my $ namehash ;
2010-02-04 08:12:33 +00:00
my $ targets ;
2010-02-05 16:36:16 +00:00
my $ result ;
2011-06-13 02:34:39 +00:00
my $ nodetype ;
2010-02-04 08:12:33 +00:00
2011-05-23 09:47:25 +00:00
# this part was used for lsslp output data format.
# when invoked by rspconfig, the input data are different.
# so I re-write this part.
#if ( $outhash ) {
# $reset_all = 0;
# foreach my $name ( keys %$outhash ) {
# my $data = $outhash->{$name};
# my $ip = @$data[4];
# if ( $name =~ /^([^\(]+)\(([^\)]+)\)$/) {
# $name = $1;
# $ip = $2;
# }
# $namehash->{$name} = $ip;
# }
#}
2011-06-13 02:34:39 +00:00
my $ hoststab = xCAT::Table - > new ( 'hosts' ) ;
if ( ! $ hoststab ) {
send_msg ( $ req , 1 , "Error open hosts table" ) ;
return ( [ RC_ERROR ] ) ;
}
my $ mactab = xCAT::Table - > new ( 'mac' ) ;
if ( ! $ mactab ) {
send_msg ( $ req , 1 , "Error open mac table" ) ;
return ( [ RC_ERROR ] ) ;
}
2011-06-02 01:59:20 +00:00
if ( $ req - > { node } ) {
2010-02-05 16:36:16 +00:00
$ reset_all = 0 ;
2012-02-10 10:12:19 +00:00
my $ typehash = xCAT::DBobjUtils - > getnodetype ( \ @ { $ req - > { node } } ) ;
2011-06-02 01:59:20 +00:00
foreach my $ nn ( @ { $ req - > { node } } ) {
2012-02-10 10:12:19 +00:00
$ nodetype = $$ typehash { $ nn } ;
2011-05-23 09:47:25 +00:00
# this brunch is just for the xcat 2.6(+) database
2011-06-13 02:34:39 +00:00
if ( $ nodetype =~ /^(cec|frame)$/ ) {
2011-05-23 09:47:25 +00:00
my $ cnodep = xCAT::DBobjUtils - > getchildren ( $ nn ) ;
2011-06-13 02:34:39 +00:00
$ nodetype = ( $ nodetype =~ /^frame$/i ) ? "bpa" : "fsp" ;
2011-05-23 09:47:25 +00:00
if ( $ cnodep ) {
foreach my $ cnode ( @$ cnodep ) {
my $ ip = xCAT::Utils:: getNodeIPaddress ( $ cnode ) ;
$ namehash - > { $ cnode } = $ ip ;
}
} else {
send_msg ( $ req , 1 , "Can't get the fsp/bpa nodes for the $nn" ) ;
return ( [ RC_ERROR ] ) ;
2011-06-02 01:59:20 +00:00
}
# this brunch is just for the xcat 2.5(-) databse
2011-06-13 02:34:39 +00:00
} elsif ( $ nodetype =~ /^(fsp|bpa)$/ ) {
2011-06-02 01:59:20 +00:00
my $ ip = xCAT::Utils:: getNodeIPaddress ( $ nn ) ;
2011-05-23 09:47:25 +00:00
$ namehash - > { $ nn } = $ ip ;
2011-06-13 02:34:39 +00:00
} elsif ( ! $ nodetype ) {
send_msg ( $ req , 0 , "$nn: no nodetype defined, skipping network reset" ) ;
2010-02-05 16:36:16 +00:00
}
2010-02-04 08:12:33 +00:00
}
2011-06-02 01:59:20 +00:00
}
2010-02-06 14:00:25 +00:00
send_msg ( $ req , 0 , "\nStart to reset network..\n" ) ;
2010-02-05 16:36:16 +00:00
my $ ip_host ;
2011-06-13 02:34:39 +00:00
my @ hostslist = $ hoststab - > getAllNodeAttribs ( [ 'node' , 'otherinterfaces' ] ) ;
2010-02-05 16:36:16 +00:00
foreach my $ host ( @ hostslist ) {
my $ name = $ host - > { node } ;
2011-06-13 02:34:39 +00:00
my $ oi = $ host - > { otherinterfaces } ;
2010-02-04 08:12:33 +00:00
#####################################
2011-06-02 01:59:20 +00:00
# find the otherinterfaces for the
2011-05-23 09:47:25 +00:00
# specified nodes, or the all nodes
2010-02-04 08:12:33 +00:00
# Skip the node if the IP attributes
2011-06-15 15:42:33 +00:00
# is same as otherinterfaces
2010-02-04 08:12:33 +00:00
#####################################
2011-06-15 15:42:33 +00:00
if ( $ reset_all eq 0 && ! exists ( $ namehash - > { $ name } ) ) {
next ;
}
2011-06-30 02:36:39 +00:00
2011-07-04 02:05:20 +00:00
#if ( $namehash->{$name} ) {
# $hoststab->setNodeAttribs( $name,{otherinterfaces=>$namehash->{$name}} );
#}
2010-06-18 16:33:31 +00:00
2011-06-13 02:34:39 +00:00
if ( ! $ oi or $ oi eq $ namehash - > { $ name } ) {
2010-02-06 14:00:25 +00:00
send_msg ( $ req , 0 , "$name: same ip address, skipping network reset" ) ;
2010-02-05 16:36:16 +00:00
next ;
}
my $ mac = $ mactab - > getNodeAttribs ( $ name , [ qw( mac ) ] ) ;
if ( ! $ mac or ! $ mac - > { mac } ) {
2010-02-06 14:00:25 +00:00
send_msg ( $ req , 0 , "$name: no mac defined, skipping network reset" ) ;
2010-02-04 08:12:33 +00:00
next ;
}
#####################################
# Make the target that will reset its
# network interface
#####################################
2011-06-13 02:34:39 +00:00
$ targets - > { $ nodetype } - > { $ oi } - > { 'args' } = "0.0.0.0,$name" ;
$ targets - > { $ nodetype } - > { $ oi } - > { 'mac' } = $ mac - > { mac } ;
$ targets - > { $ nodetype } - > { $ oi } - > { 'name' } = $ name ;
$ targets - > { $ nodetype } - > { $ oi } - > { 'ip' } = $ oi ;
$ targets - > { $ nodetype } - > { $ oi } - > { 'type' } = $ nodetype ;
if ( $ nodetype !~ /^mm$/ ) {
my % netinfo = xCAT::DBobjUtils - > getNetwkInfo ( [ $ oi ] ) ;
$ targets - > { $ nodetype } - > { $ oi } - > { 'args' } . = ",$netinfo{$oi}{'gateway'},$netinfo{$oi}{'mask'}" ;
}
$ ip_host - > { $ oi } = $ name ;
2010-02-04 08:12:33 +00:00
}
2010-02-05 16:36:16 +00:00
$ result = undef ;
2010-02-04 08:12:33 +00:00
###########################################
# Update target hardware w/discovery info
###########################################
2010-02-05 16:36:16 +00:00
my ( $ fail_nodes , $ succeed_nodes ) = rspconfig ( $ req , $ targets ) ;
2010-02-06 14:00:25 +00:00
$ result = "\nReset network failed nodes:\n" ;
2010-02-05 16:36:16 +00:00
foreach my $ ip ( @$ fail_nodes ) {
if ( $ ip_host - > { $ ip } ) {
$ result . = $ ip_host - > { $ ip } . "," ;
}
}
2010-02-06 14:00:25 +00:00
$ result . = "\nReset network succeed nodes:\n" ;
2010-02-05 16:36:16 +00:00
foreach my $ ip ( @$ succeed_nodes ) {
if ( $ ip_host - > { $ ip } ) {
$ result . = $ ip_host - > { $ ip } . "," ;
2010-04-13 05:59:05 +00:00
my $ new_ip = $ hoststab - > getNodeAttribs ( $ ip_host - > { $ ip } , [ qw( ip ) ] ) ;
$ hoststab - > setNodeAttribs ( $ ip_host - > { $ ip } , { otherinterfaces = > $ new_ip - > { ip } } ) ;
2010-02-05 16:36:16 +00:00
}
}
2010-02-06 14:00:25 +00:00
$ result . = "\nReset network finished.\n" ;
2010-04-13 05:59:05 +00:00
$ hoststab - > close ( ) ;
2010-02-05 16:36:16 +00:00
send_msg ( $ req , 0 , $ result ) ;
2010-02-04 08:12:33 +00:00
return undef ;
}
2009-10-20 13:37:44 +00:00
##########################################################################
# Stanza formatting
##########################################################################
sub format_stanza {
my $ outhash = shift ;
my $ result ;
#####################################
# Write attributes
#####################################
2010-02-04 08:12:33 +00:00
foreach my $ name ( keys %$ outhash ) {
my @ data = @ { $ outhash - > { $ name } } ;
2009-10-20 13:37:44 +00:00
my $ type = lc ( $ data [ 0 ] ) ;
2009-12-28 08:10:42 +00:00
my $ ip = $ data [ 4 ] ;
2009-10-20 13:37:44 +00:00
my $ i = 0 ;
2010-01-25 09:12:14 +00:00
if ( $ name =~ /^([^\(]+)\(([^\)]+)\)$/ ) {
$ name = $ 1 ;
$ ip = $ 2 ;
}
2009-10-20 13:37:44 +00:00
#################################
# Node attributes
#################################
$ result . = "$name:\n\tobjtype=node\n" ;
#################################
# Add each attribute
#################################
2011-12-23 02:05:58 +00:00
if ( $ type eq "cmm" ) {
$ result . = "\tmpa=$name\n" ;
} else {
$ result . = "\thcp=$name\n" ;
}
2009-10-20 13:37:44 +00:00
foreach ( @ attribs ) {
my $ d = $ data [ $ i + + ] ;
2010-02-04 08:12:33 +00:00
if ( /^nodetype$/ ) {
2011-07-15 09:23:56 +00:00
$ d = $ globalnodetype { $ type } ;
2009-10-20 13:37:44 +00:00
} elsif ( /^groups$/ ) {
$ d = "$type,all" ;
} elsif ( /^mgt$/ ) {
2011-02-17 09:19:38 +00:00
if ( $ mgt { $ type } =~ /^cec$/ ) {
$ d = "fsp" ;
} elsif ( $ mgt { $ type } =~ /^frame$/ ) {
2011-06-02 01:59:20 +00:00
$ d = "bpa" ;
2011-02-17 09:19:38 +00:00
} else {
$ d = $ mgt { $ type } ;
}
2010-02-04 08:12:33 +00:00
} elsif ( /^id$/ ) {
2011-01-28 15:42:00 +00:00
if ( $ type =~ /^(fsp|bpa|cec|frame)$/ ) {
2011-01-24 16:11:56 +00:00
$ d = $ data [ $ i + + ] ;
2010-04-21 09:33:56 +00:00
} else {
$ i + + ;
next ;
2009-10-20 13:37:44 +00:00
}
2010-02-08 15:56:18 +00:00
$ i + + ;
2011-01-28 15:42:00 +00:00
} elsif ( /^side$/ ) {
2011-12-28 10:12:46 +00:00
if ( $ type !~ /^(fsp|bpa|cmm)$/ ) {
2009-12-28 08:10:42 +00:00
next ;
}
2011-01-28 15:42:00 +00:00
} elsif ( /^parent$/ ) {
if ( $ type !~ /^(fsp|bpa|cec)$/ ) {
next ;
}
2011-03-23 01:05:13 +00:00
} elsif ( /^ip$/ ) {
2011-12-23 02:05:58 +00:00
if ( $ type =~ /^(frame|cec|fsp|bpa|cmm)$/ ) {
2011-01-28 15:42:00 +00:00
next ;
2011-03-23 01:05:13 +00:00
}
2011-02-22 07:22:35 +00:00
} elsif ( /^hidden$/ ) {
2011-04-18 08:21:03 +00:00
if ( $ type =~ /^(fsp|bpa)$/ ) {
2011-02-22 07:22:35 +00:00
$ d = "1" ;
} else {
$ d = "0" ;
}
2011-04-18 08:21:03 +00:00
} elsif ( /^otherinterfaces$/ ) {
$ d = $ otherinterfacehash { $ name } { otherinterfaces } ;
2011-07-15 09:10:54 +00:00
} elsif ( /^hwtype$/ ) {
$ d = $ globlehwtype { $ type }
2008-06-03 19:09:21 +00:00
}
2010-02-04 08:12:33 +00:00
if ( ! defined ( $ d ) ) {
next ;
}
2009-10-20 13:37:44 +00:00
$ result . = "\t$_=$d\n" ;
2008-06-03 19:09:21 +00:00
}
2010-02-04 08:12:33 +00:00
if ( exists ( $ opt { updatehosts } ) ) {
$ result . = "\tip=$ip\n" ;
}
2008-06-17 17:18:02 +00:00
}
2009-10-20 13:37:44 +00:00
return ( $ result ) ;
2008-06-03 19:09:21 +00:00
}
2008-09-30 13:45:36 +00:00
2009-10-20 13:37:44 +00:00
##########################################################################
# XML formatting
##########################################################################
sub format_xml {
2009-01-19 09:06:39 +00:00
2009-10-20 13:37:44 +00:00
my $ outhash = shift ;
my $ xml ;
2009-01-19 09:06:39 +00:00
2009-10-20 13:37:44 +00:00
#####################################
# Create XML formatted attributes
#####################################
2010-02-04 08:12:33 +00:00
foreach my $ name ( keys %$ outhash ) {
my @ data = @ { $ outhash - > { $ name } } ;
2009-10-20 13:37:44 +00:00
my $ type = lc ( $ data [ 0 ] ) ;
2009-12-28 08:10:42 +00:00
my $ ip = $ data [ 4 ] ;
2009-10-20 13:37:44 +00:00
my $ i = 0 ;
2010-01-25 09:12:14 +00:00
if ( $ name =~ /^([^\(]+)\(([^\)]+)\)$/ ) {
$ name = $ 1 ;
$ ip = $ 2 ;
}
2009-10-20 13:37:44 +00:00
#################################
# Initialize hash reference
#################################
my $ href = {
Node = > { }
} ;
2010-02-04 08:12:33 +00:00
$ href - > { Node } - > { node } = $ name ;
if ( exists ( $ opt { updatehosts } ) ) {
$ href - > { Node } - > { ip } = $ ip ;
}
2009-10-20 13:37:44 +00:00
#################################
# Add each attribute
#################################
2011-12-23 02:05:58 +00:00
if ( $ type eq "cmm" ) {
$ href - > { Node } - > { "mpa" } = $ name ;
} else {
$ href - > { Node } - > { "hcp" } = $ name ;
}
2009-10-20 13:37:44 +00:00
foreach ( @ attribs ) {
my $ d = $ data [ $ i + + ] ;
if ( /^nodetype$/ ) {
2011-07-15 09:23:56 +00:00
$ d = $ globalnodetype { $ type } ;
2009-10-20 13:37:44 +00:00
} elsif ( /^groups$/ ) {
$ d = "$type,all" ;
} elsif ( /^mgt$/ ) {
2011-02-22 07:22:35 +00:00
if ( $ mgt { $ type } =~ /^cec$/ ) {
$ d = "fsp" ;
} elsif ( $ mgt { $ type } =~ /^frame$/ ) {
2011-06-02 01:59:20 +00:00
$ d = "bpa" ;
2011-02-22 07:22:35 +00:00
} else {
$ d = $ mgt { $ type } ;
}
2010-02-04 08:12:33 +00:00
} elsif ( /^id$/ ) {
2011-02-22 07:22:35 +00:00
if ( $ type =~ /^(fsp|bpa|cec|frame)$/ ) {
2010-02-04 08:12:33 +00:00
$ d = $ data [ $ i + + ] ;
2010-04-21 09:33:56 +00:00
} else {
$ i + + ;
next ;
2009-10-20 13:37:44 +00:00
}
2010-02-08 15:56:18 +00:00
$ i + + ;
2011-01-28 15:42:00 +00:00
} elsif ( /^side$/ ) {
2011-02-22 07:22:35 +00:00
if ( $ type !~ /^(fsp|bpa)$/ ) {
2009-12-28 08:10:42 +00:00
next ;
}
2011-01-28 15:42:00 +00:00
} elsif ( /^parent$/ ) {
if ( $ type !~ /^(fsp|bpa|cec)$/ ) {
next ;
}
2011-03-23 01:05:13 +00:00
} elsif ( /^ip$/ ) {
2011-12-23 02:05:58 +00:00
if ( $ type =~ /^(frame|cec|fsp|bpa|cmm)$/ ) {
2011-01-28 15:42:00 +00:00
next ;
2011-06-02 01:59:20 +00:00
}
2011-02-22 07:22:35 +00:00
} elsif ( /^hidden$/ ) {
if ( $ type =~ /^(fsp|bpa)$/ ) {
$ d = "1" ;
} else {
$ d = "0" ;
}
2011-04-18 08:21:03 +00:00
} elsif ( /^otherinterfaces$/ ) {
$ d = $ otherinterfacehash { $ name } { otherinfterfaces } ;
2011-07-15 09:10:54 +00:00
} elsif ( /^hwtype$/ ) {
$ d = $ globlehwtype { $ type }
2009-01-19 09:06:39 +00:00
}
2010-02-04 08:12:33 +00:00
if ( ! defined ( $ d ) ) {
next ;
}
2011-02-22 07:22:35 +00:00
2009-10-20 13:37:44 +00:00
$ href - > { Node } - > { $ _ } = $ d ;
2008-10-14 07:07:38 +00:00
}
2009-10-20 13:37:44 +00:00
#################################
# XML encoding
#################################
$ xml . = XMLout ( $ href ,
NoAttr = > 1 ,
KeyAttr = > [] ,
RootName = > undef ) ;
2009-10-20 11:31:17 +00:00
}
2009-10-20 13:37:44 +00:00
return ( $ xml ) ;
}
2009-10-20 11:31:17 +00:00
2010-02-06 14:00:25 +00:00
##########################################################################
# VPD table formatting
##########################################################################
sub format_table {
my $ outhash = shift ;
my $ result ;
#####################################
# Create XML formatted attributes
#####################################
foreach my $ name ( keys %$ outhash ) {
my @ data = @ { $ outhash - > { $ name } } ;
2011-01-24 16:11:56 +00:00
my $ type = lc ( $ data [ 0 ] ) ;
2011-04-18 08:21:03 +00:00
next if ( $ type =~ /^(fsp|bpa)$/ ) ;
2011-06-24 09:24:13 +00:00
$ result . = "$name:\n" ;
#$result .= "groups=frame,all\n";
$ result . = "\tobjtype=node\n" ;
#$result .= "\tnodetype=$type\n";
$ result . = "\tmtm=$data[1]\n" ;
$ result . = "\tserial=$data[2]\n" ;
2010-02-06 14:00:25 +00:00
}
return ( $ result ) ;
}
2009-10-20 11:31:17 +00:00
2009-10-20 13:37:44 +00:00
##########################################################################
# OpenSLP running on:
# P6 FSP
# P6 BPA
# IBM SLP running on:
# P5 FSP
# P5 BPA
# HMC
# MM
# RSA
# AIX SLP
# IVM
#
# Notes:
# IBM SLP requires trailing ':' (i.e. service:management-hardware.IBM:)
# There is one exception to this rule when dealing with FSP
# concrete" service types, it will work with/without the trailing ':'
# (i.e. "service:management-hardware.IBM:cec-service-processor[:]")
#
# OpenSLP does not support ':' at the end of services
# (i.e. service:management-hardware.IBM:). Unfortunately, IBM SLP
# requires it.
#
# Given the above, to collect all the above service types, it is
# necessary to multicast:
# (1) "service:management-*" for all IBM SLP hardware
# (2) "service:management-hardware.IBM" for OpenSLP hardware (P6 FSP/BPA)
# (IBM SLP hardware will not respond to this since there is no trailing ":")
#
# * One exception to the above rule is when using FSP concrete
# service type, it will work with/without the trailing ":"
# (i.e. "service:management-hardware.IBM:cec-service-processor[:]"
#
##########################################################################
2009-10-20 11:31:17 +00:00
2009-10-20 13:37:44 +00:00
##########################################################################
# Run IBM SLP version
##########################################################################
sub slp_query {
my $ request = shift ;
my $ callback = $ request - > { callback } ;
my $ cmd = $ opt { e } ;
#############################################
# slp_query not installed
#############################################
if ( ! - x $ cmd ) {
send_msg ( $ request , 1 , "Command not found: $cmd" ) ;
return ( [ RC_ERROR ] ) ;
2009-10-20 11:31:17 +00:00
}
2009-10-20 13:37:44 +00:00
#############################################
# slp_query runnable - dependent on libstdc++
# Test for usage statement.
#############################################
my $ output = `$cmd 2>&1` ;
if ( $ output !~ /slp_query --type=service-type-string/ ) {
send_msg ( $ request , 1 , $ output ) ;
return ( [ RC_ERROR ] ) ;
}
my $ result = runcmd ( $ request , $ cmd ) ;
return ( $ result ) ;
2009-10-20 11:31:17 +00:00
}
2009-10-20 13:37:44 +00:00
##########################################################################
# Run OpenSLP version
##########################################################################
sub slptool {
my $ request = shift ;
my $ cmd = SLPTOOL ;
my $ start ;
#########################################
# slptool not installed
#########################################
if ( ! - x $ cmd ) {
send_msg ( $ request , 1 , "Command not found: $cmd" ) ;
return ( [ RC_ERROR ] ) ;
}
#########################################
# slptool runnable - test for version
#########################################
my $ output = `$cmd -v 2>&1` ;
if ( $ output !~ /^slptool version = 1.2.1\nlibslp version = 1.2.1/ ) {
send_msg ( $ request , 1 , "Incorrect 'slptool' command installed" ) ;
return ( [ RC_ERROR ] ) ;
}
#########################################
# Select broadcast, convergence, etc
#########################################
my $ mode = selectmode ( $ request ) ;
if ( defined ( $ mode ) ) {
return ( $ mode ) ;
}
my $ result = runcmd ( $ request , $ cmd ) ;
return ( $ result ) ;
}
##########################################################################
# Select OpenSLP slptool broadcast convergence, etc
##########################################################################
sub selectmode {
my $ request = shift ;
my $ fname = SLP_CONF ;
my $ mode ;
my $ maxtimeout ;
my $ converge ;
##################################
# Select convergence
##################################
if ( exists ( $ opt { c } ) ) {
$ converge = join ( ',' , @ converge ) ;
##############################
# Maximum timeout
##############################
foreach ( @ converge ) {
$ maxtimeout += $ _ ;
2008-10-14 07:07:38 +00:00
}
2008-11-04 16:55:59 +00:00
}
2009-10-20 13:37:44 +00:00
##################################
# Select multicast or broadcast
##################################
if ( ! exists ( $ opt { m } ) ) {
$ mode = "true" ;
2008-10-14 07:07:38 +00:00
}
2009-10-20 13:37:44 +00:00
##################################
# slp.conf attributes
##################################
my % attr = (
"net.slp.multicastTimeouts" = > $ converge ,
"net.slp.isBroadcastOnly" = > $ mode ,
"net.slp.multicastMaximumWait" = > $ maxtimeout
) ;
if ( $ verbose ) {
my $ msg = ! defined ( $ mode ) ? "Multicasting SLP..." : "Broadcasting SLP..." ;
trace ( $ request , $ msg ) ;
}
##################################
# Open/read slp.conf
##################################
unless ( open ( CONF , $ fname ) ) {
send_msg ( $ request , 1 , "Error opening: '$fname'" ) ;
return ( [ RC_ERROR ] ) ;
}
my @ raw_data = <CONF> ;
close ( CONF ) ;
##################################
# Find attribute
##################################
foreach my $ name ( keys % attr ) {
my $ found = 0 ;
foreach ( @ raw_data ) {
if ( /^;*$name\s*=/ ) {
if ( ! defined ( $ attr { $ name } ) ) {
s/^;*($name\s*=\s*[\w,]+)/;$1/ ;
} elsif ( $ attr { $ name } == 0 ) {
s/^;*($name\s*=\s*[\w,]+)/$1/ ;
} else {
s/^;*$name\s*=\s*[\w,]+/$name = $attr{$name}/ ;
}
$ found = 1 ;
last ;
}
}
if ( ! $ found ) {
send_msg ( $ request , 1 , "'$name' not found in '$fname'" ) ;
return ( [ RC_ERROR ] ) ;
}
2008-10-14 07:07:38 +00:00
}
2009-10-20 13:37:44 +00:00
##################################
# Rewrite file contents
##################################
unless ( open ( CONF , "+>$fname" ) ) {
send_msg ( $ request , 1 , "Error opening: '$fname'" ) ;
return ( [ RC_ERROR ] ) ;
}
print CONF @ raw_data ;
close ( CONF ) ;
return undef ;
2009-10-20 11:31:17 +00:00
}
2008-10-14 07:07:38 +00:00
2009-10-20 13:37:44 +00:00
##########################################################################
# Run the SLP command
##########################################################################
sub runcmd {
my $ request = shift ;
my $ cmd = shift ;
my $ services = shift ;
my $ callback = $ request - > { callback } ;
2011-03-20 10:22:01 +00:00
my @ services = ( WILDCARD_SERVICE , P6_SERVICE , P7_SERVICE ) ;
2009-10-20 13:37:44 +00:00
my $ start ;
###########################################
# Query specific service; otherwise,
# query all hardware/software services
###########################################
if ( exists ( $ opt { s } ) ) {
@ services = $ request - > { service } ;
2009-10-20 11:31:17 +00:00
}
2008-06-03 19:09:21 +00:00
2009-10-20 13:37:44 +00:00
if ( $ verbose ) {
#######################################
# Write header for trace
#######################################
my $ tm = localtime ( time ) ;
my $ msg = "\n-------- $tm\nTime PID" ;
trace ( $ request , $ msg ) ;
}
###########################################
# Get/validate broadcast IPs
###########################################
my $ result = validate_ip ( $ request ) ;
my $ Rc = shift ( @$ result ) ;
if ( $ Rc ) {
send_msg ( $ request , 1 , @$ result [ 0 ] ) ;
return ( [ RC_ERROR ] ) ;
}
if ( $ verbose ) {
$ start = Time::HiRes:: gettimeofday ( ) ;
}
###########################################
# Fork one process per adapter
###########################################
my $ children = 0 ;
2011-01-11 15:12:52 +00:00
$ SIG { CHLD } = sub {
my $ rc_bak = $? ;
while ( waitpid ( - 1 , WNOHANG ) > 0 ) { $ children - - ; }
2009-10-20 13:37:44 +00:00
$? = $ rc_bak ;
} ;
my $ fds = new IO:: Select ;
foreach ( keys % ip_addr ) {
my $ pipe = fork_cmd ( $ request , $ _ , $ cmd , \ @ services ) ;
if ( $ pipe ) {
$ fds - > add ( $ pipe ) ;
$ children + + ;
2009-10-20 11:31:17 +00:00
}
2008-06-03 19:09:21 +00:00
}
2009-10-20 13:37:44 +00:00
###########################################
# Process slp responses from children
###########################################
while ( $ children > 0 ) {
child_response ( $ callback , $ fds ) ;
}
while ( child_response ( $ callback , $ fds ) ) { }
if ( $ verbose ) {
my $ elapsed = Time::HiRes:: gettimeofday ( ) - $ start ;
my $ msg = sprintf ( "Total SLP Time: %.3f sec\n" , $ elapsed ) ;
trace ( $ request , $ msg ) ;
}
###########################################
# Combined responses from all children
###########################################
my @ all_results = keys % slp_result ;
format_output ( $ request , \ @ all_results ) ;
return ( [ SUCCESS , \ @ all_results ] ) ;
}
##########################################################################
# 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 ) {
2009-10-20 13:37:44 +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
#############################
# rspconfig results
#############################
if ( @$ responses [ 0 ] =~ /^RSPCONFIG6sK4ci$/ ) {
shift @$ responses ;
my $ ip = shift ( @$ responses ) ;
$ rsp_result { $ ip } = $ responses ;
next ;
}
#############################
# 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
}
#############################################################################
# Preprocess request from xCat daemon and send request to service nodes
#############################################################################
sub preprocess_request {
my $ req = shift ;
if ( $ req - > { _xcatpreprocessed } - > [ 0 ] == 1 ) { return [ $ req ] ; }
my $ callback = shift ;
my @ requests ;
2009-10-20 11:31:17 +00:00
2011-03-21 09:25:16 +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
##########################################################################
2011-01-11 15:12:52 +00:00
# Distinguish
2009-10-20 13:37:44 +00:00
##########################################################################
sub disti_multi_node
{
my $ names = shift ;
2010-02-05 16:36:16 +00:00
my $ type = shift ;
my $ bpc_model = shift ;
my $ bpc_serial = shift ;
my $ frame_number = shift ;
my $ cage_number = shift ;
my $ side = shift ;
my $ mtm = shift ;
my $ serial = shift ;
2011-01-11 15:12:52 +00:00
return undef if ( $ type eq 'FSP' and ! defined $ cage_number ) ;
2010-02-05 16:36:16 +00:00
return undef if ( $ type eq 'BPA' and ! defined $ frame_number ) ;
my $ ppctab = xCAT::Table - > new ( 'ppc' ) ;
return undef if ( ! $ ppctab ) ;
my $ nodetypetab = xCAT::Table - > new ( 'nodetype' ) ;
return undef if ( ! $ nodetypetab ) ;
my $ vpdtab = xCAT::Table - > new ( 'vpd' ) ;
2010-02-06 14:00:25 +00:00
return undef if ( ! $ vpdtab ) ;
2011-01-11 15:12:52 +00:00
2009-10-20 13:37:44 +00:00
my @ nodes = split /,/ , $ names ;
my $ correct_node = undef ;
2010-02-05 16:36:16 +00:00
foreach my $ node ( @ nodes ) {
my $ id_parent = $ ppctab - > getNodeAttribs ( $ node , [ 'id' , 'parent' ] ) ;
my $ nodetype = $ nodetypetab - > getNodeAttribs ( $ node , [ 'nodetype' ] ) ;
2010-12-29 10:32:22 +00:00
next if ( ! defined $ nodetype or ! exists $ nodetype - > { 'nodetype' } ) ;
2010-02-05 16:36:16 +00:00
next if ( $ nodetype - > { 'nodetype' } ne lc ( $ type ) ) ;
2010-02-06 14:00:25 +00:00
if ( $ nodetype - > { 'nodetype' } eq 'fsp' ) {
if ( ( exists $ id_parent - > { 'id' } ) and ( exists $ id_parent - > { 'parent' } ) ) {
2010-02-05 16:36:16 +00:00
###########################################
# For high end machines.
# Check if this node's parent and id is the
# same in SLP response.
###########################################
if ( $ id_parent - > { 'id' } eq $ cage_number ) {
2010-02-06 14:00:25 +00:00
my $ vpdnode = $ vpdtab - > getNodeAttribs ( $ id_parent - > { 'parent' } , [ 'serial' , 'mtm' ] ) ;
if ( ( exists $ vpdnode - > { 'serial' } ) and ( $ vpdnode - > { 'serial' } ne $ bpc_serial ) ) {
next ;
}
if ( ( exists $ vpdnode - > { 'mtm' } ) and ( $ vpdnode - > { 'mtm' } ne $ bpc_model ) ) {
next ;
2010-02-05 16:36:16 +00:00
}
} else {
next ;
}
} else {
###########################################
# For low end machines.
# If there is hub to connect several FSPs
# with the same switch port, check node's
# mtms
###########################################
2011-01-11 15:12:52 +00:00
my $ vpdnode = $ vpdtab - > getNodeAttribs ( $ node , [ 'serial' , 'mtm' ] ) ;
2010-02-06 14:00:25 +00:00
if ( ( exists $ vpdnode - > { 'serial' } ) and ( $ vpdnode - > { 'serial' } ne $ serial ) ) {
next ;
}
if ( ( exists $ vpdnode - > { 'mtm' } ) and ( $ vpdnode - > { 'mtm' } ne $ mtm ) ) {
next ;
2008-06-03 19:09:21 +00:00
}
2010-02-05 16:36:16 +00:00
}
###########################################
# Check if the side attribute for this node
# is the same in SLP response
# For FSP redundancy.
###########################################
2010-02-06 14:00:25 +00:00
my $ nodeside = $ vpdtab - > getNodeAttribs ( $ node , [ 'side' ] ) ;
if ( ( exists $ nodeside - > { 'side' } ) and ( $ nodeside - > { 'side' } ne $ side ) ) {
2010-02-05 16:36:16 +00:00
next ;
}
}
2010-02-06 14:00:25 +00:00
2010-02-09 08:58:10 +00:00
if ( $ nodetype - > { 'nodetype' } eq 'bpa' or $ nodetype - > { 'nodetype' } eq 'mm' ) {
2010-02-05 16:36:16 +00:00
###########################################
# If there is a hub to connect several BPAs
# with the same switch port, check this
2010-02-06 14:00:25 +00:00
# node's mtms and side
2010-02-05 16:36:16 +00:00
###########################################
2010-02-06 14:00:25 +00:00
my $ vpdnode = $ vpdtab - > getNodeAttribs ( $ node , [ 'serial' , 'mtm' , 'side' ] ) ;
if ( ( exists $ vpdnode - > { 'serial' } ) and ( $ vpdnode - > { 'serial' } ne $ serial ) ) {
next ;
}
if ( ( exists $ vpdnode - > { 'mtm' } ) and ( $ vpdnode - > { 'mtm' } ne $ mtm ) ) {
next ;
}
if ( ( exists $ vpdnode - > { 'side' } ) and ( $ vpdnode - > { 'side' } ne $ side ) ) {
next ;
2009-10-20 11:31:17 +00:00
}
2009-10-20 13:37:44 +00:00
}
2010-02-05 16:36:16 +00:00
return $ node ;
2009-10-20 13:37:44 +00:00
}
2010-02-06 14:00:25 +00:00
2011-01-11 15:12:52 +00:00
return undef ;
2009-10-20 11:31:17 +00:00
}
2008-06-03 19:09:21 +00:00
2009-10-20 13:37:44 +00:00
##########################################################################
# Run rspconfig against targets
##########################################################################
sub rspconfig {
2009-10-20 11:31:17 +00:00
2009-10-20 13:37:44 +00:00
my $ request = shift ;
my $ targets = shift ;
my $ callback = $ request - > { callback } ;
my $ start = Time::HiRes:: gettimeofday ( ) ;
2009-10-20 11:31:17 +00:00
2009-10-20 13:37:44 +00:00
my % rsp_dev = get_rsp_dev ( $ request , $ targets ) ;
#############################################
# Fork one process per MM/HMC
#############################################
my $ children = 0 ;
$ SIG { CHLD } = sub { while ( waitpid ( - 1 , WNOHANG ) > 0 ) { $ children - - ; } } ;
my $ fds = new IO:: Select ;
foreach my $ ip ( keys % rsp_dev ) {
my $ pipe = fork_cmd ( $ request , $ ip , \ % rsp_dev ) ;
if ( $ pipe ) {
$ fds - > add ( $ pipe ) ;
$ children + + ;
}
}
#############################################
# Process responses from children
#############################################
while ( $ children > 0 ) {
child_response ( $ callback , $ fds ) ;
}
while ( child_response ( $ callback , $ fds ) ) { }
if ( $ verbose ) {
my $ elapsed = Time::HiRes:: gettimeofday ( ) - $ start ;
my $ msg = sprintf ( "Total rspconfig Time: %.3f sec\n" , $ elapsed ) ;
trace ( $ request , $ msg ) ;
}
2010-02-05 16:36:16 +00:00
my $ result ;
my @ failed_node ;
my @ succeed_node ;
2009-10-20 13:37:44 +00:00
foreach my $ ip ( keys % rsp_result ) {
#################################
# Error logging on to MM
#################################
my $ result = $ rsp_result { $ ip } ;
my $ Rc = shift ( @$ result ) ;
2010-02-05 16:36:16 +00:00
if ( $ Rc != SUCCESS ) {
push @ failed_node , $ ip ;
2011-01-11 15:12:52 +00:00
} else {
2010-02-05 16:36:16 +00:00
push @ succeed_node , $ ip ;
}
2009-10-20 13:37:44 +00:00
if ( $ Rc != SUCCESS ) {
#############################
# MM connect error
#############################
if ( ref ( @$ result [ 0 ] ) ne 'ARRAY' ) {
if ( $ verbose ) {
trace ( $ request , "$ip: @$result[0]" ) ;
}
delete $ rsp_dev { $ ip } ;
next ;
2009-10-20 11:31:17 +00:00
}
2009-10-20 13:37:44 +00:00
}
2010-02-05 16:36:16 +00:00
2009-10-20 13:37:44 +00:00
##################################
# Process each response
##################################
2010-02-04 08:12:33 +00:00
if ( defined ( @$ result [ 0 ] ) ) {
foreach ( @ { @$ result [ 0 ] } ) {
2009-10-20 13:37:44 +00:00
if ( $ verbose ) {
2010-02-04 08:12:33 +00:00
trace ( $ request , "$ip: $_" ) ;
2008-06-03 19:09:21 +00:00
}
2010-02-04 08:12:33 +00:00
/^(\S+)\s+(\d+)/ ;
my $ cmd = $ 1 ;
$ Rc = $ 2 ;
2008-06-03 19:09:21 +00:00
2010-02-04 08:12:33 +00:00
if ( $ cmd =~ /^network_reset/ ) {
if ( $ Rc != SUCCESS ) {
delete $ rsp_dev { $ ip } ;
next ;
}
if ( $ verbose ) {
trace ( $ request , "Resetting management-module ($ip)...." ) ;
}
}
2008-06-03 19:09:21 +00:00
}
}
}
2010-02-05 16:36:16 +00:00
return ( \ @ failed_node , \ @ succeed_node ) ;
2008-06-03 19:09:21 +00:00
}
2009-10-20 13:37:44 +00:00
#############################################
# Get rsp devices and their logon info
#############################################
sub get_rsp_dev
2009-01-19 09:06:39 +00:00
{
2009-10-20 13:37:44 +00:00
my $ request = shift ;
my $ targets = shift ;
2010-02-05 16:36:16 +00:00
my $ mm = $ targets - > { 'mm' } ? $ targets - > { 'mm' } : { } ;
my $ hmc = $ targets - > { 'hmc' } ? $ targets - > { 'hmc' } : { } ;
my $ fsp = $ targets - > { 'fsp' } ? $ targets - > { 'fsp' } : { } ;
my $ bpa = $ targets - > { 'bpa' } ? $ targets - > { 'bpa' } : { } ;
2009-10-20 13:37:44 +00:00
if ( %$ mm )
2009-01-19 09:06:39 +00:00
{
2009-10-20 13:37:44 +00:00
my $ bladeuser = 'USERID' ;
my $ bladepass = 'PASSW0RD' ;
if ( $ verbose ) {
trace ( $ request , "telneting to management-modules....." ) ;
}
#############################################
# Check passwd table for userid/password
#############################################
my $ passtab = xCAT::Table - > new ( 'passwd' ) ;
if ( $ passtab ) {
2011-12-08 06:26:37 +00:00
#my ($ent) = $passtab->getAttribs({key=>'blade'},'username','password');
my $ ent = $ passtab - > getNodeAttribs ( 'blade' , [ 'username' , 'password' ] ) ;
2009-10-20 13:37:44 +00:00
if ( defined ( $ ent ) ) {
$ bladeuser = $ ent - > { username } ;
$ bladepass = $ ent - > { password } ;
}
}
#############################################
# Get MM userid/password
#############################################
my $ mpatab = xCAT::Table - > new ( 'mpa' ) ;
2011-12-08 06:26:37 +00:00
for my $ nd ( keys %$ mm ) {
2009-10-20 13:37:44 +00:00
my $ user = $ bladeuser ;
my $ pass = $ bladepass ;
if ( defined ( $ mpatab ) ) {
2011-12-08 06:26:37 +00:00
#my ($ent) = $mpatab->getAttribs({mpa=>$_},'username','password');
my $ ent = $ mpatab - > getNodeAttribs ( $ nd , [ 'username' , 'password' ] ) ;
2009-10-20 13:37:44 +00:00
if ( defined ( $ ent - > { password } ) ) { $ pass = $ ent - > { password } ; }
if ( defined ( $ ent - > { username } ) ) { $ user = $ ent - > { username } ; }
}
2011-12-08 06:26:37 +00:00
$ mm - > { $ nd } - > { username } = $ user ;
$ mm - > { $ nd } - > { password } = $ pass ;
2009-01-19 09:06:39 +00:00
}
}
2009-10-20 13:37:44 +00:00
if ( %$ hmc )
2009-01-19 09:06:39 +00:00
{
2009-10-20 13:37:44 +00:00
#############################################
# Get HMC userid/password
#############################################
foreach ( keys %$ hmc ) {
2011-01-11 15:12:52 +00:00
( $ hmc - > { $ _ } - > { username } , $ hmc - > { $ _ } - > { password } ) = xCAT::PPCdb:: credentials ( $ hmc - > { $ _ } - > { name } , lc ( $ hmc - > { $ _ } - > { 'type' } ) , "hscroot" ) ;
2009-10-20 13:37:44 +00:00
trace ( $ request , "user/passwd for $_ is $hmc->{$_}->{username} $hmc->{$_}->{password}" ) ;
}
2009-01-19 09:06:39 +00:00
}
2009-10-20 13:37:44 +00:00
if ( %$ fsp )
2009-01-19 09:06:39 +00:00
{
2009-10-20 13:37:44 +00:00
#############################################
# Get FSP userid/password
#############################################
foreach ( keys %$ fsp ) {
2011-01-11 15:12:52 +00:00
( $ fsp - > { $ _ } - > { username } , $ fsp - > { $ _ } - > { password } ) = xCAT::PPCdb:: credentials ( $ fsp - > { $ _ } - > { name } , lc ( $ fsp - > { $ _ } - > { 'type' } ) , "admin" ) ;
2009-10-20 13:37:44 +00:00
trace ( $ request , "user/passwd for $_ is $fsp->{$_}->{username} $fsp->{$_}->{password}" ) ;
2009-01-19 09:06:39 +00:00
}
}
2009-10-20 13:37:44 +00:00
if ( %$ bpa )
2009-01-19 09:06:39 +00:00
{
2009-10-20 13:37:44 +00:00
#############################################
# Get BPA userid/password
#############################################
foreach ( keys %$ bpa ) {
2011-01-11 15:12:52 +00:00
( $ bpa - > { $ _ } - > { username } , $ bpa - > { $ _ } - > { password } ) = xCAT::PPCdb:: credentials ( $ bpa - > { $ _ } - > { name } , lc ( $ bpa - > { $ _ } - > { 'type' } ) , "admin" ) ;
2009-10-20 13:37:44 +00:00
trace ( $ request , "user/passwd for $_ is $bpa->{$_}->{username} $bpa->{$_}->{password}" ) ;
}
2009-01-19 09:06:39 +00:00
}
2011-01-11 15:12:52 +00:00
2009-10-20 13:37:44 +00:00
return ( %$ mm , %$ hmc , %$ fsp , %$ bpa ) ;
2009-01-19 09:06:39 +00:00
}
2008-06-03 19:09:21 +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 ;
my $ doreq = shift ;
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
if ( exists ( $ opt { resetnet } ) and scalar ( keys % opt ) eq 1 ) {
2011-05-23 09:47:25 +00:00
#$result = do_resetnet( \%request );
2011-06-02 01:59:20 +00:00
send_msg ( \ % request , 0 , "the flag --resetnet has been moved to rspconfig, please see the rspconfig man page for more details" ) ;
$ result = [ 0 ] ;
2010-02-05 16:36:16 +00:00
} else {
###########################################
# SLP service-request - select program
###########################################
$ result = $ openSLP ? slptool ( \ % request ) : slp_query ( \ % request ) ;
}
2009-10-20 13:37:44 +00:00
my $ Rc = shift ( @$ result ) ;
return ( $ Rc ) ;
2008-06-03 19:09:21 +00:00
}
2009-12-28 08:10:42 +00:00
##########################################################################
2011-01-11 15:12:52 +00:00
# Write hostnames and IP address to host table. If an existing entry
2009-12-28 08:10:42 +00:00
# with same IP address can be found, return the existing hostname and IP
##########################################################################
sub writehost {
my $ hostname = shift ;
my $ ip = shift ;
my $ hoststab = xCAT::Table - > new ( "hosts" , - create = > 1 , - autocommit = > 1 ) ;
if ( ! $ hoststab ) {
return ( [ [ $ hostname , "Error opening 'hosts' table" , RC_ERROR ] ] ) ;
}
$ hoststab - > setNodeAttribs ( $ hostname , { ip = > $ ip } ) ;
$ hoststab - > close ( ) ;
}
2011-02-21 05:50:02 +00:00
##########################################################################
# Copy the user/passwd information from CEC/Frame to FSP/BPA
# This function should be called after database migration
##########################################################################
sub copypasswd {
my $ node = shift ;
if ( ( $ node ) && ( $ node =~ /xCAT::/ ) )
{
$ node = shift ;
2011-06-02 01:59:20 +00:00
}
2011-02-21 05:50:02 +00:00
my $ children = xCAT::DBobjUtils - > getchildren ( $ node ) ;
my % childentry ;
my $ directtab = xCAT::Table - > new ( 'ppcdirect' ) ;
if ( $ children and $ directtab ) {
my $ dthash = $ directtab - > getNodeAttribs ( $ node , [ qw( username password disable ) ] ) ;
my $ username = $ dthash - > { username } ;
my $ passwd = $ dthash - > { passwd } ;
my $ disable = $ dthash - > { disable } ;
foreach ( @$ children ) {
$ childentry { $ _ } { username } = $ username ;
2011-06-02 01:59:20 +00:00
$ childentry { $ _ } { password } = $ passwd ;
$ childentry { $ _ } { disable } = $ disable ;
}
$ directtab - > setNodesAttribs ( \ % childentry ) ;
}
2011-02-21 05:50:02 +00:00
return 1 ;
}
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 ) {
if ( $ foundnode =~ /^(\w+)\(.*\)/ ) {
if ( $ 1 eq $ n ) {
$ newhash - > { $ foundnode } = $ oldhash - > { $ foundnode } ;
}
}
2011-06-02 01:59:20 +00:00
elsif ( $ foundnode eq $ n ) {
2011-03-21 09:25:16 +00:00
$ newhash - > { $ foundnode } = $ oldhash - > { $ foundnode } ;
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
2011-03-23 01:05:13 +00:00
# fine the FSP/BPA nodes for the CEC/Frame.
for my $ cn ( keys %$ oldhash ) {
for my $ pn ( keys %$ newhash ) {
if ( ( $ { $ oldhash - > { $ cn } } [ 0 ] =~ /^(FSP|BPA)$/ )
and ( $ { $ newhash - > { $ pn } } [ 2 ] eq $ { $ oldhash - > { $ cn } } [ 2 ] )
and ( $ { $ newhash - > { $ pn } } [ 1 ] eq $ { $ oldhash - > { $ cn } } [ 1 ] ) ) {
$ newhash - > { $ cn } = $ oldhash - > { $ cn } ;
}
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
}
2009-10-20 13:37:44 +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 ;
my $ nets = xCAT::Utils:: my_nets ( ) ;
my $ validnets ;
for my $ net ( keys %$ nets ) {
for my $ nic ( split /,/ , $ opt { i } ) {
if ( $ nets - > { $ net } eq $ nic ) {
$ validnets - > { $ net } = $ nic ;
}
}
}
foreach my $ name ( keys %$ oldhash ) {
my @ data = @ { $ oldhash - > { $ name } } ;
my $ type = lc ( $ data [ 0 ] ) ;
if ( $ type =~ /^(fsp|bpa)$/ ) {
my $ ip = $ data [ 4 ] ;
for my $ net ( keys %$ validnets ) {
my ( $ n , $ m ) = split /\// , $ net ;
if ( xCAT::Utils:: isInSameSubnet ( $ n , $ ip , $ m , 1 ) and xCAT::Utils:: isPingable ( $ ip ) ) {
$ newhash - > { $ name } = $ oldhash - > { $ name } ;
}
}
} else {
$ newhash - > { $ name } = $ oldhash - > { $ name } ;
}
}
return $ newhash ;
}
2011-09-14 13:57:31 +00:00
##########################################################################
# Match the nodes defined by xcatsetup
# The match rules are:
# match Frame nodes with mtms
# match CEC nodes with parent name and id
# match FSP/BPA nodes with parent name and side
##########################################################################
sub match_hosts_defined_by_xcatsetup {
my $ nodename = shift ;
my $ type = shift ;
my $ mtm = shift ;
my $ sn = shift ;
my $ side = shift ;
my $ ip = shift ;
my $ cage_number = shift ;
my $ parmtm = shift ;
my $ parsn = shift ;
my $ pname = shift ;
my $ flagref = shift ;
read_from_table ( ) unless ( % ::OLD_DATA_CACHE ) ;
foreach my $ oldnode ( keys % ::OLD_DATA_CACHE )
{
my $ tmpmtm = @ { $ ::OLD_DATA_CACHE { $ oldnode } } [ 0 ] ;
my $ tmpsn = @ { $ ::OLD_DATA_CACHE { $ oldnode } } [ 1 ] ;
my $ tmpside = @ { $ ::OLD_DATA_CACHE { $ oldnode } } [ 2 ] ;
my $ tmpip = @ { $ ::OLD_DATA_CACHE { $ oldnode } } [ 3 ] ;
my $ tmpid = @ { $ ::OLD_DATA_CACHE { $ oldnode } } [ 4 ] ;
my $ tmpparent = @ { $ ::OLD_DATA_CACHE { $ oldnode } } [ 5 ] ;
my $ tmptype = uc ( @ { $ ::OLD_DATA_CACHE { $ oldnode } } [ 6 ] ) ;
my $ unmatched = @ { $ ::OLD_DATA_CACHE { $ oldnode } } [ 7 ] ;
if ( $ type eq TYPE_FRAME )
{
2011-10-23 09:29:32 +00:00
if ( $ tmpmtm eq $ mtm and $ tmpsn eq $ sn and $ type eq $ tmptype ) {
2011-09-14 13:57:31 +00:00
$$ flagref = 1 ;
print "20 got old name $oldnode\n" if ( $ DEBUG_MATCH eq 1 ) ;
return $ oldnode ;
}
}
if ( $ type eq TYPE_CEC )
{
2011-10-23 09:29:32 +00:00
if ( $ pname eq $ tmpparent and $ cage_number eq $ tmpid and $ type eq $ tmptype ) {
2011-09-14 13:57:31 +00:00
$$ flagref = 1 ;
print "21 got old name $oldnode\n" if ( $ DEBUG_MATCH eq 1 ) ;
return $ oldnode ;
}
}
if ( $ type eq TYPE_BPA or $ type eq TYPE_FSP )
{
2011-10-23 09:29:32 +00:00
if ( $ pname eq $ tmpparent and $ side eq $ tmpside and $ type eq $ tmptype ) {
2011-09-14 13:57:31 +00:00
$$ flagref = 1 ;
print "22 got old name $oldnode\n" if ( $ DEBUG_MATCH eq 1 ) ;
return $ oldnode ;
}
}
2011-12-07 10:27:06 +00:00
}
2011-09-14 13:57:31 +00:00
return undef ;
}
2011-09-18 14:38:15 +00:00
##########################################################################
# Match the nodes defined by xcatsetup
# Use ip to find HMC defined by the user
##########################################################################
sub match_ip_defined_by_xcatsetup {
my $ ip = shift ;
my $ matchflag = shift ;
read_from_table ( ) unless ( % ::OLD_DATA_CACHE ) ;
foreach my $ oldnode ( keys % ::OLD_DATA_CACHE ) {
my $ tmpip = @ { $ ::OLD_DATA_CACHE { $ oldnode } } [ 3 ] ;
my $ tmptype = uc ( @ { $ ::OLD_DATA_CACHE { $ oldnode } } [ 6 ] ) ;
next unless ( $ tmptype eq TYPE_HMC ) ;
if ( $ ip eq $ tmpip ) {
$$ matchflag = 1 ;
return $ oldnode ;
}
}
return undef ;
}
2011-06-30 02:36:39 +00:00
1 ;
2009-10-20 13:37:44 +00:00