2007-10-26 22:44:33 +00:00
#!/usr/bin/env perl
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
package xCAT_plugin::blade ;
#use Net::SNMP qw(:snmp INTEGER);
use xCAT::Table ;
2008-03-10 15:36:44 +00:00
use Thread qw( yield ) ;
2008-01-21 19:49:59 +00:00
use xCAT::Utils ;
2008-04-11 20:05:37 +00:00
use xCAT::Usage ;
2007-10-26 22:44:33 +00:00
use IO::Socket ;
use SNMP ;
use strict ;
2008-04-21 15:37:39 +00:00
my % mm_comm_pids ;
2007-10-26 22:44:33 +00:00
use XML::Simple ;
2008-04-16 17:16:40 +00:00
if ( $^O =~ /^linux/i ) {
2008-05-06 17:56:08 +00:00
$ XML:: Simple:: PREFERRED_PARSER = 'XML::Parser' ;
2008-04-16 17:16:40 +00:00
}
2007-10-26 22:44:33 +00:00
use Data::Dumper ;
use POSIX "WNOHANG" ;
use Storable qw( freeze thaw ) ;
use IO::Select ;
use IO::Handle ;
2008-03-11 19:44:28 +00:00
use Time::HiRes qw( gettimeofday sleep ) ;
2008-04-09 14:19:01 +00:00
use Net::Telnet ;
2008-04-14 15:08:28 +00:00
use xCAT::DBobjUtils ;
2008-04-09 17:30:43 +00:00
use Getopt::Long ;
2007-10-26 22:44:33 +00:00
sub handled_commands {
return {
findme = > 'blade' ,
2008-04-12 14:53:11 +00:00
getmacs = > 'nodehm:getmac,mgt' ,
2007-12-10 16:10:10 +00:00
rscan = > 'nodehm:mgt' ,
2007-10-26 22:44:33 +00:00
rpower = > 'nodehm:power,mgt' ,
2008-04-12 14:53:11 +00:00
rvitals = > 'nodehm:mgt' ,
rinv = > 'nodehm:mgt' ,
rbeacon = > 'nodehm:mgt' ,
2008-02-07 18:54:58 +00:00
rspreset = > 'nodehm:mgt' ,
2008-03-27 19:33:03 +00:00
rspconfig = > 'nodehm:mgt' ,
2008-04-12 14:53:11 +00:00
rbootseq = > 'nodehm:mgt' ,
reventlog = > 'nodehm:mgt' ,
2008-03-28 17:35:08 +00:00
switchblade = > 'nodehm:mgt' ,
2007-10-26 22:44:33 +00:00
} ;
}
2008-04-11 20:05:37 +00:00
2007-10-26 22:44:33 +00:00
my % macmap ; #Store responses from rinv for discovery
2008-01-15 19:37:30 +00:00
my $ macmaptimestamp ; #reflect freshness of cache
2007-10-26 22:44:33 +00:00
my $ mmprimoid = '1.3.6.1.4.1.2.3.51.2.22.5.1.1.4' ; #mmPrimary
my $ beaconoid = '1.3.6.1.4.1.2.3.51.2.2.8.2.1.1.11' ; #ledBladeIdentity
my $ powerstatoid = '1.3.6.1.4.1.2.3.51.2.22.1.5.1.1.4' ; #bladePowerState
my $ powerchangeoid = '1.3.6.1.4.1.2.3.51.2.22.1.6.1.1.7' ; #powerOnOffBlade
my $ powerresetoid = '1.3.6.1.4.1.2.3.51.2.22.1.6.1.1.8' ; #restartBlade
my $ mpresetoid = '1.3.6.1.4.1.2.3.51.2.22.1.6.1.1.9' ; #restartBladeSMP
my $ bladexistsoid = '1.3.6.1.4.1.2.3.51.2.22.1.5.1.1.3' ; #bladeExists
my $ bladeserialoid = '1.3.6.1.4.1.2.3.51.2.2.21.4.1.1.6' ; #bladeHardwareVpdSerialNumber
my $ blademtmoid = '1.3.6.1.4.1.2.3.51.2.2.21.4.1.1.7' ; #bladeHardwareVpdMachineType
my $ bladempveroid = '1.3.6.1.4.1.2.3.51.2.2.21.5.3.1.7' ; #bladeSysMgmtProcVpdRevision
my $ bladempaveroid = '1.3.6.1.4.1.2.3.51.2.2.21.3.1.1.4' ; #mmMainApplVpdRevisonNumber
my $ bladempabuildidoid = '1.3.6.1.4.1.2.3.51.2.2.21.3.1.1.3' ; #mmMainApplVpdBuildId
my $ bladempadateoid = '1.3.6.1.4.1.2.3.51.2.2.21.3.1.1.6' ; #mmMainApplVpdBuildDate
my $ bladempbuildidoid = '1.3.6.1.4.1.2.3.51.2.2.21.5.3.1.6' ; #bladeSysMgmtProcVpdBuildId
my $ bladebiosveroid = '1.3.6.1.4.1.2.3.51.2.2.21.5.1.1.7' ; #bladeBiosVpdRevision
my $ bladebiosbuildidoid = '1.3.6.1.4.1.2.3.51.2.2.21.5.1.1.6' ; #bladeBiosVpdBuildId
my $ bladebiosdateoid = '1.3.6.1.4.1.2.3.51.2.2.21.5.1.1.8' ; #bladeBiosVpdDate
my $ bladediagveroid = '1.3.6.1.4.1.2.3.51.2.2.21.5.2.1.7' ; #bladeDiagsVpdRevision
my $ bladediagbuildidoid = '1.3.6.1.4.1.2.3.51.2.2.21.5.2.1.6' ; #bladeDiagsVpdBuildId
my $ bladediagdateoid = '1.3.6.1.4.1.2.3.51.2.2.21.5.2.1.8' ; #bladeDiagsVpdDate
my $ eventlogoid = '1.3.6.1.4.1.2.3.51.2.3.4.2.1.2' ; #readEventLogString
my $ clearlogoid = '.1.3.6.1.4.1.2.3.51.2.3.4.3' ; #clearEventLog
2007-11-09 19:57:34 +00:00
my $ blower1speedoid = '.1.3.6.1.4.1.2.3.51.2.2.3.1' ; #blower2speed
2008-01-07 19:27:11 +00:00
my $ blower2speedoid = '.1.3.6.1.4.1.2.3.51.2.2.3.2' ; #blower2speed
my $ blower3speedoid = '.1.3.6.1.4.1.2.3.51.2.2.3.3' ; #blower2speed
my $ blower4speedoid = '.1.3.6.1.4.1.2.3.51.2.2.3.4' ; #blower2speed
2007-11-09 19:57:34 +00:00
my $ blower1stateoid = '.1.3.6.1.4.1.2.3.51.2.2.3.10' ; #blower1State
my $ blower2stateoid = '.1.3.6.1.4.1.2.3.51.2.2.3.11' ; #blower2State
2008-01-07 19:27:11 +00:00
my $ blower3stateoid = '.1.3.6.1.4.1.2.3.51.2.2.3.12' ; #blower2State
my $ blower4stateoid = '.1.3.6.1.4.1.2.3.51.2.2.3.13' ; #blower2State
2007-12-10 16:10:10 +00:00
my $ mmoname = '1.3.6.1.4.1.2.3.51.2.22.4.3' ; #chassisName
my $ mmotype = '1.3.6.1.4.1.2.3.51.2.2.21.1.1.1' ; #bladeCenterVpdMachineType
my $ mmomodel = '1.3.6.1.4.1.2.3.51.2.2.21.1.1.2' ; #bladeCenterVpdMachineModel
my $ mmoserial = '1.3.6.1.4.1.2.3.51.2.2.21.1.1.3' ; #bladeCenterSerialNumber
my $ bladeoname = '1.3.6.1.4.1.2.3.51.2.22.1.5.1.1.6' ; #bladeName
2007-12-10 16:40:40 +00:00
my $ bladeomodel = '1.3.6.1.4.1.2.3.51.2.2.21.4.1.1.12' ; #bladeModel
2007-12-10 16:10:10 +00:00
2007-10-26 22:44:33 +00:00
my @ macoids = (
'1.3.6.1.4.1.2.3.51.2.2.21.4.2.1.2' , #bladeMACAddress1Vpd
'1.3.6.1.4.1.2.3.51.2.2.21.4.2.1.3' , #bladeMACAddress2Vpd
'1.3.6.1.4.1.2.3.51.2.2.21.4.2.1.4' , #bladeMACAddress3Vpd
'1.3.6.1.4.1.2.3.51.2.2.21.4.2.1.5' , #bladeMACAddress4Vpd
) ;
my @ dcmacoids = (
'1.3.6.1.4.1.2.3.51.2.2.21.4.2.1.10' , #bladeDaughterCard1MACAddress1Vpd
'1.3.6.1.4.1.2.3.51.2.2.21.4.2.1.11' , #bladeDaughterCard1MACAddress2Vpd
'1.3.6.1.4.1.2.3.51.2.2.21.4.2.1.12' , #bladeDaughterCard1MACAddress3Vpd
'1.3.6.1.4.1.2.3.51.2.2.21.4.2.1.13' , #bladeDaughterCard1MACAddress4Vpd
) ;
my @ hsdcmacoids = (
'1.3.6.1.4.1.2.3.51.2.2.21.4.2.1.100' , #bladeHSDaughterCard1MACAddress1Vpd
'1.3.6.1.4.1.2.3.51.2.2.21.4.2.1.101' , #bladeHSDaughterCard1MACAddress2Vpd
'1.3.6.1.4.1.2.3.51.2.2.21.4.2.1.102' , #bladeHSDaughterCard1MACAddress3Vpd
'1.3.6.1.4.1.2.3.51.2.2.21.4.2.1.103' , #bladeHSDaughterCard1MACAddress4Vpd
) ;
my @ bootseqoids = (
'1.3.6.1.4.1.2.3.51.2.22.1.3.1.7' , #bootSequence1
'1.3.6.1.4.1.2.3.51.2.22.1.3.1.8' , #bootSequence2
'1.3.6.1.4.1.2.3.51.2.22.1.3.1.9' , #bootSequence3
'1.3.6.1.4.1.2.3.51.2.22.1.3.1.10' , #bootSequence4
) ;
my % bootdevices = (
0 = > 'none' ,
1 = > 'floppy' ,
2 = > 'cdrom' ,
3 = > 'hd0' ,
4 = > 'hd1' ,
5 = > 'hd2' ,
6 = > 'hd3' ,
7 = > 'net' ,
8 = > 'iscsi' ,
9 = > 'iscsicrit' ,
10 = > 'hd4' ,
11 = > 'usbflash'
) ;
my % bootnumbers = (
'none' = > 0 ,
'f' = > 1 ,
'floppy' = > 1 ,
'c' = > 2 ,
'cd' = > 2 ,
'dvd' = > 2 ,
'cdrom' = > 2 ,
'dvdrom' = > 2 ,
'h' = > 3 , #in absence of an index, presuming hd0 intended
'hd' = > 3 ,
'hardisk' = > 3 ,
'hd0' = > 3 ,
'harddisk0' = > 3 ,
'hd1' = > 4 ,
'harddisk1' = > 4 ,
'hd2' = > 5 ,
'harddisk2' = > 5 ,
'hd3' = > 6 ,
'harddisk3' = > 6 ,
'n' = > 7 ,
'network' = > 7 ,
'net' = > 7 ,
'iscsi' = > 8 ,
'iscsicrit' = > 9 ,
'hd4' = > 10 ,
'harddisk4' = > 10 ,
'usbflash' = > 11 ,
'flash' = > 11 ,
'usb' = > 11
) ;
2007-12-10 16:10:10 +00:00
my @ rscan_header = (
[ "type" , "%-8s" ] ,
[ "name" , "" ] ,
[ "id" , "%-8s" ] ,
[ "type-model" , "%-12s" ] ,
[ "serial-number" , "%-15s" ] ,
[ "address" , "%s\n" ] ) ;
2007-10-26 22:44:33 +00:00
my $ session ;
my $ slot ;
my $ didchassis = 0 ;
my @ eventlog_array = ( ) ;
my $ activemm ;
my % mpahash ;
my $ mpa ;
my $ allinchassis = 0 ;
2008-03-10 21:34:09 +00:00
my $ curn ;
2007-10-26 22:44:33 +00:00
sub fillresps {
my $ response = shift ;
my $ mac = $ response - > { node } - > [ 0 ] - > { data } - > [ 0 ] - > { contents } - > [ 0 ] ;
my $ node = $ response - > { node } - > [ 0 ] - > { name } - > [ 0 ] ;
2008-03-21 20:00:07 +00:00
$ mac = uc ( $ mac ) ; #Make sure it is uppercase, the MM people seem to change their mind on this..
2007-10-26 22:44:33 +00:00
$ macmap { $ mac } = $ node ;
#$macmap{$response->{node}->[0]->{data}->{contents}->[0]}=$response->{node}->[0]->{name};
}
sub isallchassis {
my $ bladesinchassis = 0 ;
if ( $ allinchassis ) {
return 1 ;
}
foreach ( 1 .. 14 ) {
my $ tmp = $ session - > get ( [ $ bladexistsoid . ".$_" ] ) ;
if ( $ tmp eq 1 ) { $ bladesinchassis + + }
}
my $ count = keys % { $ mpahash { $ mpa } - > { nodes } } ;
if ( $ count >= $ bladesinchassis ) { $ allinchassis + + ; return 1 } ; #commands that affect entire are okayed, i.e eventlog clear
return 0 ;
}
sub resetmp {
my $ data ;
my $ stat ;
my $ rc ;
2008-02-07 18:54:58 +00:00
#$data = $session->set($mpresetoid.".$slot", 1);
$ data = $ session - > set ( new SNMP:: Varbind ( [ "." . $ mpresetoid , $ slot , 1 , 'INTEGER' ] ) ) ;
unless ( $ data ) { return ( 1 , $ session - > { ErrorStr } ) ; }
return ( 0 , "mpreset" ) ;
2007-10-26 22:44:33 +00:00
#if ($session->{ErrorStr}) { return (1,$session->{ErrorStr}); }
2008-02-07 18:54:58 +00:00
#if ($session->{ErrorStr}) { return (1,$session->{ErrorStr}); }
#if ($data->{$mpresetoid.".$slot"} == 1) {
# return (0, "mpreset");
#} else {
# return (1,"error");
#}
2007-10-26 22:44:33 +00:00
}
2008-05-12 23:36:47 +00:00
sub waitforack {
my $ sock = shift ;
my $ select = new IO:: Select ;
$ select - > add ( $ sock ) ;
my $ str ;
if ( $ select - > can_read ( 10 ) ) { # Continue after 10 seconds, even if not acked...
if ( $ str = <$sock> ) {
} else {
$ select - > remove ( $ sock ) ; #Block until parent acks data
}
}
}
2007-10-26 22:44:33 +00:00
sub walkelog {
my $ session = shift ;
my $ oid = shift ;
unless ( $ oid =~ /^\./ ) {
$ oid = '.' . $ oid ;
}
my $ retmap = undef ;
my $ current = 1 ;
my @ bindlist ;
my $ varbind ;
do {
foreach ( $ current .. $ current + 31 ) { #Attempt to retrive 32 ents at a time, seems to be working...
push @ bindlist , [ $ oid , $ _ ] ;
}
$ current += 32 ;
$ varbind = new SNMP:: VarList (
@ bindlist
) ;
$ session - > get ( $ varbind ) ;
foreach ( @$ varbind ) {
unless ( $ { _ } - > [ 2 ] ) { last ; }
if ( $ { _ } - > [ 2 ] =~ /NOSUCHINSTANCE/ ) { last ; }
$ retmap - > { $ _ - > [ 1 ] } = $ _ - > [ 2 ] ;
}
} while ( $ varbind - > [ 31 ] and $ varbind - > [ 31 ] - > [ 2 ] != 'NOSUCHINSTANCE' and ( $ current < 600 ) ) ;
return $ retmap ;
print "Count was $current\n" ;
#print Dumper($varbind->[60]->[2]);
print "\n\n" ;
return undef ;
my $ count = 0 ;
while ( $ varbind - > [ 0 ] =~ /^$oid\.?(.*)/ ) {
$ count + + ;
if ( $ 1 ) {
$ retmap - > { $ 1 . "." . $ varbind - > [ 1 ] } = $ varbind - > [ 2 ] ; #If $1 is set, means key should
} else {
$ retmap - > { $ varbind - > [ 1 ] } = $ varbind - > [ 2 ] ; #If $1 is set, means key should
}
$ session - > getnext ( $ varbind ) ;
}
return $ retmap ;
}
sub eventlog { #Tried various optimizations, but MM seems not to do bulk-request
#TODO: retrieval of non blade events, what should be syntax?
#TODO: try retrieving 5 at a time, then 1 at a time when that stops working
my $ cmd = shift ;
my $ data ;
my @ output ;
my $ oid = $ eventlogoid ;
2008-05-05 13:47:09 +00:00
unless ( $ cmd ) {
$ cmd = 'all' ;
}
2007-10-26 22:44:33 +00:00
if ( $ cmd eq 'all' ) {
$ cmd = 65535 ; #no MM has this many logs possible, should be a good number
}
if ( $ cmd =~ /^(\d+)$/ ) {
my $ requestednumber = $ 1 ;
unless ( @ eventlog_array ) {
#my $varbind=new SNMP::Varbind([$oid,0]);
#while ($data=$session->getnext($varbind)) {
# print Dumper($data);
# if ($session->{ErrorStr}) { printf $session->{ErrorStr}."\n"; }
# foreach (keys %$data) {
# $oid=$_;
# }
# unless (oid_base_match($eventlogoid,$oid)) {
# last;
# }
my $ logents = walkelog ( $ session , $ oid ) ;
foreach ( sort { $ a <=> $ b } ( keys %$ logents ) ) {
push @ eventlog_array , $ logents - > { $ _ } . "\n" ;
}
#push @eventlog_array,$data->{$oid}; #TODO: filter against slot number, check for $allchassis for non-blade
#}
}
my $ numentries = 0 ;
#my $allchassis = isallchassis;
foreach ( @ eventlog_array ) {
m/Severity:(\S+)\s+Source:(\S+)\s+Name:\S*\s+Date:(\S+)\s+Time:(\S+)\s+Text:(.+)/ ;
my $ sev = $ 1 ;
my $ source = $ 2 ;
my $ date = $ 3 ;
my $ time = $ 4 ;
my $ text = $ 5 ;
my $ matchstring ;
if ( $ slot > 0 ) {
$ matchstring = sprintf ( "BLADE_%02d" , $ slot ) ;
} else {
$ matchstring = "^(?!BLADE).*" ;
}
if ( $ source =~ m/$matchstring$/i ) { #MM guys changed their minds on capitalization
$ numentries + + ;
unshift @ output , "$sev:$date $time $text" ; #unshift to get it in a sane order
}
if ( $ numentries >= $ requestednumber ) {
last ;
}
}
return ( 0 , @ output ) ;
}
my $ data ;
if ( $ cmd eq "clear" ) {
unless ( isallchassis ) {
return ( 1 , "Cannot clear eventlogs except for entire chassis" ) ;
}
if ( $ didchassis ) { return 0 , "eventlog cleared" }
my $ varbind = new SNMP:: Varbind ( [ $ clearlogoid , 0 , 1 , 'INTEGER' ] ) ;
$ data = $ session - > set ( $ varbind ) ;
if ( $ session - > { ErrorStr } ) { return ( 1 , $ session - > { ErrorStr } ) ; }
$ didchassis = 1 ;
if ( $ varbind - > [ 2 ] eq 1 ) {
return 0 , "eventlog cleared" ;
}
}
}
2008-03-27 19:33:03 +00:00
sub setoid {
my $ oid = shift ;
my $ offset = shift ;
my $ value = shift ;
my $ type = shift ;
unless ( $ type ) { $ type = 'INTEGER' ; }
my $ varbind = new SNMP:: Varbind ( [ $ oid , $ offset , $ value , $ type ] ) ;
my $ data = $ session - > set ( $ varbind ) ;
if ( $ session - > { ErrorStr } ) { return ( 1 , $ session - > { ErrorStr } ) ; }
return 0 , $ varbind ;
}
sub enabledefaultalerts {
#Customizers: most oids are listed, and some commented out. uncomment if you want to get them
#deprecated options are in, but commented, will elect to use what the MM official strategy suggests
my @ enabledalerts = (
#Deprecated '1.3.6.1.4.1.2.3.51.2.4.2.1.1', #critical temperature
#deprecated '1.3.6.1.4.1.2.3.51.2.4.2.1.2', #critical voltage
#deprecated '1.3.6.1.4.1.2.3.51.2.4.2.1.4', #critical blower
'1.3.6.1.4.1.2.3.51.2.4.2.1.5' , #critical power
#deprecated '1.3.6.1.4.1.2.3.51.2.4.2.1.6', #critical Hard drive
#deprecated '1.3.6.1.4.1.2.3.51.2.4.2.1.7', #critical VRM
#deprecated '1.3.6.1.4.1.2.3.51.2.4.2.1.8', #critical switch module
#deprecated '1.3.6.1.4.1.2.3.51.2.4.2.1.9', #critical config
'1.3.6.1.4.1.2.3.51.2.4.2.1.10' , #critical blade
'1.3.6.1.4.1.2.3.51.2.4.2.1.11' , #critical IO
'1.3.6.1.4.1.2.3.51.2.4.2.1.12' , #critical storage
'1.3.6.1.4.1.2.3.51.2.4.2.1.13' , #critical chassis
'1.3.6.1.4.1.2.3.51.2.4.2.1.14' , #critical fan
#deprecated '1.3.6.1.4.1.2.3.51.2.4.2.2.2', #warn single blower
#deprecated '1.3.6.1.4.1.2.3.51.2.4.2.2.3', #warn temp
#deprecated '1.3.6.1.4.1.2.3.51.2.4.2.2.4', #warn volt
#deprecated '1.3.6.1.4.1.2.3.51.2.4.2.2.6', #warn backup MM
#deprecated '1.3.6.1.4.1.2.3.51.2.4.2.2.7', #warn tray/KVM switch prob
'1.3.6.1.4.1.2.3.51.2.4.2.2.10' , #warn log full
'1.3.6.1.4.1.2.3.51.2.4.2.2.15' , #warn blade warning
'1.3.6.1.4.1.2.3.51.2.4.2.2.16' , #warn io warning
'1.3.6.1.4.1.2.3.51.2.4.2.2.17' , #warn storage warning
'1.3.6.1.4.1.2.3.51.2.4.2.2.18' , #warn power module
'1.3.6.1.4.1.2.3.51.2.4.2.2.19' , #warn chassis
'1.3.6.1.4.1.2.3.51.2.4.2.2.20' , #warn cooling
#deprecated '1.3.6.1.4.1.2.3.51.2.4.2.3.4', #info power off
#deprecated '1.3.6.1.4.1.2.3.51.2.4.2.3.5', #info power on
#deprecated '1.3.6.1.4.1.2.3.51.2.4.2.3.8', #info PFA
'1.3.6.1.4.1.2.3.51.2.4.2.3.10' , #info inventory (insert/remove)
'1.3.6.1.4.1.2.3.51.2.4.2.3.11' , #info 75% events
'1.3.6.1.4.1.2.3.51.2.4.2.3.12' , #info net reconfig
#deprecated '1.3.6.1.4.1.2.3.51.2.4.2.3.13', #info throttling
#deprecated '1.3.6.1.4.1.2.3.51.2.4.2.3.14', #info power management
#annoying '1.3.6.1.4.1.2.3.51.2.4.2.3.15', #info login events
'1.3.6.1.4.1.2.3.51.2.4.2.3.16' , #info blade events
'1.3.6.1.4.1.2.3.51.2.4.2.3.17' , #info IO events
'1.3.6.1.4.1.2.3.51.2.4.2.3.18' , #info storage events
'1.3.6.1.4.1.2.3.51.2.4.2.3.19' , #info power module events
'1.3.6.1.4.1.2.3.51.2.4.2.3.20' , #info chassis events
'1.3.6.1.4.1.2.3.51.2.4.2.3.21' , #info blower event
'1.3.6.1.4.1.2.3.51.2.4.2.3.22' , #info power on/off
) ;
setoid ( '1.3.6.1.4.1.2.3.51.2.4.2.4' , 0 , 1 ) ;
foreach ( @ enabledalerts ) {
setoid ( $ _ , 0 , 1 ) ;
}
}
2007-10-26 22:44:33 +00:00
2008-03-27 19:33:03 +00:00
my @ cfgtext ;
sub mpaconfig {
#OIDs of interest:
#1.3.6.1.4.1.2.3.51.2.4.9.3.1.4.1.1.4 snmpCommunityEntryCommunityIpAddress2
#snmpCommunityEntryCommunityName 1.3.6.1.4.1.2.3.51.2.4.9.3.1.4.1.1.2
#remoteAlerts 1.3.6.1.4.1.2.3.51.2.4.2
#remoteAlertIdEntryTextDescription 1.3.6.1.4.1.2.3.51.2.4.1.3.1.1.4
#remoteAlertIdEntryStatus 1.3.6.1.4.1.2.3.51.2.4.1.3.1.1.2 (0 invalid, 2 enable)
2008-04-09 14:19:01 +00:00
my $ mpa = shift ;
my $ user = shift ;
my $ pass = shift ;
2008-05-16 19:02:10 +00:00
my $ nodeid = shift ;
2008-03-27 19:33:03 +00:00
my $ parameter ;
my $ value ;
my $ assignment ;
my $ returncode = 0 ;
if ( $ didchassis ) { return 0 , @ cfgtext } #"Chassis already configured for this command" }
@ cfgtext = ( ) ;
2008-04-09 14:19:01 +00:00
2008-04-11 20:05:37 +00:00
my $ result = telnetcmds ( $ mpa , $ user , $ pass , @ _ ) ;
$ returncode |= @$ result [ 0 ] ;
my $ args = @$ result [ 1 ] ;
2008-04-09 14:19:01 +00:00
2008-04-11 20:05:37 +00:00
foreach $ parameter ( @$ args ) {
2008-03-27 19:33:03 +00:00
$ assignment = 0 ;
$ value = undef ;
if ( $ parameter =~ /=/ ) {
$ assignment = 1 ;
( $ parameter , $ value ) = split /=/ , $ parameter , 2 ;
}
2008-04-11 14:14:56 +00:00
if ( $ parameter =~ /^ntp$/ ) {
my $ result = ntp ( $ value ) ;
2008-04-11 20:05:37 +00:00
$ returncode |= shift ( @$ result ) ;
2008-04-11 14:14:56 +00:00
push @ cfgtext , @$ result ;
next ;
}
2008-04-11 20:05:37 +00:00
if ( $ parameter =~ /^network$/ ) {
my $ data = $ session - > get ( [ '1.3.6.1.4.1.2.3.51.2.4.9.1.1.4' , 0 ] ) ;
push @ cfgtext , "MM IP: $data" ;
my $ data = $ session - > get ( [ '1.3.6.1.4.1.2.3.51.2.4.9.1.1.3' , 0 ] ) ;
push @ cfgtext , "MM Hostname: $data" ;
my $ data = $ session - > get ( [ '1.3.6.1.4.1.2.3.51.2.4.9.1.1.9' , 0 ] ) ;
push @ cfgtext , "Gateway: $data" ;
my $ data = $ session - > get ( [ '1.3.6.1.4.1.2.3.51.2.4.9.1.1.14' , 0 ] ) ;
push @ cfgtext , "Subnet Mask: $data" ;
next ;
}
if ( $ parameter =~ /^build$/ ) {
my $ data = $ session - > get ( [ '1.3.6.1.4.1.2.3.51.2.2.21.3.1.1.3' , 1 ] ) ;
push @ cfgtext , "Build ID: $data" ;
next ;
2008-04-10 14:54:12 +00:00
}
2008-05-16 19:02:10 +00:00
if ( $ parameter eq "textid" ) {
if ( $ assignment ) {
setoid ( "1.3.6.1.4.1.2.3.51.2.22.1.7.1.1.5" , $ nodeid , $ value , 'OCTET' ) ;
}
my $ data = $ session - > get ( [ $ bladeoname , $ nodeid ] ) ;
push @ cfgtext , "textid: $data" ;
return $ returncode , @ cfgtext ;
}
2008-04-09 14:19:01 +00:00
if ( $ parameter =~ /^snmpcfg$/i ) {
my $ data = $ session - > get ( [ '1.3.6.1.4.1.2.3.51.2.4.9.3.1.6' , 0 ] ) ;
if ( $ data ) {
push @ cfgtext , "SNMP: enabled" ;
}
else {
push @ cfgtext , "SNMP: disabled" ;
}
next ;
}
if ( $ parameter =~ /^sshcfg$/i ) {
my $ data = $ session - > get ( [ '1.3.6.1.4.1.2.3.51.2.4.9.3.4.10' , 0 ] ) ;
if ( $ data =~ /NOSUCHOBJECT/ ) {
push @ cfgtext , "SSH: Not supported" ;
} elsif ( $ data ) {
push @ cfgtext , "SSH: enabled" ;
} else {
push @ cfgtext , "SSH: disabled" ;
}
}
2008-03-27 19:33:03 +00:00
if ( $ parameter eq "snmpdest" ) {
$ parameter = "snmpdest1" ;
}
if ( $ parameter =~ /snmpdest(\d+)/ ) {
if ( $ 1 > 3 ) {
2008-04-11 20:05:37 +00:00
$ returncode |= 1 ;
2008-03-27 19:33:03 +00:00
push ( @ cfgtext , "Only up to three snmp destinations may be defined" ) ;
next ;
}
my $ dstindex = $ 1 ;
if ( $ assignment ) {
setoid ( "1.3.6.1.4.1.2.3.51.2.4.9.3.1.4.1.1." . ( 2 + $ dstindex ) . ".1" , 1 , $ value , 'OCTET' ) ;
2008-03-28 19:06:31 +00:00
setoid ( "1.3.6.1.4.1.2.3.51.2.4.9.3.1.4.1.1.6.1" , 1 , 1 , 'INTEGER' ) ; #access type: read-traps, don't give full write access to the community
2008-03-27 19:33:03 +00:00
}
my $ data = $ session - > get ( [ "1.3.6.1.4.1.2.3.51.2.4.9.3.1.4.1.1." . ( 2 + $ dstindex ) . ".1.1" ] ) ;
2008-03-27 20:17:49 +00:00
push @ cfgtext , "SP SNMP Destination $1: $data" ;
2008-03-27 19:33:03 +00:00
next ;
}
2008-03-27 19:52:31 +00:00
if ( $ parameter =~ /^community/i ) {
if ( $ assignment ) {
setoid ( "1.3.6.1.4.1.2.3.51.2.4.9.3.1.4.1.1.2.1.1" , 0 , $ value , 'OCTET' ) ;
}
my $ data = $ session - > get ( [ "1.3.6.1.4.1.2.3.51.2.4.9.3.1.4.1.1.2.1.1" ] ) ;
2008-03-27 20:17:49 +00:00
push @ cfgtext , "SP SNMP Community: $data" ;
2008-03-27 19:52:31 +00:00
next ;
}
2008-03-27 19:33:03 +00:00
if ( $ parameter =~ /^alert/i ) {
if ( $ assignment ) {
2008-03-28 18:23:19 +00:00
if ( $ value =~ /^enable/i or $ value =~ /^en/i or $ value =~ /^on$/i ) {
2008-03-27 19:33:03 +00:00
setoid ( '1.3.6.1.4.1.2.3.51.2.4.1.3.1.1.4' , 12 , 'xCAT configured SNMP' , 'OCTET' ) ; #Set a description so the MM doesn't flip out
setoid ( '1.3.6.1.4.1.2.3.51.2.4.1.3.1.1.5' , 12 , 4 ) ; #Set Dest12 to SNMP
setoid ( '1.3.6.1.4.1.2.3.51.2.4.1.3.1.1.2' , 12 , 2 ) ; #enable dest12
setoid ( '1.3.6.1.4.1.2.3.51.2.4.9.3.1.3' , 0 , 0 ) ; #Enable SNMP traps
enabledefaultalerts ( ) ;
2008-03-28 18:23:19 +00:00
} elsif ( $ value =~ /^disable/i or $ value =~ /^dis/i or $ value =~ /^off$/i ) {
2008-03-27 19:33:03 +00:00
setoid ( '1.3.6.1.4.1.2.3.51.2.4.1.3.1.1.2' , 12 , 0 ) ; #Disable alert dest 12
setoid ( '1.3.6.1.4.1.2.3.51.2.4.9.3.1.3' , 0 , 1 ) ; #Disable SNMP traps period
}
}
my $ data = $ session - > get ( [ '1.3.6.1.4.1.2.3.51.2.4.1.3.1.1.2.12' ] ) ;
if ( $ data == 2 ) {
2008-03-27 20:17:49 +00:00
push @ cfgtext , "SP Alerting: enabled" ;
2008-03-27 19:33:03 +00:00
next ;
} else {
2008-03-27 20:17:49 +00:00
push @ cfgtext , "SP Alerting: disabled" ;
2008-03-27 19:33:03 +00:00
next ;
}
}
}
$ didchassis = 1 ;
return $ returncode , @ cfgtext ;
}
2008-03-28 17:35:08 +00:00
sub switchblade {
#OIDS of interest:
#1.3.6.1.4.1.2.3.51.2.22.1.1 media tray ownership
#1.3.6.1.4.1.2.3.51.2.22.1.2 kvm ownership
my @ args = @ _ ;
my $ data ;
my @ rettext ;
my $ domt = 0 ;
my $ dokvm = 0 ;
my $ targnum = $ slot ;
if ( $ args [ 1 ] =~ /^\d+$/ ) {
$ targnum = $ args [ 1 ] ;
}
if ( $ args [ 0 ] eq "list" or $ args [ 0 ] eq "stat" ) {
$ data = $ session - > get ( [ "1.3.6.1.4.1.2.3.51.2.22.1.1.0" ] ) ;
push @ rettext , "Media Tray slot: $data" ;
2008-03-28 17:42:44 +00:00
$ data = $ session - > get ( [ "1.3.6.1.4.1.2.3.51.2.22.1.2.0" ] ) ;
2008-03-28 17:35:08 +00:00
push @ rettext , "KVM slot: $data" ;
} elsif ( $ args [ 0 ] eq "both" ) {
$ domt = 1 ;
$ dokvm = 1 ;
} elsif ( $ args [ 0 ] eq "mt" or $ args [ 0 ] eq "media" ) {
$ domt = 1 ;
} elsif ( $ args [ 0 ] eq "kvm" or $ args [ 0 ] eq "video" ) {
$ dokvm = 1 ;
}
if ( $ domt ) {
setoid ( "1.3.6.1.4.1.2.3.51.2.22.1.1" , 0 , $ targnum ) ;
$ data = $ session - > get ( [ "1.3.6.1.4.1.2.3.51.2.22.1.1.0" ] ) ;
push @ rettext , "Media Tray slot: $data" ;
}
if ( $ dokvm ) {
setoid ( "1.3.6.1.4.1.2.3.51.2.22.1.2" , 0 , $ targnum ) ;
2008-03-28 17:42:44 +00:00
$ data = $ session - > get ( [ "1.3.6.1.4.1.2.3.51.2.22.1.2.0" ] ) ;
2008-03-28 17:35:08 +00:00
push @ rettext , "KVM slot: $data" ;
}
return 0 , @ rettext ;
}
2007-10-26 22:44:33 +00:00
sub bootseq {
my @ args = @ _ ;
my $ data ;
my @ order = ( ) ;
if ( $ args [ 0 ] eq "list" or $ args [ 0 ] eq "stat" ) {
foreach my $ oid ( @ bootseqoids ) {
$ data = $ session - > get ( [ $ oid , $ slot ] ) ;
if ( $ session - > { ErrorStr } ) { return ( 1 , $ session - > { ErrorStr } ) ; }
push @ order , $ bootdevices { $ data } ;
}
return ( 0 , join ( ',' , @ order ) ) ;
} else {
foreach ( @ args ) {
my @ neworder = ( split /,/ , $ _ ) ;
push @ order , @ neworder ;
}
my $ number = @ order ;
if ( $ number > 4 ) {
return ( 1 , "Only four boot sequence entries allowed" ) ;
}
my $ nonespecified = 0 ;
foreach ( @ order ) {
unless ( defined ( $ bootnumbers { $ _ } ) ) { return ( 1 , "Unsupported device $_" ) ; }
unless ( $ bootnumbers { $ _ } ) { $ nonespecified = 1 ; }
if ( $ nonespecified and $ bootnumbers { $ _ } ) { return ( 1 , "Error: cannot specify 'none' before a device" ) ; }
}
unless ( $ bootnumbers { $ order [ 0 ] } ) {
return ( 1 , "Error: cannot specify 'none' as first device" ) ;
}
foreach ( 3 , 2 , 1 , 0 ) {
my $ param = $ bootnumbers { $ order [ $ _ ] } ;
unless ( $ param ) {
$ param = 0 ;
my $ varbind = new SNMP:: Varbind ( [ $ bootseqoids [ $ _ ] , $ slot , $ param , 'INTEGER' ] ) ;
$ data = $ session - > set ( $ varbind ) ;
#$session->set($bootseqoids[$_].".$slot",$param);
if ( $ session - > { ErrorStr } ) { return ( 1 , $ session - > { ErrorStr } ) ; }
}
}
foreach ( 0 , 1 , 2 , 3 ) {
my $ param = $ bootnumbers { $ order [ $ _ ] } ;
if ( $ param ) {
my $ varbind = new SNMP:: Varbind ( [ $ bootseqoids [ $ _ ] , $ slot , $ param , 'INTEGER' ] ) ;
$ data = $ session - > set ( $ varbind ) ;
#$session->set($bootseqoids[$_].".$slot",$param);
if ( $ session - > { ErrorStr } ) { return ( 1 , $ session - > { ErrorStr } ) ; }
}
}
return bootseq ( 'list' ) ;
}
}
2007-11-09 19:57:34 +00:00
sub vitals {
my @ output ;
my $ tmp ;
my @ vitems ;
foreach ( @ _ ) {
if ( $ _ eq 'all' ) {
2007-12-10 16:10:10 +00:00
push @ vitems , qw( temp,wattage,voltage,fan,summary ) ;
2007-11-09 19:57:34 +00:00
} else {
2007-12-10 16:10:10 +00:00
push @ vitems , split ( /,/ , $ _ ) ;
2007-11-09 19:57:34 +00:00
}
}
my $ tmp ;
2007-11-19 20:43:17 +00:00
if ( grep /watt/ , @ vitems ) {
if ( $ slot < 8 ) {
$ tmp = $ session - > get ( [ "1.3.6.1.4.1.2.3.51.2.2.10.2.1.1.7." . ( $ slot + 16 ) ] ) ;
} else {
$ tmp = $ session - > get ( [ "1.3.6.1.4.1.2.3.51.2.2.10.3.1.1.7." . ( $ slot + 9 ) ] ) ;
}
unless ( $ tmp =~ /Not Readable/ ) {
if ( $ tmp =~ /(\d+)W/ ) {
$ tmp = "$1 Watts (" . int ( $ tmp * 3.413 + 0.5 ) . " BTUs/hr)" ;
}
$ tmp =~ s/^/Power Usage:/ ;
push @ output , "$tmp" ;
}
}
2007-11-09 19:57:34 +00:00
if ( grep /fan/ , @ vitems or grep /blower/ , @ vitems ) {
$ tmp = $ session - > get ( [ '1.3.6.1.4.1.2.3.51.2.2.3.1.0' ] ) ;
push @ output , "Blower 1: $tmp" ;
$ tmp = $ session - > get ( [ '1.3.6.1.4.1.2.3.51.2.2.3.2.0' ] ) ;
push @ output , "Blower 2: $tmp" ;
2008-01-07 19:27:11 +00:00
$ tmp = $ session - > get ( [ '1.3.6.1.4.1.2.3.51.2.2.3.3.0' ] ) ;
if ( $ tmp and $ tmp !~ /NOSUCHINSTANCE/ ) { push @ output , "Blower 3: $tmp" ; }
$ tmp = $ session - > get ( [ '1.3.6.1.4.1.2.3.51.2.2.3.4.0' ] ) ;
if ( $ tmp and $ tmp !~ /NOSUCHINSTANCE/ ) { push @ output , "Blower 4: $tmp" ; }
2007-11-09 19:57:34 +00:00
$ tmp = $ session - > get ( [ '1.3.6.1.4.1.2.3.51.2.2.6.1.1.5.1' ] ) ;
push @ output , "Fan Pack 1: $tmp" ;
$ tmp = $ session - > get ( [ '1.3.6.1.4.1.2.3.51.2.2.6.1.1.5.2' ] ) ;
push @ output , "Fan Pack 2: $tmp" ;
$ tmp = $ session - > get ( [ '1.3.6.1.4.1.2.3.51.2.2.6.1.1.5.3' ] ) ;
push @ output , "Fan Pack 3: $tmp" ;
$ tmp = $ session - > get ( [ '1.3.6.1.4.1.2.3.51.2.2.6.1.1.5.4' ] ) ;
push @ output , "Fan Pack 4: $tmp" ;
}
if ( grep /volt/ , @ vitems ) {
2007-12-10 16:10:10 +00:00
for my $ idx ( 15 .. 40 ) {
$ tmp = $ session - > get ( [ ".1.3.6.1.4.1.2.3.51.2.22.1.5.5.1.$idx.$slot" ] ) ;
2008-01-07 19:27:11 +00:00
unless ( ( not $ tmp ) or $ tmp =~ /Not Readable/ ) {
2007-11-09 19:57:34 +00:00
$ tmp =~ s/ = /:/ ;
push @ output , "$tmp" ;
}
2007-12-10 16:10:10 +00:00
}
2007-11-09 19:57:34 +00:00
}
if ( grep /temp/ , @ vitems ) {
$ tmp = $ session - > get ( [ "1.3.6.1.4.1.2.3.51.2.2.1.5.1.0" ] ) ;
push ( @ output , "Ambient: $tmp" ) ;
for my $ idx ( 6 .. 20 ) {
2007-12-10 16:10:10 +00:00
if ( $ idx eq 11 ) {
next ;
}
2007-11-09 19:57:34 +00:00
$ tmp = $ session - > get ( [ ".1.3.6.1.4.1.2.3.51.2.22.1.5.3.1.$idx.$slot" ] ) ;
unless ( $ tmp =~ /Not Readable/ ) {
$ tmp =~ s/ = /:/ ;
push @ output , "$tmp" ;
}
}
}
if ( grep /summary/ , @ vitems ) {
$ tmp = "Status: " . $ session - > get ( [ '1.3.6.1.4.1.2.3.51.2.22.1.5.2.1.3.' . $ slot ] ) ;
2007-11-12 18:30:02 +00:00
$ tmp . = ", " . $ session - > get ( [ '1.3.6.1.4.1.2.3.51.2.22.1.5.2.1.4.' . $ slot ] ) ;
2007-11-09 19:57:34 +00:00
push @ output , "$tmp" ;
}
return ( 0 , @ output ) ;
}
2007-12-10 16:10:10 +00:00
sub rscan {
2008-04-09 17:30:43 +00:00
my $ args = shift ;
my @ values ;
my $ result ;
my % opt ;
@ ARGV = @$ args ;
$ Getopt:: Long:: ignorecase = 0 ;
Getopt::Long:: Configure ( "bundling" ) ;
local * usage = sub {
2008-04-12 14:53:11 +00:00
my $ usage_string = xCAT::Usage - > getUsage ( "rscan" ) ;
return ( join ( '' , ( $ _ [ 0 ] , $ usage_string ) ) ) ;
2008-04-09 17:30:43 +00:00
} ;
2007-12-10 16:10:10 +00:00
2008-04-12 14:53:11 +00:00
if ( ! GetOptions ( \ % opt , qw( V|Verbose w x z ) ) ) {
2008-04-09 17:30:43 +00:00
return ( 1 , usage ( ) ) ;
}
2008-04-28 14:13:19 +00:00
if ( defined ( @ ARGV [ 0 ] ) ) {
2008-04-09 17:30:43 +00:00
return ( 1 , usage ( "Invalid argument: @ARGV\n" ) ) ;
}
if ( exists ( $ opt { x } ) and exists ( $ opt { z } ) ) {
return ( 1 , usage ( "-x and -z are mutually exclusive\n" ) ) ;
}
my $ mmname = $ session - > get ( [ $ mmoname , 0 ] ) ;
if ( $ session - > { ErrorStr } ) {
return ( 1 , $ session - > { ErrorStr } ) ;
}
my $ mmtype = $ session - > get ( [ $ mmotype , 0 ] ) ;
if ( $ session - > { ErrorStr } ) {
return ( 1 , $ session - > { ErrorStr } ) ;
}
my $ mmmodel = $ session - > get ( [ $ mmomodel , 0 ] ) ;
if ( $ session - > { ErrorStr } ) {
return ( 1 , $ session - > { ErrorStr } ) ;
}
my $ mmserial = $ session - > get ( [ $ mmoserial , 0 ] ) ;
if ( $ session - > { ErrorStr } ) {
return ( 1 , $ session - > { ErrorStr } ) ;
}
push @ values , join ( "," , "mm" , $ mmname , 0 , "$mmtype-$mmmodel" , $ mmserial , $ mpa ) ;
my $ max = length ( $ mmname ) ;
2007-12-10 16:10:10 +00:00
2008-04-09 17:30:43 +00:00
foreach ( 1 .. 14 ) {
my $ tmp = $ session - > get ( [ $ bladexistsoid . ".$_" ] ) ;
if ( $ tmp eq 1 ) {
my $ type = $ session - > get ( [ $ blademtmoid , $ _ ] ) ;
if ( $ session - > { ErrorStr } ) {
return ( 1 , $ session - > { ErrorStr } ) ;
}
$ type =~ s/Not available/null/ ;
2007-12-10 16:40:40 +00:00
2008-04-09 17:30:43 +00:00
my $ model = $ session - > get ( [ $ bladeomodel , $ _ ] ) ;
if ( $ session - > { ErrorStr } ) {
return ( 1 , $ session - > { ErrorStr } ) ;
}
$ model =~ s/Not available/null/ ;
2007-12-10 16:10:10 +00:00
2008-04-09 17:30:43 +00:00
my $ serial = $ session - > get ( [ $ bladeserialoid , $ _ ] ) ;
if ( $ session - > { ErrorStr } ) {
return ( 1 , $ session - > { ErrorStr } ) ;
}
$ serial =~ s/Not available/null/ ;
2007-12-10 16:10:10 +00:00
2008-04-09 17:30:43 +00:00
my $ name = $ session - > get ( [ $ bladeoname , $ _ ] ) ;
if ( $ session - > { ErrorStr } ) {
return ( 1 , $ session - > { ErrorStr } ) ;
}
push @ values , join ( "," , "blade" , $ name , $ _ , "$type-$model" , $ serial , "" ) ;
my $ length = length ( $ name ) ;
$ max = ( $ length > $ max ) ? $ length : $ max ;
2007-12-10 16:10:10 +00:00
}
2008-04-09 17:30:43 +00:00
}
my $ format = sprintf "%%-%ds" , ( $ max + 2 ) ;
$ rscan_header [ 1 ] [ 1 ] = $ format ;
2007-12-10 16:10:10 +00:00
2008-04-09 17:30:43 +00:00
if ( exists ( $ opt { x } ) ) {
$ result = rscan_xml ( \ @ values ) ;
}
elsif ( exists ( $ opt { z } ) ) {
$ result = rscan_stanza ( \ @ values ) ;
}
else {
foreach ( @ rscan_header ) {
$ result . = sprintf @$ _ [ 1 ] , @$ _ [ 0 ] ;
2007-12-10 16:10:10 +00:00
}
2008-04-09 17:30:43 +00:00
foreach ( @ values ) {
my @ data = split /,/ ;
my $ i = 0 ;
foreach ( @ rscan_header ) {
$ result . = sprintf @$ _ [ 1 ] , $ data [ $ i + + ] ;
}
2007-12-10 16:10:10 +00:00
}
2008-04-09 17:30:43 +00:00
}
if ( ! exists ( $ opt { w } ) ) {
return ( 0 , $ result ) ;
}
my @ tabs = qw( mp nodehm nodelist ) ;
my % db = ( ) ;
2007-12-10 16:10:10 +00:00
2008-04-09 17:30:43 +00:00
foreach ( @ tabs ) {
$ db { $ _ } = xCAT::Table - > new ( $ _ , - create = > 1 , - autocommit = > 0 ) ;
if ( ! $ db { $ _ } ) {
return ( 1 , "Error opening '$_'" ) ;
2007-12-10 16:10:10 +00:00
}
2008-04-09 17:30:43 +00:00
}
foreach ( @ values ) {
my @ data = split /,/ ;
my $ name = $ data [ 1 ] ;
2007-11-09 19:57:34 +00:00
2008-04-09 17:30:43 +00:00
my ( $ k1 , $ u1 ) ;
$ k1 - > { node } = $ name ;
$ u1 - > { mpa } = $ mpa ;
$ u1 - > { id } = $ data [ 2 ] ;
$ db { mp } - > setAttribs ( $ k1 , $ u1 ) ;
$ db { mp } { commit } = 1 ;
my ( $ k2 , $ u2 ) ;
$ k2 - > { node } = $ name ;
$ u2 - > { mgt } = "blade" ;
$ db { nodehm } - > setAttribs ( $ k2 , $ u2 ) ;
$ db { nodehm } { commit } = 1 ;
my ( $ k3 , $ u3 ) ;
$ k3 - > { node } = $ name ;
$ u3 - > { groups } = "blade,all" ;
$ db { nodelist } - > setAttribs ( $ k3 , $ u3 ) ;
$ db { nodelist } { commit } = 1 ;
}
foreach ( @ tabs ) {
if ( exists ( $ db { $ _ } { commit } ) ) {
$ db { $ _ } - > commit ;
2007-12-10 16:10:10 +00:00
}
2008-04-09 17:30:43 +00:00
}
return ( 0 , $ result ) ;
2007-12-10 16:10:10 +00:00
}
sub rscan_xml {
2008-04-09 17:30:43 +00:00
my $ values = shift ;
my $ xml ;
2007-12-10 16:10:10 +00:00
2008-04-09 17:30:43 +00:00
foreach ( @$ values ) {
my @ data = split /,/ ;
my $ i = 0 ;
2007-12-10 16:10:10 +00:00
2008-04-09 17:30:43 +00:00
my $ href = {
Node = > { }
} ;
foreach ( @ rscan_header ) {
$ href - > { Node } - > { @$ _ [ 0 ] } = $ data [ $ i + + ] ;
2007-12-10 16:10:10 +00:00
}
2008-04-09 17:30:43 +00:00
$ xml . = XMLout ( $ href , NoAttr = > 1 , KeyAttr = > [] , RootName = > undef ) ;
}
return ( $ xml ) ;
2007-12-10 16:10:10 +00:00
}
2008-04-09 17:30:43 +00:00
2008-01-04 20:29:26 +00:00
sub rscan_stanza {
2007-12-10 16:10:10 +00:00
2008-04-09 17:30:43 +00:00
my $ values = shift ;
my $ result ;
2007-12-10 16:10:10 +00:00
2008-04-09 17:30:43 +00:00
foreach ( @$ values ) {
my @ data = split /,/ ;
my $ i = 0 ;
$ result . = "$data[1]:\n\tobjtype=node\n" ;
2007-12-10 16:10:10 +00:00
2008-04-09 17:30:43 +00:00
foreach ( @ rscan_header ) {
if ( @$ _ [ 0 ] ne "name" ) {
$ result . = "\t@$_[0]=$data[$i++]\n" ;
2007-12-10 16:10:10 +00:00
}
2008-04-09 17:30:43 +00:00
$ i + + ;
2007-12-10 16:10:10 +00:00
}
2008-04-09 17:30:43 +00:00
}
return ( $ result ) ;
2007-12-10 16:10:10 +00:00
}
2008-04-09 17:30:43 +00:00
2008-03-10 21:34:09 +00:00
sub getmacs {
( my $ code , my $ macs ) = inv ( 'mac' ) ;
if ( $ code == 0 ) {
my @ macs = split /\n/ , $ macs ;
( my $ macd , my $ mac ) = split ( /:/ , $ macs [ 0 ] , 2 ) ;
$ mac =~ s/\s+//g ;
if ( $ macd =~ /mac address 1/i ) {
my $ mactab = xCAT::Table - > new ( 'mac' , - create = > 1 ) ;
$ mactab - > setNodeAttribs ( $ curn , { mac = > $ mac } ) ;
$ mactab - > close ;
return 0 , ":mac.mac set to $mac" ;
} else {
2008-03-26 13:39:50 +00:00
return 1 , "Unable to retrieve MAC address from Management Module" ;
2008-03-10 21:34:09 +00:00
}
} else {
return $ code , $ macs ;
}
}
2007-10-26 22:44:33 +00:00
sub inv {
my @ invitems ;
my $ data ;
my @ output ;
foreach ( @ _ ) {
push @ invitems , split ( /,/ , $ _ ) ;
}
my $ item ;
2008-05-15 15:06:00 +00:00
unless ( scalar ( @ invitems ) ) {
@ invitems = ( "all" ) ;
}
2007-10-26 22:44:33 +00:00
while ( my $ item = shift @ invitems ) {
if ( $ item =~ /^all/ ) {
push @ invitems , ( qw( mtm serial mac firm ) ) ;
next ;
}
if ( $ item =~ /^firm/ ) {
push @ invitems , ( qw( bios diag mprom mparom ) ) ;
next ;
}
if ( $ item =~ /^bios/ ) {
my $ biosver ;
my $ biosbuild ;
my $ biosdate ;
$ biosver = $ session - > get ( [ $ bladebiosveroid . ".$slot" ] ) ;
if ( $ session - > { ErrorStr } ) { return ( 1 , $ session - > { ErrorStr } ) ; }
$ biosbuild = $ session - > get ( [ $ bladebiosbuildidoid . ".$slot" ] ) ;
if ( $ session - > { ErrorStr } ) { return ( 1 , $ session - > { ErrorStr } ) ; }
$ biosdate = $ session - > get ( [ $ bladebiosdateoid . ".$slot" ] ) ;
if ( $ session - > { ErrorStr } ) { return ( 1 , $ session - > { ErrorStr } ) ; }
push @ output , "BIOS: $biosver ($biosbuild $biosdate)" ;
}
if ( $ item =~ /^diag/ ) {
my $ diagver ;
my $ diagdate ;
my $ diagbuild ;
$ data = $ session - > get ( [ $ bladediagveroid , $ slot ] ) ;
if ( $ session - > { ErrorStr } ) { return ( 1 , $ session - > { ErrorStr } ) ; }
$ diagver = $ data ;
$ data = $ session - > get ( [ $ bladediagbuildidoid , $ slot ] ) ;
if ( $ session - > { ErrorStr } ) { return ( 1 , $ session - > { ErrorStr } ) ; }
$ diagbuild = $ data ;
$ data = $ session - > get ( [ $ bladediagdateoid , $ slot ] ) ;
if ( $ session - > { ErrorStr } ) { return ( 1 , $ session - > { ErrorStr } ) ; }
$ diagdate = $ data ;
push @ output , "Diagnostics: $diagver ($diagbuild $diagdate)" ;
}
if ( $ item =~ /^[sm]prom/ ) {
my $ spver ;
my $ spbuild ;
$ data = $ session - > get ( [ $ bladempveroid , $ slot ] ) ;
if ( $ session - > { ErrorStr } ) { return ( 1 , $ session - > { ErrorStr } ) ; }
$ spver = $ data ;
$ data = $ session - > get ( [ $ bladempbuildidoid , $ slot ] ) ;
if ( $ session - > { ErrorStr } ) { return ( 1 , $ session - > { ErrorStr } ) ; }
$ spbuild = $ data ;
push @ output , "BMC/Mgt processor: $spver ($spbuild)" ;
}
if ( $ item =~ /^mparom/ ) {
my $ mpabuild ;
my $ mpaver ;
my $ mpadate ;
$ data = $ session - > get ( [ $ bladempaveroid , $ activemm ] ) ;
if ( $ session - > { ErrorStr } ) { return ( 1 , $ session - > { ErrorStr } ) ; }
$ mpaver = $ data ;
$ data = $ session - > get ( [ $ bladempabuildidoid , $ activemm ] ) ;
if ( $ session - > { ErrorStr } ) { return ( 1 , $ session - > { ErrorStr } ) ; }
$ mpabuild = $ data ;
$ data = $ session - > get ( [ $ bladempadateoid , $ activemm ] ) ;
if ( $ session - > { ErrorStr } ) { return ( 1 , $ session - > { ErrorStr } ) ; }
$ mpadate = $ data ;
push @ output , "Management Module firmware: $mpaver ($mpabuild $mpadate)" ;
}
if ( $ item =~ /^model/ or $ item =~ /^mtm/ ) {
$ data = $ session - > get ( [ $ blademtmoid , $ slot ] ) ;
if ( $ session - > { ErrorStr } ) { return ( 1 , $ session - > { ErrorStr } ) ; }
push @ output , "Machine Type/Model: " . $ data ;
}
if ( $ item =~ /^serial/ ) {
$ data = $ session - > get ( [ $ bladeserialoid , $ slot ] ) ;
if ( $ session - > { ErrorStr } ) { return ( 1 , $ session - > { ErrorStr } ) ; }
push @ output , "Serial Number: " . $ data ;
}
if ( $ item =~ /^mac/ ) {
foreach ( 0 .. 3 ) {
$ data = $ session - > get ( [ $ macoids [ $ _ ] , $ slot ] ) ;
if ( $ session - > { ErrorStr } ) { return ( 1 , $ session - > { ErrorStr } ) ; }
if ( $ data =~ /:/ ) {
push @ output , "MAC Address " . ( $ _ + 1 ) . ": " . $ data ;
}
}
foreach ( 0 .. 3 ) {
my $ oid = $ hsdcmacoids [ $ _ ] . ".$slot" ;
$ data = $ session - > get ( [ $ hsdcmacoids [ $ _ ] , $ slot ] ) ;
if ( $ session - > { ErrorStr } ) { return ( 1 , $ session - > { ErrorStr } ) ; }
if ( $ data =~ /:/ ) {
push @ output , "HS Daughter card MAC Address " . ( $ _ + 1 ) . ": " . $ data ;
}
}
foreach ( 0 .. 3 ) {
$ data = $ session - > get ( [ $ dcmacoids [ $ _ ] , $ slot ] ) ;
if ( $ session - > { ErrorStr } ) { return ( 1 , $ session - > { ErrorStr } ) ; }
if ( $ data =~ /:/ ) {
push @ output , "Daughter card 1 MAC Address " . ( $ _ + 1 ) . ": " . $ data ;
}
}
}
}
return ( 0 , @ output ) ;
}
sub power {
my $ subcommand = shift ;
my $ data ;
my $ stat ;
2008-02-28 17:02:46 +00:00
unless ( $ slot > 0 ) {
if ( $ subcommand eq "reset" or $ subcommand eq "boot" ) {
$ data = $ session - > set ( new SNMP:: Varbind ( [ ".1.3.6.1.4.1.2.3.51.2.7.4" , 0 , 1 , 'INTEGER' ] ) ) ;
unless ( $ data ) { return ( 1 , $ session - > { ErrorStr } ) ; }
return ( 0 , "reset" ) ;
} else {
return ( 1 , "$subcommand unsupported on the management module" ) ;
}
}
2007-10-30 13:25:11 +00:00
if ( $ subcommand eq "stat" or $ subcommand eq "boot" ) {
2007-10-26 22:44:33 +00:00
$ data = $ session - > get ( [ $ powerstatoid . "." . $ slot ] ) ;
if ( $ data == 1 ) {
$ stat = "on" ;
} elsif ( $ data == 0 ) {
$ stat = "off" ;
} else {
$ stat = "error" ;
}
} elsif ( $ subcommand eq "off" ) {
$ data = $ session - > set ( new SNMP:: Varbind ( [ "." . $ powerchangeoid , $ slot , 0 , 'INTEGER' ] ) ) ;
unless ( $ data ) { return ( 1 , $ session - > { ErrorStr } ) ; }
$ stat = "off" ;
2007-10-30 13:25:11 +00:00
}
if ( $ subcommand eq "on" or ( $ subcommand eq "boot" and $ stat eq "off" ) ) {
2007-10-26 22:44:33 +00:00
$ data = $ session - > set ( new SNMP:: Varbind ( [ "." . $ powerchangeoid , $ slot , 1 , 'INTEGER' ] ) ) ;
unless ( $ data ) { return ( 1 , $ session - > { ErrorStr } ) ; }
2008-03-17 15:53:52 +00:00
$ stat . = " " . ( $ data ? "on" : "off" ) ;
2007-10-30 13:25:11 +00:00
} elsif ( $ subcommand eq "reset" or ( $ subcommand eq "boot" and $ stat eq "on" ) ) {
2007-10-26 22:44:33 +00:00
$ data = $ session - > set ( new SNMP:: Varbind ( [ "." . $ powerresetoid , $ slot , 1 , 'INTEGER' ] ) ) ;
unless ( $ data ) { return ( 1 , $ session - > { ErrorStr } ) ; }
2008-03-17 15:53:52 +00:00
$ stat = "on reset" ;
2007-10-26 22:44:33 +00:00
}
if ( $ session - > { ErrorStr } ) { return ( 1 , $ session - > { ErrorStr } ) ; }
if ( $ stat ) { return ( 0 , $ stat ) ; }
}
sub beacon {
my $ subcommand = shift ;
my $ data ;
if ( $ subcommand eq "stat" ) {
} elsif ( $ subcommand eq "on" ) {
$ data = $ session - > set ( new SNMP:: Varbind ( [ $ beaconoid , $ slot , 1 , 'INTEGER' ] ) ) ;
} elsif ( $ subcommand eq "off" ) {
$ data = $ session - > set ( new SNMP:: Varbind ( [ $ beaconoid , $ slot , 0 , 'INTEGER' ] ) ) ;
} elsif ( $ subcommand eq "blink" ) {
$ data = $ session - > set ( new SNMP:: Varbind ( [ $ beaconoid , $ slot , 2 , 'INTEGER' ] ) ) ;
} else {
return ( 1 , "$subcommand unsupported" ) ;
}
my $ stat = $ session - > get ( [ $ beaconoid . "." . $ slot ] ) ;
if ( $ session - > { ErrorStr } ) { return ( 1 , $ session - > { ErrorStr } ) ; }
if ( $ stat == 0 ) {
return ( 0 , "off" ) ;
} elsif ( $ stat == 1 ) {
return ( 0 , "on" ) ;
} elsif ( $ stat == 2 ) {
return ( 0 , "blink" ) ;
} elsif ( $ stat == 3 ) {
return ( 0 , "unsupported" ) ;
}
}
sub bladecmd {
$ mpa = shift ;
$ slot = shift ;
2008-04-09 14:19:01 +00:00
my $ user = shift ;
my $ pass = shift ;
2007-10-26 22:44:33 +00:00
my $ command = shift ;
my @ args = @ _ ;
my $ error ;
2007-12-10 16:10:10 +00:00
2007-10-26 22:44:33 +00:00
if ( $ slot > 0 ) {
my $ tmp = $ session - > get ( [ $ bladexistsoid . ".$slot" ] ) ;
if ( $ session - > { ErrorStr } ) { return ( 1 , $ session - > { ErrorStr } ) ; }
unless ( $ tmp eq 1 ) { return ( 1 , "Target bay empty" ) ; }
}
if ( $ command eq "rbeacon" ) {
return beacon ( @ args ) ;
} elsif ( $ command eq "rpower" ) {
return power ( @ args ) ;
2007-11-09 19:57:34 +00:00
} elsif ( $ command eq "rvitals" ) {
return vitals ( @ args ) ;
2007-10-26 22:44:33 +00:00
} elsif ( $ command =~ /r[ms]preset/ ) {
return resetmp ( @ args ) ;
2008-03-27 19:33:03 +00:00
} elsif ( $ command eq "rspconfig" ) {
2008-05-16 19:02:10 +00:00
return mpaconfig ( $ mpa , $ user , $ pass , $ slot , @ args ) ;
2007-10-26 22:44:33 +00:00
} elsif ( $ command eq "rbootseq" ) {
return bootseq ( @ args ) ;
2008-03-28 17:35:08 +00:00
} elsif ( $ command eq "switchblade" ) {
return switchblade ( @ args ) ;
2008-03-10 21:34:09 +00:00
} elsif ( $ command eq "getmacs" ) {
return getmacs ( @ args ) ;
2007-10-26 22:44:33 +00:00
} elsif ( $ command eq "rinv" ) {
return inv ( @ args ) ;
} elsif ( $ command eq "reventlog" ) {
return eventlog ( @ args ) ;
2007-12-10 16:10:10 +00:00
} elsif ( $ command eq "rscan" ) {
2008-04-09 17:30:43 +00:00
return rscan ( \ @ args ) ;
2007-10-26 22:44:33 +00:00
}
return ( 1 , "$command not a supported command by blade method" ) ;
}
2008-02-14 20:25:32 +00:00
sub handle_depend {
my $ request = shift ;
my $ callback = shift ;
my $ doreq = shift ;
2008-05-12 12:51:11 +00:00
my $ dp = shift ;
2008-02-14 20:25:32 +00:00
my % node = ( ) ;
2008-05-12 12:51:11 +00:00
my $ dep = @$ dp [ 0 ] ;
my $ dep_hash = @$ dp [ 1 ] ;
2008-02-14 20:25:32 +00:00
# send all dependencies (along w/ those dependent on nothing)
2008-05-12 12:51:11 +00:00
# build moreinfo for dependencies
my % mpa_hash = ( ) ;
2008-05-06 17:56:08 +00:00
my @ moreinfo = ( ) ;
my $ reqcopy = { %$ request } ;
my @ nodes = ( ) ;
2008-05-12 12:51:11 +00:00
foreach my $ node ( keys %$ dep ) {
my $ mpa = @ { $ dep_hash - > { $ node } } [ 0 ] ;
push @ { $ mpa_hash { $ mpa } { nodes } } , $ node ;
push @ { $ mpa_hash { $ mpa } { ids } } , @ { $ dep_hash - > { $ node } } [ 1 ] ;
}
2008-05-06 17:56:08 +00:00
foreach ( keys % mpa_hash ) {
push @ nodes , @ { $ mpa_hash { $ _ } { nodes } } ;
push @ moreinfo , "\[$_\]\[" . join ( ',' , @ { $ mpa_hash { $ _ } { nodes } } ) . "\]\[" . join ( ',' , @ { $ mpa_hash { $ _ } { ids } } ) . "\]" ;
}
$ reqcopy - > { node } = \ @ nodes ;
$ reqcopy - > { moreinfo } = \ @ moreinfo ;
2008-05-12 12:51:11 +00:00
process_request ( $ reqcopy , $ callback , $ doreq , 1 ) ;
2008-02-14 20:25:32 +00:00
my $ start = Time::HiRes:: gettimeofday ( ) ;
# build list of dependent nodes w/delays
while ( my ( $ name , $ h ) = each ( %$ dep ) ) {
foreach ( keys %$ h ) {
if ( $ h - > { $ _ } =~ /(^\d+$)/ ) {
$ node { $ _ } = $ 1 / 1000.0 ;
}
}
}
# send each dependent node as its delay expires
while ( % node ) {
my @ noderange = ( ) ;
my $ delay = 0.1 ;
my $ elapsed = Time::HiRes:: gettimeofday ( ) - $ start ;
# sort in ascending delay order
foreach ( sort { $ node { $ a } <=> $ node { $ b } } keys % node ) {
if ( $ elapsed < $ node { $ _ } ) {
$ delay = $ node { $ _ } - $ elapsed ;
last ;
}
push @ noderange , $ _ ;
delete $ node { $ _ } ;
}
if ( @ noderange ) {
2008-05-12 12:51:11 +00:00
% mpa_hash = ( ) ;
foreach my $ node ( @ noderange ) {
my $ mpa = @ { $ dep_hash - > { $ node } } [ 0 ] ;
push @ { $ mpa_hash { $ mpa } { nodes } } , $ node ;
push @ { $ mpa_hash { $ mpa } { ids } } , @ { $ dep_hash - > { $ node } } [ 1 ] ;
}
@ moreinfo = ( ) ;
$ reqcopy = { %$ request } ;
@ nodes = ( ) ;
foreach ( keys % mpa_hash ) {
push @ nodes , @ { $ mpa_hash { $ _ } { nodes } } ;
push @ moreinfo , "\[$_\]\[" . join ( ',' , @ { $ mpa_hash { $ _ } { nodes } } ) . "\]\[" . join ( ',' , @ { $ mpa_hash { $ _ } { ids } } ) . "\]" ;
}
$ reqcopy - > { node } = \ @ nodes ;
$ reqcopy - > { moreinfo } = \ @ moreinfo ;
# clear global hash variable
2008-02-14 20:25:32 +00:00
% mpahash = ( ) ;
2008-05-12 12:51:11 +00:00
process_request ( $ reqcopy , $ callback , $ doreq , 1 ) ;
2008-02-14 20:25:32 +00:00
}
# millisecond sleep
Time::HiRes:: sleep ( $ delay ) ;
}
return 0 ;
}
sub build_depend {
my $ noderange = shift ;
my $ exargs = shift ;
my $ depstab = xCAT::Table - > new ( 'deps' ) ;
2008-05-12 12:51:11 +00:00
my $ mptab = xCAT::Table - > new ( 'mp' ) ;
2008-02-14 20:25:32 +00:00
my % dp = ( ) ;
my % no_dp = ( ) ;
2008-05-12 12:51:11 +00:00
my % mpa_hash ;
2008-02-14 20:25:32 +00:00
if ( ! defined ( $ depstab ) ) {
return ( \ % dp ) ;
}
2008-05-12 12:51:11 +00:00
unless ( $ mptab ) {
return ( "Cannot open mp table" ) ;
}
2008-02-14 20:25:32 +00:00
foreach my $ node ( @$ noderange ) {
my $ delay = 0 ;
my $ dep ;
my $ cmd ;
my $ ent = $ depstab - > getNodeAttribs ( $ node , [ qw( nodedep msdelay cmd ) ] ) ;
if ( defined ( $ ent - > { nodedep } ) ) { $ dep = $ ent - > { nodedep } ; }
if ( defined ( $ ent - > { cmd } ) ) { $ cmd = $ ent - > { cmd } ; }
if ( defined ( $ ent - > { msdelay } ) ) { $ delay = $ ent - > { msdelay } ; }
2008-03-31 18:38:20 +00:00
if ( ! defined ( $ dep ) || ! grep ( /^@$exargs[0]$/ , split /,/ , $ cmd ) ) {
2008-02-14 20:25:32 +00:00
$ no_dp { $ node } = 1 ;
}
2008-03-31 18:38:20 +00:00
else {
2008-05-12 12:51:11 +00:00
foreach my $ n ( split /,/ , $ dep ) {
if ( ! grep ( /^$n$/ , @$ noderange ) ) {
return ( "Missing dependency on command-line: $node -> $n" ) ;
} elsif ( $ n eq $ node ) {
return ( "Node dependent on itself: $n -> $node" ) ;
}
$ dp { $ n } { $ node } = $ delay ;
2008-02-14 20:25:32 +00:00
}
}
2008-05-12 12:51:11 +00:00
}
# if there are dependencies, add any non-dependent nodes
if ( scalar ( % dp ) ) {
foreach ( keys % no_dp ) {
if ( ! exists ( $ dp { $ _ } ) ) {
$ dp { $ _ } { $ _ } = - 1 ;
}
}
# build hash of all nodes in preprocess_request() format
while ( my ( $ name , $ h ) = each ( % dp ) ) {
my $ ent = $ mptab - > getNodeAttribs ( $ name , [ 'mpa' , 'id' ] ) ;
if ( ! defined ( $ ent - > { mpa } ) ) {
return ( "no mpa defined for node $name" ) ;
}
my $ id = ( defined ( $ ent - > { id } ) ) ? $ ent - > { id } : "" ;
push @ { $ mpa_hash { $ name } } , $ ent - > { mpa } ;
push @ { $ mpa_hash { $ name } } , $ id ;
foreach ( keys %$ h ) {
if ( $ h - > { $ _ } =~ /(^\d+$)/ ) {
my $ ent = $ mptab - > getNodeAttribs ( $ _ , [ 'mpa' , 'id' ] ) ;
if ( ! defined ( $ ent - > { mpa } ) ) {
return ( "no mpa defined for node $_" ) ;
}
my $ id = ( defined ( $ ent - > { id } ) ) ? $ ent - > { id } : "" ;
push @ { $ mpa_hash { $ _ } } , $ ent - > { mpa } ;
push @ { $ mpa_hash { $ _ } } , $ id ;
2008-02-14 20:25:32 +00:00
}
}
}
}
2008-05-12 12:51:11 +00:00
return ( [ \ % dp , \ % mpa_hash ] ) ;
2008-02-14 20:25:32 +00:00
}
2007-10-26 22:44:33 +00:00
2008-04-15 14:37:26 +00:00
sub preprocess_request {
my $ request = shift ;
if ( $ request - > { _xcatdest } ) { return [ $ request ] ; } #exit if preprocessed
my $ callback = shift ;
my @ requests ;
#display usage statement if -h is present or no noderage is specified
my $ noderange = $ request - > { node } ; #Should be arrayref
my $ command = $ request - > { command } - > [ 0 ] ;
my $ extrargs = $ request - > { arg } ;
my @ exargs = ( $ request - > { arg } ) ;
if ( ref ( $ extrargs ) ) {
@ exargs = @$ extrargs ;
}
my $ usage_string = xCAT::Usage - > parseCommand ( $ command , @ exargs ) ;
if ( $ usage_string ) {
$ callback - > ( { data = > $ usage_string } ) ;
$ request = { } ;
return ;
}
if ( ! $ noderange ) {
$ usage_string = xCAT::Usage - > getUsage ( $ command ) ;
$ callback - > ( { data = > $ usage_string } ) ;
$ request = { } ;
return ;
}
#print "noderange=@$noderange\n";
#get the MMs for the nodes for the nodes in order to figure out which service nodes to send the requests to
my $ mptab = xCAT::Table - > new ( "mp" ) ;
2008-04-15 18:34:31 +00:00
unless ( $ mptab ) {
2008-04-16 16:45:14 +00:00
$ callback - > ( { data = > "Cannot open mp table" } ) ;
2008-04-15 18:34:31 +00:00
$ request = { } ;
return ;
}
2008-04-15 14:37:26 +00:00
my % mpa_hash = ( ) ;
2008-04-15 18:34:31 +00:00
foreach my $ node ( @$ noderange ) {
2008-04-15 21:55:50 +00:00
my $ ent = $ mptab - > getNodeAttribs ( $ node , [ 'mpa' , 'id' ] ) ;
if ( defined ( $ ent - > { mpa } ) ) { push @ { $ mpa_hash { $ ent - > { mpa } } { nodes } } , $ node ; }
2008-04-15 18:34:31 +00:00
else {
2008-04-16 16:45:14 +00:00
$ callback - > ( { data = > "no mpa defined for node $node" } ) ;
2008-04-15 18:34:31 +00:00
$ request = { } ;
return ;
2008-04-15 14:37:26 +00:00
}
2008-04-15 21:55:50 +00:00
if ( defined ( $ ent - > { id } ) ) { push @ { $ mpa_hash { $ ent - > { mpa } } { ids } } , $ ent - > { id } ; }
else { push @ { $ mpa_hash { $ ent - > { mpa } } { ids } } , "" ; }
2008-04-15 14:37:26 +00:00
}
# find service nodes for the MMs
# build an individual request for each service node
my $ service = "xcat" ;
my @ mms = keys ( % mpa_hash ) ;
my $ sn = xCAT::Utils - > get_ServiceNode ( \ @ mms , $ service , "MN" ) ;
# build each request for each service node
foreach my $ snkey ( keys %$ sn )
{
#print "snkey=$snkey\n";
my $ reqcopy = { %$ request } ;
$ reqcopy - > { '_xcatdest' } = $ snkey ;
my $ mms1 = $ sn - > { $ snkey } ;
2008-05-16 14:43:46 +00:00
my @ moreinfo = ( ) ;
2008-04-15 14:37:26 +00:00
my @ nodes = ( ) ;
2008-04-15 21:55:50 +00:00
foreach ( @$ mms1 ) {
push @ nodes , @ { $ mpa_hash { $ _ } { nodes } } ;
push @ moreinfo , "\[$_\]\[" . join ( ',' , @ { $ mpa_hash { $ _ } { nodes } } ) . "\]\[" . join ( ',' , @ { $ mpa_hash { $ _ } { ids } } ) . "\]" ;
}
2008-04-15 14:37:26 +00:00
$ reqcopy - > { node } = \ @ nodes ;
#print "nodes=@nodes\n";
2008-04-15 21:55:50 +00:00
$ reqcopy - > { moreinfo } = \ @ moreinfo ;
2008-04-15 14:37:26 +00:00
push @ requests , $ reqcopy ;
}
return \ @ requests ;
}
2008-05-16 14:43:46 +00:00
sub build_more_info {
my $ noderange = shift ;
my $ callback = shift ;
my $ mptab = xCAT::Table - > new ( "mp" ) ;
my @ moreinfo = ( ) ;
unless ( $ mptab ) {
$ callback - > ( { data = > "Cannot open mp table" } ) ;
return @ moreinfo ;
}
my % mpa_hash = ( ) ;
foreach my $ node ( @$ noderange ) {
my $ ent = $ mptab - > getNodeAttribs ( $ node , [ 'mpa' , 'id' ] ) ;
if ( defined ( $ ent - > { mpa } ) ) { push @ { $ mpa_hash { $ ent - > { mpa } } { nodes } } , $ node ; }
else {
$ callback - > ( { data = > "no mpa defined for node $node" } ) ;
return @ moreinfo ; ;
}
if ( defined ( $ ent - > { id } ) ) { push @ { $ mpa_hash { $ ent - > { mpa } } { ids } } , $ ent - > { id } ; }
else { push @ { $ mpa_hash { $ ent - > { mpa } } { ids } } , "" ; }
}
2008-04-15 14:37:26 +00:00
2008-05-16 14:43:46 +00:00
foreach ( keys % mpa_hash ) {
push @ moreinfo , "\[$_\]\[" . join ( ',' , @ { $ mpa_hash { $ _ } { nodes } } ) . "\]\[" . join ( ',' , @ { $ mpa_hash { $ _ } { ids } } ) . "\]" ;
}
return \ @ moreinfo ;
}
2008-04-15 14:37:26 +00:00
2007-10-26 22:44:33 +00:00
sub process_request {
2008-04-21 15:37:39 +00:00
$ SIG { INT } = $ SIG { TERM } = sub {
foreach ( keys % mm_comm_pids ) {
kill 2 , $ _ ;
}
exit 0 ;
} ;
2007-10-26 22:44:33 +00:00
my $ request = shift ;
my $ callback = shift ;
my $ doreq = shift ;
2008-03-11 14:01:47 +00:00
my $ level = shift ;
2007-10-26 22:44:33 +00:00
my $ noderange = $ request - > { node } ;
my $ command = $ request - > { command } - > [ 0 ] ;
my @ exargs ;
2008-04-11 20:05:37 +00:00
unless ( $ command ) {
return ; #Empty request
}
2007-10-26 22:44:33 +00:00
if ( ref ( $ request - > { arg } ) ) {
@ exargs = @ { $ request - > { arg } } ;
} else {
@ exargs = ( $ request - > { arg } ) ;
}
2008-02-14 20:25:32 +00:00
2008-05-16 14:43:46 +00:00
my $ moreinfo ;
if ( $ request - > { moreinfo } ) { $ moreinfo = $ request - > { moreinfo } ; }
else { $ moreinfo = build_more_info ( $ noderange , $ callback ) ; }
2008-04-15 21:55:50 +00:00
2008-05-12 12:51:11 +00:00
if ( $ command eq "rpower" and grep ( /^on|off|boot|reset|cycle$/ , @ exargs ) ) {
2008-05-06 12:34:28 +00:00
if ( my ( $ index ) = grep ( $ exargs [ $ _ ] =~ /^--nodeps$/ , 0 .. $# exargs ) ) {
splice ( @ exargs , $ index , 1 ) ;
} else {
2008-02-14 20:25:32 +00:00
# handles 1 level of dependencies only
2008-03-11 14:01:47 +00:00
if ( ! defined ( $ level ) ) {
my $ dep = build_depend ( $ noderange , \ @ exargs ) ;
2008-05-12 12:51:11 +00:00
if ( ref ( $ dep ) ne 'ARRAY' ) {
$ callback - > ( { data = > [ $ dep ] } ) ;
return ;
}
if ( scalar ( % { @$ dep [ 0 ] } ) ) {
2008-03-11 14:01:47 +00:00
handle_depend ( $ request , $ callback , $ doreq , $ dep ) ;
return 0 ;
}
2008-02-14 20:25:32 +00:00
}
}
}
2007-10-26 22:44:33 +00:00
my $ bladeuser = 'USERID' ;
my $ bladepass = 'PASSW0RD' ;
my $ blademaxp = 64 ;
my $ sitetab = xCAT::Table - > new ( 'site' ) ;
my $ mpatab = xCAT::Table - > new ( 'mpa' ) ;
my $ mptab = xCAT::Table - > new ( 'mp' ) ;
my $ tmp ;
if ( $ sitetab ) {
( $ tmp ) = $ sitetab - > getAttribs ( { 'key' = > 'blademaxp' } , 'value' ) ;
if ( defined ( $ tmp ) ) { $ blademaxp = $ tmp - > { value } ; }
}
my $ passtab = xCAT::Table - > new ( 'passwd' ) ;
if ( $ passtab ) {
( $ tmp ) = $ passtab - > getAttribs ( { 'key' = > 'blade' } , 'username' , 'password' ) ;
if ( defined ( $ tmp ) ) {
$ bladeuser = $ tmp - > { username } ;
$ bladepass = $ tmp - > { password } ;
}
}
if ( $ request - > { command } - > [ 0 ] eq "findme" ) {
my $ mptab = xCAT::Table - > new ( "mp" ) ;
unless ( $ mptab ) { return 2 ; }
my @ bladents = $ mptab - > getAllNodeAttribs ( [ qw( node ) ] ) ;
my @ blades ;
foreach ( @ bladents ) {
push @ blades , $ _ - > { node } ;
}
my % invreq ;
$ invreq { node } = \ @ blades ;
$ invreq { arg } = [ 'mac' ] ;
$ invreq { command } = [ 'rinv' ] ;
my $ mac ;
2008-01-25 15:07:53 +00:00
my $ ip = $ request - > { '_xcat_clientip' } ;
2007-10-26 22:44:33 +00:00
my $ arptable = `/sbin/arp -n` ;
my @ arpents = split /\n/ , $ arptable ;
foreach ( @ arpents ) {
if ( m/^($ip)\s+\S+\s+(\S+)\s/ ) {
$ mac = $ 2 ;
last ;
}
}
unless ( $ mac ) { return } ;
2008-01-11 20:55:28 +00:00
#Only refresh the the cache when the request permits and no useful answer
2008-01-15 19:37:30 +00:00
if ( $ macmaptimestamp < ( time ( ) - 300 ) ) { #after five minutes, invalidate cache
% macmap = ( ) ;
}
unless ( $ request - > { cacheonly } - > [ 0 ] or $ macmap { $ mac } or $ macmaptimestamp > ( time ( ) - 20 ) ) { #do not refresh cache if requested not to, if it has an entry, or is recent
% macmap = ( ) ;
$ macmaptimestamp = time ( ) ;
2008-04-17 21:32:47 +00:00
foreach ( @ { preprocess_request ( \ % invreq , \ & fillresps ) } ) {
% invreq = %$ _ ;
process_request ( \ % invreq , \ & fillresps ) ;
}
2007-10-26 22:44:33 +00:00
}
unless ( $ macmap { $ mac } ) {
return 1 ; #failure
}
my $ mactab = xCAT::Table - > new ( 'mac' , - create = > 1 ) ;
$ mactab - > setNodeAttribs ( $ macmap { $ mac } , { mac = > $ mac } ) ;
$ mactab - > close ( ) ;
2008-01-14 22:19:17 +00:00
#my %request = (
# command => ['makedhcp'],
# node => [$macmap{$mac}]
# );
#$doreq->(\%request);
2007-10-26 22:44:33 +00:00
$ request - > { command } = [ 'discovered' ] ;
$ request - > { noderange } = [ $ macmap { $ mac } ] ;
$ doreq - > ( $ request ) ;
% { $ request } = ( ) ; #Clear request. it is done
undef $ mactab ;
return 0 ;
}
my $ children = 0 ;
2008-04-21 15:37:39 +00:00
$ SIG { CHLD } = sub { my $ cpid ; while ( $ cpid = waitpid ( - 1 , WNOHANG ) > 0 ) { delete $ mm_comm_pids { $ cpid } ; $ children - - ; } } ;
2007-10-26 22:44:33 +00:00
my $ inputs = new IO:: Select ; ;
2008-04-15 21:55:50 +00:00
foreach my $ info ( @$ moreinfo ) {
$ info =~ /^\[(.*)\]\[(.*)\]\[(.*)\]/ ;
my $ mpa = $ 1 ;
my @ nodes = split ( ',' , $ 2 ) ;
my @ ids = split ( ',' , $ 3 ) ;
#print "mpa=$mpa, nodes=@nodes, ids=@ids\n";
2007-10-26 22:44:33 +00:00
my $ user = $ bladeuser ;
my $ pass = $ bladepass ;
my $ ent ;
if ( defined ( $ mpatab ) ) {
( $ ent ) = $ mpatab - > getAttribs ( { 'mpa' = > $ mpa } , 'username' , 'password' ) ;
if ( defined ( $ ent - > { password } ) ) { $ pass = $ ent - > { password } ; }
if ( defined ( $ ent - > { username } ) ) { $ user = $ ent - > { username } ; }
}
$ mpahash { $ mpa } - > { username } = $ user ;
$ mpahash { $ mpa } - > { password } = $ pass ;
2008-04-15 21:55:50 +00:00
for ( my $ i = 0 ; $ i < @ nodes ; $ i + + ) {
my $ node = $ nodes [ $ i ] ; ;
my $ nodeid = $ ids [ $ i ] ;
$ mpahash { $ mpa } - > { nodes } - > { $ node } = $ nodeid ;
}
2007-10-26 22:44:33 +00:00
}
my $ sub_fds = new IO:: Select ;
foreach $ mpa ( sort ( keys % mpahash ) ) {
while ( $ children > $ blademaxp ) { sleep ( 0.1 ) ; }
$ children + + ;
my $ cfd ;
my $ pfd ;
2008-05-12 23:36:47 +00:00
socketpair ( $ pfd , $ cfd , AF_UNIX , SOCK_STREAM , PF_UNSPEC ) or die "socketpair: $!" ;
2007-10-26 22:44:33 +00:00
$ cfd - > autoflush ( 1 ) ;
$ pfd - > autoflush ( 1 ) ;
2008-01-21 21:07:57 +00:00
my $ cpid = xCAT::Utils - > xfork ;
2007-10-26 22:44:33 +00:00
unless ( defined ( $ cpid ) ) { die "Fork error" ; }
unless ( $ cpid ) {
close ( $ cfd ) ;
2008-03-27 19:33:03 +00:00
dompa ( $ pfd , $ mpa , \ % mpahash , $ command , - args = > \ @ exargs ) ;
2007-10-26 22:44:33 +00:00
exit ( 0 ) ;
}
2008-04-21 15:37:39 +00:00
$ mm_comm_pids { $ cpid } = 1 ;
2007-10-26 22:44:33 +00:00
close ( $ pfd ) ;
$ sub_fds - > add ( $ cfd ) ;
}
2008-05-12 23:36:47 +00:00
while ( $ sub_fds - > count > 0 or $ children > 0 ) {
2007-10-26 22:44:33 +00:00
forward_data ( $ callback , $ sub_fds ) ;
}
while ( forward_data ( $ callback , $ sub_fds ) ) { }
}
2008-04-09 14:19:01 +00:00
sub telnetcmds {
my $ mpa = shift ;
my $ user = shift ;
my $ pass = shift ;
my $ value ;
my @ unhandled ;
my % handled = ( ) ;
2008-04-11 20:05:37 +00:00
my $ result ;
my @ tcmds = qw( snmpcfg sshcfg network swnet pd1 pd2 ) ;
2008-04-09 14:19:01 +00:00
foreach my $ cmd ( @ _ ) {
2008-04-11 20:05:37 +00:00
if ( $ cmd =~ /^swnet|pd1|pd2|=/ ) {
2008-04-09 17:58:02 +00:00
my ( $ command , $ value ) = split /=/ , $ cmd ;
if ( grep ( /^$command$/ , @ tcmds ) ) {
$ handled { $ command } = $ value ;
2008-04-09 14:19:01 +00:00
next ;
2008-04-09 17:58:02 +00:00
}
2008-04-09 14:19:01 +00:00
}
push @ unhandled , $ cmd ;
}
2008-04-09 17:58:02 +00:00
2008-04-09 14:19:01 +00:00
if ( ! defined ( % handled ) ) {
2008-04-11 20:05:37 +00:00
return ( [ 0 , \ @ unhandled ] ) ;
2008-04-09 14:19:01 +00:00
}
my $ t = new Net:: Telnet (
Timeout = > 15 ,
Errmode = > 'return' ,
Prompt = > '/system> $/'
) ;
my $ Rc = $ t - > open ( $ mpa ) ;
if ( $ Rc ) {
$ Rc = $ t - > login ( $ user , $ pass ) ;
}
if ( ! $ Rc ) {
push @ cfgtext , $ t - > errmsg ;
2008-04-11 20:05:37 +00:00
return ( [ 1 , \ @ unhandled ] ) ;
2008-04-09 14:19:01 +00:00
}
2008-04-11 20:05:37 +00:00
$ Rc = 0 ;
2008-04-09 14:19:01 +00:00
foreach ( keys % handled ) {
2008-04-21 19:16:46 +00:00
if ( /^snmpcfg/ ) { $ result = snmpcfg ( $ t , $ handled { $ _ } , $ user , $ pass ) ; }
elsif ( /^sshcfg$/ ) { $ result = sshcfg ( $ t , $ handled { $ _ } , $ user ) ; }
elsif ( /^network$/ ) { $ result = network ( $ t , $ handled { $ _ } , $ mpa ) ; }
elsif ( /^swnet$/ ) { $ result = swnet ( $ t , $ handled { $ _ } ) ; }
elsif ( /^pd1|pd2$/ ) { $ result = pd ( $ t , $ _ , $ handled { $ _ } ) ; }
$ Rc |= shift ( @$ result ) ;
push @ cfgtext , @$ result ;
2008-04-09 14:19:01 +00:00
}
$ t - > close ;
2008-04-11 20:05:37 +00:00
return ( [ $ Rc , \ @ unhandled ] ) ;
}
sub pd {
my $ t = shift ;
my $ pd = shift ;
my $ value = shift ;
my @ result ;
if ( $ value ) {
if ( $ value !~ /^nonred|redwoperf|redwperf$/ ) {
return ( [ 1 , "Invalid power management (redwoperf|redwperf|nonred)" ] ) ;
}
my @ data = $ t - > cmd ( "fuelg $pd -os $value" ) ;
if ( ! grep ( /OK/i , @ data ) ) {
return ( [ 1 , @ data ] ) ;
}
return ( [ 0 , "$pd: $value" ] ) ;
}
my @ data = $ t - > cmd ( "fuelg" ) ;
my @ pds = split /--------------/ , join ( '' , @ data ) ;
$ pd =~ /pd(\d)/ ;
$ pds [ $ 1 ] =~ /Power Management Policy:\s+(.*)\n/ ;
return ( [ 0 , $ 1 ] ) ;
}
sub network {
my $ t = shift ;
my $ value = shift ;
2008-04-14 15:08:28 +00:00
my $ mpa = shift ;
2008-04-11 20:05:37 +00:00
my $ cmd = "ifconfig -eth0 -c static -r auto -d auto -m 1500 -T system:mm[1]" ;
2008-04-22 19:36:00 +00:00
my ( $ ip , $ host , $ gateway , $ mask ) ;
2008-04-14 15:08:28 +00:00
if ( $ value ) {
2008-04-21 19:16:46 +00:00
if ( $ value !~ /\*/ ) {
2008-04-22 19:36:00 +00:00
( $ ip , $ host , $ gateway , $ mask ) = split /,/ , $ value ;
if ( ! $ ip and ! $ host and ! $ gateway and ! $ mask ) {
2008-04-14 15:08:28 +00:00
return ( [ 1 , "No changes specified" ] ) ;
}
2008-04-21 19:16:46 +00:00
}
2008-04-14 15:08:28 +00:00
else {
2008-04-21 19:16:46 +00:00
if ( $ value !~ /^\*$/ ) {
return ( [ 1 , "Invalid format: 'network=*'" ] ) ;
}
my % nethash = xCAT::DBobjUtils - > getNetwkInfo ( [ $ mpa ] ) ;
2008-04-14 15:08:28 +00:00
my $ gate = $ nethash { $ mpa } { gateway } ;
2008-04-22 19:36:00 +00:00
my $ result ;
2008-04-21 19:16:46 +00:00
if ( $ gate ) {
$ result = xCAT::Utils:: toIP ( $ gate ) ;
2008-04-14 15:08:28 +00:00
if ( @$ result [ 0 ] == 0 ) {
$ gateway = @$ result [ 1 ] ;
2008-04-22 19:36:00 +00:00
}
2008-04-14 15:08:28 +00:00
}
$ mask = $ nethash { $ mpa } { mask } ;
2008-04-22 19:36:00 +00:00
$ host = $ mpa ;
2008-04-21 19:16:46 +00:00
my $ hosttab = xCAT::Table - > new ( 'hosts' ) ;
2008-04-22 19:36:00 +00:00
if ( $ hosttab ) {
2008-04-21 19:16:46 +00:00
my ( $ ent ) = $ hosttab - > getAttribs ( { node = > $ mpa } , 'ip' ) ;
if ( defined ( $ ent ) ) {
$ ip = $ ent - > { ip } ;
}
$ hosttab - > close ( ) ;
2008-04-14 15:08:28 +00:00
}
}
2008-04-22 19:36:00 +00:00
}
2008-04-11 20:05:37 +00:00
if ( $ ip ) { $ cmd . = " -i $ip" ; }
2008-04-22 19:36:00 +00:00
if ( $ host ) { $ cmd . = " -n $host" ; }
2008-04-11 20:05:37 +00:00
if ( $ gateway ) { $ cmd . = " -g $gateway" ; }
if ( $ mask ) { $ cmd . = " -s $mask" ; }
2008-04-21 19:16:46 +00:00
2008-04-11 20:05:37 +00:00
my @ data = $ t - > cmd ( $ cmd ) ;
2008-04-14 15:08:28 +00:00
my @ result = grep ( /These configuration changes will become active/ , @ data ) ;
2008-04-11 20:05:37 +00:00
if ( ! @ result ) {
return ( [ 1 , @ data ] ) ;
}
if ( $ ip ) { push @ result , "MM IP: $ip" ; }
2008-04-22 19:36:00 +00:00
if ( $ host ) { push @ result , "MM Hostname: $host" ; }
2008-04-11 20:05:37 +00:00
if ( $ gateway ) { push @ result , "Gateway: $gateway" ; }
if ( $ mask ) { push @ result , "Subnet Mask: $mask" ; }
return ( [ 0 , @ result ] ) ;
2008-04-09 14:19:01 +00:00
}
2008-04-22 19:36:00 +00:00
2008-04-11 20:05:37 +00:00
sub swnet {
my $ t = shift ;
my $ value = shift ;
my @ result ;
my ( $ ip , $ gateway , $ mask ) ;
if ( ! $ value ) {
my @ data = $ t - > cmd ( "ifconfig -T system::switch[1]" ) ;
my $ s = join ( '' , @ data ) ;
if ( $ s =~ /-i\s+(\S+)/ ) { $ ip = $ 1 ; }
if ( $ s =~ /-g\s+(\S+)/ ) { $ gateway = $ 1 ; }
if ( $ s =~ /-s\s+(\S+)/ ) { $ mask = $ 1 ; }
}
else {
my $ cmd =
"ifconfig -em disabled -ep enabled -pip enabled -T system:switch[1]" ;
( $ ip , $ gateway , $ mask ) = split /,/ , $ value ;
2008-04-14 15:08:28 +00:00
if ( ! $ ip and ! $ gateway and ! $ mask ) {
return ( [ 1 , "No changes specified" ] ) ;
}
2008-04-11 20:05:37 +00:00
if ( $ ip ) { $ cmd . = " -i $ip" ; }
if ( $ gateway ) { $ cmd . = " -g $gateway" ; }
if ( $ mask ) { $ cmd . = " -s $mask" ; }
my @ data = $ t - > cmd ( $ cmd ) ;
@ result = grep ( /OK/i , @ data ) ;
if ( ! @ result ) {
return ( [ 1 , @ data ] ) ;
}
}
if ( $ ip ) { push @ result , "Switch IP: $ip" ; }
if ( $ gateway ) { push @ result , "Gateway: $gateway" ; }
if ( $ mask ) { push @ result , "Subnet Mask: $mask" ; }
return ( [ 0 , @ result ] ) ;
}
2008-04-09 14:19:01 +00:00
sub snmpcfg {
my $ t = shift ;
my $ value = shift ;
my $ uid = shift ;
my $ pass = shift ;
2008-04-11 20:05:37 +00:00
if ( $ value !~ /^enable|disable$/i ) {
return ( [ 1 , "Invalid argument '$value' (enable|disable)" ] ) ;
}
2008-04-09 14:19:01 +00:00
# Query users on MM
my @ data = $ t - > cmd ( "users -T system:mm[1]" ) ;
my ( $ user ) = grep ( /\d+\.\s+$uid/ , @ data ) ;
if ( ! $ user ) {
2008-04-11 20:05:37 +00:00
return ( [ 1 , "Cannot find user: '$uid' on MM" ] ) ;
2008-04-09 14:19:01 +00:00
}
$ user =~ /^(\d+)./ ;
my $ id = $ 1 ;
2008-04-11 20:05:37 +00:00
my $ pp = ( $ value =~ /^enable$/i ) ? "des" : "none" ;
2008-04-09 14:19:01 +00:00
my $ cmd = "users -$id -ap sha -at write -ppw $pass -pp $pp -T system:mm[1]" ;
my @ data = $ t - > cmd ( $ cmd ) ;
if ( grep ( /OK/i , @ data ) ) {
2008-04-11 20:05:37 +00:00
return ( [ 0 , "SNMP $value: OK" ] ) ;
2008-04-09 14:19:01 +00:00
}
2008-04-11 20:05:37 +00:00
return ( [ 1 , @ data ] ) ;
2008-04-09 14:19:01 +00:00
}
sub sshcfg {
my $ t = shift ;
my $ value = shift ;
my $ uid = shift ;
2008-05-05 15:02:49 +00:00
my $ fname = ( ( xCAT::Utils:: isAIX ( ) ) ? "/.ssh/" : "/root/.ssh/" ) . "id_rsa.pub" ;
2008-04-09 14:19:01 +00:00
2008-04-11 20:05:37 +00:00
if ( $ value !~ /^enable|disable$/i ) {
return ( [ 1 , "Invalid argument '$value' (enable|disable)" ] ) ;
}
2008-04-09 14:19:01 +00:00
# Does MM support SSH
my @ data = $ t - > cmd ( "sshcfg -hk rsa -T system:mm[1]" ) ;
if ( grep ( /Error: Command not recognized/ , @ data ) ) {
2008-04-11 20:05:37 +00:00
return ( [ 1 , "SSH supported on AMM with minimum firmware BPET32" ] ) ;
2008-04-09 14:19:01 +00:00
}
# Get firmware version on MM
@ data = $ t - > cmd ( "update -a -T system:mm[1]" ) ;
my ( $ line ) = grep ( /Build ID:\s+\S+/ , @ data ) ;
# Minumum firmware version BPET32 required for SSH
$ line =~ /(\d+)/ ;
if ( $ 1 < 32 ) {
2008-04-11 20:05:37 +00:00
return ( [ 1 , "SSH supported on AMM with minimum firmware BPET32" ] ) ;
2008-04-09 14:19:01 +00:00
}
2008-04-11 20:05:37 +00:00
if ( $ value =~ /^disable$/i ) {
2008-04-09 14:19:01 +00:00
@ data = $ t - > cmd ( "ports -sshe off -T system:mm[1]" ) ;
2008-04-11 20:05:37 +00:00
return ( [ 0 , "OK" ] ) ;
2008-04-09 14:19:01 +00:00
}
# Get SSH key on Management Node
unless ( open ( RSAKEY , "<$fname" ) ) {
2008-04-11 20:05:37 +00:00
return ( [ 1 , "Error opening '$fname'" ] ) ;
2008-04-09 14:19:01 +00:00
}
my ( $ sshkey ) = <RSAKEY> ;
close ( RSAKEY ) ;
if ( $ sshkey !~ /\s+(\S+\@\S+$)/ ) {
2008-04-11 20:05:37 +00:00
return ( [ 1 , "Cannot find userid\@host in '$fname'" ] ) ;
2008-04-09 14:19:01 +00:00
}
my $ login = $ 1 ;
# Query users on MM
@ data = $ t - > cmd ( "users -T system:mm[1]" ) ;
my ( $ user ) = grep ( /\d+\.\s+$uid/ , @ data ) ;
if ( ! $ user ) {
2008-04-11 20:05:37 +00:00
return ( [ 1 , "Cannot find user: '$uid' on MM" ] ) ;
2008-04-09 14:19:01 +00:00
}
$ user =~ /^(\d+)./ ;
my $ id = $ 1 ;
# Determine is key already exists on MM
@ data = $ t - > cmd ( "users -$id -pk all -T system:mm[1]" ) ;
# Remove existing keys for this login
foreach ( split ( /Key\s+/ , join ( '' , @ data ) ) ) {
if ( /-cm\s+$login/ ) {
/^(\d+)/ ;
my $ key = $ 1 ;
@ data = $ t - > cmd ( "users -$id -pk -$key -remove -T system:mm[1]" ) ;
}
}
# Make sure SSH key is generated on MM
2008-05-05 15:02:49 +00:00
@ data = $ t - > cmd ( "sshcfg -hk rsa -T system:mm[1]" ) ;
2008-04-09 14:19:01 +00:00
2008-05-05 15:02:49 +00:00
if ( ! grep ( /ssh-rsa/ , @ data ) ) {
2008-04-09 14:19:01 +00:00
@ data = $ t - > cmd ( "sshcfg -hk gen -T system:mm[1]" ) ;
if ( ! grep ( /^OK$/i , @ data ) ) {
2008-04-11 20:05:37 +00:00
return ( [ 1 , @ data ] ) ;
2008-04-09 14:19:01 +00:00
}
# Wait for SSH key generation to complete
my $ timeout = time + 240 ;
while ( 1 ) {
if ( time >= $ timeout ) {
2008-04-11 20:05:37 +00:00
return ( [ 1 , "SSH key generation timeout" ] ) ;
2008-04-09 14:19:01 +00:00
}
sleep ( 15 ) ;
2008-05-05 15:02:49 +00:00
@ data = $ t - > cmd ( "sshcfg -hk rsa -T system:mm[1]" ) ;
if ( grep ( /ssh-rsa/ , @ data ) ) {
2008-04-09 14:19:01 +00:00
last ;
}
}
}
# Transfer SSH key from Management Node to MM
$ sshkey =~ s/@/\@/ ;
@ data = $ t - > cmd ( "users -$id -pk -T system:mm[1] -add $sshkey" ) ;
if ( $ data [ 0 ] =~ /Error/i ) {
2008-04-11 20:05:37 +00:00
return ( [ 1 , $ data [ 0 ] ] ) ;
2008-04-09 14:19:01 +00:00
}
# Enable ssh on MM
@ data = $ t - > cmd ( "ports -sshe on -T system:mm[1]" ) ;
2008-04-11 20:05:37 +00:00
return ( [ 0 , "SSH $value: OK" ] ) ;
}
sub ntp {
my $ value = shift ;
my @ result ;
my $ data = $ session - > get ( [ '1.3.6.1.4.1.2.3.51.2.4.9.3.8.1' , 0 ] ) ;
if ( $ data =~ /NOSUCHOBJECT/ ) {
return ( [ 1 , "NTP Not supported" ] ) ;
}
if ( $ value ) {
my ( $ ntp , $ ip , $ f , $ v3 ) = split /,/ , $ value ;
2008-04-14 15:08:28 +00:00
2008-04-11 20:05:37 +00:00
if ( $ ntp ) {
if ( $ ntp !~ /^enable|disable$/i ) {
return ( [ 1 , "Invalid argument '$ntp' (enable|disable)" ] ) ;
}
}
if ( $ v3 ) {
if ( $ v3 !~ /^enable|disable$/i ) {
return ( [ 1 , "Invalid argument '$v3' (enable|disable)" ] ) ;
}
}
2008-04-14 15:08:28 +00:00
if ( ! $ ntp and ! $ ip and ! $ f and ! $ v3 ) {
return ( [ 1 , "No changes specified" ] ) ;
}
2008-04-11 20:05:37 +00:00
if ( $ ntp ) {
my $ d = ( $ ntp =~ /^enable$/i ) ? 1 : 0 ;
setoid ( '1.3.6.1.4.1.2.3.51.2.4.9.3.8.1' , 0 , $ d , 'INTEGER' ) ;
push @ result , "NTP: $ntp" ;
}
if ( $ ip ) {
setoid ( '1.3.6.1.4.1.2.3.51.2.4.9.3.8.2' , 0 , $ ip , 'OCTET' ) ;
push @ result , "NTP Server: $ip" ;
}
if ( $ f ) {
setoid ( '1.3.6.1.4.1.2.3.51.2.4.9.3.8.3' , 0 , $ f , 'INTEGER' ) ;
push @ result , "NTP Frequency: $f" ;
}
if ( $ v3 ) {
my $ d = ( $ v3 =~ /^enable$/i ) ? 1 : 0 ;
setoid ( '1.3.6.1.4.1.2.3.51.2.4.9.3.8.7' , 0 , $ d , 'INTEGER' ) ;
push @ result , "NTP v3: $v3" ;
}
return ( [ 0 , @ result ] ) ;
}
my $ d = ( ! $ data ) ? "disabled" : "enabled" ;
push @ result , "NTP: $d" ;
$ data = $ session - > get ( [ '1.3.6.1.4.1.2.3.51.2.4.9.3.8.2' , 0 ] ) ;
push @ result , "NTP Server: $data" ;
$ data = $ session - > get ( [ '1.3.6.1.4.1.2.3.51.2.4.9.3.8.3' , 0 ] ) ;
push @ result , "NTP Frequency: $data (minutes)" ;
$ data = $ session - > get ( [ '1.3.6.1.4.1.2.3.51.2.4.9.3.8.7' , 0 ] ) ;
$ d = ( ! $ data ) ? "disabled" : "enabled" ;
push @ result , "NTP v3: $d" ;
return ( [ 0 , @ result ] ) ;
2008-04-09 14:19:01 +00:00
}
2007-10-26 22:44:33 +00:00
sub forward_data {
my $ callback = shift ;
my $ fds = shift ;
my @ ready_fds = $ fds - > can_read ( 1 ) ;
my $ rfh ;
my $ rc = @ ready_fds ;
foreach $ rfh ( @ ready_fds ) {
my $ data ;
if ( $ data = <$rfh> ) {
while ( $ data !~ /ENDOFFREEZE6sK4ci/ ) {
$ data . = <$rfh> ;
}
2008-05-12 23:36:47 +00:00
print $ rfh "ACK\n" ;
2007-10-26 22:44:33 +00:00
my $ responses = thaw ( $ data ) ;
foreach ( @$ responses ) {
$ callback - > ( $ _ ) ;
}
} else {
$ fds - > remove ( $ rfh ) ;
close ( $ rfh ) ;
}
}
2008-03-10 15:36:44 +00:00
yield ; #Try to avoid useless iterations as much as possible
2007-10-26 22:44:33 +00:00
return $ rc ;
}
sub dompa {
my $ out = shift ;
$ mpa = shift ;
my $ mpahash = shift ;
my $ command = shift ;
my % namedargs = @ _ ;
2008-03-27 19:33:03 +00:00
my @ exargs = @ { $ namedargs { - args } } ;
2007-10-26 22:44:33 +00:00
my $ node ;
$ session = new SNMP:: Session (
DestHost = > $ mpa ,
Version = > '3' ,
SecName = > $ mpahash - > { $ mpa } - > { username } ,
AuthProto = > 'SHA' ,
AuthPass = > $ mpahash - > { $ mpa } - > { password } ,
PrivProto = > 'DES' ,
SecLevel = > 'authPriv' ,
UseNumeric = > 1 ,
2008-05-13 23:33:16 +00:00
Retries = > 4 , # Give up sooner to make commands go smoother
Timeout = > 1500000 , #Beacon, for one, takes a bit over a second to return
2007-10-26 22:44:33 +00:00
PrivPass = > $ mpahash - > { $ mpa } - > { password } ) ;
2008-03-28 18:23:19 +00:00
if ( $ session - > { ErrorStr } ) { return 1 , $ session - > { ErrorStr } ; }
2008-03-05 17:35:14 +00:00
unless ( $ session and keys %$ session ) {
my % err = ( node = > [] ) ;
foreach ( keys % { $ mpahash { $ mpa } - > { nodes } } ) {
push ( @ { $ err { node } } , { name = > [ $ _ ] , error = > [ "Cannot communicate with $mpa" ] , errorcode = > [ 1 ] } ) ;
}
print $ out freeze ( [ \ % err ] ) ;
print $ out "\nENDOFFREEZE6sK4ci\n" ;
2008-03-11 13:10:58 +00:00
yield ;
2008-05-12 23:36:47 +00:00
waitforack ( $ out ) ;
2008-01-28 19:34:58 +00:00
return 1 , "General error establishing SNMP communication" ;
}
2007-10-26 22:44:33 +00:00
my $ tmp = $ session - > get ( [ $ mmprimoid . ".1" ] ) ;
if ( $ session - > { ErrorStr } ) { print $ session - > { ErrorStr } ; }
$ activemm = ( $ tmp ? 1 : 2 ) ;
my @ outhashes ;
if ( $ command eq "reventlog" and isallchassis ) {
#Add a dummy node for eventlog to get non-blade events
$ mpahash { $ mpa } - > { nodes } - > { $ mpa } = - 1 ;
}
foreach $ node ( sort ( keys % { $ mpahash - > { $ mpa } - > { nodes } } ) ) {
2008-03-10 21:34:09 +00:00
$ curn = $ node ;
2008-04-09 14:19:01 +00:00
my ( $ rc , @ output ) = bladecmd ( $ mpa , $ mpahash - > { $ mpa } - > { nodes } - > { $ node } , $ mpahash - > { $ mpa } - > { username } , $ mpahash - > { $ mpa } - > { password } , $ command , @ exargs ) ;
2008-04-11 20:05:37 +00:00
2007-10-26 22:44:33 +00:00
my @ output_hashes ;
foreach ( @ output ) {
my % output ;
2008-01-04 20:29:26 +00:00
2007-12-10 16:10:10 +00:00
if ( $ command eq "rscan" ) {
2008-04-11 20:05:37 +00:00
$ output { errorcode } = $ rc ;
2007-12-10 16:10:10 +00:00
$ output { data } = [ $ _ ] ;
}
else {
2008-01-04 20:29:26 +00:00
( my $ desc , my $ text ) = split ( /:/ , $ _ , 2 ) ;
unless ( $ text ) {
$ text = $ desc ;
} else {
$ desc =~ s/^\s+// ;
$ desc =~ s/\s+$// ;
if ( $ desc ) {
$ output { node } - > [ 0 ] - > { data } - > [ 0 ] - > { desc } - > [ 0 ] = $ desc ;
}
}
2007-12-10 16:10:10 +00:00
$ text =~ s/^\s+// ;
$ text =~ s/\s+$// ;
2008-04-11 20:05:37 +00:00
$ output { node } - > [ 0 ] - > { errorcode } = $ rc ;
2007-12-10 16:10:10 +00:00
$ output { node } - > [ 0 ] - > { name } - > [ 0 ] = $ node ;
$ output { node } - > [ 0 ] - > { data } - > [ 0 ] - > { contents } - > [ 0 ] = $ text ;
}
2007-10-26 22:44:33 +00:00
print $ out freeze ( [ \ % output ] ) ;
print $ out "\nENDOFFREEZE6sK4ci\n" ;
2008-05-12 23:36:47 +00:00
yield ;
waitforack ( $ out ) ;
2007-10-26 22:44:33 +00:00
}
2008-03-11 13:10:58 +00:00
yield ;
2007-10-26 22:44:33 +00:00
}
#my $msgtoparent=freeze(\@outhashes); # = XMLout(\%output,RootName => 'xcatresponse');
#print $out $msgtoparent; #$node.": $_\n";
}
1 ;
2007-12-10 16:10:10 +00:00
2008-02-14 20:25:32 +00:00
2008-03-11 14:01:47 +00:00
2008-04-09 14:19:01 +00:00
2008-04-09 17:30:43 +00:00
2008-04-10 14:54:12 +00:00
2008-04-11 20:05:37 +00:00
2008-04-14 15:08:28 +00:00
2008-05-06 17:56:08 +00:00
2008-05-12 12:51:11 +00:00
2008-05-16 19:02:10 +00:00