2 * Copyright (c) 2006,2007 The Regents of the University of California.
3 * Copyright (c) 2004-2008 Voltaire, Inc. All rights reserved.
4 * Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved.
5 * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
7 * Produced at Lawrence Livermore National Laboratory.
8 * Written by Ira Weiny <weiny2@llnl.gov>.
10 * This software is available to you under a choice of one of two
11 * licenses. You may choose to be licensed under the terms of the GNU
12 * General Public License (GPL) Version 2, available from the file
13 * COPYING in the main directory of this source tree, or the
14 * OpenIB.org BSD license below:
16 * Redistribution and use in source and binary forms, with or
17 * without modification, are permitted provided that the following
20 * - Redistributions of source code must retain the above
21 * copyright notice, this list of conditions and the following
24 * - Redistributions in binary form must reproduce the above
25 * copyright notice, this list of conditions and the following
26 * disclaimer in the documentation and/or other materials
27 * provided with the distribution.
29 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
30 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
31 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
32 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
33 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
34 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
35 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
42 #include <sys/types.h>
43 #include <sys/socket.h>
44 #include <arpa/inet.h>
52 #include <infiniband/mad.h>
53 #include <infiniband/opensm/osm_log.h>
54 #include <infiniband/vendor/osm_vendor_api.h>
55 #include <infiniband/vendor/osm_vendor_sa_api.h>
56 #include <infiniband/opensm/osm_mad_pool.h>
57 #include <infiniband/complib/cl_debug.h>
58 #include <infiniband/complib/cl_nodenamemap.h>
60 #include <netinet/in.h>
62 #include "ibdiag_common.h"
65 const char *name, *alias;
66 ib_net16_t query_type;
68 int (*handler) (const struct query_cmd * q, osm_bind_handle_t h,
69 int argc, char *argv[]);
72 char *argv0 = "saquery";
74 static char *node_name_map_file = NULL;
75 static nn_map_t *node_name_map = NULL;
76 static ib_net64_t smkey = OSM_DEFAULT_SA_KEY;
79 * Declare some globals because I don't want this to be too complex.
82 #define DEFAULT_SA_TIMEOUT_MS (1000)
83 osmv_query_res_t result;
85 osm_mad_pool_t mad_pool;
86 osm_vendor_t *vendor = NULL;
88 uint32_t sa_timeout_ms = DEFAULT_SA_TIMEOUT_MS;
89 char *sa_hca_name = NULL;
90 uint32_t sa_port_num = 0;
100 } node_print_desc = ALL;
102 char *requested_name = NULL;
103 ib_net16_t requested_lid = 0;
104 int requested_lid_flag = 0;
105 ib_net64_t requested_guid = 0;
106 int requested_guid_flag = 0;
108 static void format_buf(char *in, char *out, unsigned size)
112 for (i = 0; i < size - 3 && *in; i++) {
114 if (*in++ == '\n' && *in) {
123 * Call back for the various record requests.
125 static void query_res_cb(osmv_query_res_t * res)
130 static void print_node_desc(ib_node_record_t * node_record)
132 ib_node_info_t *p_ni = &(node_record->node_info);
133 ib_node_desc_t *p_nd = &(node_record->node_desc);
135 if (p_ni->node_type == IB_NODE_TYPE_CA) {
136 printf("%6d \"%s\"\n",
137 cl_ntoh16(node_record->lid),
138 clean_nodedesc((char *)p_nd->description));
142 static void print_node_record(ib_node_record_t * node_record)
144 ib_node_info_t *p_ni = NULL;
145 ib_node_desc_t *p_nd = NULL;
148 p_ni = &(node_record->node_info);
149 p_nd = &(node_record->node_desc);
151 switch (node_print_desc) {
153 case UNIQUE_LID_ONLY:
154 printf("%d\n", cl_ntoh16(node_record->lid));
157 printf("0x%016" PRIx64 "\n", cl_ntoh64(p_ni->port_guid));
161 name = remap_node_name(node_name_map,
162 cl_ntoh64(p_ni->node_guid),
163 (char *)p_nd->description);
164 printf("%s\n", name);
172 printf("NodeRecord dump:\n"
173 "\t\tlid.....................0x%X\n"
174 "\t\treserved................0x%X\n"
175 "\t\tbase_version............0x%X\n"
176 "\t\tclass_version...........0x%X\n"
177 "\t\tnode_type...............%s\n"
178 "\t\tnum_ports...............0x%X\n"
179 "\t\tsys_guid................0x%016" PRIx64 "\n"
180 "\t\tnode_guid...............0x%016" PRIx64 "\n"
181 "\t\tport_guid...............0x%016" PRIx64 "\n"
182 "\t\tpartition_cap...........0x%X\n"
183 "\t\tdevice_id...............0x%X\n"
184 "\t\trevision................0x%X\n"
185 "\t\tport_num................0x%X\n"
186 "\t\tvendor_id...............0x%X\n"
187 "\t\tNodeDescription.........%s\n"
189 cl_ntoh16(node_record->lid),
190 cl_ntoh16(node_record->resv),
193 ib_get_node_type_str(p_ni->node_type),
195 cl_ntoh64(p_ni->sys_guid),
196 cl_ntoh64(p_ni->node_guid),
197 cl_ntoh64(p_ni->port_guid),
198 cl_ntoh16(p_ni->partition_cap),
199 cl_ntoh16(p_ni->device_id),
200 cl_ntoh32(p_ni->revision),
201 ib_node_info_get_local_port_num(p_ni),
202 cl_ntoh32(ib_node_info_get_vendor_id(p_ni)),
203 clean_nodedesc((char *)node_record->node_desc.description)
207 static void dump_path_record(void *data)
209 char gid_str[INET6_ADDRSTRLEN];
210 char gid_str2[INET6_ADDRSTRLEN];
211 ib_path_rec_t *p_pr = data;
212 printf("PathRecord dump:\n"
213 "\t\tservice_id..............0x%016" PRIx64 "\n"
214 "\t\tdgid....................%s\n"
215 "\t\tsgid....................%s\n"
216 "\t\tdlid....................0x%X\n"
217 "\t\tslid....................0x%X\n"
218 "\t\thop_flow_raw............0x%X\n"
219 "\t\ttclass..................0x%X\n"
220 "\t\tnum_path_revers.........0x%X\n"
221 "\t\tpkey....................0x%X\n"
222 "\t\tqos_class...............0x%X\n"
223 "\t\tsl......................0x%X\n"
224 "\t\tmtu.....................0x%X\n"
225 "\t\trate....................0x%X\n"
226 "\t\tpkt_life................0x%X\n"
227 "\t\tpreference..............0x%X\n"
228 "\t\tresv2...................0x%X\n"
229 "\t\tresv3...................0x%X\n"
231 cl_ntoh64(p_pr->service_id),
232 inet_ntop(AF_INET6, p_pr->dgid.raw, gid_str, sizeof gid_str),
233 inet_ntop(AF_INET6, p_pr->sgid.raw, gid_str2, sizeof gid_str2),
234 cl_ntoh16(p_pr->dlid),
235 cl_ntoh16(p_pr->slid),
236 cl_ntoh32(p_pr->hop_flow_raw),
239 cl_ntoh16(p_pr->pkey),
240 ib_path_rec_qos_class(p_pr),
241 ib_path_rec_sl(p_pr),
246 *(uint32_t *) & p_pr->resv2, *((uint16_t *) & p_pr->resv2 + 2)
250 static void dump_class_port_info(void *data)
252 char gid_str[INET6_ADDRSTRLEN];
253 char gid_str2[INET6_ADDRSTRLEN];
254 ib_class_port_info_t *class_port_info = data;
256 printf("SA ClassPortInfo:\n"
257 "\t\tBase version.............%d\n"
258 "\t\tClass version............%d\n"
259 "\t\tCapability mask..........0x%04X\n"
260 "\t\tCapability mask 2........0x%08X\n"
261 "\t\tResponse time value......0x%02X\n"
262 "\t\tRedirect GID.............%s\n"
263 "\t\tRedirect TC/SL/FL........0x%08X\n"
264 "\t\tRedirect LID.............0x%04X\n"
265 "\t\tRedirect PKey............0x%04X\n"
266 "\t\tRedirect QP..............0x%08X\n"
267 "\t\tRedirect QKey............0x%08X\n"
268 "\t\tTrap GID.................%s\n"
269 "\t\tTrap TC/SL/FL............0x%08X\n"
270 "\t\tTrap LID.................0x%04X\n"
271 "\t\tTrap PKey................0x%04X\n"
272 "\t\tTrap HL/QP...............0x%08X\n"
273 "\t\tTrap QKey................0x%08X\n"
275 class_port_info->base_ver,
276 class_port_info->class_ver,
277 cl_ntoh16(class_port_info->cap_mask),
278 ib_class_cap_mask2(class_port_info),
279 ib_class_resp_time_val(class_port_info),
280 inet_ntop(AF_INET6, &(class_port_info->redir_gid), gid_str,
282 cl_ntoh32(class_port_info->redir_tc_sl_fl),
283 cl_ntoh16(class_port_info->redir_lid),
284 cl_ntoh16(class_port_info->redir_pkey),
285 cl_ntoh32(class_port_info->redir_qp),
286 cl_ntoh32(class_port_info->redir_qkey),
287 inet_ntop(AF_INET6, &(class_port_info->trap_gid), gid_str2,
289 cl_ntoh32(class_port_info->trap_tc_sl_fl),
290 cl_ntoh16(class_port_info->trap_lid),
291 cl_ntoh16(class_port_info->trap_pkey),
292 cl_ntoh32(class_port_info->trap_hop_qp),
293 cl_ntoh32(class_port_info->trap_qkey)
297 static void dump_portinfo_record(void *data)
299 ib_portinfo_record_t *p_pir = data;
300 const ib_port_info_t *const p_pi = &p_pir->port_info;
302 printf("PortInfoRecord dump:\n"
303 "\t\tEndPortLid..............0x%X\n"
304 "\t\tPortNum.................0x%X\n"
305 "\t\tbase_lid................0x%X\n"
306 "\t\tmaster_sm_base_lid......0x%X\n"
307 "\t\tcapability_mask.........0x%X\n"
309 cl_ntoh16(p_pir->lid),
311 cl_ntoh16(p_pi->base_lid),
312 cl_ntoh16(p_pi->master_sm_base_lid),
313 cl_ntoh32(p_pi->capability_mask)
317 static void dump_one_portinfo_record(void *data)
319 char buf[2048], buf2[4096];
320 ib_portinfo_record_t *pir = data;
321 ib_port_info_t *pi = &pir->port_info;
323 mad_dump_portinfo(buf, sizeof(buf), pi, sizeof(*pi));
325 format_buf(buf, buf2, sizeof(buf2));
327 printf("PortInfoRecord dump:\n"
329 "\t\tEndPortLid..............%u\n"
330 "\t\tPortNum.................0x%x\n"
331 "\t\tReserved................0x%x\n"
332 "\tPortInfo dump:\n\t\t%s",
333 cl_ntoh16(pir->lid), pir->port_num, pir->resv, buf2);
336 static void dump_multicast_group_record(void *data)
338 char gid_str[INET6_ADDRSTRLEN];
339 ib_member_rec_t *p_mcmr = data;
341 ib_member_get_sl_flow_hop(p_mcmr->sl_flow_hop, &sl, NULL, NULL);
342 printf("MCMemberRecord group dump:\n"
343 "\t\tMGID....................%s\n"
344 "\t\tMlid....................0x%X\n"
345 "\t\tMtu.....................0x%X\n"
346 "\t\tpkey....................0x%X\n"
347 "\t\tRate....................0x%X\n"
348 "\t\tSL......................0x%X\n"
350 inet_ntop(AF_INET6, p_mcmr->mgid.raw, gid_str, sizeof gid_str),
351 cl_ntoh16(p_mcmr->mlid),
352 p_mcmr->mtu, cl_ntoh16(p_mcmr->pkey), p_mcmr->rate, sl);
355 static void dump_multicast_member_record(void *data)
357 char gid_str[INET6_ADDRSTRLEN];
358 char gid_str2[INET6_ADDRSTRLEN];
359 ib_member_rec_t *p_mcmr = data;
360 uint16_t mlid = cl_ntoh16(p_mcmr->mlid);
362 char *node_name = "<unknown>";
364 /* go through the node records searching for a port guid which matches
365 * this port gid interface id.
366 * This gives us a node name to print, if available.
368 for (i = 0; i < result.result_cnt; i++) {
369 ib_node_record_t *nr =
370 osmv_get_query_node_rec(result.p_result_madw, i);
371 if (nr->node_info.port_guid ==
372 p_mcmr->port_gid.unicast.interface_id) {
374 clean_nodedesc((char *)nr->node_desc.description);
379 if (requested_name) {
380 if (strtol(requested_name, NULL, 0) == mlid) {
381 printf("\t\tPortGid.................%s (%s)\n",
382 inet_ntop(AF_INET6, p_mcmr->port_gid.raw,
383 gid_str, sizeof gid_str), node_name);
386 printf("MCMemberRecord member dump:\n"
387 "\t\tMGID....................%s\n"
388 "\t\tMlid....................0x%X\n"
389 "\t\tPortGid.................%s\n"
390 "\t\tScopeState..............0x%X\n"
391 "\t\tProxyJoin...............0x%X\n"
392 "\t\tNodeDescription.........%s\n"
394 inet_ntop(AF_INET6, p_mcmr->mgid.raw, gid_str,
396 cl_ntoh16(p_mcmr->mlid),
397 inet_ntop(AF_INET6, p_mcmr->port_gid.raw,
398 gid_str2, sizeof gid_str2),
399 p_mcmr->scope_state, p_mcmr->proxy_join, node_name);
403 static void dump_service_record(void *data)
405 char gid_str[INET6_ADDRSTRLEN];
406 char buf_service_key[35];
407 char buf_service_name[65];
408 ib_service_record_t *p_sr = data;
410 sprintf(buf_service_key,
411 "0x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
412 p_sr->service_key[0], p_sr->service_key[1],
413 p_sr->service_key[2], p_sr->service_key[3],
414 p_sr->service_key[4], p_sr->service_key[5],
415 p_sr->service_key[6], p_sr->service_key[7],
416 p_sr->service_key[8], p_sr->service_key[9],
417 p_sr->service_key[10], p_sr->service_key[11],
418 p_sr->service_key[12], p_sr->service_key[13],
419 p_sr->service_key[14], p_sr->service_key[15]);
420 strncpy(buf_service_name, (char *)p_sr->service_name, 64);
421 buf_service_name[64] = '\0';
423 printf("ServiceRecord dump:\n"
424 "\t\tServiceID...............0x%016" PRIx64 "\n"
425 "\t\tServiceGID..............%s\n"
426 "\t\tServiceP_Key............0x%X\n"
427 "\t\tServiceLease............0x%X\n"
428 "\t\tServiceKey..............%s\n"
429 "\t\tServiceName.............%s\n"
430 "\t\tServiceData8.1..........0x%X\n"
431 "\t\tServiceData8.2..........0x%X\n"
432 "\t\tServiceData8.3..........0x%X\n"
433 "\t\tServiceData8.4..........0x%X\n"
434 "\t\tServiceData8.5..........0x%X\n"
435 "\t\tServiceData8.6..........0x%X\n"
436 "\t\tServiceData8.7..........0x%X\n"
437 "\t\tServiceData8.8..........0x%X\n"
438 "\t\tServiceData8.9..........0x%X\n"
439 "\t\tServiceData8.10.........0x%X\n"
440 "\t\tServiceData8.11.........0x%X\n"
441 "\t\tServiceData8.12.........0x%X\n"
442 "\t\tServiceData8.13.........0x%X\n"
443 "\t\tServiceData8.14.........0x%X\n"
444 "\t\tServiceData8.15.........0x%X\n"
445 "\t\tServiceData8.16.........0x%X\n"
446 "\t\tServiceData16.1.........0x%X\n"
447 "\t\tServiceData16.2.........0x%X\n"
448 "\t\tServiceData16.3.........0x%X\n"
449 "\t\tServiceData16.4.........0x%X\n"
450 "\t\tServiceData16.5.........0x%X\n"
451 "\t\tServiceData16.6.........0x%X\n"
452 "\t\tServiceData16.7.........0x%X\n"
453 "\t\tServiceData16.8.........0x%X\n"
454 "\t\tServiceData32.1.........0x%X\n"
455 "\t\tServiceData32.2.........0x%X\n"
456 "\t\tServiceData32.3.........0x%X\n"
457 "\t\tServiceData32.4.........0x%X\n"
458 "\t\tServiceData64.1.........0x%016" PRIx64 "\n"
459 "\t\tServiceData64.2.........0x%016" PRIx64 "\n"
461 cl_ntoh64(p_sr->service_id),
462 inet_ntop(AF_INET6, p_sr->service_gid.raw, gid_str,
464 cl_ntoh16(p_sr->service_pkey),
465 cl_ntoh32(p_sr->service_lease),
468 p_sr->service_data8[0], p_sr->service_data8[1],
469 p_sr->service_data8[2], p_sr->service_data8[3],
470 p_sr->service_data8[4], p_sr->service_data8[5],
471 p_sr->service_data8[6], p_sr->service_data8[7],
472 p_sr->service_data8[8], p_sr->service_data8[9],
473 p_sr->service_data8[10], p_sr->service_data8[11],
474 p_sr->service_data8[12], p_sr->service_data8[13],
475 p_sr->service_data8[14], p_sr->service_data8[15],
476 cl_ntoh16(p_sr->service_data16[0]),
477 cl_ntoh16(p_sr->service_data16[1]),
478 cl_ntoh16(p_sr->service_data16[2]),
479 cl_ntoh16(p_sr->service_data16[3]),
480 cl_ntoh16(p_sr->service_data16[4]),
481 cl_ntoh16(p_sr->service_data16[5]),
482 cl_ntoh16(p_sr->service_data16[6]),
483 cl_ntoh16(p_sr->service_data16[7]),
484 cl_ntoh32(p_sr->service_data32[0]),
485 cl_ntoh32(p_sr->service_data32[1]),
486 cl_ntoh32(p_sr->service_data32[2]),
487 cl_ntoh32(p_sr->service_data32[3]),
488 cl_ntoh64(p_sr->service_data64[0]),
489 cl_ntoh64(p_sr->service_data64[1])
493 static void dump_inform_info_record(void *data)
495 char gid_str[INET6_ADDRSTRLEN];
496 char gid_str2[INET6_ADDRSTRLEN];
497 ib_inform_info_record_t *p_iir = data;
499 uint8_t resp_time_val;
501 ib_inform_info_get_qpn_resp_time(p_iir->inform_info.g_or_v.generic.
502 qpn_resp_time_val, &qpn,
505 if (p_iir->inform_info.is_generic) {
506 printf("InformInfoRecord dump:\n"
508 "\t\tSubscriberGID...........%s\n"
509 "\t\tSubscriberEnum..........0x%X\n"
510 "\t\tInformInfo dump:\n"
511 "\t\tgid.....................%s\n"
512 "\t\tlid_range_begin.........0x%X\n"
513 "\t\tlid_range_end...........0x%X\n"
514 "\t\tis_generic..............0x%X\n"
515 "\t\tsubscribe...............0x%X\n"
516 "\t\ttrap_type...............0x%X\n"
517 "\t\ttrap_num................%u\n"
518 "\t\tqpn.....................0x%06X\n"
519 "\t\tresp_time_val...........0x%X\n"
520 "\t\tnode_type...............0x%06X\n"
522 inet_ntop(AF_INET6, p_iir->subscriber_gid.raw, gid_str,
524 cl_ntoh16(p_iir->subscriber_enum),
525 inet_ntop(AF_INET6, p_iir->inform_info.gid.raw, gid_str2,
527 cl_ntoh16(p_iir->inform_info.lid_range_begin),
528 cl_ntoh16(p_iir->inform_info.lid_range_end),
529 p_iir->inform_info.is_generic,
530 p_iir->inform_info.subscribe,
531 cl_ntoh16(p_iir->inform_info.trap_type),
532 cl_ntoh16(p_iir->inform_info.g_or_v.generic.trap_num),
535 cl_ntoh32(ib_inform_info_get_prod_type
536 (&p_iir->inform_info))
539 printf("InformInfoRecord dump:\n"
541 "\t\tSubscriberGID...........%s\n"
542 "\t\tSubscriberEnum..........0x%X\n"
543 "\t\tInformInfo dump:\n"
544 "\t\tgid.....................%s\n"
545 "\t\tlid_range_begin.........0x%X\n"
546 "\t\tlid_range_end...........0x%X\n"
547 "\t\tis_generic..............0x%X\n"
548 "\t\tsubscribe...............0x%X\n"
549 "\t\ttrap_type...............0x%X\n"
550 "\t\tdev_id..................0x%X\n"
551 "\t\tqpn.....................0x%06X\n"
552 "\t\tresp_time_val...........0x%X\n"
553 "\t\tvendor_id...............0x%06X\n"
555 inet_ntop(AF_INET6, p_iir->subscriber_gid.raw, gid_str,
557 cl_ntoh16(p_iir->subscriber_enum),
558 inet_ntop(AF_INET6, p_iir->inform_info.gid.raw,
559 gid_str2, sizeof gid_str2),
560 cl_ntoh16(p_iir->inform_info.lid_range_begin),
561 cl_ntoh16(p_iir->inform_info.lid_range_end),
562 p_iir->inform_info.is_generic,
563 p_iir->inform_info.subscribe,
564 cl_ntoh16(p_iir->inform_info.trap_type),
565 cl_ntoh16(p_iir->inform_info.g_or_v.vend.dev_id),
568 cl_ntoh32(ib_inform_info_get_prod_type
569 (&p_iir->inform_info))
574 static void dump_one_link_record(void *data)
576 ib_link_record_t *lr = data;
577 printf("LinkRecord dump:\n"
578 "\t\tFromLID....................%u\n"
579 "\t\tFromPort...................%u\n"
580 "\t\tToPort.....................%u\n"
581 "\t\tToLID......................%u\n",
582 cl_ntoh16(lr->from_lid), lr->from_port_num,
583 lr->to_port_num, cl_ntoh16(lr->to_lid));
586 static void dump_one_slvl_record(void *data)
588 ib_slvl_table_record_t *slvl = data;
589 ib_slvl_table_t *t = &slvl->slvl_tbl;
590 printf("SL2VLTableRecord dump:\n"
591 "\t\tLID........................%u\n"
592 "\t\tInPort.....................%u\n"
593 "\t\tOutPort....................%u\n"
594 "\t\tSL: 0| 1| 2| 3| 4| 5| 6| 7| 8| 9|10|11|12|13|14|15|\n"
595 "\t\tVL:%2u|%2u|%2u|%2u|%2u|%2u|%2u|%2u|%2u|%2u|%2u|%2u|%2u"
597 cl_ntoh16(slvl->lid), slvl->in_port_num, slvl->out_port_num,
598 ib_slvl_table_get(t, 0), ib_slvl_table_get(t, 1),
599 ib_slvl_table_get(t, 2), ib_slvl_table_get(t, 3),
600 ib_slvl_table_get(t, 4), ib_slvl_table_get(t, 5),
601 ib_slvl_table_get(t, 6), ib_slvl_table_get(t, 7),
602 ib_slvl_table_get(t, 8), ib_slvl_table_get(t, 9),
603 ib_slvl_table_get(t, 10), ib_slvl_table_get(t, 11),
604 ib_slvl_table_get(t, 12), ib_slvl_table_get(t, 13),
605 ib_slvl_table_get(t, 14), ib_slvl_table_get(t, 15));
608 static void dump_one_vlarb_record(void *data)
610 ib_vl_arb_table_record_t *vlarb = data;
611 ib_vl_arb_element_t *e = vlarb->vl_arb_tbl.vl_entry;
613 printf("VLArbTableRecord dump:\n"
614 "\t\tLID........................%u\n"
615 "\t\tPort.......................%u\n"
616 "\t\tBlock......................%u\n",
617 cl_ntoh16(vlarb->lid), vlarb->port_num, vlarb->block_num);
618 for (i = 0; i < 32; i += 16) {
619 printf("\t\tVL :%2u|%2u|%2u|%2u|%2u|%2u|%2u|%2u|"
620 "%2u|%2u|%2u|%2u|%2u|%2u|%2u|%2u|",
621 e[i + 0].vl, e[i + 1].vl, e[i + 2].vl, e[i + 3].vl,
622 e[i + 4].vl, e[i + 5].vl, e[i + 6].vl, e[i + 7].vl,
623 e[i + 8].vl, e[i + 9].vl, e[i + 10].vl, e[i + 11].vl,
624 e[i + 12].vl, e[i + 13].vl, e[i + 14].vl, e[i + 15].vl);
625 printf("\n\t\tWeight:%2u|%2u|%2u|%2u|%2u|%2u|%2u|%2u|"
626 "%2u|%2u|%2u|%2u|%2u|%2u|%2u|%2u|",
627 e[i + 0].weight, e[i + 1].weight, e[i + 2].weight,
628 e[i + 3].weight, e[i + 4].weight, e[i + 5].weight,
629 e[i + 6].weight, e[i + 7].weight, e[i + 8].weight,
630 e[i + 9].weight, e[i + 10].weight, e[i + 11].weight,
631 e[i + 12].weight, e[i + 13].weight, e[i + 14].weight,
637 static void dump_one_pkey_tbl_record(void *data)
639 ib_pkey_table_record_t *pktr = data;
640 ib_net16_t *p = pktr->pkey_tbl.pkey_entry;
642 printf("PKeyTableRecord dump:\n"
643 "\t\tLID........................%u\n"
644 "\t\tPort.......................%u\n"
645 "\t\tBlock......................%u\n"
647 cl_ntoh16(pktr->lid), pktr->port_num, pktr->block_num);
648 for (i = 0; i < 32; i += 8)
649 printf("\t\t0x%04x 0x%04x 0x%04x 0x%04x"
650 " 0x%04x 0x%04x 0x%04x 0x%04x\n",
651 cl_ntoh16(p[i + 0]), cl_ntoh16(p[i + 1]),
652 cl_ntoh16(p[i + 2]), cl_ntoh16(p[i + 3]),
653 cl_ntoh16(p[i + 4]), cl_ntoh16(p[i + 5]),
654 cl_ntoh16(p[i + 6]), cl_ntoh16(p[i + 7]));
658 static void dump_one_lft_record(void *data)
660 ib_lft_record_t *lftr = data;
661 unsigned block = cl_ntoh16(lftr->block_num);
663 printf("LFT Record dump:\n"
664 "\t\tLID........................%u\n"
665 "\t\tBlock......................%u\n"
666 "\t\tLFT:\n\t\tLID\tPort Number\n", cl_ntoh16(lftr->lid), block);
667 for (i = 0; i < 64; i++)
668 printf("\t\t%u\t%u\n", block * 64 + i, lftr->lft[i]);
672 static void dump_one_mft_record(void *data)
674 ib_mft_record_t *mftr = data;
675 unsigned position = cl_ntoh16(mftr->position_block_num) >> 12;
676 unsigned block = cl_ntoh16(mftr->position_block_num) &
677 IB_MCAST_BLOCK_ID_MASK_HO;
679 printf("MFT Record dump:\n"
680 "\t\tLID........................%u\n"
681 "\t\tPosition...................%u\n"
682 "\t\tBlock......................%u\n"
683 "\t\tMFT:\n\t\tMLID\tPort Mask\n",
684 cl_ntoh16(mftr->lid), position, block);
685 for (i = 0; i < IB_MCAST_BLOCK_SIZE; i++)
686 printf("\t\t0x%x\t0x%x\n",
687 IB_LID_MCAST_START_HO + block * 64 + i,
688 cl_ntoh16(mftr->mft[i]));
691 static void dump_results(osmv_query_res_t * r, void (*dump_func) (void *))
694 for (i = 0; i < r->result_cnt; i++) {
695 void *data = osmv_get_query_result(r->p_result_madw, i);
700 static void return_mad(void)
703 * Return the IB query MAD to the pool as necessary.
705 if (result.p_result_madw != NULL) {
706 osm_mad_pool_put(&mad_pool, result.p_result_madw);
707 result.p_result_madw = NULL;
714 static ib_api_status_t
715 get_any_records(osm_bind_handle_t h,
716 ib_net16_t attr_id, ib_net32_t attr_mod, ib_net64_t comp_mask,
717 void *attr, ib_net16_t attr_offset, ib_net64_t sm_key)
719 ib_api_status_t status;
720 osmv_query_req_t req;
721 osmv_user_query_t user;
723 memset(&req, 0, sizeof(req));
724 memset(&user, 0, sizeof(user));
726 user.attr_id = attr_id;
727 user.attr_offset = attr_offset;
728 user.attr_mod = attr_mod;
729 user.comp_mask = comp_mask;
732 req.query_type = OSMV_QUERY_USER_DEFINED;
733 req.timeout_ms = sa_timeout_ms;
735 req.flags = OSM_SA_FLAGS_SYNC;
736 req.query_context = NULL;
737 req.pfn_query_cb = query_res_cb;
738 req.p_query_input = &user;
741 if ((status = osmv_query_sa(h, &req)) != IB_SUCCESS) {
742 fprintf(stderr, "Query SA failed: %s\n",
743 ib_get_err_str(status));
747 if (result.status != IB_SUCCESS) {
748 fprintf(stderr, "Query result returned: %s\n",
749 ib_get_err_str(result.status));
750 return result.status;
757 * Get all the records available for requested query type.
759 static ib_api_status_t
760 get_all_records(osm_bind_handle_t h,
761 ib_net16_t query_id, ib_net16_t attr_offset, int trusted)
763 return get_any_records(h, query_id, 0, 0, NULL, attr_offset,
764 trusted ? smkey : 0);
768 * return the lid from the node descriptor (name) supplied
770 static ib_api_status_t
771 get_lid_from_name(osm_bind_handle_t h, const char *name, ib_net16_t * lid)
774 ib_node_record_t *node_record = NULL;
775 ib_node_info_t *p_ni = NULL;
776 ib_net16_t attr_offset = ib_get_attr_offset(sizeof(*node_record));
777 ib_api_status_t status;
779 status = get_all_records(h, IB_MAD_ATTR_NODE_RECORD, attr_offset, 0);
780 if (status != IB_SUCCESS)
783 for (i = 0; i < result.result_cnt; i++) {
784 node_record = osmv_get_query_node_rec(result.p_result_madw, i);
785 p_ni = &(node_record->node_info);
787 && strncmp(name, (char *)node_record->node_desc.description,
788 sizeof(node_record->node_desc.description)) ==
790 *lid = cl_ntoh16(node_record->lid);
798 static ib_net16_t get_lid(osm_bind_handle_t h, const char *name)
800 ib_net16_t rc_lid = 0;
804 if (isalpha(name[0]))
805 assert(get_lid_from_name(h, name, &rc_lid) == IB_SUCCESS);
809 fprintf(stderr, "Failed to find lid for \"%s\"\n", name);
813 static int parse_lid_and_ports(osm_bind_handle_t h,
814 char *str, int *lid, int *port1, int *port2)
823 p = strchr(str, '/');
827 *lid = get_lid(h, str);
832 p = strchr(str, '/');
836 *port1 = strtoul(str, &e, 0);
845 *port2 = strtoul(str, &e, 0);
854 * Get the portinfo records available with IsSM or IsSMdisabled CapabilityMask bit on.
856 static ib_api_status_t
857 get_issm_records(osm_bind_handle_t h, ib_net32_t capability_mask)
859 ib_portinfo_record_t attr;
861 memset(&attr, 0, sizeof(attr));
862 attr.port_info.capability_mask = capability_mask;
864 return get_any_records(h, IB_MAD_ATTR_PORTINFO_RECORD,
865 cl_hton32(1 << 31), IB_PIR_COMPMASK_CAPMASK,
867 ib_get_attr_offset(sizeof(ib_portinfo_record_t)),
871 static ib_api_status_t print_node_records(osm_bind_handle_t h)
874 ib_node_record_t *node_record = NULL;
875 ib_net16_t attr_offset = ib_get_attr_offset(sizeof(*node_record));
876 ib_api_status_t status;
878 status = get_all_records(h, IB_MAD_ATTR_NODE_RECORD, attr_offset, 0);
879 if (status != IB_SUCCESS)
882 if (node_print_desc == ALL_DESC) {
883 printf(" LID \"name\"\n");
884 printf("================\n");
886 for (i = 0; i < result.result_cnt; i++) {
887 node_record = osmv_get_query_node_rec(result.p_result_madw, i);
888 if (node_print_desc == ALL_DESC) {
889 print_node_desc(node_record);
890 } else if (node_print_desc == NAME_OF_LID) {
891 if (requested_lid == cl_ntoh16(node_record->lid)) {
892 print_node_record(node_record);
894 } else if (node_print_desc == NAME_OF_GUID) {
895 ib_node_info_t *p_ni = &(node_record->node_info);
897 if (requested_guid == cl_ntoh64(p_ni->port_guid)) {
898 print_node_record(node_record);
901 if (!requested_name ||
902 (strncmp(requested_name,
903 (char *)node_record->node_desc.description,
904 sizeof(node_record->node_desc.
905 description)) == 0)) {
906 print_node_record(node_record);
907 if (node_print_desc == UNIQUE_LID_ONLY) {
918 static ib_api_status_t
919 get_print_path_rec_lid(osm_bind_handle_t h,
920 ib_net16_t src_lid, ib_net16_t dst_lid)
922 osmv_query_req_t req;
923 osmv_lid_pair_t lid_pair;
924 ib_api_status_t status;
926 lid_pair.src_lid = cl_hton16(src_lid);
927 lid_pair.dest_lid = cl_hton16(dst_lid);
929 memset(&req, 0, sizeof(req));
931 req.query_type = OSMV_QUERY_PATH_REC_BY_LIDS;
932 req.timeout_ms = sa_timeout_ms;
934 req.flags = OSM_SA_FLAGS_SYNC;
935 req.query_context = NULL;
936 req.pfn_query_cb = query_res_cb;
937 req.p_query_input = (void *)&lid_pair;
940 if ((status = osmv_query_sa(h, &req)) != IB_SUCCESS) {
941 fprintf(stderr, "ERROR: Query SA failed: %s\n",
942 ib_get_err_str(status));
945 if (result.status != IB_SUCCESS) {
946 fprintf(stderr, "ERROR: Query result returned: %s\n",
947 ib_get_err_str(result.status));
948 return (result.status);
950 status = result.status;
951 dump_results(&result, dump_path_record);
956 static ib_api_status_t
957 get_print_path_rec_gid(osm_bind_handle_t h,
958 const ib_gid_t * src_gid, const ib_gid_t * dst_gid)
960 osmv_query_req_t req;
961 osmv_gid_pair_t gid_pair;
962 ib_api_status_t status;
964 gid_pair.src_gid = *src_gid;
965 gid_pair.dest_gid = *dst_gid;
967 memset(&req, 0, sizeof(req));
969 req.query_type = OSMV_QUERY_PATH_REC_BY_GIDS;
970 req.timeout_ms = sa_timeout_ms;
972 req.flags = OSM_SA_FLAGS_SYNC;
973 req.query_context = NULL;
974 req.pfn_query_cb = query_res_cb;
975 req.p_query_input = (void *)&gid_pair;
978 if ((status = osmv_query_sa(h, &req)) != IB_SUCCESS) {
979 fprintf(stderr, "ERROR: Query SA failed: %s\n",
980 ib_get_err_str(status));
983 if (result.status != IB_SUCCESS) {
984 fprintf(stderr, "ERROR: Query result returned: %s\n",
985 ib_get_err_str(result.status));
986 return (result.status);
988 status = result.status;
989 dump_results(&result, dump_path_record);
994 static ib_api_status_t get_print_class_port_info(osm_bind_handle_t h)
996 osmv_query_req_t req;
997 ib_api_status_t status;
999 memset(&req, 0, sizeof(req));
1001 req.query_type = OSMV_QUERY_CLASS_PORT_INFO;
1002 req.timeout_ms = sa_timeout_ms;
1004 req.flags = OSM_SA_FLAGS_SYNC;
1005 req.query_context = NULL;
1006 req.pfn_query_cb = query_res_cb;
1007 req.p_query_input = NULL;
1010 if ((status = osmv_query_sa(h, &req)) != IB_SUCCESS) {
1011 fprintf(stderr, "ERROR: Query SA failed: %s\n",
1012 ib_get_err_str(status));
1015 if (result.status != IB_SUCCESS) {
1016 fprintf(stderr, "ERROR: Query result returned: %s\n",
1017 ib_get_err_str(result.status));
1018 return (result.status);
1020 status = result.status;
1021 dump_results(&result, dump_class_port_info);
1026 static int query_path_records(const struct query_cmd *q,
1027 osm_bind_handle_t h, int argc, char *argv[])
1029 ib_net16_t attr_offset = ib_get_attr_offset(sizeof(ib_path_rec_t));
1030 ib_api_status_t status;
1032 status = get_all_records(h, IB_MAD_ATTR_PATH_RECORD, attr_offset, 0);
1033 if (status != IB_SUCCESS)
1036 dump_results(&result, dump_path_record);
1041 static ib_api_status_t print_issm_records(osm_bind_handle_t h)
1043 ib_api_status_t status;
1045 /* First, get IsSM records */
1046 status = get_issm_records(h, IB_PORT_CAP_IS_SM);
1047 if (status != IB_SUCCESS)
1050 printf("IsSM ports\n");
1051 dump_results(&result, dump_portinfo_record);
1054 /* Now, get IsSMdisabled records */
1055 status = get_issm_records(h, IB_PORT_CAP_SM_DISAB);
1056 if (status != IB_SUCCESS)
1059 printf("\nIsSMdisabled ports\n");
1060 dump_results(&result, dump_portinfo_record);
1066 static ib_api_status_t print_multicast_member_records(osm_bind_handle_t h)
1068 osmv_query_res_t mc_group_result;
1069 ib_api_status_t status;
1071 status = get_all_records(h, IB_MAD_ATTR_MCMEMBER_RECORD,
1072 ib_get_attr_offset(sizeof(ib_member_rec_t)),
1074 if (status != IB_SUCCESS)
1077 mc_group_result = result;
1079 status = get_all_records(h, IB_MAD_ATTR_NODE_RECORD,
1080 ib_get_attr_offset(sizeof(ib_node_record_t)),
1082 if (status != IB_SUCCESS)
1085 dump_results(&mc_group_result, dump_multicast_member_record);
1089 /* return_mad for the mc_group_result */
1090 if (mc_group_result.p_result_madw != NULL) {
1091 osm_mad_pool_put(&mad_pool, mc_group_result.p_result_madw);
1092 mc_group_result.p_result_madw = NULL;
1098 static ib_api_status_t print_multicast_group_records(osm_bind_handle_t h)
1100 ib_api_status_t status;
1102 status = get_all_records(h, IB_MAD_ATTR_MCMEMBER_RECORD,
1103 ib_get_attr_offset(sizeof(ib_member_rec_t)),
1105 if (status != IB_SUCCESS)
1108 dump_results(&result, dump_multicast_group_record);
1113 static int query_class_port_info(const struct query_cmd *q,
1114 osm_bind_handle_t h, int argc, char *argv[])
1116 return get_print_class_port_info(h);
1119 static int query_node_records(const struct query_cmd *q,
1120 osm_bind_handle_t h, int argc, char *argv[])
1122 return print_node_records(h);
1125 static int query_portinfo_records(const struct query_cmd *q,
1126 osm_bind_handle_t h, int argc, char *argv[])
1128 ib_portinfo_record_t pir;
1129 ib_net64_t comp_mask = 0;
1130 int lid = 0, port = -1;
1131 ib_api_status_t status;
1134 parse_lid_and_ports(h, argv[0], &lid, &port, NULL);
1136 memset(&pir, 0, sizeof(pir));
1139 pir.lid = cl_hton16(lid);
1140 comp_mask |= IB_PIR_COMPMASK_LID;
1143 pir.port_num = cl_hton16(port);
1144 comp_mask |= IB_PIR_COMPMASK_PORTNUM;
1147 status = get_any_records(h, IB_MAD_ATTR_PORTINFO_RECORD, 0,
1149 ib_get_attr_offset(sizeof(pir)), 0);
1151 if (status != IB_SUCCESS)
1154 dump_results(&result, dump_one_portinfo_record);
1160 static int query_mcmember_records(const struct query_cmd *q,
1161 osm_bind_handle_t h, int argc, char *argv[])
1163 return print_multicast_member_records(h);
1166 static int query_service_records(const struct query_cmd *q,
1167 osm_bind_handle_t h, int argc, char *argv[])
1169 ib_net16_t attr_offset =
1170 ib_get_attr_offset(sizeof(ib_service_record_t));
1171 ib_api_status_t status;
1173 status = get_all_records(h, IB_MAD_ATTR_SERVICE_RECORD, attr_offset, 0);
1174 if (status != IB_SUCCESS)
1177 dump_results(&result, dump_service_record);
1182 static int query_informinfo_records(const struct query_cmd *q,
1183 osm_bind_handle_t h, int argc, char *argv[])
1185 ib_net16_t attr_offset =
1186 ib_get_attr_offset(sizeof(ib_inform_info_record_t));
1187 ib_api_status_t status;
1190 get_all_records(h, IB_MAD_ATTR_INFORM_INFO_RECORD, attr_offset, 0);
1191 if (status != IB_SUCCESS)
1194 dump_results(&result, dump_inform_info_record);
1199 static int query_link_records(const struct query_cmd *q,
1200 osm_bind_handle_t h, int argc, char *argv[])
1202 ib_link_record_t lr;
1203 ib_net64_t comp_mask = 0;
1204 int from_lid = 0, to_lid = 0, from_port = -1, to_port = -1;
1205 ib_api_status_t status;
1208 parse_lid_and_ports(h, argv[0], &from_lid, &from_port, NULL);
1211 parse_lid_and_ports(h, argv[1], &to_lid, &to_port, NULL);
1213 memset(&lr, 0, sizeof(lr));
1216 lr.from_lid = cl_hton16(from_lid);
1217 comp_mask |= IB_LR_COMPMASK_FROM_LID;
1219 if (from_port >= 0) {
1220 lr.from_port_num = from_port;
1221 comp_mask |= IB_LR_COMPMASK_FROM_PORT;
1224 lr.to_lid = cl_hton16(to_lid);
1225 comp_mask |= IB_LR_COMPMASK_TO_LID;
1228 lr.to_port_num = to_port;
1229 comp_mask |= IB_LR_COMPMASK_TO_PORT;
1232 status = get_any_records(h, IB_MAD_ATTR_LINK_RECORD, 0,
1234 ib_get_attr_offset(sizeof(lr)), 0);
1235 if (status != IB_SUCCESS)
1238 dump_results(&result, dump_one_link_record);
1243 static int query_sl2vl_records(const struct query_cmd *q,
1244 osm_bind_handle_t h, int argc, char *argv[])
1246 ib_slvl_table_record_t slvl;
1247 ib_net64_t comp_mask = 0;
1248 int lid = 0, in_port = -1, out_port = -1;
1249 ib_api_status_t status;
1252 parse_lid_and_ports(h, argv[0], &lid, &in_port, &out_port);
1254 memset(&slvl, 0, sizeof(slvl));
1257 slvl.lid = cl_hton16(lid);
1258 comp_mask |= IB_SLVL_COMPMASK_LID;
1261 slvl.in_port_num = in_port;
1262 comp_mask |= IB_SLVL_COMPMASK_IN_PORT;
1264 if (out_port >= 0) {
1265 slvl.out_port_num = out_port;
1266 comp_mask |= IB_SLVL_COMPMASK_OUT_PORT;
1269 status = get_any_records(h, IB_MAD_ATTR_SLVL_RECORD, 0,
1271 ib_get_attr_offset(sizeof(slvl)), 0);
1272 if (status != IB_SUCCESS)
1275 dump_results(&result, dump_one_slvl_record);
1280 static int query_vlarb_records(const struct query_cmd *q,
1281 osm_bind_handle_t h, int argc, char *argv[])
1283 ib_vl_arb_table_record_t vlarb;
1284 ib_net64_t comp_mask = 0;
1285 int lid = 0, port = -1, block = -1;
1286 ib_api_status_t status;
1289 parse_lid_and_ports(h, argv[0], &lid, &port, &block);
1291 memset(&vlarb, 0, sizeof(vlarb));
1294 vlarb.lid = cl_hton16(lid);
1295 comp_mask |= IB_VLA_COMPMASK_LID;
1298 vlarb.port_num = port;
1299 comp_mask |= IB_VLA_COMPMASK_OUT_PORT;
1302 vlarb.block_num = block;
1303 comp_mask |= IB_VLA_COMPMASK_BLOCK;
1306 status = get_any_records(h, IB_MAD_ATTR_VLARB_RECORD, 0,
1308 ib_get_attr_offset(sizeof(vlarb)), 0);
1309 if (status != IB_SUCCESS)
1312 dump_results(&result, dump_one_vlarb_record);
1317 static int query_pkey_tbl_records(const struct query_cmd *q,
1318 osm_bind_handle_t h, int argc, char *argv[])
1320 ib_pkey_table_record_t pktr;
1321 ib_net64_t comp_mask = 0;
1322 int lid = 0, port = -1, block = -1;
1323 ib_api_status_t status;
1326 parse_lid_and_ports(h, argv[0], &lid, &port, &block);
1328 memset(&pktr, 0, sizeof(pktr));
1331 pktr.lid = cl_hton16(lid);
1332 comp_mask |= IB_PKEY_COMPMASK_LID;
1335 pktr.port_num = port;
1336 comp_mask |= IB_PKEY_COMPMASK_PORT;
1339 pktr.block_num = block;
1340 comp_mask |= IB_PKEY_COMPMASK_BLOCK;
1343 status = get_any_records(h, IB_MAD_ATTR_PKEY_TBL_RECORD, 0,
1345 ib_get_attr_offset(sizeof(pktr)), smkey);
1346 if (status != IB_SUCCESS)
1349 dump_results(&result, dump_one_pkey_tbl_record);
1354 static int query_lft_records(const struct query_cmd *q,
1355 osm_bind_handle_t h, int argc, char *argv[])
1357 ib_lft_record_t lftr;
1358 ib_net64_t comp_mask = 0;
1359 int lid = 0, block = -1;
1360 ib_api_status_t status;
1363 parse_lid_and_ports(h, argv[0], &lid, &block, NULL);
1365 memset(&lftr, 0, sizeof(lftr));
1368 lftr.lid = cl_hton16(lid);
1369 comp_mask |= IB_LFTR_COMPMASK_LID;
1372 lftr.block_num = cl_hton16(block);
1373 comp_mask |= IB_LFTR_COMPMASK_BLOCK;
1376 status = get_any_records(h, IB_MAD_ATTR_LFT_RECORD, 0,
1378 ib_get_attr_offset(sizeof(lftr)), 0);
1379 if (status != IB_SUCCESS)
1382 dump_results(&result, dump_one_lft_record);
1387 static int query_mft_records(const struct query_cmd *q,
1388 osm_bind_handle_t h, int argc, char *argv[])
1390 ib_mft_record_t mftr;
1391 ib_net64_t comp_mask = 0;
1392 int lid = 0, block = -1, position = -1;
1393 ib_api_status_t status;
1396 parse_lid_and_ports(h, argv[0], &lid, &position, &block);
1398 memset(&mftr, 0, sizeof(mftr));
1401 mftr.lid = cl_hton16(lid);
1402 comp_mask |= IB_MFTR_COMPMASK_LID;
1404 if (position >= 0) {
1405 mftr.position_block_num = cl_hton16(position << 12);
1406 comp_mask |= IB_MFTR_COMPMASK_POSITION;
1409 mftr.position_block_num |=
1410 cl_hton16(block & IB_MCAST_BLOCK_ID_MASK_HO);
1411 comp_mask |= IB_MFTR_COMPMASK_BLOCK;
1414 status = get_any_records(h, IB_MAD_ATTR_MFT_RECORD, 0,
1416 ib_get_attr_offset(sizeof(mftr)), 0);
1417 if (status != IB_SUCCESS)
1420 dump_results(&result, dump_one_mft_record);
1425 static osm_bind_handle_t get_bind_handle(void)
1428 uint64_t port_guid = (uint64_t) - 1;
1429 osm_bind_handle_t h;
1430 ib_api_status_t status;
1431 ib_port_attr_t attr_array[MAX_PORTS];
1432 uint32_t num_ports = MAX_PORTS;
1433 uint32_t ca_name_index = 0;
1437 osm_log_construct(&log_osm);
1438 if ((status = osm_log_init_v2(&log_osm, TRUE, 0x0001, NULL,
1439 0, TRUE)) != IB_SUCCESS) {
1440 fprintf(stderr, "Failed to init osm_log: %s\n",
1441 ib_get_err_str(status));
1444 osm_log_set_level(&log_osm, OSM_LOG_NONE);
1446 osm_log_set_level(&log_osm, OSM_LOG_DEFAULT_LEVEL);
1448 vendor = osm_vendor_new(&log_osm, sa_timeout_ms);
1449 osm_mad_pool_construct(&mad_pool);
1450 if ((status = osm_mad_pool_init(&mad_pool)) != IB_SUCCESS) {
1451 fprintf(stderr, "Failed to init mad pool: %s\n",
1452 ib_get_err_str(status));
1457 osm_vendor_get_all_port_attr(vendor, attr_array,
1458 &num_ports)) != IB_SUCCESS) {
1459 fprintf(stderr, "Failed to get port attributes: %s\n",
1460 ib_get_err_str(status));
1464 for (i = 0; i < num_ports; i++) {
1465 if (i > 1 && cl_ntoh64(attr_array[i].port_guid)
1466 != (cl_ntoh64(attr_array[i - 1].port_guid) + 1))
1468 if (sa_port_num && sa_port_num != attr_array[i].port_num)
1471 && strcmp(sa_hca_name,
1472 vendor->ca_names[ca_name_index]) != 0)
1474 if (attr_array[i].link_state == IB_LINK_ACTIVE) {
1475 port_guid = attr_array[i].port_guid;
1480 if (port_guid == (uint64_t) - 1) {
1482 "Failed to find active port, check port status with \"ibstat\"\n");
1486 h = osmv_bind_sa(vendor, &mad_pool, port_guid);
1488 if (h == OSM_BIND_INVALID_HANDLE) {
1489 fprintf(stderr, "Failed to bind to SA\n");
1495 static void clean_up(void)
1497 osm_mad_pool_destroy(&mad_pool);
1498 osm_vendor_delete(&vendor);
1501 static const struct query_cmd query_cmds[] = {
1502 {"ClassPortInfo", "CPI", IB_MAD_ATTR_CLASS_PORT_INFO,
1503 NULL, query_class_port_info},
1504 {"NodeRecord", "NR", IB_MAD_ATTR_NODE_RECORD,
1505 NULL, query_node_records},
1506 {"PortInfoRecord", "PIR", IB_MAD_ATTR_PORTINFO_RECORD,
1507 "[[lid]/[port]]", query_portinfo_records},
1508 {"SL2VLTableRecord", "SL2VL", IB_MAD_ATTR_SLVL_RECORD,
1509 "[[lid]/[in_port]/[out_port]]", query_sl2vl_records},
1510 {"PKeyTableRecord", "PKTR", IB_MAD_ATTR_PKEY_TBL_RECORD,
1511 "[[lid]/[port]/[block]]", query_pkey_tbl_records},
1512 {"VLArbitrationTableRecord", "VLAR", IB_MAD_ATTR_VLARB_RECORD,
1513 "[[lid]/[port]/[block]]", query_vlarb_records},
1514 {"InformInfoRecord", "IIR", IB_MAD_ATTR_INFORM_INFO_RECORD,
1515 NULL, query_informinfo_records},
1516 {"LinkRecord", "LR", IB_MAD_ATTR_LINK_RECORD,
1517 "[[from_lid]/[from_port]] [[to_lid]/[to_port]]", query_link_records},
1518 {"ServiceRecord", "SR", IB_MAD_ATTR_SERVICE_RECORD,
1519 NULL, query_service_records},
1520 {"PathRecord", "PR", IB_MAD_ATTR_PATH_RECORD,
1521 NULL, query_path_records},
1522 {"MCMemberRecord", "MCMR", IB_MAD_ATTR_MCMEMBER_RECORD,
1523 NULL, query_mcmember_records},
1524 {"LFTRecord", "LFTR", IB_MAD_ATTR_LFT_RECORD,
1525 "[[lid]/[block]]", query_lft_records},
1526 {"MFTRecord", "MFTR", IB_MAD_ATTR_MFT_RECORD,
1527 "[[mlid]/[position]/[block]]", query_mft_records},
1531 static const struct query_cmd *find_query(const char *name)
1533 const struct query_cmd *q;
1534 unsigned len = strlen(name);
1536 for (q = query_cmds; q->name; q++)
1537 if (!strncasecmp(name, q->name, len) ||
1538 (q->alias && !strncasecmp(name, q->alias, len)))
1544 static const struct query_cmd *find_query_by_type(ib_net16_t type)
1546 const struct query_cmd *q;
1548 for (q = query_cmds; q->name; q++)
1549 if (q->query_type == type)
1555 static void usage(void)
1557 const struct query_cmd *q;
1559 fprintf(stderr, "Usage: %s [-h -d -p -N] [--list | -D] [-S -I -L -l -G"
1560 " -O -U -c -s -g -m --src-to-dst <src:dst> --sgid-to-dgid <src-dst> "
1561 "-C <ca_name> -P <ca_port> -t(imeout) <msec>] [query-name] [<name> | <lid> | <guid>]\n",
1563 fprintf(stderr, " Queries node records by default\n");
1564 fprintf(stderr, " -d enable debugging\n");
1565 fprintf(stderr, " -p get PathRecord info\n");
1566 fprintf(stderr, " -N get NodeRecord info\n");
1567 fprintf(stderr, " --list | -D the node desc of the CA's\n");
1568 fprintf(stderr, " -S get ServiceRecord info\n");
1569 fprintf(stderr, " -I get InformInfoRecord (subscription) info\n");
1570 fprintf(stderr, " -L return the Lids of the name specified\n");
1571 fprintf(stderr, " -l return the unique Lid of the name specified\n");
1572 fprintf(stderr, " -G return the Guids of the name specified\n");
1573 fprintf(stderr, " -O return name for the Lid specified\n");
1574 fprintf(stderr, " -U return name for the Guid specified\n");
1575 fprintf(stderr, " -c get the SA's class port info\n");
1576 fprintf(stderr, " -s return the PortInfoRecords with isSM or "
1577 "isSMdisabled capability mask bit on\n");
1578 fprintf(stderr, " -g get multicast group info\n");
1579 fprintf(stderr, " -m get multicast member info\n");
1580 fprintf(stderr, " (if multicast group specified, list member GIDs"
1581 " only for group specified\n");
1582 fprintf(stderr, " specified, for example 'saquery -m 0xC000')\n");
1583 fprintf(stderr, " -x get LinkRecord info\n");
1584 fprintf(stderr, " --src-to-dst get a PathRecord for <src:dst>\n"
1585 " where src and dst are either node "
1587 fprintf(stderr, " --sgid-to-dgid get a PathRecord for <sgid-dgid>\n"
1588 " where sgid and dgid are addresses in "
1590 fprintf(stderr, " -C <ca_name> specify the SA query HCA\n");
1591 fprintf(stderr, " -P <ca_port> specify the SA query port\n");
1592 fprintf(stderr, " --smkey <val> specify SM_Key value for the query."
1593 " If non-numeric value \n"
1594 " (like 'x') is specified then "
1595 "saquery will prompt for a value\n");
1596 fprintf(stderr, " -t | --timeout <msec> specify the SA query "
1597 "response timeout (default %u msec)\n", DEFAULT_SA_TIMEOUT_MS);
1599 " --node-name-map <node-name-map> specify a node name map\n");
1600 fprintf(stderr, "\n Supported query names (and aliases):\n");
1601 for (q = query_cmds; q->name; q++)
1602 fprintf(stderr, " %s (%s) %s\n", q->name,
1603 q->alias ? q->alias : "", q->usage ? q->usage : "");
1604 fprintf(stderr, "\n");
1609 enum saquery_command {
1611 SAQUERY_CMD_NODE_RECORD,
1612 SAQUERY_CMD_PATH_RECORD,
1613 SAQUERY_CMD_CLASS_PORT_INFO,
1615 SAQUERY_CMD_MCGROUPS,
1616 SAQUERY_CMD_MCMEMBERS,
1619 int main(int argc, char **argv)
1622 osm_bind_handle_t h;
1623 enum saquery_command command = SAQUERY_CMD_QUERY;
1624 const struct query_cmd *q = NULL;
1625 char *src = NULL, *dst = NULL;
1626 char *sgid = NULL, *dgid = NULL;
1627 ib_net16_t query_type = 0;
1628 ib_net16_t src_lid, dst_lid;
1629 ib_api_status_t status;
1631 static char const str_opts[] = "pVNDLlGOUcSIsgmxdhP:C:t:";
1632 static const struct option long_opts[] = {
1634 {"Version", 0, 0, 'V'},
1651 {"help", 0, 0, 'h'},
1652 {"list", 0, 0, 'D'},
1653 {"src-to-dst", 1, 0, 1},
1654 {"sgid-to-dgid", 1, 0, 2},
1655 {"timeout", 1, 0, 't'},
1656 {"node-name-map", 1, 0, 3},
1663 while ((ch = getopt_long(argc, argv, str_opts, long_opts, NULL)) != -1) {
1667 char *opt = strdup(optarg);
1668 char *ch = strchr(opt, ':');
1671 "ERROR: --src-to-dst <node>:<node>\n");
1680 command = SAQUERY_CMD_PATH_RECORD;
1685 char *opt = strdup(optarg);
1686 char *tok1 = strtok(opt, "-");
1687 char *tok2 = strtok(NULL, "\0");
1690 sgid = strdup(tok1);
1691 dgid = strdup(tok2);
1694 "ERROR: --sgid-to-dgid <GID>-<GID>\n");
1698 command = SAQUERY_CMD_PATH_RECORD;
1702 node_name_map_file = strdup(optarg);
1705 if (!isxdigit(*optarg) &&
1706 !(optarg = getpass("SM_Key: "))) {
1707 fprintf(stderr, "cannot get SM_Key\n");
1710 smkey = cl_hton64(strtoull(optarg, NULL, 0));
1713 command = SAQUERY_CMD_PATH_RECORD;
1716 fprintf(stderr, "%s %s\n", argv0, get_build_version());
1719 node_print_desc = ALL_DESC;
1722 command = SAQUERY_CMD_CLASS_PORT_INFO;
1725 query_type = IB_MAD_ATTR_SERVICE_RECORD;
1728 query_type = IB_MAD_ATTR_INFORM_INFO_RECORD;
1731 command = SAQUERY_CMD_NODE_RECORD;
1734 node_print_desc = LID_ONLY;
1737 node_print_desc = UNIQUE_LID_ONLY;
1740 node_print_desc = GUID_ONLY;
1743 node_print_desc = NAME_OF_LID;
1746 node_print_desc = NAME_OF_GUID;
1749 command = SAQUERY_CMD_ISSM;
1752 command = SAQUERY_CMD_MCGROUPS;
1755 command = SAQUERY_CMD_MCMEMBERS;
1758 query_type = IB_MAD_ATTR_LINK_RECORD;
1764 sa_hca_name = optarg;
1767 sa_port_num = strtoul(optarg, NULL, 0);
1770 sa_timeout_ms = strtoul(optarg, NULL, 0);
1781 if (!argc || !(q = find_query(argv[0])))
1782 query_type = IB_MAD_ATTR_NODE_RECORD;
1784 query_type = q->query_type;
1791 if (node_print_desc == NAME_OF_LID) {
1792 requested_lid = (ib_net16_t) strtoul(argv[0], NULL, 0);
1793 requested_lid_flag++;
1794 } else if (node_print_desc == NAME_OF_GUID) {
1795 requested_guid = (ib_net64_t) strtoul(argv[0], NULL, 0);
1796 requested_guid_flag++;
1798 requested_name = argv[0];
1802 if ((node_print_desc == LID_ONLY ||
1803 node_print_desc == UNIQUE_LID_ONLY ||
1804 node_print_desc == GUID_ONLY) && !requested_name) {
1805 fprintf(stderr, "ERROR: name not specified\n");
1809 if (node_print_desc == NAME_OF_LID && !requested_lid_flag) {
1810 fprintf(stderr, "ERROR: lid not specified\n");
1814 if (node_print_desc == NAME_OF_GUID && !requested_guid_flag) {
1815 fprintf(stderr, "ERROR: guid not specified\n");
1819 /* Note: lid cannot be 0; see infiniband spec 4.1.3 */
1820 if (node_print_desc == NAME_OF_LID && !requested_lid) {
1821 fprintf(stderr, "ERROR: lid invalid\n");
1825 h = get_bind_handle();
1826 node_name_map = open_node_name_map(node_name_map_file);
1829 case SAQUERY_CMD_NODE_RECORD:
1830 status = print_node_records(h);
1832 case SAQUERY_CMD_PATH_RECORD:
1834 src_lid = get_lid(h, src);
1835 dst_lid = get_lid(h, dst);
1836 printf("Path record for %s -> %s\n", src, dst);
1837 if (src_lid == 0 || dst_lid == 0) {
1838 status = IB_UNKNOWN_ERROR;
1841 get_print_path_rec_lid(h, src_lid, dst_lid);
1843 } else if (sgid && dgid) {
1844 struct in6_addr src_addr, dst_addr;
1846 if (inet_pton(AF_INET6, sgid, &src_addr) <= 0) {
1847 fprintf(stderr, "invalid src gid: %s\n", sgid);
1850 if (inet_pton(AF_INET6, dgid, &dst_addr) <= 0) {
1851 fprintf(stderr, "invalid dst gid: %s\n", dgid);
1854 status = get_print_path_rec_gid(h,
1855 (ib_gid_t *) & src_addr.s6_addr,
1856 (ib_gid_t *) & dst_addr.s6_addr);
1858 status = query_path_records(q, h, 0, NULL);
1861 case SAQUERY_CMD_CLASS_PORT_INFO:
1862 status = get_print_class_port_info(h);
1864 case SAQUERY_CMD_ISSM:
1865 status = print_issm_records(h);
1867 case SAQUERY_CMD_MCGROUPS:
1868 status = print_multicast_group_records(h);
1870 case SAQUERY_CMD_MCMEMBERS:
1871 status = print_multicast_member_records(h);
1874 if ((!q && !(q = find_query_by_type(query_type)))
1876 fprintf(stderr, "Unknown query type %d\n",
1878 status = IB_UNKNOWN_ERROR;
1880 status = q->handler(q, h, argc, argv);
1889 close_node_name_map(node_name_map);