1219820Sjeff#!/usr/bin/perl 2219820Sjeff# 3219820Sjeff# Copyright (c) 2007-2008 Voltaire, Inc. All rights reserved. 4219820Sjeff# Copyright (c) 2006 The Regents of the University of California. 5219820Sjeff# 6219820Sjeff# This software is available to you under a choice of one of two 7219820Sjeff# licenses. You may choose to be licensed under the terms of the GNU 8219820Sjeff# General Public License (GPL) Version 2, available from the file 9219820Sjeff# COPYING in the main directory of this source tree, or the 10219820Sjeff# OpenIB.org BSD license below: 11219820Sjeff# 12219820Sjeff# Redistribution and use in source and binary forms, with or 13219820Sjeff# without modification, are permitted provided that the following 14219820Sjeff# conditions are met: 15219820Sjeff# 16219820Sjeff# - Redistributions of source code must retain the above 17219820Sjeff# copyright notice, this list of conditions and the following 18219820Sjeff# disclaimer. 19219820Sjeff# 20219820Sjeff# - Redistributions in binary form must reproduce the above 21219820Sjeff# copyright notice, this list of conditions and the following 22219820Sjeff# disclaimer in the documentation and/or other materials 23219820Sjeff# provided with the distribution. 24219820Sjeff# 25219820Sjeff# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26219820Sjeff# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 27219820Sjeff# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 28219820Sjeff# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 29219820Sjeff# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 30219820Sjeff# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 31219820Sjeff# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 32219820Sjeff# SOFTWARE. 33219820Sjeff# 34219820Sjeff 35219820Sjeffuse strict; 36219820Sjeff 37219820Sjeffuse Getopt::Std; 38219820Sjeffuse IBswcountlimits; 39219820Sjeff 40219820Sjeffsub usage_and_exit 41219820Sjeff{ 42219820Sjeff my $prog = $_[0]; 43219820Sjeff print "Usage: $prog [-Rh]\n"; 44219820Sjeff print 45219820Sjeff" Validate LIDs and GUIDs (check for zero and duplicates) in the local subnet\n"; 46219820Sjeff print " -h This help message\n"; 47219820Sjeff print 48219820Sjeff" -R Recalculate ibnetdiscover information (Default is to reuse ibnetdiscover output)\n"; 49219820Sjeff exit 2; 50219820Sjeff} 51219820Sjeff 52219820Sjeffmy $argv0 = `basename $0`; 53219820Sjeffmy $regenerate_map = undef; 54219820Sjeff 55219820Sjeffchomp $argv0; 56219820Sjeffif (!getopts("hR")) { usage_and_exit $argv0; } 57219820Sjeffif (defined $Getopt::Std::opt_h) { usage_and_exit $argv0; } 58219820Sjeffif (defined $Getopt::Std::opt_R) { $regenerate_map = $Getopt::Std::opt_R; } 59219820Sjeff 60219820Sjeffsub validate_non_zero_lid 61219820Sjeff{ 62219820Sjeff my ($lid) = shift(@_); 63219820Sjeff my ($nodeguid) = shift(@_); 64219820Sjeff my ($nodetype) = shift(@_); 65219820Sjeff 66219820Sjeff if ($lid eq 0) { 67219820Sjeff print "LID 0 found for $nodetype NodeGUID $nodeguid\n"; 68219820Sjeff return 1; 69219820Sjeff } 70219820Sjeff return 0; 71219820Sjeff} 72219820Sjeff 73219820Sjeffsub validate_non_zero_guid 74219820Sjeff{ 75219820Sjeff my ($lid) = shift(@_); 76219820Sjeff my ($guid) = shift(@_); 77219820Sjeff my ($nodetype) = shift(@_); 78219820Sjeff 79219820Sjeff if ($guid eq 0x0) { 80219820Sjeff print "$nodetype GUID 0x0 found with LID $lid\n"; 81219820Sjeff return 1; 82219820Sjeff } 83219820Sjeff return 0; 84219820Sjeff} 85219820Sjeff 86219820Sjeff$insert_lid::lids = undef; 87219820Sjeff$insert_nodeguid::nodeguids = undef; 88219820Sjeff$insert_portguid::portguids = undef; 89219820Sjeff 90219820Sjeffsub insert_lid 91219820Sjeff{ 92219820Sjeff my ($lid) = shift(@_); 93219820Sjeff my ($nodeguid) = shift(@_); 94219820Sjeff my ($nodetype) = shift(@_); 95219820Sjeff my $rec = undef; 96219820Sjeff my $status = ""; 97219820Sjeff 98219820Sjeff $status = validate_non_zero_lid($lid, $nodeguid, $nodetype); 99219820Sjeff if ($status eq 0) { 100219820Sjeff if (defined($insert_lid::lids{$lid})) { 101219820Sjeff print 102219820Sjeff"LID $lid already defined for NodeGUID $insert_lid::lids{$lid}->{nodeguid}\n"; 103219820Sjeff } else { 104219820Sjeff $rec = {lid => $lid, nodeguid => $nodeguid}; 105219820Sjeff $insert_lid::lids{$lid} = $rec; 106219820Sjeff } 107219820Sjeff } 108219820Sjeff} 109219820Sjeff 110219820Sjeffsub insert_nodeguid 111219820Sjeff{ 112219820Sjeff my ($lid) = shift(@_); 113219820Sjeff my ($nodeguid) = shift(@_); 114219820Sjeff my ($nodetype) = shift(@_); 115219820Sjeff my $rec = undef; 116219820Sjeff my $status = ""; 117219820Sjeff 118219820Sjeff $status = validate_non_zero_guid($lid, $nodeguid, $nodetype); 119219820Sjeff if ($status eq 0) { 120219820Sjeff if (defined($insert_nodeguid::nodeguids{$nodeguid})) { 121219820Sjeff print 122219820Sjeff"NodeGUID $nodeguid already defined for LID $insert_nodeguid::nodeguids{$nodeguid}->{lid}\n"; 123219820Sjeff } else { 124219820Sjeff $rec = {lid => $lid, nodeguid => $nodeguid}; 125219820Sjeff $insert_nodeguid::nodeguids{$nodeguid} = $rec; 126219820Sjeff } 127219820Sjeff } 128219820Sjeff} 129219820Sjeff 130219820Sjeffsub validate_portguid 131219820Sjeff{ 132219820Sjeff my ($portguid) = shift(@_); 133219820Sjeff my ($firstport) = shift(@_); 134219820Sjeff 135219820Sjeff if (defined($insert_nodeguid::nodeguids{$portguid}) 136219820Sjeff && ($firstport ne "yes")) 137219820Sjeff { 138219820Sjeff print "PortGUID $portguid is invalid duplicate of a NodeGUID\n"; 139219820Sjeff } 140219820Sjeff} 141219820Sjeff 142219820Sjeffsub insert_portguid 143219820Sjeff{ 144219820Sjeff my ($lid) = shift(@_); 145219820Sjeff my ($portguid) = shift(@_); 146219820Sjeff my ($nodetype) = shift(@_); 147219820Sjeff my ($firstport) = shift(@_); 148219820Sjeff my $rec = undef; 149219820Sjeff my $status = ""; 150219820Sjeff 151219820Sjeff $status = validate_non_zero_guid($lid, $portguid, $nodetype); 152219820Sjeff if ($status eq 0) { 153219820Sjeff if (defined($insert_portguid::portguids{$portguid})) { 154219820Sjeff print 155219820Sjeff"PortGUID $portguid already defined for LID $insert_portguid::portguids{$portguid}->{lid}\n"; 156219820Sjeff } else { 157219820Sjeff $rec = {lid => $lid, portguid => $portguid}; 158219820Sjeff $insert_portguid::portguids{$portguid} = $rec; 159219820Sjeff validate_portguid($portguid, $firstport); 160219820Sjeff } 161219820Sjeff } 162219820Sjeff} 163219820Sjeff 164219820Sjeffsub main 165219820Sjeff{ 166219820Sjeff if ($regenerate_map 167219820Sjeff || !(-f "$IBswcountlimits::cache_dir/ibnetdiscover.topology")) 168219820Sjeff { 169219820Sjeff generate_ibnetdiscover_topology; 170219820Sjeff } 171219820Sjeff 172219820Sjeff open IBNET_TOPO, "<$IBswcountlimits::cache_dir/ibnetdiscover.topology" 173219820Sjeff or die "Failed to open ibnet topology: $!\n"; 174219820Sjeff 175219820Sjeff my $nodetype = ""; 176219820Sjeff my $nodeguid = ""; 177219820Sjeff my $portguid = ""; 178219820Sjeff my $lid = ""; 179219820Sjeff my $line = ""; 180219820Sjeff my $firstport = ""; 181219820Sjeff 182219820Sjeff while ($line = <IBNET_TOPO>) { 183219820Sjeff 184219820Sjeff if ($line =~ /^caguid=(.*)/ || $line =~ /^rtguid=(.*)/) { 185219820Sjeff $nodeguid = $1; 186219820Sjeff $nodetype = ""; 187219820Sjeff } 188219820Sjeff 189219820Sjeff if ($line =~ /^switchguid=(.*)/) { 190219820Sjeff $nodeguid = $1; 191219820Sjeff $portguid = ""; 192219820Sjeff $nodetype = ""; 193219820Sjeff } 194219820Sjeff if ($line =~ /^switchguid=(.*)\((.*)\)/) { 195219820Sjeff $nodeguid = $1; 196219820Sjeff $portguid = "0x" . $2; 197219820Sjeff } 198219820Sjeff 199219820Sjeff if ($line =~ /^Switch.*\"S-(.*)\"\s+# (.*) port.* lid (\d+) .*/) { 200219820Sjeff $nodetype = "switch"; 201219820Sjeff $firstport = "yes"; 202219820Sjeff $lid = $3; 203219820Sjeff insert_lid($lid, $nodeguid, $nodetype); 204219820Sjeff insert_nodeguid($lid, $nodeguid, $nodetype); 205219820Sjeff if ($portguid ne "") { 206219820Sjeff insert_portguid($lid, $portguid, $nodetype, $firstport); 207219820Sjeff } 208219820Sjeff } 209219820Sjeff if ($line =~ /^Ca.*/) { 210219820Sjeff $nodetype = "ca"; 211219820Sjeff $firstport = "yes"; 212219820Sjeff } 213219820Sjeff if ($line =~ /^Rt.*/) { 214219820Sjeff $nodetype = "router"; 215219820Sjeff $firstport = "yes"; 216219820Sjeff } 217219820Sjeff 218219820Sjeff if ($nodetype eq "ca" || $nodetype eq "router") { 219219820Sjeff if ($line =~ /"S-(.*)\# lid (\d+) .*/) { 220219820Sjeff $lid = $2; 221219820Sjeff insert_lid($lid, $nodeguid, $nodetype); 222219820Sjeff if ($firstport eq "yes") { 223219820Sjeff insert_nodeguid($lid, $nodeguid, $nodetype); 224219820Sjeff $firstport = "no"; 225219820Sjeff } 226219820Sjeff } 227219820Sjeff if ($line =~ /^.*"H-(.*)\# lid (\d+) .*/) { 228219820Sjeff $lid = $2; 229219820Sjeff insert_lid($lid, $nodeguid, $nodetype); 230219820Sjeff if ($firstport eq "yes") { 231219820Sjeff insert_nodeguid($lid, $nodeguid, $nodetype); 232219820Sjeff $firstport = "no"; 233219820Sjeff } 234219820Sjeff } 235219820Sjeff if ($line =~ /^.*"R-(.*)\# lid (\d+) .*/) { 236219820Sjeff $lid = $2; 237219820Sjeff insert_lid($lid, $nodeguid, $nodetype); 238219820Sjeff if ($firstport eq "yes") { 239219820Sjeff insert_nodeguid($lid, $nodeguid, $nodetype); 240219820Sjeff $firstport = "no"; 241219820Sjeff } 242219820Sjeff } 243219820Sjeff if ($line =~ /^\[(\d+)\]\((.*)\)/) { 244219820Sjeff $portguid = "0x" . $2; 245219820Sjeff insert_portguid($lid, $portguid, $nodetype, $firstport); 246219820Sjeff } 247219820Sjeff } 248219820Sjeff 249219820Sjeff } 250219820Sjeff 251219820Sjeff close IBNET_TOPO; 252219820Sjeff} 253219820Sjeffmain; 254219820Sjeff 255