1 /* 2 * Copyright (c) 2009 Sun Microsystems, Inc. All rights reserved. 3 * Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved. 4 * Copyright (c) 2002-2015 Mellanox Technologies LTD. All rights reserved. 5 * Copyright (c) 1996-2003 Intel Corporation. All rights reserved. 6 * 7 * This software is available to you under a choice of one of two 8 * licenses. You may choose to be licensed under the terms of the GNU 9 * General Public License (GPL) Version 2, available from the file 10 * COPYING in the main directory of this source tree, or the 11 * OpenIB.org BSD license below: 12 * 13 * Redistribution and use in source and binary forms, with or 14 * without modification, are permitted provided that the following 15 * conditions are met: 16 * 17 * - Redistributions of source code must retain the above 18 * copyright notice, this list of conditions and the following 19 * disclaimer. 20 * 21 * - Redistributions in binary form must reproduce the above 22 * copyright notice, this list of conditions and the following 23 * disclaimer in the documentation and/or other materials 24 * provided with the distribution. 25 * 26 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 27 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 28 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 29 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 30 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 31 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 32 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 33 * SOFTWARE. 34 * 35 */ 36 37 /* 38 * Abstract: 39 * Various OpenSM dumpers 40 */ 41 42 #if HAVE_CONFIG_H 43 # include <config.h> 44 #endif /* HAVE_CONFIG_H */ 45 46 #include <unistd.h> 47 #include <stdlib.h> 48 #include <string.h> 49 #include <errno.h> 50 #include <iba/ib_types.h> 51 #include <complib/cl_qmap.h> 52 #include <complib/cl_debug.h> 53 #include <opensm/osm_file_ids.h> 54 #define FILE_ID OSM_FILE_DUMP_C 55 #include <opensm/osm_opensm.h> 56 #include <opensm/osm_log.h> 57 #include <opensm/osm_node.h> 58 #include <opensm/osm_switch.h> 59 #include <opensm/osm_helper.h> 60 #include <opensm/osm_msgdef.h> 61 #include <opensm/osm_opensm.h> 62 63 static void dump_ucast_path_distribution(cl_map_item_t * item, FILE * file, 64 void *cxt) 65 { 66 osm_node_t *p_node; 67 osm_node_t *p_remote_node; 68 uint8_t i; 69 uint8_t num_ports; 70 uint32_t num_paths; 71 ib_net64_t remote_guid_ho; 72 osm_switch_t *p_sw = (osm_switch_t *) item; 73 74 p_node = p_sw->p_node; 75 num_ports = p_sw->num_ports; 76 77 fprintf(file, "dump_ucast_path_distribution: Switch 0x%" PRIx64 "\n" 78 "Port : Path Count Through Port", 79 cl_ntoh64(osm_node_get_node_guid(p_node))); 80 81 for (i = 0; i < num_ports; i++) { 82 num_paths = osm_switch_path_count_get(p_sw, i); 83 fprintf(file, "\n %03u : %u", i, num_paths); 84 if (i == 0) { 85 fprintf(file, " (switch management port)"); 86 continue; 87 } 88 89 p_remote_node = osm_node_get_remote_node(p_node, i, NULL); 90 if (p_remote_node == NULL) 91 continue; 92 93 remote_guid_ho = 94 cl_ntoh64(osm_node_get_node_guid(p_remote_node)); 95 96 switch (osm_node_get_type(p_remote_node)) { 97 case IB_NODE_TYPE_SWITCH: 98 fprintf(file, " (link to switch"); 99 break; 100 case IB_NODE_TYPE_ROUTER: 101 fprintf(file, " (link to router"); 102 break; 103 case IB_NODE_TYPE_CA: 104 fprintf(file, " (link to CA"); 105 break; 106 default: 107 fprintf(file, " (link to unknown node type"); 108 break; 109 } 110 111 fprintf(file, " 0x%" PRIx64 ")", remote_guid_ho); 112 } 113 114 fprintf(file, "\n"); 115 } 116 117 static void dump_ucast_routes(cl_map_item_t * item, FILE * file, void *cxt) 118 { 119 const osm_node_t *p_node; 120 osm_port_t *p_port; 121 uint8_t port_num; 122 uint8_t num_hops; 123 uint8_t best_hops; 124 uint8_t best_port; 125 uint16_t max_lid_ho; 126 uint16_t lid_ho, base_lid; 127 boolean_t direct_route_exists = FALSE; 128 boolean_t dor; 129 osm_switch_t *p_sw = (osm_switch_t *) item; 130 osm_opensm_t *p_osm = cxt; 131 132 p_node = p_sw->p_node; 133 134 max_lid_ho = p_sw->max_lid_ho; 135 136 fprintf(file, "dump_ucast_routes: " 137 "Switch 0x%016" PRIx64 "\nLID : Port : Hops : Optimal\n", 138 cl_ntoh64(osm_node_get_node_guid(p_node))); 139 140 dor = (p_osm->routing_engine_used && 141 p_osm->routing_engine_used->type == OSM_ROUTING_ENGINE_TYPE_DOR); 142 143 for (lid_ho = 1; lid_ho <= max_lid_ho; lid_ho++) { 144 fprintf(file, "0x%04X : ", lid_ho); 145 146 p_port = osm_get_port_by_lid_ho(&p_osm->subn, lid_ho); 147 if (!p_port) { 148 fprintf(file, "UNREACHABLE\n"); 149 continue; 150 } 151 152 port_num = osm_switch_get_port_by_lid(p_sw, lid_ho, 153 OSM_NEW_LFT); 154 if (port_num == OSM_NO_PATH) { 155 /* 156 This may occur if there are 'holes' in the existing 157 LID assignments. Running SM with --reassign_lids 158 will reassign and compress the LID range. The 159 subnet should work fine either way. 160 */ 161 fprintf(file, "UNREACHABLE\n"); 162 continue; 163 } 164 /* 165 Switches can lie about which port routes a given 166 lid due to a recent reconfiguration of the subnet. 167 Therefore, ensure that the hop count is better than 168 OSM_NO_PATH. 169 */ 170 if (p_port->p_node->sw) { 171 /* Target LID is switch. 172 Get its base lid and check hop count for this base LID only. */ 173 base_lid = osm_node_get_base_lid(p_port->p_node, 0); 174 base_lid = cl_ntoh16(base_lid); 175 num_hops = 176 osm_switch_get_hop_count(p_sw, base_lid, port_num); 177 } else { 178 /* Target LID is not switch (CA or router). 179 Check if we have route to this target from current switch. */ 180 num_hops = 181 osm_switch_get_hop_count(p_sw, lid_ho, port_num); 182 if (num_hops != OSM_NO_PATH) { 183 direct_route_exists = TRUE; 184 base_lid = lid_ho; 185 } else { 186 osm_physp_t *p_physp = p_port->p_physp; 187 188 if (!p_physp || !p_physp->p_remote_physp || 189 !p_physp->p_remote_physp->p_node->sw) 190 num_hops = OSM_NO_PATH; 191 else { 192 base_lid = 193 osm_node_get_base_lid(p_physp-> 194 p_remote_physp-> 195 p_node, 0); 196 base_lid = cl_ntoh16(base_lid); 197 num_hops = 198 p_physp->p_remote_physp->p_node-> 199 sw == 200 p_sw ? 0 : 201 osm_switch_get_hop_count(p_sw, 202 base_lid, 203 port_num); 204 } 205 } 206 } 207 208 if (num_hops == OSM_NO_PATH) { 209 fprintf(file, "%03u : HOPS UNKNOWN\n", port_num); 210 continue; 211 } 212 213 best_hops = osm_switch_get_least_hops(p_sw, base_lid); 214 if (!p_port->p_node->sw && !direct_route_exists) { 215 best_hops++; 216 num_hops++; 217 } 218 219 fprintf(file, "%03u : %02u : ", port_num, num_hops); 220 221 if (best_hops == num_hops) 222 fprintf(file, "yes"); 223 else { 224 /* No LMC Optimization */ 225 best_port = osm_switch_recommend_path(p_sw, p_port, 226 lid_ho, 1, TRUE, 227 FALSE, dor, 228 p_osm->subn.opt.port_shifting, 229 p_osm->subn.opt.scatter_ports, 230 OSM_NEW_LFT); 231 fprintf(file, "No %u hop path possible via port %u!", 232 best_hops, best_port); 233 } 234 235 fprintf(file, "\n"); 236 } 237 } 238 239 static void dump_mcast_routes(cl_map_item_t * item, FILE * file, void *cxt) 240 { 241 osm_switch_t *p_sw = (osm_switch_t *) item; 242 osm_mcast_tbl_t *p_tbl; 243 int16_t mlid_ho = 0; 244 int16_t mlid_start_ho; 245 uint8_t position = 0; 246 int16_t block_num = 0; 247 boolean_t first_mlid; 248 boolean_t first_port; 249 const osm_node_t *p_node; 250 uint16_t i, j; 251 uint16_t mask_entry; 252 char sw_hdr[256]; 253 char mlid_hdr[32]; 254 255 p_node = p_sw->p_node; 256 257 p_tbl = osm_switch_get_mcast_tbl_ptr(p_sw); 258 259 sprintf(sw_hdr, "\nSwitch 0x%016" PRIx64 "\nLID : Out Port(s)\n", 260 cl_ntoh64(osm_node_get_node_guid(p_node))); 261 first_mlid = TRUE; 262 while (block_num <= p_tbl->max_block_in_use) { 263 mlid_start_ho = (uint16_t) (block_num * IB_MCAST_BLOCK_SIZE); 264 for (i = 0; i < IB_MCAST_BLOCK_SIZE; i++) { 265 mlid_ho = mlid_start_ho + i; 266 position = 0; 267 first_port = TRUE; 268 sprintf(mlid_hdr, "0x%04X :", 269 mlid_ho + IB_LID_MCAST_START_HO); 270 while (position <= p_tbl->max_position) { 271 mask_entry = 272 cl_ntoh16((*p_tbl-> 273 p_mask_tbl)[mlid_ho][position]); 274 if (mask_entry == 0) { 275 position++; 276 continue; 277 } 278 for (j = 0; j < 16; j++) { 279 if ((1 << j) & mask_entry) { 280 if (first_mlid) { 281 fprintf(file, "%s", 282 sw_hdr); 283 first_mlid = FALSE; 284 } 285 if (first_port) { 286 fprintf(file, "%s", 287 mlid_hdr); 288 first_port = FALSE; 289 } 290 fprintf(file, " 0x%03X ", 291 j + (position * 16)); 292 } 293 } 294 position++; 295 } 296 if (first_port == FALSE) 297 fprintf(file, "\n"); 298 } 299 block_num++; 300 } 301 } 302 303 static void dump_lid_matrix(cl_map_item_t * item, FILE * file, void *cxt) 304 { 305 osm_switch_t *p_sw = (osm_switch_t *) item; 306 osm_opensm_t *p_osm = cxt; 307 osm_node_t *p_node = p_sw->p_node; 308 unsigned max_lid = p_sw->max_lid_ho; 309 unsigned max_port = p_sw->num_ports; 310 uint16_t lid; 311 uint8_t port; 312 313 fprintf(file, "Switch: guid 0x%016" PRIx64 "\n", 314 cl_ntoh64(osm_node_get_node_guid(p_node))); 315 for (lid = 1; lid <= max_lid; lid++) { 316 osm_port_t *p_port; 317 if (osm_switch_get_least_hops(p_sw, lid) == OSM_NO_PATH) 318 continue; 319 fprintf(file, "0x%04x:", lid); 320 for (port = 0; port < max_port; port++) 321 fprintf(file, " %02x", 322 osm_switch_get_hop_count(p_sw, lid, port)); 323 p_port = osm_get_port_by_lid_ho(&p_osm->subn, lid); 324 if (p_port) 325 fprintf(file, " # portguid 0x%016" PRIx64, 326 cl_ntoh64(osm_port_get_guid(p_port))); 327 fprintf(file, "\n"); 328 } 329 } 330 331 static void dump_ucast_lfts(cl_map_item_t * item, FILE * file, void *cxt) 332 { 333 osm_switch_t *p_sw = (osm_switch_t *) item; 334 osm_opensm_t *p_osm = cxt; 335 osm_node_t *p_node = p_sw->p_node; 336 unsigned max_lid = p_sw->max_lid_ho; 337 unsigned max_port = p_sw->num_ports; 338 uint16_t lid; 339 uint8_t port; 340 341 fprintf(file, "Unicast lids [0-%u] of switch Lid %u guid 0x%016" 342 PRIx64 " (\'%s\'):\n", 343 max_lid, cl_ntoh16(osm_node_get_base_lid(p_node, 0)), 344 cl_ntoh64(osm_node_get_node_guid(p_node)), p_node->print_desc); 345 for (lid = 0; lid <= max_lid; lid++) { 346 osm_port_t *p_port; 347 port = osm_switch_get_port_by_lid(p_sw, lid, OSM_NEW_LFT); 348 349 if (port >= max_port) 350 continue; 351 352 fprintf(file, "0x%04x %03u # ", lid, port); 353 354 p_port = osm_get_port_by_lid_ho(&p_osm->subn, lid); 355 if (p_port) { 356 p_node = p_port->p_node; 357 fprintf(file, "%s portguid 0x%016" PRIx64 ": \'%s\'", 358 ib_get_node_type_str(osm_node_get_type(p_node)), 359 cl_ntoh64(osm_port_get_guid(p_port)), 360 p_node->print_desc); 361 } else 362 fprintf(file, "unknown node and type"); 363 fprintf(file, "\n"); 364 } 365 fprintf(file, "%u lids dumped\n", max_lid); 366 } 367 368 static void dump_topology_node(cl_map_item_t * item, FILE * file, void *cxt) 369 { 370 osm_node_t *p_node = (osm_node_t *) item; 371 uint32_t cPort; 372 osm_node_t *p_nbnode; 373 osm_physp_t *p_physp, *p_default_physp, *p_rphysp; 374 uint8_t link_speed_act; 375 const char *link_speed_act_str, *link_width_act_str; 376 377 if (!p_node->node_info.num_ports) 378 return; 379 380 for (cPort = 1; cPort < osm_node_get_num_physp(p_node); cPort++) { 381 uint8_t port_state; 382 383 p_physp = osm_node_get_physp_ptr(p_node, cPort); 384 if (!p_physp) 385 continue; 386 387 p_rphysp = p_physp->p_remote_physp; 388 if (!p_rphysp) 389 continue; 390 391 CL_ASSERT(cPort == p_physp->port_num); 392 393 if (p_node->node_info.node_type == IB_NODE_TYPE_SWITCH) 394 p_default_physp = osm_node_get_physp_ptr(p_node, 0); 395 else 396 p_default_physp = p_physp; 397 398 fprintf(file, "{ %s%s Ports:%02X SystemGUID:%016" PRIx64 399 " NodeGUID:%016" PRIx64 " PortGUID:%016" PRIx64 400 " VenID:%06X DevID:%04X Rev:%08X {%s} LID:%04X PN:%02X } ", 401 p_node->node_info.node_type == IB_NODE_TYPE_SWITCH ? 402 "SW" : p_node->node_info.node_type == 403 IB_NODE_TYPE_CA ? "CA" : p_node->node_info.node_type == 404 IB_NODE_TYPE_ROUTER ? "Rt" : "**", 405 p_default_physp->port_info.base_lid == 406 p_default_physp->port_info. 407 master_sm_base_lid ? "-SM" : "", 408 p_node->node_info.num_ports, 409 cl_ntoh64(p_node->node_info.sys_guid), 410 cl_ntoh64(p_node->node_info.node_guid), 411 cl_ntoh64(p_physp->port_guid), 412 cl_ntoh32(ib_node_info_get_vendor_id 413 (&p_node->node_info)), 414 cl_ntoh16(p_node->node_info.device_id), 415 cl_ntoh32(p_node->node_info.revision), 416 p_node->print_desc, 417 cl_ntoh16(p_default_physp->port_info.base_lid), cPort); 418 419 p_nbnode = p_rphysp->p_node; 420 421 if (p_nbnode->node_info.node_type == IB_NODE_TYPE_SWITCH) 422 p_default_physp = osm_node_get_physp_ptr(p_nbnode, 0); 423 else 424 p_default_physp = p_rphysp; 425 426 fprintf(file, "{ %s%s Ports:%02X SystemGUID:%016" PRIx64 427 " NodeGUID:%016" PRIx64 " PortGUID:%016" PRIx64 428 " VenID:%08X DevID:%04X Rev:%08X {%s} LID:%04X PN:%02X } ", 429 p_nbnode->node_info.node_type == IB_NODE_TYPE_SWITCH ? 430 "SW" : p_nbnode->node_info.node_type == 431 IB_NODE_TYPE_CA ? "CA" : 432 p_nbnode->node_info.node_type == IB_NODE_TYPE_ROUTER ? 433 "Rt" : "**", 434 p_default_physp->port_info.base_lid == 435 p_default_physp->port_info. 436 master_sm_base_lid ? "-SM" : "", 437 p_nbnode->node_info.num_ports, 438 cl_ntoh64(p_nbnode->node_info.sys_guid), 439 cl_ntoh64(p_nbnode->node_info.node_guid), 440 cl_ntoh64(p_rphysp->port_guid), 441 cl_ntoh32(ib_node_info_get_vendor_id 442 (&p_nbnode->node_info)), 443 cl_ntoh32(p_nbnode->node_info.device_id), 444 cl_ntoh32(p_nbnode->node_info.revision), 445 p_nbnode->print_desc, 446 cl_ntoh16(p_default_physp->port_info.base_lid), 447 p_rphysp->port_num); 448 449 port_state = ib_port_info_get_port_state(&p_physp->port_info); 450 link_speed_act = 451 ib_port_info_get_link_speed_active(&p_physp->port_info); 452 if (link_speed_act == IB_LINK_SPEED_ACTIVE_2_5) 453 link_speed_act_str = "2.5"; 454 else if (link_speed_act == IB_LINK_SPEED_ACTIVE_5) 455 link_speed_act_str = "5"; 456 else if (link_speed_act == IB_LINK_SPEED_ACTIVE_10) 457 link_speed_act_str = "10"; 458 else 459 link_speed_act_str = "??"; 460 461 if (p_physp->ext_port_info.link_speed_active & FDR10) 462 link_speed_act_str = "FDR10"; 463 464 if (p_default_physp->port_info.capability_mask & IB_PORT_CAP_HAS_EXT_SPEEDS) { 465 link_speed_act = 466 ib_port_info_get_link_speed_ext_active(&p_physp->port_info); 467 if (link_speed_act == IB_LINK_SPEED_EXT_ACTIVE_14) 468 link_speed_act_str = "14"; 469 else if (link_speed_act == IB_LINK_SPEED_EXT_ACTIVE_25) 470 link_speed_act_str = "25"; 471 else if (link_speed_act != IB_LINK_SPEED_EXT_ACTIVE_NONE) 472 link_speed_act_str = "??"; 473 } 474 475 if (p_physp->port_info.link_width_active == 1) 476 link_width_act_str = "1x"; 477 else if (p_physp->port_info.link_width_active == 2) 478 link_width_act_str = "4x"; 479 else if (p_physp->port_info.link_width_active == 4) 480 link_width_act_str = "8x"; 481 else if (p_physp->port_info.link_width_active == 8) 482 link_width_act_str = "12x"; 483 else link_width_act_str = "??"; 484 485 if (p_default_physp->port_info.capability_mask2 & 486 IB_PORT_CAP2_IS_LINK_WIDTH_2X_SUPPORTED) { 487 if (p_physp->port_info.link_width_active == 16) 488 link_width_act_str = "2x"; 489 } 490 491 fprintf(file, "PHY=%s LOG=%s SPD=%s\n", 492 link_width_act_str, 493 port_state == IB_LINK_ACTIVE ? "ACT" : 494 port_state == IB_LINK_ARMED ? "ARM" : 495 port_state == IB_LINK_INIT ? "INI" : "DWN", 496 link_speed_act_str); 497 } 498 } 499 500 static void dump_sl2vl_tbl(cl_map_item_t * item, FILE * file, void *cxt) 501 { 502 osm_port_t *p_port = (osm_port_t *) item; 503 osm_node_t *p_node = p_port->p_node; 504 uint32_t in_port, out_port, 505 num_ports = p_node->node_info.num_ports; 506 ib_net16_t base_lid = osm_port_get_base_lid(p_port); 507 osm_physp_t *p_physp; 508 ib_slvl_table_t *p_tbl; 509 int i, n; 510 char buf[1024]; 511 const char * header_line = "#in out : 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15"; 512 const char * separator_line = "#--------------------------------------------------------"; 513 514 if (!num_ports) 515 return; 516 517 fprintf(file, "%s 0x%016" PRIx64 ", base LID %d, " 518 "\"%s\"\n%s\n%s\n", 519 ib_get_node_type_str(p_node->node_info.node_type), 520 cl_ntoh64(p_port->guid), cl_ntoh16(base_lid), 521 p_node->print_desc, header_line, separator_line); 522 523 if (p_node->node_info.node_type == IB_NODE_TYPE_SWITCH) { 524 for (out_port = 0; out_port <= num_ports; out_port++){ 525 p_physp = osm_node_get_physp_ptr(p_node, out_port); 526 527 /* no need to print SL2VL table for port that is down */ 528 if (!p_physp || !p_physp->p_remote_physp) 529 continue; 530 531 for (in_port = 0; in_port <= num_ports; in_port++) { 532 p_tbl = osm_physp_get_slvl_tbl(p_physp, in_port); 533 for (i = 0, n = 0; i < 16; i++) 534 n += sprintf(buf + n, " %-2d", 535 ib_slvl_table_get(p_tbl, i)); 536 fprintf(file, "%-3d %-3d :%s\n", 537 in_port, out_port, buf); 538 } 539 } 540 } else { 541 p_physp = p_port->p_physp; 542 p_tbl = osm_physp_get_slvl_tbl(p_physp, 0); 543 for (i = 0, n = 0; i < 16; i++) 544 n += sprintf(buf + n, " %-2d", 545 ib_slvl_table_get(p_tbl, i)); 546 fprintf(file, "%-3d %-3d :%s\n", 0, 0, buf); 547 } 548 549 fprintf(file, "%s\n\n", separator_line); 550 } 551 552 static void print_node_report(cl_map_item_t * item, FILE * file, void *cxt) 553 { 554 osm_node_t *p_node = (osm_node_t *) item; 555 osm_opensm_t *osm = cxt; 556 const osm_physp_t *p_physp, *p_remote_physp; 557 const ib_port_info_t *p_pi; 558 uint8_t port_num; 559 uint32_t num_ports; 560 uint8_t node_type; 561 562 node_type = osm_node_get_type(p_node); 563 564 num_ports = osm_node_get_num_physp(p_node); 565 port_num = node_type == IB_NODE_TYPE_SWITCH ? 0 : 1; 566 for (; port_num < num_ports; port_num++) { 567 p_physp = osm_node_get_physp_ptr(p_node, port_num); 568 if (!p_physp) 569 continue; 570 571 fprintf(file, "%-11s : %s : %02X :", 572 osm_get_manufacturer_str(cl_ntoh64 573 (osm_node_get_node_guid 574 (p_node))), 575 osm_get_node_type_str_fixed_width(node_type), port_num); 576 577 p_pi = &p_physp->port_info; 578 579 /* 580 * Port state is not defined for base switch port 0 581 */ 582 if (port_num == 0 && 583 ib_switch_info_is_enhanced_port0(&p_node->sw->switch_info) == FALSE) 584 fprintf(file, " :"); 585 else 586 fprintf(file, " %s :", 587 osm_get_port_state_str_fixed_width 588 (ib_port_info_get_port_state(p_pi))); 589 590 /* 591 * LID values are only meaningful in select cases. 592 */ 593 if (ib_port_info_get_port_state(p_pi) != IB_LINK_DOWN 594 && ((node_type == IB_NODE_TYPE_SWITCH && port_num == 0) 595 || node_type != IB_NODE_TYPE_SWITCH)) 596 fprintf(file, " %04X : %01X :", 597 cl_ntoh16(p_pi->base_lid), 598 ib_port_info_get_lmc(p_pi)); 599 else 600 fprintf(file, " : :"); 601 602 if (port_num == 0 && 603 ib_switch_info_is_enhanced_port0(&p_node->sw->switch_info) == FALSE) 604 fprintf(file, " : : "); 605 else 606 fprintf(file, " %s : %s : %s ", 607 osm_get_mtu_str 608 (ib_port_info_get_neighbor_mtu(p_pi)), 609 osm_get_lwa_str(p_pi->link_width_active), 610 osm_get_lsa_str 611 (ib_port_info_get_link_speed_active(p_pi), 612 ib_port_info_get_link_speed_ext_active(p_pi), 613 ib_port_info_get_port_state(p_pi), 614 p_physp->ext_port_info.link_speed_active & FDR10)); 615 616 if (osm_physp_get_port_guid(p_physp) == osm->subn.sm_port_guid) 617 fprintf(file, "* %016" PRIx64 " *", 618 cl_ntoh64(osm_physp_get_port_guid(p_physp))); 619 else 620 fprintf(file, ": %016" PRIx64 " :", 621 cl_ntoh64(osm_physp_get_port_guid(p_physp))); 622 623 if (port_num 624 && (ib_port_info_get_port_state(p_pi) != IB_LINK_DOWN)) { 625 p_remote_physp = osm_physp_get_remote(p_physp); 626 if (p_remote_physp) 627 fprintf(file, " %016" PRIx64 " (%02X)", 628 cl_ntoh64(osm_physp_get_port_guid 629 (p_remote_physp)), 630 osm_physp_get_port_num(p_remote_physp)); 631 else 632 fprintf(file, " UNKNOWN"); 633 } 634 635 fprintf(file, "\n"); 636 } 637 638 fprintf(file, "------------------------------------------------------" 639 "------------------------------------------------\n"); 640 } 641 642 struct dump_context { 643 osm_opensm_t *p_osm; 644 FILE *file; 645 void (*func) (cl_map_item_t *, FILE *, void *); 646 void *cxt; 647 }; 648 649 static void dump_item(cl_map_item_t * item, void *cxt) 650 { 651 ((struct dump_context *)cxt)->func(item, 652 ((struct dump_context *)cxt)->file, 653 ((struct dump_context *)cxt)->cxt); 654 } 655 656 static void dump_qmap(FILE * file, cl_qmap_t * map, 657 void (*func) (cl_map_item_t *, FILE *, void *), void *cxt) 658 { 659 struct dump_context dump_context; 660 661 dump_context.file = file; 662 dump_context.func = func; 663 dump_context.cxt = cxt; 664 665 cl_qmap_apply_func(map, dump_item, &dump_context); 666 } 667 668 void osm_dump_qmap_to_file(osm_opensm_t * p_osm, const char *file_name, 669 cl_qmap_t * map, 670 void (*func) (cl_map_item_t *, FILE *, void *), 671 void *cxt) 672 { 673 char path[1024]; 674 FILE *file; 675 676 snprintf(path, sizeof(path), "%s/%s", 677 p_osm->subn.opt.dump_files_dir, file_name); 678 679 file = fopen(path, "w"); 680 if (!file) { 681 OSM_LOG(&p_osm->log, OSM_LOG_ERROR, 682 "cannot create file \'%s\': %s\n", 683 path, strerror(errno)); 684 return; 685 } 686 687 dump_qmap(file, map, func, cxt); 688 689 fclose(file); 690 } 691 692 693 static void print_report(osm_opensm_t * osm, FILE * file) 694 { 695 fprintf(file, "\n===================================================" 696 "====================================================\n" 697 "Vendor : Ty : # : Sta : LID : LMC : MTU : LWA :" 698 " LSA : Port GUID : Neighbor Port (Port #)\n"); 699 dump_qmap(stdout, &osm->subn.node_guid_tbl, print_node_report, osm); 700 } 701 702 void osm_dump_mcast_routes(osm_opensm_t * osm) 703 { 704 if (OSM_LOG_IS_ACTIVE_V2(&osm->log, OSM_LOG_ROUTING)) 705 /* multicast routes */ 706 osm_dump_qmap_to_file(osm, "opensm.mcfdbs", 707 &osm->subn.sw_guid_tbl, 708 dump_mcast_routes, osm); 709 } 710 711 void osm_dump_all(osm_opensm_t * osm) 712 { 713 if (OSM_LOG_IS_ACTIVE_V2(&osm->log, OSM_LOG_ROUTING)) { 714 /* unicast routes */ 715 osm_dump_qmap_to_file(osm, "opensm-lid-matrix.dump", 716 &osm->subn.sw_guid_tbl, dump_lid_matrix, 717 osm); 718 osm_dump_qmap_to_file(osm, "opensm-lfts.dump", 719 &osm->subn.sw_guid_tbl, dump_ucast_lfts, 720 osm); 721 if (OSM_LOG_IS_ACTIVE_V2(&osm->log, OSM_LOG_DEBUG)) 722 dump_qmap(stdout, &osm->subn.sw_guid_tbl, 723 dump_ucast_path_distribution, osm); 724 725 /* An attempt to get osm_switch_recommend_path to report the 726 same routes that a sweep would assign. */ 727 if (osm->subn.opt.scatter_ports) 728 srandom(osm->subn.opt.scatter_ports); 729 730 osm_dump_qmap_to_file(osm, "opensm.fdbs", 731 &osm->subn.sw_guid_tbl, 732 dump_ucast_routes, osm); 733 /* multicast routes */ 734 osm_dump_qmap_to_file(osm, "opensm.mcfdbs", 735 &osm->subn.sw_guid_tbl, 736 dump_mcast_routes, osm); 737 /* SL2VL tables */ 738 if (osm->subn.opt.qos || 739 (osm->routing_engine_used && 740 osm->routing_engine_used->update_sl2vl)) 741 osm_dump_qmap_to_file(osm, "opensm-sl2vl.dump", 742 &osm->subn.port_guid_tbl, 743 dump_sl2vl_tbl, osm); 744 } 745 osm_dump_qmap_to_file(osm, "opensm-subnet.lst", 746 &osm->subn.node_guid_tbl, dump_topology_node, 747 osm); 748 if (OSM_LOG_IS_ACTIVE_V2(&osm->log, OSM_LOG_VERBOSE)) 749 print_report(osm, stdout); 750 } 751