diff --git a/perl-xCAT/xCAT/MacMap.pm b/perl-xCAT/xCAT/MacMap.pm index e1a7df81f..ab10348e0 100644 --- a/perl-xCAT/xCAT/MacMap.pm +++ b/perl-xCAT/xCAT/MacMap.pm @@ -225,7 +225,7 @@ sub rvlan { my $switchestab = xCAT::Table->new('switches', -create => 0); my @switchesents; if ($switchestab) { - foreach (values %{ $switchestab->getNodesAttribs($switches, [qw(switch snmpversion username password privacy auth)]) }) { + foreach (values %{ $switchestab->getNodesAttribs($switches, [qw(switch snmpversion username password privacy auth switchtype)]) }) { push @switchesents, @$_; } } @@ -309,7 +309,7 @@ sub dump_mac_info { } } my $switchestab = xCAT::Table->new('switches', -create => 0); - my @switchesents = $switchestab->getAllNodeAttribs([qw(switch snmpversion username password privacy auth)]); + my @switchesents = $switchestab->getAllNodeAttribs([qw(switch snmpversion username password privacy auth switchtype)]); $self->fill_switchparms(community => $community, switchesents => \@switchesents); my $switchtab = xCAT::Table->new('switch', -create => 0); my @entries = (); @@ -337,7 +337,12 @@ sub dump_mac_info { if ($self->{show_verbose_info}) { xCAT::MsgUtils->message("I", { data => ["$switch: Attempting to refresh switch information..."] }, $self->{callback}); } + my $probestart = time; $self->refresh_switch(undef, $community, $switch); + my $probestop = time; + my $probeduration = $probestop - $probestart; + xCAT::MsgUtils->message("S", "xcatprobe refresh_switch $switch ElapsedTime:$probeduration sec"); + if ($self->{show_verbose_info}) { xCAT::MsgUtils->message("I", { data => ["$switch: Finished refreshing switch information."] }, $self->{callback}); } @@ -403,7 +408,13 @@ sub find_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; } + + my $runstart = time; $self->refresh_table($discover_switch); #not cached or stale cache, refresh + my $runstop = time; + my $diffduration = $runstop - $runstart; + xCAT::MsgUtils->message("S", "refresh_table ElapsedTime:$diffduration sec"); + if ($self->{mactable}->{ lc($mac) }) { return $self->{mactable}->{ lc($mac) }; } @@ -419,6 +430,7 @@ sub fill_switchparms { foreach (@switchentries) { my $curswitch = $_->{switch}; $self->{switchparmhash}->{$curswitch} = $_; + $self->{switchparmhash}->{$curswitch}->{switchtype}=$_->{switchtype}; if ($_->{snmpversion}) { if ($_->{snmpversion} =~ /3/) { #clean up to accept things like v3 or ver3 or 3, whatever. $self->{switchparmhash}->{$curswitch}->{snmpversion} = 3; @@ -444,7 +456,7 @@ sub refresh_table { $self->{mactable} = {}; $self->{switchtab} = xCAT::Table->new('switch', -create => 1); $self->{switchestab} = xCAT::Table->new('switches', -create => 1); - my @switchentries = $self->{switchestab}->getAllNodeAttribs([qw(switch snmpversion username password privacy auth)]); + my @switchentries = $self->{switchestab}->getAllNodeAttribs([qw(switch snmpversion username password privacy auth switchtype)]); my $community = "public"; #$self->{sitetab} = xCAT::Table->new('site'); @@ -477,6 +489,9 @@ sub refresh_table { unless (defined $_->{password}) { #if no password set, inherit the community $self->{switchparmhash}->{$curswitch}->{password} = $community; } + if (defined $_->{switchtype}){ + $self->{switchparmhash}->{$curswitch}->{switchtype} =$_->{switchtype}; + } } my %checked_pairs; my @entries = $self->{switchtab}->getAllNodeAttribs([ 'node', 'port', 'switch' ]); @@ -497,7 +512,7 @@ sub refresh_table { my $ntype = $typehash->{$entry->{node}}->[0]->{nodetype}; if ( (($discover_switch) and ( $ntype ne "switch")) or ( !($discover_switch) and ( $ntype eq "switch")) ){ - xCAT::MsgUtils->message("S", "refresh_table: skip $entry->{node} and $entry->{switch}"); + xCAT::MsgUtils->message("S", "refresh_table: skip $entry->{node} and $entry->{switch}, $discover_switch , $ntype\n"); next; } if (defined($entry->{switch}) and $entry->{switch} ne "" and defined($entry->{port}) and $entry->{port} ne "") { @@ -534,7 +549,11 @@ sub refresh_table { if ($cpid == 0) { close($child); + my $runstart = time; $self->refresh_switch($parent, $community, $entry->{switch}); + my $runstop = time; + my $diffduration = $runstop - $runstart; + xCAT::MsgUtils->message("S", "refresh_switch $entry->{switch} ElapsedTime:$diffduration sec"); exit(0); } close($parent); @@ -615,6 +634,9 @@ sub walkoid { return $retmap; } + + + sub getsnmpsession { #gets an snmp v3 session appropriate for a switch using the switches table for guidance on the hows @@ -688,7 +710,54 @@ sub refresh_switch { my $community = shift; my $switch = shift; - #if ($error) { die $error; } + unless($self->{collect_mac_info}) + { + if($self->{switchparmhash}->{$switch}->{switchtype} eq 'onie'){ + #for cumulus switch, the MAC table can be retrieved with ssh + #which is much faster than snmp + my $mymac; + my $myport; + + my @res=xCAT::Utils->runcmd("ssh -o StrictHostKeyChecking=no -o PasswordAuthentication=no $switch 'bridge fdb show|grep -i -v permanent|tr A-Z a-z 2>/dev/null' 2>/dev/null",-1); + unless (@res) { + xCAT::MsgUtils->message("S", "Failed to get mac table with ssh to $switch, fall back to snmp! To obtain mac table with ssh, please make sure the passwordless root ssh to $switch is available"); + }else{ + foreach (@res){ + if($_ =~ m/^([0-9a-z]{2}:[0-9a-z]{2}:[0-9a-z]{2}:[0-9a-z]{2}:[0-9a-z]{2}:[0-9a-z]{2}) dev swp([0-9]+) .*/){ + $mymac=$1; + $myport=$2; + $myport=sprintf("%d",$myport); + + #try all the possible port number formats + #e.g, "5","swp5","05","swp05" + unless(exists $self->{switches}->{$switch}->{$myport}){ + if(exists $self->{switches}->{$switch}->{"swp".$myport}){ + $myport="swp".$myport; + }else{ + $myport=sprintf("%02d",$myport); + unless(exists $self->{switches}->{$switch}->{$myport}){ + if(exists $self->{switches}->{$switch}->{"swp".$myport}){ + $myport="swp".$myport; + }else{ + $myport=""; + } + } + } + } + + if($myport){ + if($output){ + printf $output "$mymac|%s\n", $self->{switches}->{$switch}->{$myport}; + } + } + } + + } + return; + } + } + } + my $session = $self->getsnmpsession('community' => $community, 'switch' => $switch); unless ($session) { xCAT::MsgUtils->message("S", "Failed to communicate with $switch"); @@ -789,7 +858,6 @@ sub refresh_switch { xCAT::MsgUtils->message("S", "Error communicating with " . $session->{DestHost} . ": failed to get a valid response to BRIDGE-MIB request"); return; } - # my $mactoindexmap = walkoid($session,'.1.3.6.1.2.1.17.4.3.1.2'); my $mactoindexmap = walkoid($session, '.1.3.6.1.2.1.17.7.1.2.2.1.2', silentfail => 1, verbose => $self->{show_verbose_info}, switch => $switch, callback => $self->{callback}); unless (defined($mactoindexmap)) { #if no qbridge defined, try bridge mib, probably cisco @@ -800,7 +868,6 @@ sub refresh_switch { xCAT::MsgUtils->message("S", "Error communicating with " . $session->{DestHost} . ": Unable to get MAC entries via either BRIDGE or Q-BRIDE MIB"); return; } - if (defined($self->{collect_mac_info})) { my %index_to_mac = (); my %index_to_vlan = (); diff --git a/xCAT-server/lib/xcat/plugins/nodediscover.pm b/xCAT-server/lib/xcat/plugins/nodediscover.pm index 9714f3843..b6b78383a 100644 --- a/xCAT-server/lib/xcat/plugins/nodediscover.pm +++ b/xCAT-server/lib/xcat/plugins/nodediscover.pm @@ -477,8 +477,6 @@ sub process_request { print $sock $restartstring; close($sock); - # sleep 2 seconds for genesis to complete the disocvery process - sleep(2); #Update the discoverydata table to indicate the successful discovery xCAT::DiscoveryUtils->update_discovery_data($request);