1219820Sjeff/* 2219820Sjeff * Copyright (c) 2004-2008 Voltaire, Inc. All rights reserved. 3219820Sjeff * Copyright (c) 2002-2006 Mellanox Technologies LTD. All rights reserved. 4219820Sjeff * Copyright (c) 1996-2003 Intel Corporation. All rights reserved. 5219820Sjeff * 6219820Sjeff * This software is available to you under a choice of one of two 7219820Sjeff * licenses. You may choose to be licensed under the terms of the GNU 8219820Sjeff * General Public License (GPL) Version 2, available from the file 9219820Sjeff * COPYING in the main directory of this source tree, or the 10219820Sjeff * OpenIB.org BSD license below: 11219820Sjeff * 12219820Sjeff * Redistribution and use in source and binary forms, with or 13219820Sjeff * without modification, are permitted provided that the following 14219820Sjeff * conditions are met: 15219820Sjeff * 16219820Sjeff * - Redistributions of source code must retain the above 17219820Sjeff * copyright notice, this list of conditions and the following 18219820Sjeff * disclaimer. 19219820Sjeff * 20219820Sjeff * - Redistributions in binary form must reproduce the above 21219820Sjeff * copyright notice, this list of conditions and the following 22219820Sjeff * disclaimer in the documentation and/or other materials 23219820Sjeff * provided with the distribution. 24219820Sjeff * 25219820Sjeff * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26219820Sjeff * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 27219820Sjeff * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 28219820Sjeff * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 29219820Sjeff * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 30219820Sjeff * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 31219820Sjeff * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 32219820Sjeff * SOFTWARE. 33219820Sjeff * 34219820Sjeff */ 35219820Sjeff 36219820Sjeff/* 37219820Sjeff * Abstract: 38219820Sjeff * Various OpenSM dumpers 39219820Sjeff */ 40219820Sjeff 41219820Sjeff#if HAVE_CONFIG_H 42219820Sjeff# include <config.h> 43219820Sjeff#endif /* HAVE_CONFIG_H */ 44219820Sjeff 45219820Sjeff#include <unistd.h> 46219820Sjeff#include <stdlib.h> 47219820Sjeff#include <string.h> 48219820Sjeff#include <errno.h> 49219820Sjeff#include <iba/ib_types.h> 50219820Sjeff#include <complib/cl_qmap.h> 51219820Sjeff#include <complib/cl_debug.h> 52219820Sjeff#include <opensm/osm_opensm.h> 53219820Sjeff#include <opensm/osm_log.h> 54219820Sjeff#include <opensm/osm_node.h> 55219820Sjeff#include <opensm/osm_switch.h> 56219820Sjeff#include <opensm/osm_helper.h> 57219820Sjeff#include <opensm/osm_msgdef.h> 58219820Sjeff#include <opensm/osm_opensm.h> 59219820Sjeff 60219820Sjeffstatic void dump_ucast_path_distribution(cl_map_item_t * p_map_item, 61219820Sjeff FILE *file, void *cxt) 62219820Sjeff{ 63219820Sjeff osm_node_t *p_node; 64219820Sjeff osm_node_t *p_remote_node; 65219820Sjeff uint8_t i; 66219820Sjeff uint8_t num_ports; 67219820Sjeff uint32_t num_paths; 68219820Sjeff ib_net64_t remote_guid_ho; 69219820Sjeff osm_switch_t *p_sw = (osm_switch_t *) p_map_item; 70219820Sjeff 71219820Sjeff p_node = p_sw->p_node; 72219820Sjeff num_ports = p_sw->num_ports; 73219820Sjeff 74219820Sjeff fprintf(file, "dump_ucast_path_distribution: Switch 0x%" PRIx64 "\n" 75219820Sjeff "Port : Path Count Through Port", 76219820Sjeff cl_ntoh64(osm_node_get_node_guid(p_node))); 77219820Sjeff 78219820Sjeff for (i = 0; i < num_ports; i++) { 79219820Sjeff num_paths = osm_switch_path_count_get(p_sw, i); 80219820Sjeff fprintf(file, "\n %03u : %u", i, num_paths); 81219820Sjeff if (i == 0) { 82219820Sjeff fprintf(file, " (switch management port)"); 83219820Sjeff continue; 84219820Sjeff } 85219820Sjeff 86219820Sjeff p_remote_node = osm_node_get_remote_node(p_node, i, NULL); 87219820Sjeff if (p_remote_node == NULL) 88219820Sjeff continue; 89219820Sjeff 90219820Sjeff remote_guid_ho = 91219820Sjeff cl_ntoh64(osm_node_get_node_guid(p_remote_node)); 92219820Sjeff 93219820Sjeff switch (osm_node_get_type(p_remote_node)) { 94219820Sjeff case IB_NODE_TYPE_SWITCH: 95219820Sjeff fprintf(file, " (link to switch"); 96219820Sjeff break; 97219820Sjeff case IB_NODE_TYPE_ROUTER: 98219820Sjeff fprintf(file, " (link to router"); 99219820Sjeff break; 100219820Sjeff case IB_NODE_TYPE_CA: 101219820Sjeff fprintf(file, " (link to CA"); 102219820Sjeff break; 103219820Sjeff default: 104219820Sjeff fprintf(file, " (link to unknown node type"); 105219820Sjeff break; 106219820Sjeff } 107219820Sjeff 108219820Sjeff fprintf(file, " 0x%" PRIx64 ")", remote_guid_ho); 109219820Sjeff } 110219820Sjeff 111219820Sjeff fprintf(file, "\n"); 112219820Sjeff} 113219820Sjeff 114219820Sjeffstatic void dump_ucast_routes(cl_map_item_t *p_map_item, FILE *file, void *cxt) 115219820Sjeff{ 116219820Sjeff const osm_node_t *p_node; 117219820Sjeff osm_port_t *p_port; 118219820Sjeff uint8_t port_num; 119219820Sjeff uint8_t num_hops; 120219820Sjeff uint8_t best_hops; 121219820Sjeff uint8_t best_port; 122219820Sjeff uint16_t max_lid_ho; 123219820Sjeff uint16_t lid_ho, base_lid; 124219820Sjeff boolean_t direct_route_exists = FALSE; 125219820Sjeff boolean_t dor; 126219820Sjeff osm_switch_t *p_sw = (osm_switch_t *) p_map_item; 127219820Sjeff osm_opensm_t *p_osm = cxt; 128219820Sjeff 129219820Sjeff p_node = p_sw->p_node; 130219820Sjeff 131219820Sjeff max_lid_ho = p_sw->max_lid_ho; 132219820Sjeff 133219820Sjeff fprintf(file, "__osm_ucast_mgr_dump_ucast_routes: " 134219820Sjeff "Switch 0x%016" PRIx64 "\nLID : Port : Hops : Optimal\n", 135219820Sjeff cl_ntoh64(osm_node_get_node_guid(p_node))); 136219820Sjeff 137219820Sjeff dor = (p_osm->routing_engine_used == OSM_ROUTING_ENGINE_TYPE_DOR); 138219820Sjeff 139219820Sjeff for (lid_ho = 1; lid_ho <= max_lid_ho; lid_ho++) { 140219820Sjeff fprintf(file, "0x%04X : ", lid_ho); 141219820Sjeff 142219820Sjeff p_port = cl_ptr_vector_get(&p_osm->subn.port_lid_tbl, lid_ho); 143219820Sjeff if (!p_port) { 144219820Sjeff fprintf(file, "UNREACHABLE\n"); 145219820Sjeff continue; 146219820Sjeff } 147219820Sjeff 148219820Sjeff port_num = osm_switch_get_port_by_lid(p_sw, lid_ho); 149219820Sjeff if (port_num == OSM_NO_PATH) { 150219820Sjeff /* 151219820Sjeff This may occur if there are 'holes' in the existing 152219820Sjeff LID assignments. Running SM with --reassign_lids 153219820Sjeff will reassign and compress the LID range. The 154219820Sjeff subnet should work fine either way. 155219820Sjeff */ 156219820Sjeff fprintf(file, "UNREACHABLE\n"); 157219820Sjeff continue; 158219820Sjeff } 159219820Sjeff /* 160219820Sjeff Switches can lie about which port routes a given 161219820Sjeff lid due to a recent reconfiguration of the subnet. 162219820Sjeff Therefore, ensure that the hop count is better than 163219820Sjeff OSM_NO_PATH. 164219820Sjeff */ 165219820Sjeff if (p_port->p_node->sw) { 166219820Sjeff /* Target LID is switch. 167219820Sjeff Get its base lid and check hop count for this base LID only. */ 168219820Sjeff base_lid = osm_node_get_base_lid(p_port->p_node, 0); 169219820Sjeff base_lid = cl_ntoh16(base_lid); 170219820Sjeff num_hops = 171219820Sjeff osm_switch_get_hop_count(p_sw, base_lid, port_num); 172219820Sjeff } else { 173219820Sjeff /* Target LID is not switch (CA or router). 174219820Sjeff Check if we have route to this target from current switch. */ 175219820Sjeff num_hops = 176219820Sjeff osm_switch_get_hop_count(p_sw, lid_ho, port_num); 177219820Sjeff if (num_hops != OSM_NO_PATH) { 178219820Sjeff direct_route_exists = TRUE; 179219820Sjeff base_lid = lid_ho; 180219820Sjeff } else { 181219820Sjeff osm_physp_t *p_physp = p_port->p_physp; 182219820Sjeff 183219820Sjeff if (!p_physp || !p_physp->p_remote_physp || 184219820Sjeff !p_physp->p_remote_physp->p_node->sw) 185219820Sjeff num_hops = OSM_NO_PATH; 186219820Sjeff else { 187219820Sjeff base_lid = 188219820Sjeff osm_node_get_base_lid(p_physp-> 189219820Sjeff p_remote_physp-> 190219820Sjeff p_node, 0); 191219820Sjeff base_lid = cl_ntoh16(base_lid); 192219820Sjeff num_hops = 193219820Sjeff p_physp->p_remote_physp->p_node-> 194219820Sjeff sw == 195219820Sjeff p_sw ? 0 : 196219820Sjeff osm_switch_get_hop_count(p_sw, 197219820Sjeff base_lid, 198219820Sjeff port_num); 199219820Sjeff } 200219820Sjeff } 201219820Sjeff } 202219820Sjeff 203219820Sjeff if (num_hops == OSM_NO_PATH) { 204219820Sjeff fprintf(file, "UNREACHABLE\n"); 205219820Sjeff continue; 206219820Sjeff } 207219820Sjeff 208219820Sjeff best_hops = osm_switch_get_least_hops(p_sw, base_lid); 209219820Sjeff if (!p_port->p_node->sw && !direct_route_exists) { 210219820Sjeff best_hops++; 211219820Sjeff num_hops++; 212219820Sjeff } 213219820Sjeff 214219820Sjeff fprintf(file, "%03u : %02u : ", port_num, num_hops); 215219820Sjeff 216219820Sjeff if (best_hops == num_hops) 217219820Sjeff fprintf(file, "yes"); 218219820Sjeff else { 219219820Sjeff /* No LMC Optimization */ 220219820Sjeff best_port = osm_switch_recommend_path(p_sw, p_port, 221219820Sjeff lid_ho, 1, TRUE, 222219820Sjeff dor); 223219820Sjeff fprintf(file, "No %u hop path possible via port %u!", 224219820Sjeff best_hops, best_port); 225219820Sjeff } 226219820Sjeff 227219820Sjeff fprintf(file, "\n"); 228219820Sjeff } 229219820Sjeff} 230219820Sjeff 231219820Sjeffstatic void dump_mcast_routes(cl_map_item_t *p_map_item, FILE *file, void *cxt) 232219820Sjeff{ 233219820Sjeff osm_switch_t *p_sw = (osm_switch_t *) p_map_item; 234219820Sjeff osm_mcast_tbl_t *p_tbl; 235219820Sjeff int16_t mlid_ho = 0; 236219820Sjeff int16_t mlid_start_ho; 237219820Sjeff uint8_t position = 0; 238219820Sjeff int16_t block_num = 0; 239219820Sjeff boolean_t first_mlid; 240219820Sjeff boolean_t first_port; 241219820Sjeff const osm_node_t *p_node; 242219820Sjeff uint16_t i, j; 243219820Sjeff uint16_t mask_entry; 244219820Sjeff char sw_hdr[256]; 245219820Sjeff char mlid_hdr[32]; 246219820Sjeff 247219820Sjeff p_node = p_sw->p_node; 248219820Sjeff 249219820Sjeff p_tbl = osm_switch_get_mcast_tbl_ptr(p_sw); 250219820Sjeff 251219820Sjeff sprintf(sw_hdr, "\nSwitch 0x%016" PRIx64 "\nLID : Out Port(s)\n", 252219820Sjeff cl_ntoh64(osm_node_get_node_guid(p_node))); 253219820Sjeff first_mlid = TRUE; 254219820Sjeff while (block_num <= p_tbl->max_block_in_use) { 255219820Sjeff mlid_start_ho = (uint16_t) (block_num * IB_MCAST_BLOCK_SIZE); 256219820Sjeff for (i = 0; i < IB_MCAST_BLOCK_SIZE; i++) { 257219820Sjeff mlid_ho = mlid_start_ho + i; 258219820Sjeff position = 0; 259219820Sjeff first_port = TRUE; 260219820Sjeff sprintf(mlid_hdr, "0x%04X :", 261219820Sjeff mlid_ho + IB_LID_MCAST_START_HO); 262219820Sjeff while (position <= p_tbl->max_position) { 263219820Sjeff mask_entry = 264219820Sjeff cl_ntoh16((*p_tbl-> 265219820Sjeff p_mask_tbl)[mlid_ho][position]); 266219820Sjeff if (mask_entry == 0) { 267219820Sjeff position++; 268219820Sjeff continue; 269219820Sjeff } 270219820Sjeff for (j = 0; j < 16; j++) { 271219820Sjeff if ((1 << j) & mask_entry) { 272219820Sjeff if (first_mlid) { 273219820Sjeff fprintf(file, "%s", 274219820Sjeff sw_hdr); 275219820Sjeff first_mlid = FALSE; 276219820Sjeff } 277219820Sjeff if (first_port) { 278219820Sjeff fprintf(file, "%s", 279219820Sjeff mlid_hdr); 280219820Sjeff first_port = FALSE; 281219820Sjeff } 282219820Sjeff fprintf(file, " 0x%03X ", 283219820Sjeff j + (position * 16)); 284219820Sjeff } 285219820Sjeff } 286219820Sjeff position++; 287219820Sjeff } 288219820Sjeff if (first_port == FALSE) 289219820Sjeff fprintf(file, "\n"); 290219820Sjeff } 291219820Sjeff block_num++; 292219820Sjeff } 293219820Sjeff} 294219820Sjeff 295219820Sjeffstatic void dump_lid_matrix(cl_map_item_t *p_map_item, FILE *file, void *cxt) 296219820Sjeff{ 297219820Sjeff osm_switch_t *p_sw = (osm_switch_t *) p_map_item; 298219820Sjeff osm_opensm_t *p_osm = cxt; 299219820Sjeff osm_node_t *p_node = p_sw->p_node; 300219820Sjeff unsigned max_lid = p_sw->max_lid_ho; 301219820Sjeff unsigned max_port = p_sw->num_ports; 302219820Sjeff uint16_t lid; 303219820Sjeff uint8_t port; 304219820Sjeff 305219820Sjeff fprintf(file, "Switch: guid 0x%016" PRIx64 "\n", 306219820Sjeff cl_ntoh64(osm_node_get_node_guid(p_node))); 307219820Sjeff for (lid = 1; lid <= max_lid; lid++) { 308219820Sjeff osm_port_t *p_port; 309219820Sjeff if (osm_switch_get_least_hops(p_sw, lid) == OSM_NO_PATH) 310219820Sjeff continue; 311219820Sjeff fprintf(file, "0x%04x:", lid); 312219820Sjeff for (port = 0; port < max_port; port++) 313219820Sjeff fprintf(file, " %02x", 314219820Sjeff osm_switch_get_hop_count(p_sw, lid, port)); 315219820Sjeff p_port = cl_ptr_vector_get(&p_osm->subn.port_lid_tbl, lid); 316219820Sjeff if (p_port) 317219820Sjeff fprintf(file, " # portguid 0x016%" PRIx64, 318219820Sjeff cl_ntoh64(osm_port_get_guid(p_port))); 319219820Sjeff fprintf(file, "\n"); 320219820Sjeff } 321219820Sjeff} 322219820Sjeff 323219820Sjeffstatic void dump_ucast_lfts(cl_map_item_t *p_map_item, FILE *file, void *cxt) 324219820Sjeff{ 325219820Sjeff osm_switch_t *p_sw = (osm_switch_t *) p_map_item; 326219820Sjeff osm_opensm_t *p_osm = cxt; 327219820Sjeff osm_node_t *p_node = p_sw->p_node; 328219820Sjeff unsigned max_lid = p_sw->max_lid_ho; 329219820Sjeff unsigned max_port = p_sw->num_ports; 330219820Sjeff uint16_t lid; 331219820Sjeff uint8_t port; 332219820Sjeff 333219820Sjeff fprintf(file, "Unicast lids [0-%u] of switch Lid %u guid 0x%016" 334219820Sjeff PRIx64 " (\'%s\'):\n", 335219820Sjeff max_lid, cl_ntoh16(osm_node_get_base_lid(p_node, 0)), 336219820Sjeff cl_ntoh64(osm_node_get_node_guid(p_node)), p_node->print_desc); 337219820Sjeff for (lid = 0; lid <= max_lid; lid++) { 338219820Sjeff osm_port_t *p_port; 339219820Sjeff port = osm_switch_get_port_by_lid(p_sw, lid); 340219820Sjeff 341219820Sjeff if (port >= max_port) 342219820Sjeff continue; 343219820Sjeff 344219820Sjeff fprintf(file, "0x%04x %03u # ", lid, port); 345219820Sjeff 346219820Sjeff p_port = cl_ptr_vector_get(&p_osm->subn.port_lid_tbl, lid); 347219820Sjeff if (p_port) { 348219820Sjeff p_node = p_port->p_node; 349219820Sjeff fprintf(file, "%s portguid 0x%016" PRIx64 ": \'%s\'", 350219820Sjeff ib_get_node_type_str(osm_node_get_type(p_node)), 351219820Sjeff cl_ntoh64(osm_port_get_guid(p_port)), 352219820Sjeff p_node->print_desc); 353219820Sjeff } else 354219820Sjeff fprintf(file, "unknown node and type"); 355219820Sjeff fprintf(file, "\n"); 356219820Sjeff } 357219820Sjeff fprintf(file, "%u lids dumped\n", max_lid); 358219820Sjeff} 359219820Sjeff 360219820Sjeffstatic void dump_topology_node(cl_map_item_t *p_map_item, FILE *file, void *cxt) 361219820Sjeff{ 362219820Sjeff osm_node_t *p_node = (osm_node_t *) p_map_item; 363219820Sjeff uint32_t cPort; 364219820Sjeff osm_node_t *p_nbnode; 365219820Sjeff osm_physp_t *p_physp, *p_default_physp, *p_rphysp; 366219820Sjeff uint8_t link_speed_act; 367219820Sjeff 368219820Sjeff if (!p_node->node_info.num_ports) 369219820Sjeff return; 370219820Sjeff 371219820Sjeff for (cPort = 1; cPort < osm_node_get_num_physp(p_node); cPort++) { 372219820Sjeff uint8_t port_state; 373219820Sjeff 374219820Sjeff p_physp = osm_node_get_physp_ptr(p_node, cPort); 375219820Sjeff if (!p_physp) 376219820Sjeff continue; 377219820Sjeff 378219820Sjeff p_rphysp = p_physp->p_remote_physp; 379219820Sjeff if (!p_rphysp) 380219820Sjeff continue; 381219820Sjeff 382219820Sjeff CL_ASSERT(cPort == p_physp->port_num); 383219820Sjeff 384219820Sjeff if (p_node->node_info.node_type == IB_NODE_TYPE_SWITCH) 385219820Sjeff p_default_physp = osm_node_get_physp_ptr(p_node, 0); 386219820Sjeff else 387219820Sjeff p_default_physp = p_physp; 388219820Sjeff 389219820Sjeff fprintf(file, "{ %s%s Ports:%02X SystemGUID:%016" PRIx64 390219820Sjeff " NodeGUID:%016" PRIx64 " PortGUID:%016" PRIx64 391219820Sjeff " VenID:%06X DevID:%04X Rev:%08X {%s} LID:%04X PN:%02X } ", 392219820Sjeff p_node->node_info.node_type == IB_NODE_TYPE_SWITCH ? 393219820Sjeff "SW" : p_node->node_info.node_type == 394219820Sjeff IB_NODE_TYPE_CA ? "CA" : p_node->node_info.node_type == 395219820Sjeff IB_NODE_TYPE_ROUTER ? "Rt" : "**", 396219820Sjeff p_default_physp->port_info.base_lid == 397219820Sjeff p_default_physp->port_info. 398219820Sjeff master_sm_base_lid ? "-SM" : "", 399219820Sjeff p_node->node_info.num_ports, 400219820Sjeff cl_ntoh64(p_node->node_info.sys_guid), 401219820Sjeff cl_ntoh64(p_node->node_info.node_guid), 402219820Sjeff cl_ntoh64(p_physp->port_guid), 403219820Sjeff cl_ntoh32(ib_node_info_get_vendor_id 404219820Sjeff (&p_node->node_info)), 405219820Sjeff cl_ntoh16(p_node->node_info.device_id), 406219820Sjeff cl_ntoh32(p_node->node_info.revision), 407219820Sjeff p_node->print_desc, 408219820Sjeff cl_ntoh16(p_default_physp->port_info.base_lid), cPort); 409219820Sjeff 410219820Sjeff p_nbnode = p_rphysp->p_node; 411219820Sjeff 412219820Sjeff if (p_nbnode->node_info.node_type == IB_NODE_TYPE_SWITCH) 413219820Sjeff p_default_physp = osm_node_get_physp_ptr(p_nbnode, 0); 414219820Sjeff else 415219820Sjeff p_default_physp = p_rphysp; 416219820Sjeff 417219820Sjeff fprintf(file, "{ %s%s Ports:%02X SystemGUID:%016" PRIx64 418219820Sjeff " NodeGUID:%016" PRIx64 " PortGUID:%016" PRIx64 419219820Sjeff " VenID:%08X DevID:%04X Rev:%08X {%s} LID:%04X PN:%02X } ", 420219820Sjeff p_nbnode->node_info.node_type == IB_NODE_TYPE_SWITCH ? 421219820Sjeff "SW" : p_nbnode->node_info.node_type == 422219820Sjeff IB_NODE_TYPE_CA ? "CA" : 423219820Sjeff p_nbnode->node_info.node_type == IB_NODE_TYPE_ROUTER ? 424219820Sjeff "Rt" : "**", 425219820Sjeff p_default_physp->port_info.base_lid == 426219820Sjeff p_default_physp->port_info. 427219820Sjeff master_sm_base_lid ? "-SM" : "", 428219820Sjeff p_nbnode->node_info.num_ports, 429219820Sjeff cl_ntoh64(p_nbnode->node_info.sys_guid), 430219820Sjeff cl_ntoh64(p_nbnode->node_info.node_guid), 431219820Sjeff cl_ntoh64(p_rphysp->port_guid), 432219820Sjeff cl_ntoh32(ib_node_info_get_vendor_id 433219820Sjeff (&p_nbnode->node_info)), 434219820Sjeff cl_ntoh32(p_nbnode->node_info.device_id), 435219820Sjeff cl_ntoh32(p_nbnode->node_info.revision), 436219820Sjeff p_nbnode->print_desc, 437219820Sjeff cl_ntoh16(p_default_physp->port_info.base_lid), 438219820Sjeff p_rphysp->port_num); 439219820Sjeff 440219820Sjeff port_state = ib_port_info_get_port_state(&p_physp->port_info); 441219820Sjeff link_speed_act = 442219820Sjeff ib_port_info_get_link_speed_active(&p_physp->port_info); 443219820Sjeff 444219820Sjeff fprintf(file, "PHY=%s LOG=%s SPD=%s\n", 445219820Sjeff p_physp->port_info.link_width_active == 1 ? "1x" : 446219820Sjeff p_physp->port_info.link_width_active == 2 ? "4x" : 447219820Sjeff p_physp->port_info.link_width_active == 8 ? "12x" : 448219820Sjeff "??", 449219820Sjeff port_state == IB_LINK_ACTIVE ? "ACT" : 450219820Sjeff port_state == IB_LINK_ARMED ? "ARM" : 451219820Sjeff port_state == IB_LINK_INIT ? "INI" : "DWN", 452219820Sjeff link_speed_act == 1 ? "2.5" : 453219820Sjeff link_speed_act == 2 ? "5" : 454219820Sjeff link_speed_act == 4 ? "10" : "??"); 455219820Sjeff } 456219820Sjeff} 457219820Sjeff 458219820Sjeffstatic void print_node_report(cl_map_item_t *p_map_item, FILE *file, void *cxt) 459219820Sjeff{ 460219820Sjeff osm_node_t *p_node = (osm_node_t *) p_map_item; 461219820Sjeff osm_opensm_t *osm = cxt; 462219820Sjeff const osm_physp_t *p_physp, *p_remote_physp; 463219820Sjeff const ib_port_info_t *p_pi; 464219820Sjeff uint8_t port_num; 465219820Sjeff uint32_t num_ports; 466219820Sjeff uint8_t node_type; 467219820Sjeff 468219820Sjeff node_type = osm_node_get_type(p_node); 469219820Sjeff 470219820Sjeff num_ports = osm_node_get_num_physp(p_node); 471219820Sjeff port_num = node_type == IB_NODE_TYPE_SWITCH ? 0 : 1; 472219820Sjeff for (; port_num < num_ports; port_num++) { 473219820Sjeff p_physp = osm_node_get_physp_ptr(p_node, port_num); 474219820Sjeff if (!p_physp) 475219820Sjeff continue; 476219820Sjeff 477219820Sjeff fprintf(file, "%-11s : %s : %02X :", 478219820Sjeff osm_get_manufacturer_str(cl_ntoh64 479219820Sjeff (osm_node_get_node_guid 480219820Sjeff (p_node))), 481219820Sjeff osm_get_node_type_str_fixed_width(node_type), port_num); 482219820Sjeff 483219820Sjeff p_pi = &p_physp->port_info; 484219820Sjeff 485219820Sjeff /* 486219820Sjeff * Port state is not defined for switch port 0 487219820Sjeff */ 488219820Sjeff if (port_num == 0) 489219820Sjeff fprintf(file, " :"); 490219820Sjeff else 491219820Sjeff fprintf(file, " %s :", 492219820Sjeff osm_get_port_state_str_fixed_width 493219820Sjeff (ib_port_info_get_port_state(p_pi))); 494219820Sjeff 495219820Sjeff /* 496219820Sjeff * LID values are only meaningful in select cases. 497219820Sjeff */ 498219820Sjeff if (ib_port_info_get_port_state(p_pi) != IB_LINK_DOWN 499219820Sjeff && ((node_type == IB_NODE_TYPE_SWITCH && port_num == 0) 500219820Sjeff || node_type != IB_NODE_TYPE_SWITCH)) 501219820Sjeff fprintf(file, " %04X : %01X :", 502219820Sjeff cl_ntoh16(p_pi->base_lid), 503219820Sjeff ib_port_info_get_lmc(p_pi)); 504219820Sjeff else 505219820Sjeff fprintf(file, " : :"); 506219820Sjeff 507219820Sjeff if (port_num != 0) 508219820Sjeff fprintf(file, " %s : %s : %s ", 509219820Sjeff osm_get_mtu_str 510219820Sjeff (ib_port_info_get_neighbor_mtu(p_pi)), 511219820Sjeff osm_get_lwa_str(p_pi->link_width_active), 512219820Sjeff osm_get_lsa_str 513219820Sjeff (ib_port_info_get_link_speed_active(p_pi))); 514219820Sjeff else 515219820Sjeff fprintf(file, " : : "); 516219820Sjeff 517219820Sjeff if (osm_physp_get_port_guid(p_physp) == osm->subn.sm_port_guid) 518219820Sjeff fprintf(file, "* %016" PRIx64 " *", 519219820Sjeff cl_ntoh64(osm_physp_get_port_guid(p_physp))); 520219820Sjeff else 521219820Sjeff fprintf(file, ": %016" PRIx64 " :", 522219820Sjeff cl_ntoh64(osm_physp_get_port_guid(p_physp))); 523219820Sjeff 524219820Sjeff if (port_num 525219820Sjeff && (ib_port_info_get_port_state(p_pi) != IB_LINK_DOWN)) { 526219820Sjeff p_remote_physp = osm_physp_get_remote(p_physp); 527219820Sjeff if (p_remote_physp) 528219820Sjeff fprintf(file, " %016" PRIx64 " (%02X)", 529219820Sjeff cl_ntoh64(osm_physp_get_port_guid 530219820Sjeff (p_remote_physp)), 531219820Sjeff osm_physp_get_port_num(p_remote_physp)); 532219820Sjeff else 533219820Sjeff fprintf(file, " UNKNOWN"); 534219820Sjeff } 535219820Sjeff 536219820Sjeff fprintf(file, "\n"); 537219820Sjeff } 538219820Sjeff 539219820Sjeff fprintf(file, "------------------------------------------------------" 540219820Sjeff "------------------------------------------------\n"); 541219820Sjeff} 542219820Sjeff 543219820Sjeff/********************************************************************** 544219820Sjeff **********************************************************************/ 545219820Sjeffstruct dump_context { 546219820Sjeff osm_opensm_t *p_osm; 547219820Sjeff FILE *file; 548219820Sjeff void (*func) (cl_map_item_t *, FILE *, void *); 549219820Sjeff void *cxt; 550219820Sjeff}; 551219820Sjeff 552219820Sjeffstatic void dump_item(cl_map_item_t *item, void *cxt) 553219820Sjeff{ 554219820Sjeff ((struct dump_context *)cxt)->func(item, 555219820Sjeff ((struct dump_context *)cxt)->file, 556219820Sjeff ((struct dump_context *)cxt)->cxt); 557219820Sjeff} 558219820Sjeff 559219820Sjeffstatic void dump_qmap(FILE *file, cl_qmap_t *map, 560219820Sjeff void (*func)(cl_map_item_t *, FILE *, void *), void *cxt) 561219820Sjeff{ 562219820Sjeff struct dump_context dump_context; 563219820Sjeff 564219820Sjeff dump_context.file = file; 565219820Sjeff dump_context.func = func; 566219820Sjeff dump_context.cxt = cxt; 567219820Sjeff 568219820Sjeff cl_qmap_apply_func(map, dump_item, &dump_context); 569219820Sjeff} 570219820Sjeff 571219820Sjeffvoid osm_dump_qmap_to_file(osm_opensm_t * p_osm, const char *file_name, 572219820Sjeff cl_qmap_t * map, 573219820Sjeff void (*func) (cl_map_item_t *, FILE *, void *), 574219820Sjeff void *cxt) 575219820Sjeff{ 576219820Sjeff char path[1024]; 577219820Sjeff FILE *file; 578219820Sjeff 579219820Sjeff snprintf(path, sizeof(path), "%s/%s", 580219820Sjeff p_osm->subn.opt.dump_files_dir, file_name); 581219820Sjeff 582219820Sjeff file = fopen(path, "w"); 583219820Sjeff if (!file) { 584219820Sjeff OSM_LOG(&p_osm->log, OSM_LOG_ERROR, 585219820Sjeff "cannot create file \'%s\': %s\n", 586219820Sjeff path, strerror(errno)); 587219820Sjeff return; 588219820Sjeff } 589219820Sjeff 590219820Sjeff dump_qmap(file, map, func, cxt); 591219820Sjeff 592219820Sjeff fclose(file); 593219820Sjeff} 594219820Sjeff 595219820Sjeff/********************************************************************** 596219820Sjeff **********************************************************************/ 597219820Sjeff 598219820Sjeffstatic void print_report(osm_opensm_t *osm, FILE *file) 599219820Sjeff{ 600219820Sjeff fprintf(file, "\n===================================================" 601219820Sjeff "====================================================\n" 602219820Sjeff "Vendor : Ty : # : Sta : LID : LMC : MTU : LWA :" 603219820Sjeff " LSA : Port GUID : Neighbor Port (Port #)\n"); 604219820Sjeff dump_qmap(stdout, &osm->subn.node_guid_tbl, print_node_report, osm); 605219820Sjeff} 606219820Sjeff 607219820Sjeffvoid osm_dump_mcast_routes(osm_opensm_t * osm) 608219820Sjeff{ 609219820Sjeff if (osm_log_is_active(&osm->log, OSM_LOG_ROUTING)) 610219820Sjeff /* multicast routes */ 611219820Sjeff osm_dump_qmap_to_file(osm, "opensm.mcfdbs", 612219820Sjeff &osm->subn.sw_guid_tbl, 613219820Sjeff dump_mcast_routes, osm); 614219820Sjeff} 615219820Sjeff 616219820Sjeffvoid osm_dump_all(osm_opensm_t * osm) 617219820Sjeff{ 618219820Sjeff if (osm_log_is_active(&osm->log, OSM_LOG_ROUTING)) { 619219820Sjeff /* unicast routes */ 620219820Sjeff osm_dump_qmap_to_file(osm, "opensm-lid-matrix.dump", 621219820Sjeff &osm->subn.sw_guid_tbl, dump_lid_matrix, 622219820Sjeff osm); 623219820Sjeff osm_dump_qmap_to_file(osm, "opensm-lfts.dump", 624219820Sjeff &osm->subn.sw_guid_tbl, dump_ucast_lfts, 625219820Sjeff osm); 626219820Sjeff if (osm_log_is_active(&osm->log, OSM_LOG_DEBUG)) 627219820Sjeff dump_qmap(stdout, &osm->subn.sw_guid_tbl, 628219820Sjeff dump_ucast_path_distribution, osm); 629219820Sjeff osm_dump_qmap_to_file(osm, "opensm.fdbs", 630219820Sjeff &osm->subn.sw_guid_tbl, 631219820Sjeff dump_ucast_routes, osm); 632219820Sjeff /* multicast routes */ 633219820Sjeff osm_dump_qmap_to_file(osm, "opensm.mcfdbs", 634219820Sjeff &osm->subn.sw_guid_tbl, 635219820Sjeff dump_mcast_routes, osm); 636219820Sjeff } 637219820Sjeff osm_dump_qmap_to_file(osm, "opensm-subnet.lst", 638219820Sjeff &osm->subn.node_guid_tbl, dump_topology_node, 639219820Sjeff osm); 640219820Sjeff if (osm_log_is_active(&osm->log, OSM_LOG_VERBOSE)) 641219820Sjeff print_report(osm, stdout); 642219820Sjeff} 643