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:
parent
ca89329166
commit
3b2b02b3e1
@ -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)};
|
||||
|
@ -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}) {
|
||||
|
@ -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);
|
||||
|
@ -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});
|
||||
|
@ -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: ".$@);
|
||||
|
Loading…
Reference in New Issue
Block a user