Fix defects: 2824357 lsslp is providing duplicate records for FSP and BPAs;2824601 lsslp should get correct hostname for BPA nodes;2824605 lsslp -w should update /etc/hosts
git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@3872 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
This commit is contained in:
		| @@ -1829,10 +1829,132 @@ sub my_hexnets | ||||
|     return $rethash; | ||||
| } | ||||
|  | ||||
| #------------------------------------------------------------------------------- | ||||
|  | ||||
| =head3 get_host_from_ip | ||||
|     Description: | ||||
|         Get the hostname of an IP addresses. First from hosts table, and then try system resultion. | ||||
|         If there is a shortname, it will be returned. Otherwise it will return long name. If the IP cannot be resolved, return undef; | ||||
|          | ||||
|     Arguments: | ||||
|         $ip: the IP to get; | ||||
|          | ||||
|     Returns:   | ||||
|         Return: the hostname. | ||||
| For an example | ||||
|          | ||||
|     Globals: | ||||
|         none | ||||
|          | ||||
|     Error: | ||||
|         none | ||||
|          | ||||
|     Example: | ||||
|         xCAT::Utils::get_host_from_ip('192.168.200.1') | ||||
|      | ||||
|     Comments: | ||||
| =cut | ||||
|  | ||||
| #----------------------------------------------------------------------- | ||||
| sub get_host_from_ip | ||||
| { | ||||
|     my $ip = shift; | ||||
| } | ||||
|   | ||||
| #------------------------------------------------------------------------------- | ||||
|  | ||||
| =head3 isPingable | ||||
|     Description: | ||||
|         Check if an IP address can be pinged | ||||
|          | ||||
|     Arguments: | ||||
|         $ip: the IP to ping; | ||||
|          | ||||
|     Returns:   | ||||
|         Return: 1 indicates yes; 0 indicates no. | ||||
| For an example | ||||
|          | ||||
|     Globals: | ||||
|         none | ||||
|          | ||||
|     Error: | ||||
|         none | ||||
|          | ||||
|     Example: | ||||
|         xCAT::Utils::isPingable('192.168.200.1') | ||||
|      | ||||
|     Comments: | ||||
|         none | ||||
| =cut | ||||
|  | ||||
| #----------------------------------------------------------------------- | ||||
| %::PING_CACHE; | ||||
| sub isPingable | ||||
| { | ||||
|     my $ip = shift; | ||||
|  | ||||
|     my $rc; | ||||
|     if ( exists $::PING_CACHE{ $ip}) | ||||
|     { | ||||
|          $rc = $::PING_CACHE{ $ip}; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         my $res = `LANG=C ping -c 1 -w 5 $ip 2>&1`; | ||||
|         if ( $res =~ /100% packet loss/g) | ||||
|         {  | ||||
|             $rc = 1; | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             $rc = 0; | ||||
|         } | ||||
|         $::PING_CACHE{ $ip} = $rc; | ||||
|     } | ||||
|  | ||||
|     return ! $rc;     | ||||
| } | ||||
|   | ||||
| #------------------------------------------------------------------------------- | ||||
|  | ||||
| =head3 my_nets | ||||
|     Description: | ||||
|         Return a hash ref that contains all subnet and netmask on the mn (or sn). This subroutine can be invoked on both Linux and AIX. | ||||
|          | ||||
|     Arguments: | ||||
|         none. | ||||
|          | ||||
|     Returns:   | ||||
|         Return a hash ref. Each entry will be: <subnet/mask>=><existing ip>; | ||||
|         For an example: | ||||
|             '192.168.200.0/255.255.255.0' => '192.168.200.246'; | ||||
| For an example | ||||
|          | ||||
|     Globals: | ||||
|         none | ||||
|          | ||||
|     Error: | ||||
|         none | ||||
|          | ||||
|     Example: | ||||
|         xCAT::Utils::my_nets(). | ||||
|      | ||||
|     Comments: | ||||
|         none | ||||
| =cut | ||||
| #----------------------------------------------------------------------- | ||||
| sub my_nets | ||||
| { | ||||
|     my $rethash; | ||||
|     my @nets = split /\n/, `/sbin/ip addr`; #could use ip route, but to match hexnets... | ||||
|     my @nets; | ||||
|     if ( $^O eq 'aix') | ||||
|     { | ||||
|         @nets = split /\n/, `/usr/sbin/ifconfig -a`; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         @nets = split /\n/, `/sbin/ip addr`; #could use ip route, but to match hexnets... | ||||
|     } | ||||
|     foreach (@nets) | ||||
|     { | ||||
|         my @elems = split /\s+/; | ||||
| @@ -1840,7 +1962,16 @@ sub my_nets | ||||
|         { | ||||
|             next; | ||||
|         } | ||||
|         (my $curnet, my $maskbits) = split /\//, $elems[2]; | ||||
|         my $curnet; my $maskbits; | ||||
|         if ( $^O eq 'aix') | ||||
|         { | ||||
|             $curnet = $elems[2]; | ||||
|             $maskbits = formatNetmask( $elems[4], 2, 1); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             ($curnet, $maskbits) = split /\//, $elems[2]; | ||||
|         } | ||||
|         my $curmask  = 2**$maskbits - 1 << (32 - $maskbits); | ||||
|         my $nown     = unpack("N", inet_aton($curnet)); | ||||
|         $nown = $nown & $curmask; | ||||
| @@ -4722,4 +4853,47 @@ sub get_subnet_aix | ||||
|     return @aix_nrn; | ||||
| } | ||||
|  | ||||
| #------------------------------------------------------------------------------- | ||||
|  | ||||
| =head3    isIpaddr | ||||
|  | ||||
|     returns 1 if parameter is has a valid IP address form. | ||||
|  | ||||
|     Arguments: | ||||
|         dot qulaified IP address: e.g. 1.2.3.4 | ||||
|     Returns: | ||||
|         1 - if legal IP address | ||||
|         0 - if not legal IP address. | ||||
|     Globals: | ||||
|         none | ||||
|     Error: | ||||
|         none | ||||
|     Example: | ||||
|          if ($ipAddr) { blah; } | ||||
|     Comments: | ||||
|         Doesn't test if the IP address is on the network, | ||||
|         just tests its form. | ||||
|  | ||||
| =cut | ||||
|  | ||||
| #------------------------------------------------------------------------------- | ||||
| sub isIpaddr | ||||
| { | ||||
|     my $addr = shift; | ||||
|  | ||||
|     #print "addr=$addr\n"; | ||||
|     if ($addr !~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/) | ||||
|     { | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|     if ($1 > 255 || $1 == 0 || $2 > 255 || $3 > 255 || $4 > 255) | ||||
|     { | ||||
|         return 0; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         return 1; | ||||
|     } | ||||
| } | ||||
| 1; | ||||
|   | ||||
| @@ -683,6 +683,7 @@ sub invoke_cmd { | ||||
|     my $result  = runslp( $args, $ip, $services, $request ); | ||||
|     my $unicast = @$result[0]; | ||||
|     my $values  = @$result[1]; | ||||
|     prt_result( $request, $values); | ||||
|  | ||||
|     ######################################## | ||||
|     # May have to send additional unicasts | ||||
| @@ -725,6 +726,7 @@ sub invoke_cmd { | ||||
|             #################################### | ||||
|             if ( defined($attr) ) { | ||||
|                 $values->{"URL: $url\n$attr\n"} = 1; | ||||
|                 prt_result( $values); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| @@ -744,7 +746,29 @@ sub invoke_cmd { | ||||
|     print $out "\nENDOFFREEZE6sK4ci\n"; | ||||
| } | ||||
|  | ||||
|  | ||||
| ######################################################### | ||||
| # print the slp result | ||||
| ######################################################### | ||||
| sub prt_result | ||||
| { | ||||
|     my $request = shift; | ||||
|     my $values = shift; | ||||
|     my $nets = xCAT::Utils::my_nets(); | ||||
|     for my $v (keys %$values) | ||||
|     { | ||||
|         if ( $v =~ /ip-address=([^\)]+)/g) | ||||
|         { | ||||
|             my $iplist = $1; | ||||
|             my $ip = getip_from_iplist( $iplist, $nets, $opt{i}); | ||||
|             if ( $ip) | ||||
|             { | ||||
| #                send_msg($request, "Received SLP response from $ip."); | ||||
| #print "Received SLP response from $ip.\n"; | ||||
|                 xCAT::MsgUtils->message("I", "Received SLP response from $ip.", $::callback); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| ########################################################################## | ||||
| # Run the SLP command, process the response, and send to parent | ||||
| @@ -863,7 +887,6 @@ sub runslp { | ||||
|                         my ($url_ip) = $url =~ /:\/\/(\d+\.\d+\.\d+\.\d+)/; | ||||
|                         if ( ! $::DISCOVERED_HOST{$url_ip}) | ||||
|                         { | ||||
|                             send_msg( $request, 0, "Received SLP response from $url_ip.");  | ||||
|                             $::DISCOVERED_HOST{$url_ip} = 1; | ||||
|                         } | ||||
|                         if ( $verbose ) { | ||||
| @@ -1084,11 +1107,16 @@ sub gethost_from_url { | ||||
|  | ||||
|     my $request = shift; | ||||
|     my $url     = shift; | ||||
|     my $type    = shift; | ||||
|     my $mtm     = shift; | ||||
|     my $sn      = shift; | ||||
|     my $iplist  = shift; | ||||
|  | ||||
|     ####################################### | ||||
|     # Extract IP from URL | ||||
|     ####################################### | ||||
|     my $ip = getip_from_url( $request, $url ); | ||||
|     my $nets = xCAT::Utils::my_nets(); | ||||
|     my $ip = getip_from_iplist( $iplist, $nets, $opt{i}); | ||||
|     if ( !defined( $ip )) { | ||||
|         return undef; | ||||
|     } | ||||
| @@ -1105,7 +1133,7 @@ sub gethost_from_url { | ||||
|     ####################################### | ||||
|     # Read host from hosts table | ||||
|     ####################################### | ||||
|     if ( ! %::HOST_TAB_CATCH) | ||||
|     if ( ! %::HOST_TAB_CACHE) | ||||
|     { | ||||
|         my $hosttab  = xCAT::Table->new( 'hosts' ); | ||||
|         my @entries = $hosttab->getAllNodeAttribs(['node','ip']); | ||||
| @@ -1114,13 +1142,13 @@ sub gethost_from_url { | ||||
|         { | ||||
|             if ( defined $entry->{ 'ip'}) | ||||
|             { | ||||
|                 $::HOST_TAB_CATCH{$entry->{ 'ip'}} = $entry->{ 'node'}; | ||||
|                 $::HOST_TAB_CACHE{$entry->{ 'ip'}} = $entry->{ 'node'}; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     if ( exists $::HOST_TAB_CATCH{ $ip}) | ||||
|     if ( exists $::HOST_TAB_CACHE{ $ip}) | ||||
|     { | ||||
|         return $::HOST_TAB_CATCH{ $ip}; | ||||
|         return $::HOST_TAB_CACHE{ $ip} ."($ip)"; | ||||
|     } | ||||
|  | ||||
|     ############################################################### | ||||
| @@ -1130,7 +1158,8 @@ sub gethost_from_url { | ||||
|     if ( !$host or $! ) { | ||||
| #Tentative solution | ||||
| return undef if ($opt{H}); | ||||
|         return( $ip ); | ||||
|         $host = getFactoryHostname($type,$mtm,$sn); | ||||
| #return( $ip ); | ||||
|     } | ||||
|     ####################################### | ||||
|     # Convert hostname to short-hostname | ||||
| @@ -1138,19 +1167,68 @@ return undef if ($opt{H}); | ||||
|     if ( $host =~ /([^\.]+)\./ ) { | ||||
|         $host = $1; | ||||
|     } | ||||
|     return( $host ); | ||||
|     return( "$host($ip)" ); | ||||
|  | ||||
|     ########################################### | ||||
|     #  Otherwise, URL is not in IP format | ||||
|     ########################################### | ||||
|     if ( !($url =~ /service:.*:\/\/(.*)/  )) { | ||||
|         if ( $verbose ) { | ||||
|             trace( $request, "Invalid URL: $_[0]" ); | ||||
|         } | ||||
|         return undef; | ||||
| #    ########################################### | ||||
| #    #  Otherwise, URL is not in IP format | ||||
| #    ########################################### | ||||
| #    if ( !($url =~ /service:.*:\/\/(.*)/  )) { | ||||
| #        if ( $verbose ) { | ||||
| #            trace( $request, "Invalid URL: $_[0]" ); | ||||
| #        } | ||||
| #        return undef; | ||||
| #    } | ||||
| #    return( $1 ); | ||||
|  | ||||
| } | ||||
|  | ||||
| sub getFactoryHostname | ||||
| { | ||||
|     my $type = shift; | ||||
|     my $mtm  = shift; | ||||
|     my $sn   = shift; | ||||
|  | ||||
|     if ( $type eq SERVICE_FSP) | ||||
|     { | ||||
|         return "Server-$mtm-SN$sn"; | ||||
|     } | ||||
|     return( $1 ); | ||||
|     else | ||||
|     { | ||||
|         return "$mtm*$sn"; | ||||
|     } | ||||
| } | ||||
|  | ||||
| ########################################################################## | ||||
| # Get correct IP from ip list in SLP Attr | ||||
| ########################################################################## | ||||
| sub getip_from_iplist | ||||
| { | ||||
|     my $iplist  = shift; | ||||
|     my $nets    = shift; | ||||
|     my $inc     = shift; | ||||
|      | ||||
|     my @ips = split /,/, $iplist; | ||||
|     if ( $inc) | ||||
|     { | ||||
|         for my $net (keys %$nets) | ||||
|         { | ||||
|             delete $nets->{$net} if ( $nets->{$net} ne $inc); | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     for my $ip (@ips) | ||||
|     { | ||||
|         for my $net ( keys %$nets) | ||||
|         { | ||||
|             my ($n,$m) = split /\//,$net; | ||||
|             if ( xCAT::Utils::isInSameSubnet( $n, $ip, $m, 1) and | ||||
|                  xCAT::Utils::isPingable( $ip)) | ||||
|             { | ||||
|                 return $ip; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     return undef; | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -1290,10 +1368,21 @@ sub parse_responses { | ||||
|             unless ( $rsp =~ /\($_=([^\)]+)/ ) { | ||||
|                 if ( $verbose ) { | ||||
|                     trace( $request, "Attribute not found: [$_]->($rsp)" ); | ||||
|                 } | ||||
|                 }  | ||||
|                 next;  | ||||
|             }  | ||||
|             push @result, $1;  | ||||
|         } | ||||
|  | ||||
|         ########################################### | ||||
|         # Get host directly from URL | ||||
|         ########################################### | ||||
|         if ( $type eq SERVICE_HMC or $type eq SERVICE_BPA  | ||||
|                 or $type eq SERVICE_FSP) { | ||||
|             $host = gethost_from_url( $request, $1, @result); | ||||
|             if ( !defined( $host )) { | ||||
|                 next; | ||||
|             } | ||||
|             push @result, $1; | ||||
|         } | ||||
|         ########################################### | ||||
|         # Use the IP/Hostname contained in the URL | ||||
| @@ -1304,7 +1393,8 @@ sub parse_responses { | ||||
|         # that instead of the URL. | ||||
|         # | ||||
|         ########################################### | ||||
|         if (( $type eq SERVICE_HMC ) or ( $type eq SERVICE_IVM )) { | ||||
|         if (!$host and (( $type eq SERVICE_HMC ) or ( $type eq SERVICE_IVM ) | ||||
|             or ( $type eq SERVICE_BPA) )) { | ||||
|             if ( $rsp =~ /\(name=([^\)]+)/ ) { | ||||
|                 $host = $1; | ||||
|  | ||||
| @@ -1331,7 +1421,7 @@ sub parse_responses { | ||||
|         ########################################### | ||||
|         # If MM, use the discovered host | ||||
|         ########################################### | ||||
|         if (( $type eq SERVICE_MM ) and ( defined( $mm ))) { | ||||
|         if (!$host and ( $type eq SERVICE_MM ) and ( defined( $mm ))) { | ||||
|             my $ip = getip_from_url( $request, $1 ); | ||||
|  | ||||
|             if ( defined( $ip )) { | ||||
| @@ -1341,17 +1431,8 @@ sub parse_responses { | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         ########################################### | ||||
|         # Get host directly from URL | ||||
|         ########################################### | ||||
|         if ( !defined($host) ) { | ||||
|             $host = gethost_from_url( $request, $1 ); | ||||
|             if ( !defined( $host )) { | ||||
|                 next; | ||||
|             } | ||||
|         } | ||||
|         push @result, $host; | ||||
|  | ||||
|         push @result, $host; | ||||
|         ################################### | ||||
|         # Strip off trailing ",lifetime" | ||||
|         ################################### | ||||
| @@ -1383,6 +1464,43 @@ sub parse_responses { | ||||
|     return( \%outhash ); | ||||
| } | ||||
|  | ||||
| ########################################################################## | ||||
| # Update /etc/hosts | ||||
| ########################################################################## | ||||
| sub updateEtcHosts | ||||
| { | ||||
|     my $host_ip = shift; | ||||
|     my $fname = "/etc/hosts"; | ||||
|     unless ( open( HOSTS,"<$fname" )) { | ||||
|         return undef; | ||||
|     } | ||||
|     my @rawdata = <HOSTS>; | ||||
|     close( HOSTS ); | ||||
|  | ||||
|     ###################################### | ||||
|     # Remove old entry | ||||
|     ###################################### | ||||
|     foreach my $host ( keys %$host_ip) { | ||||
|         my $ip = $host_ip->{ $host}; | ||||
|         foreach ( @rawdata ) { | ||||
|             if ( /^#/ or /^\s*\n$/ ) { | ||||
|                 next; | ||||
|             } elsif ( /\s+$host\s+$/ ) { | ||||
|                 s/$_//; | ||||
|             } | ||||
|         } | ||||
|         push @rawdata,"$ip\t$host\n"; | ||||
|     } | ||||
|     ###################################### | ||||
|     # Rewrite file | ||||
|     ###################################### | ||||
|     unless ( open( HOSTS,">$fname" )) { | ||||
|         return undef; | ||||
|     } | ||||
|     print HOSTS @rawdata; | ||||
|     close( HOSTS ); | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
|  | ||||
| ########################################################################## | ||||
| @@ -1394,6 +1512,7 @@ sub xCATdB { | ||||
|     my %keyhash = (); | ||||
|     my %updates = (); | ||||
|     my %sn_node = (); | ||||
|     my %host_ip = (); | ||||
|     ############################ | ||||
|     # Cache vpd table | ||||
|     ############################ | ||||
| @@ -1414,12 +1533,20 @@ sub xCATdB { | ||||
|     foreach ( keys %$outhash ) { | ||||
|         my $data = $outhash->{$_}; | ||||
|         my $type = @$data[0]; | ||||
|         my $nameips = @$data[4]; | ||||
|         my ($name,$ips); | ||||
|         if ( $nameips =~ /^([^\(]+)\(([^\)]+)\)$/) | ||||
|         { | ||||
|             $name = $1; | ||||
|             $ips  = $2; | ||||
|             $host_ip{$name} = $ips; | ||||
|         } | ||||
|  | ||||
|         if ( $type =~ /^BPA$/ ) { | ||||
|             my $model  = @$data[1]; | ||||
|             my $serial = @$data[2]; | ||||
|             my $ips    = @$data[3]; | ||||
|             my $name   = @$data[4]; | ||||
|             $ips    = @$data[3] if ( !$ips); | ||||
|             $name   = @$data[4] if ( !$name); | ||||
|             my $id     = @$data[6]; | ||||
|  | ||||
|             #################################### | ||||
| @@ -1442,8 +1569,8 @@ sub xCATdB { | ||||
|             my $frame      = ""; | ||||
|             my $model      = @$data[1]; | ||||
|             my $serial     = @$data[2]; | ||||
|             my $ips        = @$data[3]; | ||||
|             my $name       = @$data[4]; | ||||
|             $ips        = @$data[3] if ( !$ips); | ||||
|             $name       = @$data[4] if ( !$name); | ||||
|             my $bpc_model  = @$data[6]; | ||||
|             my $bpc_serial = @$data[7]; | ||||
|             my $cageid     = @$data[8]; | ||||
| @@ -1495,6 +1622,7 @@ sub xCATdB { | ||||
|             xCAT::PPCdb::add_systemX( $type, $data ); | ||||
|         } | ||||
|     } | ||||
|     updateEtcHosts(\%host_ip); | ||||
| } | ||||
|  | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user