2009-03-30 10:22:21 +00:00
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
package xCAT::PPCmac ;
2009-04-14 03:29:22 +00:00
use Socket ;
2009-03-30 10:22:21 +00:00
use strict ;
use Getopt::Long ;
2012-02-08 09:27:36 +00:00
use Data::Dumper ;
2009-03-30 10:22:21 +00:00
use xCAT::PPCcli qw( SUCCESS EXPECT_ERROR RC_ERROR NR_ERROR ) ;
2010-05-07 02:44:50 +00:00
use xCAT::NetworkUtils ;
2009-03-30 10:22:21 +00:00
2012-02-08 09:27:36 +00:00
use xCAT::LparNetbootExp ;
2009-03-30 10:22:21 +00:00
##########################################################################
# Parse the command line for options and operands
##########################################################################
sub parse_args {
my $ request = shift ;
my % opt = ( ) ;
my $ cmd = $ request - > { command } ;
my $ args = $ request - > { arg } ;
2009-04-14 03:29:22 +00:00
my $ node = $ request - > { node } ;
2009-03-30 10:22:21 +00:00
my $ vers =
my @ VERSION = qw( 2.1 ) ;
#############################################
# Responds with usage statement
#############################################
local * usage = sub {
my $ usage_string = xCAT::Usage - > getUsage ( $ cmd ) ;
return ( [ $ _ [ 0 ] , $ usage_string ] ) ;
} ;
#############################################
# Process command-line arguments
#############################################
if ( ! defined ( $ args ) ) {
$ request - > { method } = $ cmd ;
return ( \ % opt ) ;
}
#############################################
# Checks case in GetOptions, allows opts
# to be grouped (e.g. -vx), and terminates
# at the first unrecognized option.
#############################################
@ ARGV = @$ args ;
$ Getopt:: Long:: ignorecase = 0 ;
Getopt::Long:: Configure ( "bundling" ) ;
2012-03-06 07:51:22 +00:00
if ( ! GetOptions ( \ % opt , qw( h|help V|Verbose v|version C=s G=s S=s D d f M o F=s arp ) ) ) {
2009-03-30 10:22:21 +00:00
return ( usage ( ) ) ;
}
####################################
# Option -h for Help
####################################
2009-11-10 06:27:14 +00:00
#if ( exists( $opt{h} )) {
# return( usage() );
#}
2009-03-30 10:22:21 +00:00
####################################
# Option -v for version
####################################
if ( exists ( $ opt { v } ) ) {
return ( \ @ VERSION ) ;
}
####################################
# Check for "-" with no option
####################################
if ( grep ( /^-$/ , @ ARGV ) ) {
return ( usage ( "Missing option: -" ) ) ;
}
####################################
# Check for an extra argument
####################################
if ( defined ( $ ARGV [ 0 ] ) ) {
return ( usage ( "Invalid Argument: $ARGV[0]" ) ) ;
}
####################################
2009-04-14 03:29:22 +00:00
# Check argument for ping test
2009-03-30 10:22:21 +00:00
####################################
2009-04-14 03:29:22 +00:00
if ( exists ( $ opt { D } ) ) {
my @ network ;
my $ client_ip ;
my $ gateway ;
2009-04-28 09:10:19 +00:00
my $ server ;
2009-04-14 03:29:22 +00:00
my $ server_ip ;
2009-04-28 09:10:19 +00:00
my % server_nethash ;
2009-04-14 03:29:22 +00:00
2009-04-28 09:10:19 +00:00
####################################
# Set server IP
####################################
2009-04-14 03:29:22 +00:00
if ( exists ( $ opt { S } ) ) {
push @ network , $ _ ;
} else {
2011-04-20 09:52:33 +00:00
$ server = xCAT::Utils - > getSNformattedhash ( $ node , "xcat" , "node" , "primary" ) ;
2009-04-28 09:10:19 +00:00
foreach my $ key ( keys %$ server ) {
my $ valid_ip = xCAT::Utils - > validate_ip ( $ key ) ;
if ( $ valid_ip ) {
###################################################
# Service node is returned as hostname, Convert
# hostname to IP
####################################
2010-05-07 02:44:50 +00:00
$ server_ip = xCAT::NetworkUtils - > getipaddr ( $ key ) ;
2009-04-28 09:10:19 +00:00
chomp $ server_ip ;
} else {
####################################
# Service node is returned as an IP
# set the IP as server
####################################
$ server_ip = $ key ;
}
2009-04-14 03:29:22 +00:00
if ( $ server_ip ) {
2009-04-28 09:10:19 +00:00
$ opt { S } = $ server_ip ;
2009-04-14 03:29:22 +00:00
push @ network , $ server_ip ;
}
2009-04-28 09:10:19 +00:00
last ;
}
}
####################################################################
# Fulfill in the server network information for gateway resolving
####################################################################
if ( exists ( $ opt { S } ) ) {
2010-05-06 09:32:49 +00:00
# why convert to hostname??
#$server = gethostbyaddr( inet_aton($opt{S}), AF_INET );
$ server = $ opt { S } ;
2009-04-28 09:10:19 +00:00
if ( $ server ) {
% server_nethash = xCAT::DBobjUtils - > getNetwkInfo ( [ $ server ] ) ;
2009-04-14 03:29:22 +00:00
}
2009-03-30 10:22:21 +00:00
}
2009-04-14 03:29:22 +00:00
2010-05-31 08:15:32 +00:00
my % client_nethash = xCAT::DBobjUtils - > getNetwkInfo ( $ node ) ;
#####################################
# Network attributes undefined
#####################################
if ( ! % client_nethash ) {
# IPv6, the client ip address may not be available,
# if the link local address is being used,
# the link local address is calculated from mac address
if ( $ opt { S } =~ /:/ ) {
#get the network "fe80::"
my $ tmpll = "fe80::1" ;
% client_nethash = xCAT::DBobjUtils - > getNetwkInfo ( [ $ tmpll ] ) ;
2010-05-31 08:20:33 +00:00
if ( defined $ client_nethash { $ tmpll } )
{
$ client_nethash { @$ node [ 0 ] } = $ client_nethash { $ tmpll } ;
}
2010-05-31 08:15:32 +00:00
} else {
2011-07-13 09:57:37 +00:00
my $ nodes = join ( "," , @$ node ) ;
return ( [ RC_ERROR , "Cannot get network information for $nodes, check networks table and IP address for this node to make sure there is correct network in networks table" ] ) ;
2010-05-31 08:15:32 +00:00
}
}
if ( exists ( $ opt { C } ) ) {
if ( scalar ( @$ node ) > 1 ) {
return ( [ RC_ERROR , "Option '-C' doesn't work with noderange\n" ] ) ;
}
push @ network , $ _ ;
} else {
# get, check the node IP
$ client_ip = xCAT::NetworkUtils - > getipaddr ( @$ node [ 0 ] ) ;
chomp $ client_ip ;
if ( $ client_ip ) {
$ opt { C } = $ client_ip ;
push @ network , $ client_ip ;
2010-05-31 08:20:33 +00:00
} else {
if ( $ opt { S } =~ /:/ ) {
# set the IPv6 loopback address, lpar_netboot will handle it
$ opt { C } = "::1" ;
push @ network , "::1" ;
}
2010-05-31 08:15:32 +00:00
}
}
2009-04-14 03:29:22 +00:00
if ( exists ( $ opt { G } ) ) {
push @ network , $ _ ;
2009-04-28 09:10:19 +00:00
} elsif ( $ client_nethash { @$ node [ 0 ] } { net } eq $ server_nethash { $ server } { net } ) {
2009-04-14 03:29:22 +00:00
####################################
2009-04-28 09:10:19 +00:00
# Set gateway to service node if
# service node and client node are
# in the same net
2009-04-14 03:29:22 +00:00
####################################
2009-04-28 09:10:19 +00:00
$ gateway = $ opt { S } ;
$ opt { G } = $ gateway ;
push @ network , $ gateway ;
2009-04-14 03:29:22 +00:00
} else {
####################################
# Set gateway in networks table
####################################
2009-04-28 09:10:19 +00:00
$ gateway = $ client_nethash { @$ node [ 0 ] } { gateway } ;
2009-04-14 03:29:22 +00:00
if ( $ gateway ) {
$ opt { G } = $ gateway ;
push @ network , $ gateway ;
}
2009-03-30 10:22:21 +00:00
}
2009-04-14 03:29:22 +00:00
if ( @ network ) {
if ( scalar ( @ network ) != 3 ) {
return ( usage ( ) ) ;
}
2009-04-28 09:10:19 +00:00
my $ result = xCAT::Utils - > validate_ip ( $ opt { C } , $ opt { G } , $ opt { S } ) ;
2009-04-14 03:29:22 +00:00
if ( @$ result [ 0 ] ) {
return ( usage ( @$ result [ 1 ] ) ) ;
}
}
} elsif ( exists ( $ opt { S } ) || exists ( $ opt { G } ) || exists ( $ opt { C } ) ) {
2009-04-28 09:10:19 +00:00
return ( [ RC_ERROR , "Option '-D' is required for ping test\n" ] ) ;
2009-04-14 03:29:22 +00:00
}
2009-10-13 06:02:45 +00:00
####################################
# Check -F options's format
####################################
2011-04-20 09:52:33 +00:00
if ( exists ( $ opt { F } ) ) {
my @ filters = split /,/ , $ opt { F } ;
foreach ( @ filters ) {
my @ value = split /=/ , $ _ ;
if ( ! @ value [ 1 ] ) {
return ( usage ( "Option '-F' contains wrong filter format" ) ) ;
2009-10-13 06:02:45 +00:00
}
}
2010-06-01 08:46:21 +00:00
}
2009-10-13 06:02:45 +00:00
2009-03-30 10:22:21 +00:00
####################################
# Set method to invoke
####################################
$ request - > { method } = $ cmd ;
return ( \ % opt ) ;
}
##########################################################################
2009-04-20 05:03:07 +00:00
# Get LPAR MAC addresses
2009-03-30 10:22:21 +00:00
##########################################################################
2009-04-20 05:03:07 +00:00
sub do_getmacs {
2009-03-30 10:22:21 +00:00
my $ request = shift ;
my $ d = shift ;
my $ exp = shift ;
my $ name = shift ;
2009-03-30 10:26:51 +00:00
my $ node = shift ;
2009-03-30 10:22:21 +00:00
my $ opt = $ request - > { opt } ;
my $ ssh = @$ exp [ 0 ] ;
my $ userid = @$ exp [ 4 ] ;
my $ pw = @$ exp [ 5 ] ;
2012-02-08 09:27:36 +00:00
my % optarg ;
2009-03-30 10:22:21 +00:00
my $ cmd ;
my $ result ;
#######################################
# Disconnect Expect session
#######################################
xCAT::PPCcli:: disconnect ( $ exp ) ;
#######################################
# Get node data
#######################################
my $ id = @$ d [ 0 ] ;
my $ pprofile = @$ d [ 1 ] ;
my $ fsp = @$ d [ 2 ] ;
my $ hcp = @$ d [ 3 ] ;
2012-02-08 09:27:36 +00:00
########################################
## Find Expect script
########################################
#$cmd = ($::XCATROOT) ? "$::XCATROOT/sbin/" : "/opt/xcat/sbin/";
#$cmd .= "lpar_netboot.expect";
#
########################################
## Check command installed
########################################
#if ( !-x $cmd ) {
# return( [RC_ERROR,"Command not installed: $cmd"] );
#}
2009-03-30 10:22:21 +00:00
#######################################
2009-04-09 09:32:55 +00:00
# Save user name and passwd of hcp to
# environment variables.
# lpar_netboot.expect depends on this
2009-03-30 10:22:21 +00:00
#######################################
2009-04-09 09:32:55 +00:00
$ ENV { HCP_USERID } = $ userid ;
$ ENV { HCP_PASSWD } = $ pw ;
2009-03-30 10:22:21 +00:00
#######################################
# Turn on verbose and debugging
#######################################
if ( exists ( $ request - > { verbose } ) ) {
2012-02-08 09:27:36 +00:00
#$cmd.= " -v -x";
$ optarg { 'v' } = 1 ; #for verbose
$ optarg { 'x' } = 1 ; #for debug
2009-03-30 10:22:21 +00:00
}
#######################################
# Force LPAR shutdown
#######################################
if ( exists ( $ opt - > { f } ) ) {
2012-02-08 09:27:36 +00:00
#$cmd.= " -i";
$ optarg { 'i' } = 1 ;
2009-05-12 06:32:46 +00:00
} else {
#################################
# Force LPAR shutdown if LPAR is
# running Linux
#################################
my $ table = "nodetype" ;
my $ intable = 0 ;
my @ TableRowArray = xCAT::DBobjUtils - > getDBtable ( $ table ) ;
2010-11-16 08:03:24 +00:00
if ( @ TableRowArray ) {
2009-05-12 06:32:46 +00:00
foreach ( @ TableRowArray ) {
my @ nodelist = split ( ',' , $ _ - > { 'node' } ) ;
my @ oslist = split ( ',' , $ _ - > { 'os' } ) ;
my $ osname = "AIX" ;
if ( grep ( /^$node$/ , @ nodelist ) ) {
if ( ! grep ( /^$osname$/ , @ oslist ) ) {
2012-02-08 09:27:36 +00:00
#$cmd.= " -i";
$ optarg { 'i' } = 1 ;
2009-05-12 06:32:46 +00:00
}
$ intable = 1 ;
last ;
}
}
}
#################################
# Force LPAR shutdown if LPAR OS
# type is not assigned in table
# but mnt node is running Linux
#################################
if ( xCAT::Utils - > isLinux ( ) && $ intable == 0 ) {
2012-02-08 09:27:36 +00:00
#$cmd.= " -i";
$ optarg { 'i' } = 1 ;
2009-05-12 06:32:46 +00:00
}
2009-03-30 10:22:21 +00:00
}
2009-05-12 06:32:46 +00:00
2011-04-20 09:52:33 +00:00
my % client_nethash = xCAT::DBobjUtils - > getNetwkInfo ( [ $ node ] ) ;
if ( grep /hf/ , $ client_nethash { $ node } { mgtifname } ) {
2012-02-08 09:27:36 +00:00
#$cmd.= " -t hfi-ent";
$ optarg { 't' } = "hfi-ent" ;
2010-06-01 08:46:21 +00:00
} else {
2012-02-08 09:27:36 +00:00
#$cmd.= " -t ent";
$ optarg { 't' } = "ent" ;
2010-06-01 08:46:21 +00:00
}
2009-03-30 10:22:21 +00:00
#######################################
# Network specified (-D ping test)
#######################################
2010-05-27 01:43:39 +00:00
if ( exists ( $ opt - > { S } ) ) {
if ( exists ( $ opt - > { o } ) ) {
2012-02-08 09:27:36 +00:00
#$cmd .=" -o";
$ optarg { 'o' } = 1 ;
2010-05-27 01:43:39 +00:00
}
2012-02-08 09:27:36 +00:00
#$cmd.= " -D -s auto -d auto -S $opt->{S} -G $opt->{G} -C $opt->{C}";
$ optarg { 'D' } = 1 ;
$ optarg { 's' } = 'auto' ;
$ optarg { 'd' } = 'auto' ;
$ optarg { 'S' } = $ opt - > { S } ;
$ optarg { 'C' } = $ opt - > { C } ;
$ optarg { 'G' } = $ opt - > { G } ;
2009-03-30 10:22:21 +00:00
}
#######################################
# Add command options
#######################################
2012-02-08 09:27:36 +00:00
#$cmd.= " -f -M -A -n \"$name\" \"$pprofile\" \"$fsp\" $id $hcp \"$node\"";
$ optarg { 'f' } = 1 ;
$ optarg { 'M' } = 1 ;
$ optarg { 'A' } = 1 ;
$ optarg { 'n' } = $ name ;
$ optarg { 'pprofile' } = $ pprofile ;
$ optarg { 'fsp' } = $ fsp ;
$ optarg { 'id' } = $ id ;
$ optarg { 'hcp' } = $ hcp ;
$ optarg { 'node' } = $ node ;
########################################
## Execute command
########################################
#my $pid = open( OUTPUT, "$cmd 2>&1 |");
#$SIG{INT} = $SIG{TERM} = sub { #prepare to process job termination and propogate it down
# kill 9, $pid;
# return( [RC_ERROR,"Received INT or TERM signal"] );
#};
#if ( !$pid ) {
# return( [RC_ERROR,"$cmd fork error: $!"] );
#}
########################################
## Get command output
########################################
#while ( <OUTPUT> ) {
# $result.=$_;
#}
#close OUTPUT;
#
########################################
## Get command exit code
########################################
#
#foreach ( split /\n/, $result ) {
# if ( /^lpar_netboot / ) {
# $Rc = RC_ERROR;
# last;
# }
#}
my $ Rc = xCAT::LparNetbootExp - > lparnetbootexp ( \ % optarg , $ request ) ;
2009-03-30 10:22:21 +00:00
######################################
# Split results into array
######################################
2012-02-17 05:59:11 +00:00
return $ Rc ;
2009-03-30 10:22:21 +00:00
}
##########################################################################
# Get LPAR MAC addresses
##########################################################################
sub getmacs {
my $ request = shift ;
2009-06-05 07:29:12 +00:00
my $ par = shift ;
2009-03-30 10:22:21 +00:00
my $ exp = shift ;
my $ opt = $ request - > { opt } ;
my $ hwtype = @$ exp [ 2 ] ;
my $ result ;
2009-03-30 10:26:51 +00:00
my $ name ;
2009-09-17 10:54:01 +00:00
my @ emptynode ;
2009-03-30 10:22:21 +00:00
2009-06-05 07:29:12 +00:00
if ( $ par =~ /^HASH/ ) {
#########################################
# Parse the filters specified by user
#########################################
my $ filter ;
if ( $ opt - > { F } ) {
my @ filters = split /,/ , $ opt - > { F } ;
foreach ( @ filters ) {
my @ value = split /=/ , $ _ ;
$ filter - > { @ value [ 0 ] } = @ value [ 1 ] ;
}
}
#########################################
# A hash to save lpar attributes
#########################################
my % nodeatt = ( ) ;
2009-06-05 10:07:38 +00:00
#########################################
# Cleanup old data
#########################################
2009-06-05 07:29:12 +00:00
my $ result = ( ) ;
#########################################
# No ping test performed, call lshwres
# to achieve the MAC address
#########################################
foreach my $ hcp ( keys %$ par ) {
my $ hash = $ par - > { $ hcp } ;
my $ cmd ;
#########################################
# Achieve virtual ethernet MAC address
#########################################
@$ cmd [ 0 ] = [ "lpar" , "virtualio" , "" , "eth" ] ;
@$ cmd [ 1 ] = [ "port" , "hea" , "" , "logical" ] ;
@$ cmd [ 2 ] = [ "port" , "hea" , "" , "phys" ] ;
#########################################
# Parse the output of lshwres command
#########################################
for ( my $ stat = 0 ; $ stat < 3 ; $ stat + + ) {
my $ output = xCAT::PPCcli:: lshwres ( $ exp , @$ cmd [ $ stat ] , $ hcp ) ;
my $ macs ;
foreach my $ line ( @$ output ) {
if ( $ line =~ /^.*lpar\_id=(\d+),.*$/ ) {
#########################################
# For the first two commands
#########################################
my $ lparid = $ 1 ;
$ nodeatt { $ hcp } { $ lparid } { 'num' } + + ;
$ macs = $ nodeatt { $ hcp } { $ lparid } { 'num' } ;
my @ attrs = split /,/ , $ line ;
foreach ( @ attrs ) {
my @ attr = split /=/ , $ _ ;
$ nodeatt { $ hcp } { $ lparid } { $ macs } { @ attr [ 0 ] } = @ attr [ 1 ] ;
}
} elsif ( ( $ line =~ /^(.*)port\_group=(\d+),(.*),"log\_port\_ids=(.*)"/ ) || ( $ line =~ /^(.*)port\_group=(\d+),(.*),log\_port\_ids=(.*)/ ) ) {
#########################################
# For the third command
#########################################
my $ port_group = $ 2 ;
if ( $ 4 !~ /^none$/ ) {
my @ ids = split /,/ , $ 4 ;
my @ attrs = split /,/ , $ 1 ;
foreach ( @ attrs ) {
my @ attr = split /=/ , $ _ ;
foreach ( @ ids ) {
$ nodeatt { $ hcp } { $ port_group } { $ _ } { @ attr [ 0 ] } = @ attr [ 1 ] ;
}
}
my @ attrs = split /,/ , $ 3 ;
foreach ( @ attrs ) {
my @ attr = split /=/ , $ _ ;
foreach ( @ ids ) {
$ nodeatt { $ hcp } { $ port_group } { $ _ } { @ attr [ 0 ] } = @ attr [ 1 ] ;
}
}
}
}
}
}
foreach ( keys %$ hash ) {
my $ node = $ _ ;
my $ d = $ hash - > { $ _ } ;
my $ mtms = @$ d [ 2 ] ;
my $ id = @$ d [ 0 ] ;
2009-09-17 10:54:01 +00:00
my $ nodetype = @$ d [ 4 ] ;
2009-06-05 07:29:12 +00:00
my $ mac_count = $ nodeatt { $ mtms } { $ id } { 'num' } ;
2009-06-05 10:07:38 +00:00
my $ value = ( ) ;
2009-07-08 05:48:10 +00:00
my $ data = ( ) ;
2009-06-05 07:29:12 +00:00
my $ type ;
2009-09-17 10:54:01 +00:00
#########################################
# Invalid target hardware
#########################################
if ( $ nodetype ne "lpar" ) {
return ( [ [ $ node , "Node must be LPAR" , RC_ERROR ] ] ) ;
}
2009-06-05 09:06:07 +00:00
#########################################
# Put all the attributes required
# together
#########################################
2009-07-08 05:48:10 +00:00
push @$ value , "\n#Type Phys_Port_Loc MAC_Address Adapter Port_Group Phys_Port Logical_Port VLan VSwitch Curr_Conn_Speed" ;
2009-06-05 09:06:07 +00:00
2009-06-05 07:29:12 +00:00
for ( my $ num = 1 ; $ num <= $ mac_count ; $ num + + ) {
my $ mac_addr = $ nodeatt { $ mtms } { $ id } { $ num } { 'mac_addr' } ;
my $ adapter_id = $ nodeatt { $ mtms } { $ id } { $ num } { 'adapter_id' } ;
my $ port_group = $ nodeatt { $ mtms } { $ id } { $ num } { 'port_group' } ;
my $ phys_port_id = $ nodeatt { $ mtms } { $ id } { $ num } { 'phys_port_id' } ;
my $ logical_port_id = $ nodeatt { $ mtms } { $ id } { $ num } { 'logical_port_id' } ;
my $ vlan_id = $ nodeatt { $ mtms } { $ id } { $ num } { 'port_vlan_id' } ;
my $ vswitch = $ nodeatt { $ mtms } { $ id } { $ num } { 'vswitch' } ;
my $ phys_port_loc = $ nodeatt { $ mtms } { $ port_group } { $ logical_port_id } { 'phys_port_loc' } ;
my $ curr_conn_speed = $ nodeatt { $ mtms } { $ port_group } { $ logical_port_id } { 'curr_conn_speed' } ;
if ( $ phys_port_loc ) {
2009-10-14 09:06:03 +00:00
$ type = "hea " ;
2009-06-05 07:29:12 +00:00
} else {
2009-06-05 10:07:38 +00:00
$ type = "virtualio" ;
2009-06-05 07:29:12 +00:00
}
my % att = ( ) ;
2009-06-05 09:06:07 +00:00
$ att { 'MAC_Address' } = ( $ mac_addr ) ? $ mac_addr : "N/A" ;
$ att { 'Adapter' } = ( $ adapter_id ) ? $ adapter_id : "N/A" ;
2009-06-05 07:29:12 +00:00
$ att { 'Port_Group' } = ( $ port_group ) ? $ port_group : "N/A" ;
2009-06-05 09:06:07 +00:00
$ att { 'Phys_Port' } = ( $ phys_port_id ) ? $ phys_port_id : "N/A" ;
$ att { 'Logical_Port' } = ( $ logical_port_id ) ? $ logical_port_id : "N/A" ;
$ att { 'VLan' } = ( $ vlan_id ) ? $ vlan_id : "N/A" ;
2009-06-05 07:29:12 +00:00
$ att { 'VSwitch' } = ( $ vswitch ) ? $ vswitch : "N/A" ;
$ att { 'Phys_Port_Loc' } = ( $ phys_port_loc ) ? $ phys_port_loc : "N/A" ;
$ att { 'Curr_Conn_Speed' } = ( $ curr_conn_speed ) ? $ curr_conn_speed : "N/A" ;
$ att { 'Type' } = $ type ;
#########################################
# Parse the adapter with the filters
# specified
#########################################
if ( defined ( $ filter ) ) {
2012-03-21 09:49:34 +00:00
my $ matched = 0 ;
foreach my $ key ( keys %$ filter ) {
if ( $ key eq "MAC_Address" ) {
my $ mac = lc ( $ att { $ key } ) ;
my $ filter_mac = lc ( $ filter - > { $ key } ) ;
$ mac =~ s/://g ;
$ filter_mac =~ s/://g ;
if ( grep ( /$filter_mac/ , $ mac ) ) {
$ matched = 1 ;
last ;
}
} elsif ( grep ( /$filter->{$key}/ , $ att { $ key } ) ) {
$ matched = 1 ;
2009-06-05 07:29:12 +00:00
last ;
}
}
2012-03-21 09:54:53 +00:00
if ( $ matched ) {
2009-07-08 05:48:10 +00:00
push @$ value , "$att{'Type'} $att{'Phys_Port_Loc'} $att{'MAC_Address'} $att{'Adapter'} $att{'Port_Group'} $att{'Phys_Port'} $att{'Logical_Port'} $att{'VLan'} $att{'VSwitch'} $att{'Curr_Conn_Speed'}" ;
2009-06-05 07:29:12 +00:00
}
} else {
2009-07-08 05:48:10 +00:00
push @$ value , "$att{'Type'} $att{'Phys_Port_Loc'} $att{'MAC_Address'} $att{'Adapter'} $att{'Port_Group'} $att{'Phys_Port'} $att{'Logical_Port'} $att{'VLan'} $att{'VSwitch'} $att{'Curr_Conn_Speed'}" ;
2009-06-05 07:29:12 +00:00
}
}
#########################################
# Write MAC address to database
#########################################
2009-07-14 10:16:13 +00:00
if ( ! exists ( $ opt - > { d } ) ) {
writemac ( $ node , $ value ) ;
}
2009-06-05 10:07:38 +00:00
2009-09-17 10:54:01 +00:00
if ( scalar ( @$ value ) < 2 ) {
2010-03-11 07:36:37 +00:00
my $ filter = "lpar_id,curr_profile" ;
2009-09-17 10:54:01 +00:00
my $ prof = xCAT::PPCcli:: lssyscfg ( $ exp , "node" , $ mtms , $ filter , $ id ) ;
my $ Rc = shift ( @$ prof ) ;
#########################################
# Return error
#########################################
if ( $ Rc != SUCCESS ) {
return ( [ [ $ node , @$ prof [ 0 ] , $ Rc ] ] ) ;
}
foreach my $ val ( @$ prof ) {
2010-03-11 07:36:37 +00:00
my ( $ lpar_id , $ curr_profile ) = split /,/ , $ val ;
if ( ( ! length ( $ curr_profile ) ) || ( $ curr_profile =~ /^none$/ ) ) {
2009-09-17 10:54:01 +00:00
push @ emptynode , $ node ;
}
}
}
2009-07-08 05:48:10 +00:00
foreach ( @$ value ) {
if ( /^#\s?Type/ ) {
$ data . = "\n$_\n" ;
} else {
$ data . = format_mac ( $ _ ) ;
}
}
2009-06-05 10:07:38 +00:00
push @$ result , [ $ node , $ data , 0 ] ;
2009-06-05 07:29:12 +00:00
}
}
2009-09-17 10:54:01 +00:00
if ( scalar ( @ emptynode ) > 0 ) {
return ( [ [ join ( "," , @ emptynode ) , "\nThese nodes have no active profiles. Please active the nodes to enable the default profiles" , RC_ERROR ] ] ) ;
}
2009-09-14 10:15:13 +00:00
return ( [ @$ result ] ) ;
2009-06-05 07:29:12 +00:00
} else {
#########################################
# Connect to fsp to achieve MAC address
#########################################
my $ d = $ par ;
#########################################
# Get node data
#########################################
my $ lparid = @$ d [ 0 ] ;
my $ mtms = @$ d [ 2 ] ;
my $ type = @$ d [ 4 ] ;
my $ node = @$ d [ 6 ] ;
#########################################
# Invalid target hardware
#########################################
if ( $ type ne "lpar" ) {
return ( [ [ $ node , "Node must be LPAR" , RC_ERROR ] ] ) ;
}
#########################################
# Get name known by HCP
#########################################
my $ filter = "name,lpar_id" ;
my $ values = xCAT::PPCcli:: lssyscfg ( $ exp , $ type , $ mtms , $ filter ) ;
my $ Rc = shift ( @$ values ) ;
#########################################
# Return error
#########################################
if ( $ Rc != SUCCESS ) {
return ( [ [ $ node , @$ values [ 0 ] , $ Rc ] ] ) ;
}
#########################################
# Find LPARs by lpar_id
#########################################
foreach ( @$ values ) {
if ( /^(.*),$lparid$/ ) {
$ name = $ 1 ;
last ;
}
}
#########################################
# Node not found by lpar_id
#########################################
if ( ! defined ( $ name ) ) {
return ( [ [ $ node , "Node not found, lparid=$lparid" , RC_ERROR ] ] ) ;
2009-03-30 10:22:21 +00:00
}
2009-05-27 07:52:18 +00:00
2012-05-18 02:52:02 +00:00
#my $sitetab = xCAT::Table->new('site');
#my $vcon = $sitetab->getAttribs({key => "conserverondemand"}, 'value');
#there may be something wrong with the conserverondemand attribute.
# Currently, the code is not used. So not fix this time. Just keep it here.
my @ vcons = xCAT::Utils - > get_site_attribute ( "conserverondemand" ) ;
my $ vcon = $ vcons [ 0 ] ;
#if ($vcon and $vcon->{"value"} and $vcon->{"value"} eq "yes" ) {
if ( defined ( $ vcon ) and $ vcon eq "yes" ) {
2009-06-05 07:29:12 +00:00
$ result = xCAT::PPCcli:: lpar_netboot (
2009-05-27 07:52:18 +00:00
$ exp ,
$ request - > { verbose } ,
$ name ,
$ d ,
$ opt ) ;
2009-06-05 07:29:12 +00:00
} else {
#########################################
# Manually collect MAC addresses.
#########################################
$ result = do_getmacs ( $ request , $ d , $ exp , $ name , $ node ) ;
2012-02-17 05:59:11 +00:00
$ Rc = shift ( @$ result ) ;
2009-06-05 07:29:12 +00:00
}
2012-05-18 02:52:02 +00:00
#$sitetab->close;
2012-02-17 05:59:11 +00:00
2009-03-30 10:22:21 +00:00
2009-06-05 07:29:12 +00:00
##################################
# Form string from array results
##################################
if ( exists ( $ request - > { verbose } ) ) {
if ( $ Rc == SUCCESS ) {
if ( ! exists ( $ opt - > { d } ) ) {
writemac ( $ node , $ result ) ;
}
2009-03-30 10:22:21 +00:00
}
2009-06-05 07:29:12 +00:00
return ( [ [ $ node , join ( '' , @$ result ) , $ Rc ] ] ) ;
2009-03-30 10:22:21 +00:00
}
2009-06-05 07:29:12 +00:00
##################################
# Return error
##################################
if ( $ Rc != SUCCESS ) {
2010-12-20 09:14:15 +00:00
if ( @$ result [ 0 ] =~ /lpar_netboot Status: (.*)/ ) {
2009-06-05 07:29:12 +00:00
return ( [ [ $ node , $ 1 , $ Rc ] ] ) ;
}
return ( [ [ $ node , join ( '' , @$ result ) , $ Rc ] ] ) ;
2009-03-30 10:22:21 +00:00
}
2009-06-05 07:29:12 +00:00
#####################################
# lpar_netboot returns:
#
# # Connecting to lpar4\n
# # Connected\n
# # Checking for power off.\n
# # Power off complete.\n
# # Power on lpar4 to Open Firmware.\n
# # Power on complete.\n
# # Getting adapter location codes.\n
# # Type\t Location Code\t MAC Address\t Full Path Name\tPing Result\n
# ent U9117.MMA.10F6F3D-V5-C3-T1 1e0e122a930d /vdevice/l-lan@30000003
#
#####################################
my $ data ;
2009-03-30 10:22:21 +00:00
2009-06-05 07:29:12 +00:00
foreach ( @$ result ) {
if ( /^#\s?Type/ ) {
$ data . = "\n$_\n" ;
2010-06-01 08:46:21 +00:00
} elsif ( /^ent\s+/ or /^hfi-ent\s+/ ) {
2009-06-05 07:29:12 +00:00
$ data . = format_mac ( $ _ ) ;
}
2009-03-30 10:22:21 +00:00
}
2009-06-05 07:29:12 +00:00
#####################################
# Write first valid adapter MAC to database
#####################################
if ( ! exists ( $ opt - > { d } ) ) {
writemac ( $ node , $ result ) ;
}
return ( [ [ $ node , $ data , $ Rc ] ] ) ;
2009-03-30 10:22:21 +00:00
}
}
2010-06-02 09:57:06 +00:00
##########################################################################
# Calculate secondary 1 and secondary 2 MAC address based on primary MAC
# for HFI devices
##########################################################################
sub cal_mac {
my $ mac = shift ;
$ mac =~ s/://g ;
$ mac =~ /(.........)(.)(..)/ ;
my ( $ basemac , $ mac_h , $ mac_l ) = ( $ 1 , $ 2 , $ 3 ) ;
my $ macnum_l = hex ( $ mac_l ) ;
my $ macnum_h = hex ( $ mac_h ) ;
$ macnum_l += 1 ;
if ( $ macnum_l > 0xFF ) {
$ macnum_h += 1 ;
}
my $ newmac_l = sprintf ( "%02X" , $ macnum_l ) ;
$ newmac_l =~ /(..)$/ ;
$ newmac_l = $ 1 ;
my $ newmac_h = sprintf ( "%01X" , $ macnum_h ) ;
my $ newmac = $ basemac . $ newmac_h . $ newmac_l ;
return ( $ newmac ) ;
}
2009-03-30 10:22:21 +00:00
##########################################################################
# Insert colons in MAC addresses for Linux only
##########################################################################
sub format_mac {
2011-05-03 06:14:03 +00:00
my $ data = shift ;
2009-03-30 10:22:21 +00:00
2011-05-03 06:14:03 +00:00
$ data =~ /^(\S+\s+\S+\s+)(\S+)(\s+.*)$/ ;
my $ mac = $ 2 ;
2010-06-02 09:57:06 +00:00
#####################################
# Get adapter mac
#####################################
2011-04-20 09:52:33 +00:00
my @ newmacs ;
my @ macs = split /\|/ , $ mac ;
2011-05-03 06:14:03 +00:00
if ( ! xCAT::Utils - > isAIX ( ) ) {
foreach my $ mac_a ( @ macs ) {
2010-06-02 09:57:06 +00:00
#################################
2011-04-20 09:52:33 +00:00
# Delineate MAC with colons
2010-06-02 09:57:06 +00:00
#################################
2011-04-20 09:52:33 +00:00
$ mac_a = lc ( $ mac_a ) ;
$ mac_a =~ s/(\w{2})/$1:/g ;
$ mac_a =~ s/:$// ;
push @ newmacs , $ mac_a ;
2010-06-02 09:57:06 +00:00
}
2011-05-03 06:14:03 +00:00
my $ newmac = join ( "|" , @ newmacs ) ;
$ data =~ s/$mac/$newmac/ ;
2009-03-30 10:22:21 +00:00
}
2011-04-20 09:52:33 +00:00
2011-05-03 06:14:03 +00:00
return ( "$data\n" ) ;
2011-04-20 09:52:33 +00:00
2009-03-30 10:22:21 +00:00
}
##########################################################################
# Write first valid adapter MAC to database
##########################################################################
sub writemac {
my $ name = shift ;
my $ data = shift ;
my $ value ;
my $ pingret ;
2009-06-05 07:29:12 +00:00
my $ ping_test ;
my $ mac ;
2009-03-30 10:22:21 +00:00
my @ fields ;
#####################################
# Find first valid adapter
#####################################
foreach ( @$ data ) {
2010-06-01 08:46:21 +00:00
if ( /^ent\s+/ or /^hfi-ent\s+/ ) {
2009-03-30 10:22:21 +00:00
$ value = $ _ ;
#####################################
# MAC not found in output
#####################################
if ( ! defined ( $ value ) ) {
return ;
}
@ fields = split /\s+/ , $ value ;
$ pingret = $ fields [ 4 ] ;
if ( $ pingret eq "successful" ) {
2009-06-05 07:29:12 +00:00
$ ping_test = 0 ;
2009-03-30 10:22:21 +00:00
last ;
}
}
}
#####################################
# If no valid adapter, find the first one
#####################################
if ( $ pingret ne "successful" ) {
foreach ( @$ data ) {
2010-06-01 08:46:21 +00:00
if ( /^ent\s+/ or /^hfi-ent\s+/ ) {
2009-06-05 07:29:12 +00:00
$ value = $ _ ;
$ ping_test = 0 ;
last ;
} elsif ( /^hea\s+/ || /^virtualio\s+/ ) {
$ value = $ _ ;
$ ping_test = 1 ;
2009-03-30 10:22:21 +00:00
last ;
}
}
}
#####################################
# MAC not found in output
#####################################
if ( ! defined ( $ value ) ) {
return ;
}
#####################################
# Get adapter mac
#####################################
$ value = format_mac ( $ value ) ;
@ fields = split /\s+/ , $ value ;
2009-07-08 05:48:10 +00:00
$ mac = $ fields [ 2 ] ;
2009-03-30 10:22:21 +00:00
#####################################
# Write adapter mac to database
#####################################
my $ mactab = xCAT::Table - > new ( "mac" , - create = > 1 , - autocommit = > 1 ) ;
if ( ! $ mactab ) {
return ( [ [ $ name , "Error opening 'mac'" , RC_ERROR ] ] ) ;
}
$ mactab - > setNodeAttribs ( $ name , { mac = > $ mac } ) ;
$ mactab - > close ( ) ;
}
1 ;