ibfindnodesusing.pl revision 219820
1254885Sdumbbell#!/usr/bin/perl 2254885Sdumbbell# 3254885Sdumbbell# Copyright (C) 2001-2003 The Regents of the University of California. 4254885Sdumbbell# Copyright (c) 2006 The Regents of the University of California. 5254885Sdumbbell# Copyright (c) 2007-2008 Voltaire, Inc. All rights reserved. 6254885Sdumbbell# 7254885Sdumbbell# Produced at Lawrence Livermore National Laboratory. 8254885Sdumbbell# Written by Ira Weiny <weiny2@llnl.gov> 9254885Sdumbbell# Jim Garlick <garlick@llnl.gov> 10254885Sdumbbell# Albert Chu <chu11@llnl.gov> 11254885Sdumbbell# 12254885Sdumbbell# This software is available to you under a choice of one of two 13254885Sdumbbell# licenses. You may choose to be licensed under the terms of the GNU 14254885Sdumbbell# General Public License (GPL) Version 2, available from the file 15254885Sdumbbell# COPYING in the main directory of this source tree, or the 16254885Sdumbbell# OpenIB.org BSD license below: 17254885Sdumbbell# 18254885Sdumbbell# Redistribution and use in source and binary forms, with or 19254885Sdumbbell# without modification, are permitted provided that the following 20254885Sdumbbell# conditions are met: 21254885Sdumbbell# 22254885Sdumbbell# - Redistributions of source code must retain the above 23254885Sdumbbell# copyright notice, this list of conditions and the following 24254885Sdumbbell# disclaimer. 25254885Sdumbbell# 26254885Sdumbbell# - Redistributions in binary form must reproduce the above 27254885Sdumbbell# copyright notice, this list of conditions and the following 28254885Sdumbbell# disclaimer in the documentation and/or other materials 29254885Sdumbbell# provided with the distribution. 30254885Sdumbbell# 31254885Sdumbbell# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 32254885Sdumbbell# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 33254885Sdumbbell# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 34254885Sdumbbell# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 35254885Sdumbbell# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 36254885Sdumbbell# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 37254885Sdumbbell# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 38254885Sdumbbell# SOFTWARE. 39254885Sdumbbell# 40254885Sdumbbell 41254885Sdumbbelluse strict; 42254885Sdumbbell 43254885Sdumbbelluse Getopt::Std; 44254885Sdumbbelluse IBswcountlimits; 45254885Sdumbbellmy $ca_name = ""; 46254885Sdumbbellmy $ca_port = ""; 47254885Sdumbbell 48254885Sdumbbell# ========================================================================= 49254885Sdumbbell# 50254885Sdumbbellsub get_hosts_routed 51254885Sdumbbell{ 52254885Sdumbbell my $sw_guid = $_[0]; 53254885Sdumbbell my $sw_port = $_[1]; 54254885Sdumbbell my @hosts = undef; 55254885Sdumbbell my $extra_params = get_ca_name_port_param_string($ca_name, $ca_port); 56254885Sdumbbell 57254885Sdumbbell if ($sw_guid eq "") { return (@hosts); } 58254885Sdumbbell 59254885Sdumbbell my $data = `ibroute $extra_params -G $sw_guid`; 60254885Sdumbbell my @lines = split("\n", $data); 61254885Sdumbbell foreach my $line (@lines) { 62254885Sdumbbell if ($line =~ /\w+\s+(\d+)\s+:\s+\(Channel Adapter.*:\s+'(.*)'\)/) { 63254885Sdumbbell if ($1 == $sw_port) { 64254885Sdumbbell push @hosts, $2; 65254885Sdumbbell } 66254885Sdumbbell } 67254885Sdumbbell } 68254885Sdumbbell 69254885Sdumbbell return (@hosts); 70254885Sdumbbell} 71254885Sdumbbell 72254885Sdumbbell# ========================================================================= 73254885Sdumbbell# 74254885Sdumbbellsub usage_and_exit 75254885Sdumbbell{ 76254885Sdumbbell my $prog = $_[0]; 77254885Sdumbbell print 78254885Sdumbbell"Usage: $prog [-R -C <ca_name> -P <ca_port>] <switch_guid|switch_name> <port>\n"; 79254885Sdumbbell print " find a list of nodes which are routed through switch:port\n"; 80254885Sdumbbell print " -R Recalculate ibnetdiscover information\n"; 81254885Sdumbbell print " -C <ca_name> use selected Channel Adaptor name for queries\n"; 82254885Sdumbbell print " -P <ca_port> use selected channel adaptor port for queries\n"; 83254885Sdumbbell exit 2; 84254885Sdumbbell} 85254885Sdumbbell 86254885Sdumbbellmy $argv0 = `basename $0`; 87254885Sdumbbellmy $regenerate_map = undef; 88254885Sdumbbellchomp $argv0; 89254885Sdumbbellif (!getopts("hRC:P:")) { usage_and_exit $argv0; } 90254885Sdumbbellif (defined $Getopt::Std::opt_h) { usage_and_exit $argv0; } 91254885Sdumbbellif (defined $Getopt::Std::opt_R) { $regenerate_map = $Getopt::Std::opt_R; } 92254885Sdumbbellif (defined $Getopt::Std::opt_C) { $ca_name = $Getopt::Std::opt_C; } 93254885Sdumbbellif (defined $Getopt::Std::opt_P) { $ca_port = $Getopt::Std::opt_P; } 94254885Sdumbbell 95254885Sdumbbellmy $target_switch = format_guid($ARGV[0]); 96254885Sdumbbellmy $target_port = $ARGV[1]; 97254885Sdumbbell 98254885Sdumbbellget_link_ends($regenerate_map, $ca_name, $ca_port); 99254885Sdumbbell 100254885Sdumbbellif ($target_switch eq "" || $target_port eq "") { 101254885Sdumbbell usage_and_exit $argv0; 102254885Sdumbbell} 103254885Sdumbbell 104254885Sdumbbell# sortn: 105254885Sdumbbell# 106254885Sdumbbell# sort a group of alphanumeric strings by the last group of digits on 107254885Sdumbbell# those strings, if such exists (good for numerically suffixed host lists) 108254885Sdumbbell# 109254885Sdumbbellsub sortn 110254885Sdumbbell{ 111254885Sdumbbell map { $$_[0] } 112254885Sdumbbell sort { ($$a[1] || 0) <=> ($$b[1] || 0) } map { [$_, /(\d*)$/] } @_; 113254885Sdumbbell} 114254885Sdumbbell 115254885Sdumbbell# comp2(): 116254885Sdumbbell# 117254885Sdumbbell# takes a list of names and returns a hash of arrays, indexed by name prefix, 118254885Sdumbbell# each containing a list of numerical ranges describing the initial list. 119254885Sdumbbell# 120254885Sdumbbell# e.g.: %hash = comp2(lx01,lx02,lx03,lx05,dev0,dev1,dev21) 121254885Sdumbbell# will return: 122254885Sdumbbell# $hash{"lx"} = ["01-03", "05"] 123254885Sdumbbell# $hash{"dev"} = ["0-1", "21"] 124254885Sdumbbell# 125254885Sdumbbellsub comp2 126254885Sdumbbell{ 127254885Sdumbbell my (%i) = (); 128254885Sdumbbell my (%s) = (); 129254885Sdumbbell 130254885Sdumbbell # turn off warnings here to avoid perl complaints about 131254885Sdumbbell # uninitialized values for members of %i and %s 132254885Sdumbbell local ($^W) = 0; 133254885Sdumbbell push( 134254885Sdumbbell @{ 135254885Sdumbbell $s{$$_[0]}[ 136254885Sdumbbell ( 137254885Sdumbbell $s{$$_[0]}[$i{$$_[0]}][$#{$s{$$_[0]}[$i{$$_[0]}]}] == 138254885Sdumbbell ($$_[1] - 1) 139254885Sdumbbell ) ? $i{$$_[0]} : ++$i{$$_[0]} 140254885Sdumbbell ] 141254885Sdumbbell }, 142254885Sdumbbell ($$_[1]) 143254885Sdumbbell ) for map { [/(.*?)(\d*)$/] } sortn(@_); 144254885Sdumbbell 145254885Sdumbbell for my $key (keys %s) { 146254885Sdumbbell @{$s{$key}} = 147254885Sdumbbell map { $#$_ > 0 ? "$$_[0]-$$_[$#$_]" : @{$_} } @{$s{$key}}; 148254885Sdumbbell } 149254885Sdumbbell 150254885Sdumbbell return %s; 151254885Sdumbbell} 152254885Sdumbbell 153254885Sdumbbellsub compress_hostlist 154254885Sdumbbell{ 155254885Sdumbbell my %rng = comp2(@_); 156254885Sdumbbell my @list = (); 157254885Sdumbbell 158254885Sdumbbell local $" = ","; 159254885Sdumbbell 160254885Sdumbbell foreach my $k (keys %rng) { 161254885Sdumbbell @{$rng{$k}} = map { "$k$_" } @{$rng{$k}}; 162254885Sdumbbell } 163254885Sdumbbell @list = map { @{$rng{$_}} } sort keys %rng; 164254885Sdumbbell return "@list"; 165254885Sdumbbell} 166254885Sdumbbell 167254885Sdumbbell# ========================================================================= 168254885Sdumbbell# 169254885Sdumbbellsub main 170254885Sdumbbell{ 171254885Sdumbbell my $found_switch = undef; 172254885Sdumbbell my $cache_file = get_cache_file($ca_name, $ca_port); 173254885Sdumbbell open IBNET_TOPO, "<$cache_file" or die "Failed to open ibnet topology\n"; 174254885Sdumbbell my $in_switch = "no"; 175254885Sdumbbell my $switch_guid = ""; 176254885Sdumbbell my $desc = undef; 177254885Sdumbbell my %ports = undef; 178254885Sdumbbell while (my $line = <IBNET_TOPO>) { 179254885Sdumbbell 180254885Sdumbbell if ($line =~ /^Switch.*\"S-(.*)\"\s+# (.*) port.*/) { 181254885Sdumbbell $switch_guid = $1; 182254885Sdumbbell $desc = $2; 183254885Sdumbbell if ("0x$switch_guid" eq $target_switch 184254885Sdumbbell || $desc =~ /.*$target_switch\s+.*/) 185254885Sdumbbell { 186254885Sdumbbell $found_switch = "yes"; 187 goto FOUND; 188 } 189 } 190 if ($line =~ /^Ca.*/ || $line =~ /^Rt.*/) { $in_switch = "no"; } 191 192 if ($line =~ /^\[(\d+)\].*/ && $in_switch eq "yes") { 193 $ports{$1} = $line; 194 } 195 196 } 197 198 FOUND: 199 close IBNET_TOPO; 200 if (!$found_switch) { 201 print "Switch \"$target_switch\" not found\n"; 202 print " Try running with the \"-R\" or \"-P\" option.\n"; 203 exit 1; 204 } 205 206 $switch_guid = "0x$switch_guid"; 207 208 my $hr = $IBswcountlimits::link_ends{$switch_guid}{$target_port}; 209 my $rem_sw_guid = $hr->{rem_guid}; 210 my $rem_sw_port = $hr->{rem_port}; 211 my $rem_sw_desc = $hr->{rem_desc}; 212 213 my @hosts = undef; 214 @hosts = get_hosts_routed($switch_guid, $target_port); 215 216 my $hosts = compress_hostlist(@hosts); 217 @hosts = split ",", $hosts; 218 print 219"$switch_guid $target_port ($desc) ==>> $rem_sw_guid $rem_sw_port ($rem_sw_desc)\n"; 220 print "@hosts\n\n"; 221 222 @hosts = get_hosts_routed($rem_sw_guid, $rem_sw_port); 223 224 $hosts = compress_hostlist(@hosts); 225 @hosts = split ",", $hosts; 226 print 227"$switch_guid $target_port ($desc) <<== $rem_sw_guid $rem_sw_port ($rem_sw_desc)\n"; 228 print "@hosts\n"; 229} 230main 231 232