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