diff --git a/perl-xCAT/xCAT/Usage.pm b/perl-xCAT/xCAT/Usage.pm index 95223e285..f8e527669 100644 --- a/perl-xCAT/xCAT/Usage.pm +++ b/perl-xCAT/xCAT/Usage.pm @@ -112,11 +112,13 @@ my %usage = ( "getmacs" => "Usage: Common: - getmacs [-d] [-V|--verbose] getmacs [-h|--help|-v|--version] PPC specific: getmacs [-F filter] - getmacs [-f][-d] [--arp] | [-D [-S server] [-G gateway] [-C client]]", + getmacs [-V| --verbose] [-f] [-d] [--arp] | [-D [-S server] [-G gateway] [-C client]] + blade specific: + getmacs [-V| --verbose] [-d] [--arp] +", "mkvm" => "Usage: Common: diff --git a/perl-xCAT/xCAT/Utils.pm b/perl-xCAT/xCAT/Utils.pm index f0b564819..8b4512c18 100644 --- a/perl-xCAT/xCAT/Utils.pm +++ b/perl-xCAT/xCAT/Utils.pm @@ -5594,4 +5594,110 @@ sub full_path return $fullpath; } + +#------------------------------------------------------------------------------- + +=head3 get_mac_by_arp + Description: + Get the MAC address by arp protocol + + Arguments: + nodes: a reference to nodes array + display: whether just display the result, if not 'yes', the result will + be written to the mac table. + Returns: + Return a hash with node name as key + Globals: + none + Error: + none + Example: + xCAT::Utils->get_mac_by_arp($nodes, $display); + Comments: + +=cut + +#------------------------------------------------------------------------------- +sub get_mac_by_arp () +{ + my ($class, $nodes, $display) = @_; + + my $node; + my $data; + my %ret = (); + my $unreachable_nodes = ""; + my $noderange = join (',', @$nodes); + my @output = xCAT::Utils->runcmd("/opt/xcat/bin/pping $noderange", -1); + + foreach my $line (@output) { + my ($hostname, $result) = split ':', $line; + my ($token, $status) = split ' ', $result; + chomp($token); + if ($token eq 'ping') { + $node->{$hostname}->{reachable} = 1; + } + } + + foreach my $n ( @$nodes ) { + if ( $node->{$n}->{reachable} ) { + my $output; + my $IP = xCAT::Utils::toIP( $n ); + if ( xCAT::Utils->isAIX() ) { + $output = `/usr/sbin/arp -a`; + } else { + $output = `/sbin/arp -n`; + } + + my ($ip, $mac); + my @lines = split /\n/, $output; + foreach my $line ( @lines ) { + if ( xCAT::Utils->isAIX() && $line =~ /\((\S+)\)\s+at\s+(\S+)/ ) { + ($ip, $mac) = ($1,$2); + ###################################################### + # Change mac format to be same as linux, but without ':' + # For example: '0:d:60:f4:f8:22' to '000d60f4f822' + ###################################################### + if ( $mac) + { + my @mac_sections = split /:/, $mac; + for my $m (@mac_sections) + { + $m = "0$m" if ( length($m) == 1); + } + $mac = join '', @mac_sections; + } + } elsif ( $line =~ /^(\S+)+\s+\S+\s+(\S+)\s/ ) { + ($ip, $mac) = ($1,$2); + } else { + ($ip, $mac) = (undef,undef); + } + if ( @$IP[1] !~ $ip ) { + ($ip, $mac) = (undef,undef); + } else { + last; + } + } + if ( $ip && $mac ) { + if ( $display ne "yes" ) { + ##################################### + # Write adapter mac to database + ##################################### + my $mactab = xCAT::Table->new( "mac", -create=>1, -autocommit=>1 ); + $mactab->setNodeAttribs( $n,{mac=>$mac} ); + $mactab->close(); + } + $ret{$n} = "MAC Address: $mac"; + } else { + $ret{$n} = "Cannot find MAC Address in arp table, please make sure target node and management node are in same network."; + } + } else { + $ret{$n} = "Unreachable."; + } + } + + return \%ret; +} + + + 1; diff --git a/xCAT-client/pods/man1/getmacs.1.pod b/xCAT-client/pods/man1/getmacs.1.pod index ff3521e87..32b6526ca 100644 --- a/xCAT-client/pods/man1/getmacs.1.pod +++ b/xCAT-client/pods/man1/getmacs.1.pod @@ -6,16 +6,17 @@ B - Collects node MAC address. =head2 Common: -I - I =head2 PPC specific: -I [-F filter] +I -I [-f][-d] [--arp] | [-D [-S server] [-G gateway] [-C client]] +I +=head2 blade specific: + +I =head1 DESCRIPTION @@ -37,7 +38,7 @@ B<-D> Perform ping test. Please be aware that in this way, the lpars w B<-f> Force immediate shutdown of the partition. -B<-F> Specify filters to select the correct adapter. Acceptable filters are Type,MAC_Address,Phys_Port_Loc,Adapter,Port_Group,Phys_Port,Logical_Port,VLan,VSwitch,Curr_Conn_Speed. +B<-F> Specify filters to select the correct adapter. Acceptable filters are Type, MAC_Address, Phys_Port_Loc, Adapter, Port_Group, Phys_Port, Logical_Port, VLan, VSwitch, Curr_Conn_Speed. B<-G> Gateway IP address of the partition. The default is to read from xCAT database if no -G specified. diff --git a/xCAT-server/lib/perl/xCAT/PPC.pm b/xCAT-server/lib/perl/xCAT/PPC.pm index b0624c5cd..84eb2fbad 100644 --- a/xCAT-server/lib/perl/xCAT/PPC.pm +++ b/xCAT-server/lib/perl/xCAT/PPC.pm @@ -343,78 +343,18 @@ sub process_command { } } } elsif ( $request->{command} =~ /^(getmacs)$/ && exists( $request->{opt}->{arp} ) ) { - my $node; - my $data; - my $unreachable_nodes; - my $noderange = join (',', @$nodes); - my @output = xCAT::Utils->runcmd("/opt/xcat/bin/pping $noderange", -1); - - foreach my $line (@output) { - my ($hostname, $result) = split ':', $line; - my ($token, $status) = split ' ', $result; - chomp($token); - if ($token eq 'ping') { - $node->{$hostname}->{reachable} = 1; - } + my $display = ""; + if (defined($request->{opt}->{d})) { + $display = "yes"; } - - foreach my $n ( @$nodes ) { - if ( $node->{$n}->{reachable} ) { - my $output; - my $IP = xCAT::Utils::toIP( $n ); - if ( xCAT::Utils->isAIX() ) { - $output = `/usr/sbin/arp -a`; - } else { - $output = `/sbin/arp -n`; - } - - my ($ip, $mac); - my @lines = split /\n/, $output; - foreach my $line ( @lines ) { - if ( xCAT::Utils->isAIX() && $line =~ /\((\S+)\)\s+at\s+(\S+)/ ) { - ($ip, $mac) = ($1,$2); - ###################################################### - # Change mac format to be same as linux. For example: - # '0:d:60:f4:f8:22' to '00:0d:60:f4:f8:22' - ###################################################### - if ( $mac) - { - my @mac_sections = split /:/, $mac; - for my $m (@mac_sections) - { - $m = "0$m" if ( length($m) == 1); - } - $mac = join ':', @mac_sections; - } - } elsif ( $line =~ /^(\S+)+\s+\S+\s+(\S+)\s/ ) { - ($ip, $mac) = ($1,$2); - } else { - ($ip, $mac) = (undef,undef); - } - if ( @$IP[1] !~ $ip ) { - ($ip, $mac) = (undef,undef); - } else { - last; - } - } - if ( $ip && $mac ) { - if ( !exists( $request->{opt}->{d} ) ) { - ##################################### - # Write adapter mac to database - ##################################### - my $mactab = xCAT::Table->new( "mac", -create=>1, -autocommit=>1 ); - $mactab->setNodeAttribs( $n,{mac=>$mac} ); - $mactab->close(); - } - - $callback->({node=>[{name=>[$n],data=>["\n#IP MAC\n$ip $mac\n"]}]}); - } - } else { - $unreachable_nodes = join (",", $n, $unreachable_nodes); - } + my $output = xCAT::Utils->get_mac_by_arp($nodes, $display); + + my $rsp = (); + foreach my $node (keys %{$output}) { + push @{$rsp->{node}}, {name => [$node], data => [$output->{$node}]}; } - $callback->({data=>["Unreachable Nodes:"]}); - $callback->({data=>["$unreachable_nodes\n"]}); + $rsp->{errorcode} = 0; + $callback->($rsp); } elsif ( $request->{command} =~ /^rpower$/ ) { my $hw; my $sessions; diff --git a/xCAT-server/lib/xcat/plugins/blade.pm b/xCAT-server/lib/xcat/plugins/blade.pm index 72b66fced..7147efbf8 100644 --- a/xCAT-server/lib/xcat/plugins/blade.pm +++ b/xCAT-server/lib/xcat/plugins/blade.pm @@ -1351,15 +1351,30 @@ sub rscan_stanza { } sub getmacs { - my (@args) = @_; + my ($node, @args) = @_; my $display = (); + my $byarp = (); foreach my $arg (@args) { if ($arg eq "-d") { $display = "yes"; + } elsif ($arg eq "--arp") { + $byarp = "yes"; } } + if ($byarp eq "yes") { + my $output = xCAT::Utils->get_mac_by_arp([$node], $display); + my @ret = (); + foreach my $n (keys %$output) { + if ($n ne $node) { + next; + } + push @ret, $output->{$n}; + } + return (0, @ret); + } + (my $code,my @macs)=inv('mac'); foreach (@macs) { if (/(.*) ->/) { #Convert JS style mac ranges to pretend to be simple @@ -1674,7 +1689,7 @@ sub bladecmd { } elsif ($command eq "switchblade") { return switchblade(@args); } elsif ($command eq "getmacs") { - return getmacs(@args); + return getmacs($node, @args); } elsif ($command eq "rinv") { return inv(@args); } elsif ($command eq "reventlog") { @@ -1992,7 +2007,7 @@ sub preprocess_request { #parse the arguments for commands if ($command eq "getmacs") { foreach my $arg (@exargs) { - if (defined($arg) && $arg !~ /^-V|--verbose|-d$/) { + if (defined($arg) && $arg !~ /^-V|--verbose|-d|--arp$/) { $usage_string="Error arguments\n"; $usage_string .=xCAT::Usage->getUsage($command); $callback->({data=>$usage_string});