Hey Sasha,

Here's the script I mentioned before that I used for the balance checking
earlier.  Its nothing fancy but probably could be useful to others.

Al

-- 
Albert Chu
[EMAIL PROTECTED]
925-422-5311
Computer Scientist
High Performance Systems Division
Lawrence Livermore National Laboratory
>From 110a19a2d1bdaafe1ace7b2c48f39be5c1ec388f Mon Sep 17 00:00:00 2001
From: Albert L. Chu <[EMAIL PROTECTED]>
Date: Sat, 1 Mar 2008 20:02:03 -0800
Subject: [PATCH] add check_lft_balance script


Signed-off-by: Albert L. Chu <[EMAIL PROTECTED]>
---
 infiniband-diags/Makefile.am                  |    6 +-
 infiniband-diags/infiniband-diags.spec.in     |    4 +
 infiniband-diags/man/check_lft_balance.8      |   42 ++++
 infiniband-diags/scripts/check_lft_balance.pl |  319 +++++++++++++++++++++++++
 4 files changed, 369 insertions(+), 2 deletions(-)
 create mode 100644 infiniband-diags/man/check_lft_balance.8
 create mode 100755 infiniband-diags/scripts/check_lft_balance.pl

diff --git a/infiniband-diags/Makefile.am b/infiniband-diags/Makefile.am
index ca66e2d..8bbda9e 100644
--- a/infiniband-diags/Makefile.am
+++ b/infiniband-diags/Makefile.am
@@ -25,7 +25,8 @@ sbin_SCRIPTS = scripts/ibcheckerrs scripts/ibchecknet scripts/ibchecknode \
 	       scripts/ibqueryerrors.pl scripts/ibswportwatch.pl \
 	       scripts/iblinkinfo.pl scripts/ibprintswitch.pl \
 	       scripts/ibprintca.pl scripts/ibprintrt.pl \
-	       scripts/ibfindnodesusing.pl scripts/ibidsverify.pl
+	       scripts/ibfindnodesusing.pl scripts/ibidsverify.pl \
+	       scripts/check_lft_balance.pl
 
 src_ibaddr_SOURCES = src/ibaddr.c src/ibdiag_common.c
 src_ibaddr_CFLAGS = -Wall $(DBGFLAGS)
@@ -89,7 +90,8 @@ man_MANS = man/ibaddr.8 man/ibcheckerrors.8 man/ibcheckerrs.8 \
 	man/iblinkinfo.8 man/ibqueryerrors.8 man/ibswportwatch.8 \
 	man/ibprintswitch.8 man/ibprintca.8 man/ibfindnodesusing.8 \
 	man/ibdatacounts.8 man/ibdatacounters.8 \
-	man/ibrouters.8 man/ibprintrt.8 man/ibidsverify.8
+	man/ibrouters.8 man/ibprintrt.8 man/ibidsverify.8 \
+	man/check_lft_balance.pl
 
 BUILT_SOURCES = ibdiag_version
 ibdiag_version:
diff --git a/infiniband-diags/infiniband-diags.spec.in b/infiniband-diags/infiniband-diags.spec.in
index 7a0e17b..9c8c0c4 100644
--- a/infiniband-diags/infiniband-diags.spec.in
+++ b/infiniband-diags/infiniband-diags.spec.in
@@ -48,6 +48,7 @@ rm -rf $RPM_BUILD_ROOT
 %{_sbindir}/vendstat
 %{_sbindir}/dump_mfts.sh
 %{_sbindir}/dump_lfts.sh
+%{_sbindir}/check_lft_balance.pl
 %{_sbindir}/set_nodedesc.sh
 %{_sbindir}/sm*
 %define _perldir %(perl -e 'use Config; $T=$Config{installsitearch}; $T=~/(.*)\\/site_perl.*/; print $1;')
@@ -56,6 +57,9 @@ rm -rf $RPM_BUILD_ROOT
 %doc README COPYING ChangeLog
 
 %changelog
