2
0
mirror of https://github.com/xcat2/xcat-core.git synced 2025-05-29 17:23:08 +00:00

switch based node discovery enhancement: 1)obtain mac table from cumulus switch via ssh;2)remove unnecessary sleep 2 after node discovery

This commit is contained in:
immarvin 2017-09-08 03:01:07 -04:00
parent 42db21b269
commit ce8bb55e1d
2 changed files with 74 additions and 9 deletions

View File

@ -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 => ["<INFO>$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 => ["<INFO>$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 = ();

View File

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