1#!/usr/bin/perl
2#
3# Copyright (c) 2008 Voltaire, Inc. All rights reserved.
4# Copyright (c) 2006 The Regents of the University of California.
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
43my $sw_addr = "";
44my $sw_port = "";
45my $verbose = undef;
46
47# =========================================================================
48#
49sub print_verbose
50{
51	if ($verbose) {
52		print $_[0];
53	}
54}
55
56# =========================================================================
57#
58sub print_all_counts
59{
60	if (!$verbose) { return; }
61
62	print "   Counter\t\t\tNew ==> Old\n";
63	foreach my $cnt (@IBswcountlimits::counters) {
64		print
65"   $cnt\t\t\t$IBswcountlimits::new_counts{$cnt} ==> $IBswcountlimits::cur_counts{$cnt}\n";
66	}
67}
68
69# =========================================================================
70#
71sub usage_and_exit
72{
73	my $prog = $_[0];
74	print
75	  "Usage: $prog [-p <pause_time> -b -v -n <cycles> -G] <guid|lid> <port>\n";
76	print "   Attempt to diagnose a problem on a port\n";
77	print
78"   Run this on a link while a job is running which utilizes that link.\n";
79	print
80"   -p <pause_time> define the ammount of time between counter polls (default $IBswcountlimits::pause_time)\n";
81	print "   -v Be verbose\n";
82	print "   -n <cycles> run n cycles then exit (default -1 == forever)\n";
83	print "   -G Address provided is a GUID\n";
84	print "   -b report bytes/second packets/second\n";
85	exit 2;
86}
87
88# =========================================================================
89#
90sub clear_counters
91{
92	# clear the counters
93	foreach my $count (@IBswcountlimits::counters) {
94		$IBswcountlimits::cur_counts{$count} = 0;
95		$IBswcountlimits::new_counts{$count} = 0;
96	}
97}
98
99# =========================================================================
100#
101sub mv_counts
102{
103	foreach my $count (@IBswcountlimits::counters) {
104		$IBswcountlimits::cur_counts{$count} =
105		  $IBswcountlimits::new_counts{$count};
106	}
107}
108
109# =========================================================================
110# use perfquery to get the counters.
111my $GUID = "";
112
113sub get_new_counts
114{
115	my $addr = $_[0];
116	my $port = $_[1];
117	mv_counts;
118	ensure_cache_dir;
119	if (
120		system(
121"perfquery $GUID $addr $port > $IBswcountlimits::cache_dir/perfquery.out"
122		)
123	  )
124	{
125		die "perfquery failed : \"perfquery $GUID $addr $port\"\n";
126	}
127	open PERF_QUERY, "<$IBswcountlimits::cache_dir/perfquery.out"
128	  or die "cannot read '$IBswcountlimits::cache_dir/perfquery.out': $!\n";
129	while (my $line = <PERF_QUERY>) {
130		foreach my $count (@IBswcountlimits::counters) {
131			if ($line =~ /^$count:\.+(\d+)/) {
132				$IBswcountlimits::new_counts{$count} = $1;
133			}
134		}
135	}
136	close PERF_QUERY;
137}
138
139my $cycle = -1;    # forever
140
141my $bytes_per_second = undef;
142my $argv0            = `basename $0`;
143chomp $argv0;
144if (!getopts("hbvp:n:G"))        { usage_and_exit $argv0; }
145if (defined $Getopt::Std::opt_h) { usage_and_exit $argv0; }
146if (defined $Getopt::Std::opt_p) {
147	$IBswcountlimits::pause_time = $Getopt::Std::opt_p;
148}
149if (defined $Getopt::Std::opt_v) { $verbose          = $Getopt::Std::opt_v; }
150if (defined $Getopt::Std::opt_n) { $cycle            = $Getopt::Std::opt_n; }
151if (defined $Getopt::Std::opt_G) { $GUID             = "-G"; }
152if (defined $Getopt::Std::opt_b) { $bytes_per_second = $Getopt::Std::opt_b; }
153
154my $sw_addr = $ARGV[0];
155my $sw_port = $ARGV[1];
156
157sub main
158{
159	clear_counters;
160	get_new_counts($sw_addr, $sw_port);
161	while ($cycle != 0) {
162		print "Checking counts...\n";
163		sleep($IBswcountlimits::pause_time);
164		get_new_counts($sw_addr, $sw_port);
165		check_counter_rates;
166		if ($bytes_per_second) {
167			print_data_rates;
168		}
169		print_all_counts;
170		if ($cycle != -1) { $cycle = $cycle - 1; }
171	}
172}
173main;
174
175