1#!/usr/bin/perl 2# 3# Copyright (c) 2007-2008 Voltaire, Inc. All rights reserved. 4# Copyright (c) 2006 The Regents of the University of California. 5# 6# This software is available to you under a choice of one of two 7# licenses. You may choose to be licensed under the terms of the GNU 8# General Public License (GPL) Version 2, available from the file 9# COPYING in the main directory of this source tree, or the 10# OpenIB.org BSD license below: 11# 12# Redistribution and use in source and binary forms, with or 13# without modification, are permitted provided that the following 14# conditions are met: 15# 16# - Redistributions of source code must retain the above 17# copyright notice, this list of conditions and the following 18# disclaimer. 19# 20# - Redistributions in binary form must reproduce the above 21# copyright notice, this list of conditions and the following 22# disclaimer in the documentation and/or other materials 23# provided with the distribution. 24# 25# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 27# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 28# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 29# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 30# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 31# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 32# SOFTWARE. 33# 34 35use strict; 36 37use Getopt::Std; 38use IBswcountlimits; 39 40sub usage_and_exit 41{ 42 my $prog = $_[0]; 43 print "Usage: $prog [-Rh]\n"; 44 print 45" Validate LIDs and GUIDs (check for zero and duplicates) in the local subnet\n"; 46 print " -h This help message\n"; 47 print 48" -R Recalculate ibnetdiscover information (Default is to reuse ibnetdiscover output)\n"; 49 exit 2; 50} 51 52my $argv0 = `basename $0`; 53my $regenerate_map = undef; 54 55chomp $argv0; 56if (!getopts("hR")) { usage_and_exit $argv0; } 57if (defined $Getopt::Std::opt_h) { usage_and_exit $argv0; } 58if (defined $Getopt::Std::opt_R) { $regenerate_map = $Getopt::Std::opt_R; } 59 60sub validate_non_zero_lid 61{ 62 my ($lid) = shift(@_); 63 my ($nodeguid) = shift(@_); 64 my ($nodetype) = shift(@_); 65 66 if ($lid eq 0) { 67 print "LID 0 found for $nodetype NodeGUID $nodeguid\n"; 68 return 1; 69 } 70 return 0; 71} 72 73sub validate_non_zero_guid 74{ 75 my ($lid) = shift(@_); 76 my ($guid) = shift(@_); 77 my ($nodetype) = shift(@_); 78 79 if ($guid eq 0x0) { 80 print "$nodetype GUID 0x0 found with LID $lid\n"; 81 return 1; 82 } 83 return 0; 84} 85 86$insert_lid::lids = undef; 87$insert_nodeguid::nodeguids = undef; 88$insert_portguid::portguids = undef; 89 90sub insert_lid 91{ 92 my ($lid) = shift(@_); 93 my ($nodeguid) = shift(@_); 94 my ($nodetype) = shift(@_); 95 my $rec = undef; 96 my $status = ""; 97 98 $status = validate_non_zero_lid($lid, $nodeguid, $nodetype); 99 if ($status eq 0) { 100 if (defined($insert_lid::lids{$lid})) { 101 print 102"LID $lid already defined for NodeGUID $insert_lid::lids{$lid}->{nodeguid}\n"; 103 } else { 104 $rec = {lid => $lid, nodeguid => $nodeguid}; 105 $insert_lid::lids{$lid} = $rec; 106 } 107 } 108} 109 110sub insert_nodeguid 111{ 112 my ($lid) = shift(@_); 113 my ($nodeguid) = shift(@_); 114 my ($nodetype) = shift(@_); 115 my $rec = undef; 116 my $status = ""; 117 118 $status = validate_non_zero_guid($lid, $nodeguid, $nodetype); 119 if ($status eq 0) { 120 if (defined($insert_nodeguid::nodeguids{$nodeguid})) { 121 print 122"NodeGUID $nodeguid already defined for LID $insert_nodeguid::nodeguids{$nodeguid}->{lid}\n"; 123 } else { 124 $rec = {lid => $lid, nodeguid => $nodeguid}; 125 $insert_nodeguid::nodeguids{$nodeguid} = $rec; 126 } 127 } 128} 129 130sub validate_portguid 131{ 132 my ($portguid) = shift(@_); 133 my ($firstport) = shift(@_); 134 135 if (defined($insert_nodeguid::nodeguids{$portguid}) 136 && ($firstport ne "yes")) 137 { 138 print "PortGUID $portguid is invalid duplicate of a NodeGUID\n"; 139 } 140} 141 142sub insert_portguid 143{ 144 my ($lid) = shift(@_); 145 my ($portguid) = shift(@_); 146 my ($nodetype) = shift(@_); 147 my ($firstport) = shift(@_); 148 my $rec = undef; 149 my $status = ""; 150 151 $status = validate_non_zero_guid($lid, $portguid, $nodetype); 152 if ($status eq 0) { 153 if (defined($insert_portguid::portguids{$portguid})) { 154 print 155"PortGUID $portguid already defined for LID $insert_portguid::portguids{$portguid}->{lid}\n"; 156 } else { 157 $rec = {lid => $lid, portguid => $portguid}; 158 $insert_portguid::portguids{$portguid} = $rec; 159 validate_portguid($portguid, $firstport); 160 } 161 } 162} 163 164sub main 165{ 166 if ($regenerate_map 167 || !(-f "$IBswcountlimits::cache_dir/ibnetdiscover.topology")) 168 { 169 generate_ibnetdiscover_topology; 170 } 171 172 open IBNET_TOPO, "<$IBswcountlimits::cache_dir/ibnetdiscover.topology" 173 or die "Failed to open ibnet topology: $!\n"; 174 175 my $nodetype = ""; 176 my $nodeguid = ""; 177 my $portguid = ""; 178 my $lid = ""; 179 my $line = ""; 180 my $firstport = ""; 181 182 while ($line = <IBNET_TOPO>) { 183 184 if ($line =~ /^caguid=(.*)/ || $line =~ /^rtguid=(.*)/) { 185 $nodeguid = $1; 186 $nodetype = ""; 187 } 188 189 if ($line =~ /^switchguid=(.*)/) { 190 $nodeguid = $1; 191 $portguid = ""; 192 $nodetype = ""; 193 } 194 if ($line =~ /^switchguid=(.*)\((.*)\)/) { 195 $nodeguid = $1; 196 $portguid = "0x" . $2; 197 } 198 199 if ($line =~ /^Switch.*\"S-(.*)\"\s+# (.*) port.* lid (\d+) .*/) { 200 $nodetype = "switch"; 201 $firstport = "yes"; 202 $lid = $3; 203 insert_lid($lid, $nodeguid, $nodetype); 204 insert_nodeguid($lid, $nodeguid, $nodetype); 205 if ($portguid ne "") { 206 insert_portguid($lid, $portguid, $nodetype, $firstport); 207 } 208 } 209 if ($line =~ /^Ca.*/) { 210 $nodetype = "ca"; 211 $firstport = "yes"; 212 } 213 if ($line =~ /^Rt.*/) { 214 $nodetype = "router"; 215 $firstport = "yes"; 216 } 217 218 if ($nodetype eq "ca" || $nodetype eq "router") { 219 if ($line =~ /"S-(.*)\# lid (\d+) .*/) { 220 $lid = $2; 221 insert_lid($lid, $nodeguid, $nodetype); 222 if ($firstport eq "yes") { 223 insert_nodeguid($lid, $nodeguid, $nodetype); 224 $firstport = "no"; 225 } 226 } 227 if ($line =~ /^.*"H-(.*)\# lid (\d+) .*/) { 228 $lid = $2; 229 insert_lid($lid, $nodeguid, $nodetype); 230 if ($firstport eq "yes") { 231 insert_nodeguid($lid, $nodeguid, $nodetype); 232 $firstport = "no"; 233 } 234 } 235 if ($line =~ /^.*"R-(.*)\# lid (\d+) .*/) { 236 $lid = $2; 237 insert_lid($lid, $nodeguid, $nodetype); 238 if ($firstport eq "yes") { 239 insert_nodeguid($lid, $nodeguid, $nodetype); 240 $firstport = "no"; 241 } 242 } 243 if ($line =~ /^\[(\d+)\]\((.*)\)/) { 244 $portguid = "0x" . $2; 245 insert_portguid($lid, $portguid, $nodetype, $firstport); 246 } 247 } 248 249 } 250 251 close IBNET_TOPO; 252} 253main; 254 255