2007-11-16 19:47:00 +00:00
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
package xCAT::PPC ;
use strict ;
2008-06-02 17:54:15 +00:00
use lib "/opt/xcat/lib/perl" ;
2007-11-16 19:47:00 +00:00
use xCAT::Table ;
2008-01-21 19:49:59 +00:00
use xCAT::Utils ;
2012-08-09 04:00:45 +00:00
use xCAT::TableUtils ;
use xCAT::ServiceNodeUtils ;
2009-03-20 21:36:49 +00:00
use xCAT::SvrUtils ;
2010-08-02 08:35:45 +00:00
use xCAT::FSPUtils ;
2008-04-12 14:53:11 +00:00
use xCAT::Usage ;
2007-11-16 19:47:00 +00:00
use POSIX "WNOHANG" ;
use Storable qw( freeze thaw ) ;
2008-05-02 19:15:23 +00:00
use Time::HiRes qw( gettimeofday sleep ) ;
2007-11-16 19:47:00 +00:00
use IO::Select ;
2008-03-19 17:44:30 +00:00
use Socket ;
2008-03-10 19:08:34 +00:00
use xCAT::PPCcli ;
2008-02-14 19:47:42 +00:00
use xCAT::GlobalDef ;
2008-03-19 17:44:30 +00:00
use xCAT::DBobjUtils ;
2008-09-25 03:04:56 +00:00
use xCAT_monitoring::monitorctrl ;
2008-10-21 02:50:13 +00:00
use Thread qw( yield ) ;
2010-07-21 19:04:10 +00:00
use xCAT::PPCdb ;
2010-08-12 05:52:34 +00:00
#use Data::Dumper;
2009-12-02 09:38:51 +00:00
2007-11-16 19:47:00 +00:00
##########################################
# Globals
##########################################
my % modules = (
2009-12-10 02:19:40 +00:00
rinv = > { hmc = > "xCAT::PPCinv" ,
2010-08-19 03:25:01 +00:00
ivm = > "xCAT::PPCinv" ,
2009-12-10 02:19:40 +00:00
fsp = > "xCAT::FSPinv" ,
bpa = > "xCAT::FSPinv" ,
2010-12-16 09:58:58 +00:00
cec = > "xCAT::FSPinv" ,
frame = > "xCAT::FSPinv" ,
2011-04-13 09:42:58 +00:00
} ,
2009-12-10 02:19:40 +00:00
rpower = > { hmc = > "xCAT::PPCpower" ,
2010-08-19 03:25:01 +00:00
ivm = > "xCAT::PPCpower" ,
2009-12-10 02:19:40 +00:00
fsp = > "xCAT::FSPpower" ,
bpa = > "xCAT::FSPpower" ,
2010-12-10 03:00:22 +00:00
cec = > "xCAT::FSPpower" ,
frame = > "xCAT::FSPpower" ,
2011-04-13 09:42:58 +00:00
} ,
2009-12-10 02:19:40 +00:00
rvitals = > { hmc = > "xCAT::PPCvitals" ,
2010-01-18 06:14:05 +00:00
fsp = > "xCAT::FSPvitals" ,
bpa = > "xCAT::FSPvitals" ,
2010-12-16 09:58:58 +00:00
cec = > "xCAT::FSPvitals" ,
frame = > "xCAT::FSPvitals" ,
2011-04-13 09:42:58 +00:00
} ,
2009-12-10 02:19:40 +00:00
rscan = > { hmc = > "xCAT::PPCscan" ,
2010-05-05 07:59:08 +00:00
fsp = > "xCAT::FSPscan" ,
2010-12-14 05:30:33 +00:00
cec = > "xCAT::FSPscan" ,
2011-10-19 05:23:10 +00:00
ivm = > "xCAT::PPCscan" ,
2011-04-13 09:42:58 +00:00
} ,
2009-12-10 02:19:40 +00:00
mkvm = > { hmc = > "xCAT::PPCvm" ,
2010-11-25 03:33:09 +00:00
fsp = > "xCAT::FSPvm" ,
2010-12-20 13:39:54 +00:00
cec = > "xCAT::FSPvm" ,
2011-04-13 09:42:58 +00:00
} ,
2009-12-10 02:19:40 +00:00
rmvm = > { hmc = > "xCAT::PPCvm" ,
2013-09-11 09:36:27 +00:00
fsp = > "xCAT::FSPvm" ,
2011-04-13 09:42:58 +00:00
} ,
2009-12-10 02:19:40 +00:00
lsvm = > { hmc = > "xCAT::PPCvm" ,
2010-11-25 03:33:09 +00:00
fsp = > "xCAT::FSPvm" ,
2010-12-20 13:39:54 +00:00
cec = > "xCAT::FSPvm" ,
2011-04-13 09:42:58 +00:00
} ,
2009-12-10 02:19:40 +00:00
chvm = > { hmc = > "xCAT::PPCvm" ,
2011-03-02 09:34:40 +00:00
fsp = > "xCAT::FSPvm" ,
cec = > "xCAT::FSPvm" ,
2011-04-13 09:42:58 +00:00
} ,
2009-12-10 02:19:40 +00:00
rnetboot = > { hmc = > "xCAT::PPCboot" ,
2010-08-19 03:25:01 +00:00
ivm = > "xCAT::PPCboot" ,
2010-01-07 06:00:53 +00:00
fsp = > "xCAT::FSPboot" ,
2010-12-20 13:39:54 +00:00
cec = > "xCAT::FSPboot" ,
2011-04-13 09:42:58 +00:00
} ,
2009-12-10 02:19:40 +00:00
getmacs = > { hmc = > "xCAT::PPCmac" ,
2010-08-19 03:25:01 +00:00
ivm = > "xCAT::PPCmac" ,
2010-01-07 06:00:53 +00:00
fsp = > "xCAT::FSPmac" ,
2011-03-15 07:13:34 +00:00
cec = > "xCAT::FSPmac" ,
2011-04-13 09:42:58 +00:00
} ,
2009-12-10 02:19:40 +00:00
reventlog = > { hmc = > "xCAT::PPClog" ,
2011-04-13 09:42:58 +00:00
} ,
2009-12-10 02:19:40 +00:00
rspconfig = > { hmc = > "xCAT::PPCcfg" ,
2010-05-17 07:42:59 +00:00
fsp = > "xCAT::FSPcfg" ,
2010-05-27 01:43:39 +00:00
bpa = > "xCAT::FSPcfg" ,
2010-12-17 02:59:35 +00:00
cec = > "xCAT::FSPcfg" ,
2012-03-06 05:17:56 +00:00
blade = > "xCAT::FSPcfg" ,
2010-12-17 02:59:35 +00:00
frame = > "xCAT::FSPcfg" ,
2011-04-13 09:42:58 +00:00
} ,
2009-12-10 02:19:40 +00:00
rflash = > { hmc = > "xCAT::PPCrflash" ,
fsp = > "xCAT::FSPflash" ,
bpa = > "xCAT::FSPflash" ,
2010-12-17 08:43:24 +00:00
cec = > "xCAT::FSPflash" ,
frame = > "xCAT::FSPflash" ,
2011-04-13 09:42:58 +00:00
} ,
2009-12-10 02:19:40 +00:00
mkhwconn = > { hmc = > "xCAT::PPCconn" ,
2010-02-26 09:42:41 +00:00
fsp = > "xCAT::FSPconn" ,
2010-12-20 13:39:54 +00:00
cec = > "xCAT::FSPconn" ,
2010-02-26 09:42:41 +00:00
bpa = > "xCAT::FSPconn" ,
2010-12-20 13:39:54 +00:00
frame = > "xCAT::FSPconn" ,
2011-04-13 09:42:58 +00:00
} ,
2009-12-10 02:19:40 +00:00
rmhwconn = > { hmc = > "xCAT::PPCconn" ,
2010-02-26 09:42:41 +00:00
fsp = > "xCAT::FSPconn" ,
2010-12-20 13:39:54 +00:00
cec = > "xCAT::FSPconn" ,
2010-02-26 09:42:41 +00:00
bpa = > "xCAT::FSPconn" ,
2010-12-20 13:39:54 +00:00
frame = > "xCAT::FSPconn" ,
2011-04-13 09:42:58 +00:00
} ,
2009-12-10 02:19:40 +00:00
lshwconn = > { hmc = > "xCAT::PPCconn" ,
2010-05-05 03:22:39 +00:00
fsp = > "xCAT::FSPconn" ,
2010-12-20 13:39:54 +00:00
cec = > "xCAT::FSPconn" ,
2010-05-05 03:22:39 +00:00
bpa = > "xCAT::FSPconn" ,
2010-12-20 13:39:54 +00:00
frame = > "xCAT::FSPconn" ,
2011-04-13 09:42:58 +00:00
} ,
2009-12-10 02:19:40 +00:00
renergy = > { hmc = > "xCAT::PPCenergy" ,
2011-01-26 13:28:28 +00:00
fsp = > "xCAT::PPCenergy" ,
cec = > "xCAT::PPCenergy" ,
2011-04-13 09:42:58 +00:00
} ,
2010-12-13 05:54:32 +00:00
rbootseq = > { fsp = > "xCAT::FSPbootseq" ,
2010-12-20 13:39:54 +00:00
cec = > "xCAT::FSPbootseq" ,
2010-12-13 05:54:32 +00:00
} ,
2009-05-19 03:20:17 +00:00
) ;
2007-11-16 19:47:00 +00:00
2009-12-10 02:19:40 +00:00
2007-11-16 19:47:00 +00:00
##########################################
# Database errors
##########################################
my % errmsg = (
2009-05-19 03:20:17 +00:00
NODE_UNDEF = > "Node not defined in '%s' database" ,
NO_ATTR = > "'%s' not defined in '%s' database" ,
2009-07-08 07:41:43 +00:00
NO_UNDEF = > "'%s' not defined in '%s' database for '%s'" ,
2009-05-19 03:20:17 +00:00
DB_UNDEF = > "'%s' database not defined"
) ;
2007-11-16 19:47:00 +00:00
##########################################################################
# Invokes the callback with the specified message
##########################################################################
2008-02-18 20:26:39 +00:00
sub send_msg {
2007-11-16 19:47:00 +00:00
my $ request = shift ;
2008-02-18 20:26:39 +00:00
my $ ecode = shift ;
2007-11-16 19:47:00 +00:00
my % output ;
2009-06-05 08:02:34 +00:00
#################################################
# Called from child process - send to parent
#################################################
2007-11-16 19:47:00 +00:00
if ( exists ( $ request - > { pipe } ) ) {
my $ out = $ request - > { pipe } ;
2008-02-18 20:26:39 +00:00
$ output { errorcode } = $ ecode ;
2007-11-16 19:47:00 +00:00
$ output { data } = \ @ _ ;
print $ out freeze ( [ \ % output ] ) ;
2007-12-06 16:36:32 +00:00
print $ out "\nENDOFFREEZE6sK4ci\n" ;
2007-11-16 19:47:00 +00:00
}
2009-06-05 08:02:34 +00:00
#################################################
# Called from parent - invoke callback directly
#################################################
2007-11-16 19:47:00 +00:00
elsif ( exists ( $ request - > { callback } ) ) {
my $ callback = $ request - > { callback } ;
2008-02-18 20:26:39 +00:00
$ output { errorcode } = $ ecode ;
2007-11-16 19:47:00 +00:00
$ output { data } = \ @ _ ;
$ callback - > ( \ % output ) ;
}
}
##########################################################################
# Fork child to execute remote commands
##########################################################################
sub process_command {
my $ request = shift ;
2010-08-02 08:35:45 +00:00
my $ hcps_will = shift ;
my $ failed_nodes = shift ;
my $ failed_msg = shift ;
2007-11-16 19:47:00 +00:00
my % nodes = ( ) ;
my $ callback = $ request - > { callback } ;
2012-05-17 08:42:12 +00:00
#my $sitetab = xCAT::Table->new( 'site' );
2011-11-30 08:18:21 +00:00
my @ site = qw( ppcmaxp ppctimeout maxssh ppcretry fsptimeout powerinterval syspowerinterval ) ;
2007-11-16 19:47:00 +00:00
my $ start ;
2010-08-02 08:35:45 +00:00
my $ verbose = $ request - > { verbose } ;
2007-11-16 19:47:00 +00:00
2009-06-05 08:02:34 +00:00
#######################################
# Default site table attributes
#######################################
2008-05-02 19:15:23 +00:00
$ request - > { ppcmaxp } = 64 ;
$ request - > { ppctimeout } = 0 ;
$ request - > { fsptimeout } = 0 ;
$ request - > { ppcretry } = 3 ;
2009-10-13 13:37:30 +00:00
$ request - > { maxssh } = 8 ;
2011-11-30 08:18:21 +00:00
$ request - > { powerinterval } = 0 ;
$ request - > { syspowerinterval } = 0 ;
2008-05-02 19:15:23 +00:00
2009-06-05 08:02:34 +00:00
#######################################
# Get site table attributes
#######################################
2012-05-17 08:42:12 +00:00
foreach ( @ site ) {
2012-08-09 04:00:45 +00:00
my @ val = xCAT::TableUtils - > get_site_attribute ( $ _ ) ;
2012-05-17 08:42:12 +00:00
if ( defined ( $ val [ 0 ] ) ) {
$ request - > { $ _ } = $ val [ 0 ] ;
2008-05-01 19:57:58 +00:00
}
2012-05-17 08:42:12 +00:00
}
2007-11-16 19:47:00 +00:00
if ( exists ( $ request - > { verbose } ) ) {
$ start = Time::HiRes:: gettimeofday ( ) ;
}
2009-10-13 02:05:18 +00:00
2009-06-05 08:02:34 +00:00
#######################################
# Group nodes based on command
#######################################
2012-07-12 07:55:31 +00:00
my $ nodes ;
unless ( $ request - > { command } =~ /^rspconfig$/ && exists ( $ request - > { opt } - > { resetnet } ) ) {
$ nodes = preprocess_nodes ( $ request , $ hcps_will ) ;
if ( ! defined ( $ nodes ) ) {
return ( 1 ) ;
}
2007-11-16 19:47:00 +00:00
}
2012-03-06 05:17:56 +00:00
2009-06-05 08:02:34 +00:00
#get new node status
2009-05-19 03:20:17 +00:00
my % oldnodestatus = ( ) ; #saves the old node status
my @ allerrornodes = ( ) ;
my $ check = 0 ;
my $ global_check = 1 ;
2012-08-09 04:00:45 +00:00
my @ val = xCAT::TableUtils - > get_site_attribute ( "nodestatus" ) ;
2012-05-17 08:42:12 +00:00
if ( defined ( $ val [ 0 ] ) ) {
if ( $ val [ 0 ] =~ /0|n|N/ ) { $ global_check = 0 ; }
2009-05-19 03:20:17 +00:00
}
my $ command = $ request - > { command } ;
if ( ( $ command eq 'rpower' ) || ( $ command eq 'rnetboot' ) ) {
my $ subcommand = "temp" ;
if ( $ command eq 'rpower' ) { $ subcommand = $ request - > { op } ; }
if ( ( $ global_check ) && ( $ subcommand ne 'stat' ) && ( $ subcommand ne 'status' ) && ( $ subcommand ne 'state' ) ) {
$ check = 1 ;
my $ noderange = $ request - > { node } ;
my @ allnodes = @$ noderange ;
2009-06-05 08:02:34 +00:00
#save the old status
2009-05-19 03:20:17 +00:00
my $ nodelisttab = xCAT::Table - > new ( 'nodelist' ) ;
if ( $ nodelisttab ) {
my $ tabdata = $ nodelisttab - > getNodesAttribs ( \ @ allnodes , [ 'node' , 'status' ] ) ;
foreach my $ node ( @ allnodes )
{
my $ tmp1 = $ tabdata - > { $ node } - > [ 0 ] ;
if ( $ tmp1 ) {
if ( $ tmp1 - > { status } ) { $ oldnodestatus { $ node } = $ tmp1 - > { status } ; }
else { $ oldnodestatus { $ node } = "" ; }
}
}
}
2009-06-05 08:02:34 +00:00
#print "oldstatus:" . Dumper(\%oldnodestatus);
2009-05-19 03:20:17 +00:00
2009-06-05 08:02:34 +00:00
#set the new status to the nodelist.status
2009-05-19 03:20:17 +00:00
my % newnodestatus = ( ) ;
my $ newstat ;
if ( ( $ subcommand eq 'off' ) || ( $ subcommand eq 'softoff' ) ) {
my $ newstat = $ ::STATUS_POWERING_OFF ;
$ newnodestatus { $ newstat } = \ @ allnodes ;
} else {
2009-06-05 08:02:34 +00:00
#get the current nodeset stat
2009-05-19 03:20:17 +00:00
if ( @ allnodes > 0 ) {
my $ nsh = { } ;
my ( $ ret , $ msg ) = xCAT::SvrUtils - > getNodesetStates ( \ @ allnodes , $ nsh ) ;
if ( ! $ ret ) {
foreach ( keys %$ nsh ) {
my $ newstat = xCAT_monitoring::monitorctrl - > getNodeStatusFromNodesetState ( $ _ , $ command ) ;
$ newnodestatus { $ newstat } = $ nsh - > { $ _ } ;
}
} else {
trace ( $ request , $ msg ) ;
}
}
}
2013-08-16 06:48:38 +00:00
#donot update node provision status (installing or netbooting) here
xCAT::Utils - > filter_nostatusupdate ( \ % newnodestatus ) ;
2009-06-05 08:02:34 +00:00
#print "newstatus" . Dumper(\%newnodestatus);
2009-05-19 03:20:17 +00:00
xCAT_monitoring::monitorctrl:: setNodeStatusAttributes ( \ % newnodestatus , 1 ) ;
2008-09-26 23:07:45 +00:00
}
}
2008-09-25 03:04:56 +00:00
2008-10-21 02:50:13 +00:00
2009-03-25 02:56:58 +00:00
2009-06-05 08:02:34 +00:00
#######################################
# Fork process
#######################################
2008-10-21 02:50:13 +00:00
my $ children = 0 ;
my $ fds = new IO:: Select ;
2009-06-05 08:02:34 +00:00
# For the commands getmacs and rnetboot, each time
# to fork process, pick out the HMC that has the
# least process number created to connect to the HMC.
# After the process by preprocess_nodes, the $nodes
# variable has following structure:
# $nodes
# |hcp
# |[[hcp,node1_attr], [hcp,node2_attr] ...]
# |count //node number managed by the hcp
# |runprocess //the process number connect to the hcp
# |index //the index of node will be forked of the hcp
2010-12-13 05:54:32 +00:00
if ( ( $ request - > { command } =~ /^(getmacs)$/ && exists ( $ request - > { opt } - > { D } ) ) || ( $ request - > { command } =~ /^(rnetboot)$/ ) || ( $ request - > { command } =~ /^(rbootseq)$/ ) ) {
2009-04-09 11:08:56 +00:00
my % pid_owner = ( ) ;
2009-10-13 02:43:01 +00:00
$ request - > { maxssh } = int ( $ request - > { maxssh } / 2 ) ;
2009-06-05 08:02:34 +00:00
# Use the CHID signal to control the
#connection number of certain hcp
2009-04-09 11:08:56 +00:00
$ SIG { CHLD } = sub { my $ pid = 0 ; while ( ( $ pid = waitpid ( - 1 , WNOHANG ) ) > 0 )
2009-07-28 07:57:26 +00:00
{ $ nodes - > { $ pid_owner { $ pid } } { 'runprocess' } - - ; delete $ pid_owner { $ pid } ; $ children - - ; } } ;
$ SIG { INT } = $ SIG { TERM } = sub { #prepare to process job termination and propogate it down
foreach ( keys % pid_owner ) {
kill 9 , $ _ ;
}
exit 0 ;
} ;
2009-05-19 03:20:17 +00:00
2009-04-09 11:08:56 +00:00
my $ hasnode = 1 ;
while ( $ hasnode ) {
while ( $ children >= $ request - > { ppcmaxp } ) {
my $ handlednodes = { } ;
2010-08-02 08:35:45 +00:00
child_response ( $ callback , $ fds , $ handlednodes , $ failed_nodes , $ failed_msg , $ verbose ) ;
2009-05-19 03:20:17 +00:00
2009-06-05 08:02:34 +00:00
#update the node status to the nodelist.status table
2009-04-09 11:08:56 +00:00
if ( $ check ) {
updateNodeStatus ( $ handlednodes , \ @ allerrornodes ) ;
}
2009-05-19 03:20:17 +00:00
2009-04-09 11:08:56 +00:00
Time::HiRes:: sleep ( 0.1 ) ;
}
2009-06-05 08:02:34 +00:00
# Pick out the hcp which has least processes
2009-04-09 11:08:56 +00:00
my $ least_processes = $ request - > { maxssh } ;
my $ least_hcp ;
my $ got_one = 0 ;
while ( ! $ got_one ) {
$ hasnode = 0 ;
foreach my $ hcp ( keys %$ nodes ) {
if ( $ nodes - > { $ hcp } { 'index' } < $ nodes - > { $ hcp } { 'count' } ) {
$ hasnode = 1 ;
if ( $ nodes - > { $ hcp } { 'runprocess' } < $ least_processes ) {
$ least_processes = $ nodes - > { $ hcp } { 'runprocess' } ;
$ least_hcp = $ hcp ;
}
}
}
2009-05-19 03:20:17 +00:00
2009-04-09 11:08:56 +00:00
if ( ! $ hasnode ) {
2009-06-05 08:02:34 +00:00
# There are no node in the $nodes
2009-04-09 11:08:56 +00:00
goto ENDOFFORK ;
}
2009-05-19 03:20:17 +00:00
2009-04-09 11:08:56 +00:00
if ( $ least_processes < $ request - > { maxssh } ) {
$ got_one = 1 ;
} else {
my $ handlednodes = { } ;
2010-08-02 08:35:45 +00:00
child_response ( $ callback , $ fds , $ handlednodes , $ failed_nodes , $ failed_msg , $ verbose ) ;
2009-05-19 03:20:17 +00:00
2009-06-05 08:02:34 +00:00
#update the node status to the nodelist.status table
2009-04-09 11:08:56 +00:00
if ( $ check ) {
updateNodeStatus ( $ handlednodes , \ @ allerrornodes ) ;
}
Time::HiRes:: sleep ( 0.1 ) ;
}
}
2009-05-19 03:20:17 +00:00
2009-10-13 02:43:01 +00:00
Time::HiRes:: sleep ( 0.1 ) ;
2009-04-09 11:08:56 +00:00
my ( $ pipe , $ pid ) = fork_cmd ( $ nodes - > { $ least_hcp } { 'nodegroup' } - > [ $ nodes - > { $ least_hcp } { 'index' } ] - > [ 0 ] ,
2009-05-19 03:20:17 +00:00
$ nodes - > { $ least_hcp } { 'nodegroup' } - > [ $ nodes - > { $ least_hcp } { 'index' } ] - > [ 1 ] , $ request ) ;
2009-04-09 11:08:56 +00:00
if ( $ pid ) {
$ pid_owner { $ pid } = $ least_hcp ;
$ nodes - > { $ least_hcp } { 'index' } + + ;
$ nodes - > { $ least_hcp } { 'runprocess' } + + ;
}
2009-05-19 03:20:17 +00:00
2009-04-09 11:08:56 +00:00
if ( $ pipe ) {
$ fds - > add ( $ pipe ) ;
$ children + + ;
}
2008-05-01 19:57:58 +00:00
}
2009-07-14 12:16:11 +00:00
} elsif ( $ request - > { command } =~ /^(getmacs)$/ && exists ( $ request - > { opt } - > { arp } ) ) {
2010-02-04 10:24:13 +00:00
my $ display = "" ;
if ( defined ( $ request - > { opt } - > { d } ) ) {
$ display = "yes" ;
2009-07-14 12:16:11 +00:00
}
2010-02-05 09:31:40 +00:00
my $ output = xCAT::SvrUtils - > get_mac_by_arp ( $ nodes , $ display ) ;
2010-02-04 10:24:13 +00:00
my $ rsp = ( ) ;
foreach my $ node ( keys % { $ output } ) {
push @ { $ rsp - > { node } } , { name = > [ $ node ] , data = > [ $ output - > { $ node } ] } ;
2009-07-14 12:16:11 +00:00
}
2010-02-04 10:24:13 +00:00
$ rsp - > { errorcode } = 0 ;
$ callback - > ( $ rsp ) ;
2009-10-13 02:05:18 +00:00
} elsif ( $ request - > { command } =~ /^rpower$/ ) {
my $ hw ;
my $ sessions ;
my $ pid_owner ;
my $ remain_node = $ nodes ;
2011-11-30 08:18:21 +00:00
my $ num = 0 ;
2009-10-13 02:05:18 +00:00
while ( scalar ( $ remain_node ) ) {
$ remain_node = ( ) ;
foreach my $ hash ( @$ nodes ) {
$ SIG { CHLD } = sub { my $ pid = 0 ; while ( ( $ pid = waitpid ( - 1 , WNOHANG ) ) > 0 ) { $ hw - > { $ pid_owner - > { $ pid } } - - ; $ children - - ; } } ;
2011-09-14 03:27:30 +00:00
$ SIG { INT } = $ SIG { TERM } = $ SIG { KILL } = sub { #prepare to process job termination and propogate it down
foreach my $ pid ( keys % { $ pid_owner } ) {
& kill_children_by_pid ( $ pid ) ;
}
exit 0 ;
} ;
2009-10-13 02:05:18 +00:00
while ( $ children >= $ request - > { ppcmaxp } ) {
my $ handlednodes = { } ;
2010-08-02 08:35:45 +00:00
child_response ( $ callback , $ fds , $ handlednodes , $ failed_nodes , $ failed_msg , $ verbose ) ;
2009-10-13 02:05:18 +00:00
#update the node status to the nodelist.status table
if ( $ check ) {
updateNodeStatus ( $ handlednodes , \ @ allerrornodes ) ;
}
Time::HiRes:: sleep ( 0.1 ) ;
}
if ( $ hw - > { @$ hash [ 0 ] } >= $ request - > { maxssh } ) {
my $ handlednodes = { } ;
2010-08-02 08:35:45 +00:00
child_response ( $ callback , $ fds , $ handlednodes , $ failed_nodes , $ failed_msg , $ verbose ) ;
2009-10-13 02:05:18 +00:00
#update the node status to the nodelist.status table
if ( $ check ) {
updateNodeStatus ( $ handlednodes , \ @ allerrornodes ) ;
}
Time::HiRes:: sleep ( 0.1 ) ;
push ( @$ remain_node , [ @$ hash [ 0 ] , @$ hash [ 1 ] ] ) ;
next ;
}
2011-11-30 08:18:21 +00:00
2012-02-07 15:49:14 +00:00
if ( $ num > 0 && $ request - > { op } =~ /^on/ && $ request - > { fsp_api } == 1 ) {
2011-11-30 08:18:21 +00:00
my $ t_hash = @$ hash [ 1 ] ;
my $ one_key_in_thash = ( keys %$ t_hash ) [ 0 ] ;
my $ one_d = $ t_hash - > { $ one_key_in_thash } ;
#print Dumper($one_d);
if ( $$ one_d [ 4 ] =~ /^fsp$/ || $$ one_d [ 4 ] =~ /^cec$/ ) {
if ( $ request - > { syspowerinterval } > 0 ) {
2011-12-30 09:04:04 +00:00
no_interrupt_sleep ( $ request - > { syspowerinterval } ) ;
2011-11-30 08:18:21 +00:00
}
}
}
2009-10-13 02:05:18 +00:00
my ( $ pipe , $ pid ) = fork_cmd ( @$ hash [ 0 ] , @$ hash [ 1 ] , $ request ) ;
2011-11-30 08:18:21 +00:00
$ num + + ;
2009-10-13 02:05:18 +00:00
if ( $ pid ) {
$ pid_owner - > { $ pid } = @$ hash [ 0 ] ;
$ hw - > { @$ hash [ 0 ] } + + ;
}
if ( $ pipe ) {
$ fds - > add ( $ pipe ) ;
$ children + + ;
}
}
$ nodes = $ remain_node ;
}
2011-06-02 02:15:23 +00:00
} elsif ( $ request - > { command } =~ /^rspconfig$/ && exists ( $ request - > { opt } - > { resetnet } ) ) {
runcmd ( $ request ) ;
2009-04-09 11:08:56 +00:00
} else {
2011-09-14 03:27:30 +00:00
my % pid_owner = ( ) ;
2009-04-09 11:08:56 +00:00
$ SIG { CHLD } = sub { while ( waitpid ( - 1 , WNOHANG ) > 0 ) { $ children - - ; } } ;
2011-09-14 03:27:30 +00:00
$ SIG { INT } = $ SIG { TERM } = $ SIG { KILL } = sub { #prepare to process job termination and propogate it down
foreach my $ pid ( keys % pid_owner ) {
& kill_children_by_pid ( $ pid ) ;
}
exit 0 ;
} ;
2009-04-09 11:08:56 +00:00
my $ hw ;
my $ sessions ;
2009-05-19 03:20:17 +00:00
2009-04-09 11:08:56 +00:00
foreach ( @$ nodes ) {
while ( $ children >= $ request - > { ppcmaxp } ) {
my $ handlednodes = { } ;
2010-08-02 08:35:45 +00:00
child_response ( $ callback , $ fds , $ handlednodes , $ failed_nodes , $ failed_msg , $ verbose ) ;
2009-05-19 03:20:17 +00:00
2009-06-05 08:02:34 +00:00
#update the node status to the nodelist.status table
2009-04-09 11:08:56 +00:00
if ( $ check ) {
updateNodeStatus ( $ handlednodes , \ @ allerrornodes ) ;
}
2009-05-19 03:20:17 +00:00
2009-04-09 11:08:56 +00:00
Time::HiRes:: sleep ( 0.1 ) ;
}
2009-06-05 08:02:34 +00:00
###################################
# sleep between connects to same
# HMC/IVM so as not to overwelm it
###################################
2009-04-09 11:08:56 +00:00
if ( $ hw ne @$ _ [ 0 ] ) {
$ sessions = 1 ;
} elsif ( $ sessions + + >= $ request - > { maxssh } ) {
sleep ( 1 ) ;
$ sessions = 1 ;
}
$ hw = @$ _ [ 0 ] ;
2009-05-19 03:20:17 +00:00
2011-09-14 03:27:30 +00:00
my ( $ pipe , $ pid ) = fork_cmd ( @$ _ [ 0 ] , @$ _ [ 1 ] , $ request ) ;
2009-04-09 11:08:56 +00:00
if ( $ pipe ) {
2011-09-14 03:27:30 +00:00
$ pid_owner { $ pid } = $ pid ;
2009-04-09 11:08:56 +00:00
$ fds - > add ( $ pipe ) ;
$ children + + ;
}
2007-11-16 19:47:00 +00:00
}
}
2009-05-19 03:20:17 +00:00
2009-04-09 11:08:56 +00:00
ENDOFFORK:
2009-06-05 08:02:34 +00:00
#######################################
# Process responses from children
#######################################
2008-10-21 02:50:13 +00:00
while ( $ fds - > count > 0 or $ children > 0 ) {
2009-03-25 02:56:58 +00:00
my $ handlednodes = { } ;
2010-08-02 08:35:45 +00:00
child_response ( $ callback , $ fds , $ handlednodes , $ failed_nodes , $ failed_msg , $ verbose ) ;
2008-10-21 02:50:13 +00:00
2009-06-05 08:02:34 +00:00
#update the node status to the nodelist.status table
2008-10-21 02:50:13 +00:00
if ( $ check ) {
2009-05-19 03:20:17 +00:00
updateNodeStatus ( $ handlednodes , \ @ allerrornodes ) ;
2008-10-21 02:50:13 +00:00
}
2008-05-02 19:15:23 +00:00
Time::HiRes:: sleep ( 0.1 ) ;
2008-02-18 20:00:34 +00:00
}
2009-05-19 03:20:17 +00:00
2009-06-05 08:02:34 +00:00
#drain one more time
2008-10-21 02:50:13 +00:00
my $ rc = 1 ;
while ( $ rc > 0 ) {
2009-05-19 03:20:17 +00:00
my $ handlednodes = { } ;
2010-08-02 08:35:45 +00:00
$ rc = child_response ( $ callback , $ fds , $ handlednodes , $ failed_nodes , $ failed_msg , $ verbose ) ;
2009-06-05 08:02:34 +00:00
#update the node status to the nodelist.status table
2009-05-19 03:20:17 +00:00
if ( $ check ) {
updateNodeStatus ( $ handlednodes , \ @ allerrornodes ) ;
}
2008-10-21 02:50:13 +00:00
}
2007-11-16 19:47:00 +00:00
if ( exists ( $ request - > { verbose } ) ) {
2008-06-02 17:54:15 +00:00
my $ elapsed = Time::HiRes:: gettimeofday ( ) - $ start ;
my $ msg = sprintf ( "Total Elapsed Time: %.3f sec\n" , $ elapsed ) ;
trace ( $ request , $ msg ) ;
2007-11-16 19:47:00 +00:00
}
2008-09-25 03:04:56 +00:00
2009-03-25 02:56:58 +00:00
if ( $ check ) {
2009-06-05 08:02:34 +00:00
#print "allerrornodes=@allerrornodes\n";
#revert the status back for there is no-op for the nodes
2009-03-25 02:56:58 +00:00
my % old = ( ) ;
foreach my $ node ( @ allerrornodes ) {
2009-05-19 03:20:17 +00:00
my $ stat = $ oldnodestatus { $ node } ;
if ( exists ( $ old { $ stat } ) ) {
my $ pa = $ old { $ stat } ;
push ( @$ pa , $ node ) ;
}
else {
$ old { $ stat } = [ $ node ] ;
}
2009-03-25 02:56:58 +00:00
}
xCAT_monitoring::monitorctrl:: setNodeStatusAttributes ( \ % old , 1 ) ;
}
2008-10-21 02:50:13 +00:00
return ( 0 ) ;
}
2008-09-25 03:04:56 +00:00
2011-12-30 09:04:04 +00:00
sub no_interrupt_sleep {
my $ sleep_time = shift ;
my $ sleep_end = time + $ sleep_time ;
while ( 1 ) {
my $ sleep_duration = $ sleep_end - time ;
last if $ sleep_duration <= 0 ;
Time::HiRes:: sleep ( $ sleep_duration ) ;
}
}
2011-09-14 03:27:30 +00:00
sub kill_children_by_pid {
my $ pid = shift ;
my @ pids = `ps -o pid,ppid -e` ;
for my $ a_pid ( @ pids ) {
if ( $ a_pid =~ /\s*(\d*)\s*(\d*)/ ) {
my $ tmp_pid = $ 1 ;
my $ tmp_ppid = $ 2 ;
if ( $ tmp_ppid == $ pid ) {
kill 9 , $ tmp_pid ;
}
}
}
}
2008-10-21 02:50:13 +00:00
##########################################################################
# updateNodeStatus
##########################################################################
sub updateNodeStatus {
2009-05-19 03:20:17 +00:00
my $ handlednodes = shift ;
my $ allerrornodes = shift ;
foreach my $ node ( keys ( %$ handlednodes ) ) {
if ( $ handlednodes - > { $ node } == - 1 ) { push ( @$ allerrornodes , $ node ) ; }
}
2007-11-16 19:47:00 +00:00
}
2007-12-06 16:36:32 +00:00
##########################################################################
# Verbose mode (-V)
##########################################################################
sub trace {
my $ request = shift ;
2008-06-02 17:54:15 +00:00
my $ msg = shift ;
2007-12-06 16:36:32 +00:00
my ( $ sec , $ min , $ hour , $ mday , $ mon , $ yr , $ wday , $ yday , $ dst ) = localtime ( time ) ;
2008-06-02 17:54:15 +00:00
my $ formatted = sprintf "%02d:%02d:%02d %5d %s" , $ hour , $ min , $ sec , $$ , $ msg ;
2008-02-18 20:00:34 +00:00
my $ callback = $ request - > { callback } ;
2008-06-02 17:54:15 +00:00
$ callback - > ( { data = > [ $ formatted ] } ) ;
2007-12-06 16:36:32 +00:00
}
2007-11-16 19:47:00 +00:00
##########################################################################
# Send response from child process back to xCAT client
##########################################################################
sub child_response {
my $ callback = shift ;
my $ fds = shift ;
2008-09-25 03:04:56 +00:00
my $ errornodes = shift ;
2010-08-02 08:35:45 +00:00
my $ failed_nodes = shift ;
my $ failed_msg = shift ;
my $ verbose = shift ;
2007-11-16 19:47:00 +00:00
my @ ready_fds = $ fds - > can_read ( 1 ) ;
2008-10-21 02:50:13 +00:00
my $ rc = @ ready_fds ;
2011-03-08 06:46:47 +00:00
my $ mkvm_cec ;
2007-11-16 19:47:00 +00:00
foreach my $ rfh ( @ ready_fds ) {
2008-06-02 17:54:15 +00:00
my $ data = <$rfh> ;
2007-11-16 19:47:00 +00:00
2009-06-05 08:02:34 +00:00
#################################
# Read from child process
#################################
2008-06-02 17:54:15 +00:00
if ( defined ( $ data ) ) {
2007-12-06 16:36:32 +00:00
while ( $ data !~ /ENDOFFREEZE6sK4ci/ ) {
$ data . = <$rfh> ;
}
my $ responses = thaw ( $ data ) ;
2010-01-29 08:23:22 +00:00
my @ nodes ;
foreach ( @$ responses ) {
my $ node = $ _ - > { node } - > [ 0 ] - > { name } - > [ 0 ] ;
2010-02-23 07:16:18 +00:00
if ( ! grep /^$node$/ , @ nodes ) {
push ( @ nodes , $ node ) ;
}
2010-01-29 08:23:22 +00:00
}
foreach ( sort @ nodes ) {
my $ nodename = $ _ ;
foreach ( @$ responses ) {
if ( $ nodename eq $ _ - > { node } - > [ 0 ] - > { name } - > [ 0 ] ) {
2011-03-08 06:46:47 +00:00
# One special case for mkvm to output some messages
if ( ( exists ( $ _ - > { errorcode } ) ) && ( $ _ - > { errorcode } eq "mkvm" ) ) {
$ mkvm_cec = $ nodename ;
next ;
}
2010-01-29 08:23:22 +00:00
#save the nodes that has errors for node status monitoring
if ( ( exists ( $ _ - > { errorcode } ) ) && ( $ _ - > { errorcode } != 0 ) ) {
2012-03-05 07:22:49 +00:00
#if($$failed_nodes[0] !~ /^noloop$/) {
#if (!grep /^$nodename$/, @$failed_nodes) {
# push(@$failed_nodes, $nodename);
#}
#if( defined( $failed_msg->{$nodename} )) {
# my $f = $failed_msg->{$nodename};
# my $c = scalar(@$f);
# $failed_msg->{$nodename}->[$c] = $_;
#} else {
# $failed_msg->{$nodename}->[0] = $_;
#}
#} else {
#$callback->( $_ );
#}
if ( $ errornodes ) { $ errornodes - > { $ _ - > { node } - > [ 0 ] - > { name } - > [ 0 ] } = - 1 ; }
2010-08-02 08:35:45 +00:00
#if verbose, print all the message;
#if not, print successful mesg for success, or all the failed mesg for failed.
2012-03-05 07:22:49 +00:00
#if ( $verbose ) {
# $callback->( $_ );
# }
2010-08-02 08:35:45 +00:00
2010-01-29 08:23:22 +00:00
} else {
2012-03-05 07:22:49 +00:00
if ( $ errornodes ) { $ errornodes - > { $ _ - > { node } - > [ 0 ] - > { name } - > [ 0 ] } = 1 ; }
#$callback->( $_ );
2010-01-29 08:23:22 +00:00
}
2012-03-05 07:22:49 +00:00
$ callback - > ( $ _ ) ;
2010-01-29 08:23:22 +00:00
}
}
}
2011-03-08 06:46:47 +00:00
if ( defined ( $ mkvm_cec ) ) {
my $ r ;
$ r - > { errorcode } = 0 ;
$ r - > { node } - > [ 0 ] - > { name } - > [ 0 ] = $ mkvm_cec ;
$ r - > { node } - > [ 0 ] - > { data } - > [ 0 ] - > { contents } - > [ 0 ] = "Please reboot the CEC $mkvm_cec firstly, and then use chvm to assign the I/O slots to the LPARs" ;
$ callback - > ( $ r ) ;
}
2007-12-06 16:36:32 +00:00
next ;
2007-11-16 19:47:00 +00:00
}
2009-06-05 08:02:34 +00:00
#################################
# Done - close handle
#################################
2007-11-16 19:47:00 +00:00
$ fds - > remove ( $ rfh ) ;
close ( $ rfh ) ;
2007-12-06 16:36:32 +00:00
}
2008-10-21 02:50:13 +00:00
yield ; #Try to avoid useless iterations as much as possible
2009-06-05 08:02:34 +00:00
return $ rc ;
2007-11-16 19:47:00 +00:00
}
2008-03-19 17:44:30 +00:00
##########################################################################
# Finds attributes for given node is various databases
##########################################################################
sub resolve_hcp {
my $ request = shift ;
my $ noderange = shift ;
my @ nodegroup = ( ) ;
2009-01-19 08:58:29 +00:00
my $ tab = ( $ request - > { hwtype } eq "fsp" or $ request - > { hwtype } eq "bpa" ) ? "ppcdirect" : "ppchcp" ;
2008-03-19 17:44:30 +00:00
my $ db = xCAT::Table - > new ( $ tab ) ;
2009-06-05 08:02:34 +00:00
####################################
# Database not defined
####################################
2008-03-19 17:44:30 +00:00
if ( ! defined ( $ db ) ) {
send_msg ( $ request , 1 , sprintf ( $ errmsg { DB_UNDEF } , $ tab ) ) ;
return undef ;
}
2009-06-05 08:02:34 +00:00
####################################
# Process each node
####################################
2008-05-02 19:46:29 +00:00
foreach my $ hcp ( @$ noderange ) {
2009-07-27 15:28:11 +00:00
# my ($ent) = $db->getAttribs( {hcp=>$hcp},"hcp" );
# my ($ent) = $db->getNodeAttribs( $hcp, ["hcp"]);
# if ( !defined( $ent )) {
# my $msg = sprintf( "$hcp: $errmsg{NODE_UNDEF}", $tab );
# send_msg( $request, 1, $msg );
# next;
# }
2009-06-05 08:02:34 +00:00
################################
2009-09-02 16:48:58 +00:00
# Get userid and password
2009-06-05 08:02:34 +00:00
################################
2008-05-02 19:46:29 +00:00
my @ cred = xCAT::PPCdb:: credentials ( $ hcp , $ request - > { hwtype } ) ;
$ request - > { $ hcp } { cred } = \ @ cred ;
2009-06-05 08:02:34 +00:00
################################
# Save values
################################
2008-05-02 19:46:29 +00:00
push @ nodegroup , [ $ hcp ] ;
2008-03-19 17:44:30 +00:00
}
return ( \ @ nodegroup ) ;
}
2007-11-16 19:47:00 +00:00
##########################################################################
# Group nodes depending on command
##########################################################################
sub preprocess_nodes {
my $ request = shift ;
2010-08-02 08:35:45 +00:00
my $ hcps_will = shift ;
2007-11-16 19:47:00 +00:00
my $ noderange = $ request - > { node } ;
my $ method = $ request - > { method } ;
my % nodehash = ( ) ;
my @ nodegroup = ( ) ;
2009-09-02 16:48:58 +00:00
my % hcpgroup = ( ) ;
2007-11-16 19:47:00 +00:00
my % tabs = ( ) ;
2008-03-19 17:44:30 +00:00
my $ netwk ;
2007-11-16 19:47:00 +00:00
2009-06-05 08:02:34 +00:00
########################################
# Special cases
# rscan - Nodes are hardware control pts
2009-12-10 02:19:40 +00:00
# FSPpower, FSPinv and FSPrflash
2009-06-05 08:02:34 +00:00
########################################
2009-12-29 08:23:20 +00:00
if ( ( ! $ request - > { hcp } && ( $ request - > { hcp } ne "hmc" ) )
2009-09-21 06:33:27 +00:00
and ( $ request - > { command } !~ /^renergy$/ )
and ( ( $ request - > { command } =~ /^(rscan|rspconfig)$/ )
or ( $ request - > { hwtype } eq "fsp" or $ request - > { hwtype } eq "bpa" )
2009-12-10 02:19:40 +00:00
or ( $ request - > { command } eq 'lshwconn' and $ request - > { nodetype } eq 'hmc' ) ) and ( $ request - > { fsp_api } != 1 )
2009-09-21 06:33:27 +00:00
) {
2012-03-06 05:17:56 +00:00
my $ result = resolve_hcp ( $ request , $ noderange ) ;
2008-03-19 17:44:30 +00:00
return ( $ result ) ;
}
2009-06-05 08:02:34 +00:00
##########################################
# Special processing - rnetboot
##########################################
2010-12-13 05:54:32 +00:00
if ( $ request - > { command } eq "rnetboot" || $ request - > { command } eq "rbootseq" ) {
2008-03-19 17:44:30 +00:00
$ netwk = resolve_netwk ( $ request , $ noderange ) ;
2012-11-30 09:06:20 +00:00
if ( ! ( %$ netwk ) ) {
2007-11-16 19:47:00 +00:00
return undef ;
}
}
2009-06-05 08:02:34 +00:00
##########################################
# Open databases needed
##########################################
2008-03-19 14:18:39 +00:00
foreach ( qw( ppc vpd nodetype ) ) {
2007-11-16 19:47:00 +00:00
$ tabs { $ _ } = xCAT::Table - > new ( $ _ ) ;
if ( ! exists ( $ tabs { $ _ } ) ) {
2008-02-18 20:26:39 +00:00
send_msg ( $ request , 1 , sprintf ( $ errmsg { DB_UNDEF } , $ _ ) ) ;
2007-11-16 19:47:00 +00:00
return undef ;
}
}
2012-05-02 05:51:24 +00:00
##########################################################
# For DFM actions, all the IPs of the FSPs/BPAs corresponding CECs/Frames will be used to do the
# comminucation with the hdwr_svr. So use the gethcpAttribs() to collect the CECs' FSPs, and Frames'
# BPA here for process fork .
# In the HMC hardware control environment, the mkhwconn/rmhwconn commands will use the FSPs' IPs or
# the BPAs' IPs. So it also need to collect the CECs' FSPs, and Frames' BPA here.
##########################################################
2012-06-08 09:57:22 +00:00
if ( $ request - > { fsp_api } == 1 || $ request - > { command } =~ /^(mkhwconn|rmhwconn|lshwconn)$/ ) {
2012-04-28 09:22:50 +00:00
xCAT::FSPUtils:: getHcpAttribs ( $ request , \ % tabs ) ;
}
2009-05-19 03:20:17 +00:00
2009-06-05 08:02:34 +00:00
##########################################
2012-05-02 13:47:59 +00:00
# Group nodes. The first key is hcp, and the second kery is mtms.
2012-05-02 05:51:24 +00:00
# All the attributs collected here will be used for the different commands Grcup Nodes later.
2009-06-05 08:02:34 +00:00
##########################################
2007-11-16 19:47:00 +00:00
foreach my $ node ( @$ noderange ) {
my $ d = resolve ( $ request , $ node , \ % tabs ) ;
2009-06-05 08:02:34 +00:00
######################################
# Error locating node attributes
######################################
2007-11-16 19:47:00 +00:00
if ( ref ( $ d ) ne 'ARRAY' ) {
2008-02-18 20:26:39 +00:00
send_msg ( $ request , 1 , "$node: $d" ) ;
2007-11-16 19:47:00 +00:00
next ;
}
2009-06-05 08:02:34 +00:00
######################################
# Get data values
######################################
2012-03-05 07:22:49 +00:00
my $ hcp = @$ d [ 3 ] ;
#my $hcp = $hcps_will->{$node};
#@$d[3] = $hcp;
2007-11-16 19:47:00 +00:00
my $ mtms = @$ d [ 2 ] ;
2012-04-18 00:55:11 +00:00
2009-05-20 09:04:19 +00:00
######################################
2012-05-02 05:51:24 +00:00
# Special case for mkhwconn with -p. The hcp in the command is specified by the users,
# not in the DB, and the hcp value is stored in $request->{opt}->{p}.
# So set the $request->{opt}->{p} as the key the %nodehash directly.
2009-05-20 09:04:19 +00:00
######################################
2009-08-04 20:28:03 +00:00
if ( $ request - > { command } eq "mkhwconn" and
2009-05-20 09:04:19 +00:00
exists $ request - > { opt } - > { p } )
{
$ nodehash { $ request - > { opt } - > { p } } { $ mtms } { $ node } = $ d ;
}
######################################
#The common case
######################################
else
{
$ nodehash { $ hcp } { $ mtms } { $ node } = $ d ;
}
2007-11-16 19:47:00 +00:00
}
2009-05-19 03:20:17 +00:00
2009-06-05 08:02:34 +00:00
##########################################
# Get userid and password
##########################################
2008-05-02 19:46:29 +00:00
while ( my ( $ hcp , $ hash ) = each ( % nodehash ) ) {
2012-03-06 05:17:56 +00:00
my @ cred ;
2012-04-28 09:22:50 +00:00
if ( $ request - > { fsp_api } != 1 ) {
if ( $ request - > { hcp } && ( $ request - > { hcp } eq "hmc" ) ) {
@ cred = xCAT::PPCdb:: credentials ( $ hcp , $ request - > { hcp } ) ;
} else {
@ cred = xCAT::PPCdb:: credentials ( $ hcp , $ request - > { hwtype } ) ;
}
2009-09-02 16:48:58 +00:00
$ request - > { $ hcp } { cred } = \ @ cred ;
2012-04-28 09:22:50 +00:00
}
2012-05-02 05:51:24 +00:00
######################################################
#In DFM suppport, only the mkhwconn command need the userid/password to
#create the connection between hdwr_svr and FSPs/BPAs
######################################################
2012-04-28 09:22:50 +00:00
if ( $ request - > { fsp_api } == 1 && $ request - > { command } eq "mkhwconn" ) {
my $ user ;
2012-05-02 13:47:59 +00:00
while ( my ( $ mtms , $ h ) = each ( %$ hash ) ) {
while ( my ( $ node , $ tmp_d ) = each ( %$ h ) ) {
my $ type = $$ tmp_d [ 4 ] ;
###############
#For NGP, get the passwd of the cmm's username USERID
###############
if ( $ type && $ type =~ /^blade$/ ) {
$ user = "USERID" ;
my $ cmm = $$ tmp_d [ 5 ] ;
@ cred = xCAT::PPCdb:: credentials ( $ cmm , $ type , $ user ) ;
$ request - > { $ cmm } { cred } = \ @ cred ;
}
############################
#For P7 IH DFM, get the password of the CEC's/Frame's username HMC
###########################
if ( $ type && $ type =~ /^(fsp|bpa|cec|frame)$/ ) {
$ user = "HMC" ;
@ cred = xCAT::PPCdb:: credentials ( $ hcp , $ type , $ user ) ;
$ request - > { $ hcp } { cred } = \ @ cred ;
}
}
}
2012-04-28 09:22:50 +00:00
}
2008-05-02 19:46:29 +00:00
}
2009-06-05 08:02:34 +00:00
##########################################
# Group the nodes - we will fork one
# process per nodegroup array element.
##########################################
##########################################
# These commands are grouped on an
# LPAR-by-LPAR basis - fork one process
# per LPAR.
##########################################
2010-12-13 05:54:32 +00:00
if ( ( $ method =~ /^(getmacs)$/ && exists ( $ request - > { opt } - > { D } ) ) || ( $ method =~ /^(rnetboot)$/ ) || $ method =~ /^(rbootseq)$/ ) {
2007-11-16 19:47:00 +00:00
while ( my ( $ hcp , $ hash ) = each ( % nodehash ) ) {
2009-04-09 11:08:56 +00:00
@ nodegroup = ( ) ;
2007-11-16 19:47:00 +00:00
while ( my ( $ mtms , $ h ) = each ( %$ hash ) ) {
while ( my ( $ lpar , $ d ) = each ( %$ h ) ) {
push @$ d , $ lpar ;
2008-03-19 17:44:30 +00:00
2009-06-05 08:02:34 +00:00
##########################
# Save network info
##########################
2010-12-13 05:54:32 +00:00
if ( $ method =~ /^rnetboot$/ || $ method =~ /^(rbootseq)$/ ) {
2008-03-19 17:44:30 +00:00
push @$ d , $ netwk - > { $ lpar } ;
}
2007-11-16 19:47:00 +00:00
push @ nodegroup , [ $ hcp , $ d ] ;
}
}
2009-04-09 11:08:56 +00:00
$ hcpgroup { $ hcp } { 'nodegroup' } = [ @ nodegroup ] ;
$ hcpgroup { $ hcp } { 'count' } = $# nodegroup + 1 ;
$ hcpgroup { $ hcp } { 'runprocess' } = 0 ;
$ hcpgroup { $ hcp } { 'index' } = 0 ;
2007-11-16 19:47:00 +00:00
}
2009-04-09 11:08:56 +00:00
return ( \ % hcpgroup ) ;
2007-11-16 19:47:00 +00:00
}
2009-04-09 11:08:56 +00:00
2009-07-14 12:16:11 +00:00
elsif ( $ method =~ /^(getmacs)$/ && exists ( $ request - > { opt } - > { arp } ) ) {
return ( $ noderange ) ;
}
2009-06-05 08:02:34 +00:00
##########################################
# Power control commands are grouped
# by CEC which is the smallest entity
# that commands can be sent to in parallel.
# If commands are sent in parallel to a
# single CEC, the CEC itself will serialize
# them - fork one process per CEC.
##########################################
2009-09-21 06:33:27 +00:00
elsif ( $ method =~ /^powercmd/ || $ method =~ /^renergy/ ) {
2007-11-16 19:47:00 +00:00
while ( my ( $ hcp , $ hash ) = each ( % nodehash ) ) {
while ( my ( $ mtms , $ h ) = each ( %$ hash ) ) {
push @ nodegroup , [ $ hcp , $ h ] ;
}
}
return ( \ @ nodegroup ) ;
}
2009-06-05 08:02:34 +00:00
##########################################
# All other commands are grouped by
# hardware control point - fork one
# process per hardware control point.
##########################################
2007-11-16 19:47:00 +00:00
while ( my ( $ hcp , $ hash ) = each ( % nodehash ) ) {
2012-03-06 05:17:56 +00:00
push @ nodegroup , [ $ hcp , $ hash ] ;
}
return ( \ @ nodegroup ) ;
2007-11-16 19:47:00 +00:00
}
2008-03-19 17:44:30 +00:00
##########################################################################
# Finds attributes for given node is various databases
##########################################################################
sub resolve_netwk {
my $ request = shift ;
my $ noderange = shift ;
my % nethash = xCAT::DBobjUtils - > getNetwkInfo ( $ noderange ) ;
my $ tab = xCAT::Table - > new ( 'mac' ) ;
my % result = ( ) ;
2008-04-15 18:51:35 +00:00
my $ ip ;
2008-03-19 17:44:30 +00:00
2009-06-05 08:02:34 +00:00
#####################################
# Network attributes undefined
#####################################
2008-06-02 17:54:15 +00:00
if ( ! % nethash ) {
2008-03-19 17:44:30 +00:00
send_msg ( $ request , 1 , sprintf ( $ errmsg { NODE_UNDEF } , "networks" ) ) ;
return undef ;
}
2009-06-05 08:02:34 +00:00
#####################################
# mac database undefined
#####################################
2008-03-19 17:44:30 +00:00
if ( ! defined ( $ tab ) ) {
send_msg ( $ request , 1 , sprintf ( $ errmsg { DB_UNDEF } , "mac" ) ) ;
return undef ;
}
foreach ( @$ noderange ) {
2009-06-05 08:02:34 +00:00
#################################
# Get gateway (-G)
#################################
2008-03-19 17:44:30 +00:00
if ( ! exists ( $ nethash { $ _ } ) ) {
my $ msg = sprintf ( "$_: $errmsg{NODE_UNDEF}" , "networks" ) ;
send_msg ( $ request , 1 , $ msg ) ;
next ;
}
2008-04-02 12:43:12 +00:00
my $ gateway = $ nethash { $ _ } { gateway } ;
2010-12-30 02:05:31 +00:00
my $ gateway_ip ;
2014-01-27 15:57:13 +00:00
if ( defined ( $ gateway ) && $ gateway ) {
2012-08-09 04:00:45 +00:00
$ ip = xCAT::NetworkUtils:: toIP ( $ gateway ) ;
2010-12-30 02:05:31 +00:00
if ( @$ ip [ 0 ] != 0 ) {
send_msg ( $ request , 1 , "$_: Cannot resolve '$gateway'" ) ;
next ;
}
$ gateway_ip = @$ ip [ 1 ] ;
2014-01-27 15:57:13 +00:00
} else {
# If the <xcatmaster> is the gateway, the ip forwarding must be enabled on the MN/SN,
# xCAT will setup the ipforarding automatically, but still see problems about the ip forwarding occassionally.
send_msg ( $ request , 1 , "$_: No gateway defined for this node, check the networks table. If the gateway in the networks table is '<xcatmaster>', check the ip forwarding setup on the management node and service nodes." ) ;
next ;
2008-04-02 12:43:12 +00:00
}
2008-04-15 18:51:35 +00:00
2010-05-11 06:22:28 +00:00
my $ netmask = $ nethash { $ _ } { mask } ;
if ( ! defined ( $ netmask ) ) {
my $ msg = sprintf ( "$_: $errmsg{NO_ATTR}" , "mask" , "networks" ) ;
send_msg ( $ request , 1 , $ msg ) ;
next ;
}
2009-06-05 08:02:34 +00:00
#################################
# Get server (-S)
#################################
2012-08-09 04:00:45 +00:00
my $ server = xCAT::TableUtils - > GetMasterNodeName ( $ _ ) ;
2008-03-19 17:44:30 +00:00
if ( $ server == 1 ) {
send_msg ( $ request , 1 , "$_: Unable to identify master" ) ;
next ;
}
2012-08-09 04:00:45 +00:00
$ ip = xCAT::NetworkUtils:: toIP ( $ server ) ;
2008-04-15 18:51:35 +00:00
if ( @$ ip [ 0 ] != 0 ) {
2008-04-02 12:43:12 +00:00
send_msg ( $ request , 1 , "$_: Cannot resolve '$server'" ) ;
next ;
}
2008-04-15 18:51:35 +00:00
my $ server_ip = @$ ip [ 1 ] ;
2009-06-05 08:02:34 +00:00
#################################
# Get client (-C)
#################################
2012-08-09 04:00:45 +00:00
$ ip = xCAT::NetworkUtils:: toIP ( $ _ ) ;
2008-04-15 18:51:35 +00:00
if ( @$ ip [ 0 ] != 0 ) {
2008-04-02 12:43:12 +00:00
send_msg ( $ request , 1 , "$_: Cannot resolve '$_'" ) ;
next ;
}
2008-04-15 18:51:35 +00:00
my $ client_ip = @$ ip [ 1 ] ;
2009-05-19 03:20:17 +00:00
2009-06-05 08:02:34 +00:00
#################################
# Get mac-address (-m)
#################################
2008-11-07 13:34:47 +00:00
my ( $ ent ) = $ tab - > getNodeAttribs ( $ _ , [ 'mac' ] ) ;
2008-03-19 17:44:30 +00:00
if ( ! defined ( $ ent ) ) {
my $ msg = sprintf ( "$_: $errmsg{NO_ATTR}" , "mac" , "mac" ) ;
send_msg ( $ request , 1 , $ msg ) ;
next ;
}
2009-06-05 08:02:34 +00:00
#################################
# Save results
#################################
2008-04-02 12:43:12 +00:00
$ result { $ _ } { gateway } = $ gateway_ip ;
$ result { $ _ } { server } = $ server_ip ;
$ result { $ _ } { client } = $ client_ip ;
2008-03-19 17:44:30 +00:00
$ result { $ _ } { mac } = $ ent - > { mac } ;
2010-05-11 06:22:28 +00:00
$ result { $ _ } { netmask } = $ netmask ;
2008-03-19 17:44:30 +00:00
}
return ( \ % result ) ;
}
2007-11-16 19:47:00 +00:00
##########################################################################
2008-03-19 17:44:30 +00:00
# Finds attributes for given node is various databases
2007-11-16 19:47:00 +00:00
##########################################################################
sub resolve {
my $ request = shift ;
my $ node = shift ;
my $ tabs = shift ;
2008-03-20 18:32:18 +00:00
my @ attribs = qw( id pprofile parent hcp ) ;
2007-11-16 19:47:00 +00:00
my @ values = ( ) ;
2009-06-05 08:02:34 +00:00
#################################
# Get node type
#################################
2011-06-07 05:41:37 +00:00
#my $ent = $tabs->{nodetype}->getNodeAttribs($node,[qw(nodetype node)]);
#if ( !defined( $ent )) {
# return( sprintf( $errmsg{NODE_UNDEF}, "nodetype" ));
#}
2009-06-05 08:02:34 +00:00
#################################
# Check for type
#################################
2011-06-07 05:41:37 +00:00
#if ( !exists( $ent->{nodetype} )) {
# return( sprintf( $errmsg{NO_ATTR}, "nodetype","nodetype" ));
#}
2009-06-05 08:02:34 +00:00
#################################
# Check for valid "type"
#################################
2012-02-10 10:32:50 +00:00
my $ ttype = xCAT::DBobjUtils - > getnodetype ( $ node , "ppc" ) ;
2008-02-14 19:47:42 +00:00
my ( $ type ) = grep (
2012-03-05 07:22:49 +00:00
/^$::NODETYPE_LPAR|$::NODETYPE_OSI|$::NODETYPE_BPA|$::NODETYPE_FSP|$::NODETYPE_CEC|$::NODETYPE_FRAME|$::NODETYPE_BLADE$/ ,
2011-06-07 05:41:37 +00:00
#split /,/, $ent->{nodetype} );
2012-02-17 06:00:45 +00:00
split /,/ , $ ttype ) ;
2008-02-13 19:26:13 +00:00
if ( ! defined ( $ type ) ) {
2011-06-07 05:41:37 +00:00
#return( "Invalid node type: $ent->{nodetype}" );
return ( "Invalid node type: $ttype" ) ;
2007-11-16 19:47:00 +00:00
}
2009-06-05 08:02:34 +00:00
#################################
# Get attributes
#################################
2008-11-07 13:34:47 +00:00
my ( $ att ) = $ tabs - > { ppc } - > getNodeAttribs ( $ node , \ @ attribs ) ;
2009-05-19 03:20:17 +00:00
2007-11-16 19:47:00 +00:00
if ( ! defined ( $ att ) ) {
return ( sprintf ( $ errmsg { NODE_UNDEF } , "ppc" ) ) ;
}
2009-06-05 08:02:34 +00:00
#################################
# Special lpar processing
#################################
2008-02-14 19:47:42 +00:00
if ( $ type =~ /^$::NODETYPE_OSI|$::NODETYPE_LPAR$/ ) {
2007-11-16 19:47:00 +00:00
$ att - > { bpa } = 0 ;
$ att - > { type } = "lpar" ;
2007-11-19 16:39:20 +00:00
$ att - > { node } = $ att - > { parent } ;
2007-11-16 19:47:00 +00:00
2007-11-19 16:39:20 +00:00
if ( ! exists ( $ att - > { parent } ) ) {
return ( sprintf ( $ errmsg { NO_ATTR } , "parent" , "ppc" ) ) ;
2007-11-16 19:47:00 +00:00
}
2009-06-05 08:02:34 +00:00
#############################
# Get BPA (if any)
2012-05-25 09:05:53 +00:00
#DFM doesn't support rvitals with temp, so add the if fsp_api != 1
#It will improve the performance of rvitals with all
2009-06-05 08:02:34 +00:00
#############################
2007-11-16 19:47:00 +00:00
if ( ( $ request - > { command } eq "rvitals" ) &&
2012-05-25 09:05:53 +00:00
( $ request - > { method } =~ /^all|temp$/ ) && $ request - > { fsp_api } != 1 ) {
2009-05-19 03:20:17 +00:00
my ( $ ent ) = $ tabs - > { ppc } - > getNodeAttribs ( $ att - > { parent } , [ 'parent' ] ) ;
2009-06-05 08:02:34 +00:00
#############################
# Find MTMS in vpd database
#############################
2009-05-19 03:20:17 +00:00
if ( ( defined ( $ ent ) ) && exists ( $ ent - > { parent } ) ) {
my @ attrs = qw( mtm serial ) ;
my ( $ vpd ) = $ tabs - > { vpd } - > getNodeAttribs ( $ ent - > { parent } , \ @ attrs ) ;
2009-06-05 08:02:34 +00:00
########################
# Verify attributes
########################
2007-11-16 19:47:00 +00:00
foreach ( @ attrs ) {
2009-07-08 07:41:43 +00:00
if ( ! defined ( $ vpd ) || ! exists ( $ vpd - > { $ _ } ) ) {
return ( sprintf ( $ errmsg { NO_UNDEF } , $ _ , "vpd" , $ ent - > { parent } ) ) ;
2007-11-16 19:47:00 +00:00
}
}
$ att - > { bpa } = "$vpd->{mtm}*$vpd->{serial}" ;
}
}
}
2009-06-05 08:02:34 +00:00
#################################
# Optional and N/A fields
#################################
2008-02-14 19:47:42 +00:00
elsif ( $ type =~ /^$::NODETYPE_FSP$/ ) {
2008-03-20 18:32:18 +00:00
$ att - > { pprofile } = 0 ;
$ att - > { id } = 0 ;
$ att - > { fsp } = 0 ;
$ att - > { node } = $ node ;
$ att - > { type } = $ type ;
$ att - > { parent } = exists ( $ att - > { parent } ) ? $ att - > { parent } : 0 ;
$ att - > { bpa } = $ att - > { parent } ;
2011-05-12 10:11:04 +00:00
my $ ntype ;
if ( exists ( $ att - > { parent } ) ) {
2012-02-10 10:32:50 +00:00
$ ntype = xCAT::DBobjUtils - > getnodetype ( $ att - > { parent } , "ppc" ) ;
2011-05-12 10:11:04 +00:00
}
if ( ( $ request - > { command } eq "rvitals" ) &&
2012-05-25 09:05:53 +00:00
( $ request - > { method } =~ /^all|temp$/ && $ ntype =~ /^cec$/ ) && $ request - > { fsp_api } != 1 ) {
2011-05-12 10:11:04 +00:00
my ( $ ent ) = $ tabs - > { ppc } - > getNodeAttribs ( $ att - > { parent } , [ 'parent' ] ) ;
#############################
# Find MTMS in vpd database
#############################
if ( ( defined ( $ ent ) ) && exists ( $ ent - > { parent } ) ) {
my @ attrs = qw( mtm serial ) ;
my ( $ vpd ) = $ tabs - > { vpd } - > getNodeAttribs ( $ ent - > { parent } , \ @ attrs ) ;
########################
# Verify attributes
########################
foreach ( @ attrs ) {
if ( ! defined ( $ vpd ) || ! exists ( $ vpd - > { $ _ } ) ) {
return ( sprintf ( $ errmsg { NO_UNDEF } , $ _ , "vpd" , $ ent - > { parent } ) ) ;
}
}
$ att - > { bpa } = "$vpd->{mtm}*$vpd->{serial}" ;
}
} elsif ( ( $ request - > { command } eq "rvitals" ) &&
2012-05-25 09:05:53 +00:00
( $ request - > { method } =~ /^all|temp$/ && $ ntype =~ /^bpa$/ ) && $ request - > { fsp_api } != 1 ) {
2011-05-12 10:11:04 +00:00
my @ attrs = qw( mtm serial ) ;
my ( $ vpd ) = $ tabs - > { vpd } - > getNodeAttribs ( $ att - > { parent } , \ @ attrs ) ;
########################
# Verify attributes
########################
foreach my $ attr ( @ attrs ) {
if ( ! defined ( $ vpd ) || ! exists ( $ vpd - > { $ attr } ) ) {
return ( sprintf ( $ errmsg { NO_UNDEF } , $ attr , "vpd" , $ att - > { parent } ) ) ;
}
}
$ att - > { bpa } = "$vpd->{mtm}*$vpd->{serial}" ;
}
2007-11-16 19:47:00 +00:00
}
2008-03-06 15:17:30 +00:00
elsif ( $ type =~ /^$::NODETYPE_BPA$/ ) {
2008-03-20 18:32:18 +00:00
$ att - > { pprofile } = 0 ;
$ att - > { id } = 0 ;
$ att - > { bpa } = 0 ;
$ att - > { parent } = 0 ;
$ att - > { fsp } = 0 ;
$ att - > { node } = $ node ;
$ att - > { type } = $ type ;
2007-11-16 19:47:00 +00:00
}
2012-03-05 07:22:49 +00:00
elsif ( $ type =~ /^$::NODETYPE_CEC|$::NODETYPE_BLADE$/ ) {
2010-12-10 03:00:22 +00:00
$ att - > { pprofile } = 0 ;
2012-03-05 07:22:49 +00:00
if ( $ type =~ /^$::NODETYPE_CEC$/ ) {
$ att - > { id } = 0 ;
}
2010-12-10 03:00:22 +00:00
$ att - > { fsp } = 0 ;
$ att - > { node } = $ node ;
$ att - > { type } = $ type ;
$ att - > { parent } = exists ( $ att - > { parent } ) ? $ att - > { parent } : 0 ;
$ att - > { bpa } = $ att - > { parent } ;
2011-05-12 10:11:04 +00:00
if ( ( $ request - > { command } eq "rvitals" ) &&
2012-05-25 09:05:53 +00:00
( $ request - > { method } =~ /^all|temp$/ ) && $ request - > { fsp_api } != 1 ) {
2011-05-12 10:11:04 +00:00
#############################
# Find MTMS in vpd database
#############################
if ( exists ( $ att - > { parent } ) ) {
my @ attrs = qw( mtm serial ) ;
my ( $ vpd ) = $ tabs - > { vpd } - > getNodeAttribs ( $ att - > { parent } , \ @ attrs ) ;
########################
# Verify attributes
########################
foreach ( @ attrs ) {
if ( ! defined ( $ vpd ) || ! exists ( $ vpd - > { $ _ } ) ) {
return ( sprintf ( $ errmsg { NO_UNDEF } , $ _ , "vpd" , $ att - > { parent } ) ) ;
}
}
$ att - > { bpa } = "$vpd->{mtm}*$vpd->{serial}" ;
}
}
2010-12-10 03:00:22 +00:00
}
2010-12-17 08:43:24 +00:00
elsif ( $ type =~ /^$::NODETYPE_FRAME$/ ) {
$ att - > { pprofile } = 0 ;
$ att - > { id } = 0 ;
$ att - > { bpa } = 0 ;
$ att - > { parent } = 0 ;
$ att - > { fsp } = 0 ;
$ att - > { node } = $ node ;
$ att - > { type } = $ type ;
}
2009-06-05 08:02:34 +00:00
#################################
# Find MTMS in vpd database
#################################
2007-11-16 19:47:00 +00:00
my @ attrs = qw( mtm serial ) ;
2008-11-07 13:34:47 +00:00
my ( $ vpd ) = $ tabs - > { vpd } - > getNodeAttribs ( $ att - > { node } , \ @ attrs ) ;
2007-11-16 19:47:00 +00:00
if ( ! defined ( $ vpd ) ) {
2008-06-02 17:54:15 +00:00
return ( sprintf ( $ errmsg { NODE_UNDEF } , "vpd: ($att->{node})" ) ) ;
2007-11-16 19:47:00 +00:00
}
2009-06-05 08:02:34 +00:00
################################
# Verify both vpd attributes
################################
2007-11-16 19:47:00 +00:00
foreach ( @ attrs ) {
if ( ! exists ( $ vpd - > { $ _ } ) ) {
2008-06-02 17:54:15 +00:00
return ( sprintf ( $ errmsg { NO_ATTR } , $ _ , "vpd: ($att->{node})" ) ) ;
2007-11-16 19:47:00 +00:00
}
}
$ att - > { fsp } = "$vpd->{mtm}*$vpd->{serial}" ;
2009-06-05 08:02:34 +00:00
#################################
# Verify required attributes
#################################
2007-11-16 19:47:00 +00:00
foreach my $ at ( @ attribs ) {
if ( ! exists ( $ att - > { $ at } ) ) {
2011-03-08 06:46:47 +00:00
if ( ! ( $ request - > { fsp_api } == 1 && ! exists ( $ att - > { pprofile } ) ) ) { #for p7 ih, there is no pprofile attribute
return ( sprintf ( $ errmsg { NO_ATTR } , $ at , "ppc" ) ) ;
}
2007-11-16 19:47:00 +00:00
}
}
2012-04-28 09:22:50 +00:00
############################
2012-05-02 05:51:24 +00:00
#Specail case for mkhwconn/lshwconn/rmhwconn with -s . The sfp value( always the hmc) should
#be set as the hcp.
2012-04-28 09:22:50 +00:00
############################
if ( $ request - > { command } =~ /^(mkhwconn|lshwconn|rmhwconn)$/ && grep ( /^-s$/ , @ { $ request - > { arg } } ) ) {
my $ sfp ;
unless ( $ request - > { sfp } ) {
my $ ent = $ tabs - > { ppc } - > getNodeAttribs ( $ node , [ qw( sfp ) ] ) ;
if ( $ request - > { command } =~ /^(lshwconn|rmhwconn)$/ && ! defined ( $ ent ) ) {
return ( "$node: No sfp defined in the ppc table." ) ;
}
$ sfp = $ ent - > { sfp } ;
} else {
$ sfp = $ request - > { sfp } ;
}
if ( $ request - > { command } =~ /^(mkhwconn)$/ && ! defined ( $ sfp ) ) {
return ( "$node: Please specify the sfp in the commands or in the ppc table." ) ;
}
$ request - > { fsp_api } = 0 ;
$ request - > { hwtype } = "hmc" ;
$ att - > { hcp } = $ sfp ;
}
2009-06-05 08:02:34 +00:00
#################################
# Build array of data
#################################
2008-03-20 18:32:18 +00:00
foreach ( qw( id pprofile fsp hcp type bpa ) ) {
2007-11-16 19:47:00 +00:00
push @ values , $ att - > { $ _ } ;
}
return ( \ @ values ) ;
}
##########################################################################
# Forks a process to run the ssh command
##########################################################################
sub fork_cmd {
my $ host = shift ;
my $ nodes = shift ;
my $ request = shift ;
2009-06-05 08:02:34 +00:00
#######################################
# Pipe childs output back to parent
#######################################
2007-11-16 19:47:00 +00:00
my $ parent ;
my $ child ;
pipe $ parent , $ child ;
2008-01-21 19:49:59 +00:00
my $ pid = xCAT::Utils - > xfork ;
2007-11-16 19:47:00 +00:00
if ( ! defined ( $ pid ) ) {
2009-06-05 08:02:34 +00:00
###################################
# Fork error
###################################
2008-02-18 20:26:39 +00:00
send_msg ( $ request , 1 , "Fork error: $!" ) ;
2007-11-16 19:47:00 +00:00
return undef ;
}
elsif ( $ pid == 0 ) {
2009-06-05 08:02:34 +00:00
###################################
# Child process
###################################
2007-11-16 19:47:00 +00:00
close ( $ parent ) ;
$ request - > { pipe } = $ child ;
2008-05-02 19:15:23 +00:00
invoke_cmd ( $ host , $ nodes , $ request ) ;
2007-11-16 19:47:00 +00:00
exit ( 0 ) ;
}
else {
2009-06-05 08:02:34 +00:00
###################################
# Parent process
###################################
2007-11-16 19:47:00 +00:00
close ( $ child ) ;
2009-04-09 11:08:56 +00:00
return ( $ parent , $ pid ) ;
2007-11-16 19:47:00 +00:00
}
return ( 0 ) ;
}
2011-06-17 07:29:17 +00:00
sub handle_cmd {
my $ server = shift ;
my $ host = shift ;
my $ request = shift ;
my $ verbose = $ request - > { verbose } ;
eval { require xCAT::PPCfsp } ;
if ( $@ ) {
send_msg ( $ request , 1 , $@ ) ;
return ;
}
my @ exp = xCAT::PPCfsp:: connect ( $ request , $ server ) ;
####################################
# Error connecting
####################################
if ( ref ( $ exp [ 0 ] ) ne "LWP::UserAgent" ) {
#send_msg( $request, 1, $exp[0] );
my @ output_array ;
my $ methods = $ request - > { method } ;
foreach ( keys %$ methods ) {
my % output ;
$ output { node } - > [ 0 ] - > { name } - > [ 0 ] = "$host" ;
$ output { node } - > [ 0 ] - > { data } - > [ 0 ] - > { contents } - > [ 0 ] = "$server: $exp[0]" ;
$ output { node } - > [ 0 ] - > { cmd } - > [ 0 ] = $ _ ;
$ output { errorcode } = 128 ;
push @ output_array , \ % output ;
}
return \ @ output_array ;
}
$ request - > { host } = $ host ;
my $ result = xCAT::PPCfsp:: handler ( $ server , $ request , \ @ exp ) ;
####################################
# Output verbose Perl::LWP
####################################
if ( $ verbose ) {
my $ verbose_log = $ exp [ 3 ] ;
my $ output = shift @$ result ;
$ output - > { data } = [ $$ verbose_log ] ;
unshift @$ result , \ %$ output ;
}
return $ result ;
}
sub handle_find_hw_children {
my $ host = shift ;
my $ child_type = shift ;
my @ children = ( ) ;
my $ vpdtab = xCAT::Table - > new ( "vpd" ) ;
if ( ! defined ( $ vpdtab ) or ! defined ( $ child_type ) ) {
return undef ;
}
2011-12-08 08:08:18 +00:00
my $ mtms = $ vpdtab - > getNodeAttribs ( $ host , qw( serial mtm ) ) ;
2011-06-17 07:29:17 +00:00
if ( ! defined ( $ mtms ) ) {
return undef ;
}
2011-12-30 09:04:04 +00:00
my @ nodearray = $ vpdtab - > getAttribs ( { serial = > $ mtms - > { serial } , mtm = > $ mtms - > { mtm } } , qw( node side ) ) ; # need regx
2012-11-30 09:06:20 +00:00
if ( ! ( @ nodearray ) ) {
2011-06-17 07:29:17 +00:00
return undef ;
}
2012-02-10 10:32:50 +00:00
my @ tempnodes ;
foreach ( @ nodearray ) {
push @ tempnodes , $ _ - > { node } ;
}
my $ typehash = xCAT::DBobjUtils - > getnodetype ( \ @ tempnodes , "ppc" ) ;
2011-06-17 07:29:17 +00:00
foreach my $ node ( @ nodearray ) {
2012-02-10 10:32:50 +00:00
my $ n_type = $$ typehash { $ node - > { node } } ;
2011-06-17 07:29:17 +00:00
if ( $ n_type !~ /^$child_type$/ or ! defined ( $ node - > { side } ) ) {
next ;
}
push @ children , $ node ;
}
if ( scalar ( @ children ) eq '0' ) {
return undef ;
}
return \ @ children ;
}
sub print_res {
my $ request = shift ;
my $ host = shift ;
my $ res_array = shift ;
if ( ! defined ( $ res_array ) or ref ( $ res_array ) ne 'ARRAY' ) {
return ;
}
my $ out = $ request - > { pipe } ;
print $ out freeze ( $ res_array ) ;
print $ out "\nENDOFFREEZE6sK4ci\n" ;
return ;
}
sub get_dirindex_from_side {
my $ side = shift ;
my $ dir = undef ;
if ( $ side =~ /(a+)-\d*/i ) {
$ dir = '0' ;
} elsif ( $ side =~ /(b+)-\d*/i ) {
$ dir = '1' ;
} else {
$ dir = '2' ;
}
return $ dir ;
}
sub reorgnize_res_for_handle_cmd {
my $ request = shift ;
my $ host = shift ;
my $ output = shift ;
my $ methods = $ request - > { method } ;
my % re_output = ( ) ;
my % succ_side = ( ) ;
my $ dir = undef ;
foreach my $ side ( keys %$ output ) {
my $ res = $ output - > { $ side } ;
foreach my $ index ( @$$ res ) {
$ dir = & get_dirindex_from_side ( $ side ) ;
my $ cmd = $ index - > { node } - > [ 0 ] - > { cmd } - > [ 0 ] ;
if ( ( $ index - > { node } - > [ 0 ] - > { data } - > [ 0 ] - > { contents } - > [ 0 ] ) =~ /feature is not available/ ) {
$ dir = '0' ;
}
if ( ! defined ( $ succ_side { $ cmd } { $ dir } { done } ) ) {
if ( defined ( $ re_output { $ cmd } { $ dir } ) ) {
my $ array = $ re_output { $ cmd } { $ dir } ;
my $ n = scalar ( @$ array ) ;
$ array - > [ $ n ] = $ index ;
} else {
$ re_output { $ cmd } { $ dir } [ 0 ] = $ index ;
}
} else {
next ;
}
if ( $ index - > { errorcode } eq '0' ) {
@ { $ re_output { $ cmd } { $ dir } } = ( ) ;
$ re_output { $ cmd } { $ dir } [ 0 ] = $ index ;
$ succ_side { $ cmd } { $ dir } { done } + + ;
}
}
}
foreach my $ method ( keys % re_output ) {
my $ value = $ re_output { $ method } ;
foreach my $ side ( keys %$ value ) {
my $ res_array = $ value - > { $ side } ;
& print_res ( $ request , $ host , $ res_array ) ;
}
}
return undef ;
}
sub process_children {
my $ request = shift ;
my $ host = shift ;
my $ node_array = shift ;
my % output = ( ) ;
my % conn_flag = ( ) ;
foreach my $ index ( @$ node_array ) {
my $ side = $ index - > { side } ;
my $ dir = & get_dirindex_from_side ( $ side ) ;
if ( defined ( $ conn_flag { $ dir } ) ) {
next ;
}
2011-08-23 03:09:26 +00:00
$ request - > { $ index - > { node } } { cred } = $ request - > { $ host } { cred } ;
2011-06-17 07:29:17 +00:00
my $ res = & handle_cmd ( $ index - > { node } , $ host , $ request ) ;
$ output { $ side } = \ $ res ;
if ( $ res - > [ 0 ] - > { errorcode } ne '128' ) {
$ conn_flag { $ dir } = 1 ;
}
}
& reorgnize_res_for_handle_cmd ( $ request , $ host , \ % output ) ;
return undef ;
}
my % children_type = (
cec = > "fsp" ,
frame = > "bpa"
) ;
sub handle_redundance_fsps {
my $ host = shift ;
my $ hwtype = shift ;
my $ request = shift ;
my $ res = undef ;
if ( $ hwtype =~ /^(bpa|fsp)$/ ) {
$ res = & handle_cmd ( $ host , $ host , $ request ) ;
& print_res ( $ request , $ host , $ res ) ;
} elsif ( $ hwtype =~ /^(cec|frame)$/ ) {
my $ child_type = $ children_type { $ hwtype } ;
my $ children = & handle_find_hw_children ( $ host , $ child_type ) ;
if ( ! defined ( $ children ) ) {
send_msg ( $ request , 1 , "Not found any $child_type for $host" ) ;
} else {
& process_children ( $ request , $ host , $ children ) ;
}
} else {
send_msg ( $ request , 1 , "$hwtype not support!" ) ;
}
return undef ;
}
sub check_node_info {
my $ hash = shift ;
my $ if_lpar = undef ;
while ( my ( $ mtms , $ h ) = each ( %$ hash ) ) {
while ( my ( $ name , $ d ) = each ( %$ h ) ) {
my $ node_type = @$ d [ 4 ] ;
if ( $ node_type =~ /^lpar$/ ) {
$ if_lpar = $ name ;
last ;
}
}
}
return $ if_lpar ;
}
2007-11-16 19:47:00 +00:00
##########################################################################
# Run the command, process the response, and send to parent
##########################################################################
sub invoke_cmd {
my $ host = shift ;
my $ nodes = shift ;
my $ request = shift ;
my $ hwtype = $ request - > { hwtype } ;
my $ verbose = $ request - > { verbose } ;
2009-09-02 16:48:58 +00:00
my $ cmd = $ request - > { command } ;
2009-12-29 08:23:20 +00:00
my $ power = $ request - > { hcp } ;
2007-11-16 19:47:00 +00:00
my @ exp ;
2007-12-07 16:10:10 +00:00
my $ verbose_log ;
2007-11-16 19:47:00 +00:00
my @ outhash ;
2008-05-27 13:56:51 +00:00
2009-09-21 06:33:27 +00:00
########################################
# If the request command is renergy, just
# uses the xCAT CIM Client to handle it
########################################
if ( $ request - > { command } eq "renergy" ) {
my $ result = & runcmd ( $ request , $ host , $ nodes ) ;
########################################
# Format and send back to parent
########################################
2009-09-21 11:30:05 +00:00
foreach my $ line ( @$ result ) {
2009-09-21 06:33:27 +00:00
my % output ;
2009-09-21 11:30:05 +00:00
$ output { node } - > [ 0 ] - > { name } - > [ 0 ] = @$ line [ 0 ] ;
$ output { node } - > [ 0 ] - > { data } - > [ 0 ] - > { contents } - > [ 0 ] = @$ line [ 1 ] ;
$ output { errorcode } = @$ line [ 2 ] ;
2009-09-21 06:33:27 +00:00
push @ outhash , \ % output ;
}
my $ out = $ request - > { pipe } ;
print $ out freeze ( [ @ outhash ] ) ;
print $ out "\nENDOFFREEZE6sK4ci\n" ;
return ;
}
2009-06-05 08:02:34 +00:00
########################################
# Direct-attached FSP handler
########################################
2012-03-05 07:22:49 +00:00
if ( ( $ power ne "hmc" ) && ( $ hwtype =~ /^(fsp|bpa|cec|frame|blade)$/ ) && $ request - > { fsp_api } == 0 ) {
2011-06-17 07:29:17 +00:00
if ( $ request - > { command } eq 'rpower' ) {
my $ check = & check_node_info ( $ nodes ) ;
if ( defined ( $ check ) ) {
my % output ;
$ output { node } - > [ 0 ] - > { name } - > [ 0 ] = $ check ;
$ output { node } - > [ 0 ] - > { data } - > [ 0 ] - > { contents } - > [ 0 ] = "Error: $request->{command} not support on lpar in ASMI mode" ;
$ output { node } - > [ 0 ] - > { cmd } - > [ 0 ] = $ request - > { method } ;
$ output { errorcode } = 1 ;
my $ out = $ request - > { pipe } ;
print $ out freeze ( [ \ % output ] ) ;
print $ out "\nENDOFFREEZE6sK4ci\n" ;
return ;
}
2007-11-16 19:47:00 +00:00
2011-06-17 07:29:17 +00:00
if ( ref ( $ request - > { method } ) ne 'HASH' ) {
my % method_hash = ( ) ;
my $ method = $ request - > { method } ;
$ method_hash { $ method } = undef ;
$ request - > { method } = \ % method_hash ;
2007-12-06 19:09:40 +00:00
}
}
2011-06-17 07:29:17 +00:00
& handle_redundance_fsps ( $ host , $ hwtype , $ request ) ;
2007-11-16 19:47:00 +00:00
return ;
}
2007-12-07 16:10:10 +00:00
2009-06-05 08:02:34 +00:00
########################################
# HMC and IVM-managed handler
# Connect to list of remote servers
########################################
2010-01-07 06:00:53 +00:00
if ( $ request - > { fsp_api } == 0 ) {
foreach ( split /,/ , $ host ) {
if ( $ power ne "hmc" ) {
@ exp = xCAT::PPCcli:: connect ( $ request , $ hwtype , $ _ ) ;
} else {
@ exp = xCAT::PPCcli:: connect ( $ request , $ power , $ _ ) ;
}
####################################
# Successfully connected
####################################
if ( ref ( $ exp [ 0 ] ) eq "Expect" ) {
last ;
}
}
########################################
# Error connecting
########################################
if ( ref ( $ exp [ 0 ] ) ne "Expect" ) {
send_msg ( $ request , 1 , $ exp [ 0 ] ) ;
return ;
}
2007-11-16 19:47:00 +00:00
}
2010-01-07 06:00:53 +00:00
2009-06-05 08:02:34 +00:00
########################################
# Process specific command
########################################
2009-09-29 11:41:58 +00:00
my $ result = runcmd ( $ request , $ nodes , \ @ exp ) ;
2007-11-16 19:47:00 +00:00
2009-06-05 08:02:34 +00:00
########################################
# Close connection to remote server
########################################
2010-01-07 06:00:53 +00:00
if ( $ request - > { fsp_api } == 0 ) {
xCAT::PPCcli:: disconnect ( \ @ exp ) ;
}
2007-12-06 19:09:40 +00:00
2009-06-05 08:02:34 +00:00
########################################
# Get verbose Expect output
########################################
2007-12-06 16:36:32 +00:00
if ( $ verbose ) {
2007-12-07 16:10:10 +00:00
$ verbose_log = $ exp [ 6 ] ;
2007-12-06 16:36:32 +00:00
}
2009-06-05 08:02:34 +00:00
########################################
# Return error
########################################
2007-11-16 19:47:00 +00:00
if ( ref ( $ result ) ne 'ARRAY' ) {
2008-02-18 20:26:39 +00:00
send_msg ( $ request , 1 , $$ verbose_log . $ result ) ;
2007-11-16 19:47:00 +00:00
return ;
}
2009-06-05 08:02:34 +00:00
########################################
# Prepend verbose output
########################################
2007-12-07 16:10:10 +00:00
if ( defined ( $ verbose_log ) ) {
my % output ;
$ output { data } = [ $$ verbose_log ] ;
push @ outhash , \ % output ;
}
2009-06-05 08:02:34 +00:00
########################################
# Send result back to parent process
########################################
2007-12-06 16:36:32 +00:00
if ( @$ result [ 0 ] eq "FORMATDATA6sK4ci" ) {
2007-11-16 19:47:00 +00:00
my $ out = $ request - > { pipe } ;
2007-12-07 16:10:10 +00:00
push @ outhash , @$ result [ 1 ] ;
print $ out freeze ( [ @ outhash ] ) ;
2007-12-06 16:36:32 +00:00
print $ out "\nENDOFFREEZE6sK4ci\n" ;
2007-11-16 19:47:00 +00:00
return ;
}
2009-06-05 08:02:34 +00:00
########################################
# Format and send back to parent
########################################
2007-11-16 19:47:00 +00:00
foreach ( @$ result ) {
my % output ;
$ output { node } - > [ 0 ] - > { name } - > [ 0 ] = @$ _ [ 0 ] ;
2010-08-02 08:35:45 +00:00
#$output{node}->[0]->{data}->[0]->{contents}->[0] = @$_[1];
2008-03-04 20:16:35 +00:00
$ output { errorcode } = @$ _ [ 2 ] ;
2010-08-02 08:35:45 +00:00
if ( $ output { errorcode } != 0 ) {
if ( $ request - > { fsp_api } == 1 ) {
2010-08-05 06:37:39 +00:00
#$output{node}->[0]->{data}->[0]->{contents}->[0] = "(trying fsp-api)@$_[1]";
$ output { node } - > [ 0 ] - > { data } - > [ 0 ] - > { contents } - > [ 0 ] = "@$_[1]" ;
2010-08-02 08:35:45 +00:00
} else {
2010-08-05 06:37:39 +00:00
#$output{node}->[0]->{data}->[0]->{contents}->[0] = "(trying HMC )@$_[1]";
$ output { node } - > [ 0 ] - > { data } - > [ 0 ] - > { contents } - > [ 0 ] = "@$_[1]" ;
2010-08-02 08:35:45 +00:00
}
} else {
$ output { node } - > [ 0 ] - > { data } - > [ 0 ] - > { contents } - > [ 0 ] = @$ _ [ 1 ] ;
}
2007-11-16 19:47:00 +00:00
push @ outhash , \ % output ;
}
my $ out = $ request - > { pipe } ;
print $ out freeze ( [ @ outhash ] ) ;
2007-12-06 16:36:32 +00:00
print $ out "\nENDOFFREEZE6sK4ci\n" ;
2007-11-16 19:47:00 +00:00
}
##########################################################################
# Run the command method specified
##########################################################################
sub runcmd {
my $ request = shift ;
my $ cmd = $ request - > { command } ;
my $ method = $ request - > { method } ;
2007-11-30 20:04:17 +00:00
my $ hwtype = $ request - > { hwtype } ;
2009-12-10 02:19:40 +00:00
#my $modname = $modules{$cmd};
my $ modname = $ modules { $ cmd } { $ hwtype } ;
2007-11-30 20:04:17 +00:00
2009-06-05 08:02:34 +00:00
######################################
# Command not supported
######################################
2007-11-30 20:04:17 +00:00
if ( ! defined ( $ modname ) ) {
return ( [ "$cmd not a supported command by $hwtype method" ] ) ;
}
2009-06-05 08:02:34 +00:00
######################################
# Load specific module
######################################
2008-01-10 14:34:34 +00:00
eval "require $modname" ;
if ( $@ ) {
return ( [ $@ ] ) ;
2007-11-16 19:47:00 +00:00
}
2009-06-05 08:02:34 +00:00
######################################
# Invoke method
######################################
2007-11-16 19:47:00 +00:00
no strict 'refs' ;
my $ result = $ { $ modname . "::" } { $ method } - > ( $ request , @ _ ) ;
use strict ;
return ( $ result ) ;
}
2008-04-16 16:45:14 +00:00
##########################################################################
# Pre-process request from xCat daemon. Send the request to the the service
# nodes of the HCPs.
##########################################################################
sub preprocess_request {
2008-05-02 19:15:23 +00:00
2009-05-19 03:20:17 +00:00
my $ package = shift ;
my $ req = shift ;
2009-06-05 08:02:34 +00:00
#if ($req->{_xcatdest}) { return [$req]; } #exit if preprocessed
2009-05-19 03:20:17 +00:00
if ( $ req - > { _xcatpreprocessed } - > [ 0 ] == 1 ) { return [ $ req ] ; }
my $ callback = shift ;
2010-08-02 03:29:15 +00:00
my $ subreq = shift ;
2009-05-19 03:20:17 +00:00
my @ requests ;
2008-04-16 16:45:14 +00:00
2009-06-05 08:02:34 +00:00
#####################################
# Parse arguments
#####################################
2009-05-19 03:20:17 +00:00
my $ opt = parse_args ( $ package , $ req , $ callback ) ;
if ( ref ( $ opt ) eq 'ARRAY' )
{
send_msg ( $ req , 1 , @$ opt ) ;
2010-04-08 07:39:15 +00:00
delete ( $ req - > { callback } ) ; # if not, it will cause an error -- "Can't encode a value of type: CODE" in hierairchy.
2009-05-19 03:20:17 +00:00
return ( 1 ) ;
}
2010-04-08 07:39:15 +00:00
delete ( $ req - > { callback } ) ; # remove 'callback' => sub { "DUMMY" } in hierairchy.
2009-05-19 03:20:17 +00:00
$ req - > { opt } = $ opt ;
2010-03-29 03:38:05 +00:00
if ( exists ( $ req - > { opt } - > { V } ) ) {
$ req - > { verbose } = 1 ;
}
2009-06-05 08:02:34 +00:00
####################################
# Get hwtype
####################################
2009-05-19 03:20:17 +00:00
$ package =~ s/xCAT_plugin::// ;
2010-08-02 03:29:15 +00:00
my $ deps ;
my $ nodeseq ;
if ( ( $ req - > { command } - > [ 0 ] eq 'rpower' ) && ( ! grep ( /^--nodeps$/ , @ { $ req - > { arg } } ) )
&& ( ( $ req - > { op } - > [ 0 ] eq 'on' ) || ( $ req - > { op } - > [ 0 ] eq 'off' )
|| ( $ req - > { op } - > [ 0 ] eq 'softoff' ) || ( $ req - > { op } - > [ 0 ] eq 'reset' ) ) ) {
2009-05-19 03:20:17 +00:00
2010-08-02 03:29:15 +00:00
$ deps = xCAT::SvrUtils - > build_deps ( $ req - > { node } , $ req - > { op } - > [ 0 ] ) ;
2009-05-19 03:20:17 +00:00
2010-08-02 03:29:15 +00:00
# no dependencies at all
if ( ! defined ( $ deps ) ) {
foreach my $ node ( @ { $ req - > { node } } ) {
$ nodeseq - > [ 0 ] - > { $ node } = 1 ;
}
} else {
$ nodeseq = xCAT::SvrUtils - > handle_deps ( $ deps , $ req - > { node } , $ callback ) ;
}
2009-05-19 03:20:17 +00:00
}
2010-08-02 03:29:15 +00:00
if ( $ nodeseq == 1 ) {
return undef ;
}
# no dependency defined in deps table,
# generate the $nodeseq hash
if ( ! $ nodeseq ) {
foreach my $ node ( @ { $ req - > { node } } ) {
$ nodeseq - > [ 0 ] - > { $ node } = 1 ;
2009-05-19 03:20:17 +00:00
}
}
2010-08-02 03:29:15 +00:00
my $ i = 0 ;
for ( $ i = 0 ; $ i < scalar ( @ { $ nodeseq } ) ; $ i + + ) {
#reset the @requests for this loop
@ requests = ( ) ;
####################################
# Prompt for usage if needed and on MN
####################################
my @ dnodes = keys ( % { $ nodeseq - > [ $ i ] } ) ;
if ( scalar ( @ dnodes ) == 0 ) {
next ;
}
if ( scalar ( @ { $ nodeseq } ) > 1 ) {
my % output ;
my $ cnodes = join ( ',' , @ dnodes ) ;
$ output { data } = [ "Performing action against the following nodes: $cnodes" ] ;
$ callback - > ( \ % output ) ;
}
my $ noderange = \ @ dnodes ;
$ req - > { node } = \ @ dnodes ; #Should be arrayref
#$req->{noderange} = \@dnodes; #Should be arrayref
my $ command = $ req - > { command } - > [ 0 ] ;
my $ extrargs = $ req - > { arg } ;
my @ exargs = ( $ req - > { arg } ) ;
if ( ref ( $ extrargs ) ) {
@ exargs = @$ extrargs ;
}
if ( $ ENV { 'XCATBYPASS' } ) {
my $ usage_string = xCAT::Usage - > parseCommand ( $ command , @ exargs ) ;
if ( $ usage_string ) {
$ callback - > ( { data = > [ $ usage_string ] } ) ;
$ req = { } ;
return ;
}
if ( ! $ noderange ) {
$ usage_string = "Missing noderange" ;
$ callback - > ( { data = > [ $ usage_string ] } ) ;
$ req = { } ;
return ;
}
}
##################################################################
# get the HCPs for the LPARs in order to figure out which service
# nodes to send the requests to
###################################################################
2011-12-12 03:18:37 +00:00
#my $hcptab_name = ($package eq "fsp" or $package eq "bpa") ? "ppcdirect" : "ppchcp";
#my $hcptab = xCAT::Table->new( $hcptab_name );
#unless ($hcptab ) {
# $callback->({data=>["Cannot open $hcptab_name table"]});
# $req = {};
# return;
#}
2010-08-02 03:29:15 +00:00
# Check if each node is hcp
my % hcp_hash = ( ) ;
my @ missednodes = ( ) ;
2011-12-12 03:18:37 +00:00
my $ support_hcp_type ;
# in the DFM model, cec/fsp/Frame/bpa can be hcp.
if ( $ package eq "fsp" or $ package eq "bpa" ) {
2012-03-06 05:17:56 +00:00
$ support_hcp_type = "(fsp|cec|bpa|frame|blade)" ;
2011-12-12 03:18:37 +00:00
# in the HMC model, only hmc can be hcp.
} elsif ( $ package eq "hmc" ) {
$ support_hcp_type = "hmc" ;
# package equal 'ivm', only ivm can be hcp.
} else {
$ support_hcp_type = "ivm" ;
}
2012-04-10 13:28:24 +00:00
my $ typehash = xCAT::DBobjUtils - > getnodetype ( \ @$ noderange ) ;
2010-08-02 03:29:15 +00:00
foreach ( @$ noderange ) {
2012-02-10 10:32:50 +00:00
my $ nodetype = $$ typehash { $ _ } ;
2011-12-12 03:18:37 +00:00
if ( $ nodetype and $ nodetype =~ /$support_hcp_type/ ) {
push @ { $ hcp_hash { $ _ } { nodes } } , $ _ ;
} else {
2010-08-02 03:29:15 +00:00
push @ missednodes , $ _ ;
}
}
2011-12-12 03:18:37 +00:00
#foreach ( @$noderange ) {
# my ($ent) = $hcptab->getNodeAttribs( $_,"hcp" );
# if ( !defined( $ent )) {
# push @missednodes, $_;
# next;
# }
# push @{$hcp_hash{$_}{nodes}}, $_;
#}
2010-08-02 03:29:15 +00:00
#check if the left-over nodes are lpars
if ( @ missednodes > 0 ) {
my $ ppctab = xCAT::Table - > new ( "ppc" ) ;
unless ( $ ppctab ) {
$ callback - > ( { data = > [ "Cannot open ppc table" ] } ) ;
2009-05-19 03:20:17 +00:00
$ req = { } ;
return ;
}
2010-08-02 03:29:15 +00:00
foreach my $ node ( @ missednodes ) {
2011-05-10 07:58:27 +00:00
2010-08-02 03:29:15 +00:00
my $ ent = $ ppctab - > getNodeAttribs ( $ node , [ 'hcp' ] ) ;
2011-05-10 07:58:27 +00:00
#if (defined($ent->{hcp})) { push @{$hcp_hash{$ent->{hcp}}{nodes}}, $node;}
2010-08-02 08:35:45 +00:00
if ( defined ( $ ent - > { hcp } ) ) {
2011-05-10 07:58:27 +00:00
#for multiple hardware control points, the hcps should be split to nodes
my @ h = split ( "," , $ ent - > { hcp } ) ;
foreach my $ hcp ( @ h ) {
2010-08-02 08:35:45 +00:00
push @ { $ hcp_hash { $ hcp } { nodes } } , $ node ;
2011-05-10 07:58:27 +00:00
}
2010-08-02 08:35:45 +00:00
} else {
2010-08-02 03:29:15 +00:00
$ callback - > ( { data = > [ "The node $node is neither a hcp nor an lpar" ] } ) ;
$ req = { } ;
return ;
}
}
}
2012-08-09 04:00:45 +00:00
my @ masters = xCAT::TableUtils - > get_site_attribute ( "master" ) ;
2011-10-14 05:34:10 +00:00
#When run mkhwconn/lshwconn/rmhwconn with -T fnm for CNM, it will send the command to CEC/Frame direclty,
#not through the service node if specified.
2012-04-12 08:11:57 +00:00
if ( $ req - > { command } - > [ 0 ] =~ /^(mkhwconn|lshwconn|rmhwconn|rpower)$/
2011-10-19 05:23:10 +00:00
&& ( $ req - > { opt } - > { T } == 1 ) ) {
#for fnm
my $ reqcopy = { %$ req } ;
2012-08-09 04:00:45 +00:00
#my @masters = xCAT::TableUtils->get_site_attribute("master");
2011-10-19 05:23:10 +00:00
if ( $ masters [ 0 ] ) {
$ reqcopy - > { '_xcatdest' } = $ masters [ 0 ] ;
push @ requests , $ reqcopy ;
} else {
$ callback - > ( { data = > [ "The value of the attribute master in the site table is NOT set" ] } ) ;
$ req = { } ;
return ;
}
} else {
2011-10-14 05:34:10 +00:00
# find service nodes for the HCPs
2010-08-02 03:29:15 +00:00
# build an individual request for each service node
my $ service = "xcat" ;
my @ hcps = keys ( % hcp_hash ) ;
2012-11-09 03:32:39 +00:00
my $ sn ;
2012-11-09 06:08:41 +00:00
my @ dfmdispatch = xCAT::TableUtils - > get_site_attribute ( "hwctrldispatch" ) ;
2012-11-09 03:32:39 +00:00
if ( defined ( $ dfmdispatch [ 0 ] ) and ( $ dfmdispatch [ 0 ] =~ /0|n/i ) ) {
if ( $ masters [ 0 ] ) {
push @ { $ sn - > { $ masters [ 0 ] } } , @ hcps ;
} else {
$ callback - > ( { data = > [ "The value of the attribute master in the site table is NOT set" ] } ) ;
$ req = { } ;
return ;
}
} else {
$ sn = xCAT::ServiceNodeUtils - > get_ServiceNode ( \ @ hcps , $ service , "MN" ) ;
}
2010-08-02 03:29:15 +00:00
# build each request for each service node
2011-10-19 05:23:10 +00:00
foreach my $ snkey ( keys %$ sn )
{
2010-08-02 03:29:15 +00:00
#$callback->({data=>["The service node $snkey "]});
my $ reqcopy = { %$ req } ;
$ reqcopy - > { '_xcatdest' } = $ snkey ;
$ reqcopy - > { _xcatpreprocessed } - > [ 0 ] = 1 ;
my $ hcps1 = $ sn - > { $ snkey } ;
my @ nodes = ( ) ;
foreach ( @$ hcps1 ) {
push @ nodes , @ { $ hcp_hash { $ _ } { nodes } } ;
}
@ nodes = sort @ nodes ;
2010-08-02 08:35:45 +00:00
my % hash = map { $ _ = > 1 } @ nodes ; #remove the repeated node for multiple hardware control points
@ nodes = keys % hash ;
2010-08-02 03:29:15 +00:00
$ reqcopy - > { node } = \ @ nodes ;
#print "nodes=@nodes\n";
push @ requests , $ reqcopy ;
2011-10-28 06:16:15 +00:00
2012-02-07 06:11:28 +00:00
if ( ( $ req - > { command } - > [ 0 ] eq "rflash" ) && ( exists ( $ req - > { opt } - > { activate } ) ) ) {
my $ linuxrequired = 0 ;
if ( xCAT::Utils - > isLinux ( ) ) {
2012-08-09 04:00:45 +00:00
my @ installloc = xCAT::TableUtils - > get_site_attribute ( "installloc" ) ;
2012-02-07 06:11:28 +00:00
if ( ! ( $ installloc [ 0 ] ) ) {
$ linuxrequired = 1 ;
}
}
if ( ( $ linuxrequired || xCAT::Utils - > isAIX ( ) ) && ( $ masters [ 0 ] ne $ snkey ) ) {
2012-08-09 04:00:45 +00:00
my $ install_dir = xCAT::TableUtils - > getInstallDir ( ) ;
2012-02-07 06:11:28 +00:00
my $ cmd = "$::XCATROOT/bin/xdcp $snkey -R $install_dir/packages_fw $install_dir/" ;
2011-10-28 06:16:15 +00:00
my $ result = xCAT::Utils - > runcmd ( "$cmd" , - 1 ) ;
if ( $ ::RUNCMD_RC != 0 ) {
2012-02-07 06:11:28 +00:00
$ callback - > ( { data = > [ "$result. Could not copy rpms in the $install_dir/packages_fw to $snkey.\n" ] } ) ;
2011-10-28 06:16:15 +00:00
$ req = { } ;
return ;
}
}
}
2011-10-19 05:23:10 +00:00
}
2010-08-02 03:29:15 +00:00
}
# No dependency, use the original logic
if ( scalar ( @ { $ nodeseq } ) == 1 ) {
return \ @ requests ;
2009-05-19 03:20:17 +00:00
}
2010-08-02 03:29:15 +00:00
# do all the new request entries in this loop
my $ j = 0 ;
for ( $ j = 0 ; $ j < scalar ( @ requests ) ; $ j + + ) {
$ subreq - > ( \ % { $ requests [ $ j ] } , $ callback ) ;
}
2009-05-19 03:20:17 +00:00
2010-08-02 03:29:15 +00:00
# We can not afford waiting 'msdelay' for each node,
# for performance considerations,
# use the maximum msdelay for all nodes
my $ delay = 0 ;
# do not need to calculate msdelay for the last loop
if ( $ i < scalar ( @ { $ nodeseq } ) ) {
foreach my $ reqnode ( @ { $ req - > { node } } ) {
foreach my $ depnode ( keys % { $ deps } ) {
foreach my $ depent ( @ { $ deps - > { $ depnode } } ) {
# search if the 'nodedep' includes the $reqnode
# do not use grep, performance problem!
foreach my $ depentnode ( split ( /,/ , $ depent - > { 'nodedep' } ) ) {
if ( $ depentnode eq $ reqnode ) {
if ( $ depent - > { 'msdelay' } > $ delay ) {
$ delay = $ depent - > { 'msdelay' } ;
}
}
}
}
}
}
}
if ( $ ENV { 'XCATDEBUG' } ) {
my % output ;
$ output { data } = [ "delay = $delay" ] ;
$ callback - > ( \ % output ) ;
}
#convert from millisecond to second
$ delay /= 1000.0 ;
2010-10-21 08:56:59 +00:00
if ( $ delay && ( $ i < scalar ( @ { $ nodeseq } ) ) ) {
2010-08-02 03:29:15 +00:00
my % output ;
$ output { data } = [ "Waiting $delay seconds for node dependencies\n" ] ;
$ callback - > ( \ % output ) ;
if ( $ ENV { 'XCATDEBUG' } ) {
$ output { data } = [ "Before sleep $delay seconds" ] ;
$ callback - > ( \ % output ) ;
}
Time::HiRes:: sleep ( $ delay ) ;
if ( $ ENV { 'XCATDEBUG' } ) {
$ output { data } = [ "Wake up!" ] ;
$ callback - > ( \ % output ) ;
}
2009-06-05 08:02:34 +00:00
}
2009-01-15 03:01:54 +00:00
}
2010-08-02 03:29:15 +00:00
return undef ;
2009-01-15 03:01:54 +00:00
}
2009-04-02 15:37:19 +00:00
####################################
2009-05-14 08:13:41 +00:00
# Parse arguments
2009-04-02 15:37:19 +00:00
####################################
2009-05-14 08:13:41 +00:00
sub parse_args
2009-04-02 15:37:19 +00:00
{
2009-05-14 08:13:41 +00:00
my $ package = shift ;
my $ req = shift ;
my $ callback = shift ;
$ package =~ s/xCAT_plugin::// ;
2009-06-05 08:02:34 +00:00
# if ( exists $req->{opt})
# {
# return $req->{opt};
# }
#################################
# To match the old logic
##################################
2009-05-14 08:13:41 +00:00
my $ command = $ req - > { command } - > [ 0 ] ;
my $ stdin = $ req - > { stdin } - > [ 0 ] ;
$ req - > { command } = $ command ;
$ req - > { stdin } = $ stdin ;
$ req - > { hwtype } = $ package ;
2010-04-08 07:39:15 +00:00
$ req - > { callback } = $ callback ;
2009-05-14 08:13:41 +00:00
$ req - > { method } = "parse_args" ;
2009-05-19 03:20:17 +00:00
2009-05-14 08:13:41 +00:00
my $ opt = runcmd ( $ req ) ;
2009-05-19 03:20:17 +00:00
2009-05-14 08:13:41 +00:00
$ req - > { command } = [ $ command ] ;
$ req - > { stdin } = [ $ stdin ] ;
2010-03-29 03:38:05 +00:00
$ req - > { method } = [ $ req - > { method } ] ;
$ req - > { op } = [ $ req - > { op } ] ;
2009-05-14 08:13:41 +00:00
return $ opt ;
2009-04-02 15:37:19 +00:00
}
2009-05-14 08:13:41 +00:00
2008-04-16 16:45:14 +00:00
2007-11-16 19:47:00 +00:00
##########################################################################
# Process request from xCat daemon
##########################################################################
sub process_request {
my $ package = shift ;
my $ req = shift ;
my $ callback = shift ;
2009-09-29 11:41:58 +00:00
my $ subreq = shift ;
2007-11-16 19:47:00 +00:00
2009-06-05 08:02:34 +00:00
####################################
# Get hwtype
####################################
2007-11-16 19:47:00 +00:00
$ package =~ s/xCAT_plugin::// ;
2008-04-12 14:53:11 +00:00
2009-06-05 08:02:34 +00:00
####################################
# Build hash to pass around
####################################
2009-05-14 08:13:41 +00:00
my $ request = { %$ req } ;
$ request - > { command } = $ req - > { command } - > [ 0 ] ;
2010-03-29 03:38:05 +00:00
$ request - > { stdin } = $ req - > { stdin } - > [ 0 ] ;
$ request - > { method } = $ req - > { method } - > [ 0 ] ;
$ request - > { op } = $ req - > { op } - > [ 0 ] ;
2011-06-17 07:29:17 +00:00
$ request - > { enableASMI } = $ req - > { enableASMI } ;
2010-05-05 02:37:09 +00:00
#support more options in hierachy
if ( ref ( $ req - > { opt } ) eq 'ARRAY' ) {
my $ h = $ req - > { opt } - > [ 0 ] ;
my % t = ( ) ;
foreach my $ k ( keys %$ h ) {
$ t { $ k } = $ h - > { $ k } - > [ 0 ] ;
}
$ request - > { opt } = \ % t ;
}
2012-08-02 06:54:34 +00:00
if ( ref ( $ req - > { hwtype } ) eq 'ARRAY' ) {
$ request - > { hwtype } = $ req - > { hwtype } - > [ 0 ] ;
}
# $request->{hwtype} = $package;
2009-05-14 08:13:41 +00:00
$ request - > { callback } = $ callback ;
2009-09-29 11:41:58 +00:00
$ request - > { subreq } = $ subreq ;
2009-07-01 06:03:26 +00:00
#########################
2009-08-04 20:28:03 +00:00
#This is a special case for rspconfig and mkhwconn,
2009-07-31 19:45:28 +00:00
#we shouldn't set hwtype as$package. and reserved for other commands.
#probably for all HW ctrl commands it still true?
2009-07-01 06:03:26 +00:00
#########################
2009-07-31 19:45:28 +00:00
if ( $ request - > { command } ne "rspconfig" and
2009-08-04 20:28:03 +00:00
$ request - > { command } ne "mkhwconn" ) {
2009-07-01 06:03:26 +00:00
$ request - > { hwtype } = $ package ;
}
2009-06-05 08:02:34 +00:00
####################################
# Option -V for verbose output
####################################
2012-03-05 07:22:49 +00:00
if ( exists ( $ request - > { opt } - > { V } ) ) {
$ request - > { verbose } = 1 ;
}
2012-04-20 03:18:38 +00:00
#if( $request->{hwtype} ne 'hmc' ) {
if ( $ request - > { hwtype } !~ /hmc|ivm/ ) {
2012-03-05 07:22:49 +00:00
$ request - > { fsp_api } = 1 ;
#For using rspconfig to disable/enable dev/celogin1 through ASMI
my $ arg = $ request - > { arg } ;
if ( $ request - > { command } eq "rspconfig" and grep ( /^(dev|celogin1)/ , @$ arg ) ) {
$ request - > { fsp_api } = 0 ;
}
} else {
$ request - > { fsp_api } = 0 ;
}
#print Dumper($request);
process_command ( $ request ) ;
return ;
2009-06-05 08:02:34 +00:00
####################################
# Process remote command
####################################
2010-08-02 08:35:45 +00:00
#process_command( $request );
2012-03-05 07:22:49 +00:00
#The following code will not be used in xCAT 2.7
2010-08-02 08:35:45 +00:00
#The following code supports for Multiple hardware control points.
#use @failed_nodes to store the nodes which need to be run.
#print "before process_command\n";
2010-08-12 05:52:34 +00:00
#print Dumper($request);
2010-08-02 08:35:45 +00:00
my % failed_msg = ( ) ; # store the error msgs
my $ t = $ request - > { node } ;
my @ failed_nodes = @$ t ;
#print "-------failed nodes-------\n";
#print Dumper(\@failed_nodes);
2011-05-20 09:28:02 +00:00
my $ hcps = getHCPsOfNodes ( \ @ failed_nodes , $ callback , $ request ) ;
2010-08-02 08:35:45 +00:00
if ( ! defined ( $ hcps ) ) {
#Not found the hcp for one node
$ request = { } ;
return ;
}
#####################
#print Dumper($hcps);
#$VAR1 = {
# 'lpar01' => {
# 'num' => 2,
# 'hcp' => [
# 'Server-9110-51A-SN1075ECF',
# 'c76v2hmc02'
# ]
# }
# };
######################
while ( 1 ) {
my $ lasthcp_type ;
my % hcps_will = ( ) ;
my @ next = ( ) ;
my $ count ; #to count the nodes who doesn't have hcp in the $hcps
if ( @ failed_nodes == 0 ) {
#all nodes succeeded --- no node in @$failed_nodes;
return ;
}
foreach my $ node ( @ failed_nodes ) {
#for multiple, get the first hcp in the $hcps{$node}.
my $ hcp_list = $ hcps - > { $ node } - > { hcp } ;
#print Dumper($hcp_list);
my $ thishcp = shift ( @$ hcp_list ) ;
if ( ! defined ( $ thishcp ) ) {
#if no hcp, count++;
$ count + + ;
if ( $ count == @ failed_nodes ) {
# all the hcps of the nodes are tried. But still failed. so output the error msg and exit.
#print Dumper(\%failed_msg);
#prompt all the error msg.
foreach my $ failed_node ( @ failed_nodes ) {
my $ msg = $ failed_msg { $ failed_node } ;
foreach my $ item ( @$ msg ) {
if ( $ item ) {
#print Dumper($item);
$ callback - > ( $ item ) ;
} # end of if
} # end of foreach
} #end of foreach
#output all the msgs of the failed nodes, so return
return ;
} #end of if
#if $count != @failed_nodes, let's check next node
next ;
} #end of if
#print "thishcp:$thishcp\n";
#get the nodetype of hcp:
2010-12-30 10:23:21 +00:00
#my $thishcp_type = xCAT::FSPUtils->getTypeOfNode($thishcp,$callback);
2012-02-10 10:32:50 +00:00
my $ thishcp_type = xCAT::DBobjUtils - > getnodetype ( $ thishcp , "ppc" ) ;
2010-08-02 08:35:45 +00:00
if ( ! defined ( $ thishcp_type ) ) {
2011-08-12 08:16:41 +00:00
my % output = ( ) ;
2011-08-11 10:44:38 +00:00
$ output { node } - > [ 0 ] - > { name } = [ $ node ] ;
2011-08-12 08:16:41 +00:00
$ output { node } - > [ 0 ] - > { data } = [ "the type of $node\'s hcp is not defined in the 'ppc' table." ] ;
2011-08-11 10:44:38 +00:00
$ output { errorcode } = '1' ;
$ callback - > ( \ % output ) ;
2010-08-02 08:35:45 +00:00
next ;
}
#print "lasthcp_type:$lasthcp_type ;thishcp_type:$thishcp_type\n";
if ( defined ( $ lasthcp_type ) ) {
2010-12-20 01:33:46 +00:00
if ( ( $ lasthcp_type =~ /^(hmc)$/ && $ thishcp_type =~ /^(fsp|bpa|cec)$/ ) or ( ( $ lasthcp_type =~ /^(fsp|bpa|cec)$/ ) && ( $ thishcp_type =~ /^(hmc)$/ ) ) ) {
2010-08-02 08:35:45 +00:00
$ callback - > ( { data = > [ "the $node\'s hcp type is different from the other's in the specified noderange in the 'ppc' table." ] } ) ;
return ;
}
}
$ lasthcp_type = $ thishcp_type ;
$ hcps_will { $ node } = $ thishcp ;
push ( @ next , $ node ) ;
} #end of foreach
my $ request_new ;
%$ request_new = %$ request ;
$ request_new - > { node } = \ @ next ;
$ request_new - > { fsp_api } = 0 ;
2010-12-23 07:34:28 +00:00
if ( $ lasthcp_type =~ /^(fsp|bpa|cec|frame)$/ ) {
2011-06-17 07:29:17 +00:00
#my $fsp_api = check_fsp_api($request);
#if($fsp_api == 0 ) {
$ request_new - > { fsp_api } = 1 ;
# }
2010-08-02 08:35:45 +00:00
}
2011-06-17 07:29:17 +00:00
#For mkhwconn ....
2010-09-06 08:03:28 +00:00
if ( $ request - > { hwtype } ne 'hmc' ) {
$ request_new - > { hwtype } = $ lasthcp_type ;
2010-12-09 07:29:16 +00:00
} else {
$ request_new - > { fsp_api } = 0 ;
2010-09-06 08:03:28 +00:00
}
2011-06-17 07:29:17 +00:00
#print Dumper($request_new);
2010-08-02 08:35:45 +00:00
@ failed_nodes = ( ) ;
2011-06-27 10:57:33 +00:00
if ( $ hcps - > { maxnum } == 1 && $ request_new - > { command } !~ /^(rspconfig|rpower|reventlog)$/ ) {
push @ failed_nodes , "noloop" ; # if each node only has one hcp, it will return immediately.
}
2011-06-17 07:29:17 +00:00
#For rspconfig to use ASMI
if ( defined ( $ request - > { enableASMI } ) && ( $ request - > { enableASMI } eq "1" ) ) {
$ request_new - > { fsp_api } = 0 ;
}
2010-08-02 08:35:45 +00:00
process_command ( $ request_new , \ % hcps_will , \ @ failed_nodes , \ % failed_msg ) ;
2011-06-17 07:29:17 +00:00
#print "after result:\n";
#print Dumper(\@failed_nodes);
if ( $ lasthcp_type =~ /^(fsp|bpa|cec|frame)$/ &&
$ request - > { hwtype } ne 'hmc' &&
$ request_new - > { fsp_api } ne '0' ) {
if ( $ request_new - > { command } =~ /^(rspconfig|rpower|reventlog)$/ ) {
2012-08-09 04:00:45 +00:00
my @ enableASMI = xCAT::TableUtils - > get_site_attribute ( "enableASMI" ) ;
2011-06-17 07:29:17 +00:00
if ( defined ( $ enableASMI [ 0 ] ) ) {
2011-08-23 03:09:26 +00:00
if ( ( $ request_new - > { command } !~ /^rspconfig$/ ) ||
( ref ( $ request_new - > { method } eq 'HASH' ) ) ) {
$ enableASMI [ 0 ] =~ tr /a-z/ A - Z / ; # convert to upper
if ( ( $ enableASMI [ 0 ] eq "1" ) || ( $ enableASMI [ 0 ] eq "YES" ) ) {
#through asmi ......
$ request_new - > { fsp_api } = 0 ;
if ( @ failed_nodes != 0 ) {
my @ temp = @ failed_nodes ;
@ failed_nodes = ( ) ;
$ request_new - > { node } = \ @ temp ;
process_command ( $ request_new , \ % hcps_will , \ @ failed_nodes , \ % failed_msg ) ;
} #end of if
} #end of if
} # end of if
} #end of if
}
2010-08-12 05:52:34 +00:00
} #end of if
2010-08-02 08:35:45 +00:00
} #end of while(1)
2007-11-16 19:47:00 +00:00
}
2008-09-30 13:44:19 +00:00
##########################################################################
# connect hmc via ssh and execute remote command
##########################################################################
sub sshcmds_on_hmc
{
my $ ip = shift ;
my $ user = shift ;
my $ password = shift ;
my @ cmds = @ _ ;
2009-05-19 03:20:17 +00:00
2008-09-30 13:44:19 +00:00
my % handled ;
my @ data ;
my @ exp ;
for my $ cmd ( @ cmds )
{
if ( $ cmd =~ /(.+?)=(.*)/ )
{
my ( $ command , $ value ) = ( $ 1 , $ 2 ) ;
$ handled { $ command } = $ value ;
}
}
my % request = (
ppcretry = > 1 ,
verbose = > 0 ,
ppcmaxp = > 64 ,
ppctimeout = > 0 ,
fsptimeout = > 0 ,
ppcretry = > 3 ,
2009-10-13 13:37:30 +00:00
maxssh = > 8
2008-09-30 13:44:19 +00:00
) ;
my $ valid_ip ;
foreach my $ individual_ip ( split /,/ , $ ip ) {
2009-06-05 08:02:34 +00:00
################################
# Get userid and password
################################
2010-02-04 12:49:25 +00:00
my @ cred = ( $ user , $ password ) ;
2009-05-19 03:20:17 +00:00
$ request { $ individual_ip } { cred } = \ @ cred ;
2008-09-30 13:44:19 +00:00
@ exp = xCAT::PPCcli:: connect ( \ % request , 'hmc' , $ individual_ip ) ;
2009-06-05 08:02:34 +00:00
####################################
# Successfully connected
####################################
2008-09-30 13:44:19 +00:00
if ( ref ( $ exp [ 0 ] ) eq "Expect" ) {
$ valid_ip = $ individual_ip ;
last ;
}
}
2007-11-16 19:47:00 +00:00
2009-06-05 08:02:34 +00:00
########################################
# Error connecting
########################################
2008-09-30 13:44:19 +00:00
if ( ref ( $ exp [ 0 ] ) ne "Expect" ) {
return ( [ 1 , @ cmds ] ) ;
}
2009-06-05 08:02:34 +00:00
########################################
# Process specific command
########################################
2008-09-30 13:44:19 +00:00
for my $ cmd ( keys % handled )
{
my $ result ;
if ( $ cmd eq 'network_reset' )
{
$ result = xCAT::PPCcli:: network_reset ( \ @ exp , $ valid_ip , $ handled { $ cmd } ) ;
my $ RC = shift ( @$ result ) ;
}
push @ data , @$ result [ 0 ] ;
}
2009-06-05 08:02:34 +00:00
########################################
# Close connection to remote server
########################################
2008-09-30 13:44:19 +00:00
xCAT::PPCcli:: disconnect ( \ @ exp ) ;
2007-11-16 19:47:00 +00:00
2008-09-30 13:44:19 +00:00
return ( [ 0 , undef , \ @ data ] ) ;
}
2007-11-16 19:47:00 +00:00
2009-12-02 09:38:51 +00:00
2009-12-10 02:19:40 +00:00
sub check_fsp_api
2009-12-02 09:38:51 +00:00
{
my $ request = shift ;
2009-12-10 02:19:40 +00:00
# my $fsp_api = "/opt/xcat/sbin/fsp-api";
2010-04-09 06:55:23 +00:00
my $ fsp_api = ( $ ::XCATROOT ) ? "$::XCATROOT/sbin/fsp-api" : "/opt/xcat/sbin/fsp-api" ;
#my $libfsp = "/usr/lib/libfsp.a";
my $ libfsp_aix = ( $ ::XCATROOT ) ? "$::XCATROOT/lib/libfsp.so" : "/opt/xcat/lib/libfsp.so" ;
my $ libfsp_linux = ( $ ::XCATROOT ) ? "$::XCATROOT/lib/libfsp.a" : "/opt/xcat/lib/libfsp.a" ;
2010-01-07 06:00:53 +00:00
# my $libfsp = "/opt/xcat/lib/libfsp.a";
2009-12-10 02:19:40 +00:00
# my $libfsp = ($::XCATROOT) ? "$::XCATROOT/lib/libfsp.a" : "/opt/xcat/lib/libfsp.a";
2009-12-02 09:38:51 +00:00
# my $hw_svr = "/opt/csm/csmbin/hdwr_svr";
my $ msg = ( ) ;
# if((-e $fsp_api) && (-x $fsp_api)&& (-e $libfsp) && (-e $hw_svr)) {
2010-04-09 06:55:23 +00:00
if ( ( - e $ fsp_api ) && ( - x $ fsp_api ) && ( ( - e $ libfsp_aix ) || ( - e $ libfsp_linux ) ) ) {
2009-12-02 09:38:51 +00:00
return 0 ;
}
return - 1 ;
}
2010-08-02 08:35:45 +00:00
sub getHCPsOfNodes
{
my $ nodes = shift ;
my $ callback = shift ;
2011-05-20 09:28:02 +00:00
my $ request = shift ;
my % hcps ;
if ( $ request - > { command } eq "mkhwconn" or $ request - > { command } eq "lshwconn" or $ request - > { command } eq "rmhwconn" ) {
if ( grep ( /^-s$/ , @ { $ request - > { arg } } ) ) {
my $ ppctab = xCAT::Table - > new ( 'ppc' ) ;
my % newhcp ;
if ( $ ppctab ) {
2012-02-10 10:32:50 +00:00
my $ typeref = xCAT::DBobjUtils - > getnodetype ( $ nodes , "ppc" ) ;
2011-05-20 09:28:02 +00:00
my $ i = 0 ;
2011-07-13 04:18:03 +00:00
unless ( $ request - > { sfp } ) {
2011-06-21 06:37:55 +00:00
for my $ n ( @$ nodes ) {
2012-02-27 09:10:04 +00:00
if ( $$ typeref { $ n } =~ /^fsp|bpa$/ ) {
2011-06-21 06:37:55 +00:00
my $ np = $ ppctab - > getNodeAttribs ( $ n , [ qw( parent ) ] ) ;
if ( $ np ) { # use parent(frame/cec)'s sfp attributes first,for high end machine with 2.5/2.6+ database
my $ psfp = $ ppctab - > getNodeAttribs ( $ np - > { parent } , [ qw( sfp ) ] ) ;
$ newhcp { $ n } { hcp } = [ $ psfp - > { sfp } ] if ( $ psfp ) ;
} else { # if the node don't have a parent,for low end machine with 2.5 database
my $ psfp = $ ppctab - > getNodeAttribs ( $ n , [ qw( sfp ) ] ) ;
$ newhcp { $ n } { hcp } = [ $ psfp - > { sfp } ] if ( $ psfp ) ;
}
} else {
my $ psfp = $ ppctab - > getNodeAttribs ( $ n , [ qw( sfp ) ] ) ;
$ newhcp { $ n } { hcp } = [ $ psfp - > { sfp } ] if ( $ psfp ) ;
2011-05-20 09:28:02 +00:00
}
2011-06-21 06:37:55 +00:00
$ newhcp { $ n } { num } = 1 ;
}
return \ % newhcp ;
} else {
2011-07-13 04:18:03 +00:00
my $ sfp = $ request - > { sfp } ;
2011-06-21 06:37:55 +00:00
my % sfphash ;
for my $ n ( @$ nodes ) {
# record hcp
$ newhcp { $ n } { hcp } = [ $ sfp ] ;
$ newhcp { $ n } { num } = 1 ;
# set the sfp attribute to the database
2012-02-27 09:10:04 +00:00
if ( $$ typeref { $ n } =~ /^fsp|bpa$/ ) {
2011-06-21 06:37:55 +00:00
my $ np = $ ppctab - > getNodeAttribs ( $ n , [ qw( parent ) ] ) ;
$ sfphash { $ np } { sfp } = $ sfp if ( $ np ) ;
}
$ sfphash { $ n } { sfp } = $ sfp ;
2011-05-20 09:28:02 +00:00
}
2011-06-21 06:37:55 +00:00
$ ppctab - > setNodesAttribs ( \ % sfphash ) ;
return \ % newhcp ;
}
} else {
2011-05-20 09:28:02 +00:00
$ callback - > ( { data = > [ "Could not open the ppc table" ] } ) ;
2011-06-21 06:37:55 +00:00
return undef ;
2011-05-20 09:28:02 +00:00
}
2011-06-21 06:37:55 +00:00
}
2011-05-20 09:28:02 +00:00
}
2011-06-27 10:57:33 +00:00
$ hcps { maxnum } = 0 ;
2010-08-02 08:35:45 +00:00
#get hcp from ppc.
foreach my $ node ( @$ nodes ) {
2010-12-30 10:23:21 +00:00
#my $thishcp_type = xCAT::FSPUtils->getTypeOfNode($node, $callback);
2012-02-10 10:32:50 +00:00
my $ thishcp_type = xCAT::DBobjUtils - > getnodetype ( $ node , "ppc" ) ;
2010-08-04 07:06:48 +00:00
if ( $ thishcp_type eq "hmc" ) {
$ hcps { $ node } { hcp } = [ $ node ] ;
$ hcps { $ node } { num } = 1 ;
} else {
my $ ppctab = xCAT::Table - > new ( 'ppc' ) ;
unless ( $ ppctab ) {
$ callback - > ( { data = > [ "Cannot open ppc table" ] } ) ;
return undef ;
}
#xCAT::MsgUtils->message('E', "Failed to open table 'ppc'.") if ( ! $ppctab);
my $ hcp_hash = $ ppctab - > getNodeAttribs ( $ node , [ qw( hcp ) ] ) ;
my $ hcp = $ hcp_hash - > { hcp } ;
if ( ! $ hcp ) {
2010-08-05 00:38:21 +00:00
#xCAT::MsgUtils->message('E', "Not found the hcp of $node");
$ callback - > ( { data = > [ "Not found the hcp of $node" ] } ) ;
return undef ;
}
#print "hcp:\n";
#print Dumper($hcp);
my @ h = split ( "," , $ hcp ) ;
$ hcps { $ node } { hcp } = \ @ h ;
$ hcps { $ node } { num } = @ h ;
}
2011-06-27 10:57:33 +00:00
if ( $ hcps { maxnum } < $ hcps { $ node } { num } ) {
$ hcps { maxnum } = $ hcps { $ node } { num } ;
}
2010-08-02 08:35:45 +00:00
}
#print "in getHCPsOfNodes\n";
#print Dumper(\%hcps);
return \ % hcps ;
}
2009-12-02 09:38:51 +00:00
2007-11-16 19:47:00 +00:00
1 ;
2008-11-07 13:34:47 +00:00