]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - contrib/ofed/management/infiniband-diags/scripts/iblinkinfo.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 / iblinkinfo.pl
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
38 use strict;
39
40 use Getopt::Std;
41 use IBswcountlimits;
42
43 sub usage_and_exit
44 {
45         my $prog = $_[0];
46         print
47 "Usage: $prog [-Rhclp -S <guid> -D <direct route> -C <ca_name> -P <ca_port>]\n";
48         print
49 "   Report link speed and connection for each port of each switch which is active\n";
50         print "   -h This help message\n";
51         print
52 "   -R Recalculate ibnetdiscover information (Default is to reuse ibnetdiscover output)\n";
53         print
54 "   -D <direct route> output only the switch specified by direct route path\n";
55         print "   -S <guid> output only the switch specified by <guid> (hex format)\n";
56         print "   -d print only down links\n";
57         print
58           "   -l (line mode) print all information for each link on each line\n";
59         print
60 "   -p print additional switch settings (PktLifeTime,HoqLife,VLStallCount)\n";
61         print "   -c print port capabilities (enabled/supported values)\n";
62         print "   -C <ca_name> use selected Channel Adaptor name for queries\n";
63         print "   -P <ca_port> use selected channel adaptor port for queries\n";
64         print "   -g print port guids instead of node guids\n";
65         exit 2;
66 }
67
68 my $argv0              = `basename $0`;
69 my $regenerate_map     = undef;
70 my $single_switch      = undef;
71 my $direct_route       = undef;
72 my $line_mode          = undef;
73 my $print_add_switch   = undef;
74 my $print_extended_cap = undef;
75 my $only_down_links    = undef;
76 my $ca_name            = "";
77 my $ca_port            = "";
78 my $print_port_guids   = undef;
79 my $switch_found       = "no";
80 chomp $argv0;
81
82 if (!getopts("hcpldRS:D:C:P:g")) { usage_and_exit $argv0; }
83 if (defined $Getopt::Std::opt_h) { usage_and_exit $argv0; }
84 if (defined $Getopt::Std::opt_D) { $direct_route   = $Getopt::Std::opt_D; }
85 if (defined $Getopt::Std::opt_R) { $regenerate_map = $Getopt::Std::opt_R; }
86 if (defined $Getopt::Std::opt_S) {
87         $single_switch = format_guid($Getopt::Std::opt_S);
88 }
89 if (defined $Getopt::Std::opt_d) { $only_down_links    = $Getopt::Std::opt_d; }
90 if (defined $Getopt::Std::opt_l) { $line_mode          = $Getopt::Std::opt_l; }
91 if (defined $Getopt::Std::opt_p) { $print_add_switch   = $Getopt::Std::opt_p; }
92 if (defined $Getopt::Std::opt_c) { $print_extended_cap = $Getopt::Std::opt_c; }
93 if (defined $Getopt::Std::opt_C) { $ca_name            = $Getopt::Std::opt_C; }
94 if (defined $Getopt::Std::opt_P) { $ca_port            = $Getopt::Std::opt_P; }
95 if (defined $Getopt::Std::opt_g) { $print_port_guids   = $Getopt::Std::opt_g; }
96
97 my $extra_smpquery_params = get_ca_name_port_param_string($ca_name, $ca_port);
98
99 sub main
100 {
101         get_link_ends($regenerate_map, $ca_name, $ca_port);
102         if (defined($direct_route)) {
103                 # convert DR to guid, then use original single_switch option
104                 $single_switch = convert_dr_to_guid($direct_route);
105                 if (!defined($single_switch) || !is_switch($single_switch)) {
106                         printf("The direct route (%s) does not map to a switch.\n",
107                                 $direct_route);
108                         return;
109                 }
110         }
111         foreach my $switch (sort (keys(%IBswcountlimits::link_ends))) {
112                 if ($single_switch && $switch ne $single_switch) {
113                         next;
114                 } else {
115                         $switch_found = "yes";
116                 }
117                 my $switch_prompt = "no";
118                 my $num_ports = get_num_ports($switch, $ca_name, $ca_port);
119                 if ($num_ports == 0) {
120                         printf("ERROR: switch $switch has 0 ports???\n");
121                 }
122                 my @output_lines    = undef;
123                 my $pkt_lifetime    = "";
124                 my $pkt_life_prompt = "";
125                 my $port_timeouts   = "";
126                 my $print_switch    = "yes";
127                 if ($only_down_links) { $print_switch = "no"; }
128                 if ($print_add_switch) {
129                         my $data = `smpquery $extra_smpquery_params -G switchinfo $switch`;
130                         if ($data eq "") {
131                                 printf("ERROR: failed to get switchinfo for $switch\n");
132                         }
133                         my @lines = split("\n", $data);
134                         foreach my $line (@lines) {
135                                 if ($line =~ /^LifeTime:\.+(.*)/) { $pkt_lifetime = $1; }
136                         }
137                         $pkt_life_prompt = sprintf(" (LT: %2s)", $pkt_lifetime);
138                 }
139                 foreach my $port (1 .. $num_ports) {
140                         my $hr = $IBswcountlimits::link_ends{$switch}{$port};
141                         if ($switch_prompt eq "no" && !$line_mode) {
142                                 my $switch_name = "";
143                                 my $tmp_port = $port;
144                                 while ($switch_name eq "" && $tmp_port <= $num_ports) {
145                                         # the first port is down find switch name with up port
146                                         my $hr = $IBswcountlimits::link_ends{$switch}{$tmp_port};
147                                         $switch_name = $hr->{loc_desc};
148                                         $tmp_port++;
149                                 }
150                                 if ($switch_name eq "") {
151                                         printf(
152                                                 "WARNING: Switch Name not found for $switch\n");
153                                 }
154                                 push(
155                                         @output_lines,
156                                         sprintf(
157                                                 "Switch %18s %s%s:\n",
158                                                 $switch, $switch_name, $pkt_life_prompt
159                                         )
160                                 );
161                                 $switch_prompt = "yes";
162                         }
163                         my $data =
164                           `smpquery $extra_smpquery_params -G portinfo $switch $port`;
165                         if ($data eq "") {
166                                 printf(
167                                         "ERROR: failed to get portinfo for $switch port $port\n");
168                         }
169                         my @lines          = split("\n", $data);
170                         my $speed          = "";
171                         my $speed_sup      = "";
172                         my $speed_enable   = "";
173                         my $width          = "";
174                         my $width_sup      = "";
175                         my $width_enable   = "";
176                         my $state          = "";
177                         my $hoq_life       = "";
178                         my $vl_stall       = "";
179                         my $phy_link_state = "";
180
181                         foreach my $line (@lines) {
182                                 if ($line =~ /^LinkSpeedActive:\.+(.*)/) { $speed = $1; }
183                                 if ($line =~ /^LinkSpeedEnabled:\.+(.*)/) {
184                                         $speed_enable = $1;
185                                 }
186                                 if ($line =~ /^LinkSpeedSupported:\.+(.*)/) { $speed_sup = $1; }
187                                 if ($line =~ /^LinkWidthActive:\.+(.*)/)    { $width     = $1; }
188                                 if ($line =~ /^LinkWidthEnabled:\.+(.*)/) {
189                                         $width_enable = $1;
190                                 }
191                                 if ($line =~ /^LinkWidthSupported:\.+(.*)/) { $width_sup = $1; }
192                                 if ($line =~ /^LinkState:\.+(.*)/)          { $state     = $1; }
193                                 if ($line =~ /^HoqLife:\.+(.*)/)            { $hoq_life  = $1; }
194                                 if ($line =~ /^VLStallCount:\.+(.*)/)       { $vl_stall  = $1; }
195                                 if ($line =~ /^PhysLinkState:\.+(.*)/) { $phy_link_state = $1; }
196                         }
197                         my $rem_port         = $hr->{rem_port};
198                         my $rem_lid          = $hr->{rem_lid};
199                         my $rem_speed_sup    = "";
200                         my $rem_speed_enable = "";
201                         my $rem_width_sup    = "";
202                         my $rem_width_enable = "";
203                         if ($rem_lid ne "" && $rem_port ne "") {
204                                 $data =
205                                   `smpquery $extra_smpquery_params portinfo $rem_lid $rem_port`;
206                                 if ($data eq "") {
207                                         printf(
208                                                 "ERROR: failed to get portinfo for $switch port $port\n"
209                                         );
210                                 }
211                                 my @lines = split("\n", $data);
212                                 foreach my $line (@lines) {
213                                         if ($line =~ /^LinkSpeedEnabled:\.+(.*)/) {
214                                                 $rem_speed_enable = $1;
215                                         }
216                                         if ($line =~ /^LinkSpeedSupported:\.+(.*)/) {
217                                                 $rem_speed_sup = $1;
218                                         }
219                                         if ($line =~ /^LinkWidthEnabled:\.+(.*)/) {
220                                                 $rem_width_enable = $1;
221                                         }
222                                         if ($line =~ /^LinkWidthSupported:\.+(.*)/) {
223                                                 $rem_width_sup = $1;
224                                         }
225                                 }
226                         }
227                         my $capabilities = "";
228                         if ($print_extended_cap) {
229                                 $capabilities = sprintf("(%3s %s %6s / %8s [%s/%s][%s/%s])",
230                                         $width, $speed, $state, $phy_link_state, $width_enable,
231                                         $width_sup, $speed_enable, $speed_sup);
232                         } else {
233                                 $capabilities = sprintf("(%3s %s %6s / %8s)",
234                                         $width, $speed, $state, $phy_link_state);
235                         }
236                         if ($print_add_switch) {
237                                 $port_timeouts =
238                                   sprintf(" (HOQ:%s VL_Stall:%s)", $hoq_life, $vl_stall);
239                         }
240                         if (!$only_down_links || ($only_down_links && $state eq "Down")) {
241                                 my $width_msg = "";
242                                 my $speed_msg = "";
243                                 if ($rem_width_enable ne "" && $rem_width_sup ne "") {
244                                         if (   $width_enable =~ /12X/
245                                                 && $rem_width_enable =~ /12X/
246                                                 && $width !~ /12X/)
247                                         {
248                                                 $width_msg = "Could be 12X";
249                                         } else {
250                                                 if (   $width_enable =~ /8X/
251                                                         && $rem_width_enable =~ /8X/
252                                                         && $width !~ /8X/)
253                                                 {
254                                                         $width_msg = "Could be 8X";
255                                                 } else {
256                                                         if (   $width_enable =~ /4X/
257                                                                 && $rem_width_enable =~ /4X/
258                                                                 && $width !~ /4X/)
259                                                         {
260                                                                 $width_msg = "Could be 4X";
261                                                         }
262                                                 }
263                                         }
264                                 }
265                                 if ($rem_speed_enable ne "" && $rem_speed_sup ne "") {
266                                         if (   $speed_enable =~ /10\.0/
267                                                 && $rem_speed_enable =~ /10\.0/
268                                                 && $speed !~ /10\.0/)
269                                         {
270                                                 $speed_msg = "Could be 10.0 Gbps";
271                                         } else {
272                                                 if (   $speed_enable =~ /5\.0/
273                                                         && $rem_speed_enable =~ /5\.0/
274                                                         && $speed !~ /5\.0/)
275                                                 {
276                                                         $speed_msg = "Could be 5.0 Gbps";
277                                                 }
278                                         }
279                                 }
280
281                                 if ($line_mode) {
282                                         my $line_begin = sprintf("%18s \"%30s\"%s",
283                                                 $switch, $hr->{loc_desc}, $pkt_life_prompt);
284                                         my $ext_guid = sprintf("%18s", $hr->{rem_guid});
285                                         if ($print_port_guids && $hr->{rem_port_guid} ne "") {
286                                                 $ext_guid = sprintf("0x%016s", $hr->{rem_port_guid});
287                                         }
288                                         push(
289                                                 @output_lines,
290                                                 sprintf(
291 "%s %6s %4s[%2s]  ==%s%s==>  %18s %6s %4s[%2s] \"%s\" ( %s %s)\n",
292                                                         $line_begin,     $hr->{loc_sw_lid},
293                                                         $port,           $hr->{loc_ext_port},
294                                                         $capabilities,   $port_timeouts,
295                                                         $ext_guid,       $hr->{rem_lid},
296                                                         $hr->{rem_port}, $hr->{rem_ext_port},
297                                                         $hr->{rem_desc}, $width_msg,
298                                                         $speed_msg
299                                                 )
300                                         );
301                                 } else {
302                                         push(
303                                                 @output_lines,
304                                                 sprintf(
305 " %6s %4s[%2s]  ==%s%s==>  %6s %4s[%2s] \"%s\" ( %s %s)\n",
306                                                         $hr->{loc_sw_lid},   $port,
307                                                         $hr->{loc_ext_port}, $capabilities,
308                                                         $port_timeouts,      $hr->{rem_lid},
309                                                         $hr->{rem_port},     $hr->{rem_ext_port},
310                                                         $hr->{rem_desc},     $width_msg,
311                                                         $speed_msg
312                                                 )
313                                         );
314                                 }
315                                 $print_switch = "yes";
316                         }
317                 }
318                 if ($print_switch eq "yes") {
319                         foreach my $line (@output_lines) { print $line; }
320                 }
321         }
322         if ($single_switch && $switch_found ne "yes") {
323                 printf("Switch \"%s\" not found.\n", $single_switch);
324         }
325 }
326 main;
327