defects: 2940290,2940304: move the getmacs --arp function to Utils.pm. Make the --arp supported by blade server and changed the format of MAC without : for aix
git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@5141 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
This commit is contained in:
		| @@ -112,11 +112,13 @@ my %usage = ( | ||||
|     "getmacs" =>  | ||||
| "Usage:  | ||||
|    Common: | ||||
|        getmacs <noderange> [-d] [-V|--verbose] | ||||
|        getmacs [-h|--help|-v|--version] | ||||
|    PPC specific: | ||||
|        getmacs <noderange> [-F filter]  | ||||
|        getmacs <noderange> [-f][-d] [--arp] | [-D [-S server] [-G gateway] [-C client]]", | ||||
|        getmacs <noderange> [-V| --verbose] [-f] [-d] [--arp] | [-D [-S server] [-G gateway] [-C client]] | ||||
|    blade specific: | ||||
|        getmacs <noderange> [-V| --verbose] [-d] [--arp] | ||||
| ", | ||||
|     "mkvm" =>  | ||||
| "Usage: | ||||
|     Common: | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -6,16 +6,17 @@ B<getmacs> - Collects node MAC address. | ||||
|  | ||||
| =head2 Common: | ||||
|  | ||||
| I<getmacs noderange [-d] [-V| --verbose]> | ||||
|  | ||||
| I<getmacs [-h| --help | -v| --version]> | ||||
|  | ||||
| =head2 PPC specific: | ||||
|  | ||||
| I<getmacs noderange> [-F filter] | ||||
| I<getmacs noderange [-F filter]> | ||||
|  | ||||
| I<getmacs [-V| --verbose] noderange> [-f][-d] [--arp] | [-D [-S server] [-G gateway] [-C client]] | ||||
| I<getmacs noderange [-V| --verbose] [-f] [-d] [--arp] | [-D [-S server] [-G gateway] [-C client]]> | ||||
|  | ||||
| =head2 blade specific: | ||||
|  | ||||
| I<getmacs noderange [-V| --verbose] [-d] [--arp]> | ||||
|  | ||||
| =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. | ||||
|  | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -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}); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user