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:
zhanx 2009-07-23 20:02:39 +00:00
parent 46b4d61fde
commit a574da32af
2 changed files with 340 additions and 38 deletions

View File

@ -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;

View File

@ -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);
}