Improve performance of discovery process

-Pull UDP queue in to remove duplicates
-Query all caches before slow refresh activities
-Decrease timeout on nodediscover notification
-Switch now only bothers refreshing a cache older than 20 seconds


git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@249 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
This commit is contained in:
jbjohnso 2008-01-11 20:55:28 +00:00
parent ca89329166
commit 3b2b02b3e1
5 changed files with 42 additions and 9 deletions

View File

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

View File

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

View File

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

View File

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

View File

@ -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: ".$@);