1#!/usr/bin/perl
2#
3# Copyright (c) 2006 The Regents of the University of California.
4# Copyright (c) 2007-2008 Voltaire, Inc. All rights reserved.
5#
6# Produced at Lawrence Livermore National Laboratory.
7# Written by Ira Weiny <weiny2@llnl.gov>.
8#
9# This software is available to you under a choice of one of two
10# licenses.  You may choose to be licensed under the terms of the GNU
11# General Public License (GPL) Version 2, available from the file
12# COPYING in the main directory of this source tree, or the
13# OpenIB.org BSD license below:
14#
15#     Redistribution and use in source and binary forms, with or
16#     without modification, are permitted provided that the following
17#     conditions are met:
18#
19#      - Redistributions of source code must retain the above
20#        copyright notice, this list of conditions and the following
21#        disclaimer.
22#
23#      - Redistributions in binary form must reproduce the above
24#        copyright notice, this list of conditions and the following
25#        disclaimer in the documentation and/or other materials
26#        provided with the distribution.
27#
28# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
29# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
30# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
31# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
32# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
33# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
34# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
35# SOFTWARE.
36#
37
38use strict;
39
40use Getopt::Std;
41use IBswcountlimits;
42
43# =========================================================================
44#
45sub usage_and_exit
46{
47	my $prog = $_[0];
48	print "Usage: $prog [-R -l] [-G <rt_guid> | <node_name>]\n";
49	print "   print only the rt specified from the ibnetdiscover output\n";
50	print "   -R Recalculate ibnetdiscover information\n";
51	print "   -l list rts\n";
52	print "   -C <ca_name> use selected channel adaptor name for queries\n";
53	print "   -P <ca_port> use selected channel adaptor port for queries\n";
54	print "   -G node is specified with GUID\n";
55	exit 2;
56}
57
58my $argv0          = `basename $0`;
59my $regenerate_map = undef;
60my $list_rts       = undef;
61my $ca_name        = "";
62my $ca_port        = "";
63my $name_is_guid   = "no";
64chomp $argv0;
65if (!getopts("hRlC:P:G"))         { usage_and_exit $argv0; }
66if (defined $Getopt::Std::opt_h) { usage_and_exit $argv0; }
67if (defined $Getopt::Std::opt_R) { $regenerate_map = $Getopt::Std::opt_R; }
68if (defined $Getopt::Std::opt_l) { $list_rts       = $Getopt::Std::opt_l; }
69if (defined $Getopt::Std::opt_C) { $ca_name        = $Getopt::Std::opt_C; }
70if (defined $Getopt::Std::opt_P) { $ca_port        = $Getopt::Std::opt_P; }
71if (defined $Getopt::Std::opt_G) { $name_is_guid   = "yes"; }
72
73my $target_rt = $ARGV[0];
74
75if ($name_is_guid eq "yes") {
76	$target_rt = format_guid($target_rt);
77}
78
79my $cache_file = get_cache_file($ca_name, $ca_port);
80
81if ($regenerate_map || !(-f "$cache_file")) {
82	generate_ibnetdiscover_topology($ca_name, $ca_port);
83}
84
85if ($list_rts) {
86	system("ibrouters $cache_file");
87	exit 1;
88}
89
90if ($target_rt eq "") {
91	usage_and_exit $argv0;
92}
93
94# =========================================================================
95#
96sub main
97{
98	my $found_rt = 0;
99	open IBNET_TOPO, "<$cache_file" or die "Failed to open ibnet topology\n";
100	my $in_rt = "no";
101	my %ports = undef;
102	while (my $line = <IBNET_TOPO>) {
103		if ($line =~ /^Rt.*\"R-(.*)\"\s+# (.*)/) {
104			my $guid = $1;
105			my $desc = $2;
106			if ($in_rt eq "yes") {
107				$in_rt = "no";
108				foreach my $port (sort { $a <=> $b } (keys %ports)) {
109					print $ports{$port};
110				}
111			}
112			if ("0x$guid" eq $target_rt || $desc =~ /[\s\"]$target_rt[\s\"]/) {
113				print $line;
114				$in_rt    = "yes";
115				$found_rt++;
116			}
117		}
118		if ($line =~ /^Switch.*/ || $line =~ /^Ca.*/) { $in_rt = "no"; }
119
120		if ($line =~ /^\[(\d+)\].*/ && $in_rt eq "yes") {
121			$ports{$1} = $line;
122		}
123
124	}
125	if ($found_rt == 0) {
126		die "\"$target_rt\" not found\n" .
127			"   Try running with the \"-R\" option.\n" .
128			"   If still not found the node is probably down.\n";
129	}
130	if ($found_rt > 1) {
131		print "\nWARNING: Found $found_rt Router's with the name \"$target_rt\"\n";
132	}
133	close IBNET_TOPO;
134}
135main
136
137