+* Mon Mar 03 2008 Albert Chu <[EMAIL PROTECTED]> - 1.3.5
+- Add check_lft_balance script.
+
 * Wed Oct 31 2007 Ira Weiny <[EMAIL PROTECTED]> - 1.3.2
 - Change switch-map option to node-name-map
 
diff --git a/infiniband-diags/man/check_lft_balance.8 b/infiniband-diags/man/check_lft_balance.8
new file mode 100644
index 0000000..35243f6
--- /dev/null
+++ b/infiniband-diags/man/check_lft_balance.8
@@ -0,0 +1,42 @@
+.TH CHECK_LFT_BALANCE.SH 8 "March 1, 2008" "OpenIB" "OpenIB Diagnostics"
+
+.SH NAME
+check_lft_balance.sh \- check InfiniBand unicast forwarding tables balance
+
+.SH SYNOPSIS
+.B check_lft_balance.sh
+[-hRv]
+
+
+.SH DESCRIPTION
+.PP
+check_lft_balance.sh is a script which checks for balancing in Infiniband
+unicast forwarding tables.  It analyzes the output of 
+.BR dump_lfts(8)
+and
+.BR iblinkinfo(8).
+
+.SH OPTIONS
+
+.PP
+.TP
+\fB\-h\fR
+show help
+.TP
+\fB\-R\fR
+Recalculate dump_lfts information, ie do not use the cached
+information.  This option is slower but should be used if the diag tools have
+not been used for some time or if there are other reasons to believe that
+the fabric has changed.
+.TP
+\fB\-v\fR
+verbose output
+
+.SH SEE ALSO
+.BR dump_lfts(8),
+.BR iblinkinfo(8)
+
+.SH AUTHORS
+.TP
+Albert Chu
+.RI < [EMAIL PROTECTED] >
diff --git a/infiniband-diags/scripts/check_lft_balance.pl b/infiniband-diags/scripts/check_lft_balance.pl
new file mode 100755
index 0000000..c4186ed
--- /dev/null
+++ b/infiniband-diags/scripts/check_lft_balance.pl
@@ -0,0 +1,319 @@
+#!/usr/bin/perl
+#
+# Copyright (C) 2001-2003 The Regents of the University of California.
+# Copyright (c) 2006 The Regents of the University of California.
+# Copyright (c) 2007 Voltaire, Inc. All rights reserved.
+#
+# Produced at Lawrence Livermore National Laboratory.
+# Written by Ira Weiny <[EMAIL PROTECTED]>
+#            Jim Garlick <[EMAIL PROTECTED]>
+#            Albert Chu <[EMAIL PROTECTED]>
+#
+# This software is available to you under a choice of one of two
+# licenses.  You may choose to be licensed under the terms of the GNU
+# General Public License (GPL) Version 2, available from the file
+# COPYING in the main directory of this source tree, or the
+# OpenIB.org BSD license below:
+#
+#     Redistribution and use in source and binary forms, with or
+#     without modification, are permitted provided that the following
+#     conditions are met:
+#
+#      - Redistributions of source code must retain the above
+#        copyright notice, this list of conditions and the following
+#        disclaimer.
+#
+#      - Redistributions in binary form must reproduce the above
+#        copyright notice, this list of conditions and the following
+#        disclaimer in the documentation and/or other materials
+#        provided with the distribution.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+#
+
+use strict;
+
+use Getopt::Std;
+use IBswcountlimits;
+
+my $file             = undef;
+my $regenerate_cache = 0;
+my $verbose          = 0;
+
+my $switch_lid                            = undef;
+my $switch_guid                           = undef;
+my $switch_name                           = undef;
+my %switch_port_count                     = ();
+my @switch_maybe_directly_connected_hosts = ();
+my $host                                  = undef;
+my @host_ports                            = ();
+
+my @lft_lines = ();
+my $lft_line;
+
+my $lids_per_port;
+my $lids_per_port_calculated;
+
+sub usage
+{
+	my $prog = `basename $0`;
+
+	chomp($prog);
+	print "Usage: $prog [-R -v]\n";
+	print "  -R recalculate all cached information\n";
+	print "  -v verbose output\n";
+	exit 0;
+}
+
+sub is_port_up
+{
+	my $iblinkinfo_output = $_[0];
+	my $port              = $_[1];
+	my $decport;
+	my @lines;
+	my $line;
+
+	$port =~ /0+(.+)/;
+	$decport = $1;
+
+	# Add a space if necessary
+	if ($decport >= 1 && $decport <= 9) {
+		$decport = " $decport";
+	}
+
+	@lines = split("\n", $iblinkinfo_output);
+	foreach $line (@lines) {
+		if ($line =~ /$decport\[..\]  ==/) {
+			if ($line =~ /Down/) {
+				return 0;
+			}
+		}
+	}
+	return 1;
+}
+
+sub is_directly_connected
+{
+	my $iblinkinfo_output = $_[0];
+	my $port              = $_[1];
+	my $decport;
+	my $str;
+	my $rv = 0;
+	my $host_tmp;
+	my @lines;
+	my $line;
+
+	if (($switch_port_count{$port} != $lids_per_port)
+		|| !(@switch_maybe_directly_connected_hosts))
+	{
+		return $rv;
+	}
+
+	$port =~ /0+(.+)/;
+	$decport = $1;
+
+	# Add a space if necessary
+	if ($decport >= 1 && $decport <= 9) {
+		$decport = " $decport";
+	}
+
+	@lines = split("\n", $iblinkinfo_output);
+	foreach $line (@lines) {
+		if ($line =~ /$decport\[..\]  ==/) {
+			$str = $line;
+		}
+	}
+
+	if ($str =~ "Active") {
+		$str =~
+/[\d]+[\s]+[\d]+\[.+\]  \=\=.+\=\=>[\s]+[\d]+[\s]+[\d]+\[.+\] \"(.+)\".+/;
+		for $host_tmp (@switch_maybe_directly_connected_hosts) {
+			if ($1 == $host_tmp) {
+				$rv = 1;
+				last;
+			}
+		}
+	}
+
+	return $rv;
+}
+
+sub output_switch_port_usage
+{
+	my $min_usage = 999999;
+	my $max_usage = 0;
+	my @ports     = (
+		"001", "002", "003", "004", "005", "006", "007", "008",
+		"009", "010", "011", "012", "013", "014", "015", "016",
+		"017", "018", "019", "020", "021", "022", "023", "024"
+	);
+	my @output_ports = ();
+	my $port;
+	my $iblinkinfo_output;
+	my $ret;
+
+	# Run command once to reduce number of calls to iblinkinfo.pl
+	$iblinkinfo_output = `iblinkinfo.pl -S $switch_guid`;
+
+	for $port (@ports) {
+		if (!defined($switch_port_count{$port})) {
+			$switch_port_count{$port} = 0;
+		}
+
+		if ($switch_port_count{$port} == 0) {
+			# If port is down, don't use it in this calculation
+			$ret = is_port_up($iblinkinfo_output, $port);
+			if ($ret == 0) {
+				next;
+			}
+		}
+
+		# If port is directly connected to a node, don't use
+		# it in this calculation.
+		if (is_directly_connected($iblinkinfo_output, $port) == 1) {
+			next;
+		}
+
+		# Save off ports that should be output later
+		push(@output_ports, $port);
+
+		if ($switch_port_count{$port} < $min_usage) {
+			$min_usage = $switch_port_count{$port};
+		}
+		if ($switch_port_count{$port} > $max_usage) {
+			$max_usage = $switch_port_count{$port};
+		}
+	}
+
+	if ($verbose || ($max_usage > ($min_usage + 1))) {
+		if ($max_usage > ($min_usage + 1)) {
+			print
+"Unbalanced Switch Port Usage: $switch_name, $switch_guid, $switch_lid\n";
+		} else {
+			print
+			  "Switch Port Usage: $switch_name, $switch_guid, $switch_lid\n";
+		}
+		for $port (@output_ports) {
+			print "Port $port: $switch_port_count{$port}\n";
+		}
+	}
+}
+
+sub process_host_ports
+{
+	my $test_port;
+	my $tmp;
+	my $flag = 0;
+
+	if (@host_ports == $lids_per_port) {
+		# Are all the host ports identical?
+		$test_port = $host_ports[0];
+		for $tmp (@host_ports) {
+			if ($tmp != $test_port) {
+				$flag = 1;
+				last;
+			}
+		}
+		# If all host ports are identical, maybe its directly
+		# connected to a host.
+		if ($flag == 0) {
+			push(@switch_maybe_directly_connected_hosts, $host);
+		}
+	}
+}
+
+if (!getopts("hRv")) {
+	usage();
+}
+
+if (defined($main::opt_h)) {
+	usage();
+}
+
+if (defined($main::opt_R)) {
+	$regenerate_cache = 1;
+}
+
+if (defined($main::opt_v)) {
+	$verbose = 1;
+}
+
+if (!defined($file)) {
+	my $cache_file = "$IBswcountlimits::cache_dir/dump_lfts.out";
+	if ($regenerate_cache
+		|| !(-f "$IBswcountlimits::cache_dir/dump_lfts.out"))
+	{
+
+		`dump_lfts.sh > $cache_file`;
+		if ($? != 0) {
+			die "Execution of dump_lfts.sh failed with errors\n";
+		}
+	}
+	$file = $cache_file;
+}
+
+if (!open(FH, "< $file")) {
+	print STDERR ("Couldn't open file: file=$file: $!\n");
+}
+
[EMAIL PROTECTED] = <FH>;
+
+foreach $lft_line (@lft_lines) {
+	chomp($lft_line);
+	if ($lft_line =~ /Unicast/) {
+		$lft_line =~ /Unicast lids .+ of switch Lid (.+) guid (.+) \((.+)\)/;
+		if (@host_ports) {
+			process_host_ports();
+		}
+		if (defined($switch_name)) {
+			output_switch_port_usage();
+		}
+		$switch_lid                            = $1;
+		$switch_guid                           = $2;
+		$switch_name                           = $3;
+		@switch_maybe_directly_connected_hosts = ();
+		%switch_port_count                     = ();
+		@host_ports                            = ();
+		$lids_per_port                         = 0;
+		$lids_per_port_calculated              = 0;
+	} elsif ($lft_line =~ /Channel/) {
+		$lft_line =~ /.+ (.+) : \(Channel Adapter portguid .+: '(.+)'\)/;
+		$host = $2;
+		$switch_port_count{$1}++;
+		if (@host_ports) {
+			process_host_ports();
+		}
+		@host_ports = ($1);
+
+		if ($lids_per_port == 0) {
+			$lids_per_port++;
+		} else {
+			$lids_per_port_calculated++;
+		}
+	} elsif ($lft_line =~ /path/) {
+		$lft_line =~ /.+ (.+) : \(path #. out of .: portguid .+\)/;
+		$switch_port_count{$1}++;
+		if ($lids_per_port_calculated == 0) {
+			$lids_per_port++;
+		}
+		push(@host_ports, $1);
+	} else {
+		if ($lids_per_port) {
+			$lids_per_port_calculated++;
+		}
+		next;
+	}
+}
+
+if (@host_ports) {
+	process_host_ports();
+}
+output_switch_port_usage();
+
-- 
1.5.1
_______________________________________________
general mailing list
[email protected]
http://lists.openfabrics.org/cgi-bin/mailman/listinfo/general

To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general

Reply via email to