]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - contrib/ofed/management/infiniband-diags/scripts/ibqueryerrors.pl
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / contrib / ofed / management / infiniband-diags / scripts / ibqueryerrors.pl
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
38 use strict;
39
40 use Getopt::Std;
41 use IBswcountlimits;
42
43 my $print_action          = "no";
44 my $report_port_info      = undef;
45 my $single_switch         = undef;
46 my $include_data_counters = undef;
47 my $cache_file            = "";
48 my $switch_found          = "no";
49
50 # =========================================================================
51 #
52 sub report_counts
53 {
54         my $addr         = $_[0];
55         my $port         = $_[1];
56         my $ca_name      = $_[2];
57         my $ca_port      = $_[3];
58         my $extra_params = get_ca_name_port_param_string($ca_name, $ca_port);
59
60         if (any_counts()) {
61                 print("   GUID $addr port $port:");
62                 check_counters($print_action);
63                 if ($include_data_counters) {
64                         check_data_counters($print_action);
65                 }
66                 print("\n");
67
68                 if ($report_port_info) {
69                         my $lid   = "";
70                         my $speed = "";
71                         my $width = "";
72                         my $data  = `smpquery $extra_params -G portinfo $addr $port`;
73                         my @lines = split("\n", $data);
74                         foreach my $line (@lines) {
75                                 if ($line =~ /^# Port info: Lid (\w+) port.*/) { $lid   = $1; }
76                                 if ($line =~ /^LinkSpeedActive:\.+(.*)/)       { $speed = $1; }
77                                 if ($line =~ /^LinkWidthActive:\.+(.*)/)       { $width = $1; }
78                         }
79                         my $hr = $IBswcountlimits::link_ends{"$addr"}{$port};
80                         if ($hr) {
81                                 printf(
82 "         Link info: %6s %4s[%2s]  ==(%3s %s)==>  %18s %4s[%2s] \"%s\"\n",
83                                         $lid,                $port,
84                                         $hr->{loc_ext_port}, $width,
85                                         $speed,              $hr->{rem_guid},
86                                         $hr->{rem_port},     $hr->{rem_ext_port},
87                                         $hr->{rem_desc}
88                                 );
89                         } else {
90                                 printf(
91 "         Link info: %6s %4s[  ]  ==(%3s %s)==>     (Disconnected)\n",
92                                         $lid, $port, $width, $speed);
93                         }
94                 }
95         }
96 }
97
98 # =========================================================================
99 # use perfquery to get the counters.
100 sub get_counts
101 {
102         my $addr         = $_[0];
103         my $port         = $_[1];
104         my $ca_name      = $_[2];
105         my $ca_port      = $_[3];
106         my $extra_params = get_ca_name_port_param_string($ca_name, $ca_port);
107
108         my $data = `perfquery $extra_params -G $addr $port` ||
109                 die "'perfquery $extra_params -G $addr $port' FAILED.\n";
110         my @lines = split("\n", $data);
111         foreach my $line (@lines) {
112                 foreach my $count (@IBswcountlimits::counters) {
113                         if ($line =~ /^$count:\.+(\d+)/) {
114                                 $IBswcountlimits::cur_counts{$count} = $1;
115                         }
116                 }
117         }
118 }
119
120 # =========================================================================
121 #
122 my %switches = ();
123
124 sub get_switches
125 {
126         my $data = `ibswitches $cache_file` ||
127                 die "'ibswitches $cache_file' failed.\n";
128         my @lines = split("\n", $data);
129         foreach my $line (@lines) {
130                 if ($line =~ /^Switch\s+:\s+(\w+)\s+ports\s+(\d+)\s+.*/) {
131                         $switches{$1} = $2;
132                 }
133         }
134 }
135
136 # =========================================================================
137 #
138 sub usage_and_exit
139 {
140         my $prog = $_[0];
141         print
142 "Usage: $prog [-a -c -r -R -s <err1,err2,...> -S <switch_guid> -D <direct route> -d -C <ca_name> -P <ca_port>]\n";
143         print "   Report counters on all switches in subnet\n";
144         print "   -a Report an action to take\n";
145         print "   -c suppress some of the common counters\n";
146         print "   -r report port configuration information\n";
147         print "   -R Recalculate ibnetdiscover information\n";
148         print "   -s <err1,err2,...> suppress errors listed\n";
149         print
150 "   -D <direct route> output only the switch specified by direct route path\n";
151         print "   -S <switch_guid> query only <switch_guid> (hex format)\n";
152         print "   -d include the data counters in the output\n";
153         print "   -C <ca_name> use selected Channel Adaptor name for queries\n";
154         print "   -P <ca_port> use selected channel adaptor port for queries\n";
155         exit 2;
156 }
157
158 my $argv0          = `basename $0`;
159 my $regenerate_map = undef;
160 my $single_switch  = undef;
161 my $direct_route   = undef;
162 my $ca_name        = "";
163 my $ca_port        = "";
164
165 chomp $argv0;
166 if (!getopts("has:crRS:D:dC:P:")) { usage_and_exit $argv0; }
167 if (defined $Getopt::Std::opt_h)  { usage_and_exit $argv0; }
168 if (defined $Getopt::Std::opt_a) { $print_action = "yes"; }
169 if (defined $Getopt::Std::opt_s) {
170         @IBswcountlimits::suppress_errors = split(",", $Getopt::Std::opt_s);
171 }
172 if (defined $Getopt::Std::opt_c) {
173         @IBswcountlimits::suppress_errors = split(",", "RcvSwRelayErrors");
174 }
175 if (defined $Getopt::Std::opt_r) { $report_port_info = $Getopt::Std::opt_r; }
176 if (defined $Getopt::Std::opt_R) { $regenerate_map   = $Getopt::Std::opt_R; }
177 if (defined $Getopt::Std::opt_D) { $direct_route     = $Getopt::Std::opt_D; }
178 if (defined $Getopt::Std::opt_S) {
179         $single_switch = format_guid($Getopt::Std::opt_S);
180 }
181 if (defined $Getopt::Std::opt_d) {
182         $include_data_counters = $Getopt::Std::opt_d;
183 }
184 if (defined $Getopt::Std::opt_C) { $ca_name = $Getopt::Std::opt_C; }
185 if (defined $Getopt::Std::opt_P) { $ca_port = $Getopt::Std::opt_P; }
186
187 $cache_file = get_cache_file($ca_name, $ca_port);
188
189 sub main
190 {
191         if (@IBswcountlimits::suppress_errors) {
192                 my $msg = join(",", @IBswcountlimits::suppress_errors);
193                 print "Suppressing: $msg\n";
194         }
195         get_link_ends($regenerate_map, $ca_name, $ca_port);
196         get_switches;
197         if (defined($direct_route)) {
198                 # convert DR to guid, then use original single_switch option
199                 $single_switch = convert_dr_to_guid($direct_route);
200                 if (!defined($single_switch) || !is_switch($single_switch)) {
201                         printf("The direct route (%s) does not map to a switch.\n",
202                                 $direct_route);
203                         return;
204                 }
205         }
206         foreach my $sw_addr (keys %switches) {
207                 if ($single_switch && $sw_addr ne "$single_switch") {
208                         next;
209                 } else {
210                         $switch_found = "yes";
211                 }
212
213                 my $switch_prompt = "no";
214                 foreach my $sw_port (1 .. $switches{$sw_addr}) {
215                         clear_counters;
216                         get_counts($sw_addr, $sw_port, $ca_name, $ca_port);
217                         if (any_counts() && $switch_prompt eq "no") {
218                                 my $hr = $IBswcountlimits::link_ends{"$sw_addr"}{$sw_port};
219                                 printf("Errors for %18s \"%s\"\n", $sw_addr, $hr->{loc_desc});
220                                 $switch_prompt = "yes";
221                         }
222                         report_counts($sw_addr, $sw_port);
223                 }
224         }
225         if ($single_switch && $switch_found ne "yes") {
226                 printf("Switch \"%s\" not found.\n", $single_switch);
227         }
228 }
229 main;
230