diff --git a/perl-xCAT-2.0/xCAT/MacMap.pm b/perl-xCAT-2.0/xCAT/MacMap.pm index aecfbe099..33e28a2cc 100755 --- a/perl-xCAT-2.0/xCAT/MacMap.pm +++ b/perl-xCAT-2.0/xCAT/MacMap.pm @@ -84,6 +84,7 @@ sub find_mac { # and returns undef if unable to find the node, and the nodename otherwise my $self = shift; my $mac = shift; + my $cachedonly = shift; # For now HARDCODE (TODO, configurable?) a cache as stale after five minutes # Also, if things are changed in the config, our cache could be wrong, # invalidate on switch table write? @@ -91,12 +92,16 @@ sub find_mac { my $reftbl = 0; foreach (keys %{$self->{mactable}}) { if ((lc($mac) ne $_) and ($self->{mactable}->{lc($mac)} eq $self->{mactable}->{$_})) { - $reftbl = 1; - #The cache indicates confusion, flush it.. + #$reftbl = 1; + #Delete *possibly* stale data, without being heavy handed.. + delete $self->{mactable}->{$_}; } } unless ($reftbl) { return $self->{mactable}->{lc($mac)};} } + #If requesting a cache only check or the cache is a mere 20 seconds old + #don't bother querying switches + if ($cachedonly or ($self->{timestamp} > (time() - 20))) { return undef; } $self->refresh_table; #not cached or stale cache, refresh if ($self->{mactable}->{lc($mac)}) { return $self->{mactable}->{lc($mac)}; diff --git a/xCAT-server-2.0/lib/xcat/plugins/blade.pm b/xCAT-server-2.0/lib/xcat/plugins/blade.pm index 4f21c2f0c..27a664696 100644 --- a/xCAT-server-2.0/lib/xcat/plugins/blade.pm +++ b/xCAT-server-2.0/lib/xcat/plugins/blade.pm @@ -884,7 +884,8 @@ sub process_request { } unless ($mac) { return }; - unless ($macmap{$mac}) { + #Only refresh the the cache when the request permits and no useful answer + unless ($request->{cacheonly}->[0] or $macmap{$mac}) { process_request(\%invreq,\&fillresps); } unless ($macmap{$mac}) { diff --git a/xCAT-server-2.0/lib/xcat/plugins/nodediscover.pm b/xCAT-server-2.0/lib/xcat/plugins/nodediscover.pm index 7885ca65b..ca89877b5 100644 --- a/xCAT-server-2.0/lib/xcat/plugins/nodediscover.pm +++ b/xCAT-server-2.0/lib/xcat/plugins/nodediscover.pm @@ -53,9 +53,10 @@ sub process_request { #now, notify the node to continue life my $sock = new IO::Socket::INET ( PeerAddr => $ip, - PeerPort => '3001', - Proto => 'tcp' - ); + PeerPort => '3001', + Timeout => '1', + Proto => 'tcp' + ); unless ($sock) { syslog("err","Failed to notify $ip that it's actually $node."); return; } #Give up if the node won't hear of it. print $sock "restart"; close($sock); diff --git a/xCAT-server-2.0/lib/xcat/plugins/switch.pm b/xCAT-server-2.0/lib/xcat/plugins/switch.pm index 5b8fc2ead..8c64d8da6 100644 --- a/xCAT-server-2.0/lib/xcat/plugins/switch.pm +++ b/xCAT-server-2.0/lib/xcat/plugins/switch.pm @@ -31,7 +31,7 @@ sub process_request { unless ($mac) { return; } - my $node = $macmap->find_mac($mac); + my $node = $macmap->find_mac($mac,$req->{cacheonly}->[0]); if ($node) { my $mactab = xCAT::Table->new('mac',-create=>1); $mactab->setNodeAttribs($node,{mac=>$mac}); diff --git a/xCAT-server-2.0/sbin/xcatd b/xCAT-server-2.0/sbin/xcatd index bf532a827..152455af6 100755 --- a/xCAT-server-2.0/sbin/xcatd +++ b/xCAT-server-2.0/sbin/xcatd @@ -180,6 +180,7 @@ sub do_udp_service { #This function opens up a UDP port #Could be used for heartbeating and such as desired my $socket; + my $select = new IO::Select; if (xCAT::Utils->isLinux()) { $socket = IO::Socket::INET6->new(LocalPort => $port, Proto => 'udp', @@ -190,6 +191,7 @@ if (xCAT::Utils->isLinux()) { Domain => AF_INET); } + $select->add($socket); openlog("xCAT UDP",'','local4'); unless ($socket) { syslog("err","xCAT UDP service unable to open port $port: $!"); @@ -201,9 +203,19 @@ if (xCAT::Utils->isLinux()) { my $sport; my $client; my $peerhost; + my %packets; until ($quit) { - eval { while ($part = $socket->recv($data,1500)) { - ($sport,$client) = sockaddr_in($part); + eval { + while (1) { + until ($select->can_read(5)) {} #Wait for data + while ($select->can_read(0)) { #Pull all buffer data that can be pulled + $part = $socket->recv($data,1500); + ($sport,$client) = sockaddr_in($part); + $packets{inet_ntoa($client)} = [$part,$data]; + } + foreach my $pkey (keys %packets) { + ($sport,$client) = sockaddr_in($packets{$pkey}->[0]); + $data=$packets{$pkey}->[1]; $peerhost=gethostbyaddr($client,AF_INET)."\n"; my $req = eval { XMLin($data, SuppressEmpty=>undef,ForceArray=>1) }; if ($req and $req->{command} and ($req->{command}->[0] eq "findme")) { @@ -211,11 +223,25 @@ if (xCAT::Utils->isLinux()) { $req->{'!xcat_clientip'}=inet_ntoa($client); $req->{'!xcat_clientport'}=$sport; if (defined($cmd_handlers{"findme"})) { + $req->{cacheonly}->[0] = 1; plugin_command($req,undef,\&convey_response); + if ($req->{cacheonly}->[0]) { + delete $req->{cacheonly}; + plugin_command($req,undef,\&convey_response); + } } } if ($quit) { last; } + while ($select->can_read(0)) { #grab any incoming requests during run + $part = $socket->recv($data,1500); + ($sport,$client) = sockaddr_in($part); + $packets{inet_ntoa($client)} = [$part,$data]; + } + #Some of those 'future' packets might be stale dupes of this packet, so... + delete $packets{$pkey}; #Delete any duplicates of current packet } + if ($quit) { last; } + } }; if ($@) { syslog("local4|err","xcatd: possible BUG encountered by xCAT UDP service: ".$@);