|
Packit |
db064d |
#!/usr/bin/perl
|
|
Packit |
db064d |
#
|
|
Packit |
db064d |
# Copyright (C) 2001-2003 The Regents of the University of California.
|
|
Packit |
db064d |
# Copyright (c) 2006 The Regents of the University of California.
|
|
Packit |
db064d |
# Copyright (c) 2007-2008 Voltaire, Inc. All rights reserved.
|
|
Packit |
db064d |
#
|
|
Packit |
db064d |
# Produced at Lawrence Livermore National Laboratory.
|
|
Packit |
db064d |
# Written by Ira Weiny <weiny2@llnl.gov>
|
|
Packit |
db064d |
# Jim Garlick <garlick@llnl.gov>
|
|
Packit |
db064d |
# Albert Chu <chu11@llnl.gov>
|
|
Packit |
db064d |
#
|
|
Packit |
db064d |
# This software is available to you under a choice of one of two
|
|
Packit |
db064d |
# licenses. You may choose to be licensed under the terms of the GNU
|
|
Packit |
db064d |
# General Public License (GPL) Version 2, available from the file
|
|
Packit |
db064d |
# COPYING in the main directory of this source tree, or the
|
|
Packit |
db064d |
# OpenIB.org BSD license below:
|
|
Packit |
db064d |
#
|
|
Packit |
db064d |
# Redistribution and use in source and binary forms, with or
|
|
Packit |
db064d |
# without modification, are permitted provided that the following
|
|
Packit |
db064d |
# conditions are met:
|
|
Packit |
db064d |
#
|
|
Packit |
db064d |
# - Redistributions of source code must retain the above
|
|
Packit |
db064d |
# copyright notice, this list of conditions and the following
|
|
Packit |
db064d |
# disclaimer.
|
|
Packit |
db064d |
#
|
|
Packit |
db064d |
# - Redistributions in binary form must reproduce the above
|
|
Packit |
db064d |
# copyright notice, this list of conditions and the following
|
|
Packit |
db064d |
# disclaimer in the documentation and/or other materials
|
|
Packit |
db064d |
# provided with the distribution.
|
|
Packit |
db064d |
#
|
|
Packit |
db064d |
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
Packit |
db064d |
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
Packit |
db064d |
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
Packit |
db064d |
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
|
Packit |
db064d |
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
|
Packit |
db064d |
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
Packit |
db064d |
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
Packit |
db064d |
# SOFTWARE.
|
|
Packit |
db064d |
#
|
|
Packit |
db064d |
|
|
Packit |
db064d |
use strict;
|
|
Packit |
db064d |
|
|
Packit |
db064d |
use Getopt::Std;
|
|
Packit |
db064d |
use IBswcountlimits;
|
|
Packit |
db064d |
my $ca_name = "";
|
|
Packit |
db064d |
my $ca_port = "";
|
|
Packit |
db064d |
|
|
Packit |
db064d |
# =========================================================================
|
|
Packit |
db064d |
#
|
|
Packit |
db064d |
sub get_hosts_routed
|
|
Packit |
db064d |
{
|
|
Packit |
db064d |
my $sw_guid = $_[0];
|
|
Packit |
db064d |
my $sw_port = $_[1];
|
|
Packit |
db064d |
my @hosts = undef;
|
|
Packit |
db064d |
my $extra_params = get_ca_name_port_param_string($ca_name, $ca_port);
|
|
Packit |
db064d |
|
|
Packit |
db064d |
if ($sw_guid eq "") { return (@hosts); }
|
|
Packit |
db064d |
|
|
Packit |
db064d |
my $data = `ibroute $extra_params -G $sw_guid`;
|
|
Packit |
db064d |
my @lines = split("\n", $data);
|
|
Packit |
db064d |
foreach my $line (@lines) {
|
|
Packit |
db064d |
if ($line =~ /\w+\s+(\d+)\s+:\s+\(Channel Adapter.*:\s+'(.*)'\)/) {
|
|
Packit |
db064d |
if ($1 == $sw_port) {
|
|
Packit |
db064d |
push @hosts, $2;
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
return (@hosts);
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
# =========================================================================
|
|
Packit |
db064d |
#
|
|
Packit |
db064d |
sub usage_and_exit
|
|
Packit |
db064d |
{
|
|
Packit |
db064d |
my $prog = $_[0];
|
|
Packit |
db064d |
print
|
|
Packit |
db064d |
"Usage: $prog [-R -C <ca_name> -P <ca_port>] <switch_guid|switch_name> <port>\n";
|
|
Packit |
db064d |
print " find a list of nodes which are routed through switch:port\n";
|
|
Packit |
db064d |
print " -R Recalculate ibnetdiscover information\n";
|
|
Packit |
db064d |
print " -C <ca_name> use selected Channel Adaptor name for queries\n";
|
|
Packit |
db064d |
print " -P <ca_port> use selected channel adaptor port for queries\n";
|
|
Packit |
db064d |
exit 2;
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
my $argv0 = `basename $0`;
|
|
Packit |
db064d |
my $regenerate_map = undef;
|
|
Packit |
db064d |
chomp $argv0;
|
|
Packit |
db064d |
if (!getopts("hRC:P:")) { usage_and_exit $argv0; }
|
|
Packit |
db064d |
if (defined $Getopt::Std::opt_h) { usage_and_exit $argv0; }
|
|
Packit |
db064d |
if (defined $Getopt::Std::opt_R) { $regenerate_map = $Getopt::Std::opt_R; }
|
|
Packit |
db064d |
if (defined $Getopt::Std::opt_C) { $ca_name = $Getopt::Std::opt_C; }
|
|
Packit |
db064d |
if (defined $Getopt::Std::opt_P) { $ca_port = $Getopt::Std::opt_P; }
|
|
Packit |
db064d |
|
|
Packit |
db064d |
my $target_switch = format_guid($ARGV[0]);
|
|
Packit |
db064d |
my $target_port = $ARGV[1];
|
|
Packit |
db064d |
|
|
Packit |
db064d |
get_link_ends($regenerate_map, $ca_name, $ca_port);
|
|
Packit |
db064d |
|
|
Packit |
db064d |
if ($target_switch eq "" || $target_port eq "") {
|
|
Packit |
db064d |
usage_and_exit $argv0;
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
# sortn:
|
|
Packit |
db064d |
#
|
|
Packit |
db064d |
# sort a group of alphanumeric strings by the last group of digits on
|
|
Packit |
db064d |
# those strings, if such exists (good for numerically suffixed host lists)
|
|
Packit |
db064d |
#
|
|
Packit |
db064d |
sub sortn
|
|
Packit |
db064d |
{
|
|
Packit |
db064d |
map { $$_[0] }
|
|
Packit |
db064d |
sort { ($$a[1] || 0) <=> ($$b[1] || 0) } map { [$_, /(\d*)$/] } @_;
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
# comp2():
|
|
Packit |
db064d |
#
|
|
Packit |
db064d |
# takes a list of names and returns a hash of arrays, indexed by name prefix,
|
|
Packit |
db064d |
# each containing a list of numerical ranges describing the initial list.
|
|
Packit |
db064d |
#
|
|
Packit |
db064d |
# e.g.: %hash = comp2(lx01,lx02,lx03,lx05,dev0,dev1,dev21)
|
|
Packit |
db064d |
# will return:
|
|
Packit |
db064d |
# $hash{"lx"} = ["01-03", "05"]
|
|
Packit |
db064d |
# $hash{"dev"} = ["0-1", "21"]
|
|
Packit |
db064d |
#
|
|
Packit |
db064d |
sub comp2
|
|
Packit |
db064d |
{
|
|
Packit |
db064d |
my (%i) = ();
|
|
Packit |
db064d |
my (%s) = ();
|
|
Packit |
db064d |
|
|
Packit |
db064d |
# turn off warnings here to avoid perl complaints about
|
|
Packit |
db064d |
# uninitialized values for members of %i and %s
|
|
Packit |
db064d |
local ($^W) = 0;
|
|
Packit |
db064d |
push(
|
|
Packit |
db064d |
@{
|
|
Packit |
db064d |
$s{$$_[0]}[
|
|
Packit |
db064d |
(
|
|
Packit |
db064d |
$s{$$_[0]}[$i{$$_[0]}][$#{$s{$$_[0]}[$i{$$_[0]}]}] ==
|
|
Packit |
db064d |
($$_[1] - 1)
|
|
Packit |
db064d |
) ? $i{$$_[0]} : ++$i{$$_[0]}
|
|
Packit |
db064d |
]
|
|
Packit |
db064d |
},
|
|
Packit |
db064d |
($$_[1])
|
|
Packit |
db064d |
) for map { [/(.*?)(\d*)$/] } sortn(@_);
|
|
Packit |
db064d |
|
|
Packit |
db064d |
for my $key (keys %s) {
|
|
Packit |
db064d |
@{$s{$key}} =
|
|
Packit |
db064d |
map { $#$_ > 0 ? "$$_[0]-$$_[$#$_]" : @{$_} } @{$s{$key}};
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
return %s;
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
sub compress_hostlist
|
|
Packit |
db064d |
{
|
|
Packit |
db064d |
my %rng = comp2(@_);
|
|
Packit |
db064d |
my @list = ();
|
|
Packit |
db064d |
|
|
Packit |
db064d |
local $" = ",";
|
|
Packit |
db064d |
|
|
Packit |
db064d |
foreach my $k (keys %rng) {
|
|
Packit |
db064d |
@{$rng{$k}} = map { "$k$_" } @{$rng{$k}};
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
@list = map { @{$rng{$_}} } sort keys %rng;
|
|
Packit |
db064d |
return "@list";
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
# =========================================================================
|
|
Packit |
db064d |
#
|
|
Packit |
db064d |
sub main
|
|
Packit |
db064d |
{
|
|
Packit |
db064d |
my $found_switch = undef;
|
|
Packit |
db064d |
my $cache_file = get_cache_file($ca_name, $ca_port);
|
|
Packit |
db064d |
open IBNET_TOPO, "<$cache_file" or die "Failed to open ibnet topology\n";
|
|
Packit |
db064d |
my $in_switch = "no";
|
|
Packit |
db064d |
my $switch_guid = "";
|
|
Packit |
db064d |
my $desc = undef;
|
|
Packit |
db064d |
my %ports = undef;
|
|
Packit |
db064d |
while (my $line = <IBNET_TOPO>) {
|
|
Packit |
db064d |
|
|
Packit |
db064d |
if ($line =~ /^Switch.*\"S-(.*)\"\s+# (.*) port.*/) {
|
|
Packit |
db064d |
$switch_guid = $1;
|
|
Packit |
db064d |
$desc = $2;
|
|
Packit |
db064d |
if ("0x$switch_guid" eq $target_switch
|
|
Packit |
db064d |
|| $desc =~ /.*$target_switch\s+.*/)
|
|
Packit |
db064d |
{
|
|
Packit |
db064d |
$found_switch = "yes";
|
|
Packit |
db064d |
goto FOUND;
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
if ($line =~ /^Ca.*/ || $line =~ /^Rt.*/) { $in_switch = "no"; }
|
|
Packit |
db064d |
|
|
Packit |
db064d |
if ($line =~ /^\[(\d+)\].*/ && $in_switch eq "yes") {
|
|
Packit |
db064d |
$ports{$1} = $line;
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
FOUND:
|
|
Packit |
db064d |
close IBNET_TOPO;
|
|
Packit |
db064d |
if (!$found_switch) {
|
|
Packit |
db064d |
print "Switch \"$target_switch\" not found\n";
|
|
Packit |
db064d |
print " Try running with the \"-R\" or \"-P\" option.\n";
|
|
Packit |
db064d |
exit 1;
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
|
|
Packit |
db064d |
$switch_guid = "0x$switch_guid";
|
|
Packit |
db064d |
|
|
Packit |
db064d |
my $hr = $IBswcountlimits::link_ends{$switch_guid}{$target_port};
|
|
Packit |
db064d |
my $rem_sw_guid = $hr->{rem_guid};
|
|
Packit |
db064d |
my $rem_sw_port = $hr->{rem_port};
|
|
Packit |
db064d |
my $rem_sw_desc = $hr->{rem_desc};
|
|
Packit |
db064d |
|
|
Packit |
db064d |
my @hosts = undef;
|
|
Packit |
db064d |
@hosts = get_hosts_routed($switch_guid, $target_port);
|
|
Packit |
db064d |
|
|
Packit |
db064d |
my $hosts = compress_hostlist(@hosts);
|
|
Packit |
db064d |
@hosts = split ",", $hosts;
|
|
Packit |
db064d |
print
|
|
Packit |
db064d |
"$switch_guid $target_port ($desc) ==>> $rem_sw_guid $rem_sw_port ($rem_sw_desc)\n";
|
|
Packit |
db064d |
print "@hosts\n\n";
|
|
Packit |
db064d |
|
|
Packit |
db064d |
@hosts = get_hosts_routed($rem_sw_guid, $rem_sw_port);
|
|
Packit |
db064d |
|
|
Packit |
db064d |
$hosts = compress_hostlist(@hosts);
|
|
Packit |
db064d |
@hosts = split ",", $hosts;
|
|
Packit |
db064d |
print
|
|
Packit |
db064d |
"$switch_guid $target_port ($desc) <<== $rem_sw_guid $rem_sw_port ($rem_sw_desc)\n";
|
|
Packit |
db064d |
print "@hosts\n";
|
|
Packit |
db064d |
}
|
|
Packit |
db064d |
main
|
|
Packit |
db064d |
|