Index: stable/9/contrib/ofed/librdmacm/examples/build/cmatose/Makefile =================================================================== --- stable/9/contrib/ofed/librdmacm/examples/build/cmatose/Makefile (revision 275448) +++ stable/9/contrib/ofed/librdmacm/examples/build/cmatose/Makefile (revision 275449) @@ -1,10 +1,11 @@ # # $FreeBSD$ # .PATH: ${.CURDIR}/../.. PROG= cmatose MAN= SRCS= cmatose.c LDADD+= -libverbs -lrdmacm -lpthread +LDADD+= -lmlx4 .include Index: stable/9/contrib/ofed/librdmacm/examples/build/mckey/Makefile =================================================================== --- stable/9/contrib/ofed/librdmacm/examples/build/mckey/Makefile (revision 275448) +++ stable/9/contrib/ofed/librdmacm/examples/build/mckey/Makefile (revision 275449) @@ -1,10 +1,11 @@ # # $FreeBSD$ # .PATH: ${.CURDIR}/../.. PROG= mckey MAN= SRCS= mckey.c LDADD+= -libverbs -lrdmacm -lpthread +LDADD+= -lmlx4 .include Index: stable/9/contrib/ofed/librdmacm/examples/build/rping/Makefile =================================================================== --- stable/9/contrib/ofed/librdmacm/examples/build/rping/Makefile (revision 275448) +++ stable/9/contrib/ofed/librdmacm/examples/build/rping/Makefile (revision 275449) @@ -1,10 +1,11 @@ # # $FreeBSD$ # .PATH: ${.CURDIR}/../.. PROG= rping MAN= SRCS= rping.c LDADD+= -libverbs -lrdmacm -lpthread +LDADD+= -lmlx4 .include Index: stable/9/contrib/ofed/librdmacm/examples/build/udaddy/Makefile =================================================================== --- stable/9/contrib/ofed/librdmacm/examples/build/udaddy/Makefile (revision 275448) +++ stable/9/contrib/ofed/librdmacm/examples/build/udaddy/Makefile (revision 275449) @@ -1,10 +1,11 @@ # # $FreeBSD$ # .PATH: ${.CURDIR}/../.. PROG= udaddy MAN= SRCS= udaddy.c LDADD+= -libverbs -lrdmacm -lpthread +LDADD+= -lmlx4 .include Index: stable/9/contrib/ofed/management/infiniband-diags/src/ibnetdiscover.c =================================================================== --- stable/9/contrib/ofed/management/infiniband-diags/src/ibnetdiscover.c (revision 275448) +++ stable/9/contrib/ofed/management/infiniband-diags/src/ibnetdiscover.c (revision 275449) @@ -1,1051 +1,1051 @@ /* * Copyright (c) 2004-2008 Voltaire Inc. All rights reserved. * Copyright (c) 2007 Xsigo Systems Inc. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU * General Public License (GPL) Version 2, available from the file * COPYING in the main directory of this source tree, or the * OpenIB.org BSD license below: * * Redistribution and use in source and binary forms, with or * without modification, are permitted provided that the following * conditions are met: * * - Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * - Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * */ #if HAVE_CONFIG_H # include #endif /* HAVE_CONFIG_H */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include -#include +#include #include "ibnetdiscover.h" #include "grouping.h" #include "ibdiag_common.h" static char *node_type_str[] = { "???", "ca", "switch", "router", "iwarp rnic" }; static char *linkwidth_str[] = { "??", "1x", "4x", "??", "8x", "??", "??", "??", "12x" }; static char *linkspeed_str[] = { "???", "SDR", "DDR", "???", "QDR" }; static int timeout = 2000; /* ms */ static int dumplevel = 0; static int verbose; static FILE *f; char *argv0 = "ibnetdiscover"; static char *node_name_map_file = NULL; static nn_map_t *node_name_map = NULL; Node *nodesdist[MAXHOPS+1]; /* last is Ca list */ Node *mynode; int maxhops_discovered = 0; struct ChassisList *chassis = NULL; static char * get_linkwidth_str(int linkwidth) { if (linkwidth > 8) return linkwidth_str[0]; else return linkwidth_str[linkwidth]; } static char * get_linkspeed_str(int linkspeed) { if (linkspeed > 4) return linkspeed_str[0]; else return linkspeed_str[linkspeed]; } static inline const char* node_type_str2(Node *node) { switch(node->type) { case SWITCH_NODE: return "SW"; case CA_NODE: return "CA"; case ROUTER_NODE: return "RT"; } return "??"; } void decode_port_info(void *pi, Port *port) { mad_decode_field(pi, IB_PORT_LID_F, &port->lid); mad_decode_field(pi, IB_PORT_LMC_F, &port->lmc); mad_decode_field(pi, IB_PORT_STATE_F, &port->state); mad_decode_field(pi, IB_PORT_PHYS_STATE_F, &port->physstate); mad_decode_field(pi, IB_PORT_LINK_WIDTH_ACTIVE_F, &port->linkwidth); mad_decode_field(pi, IB_PORT_LINK_SPEED_ACTIVE_F, &port->linkspeed); } int get_port(Port *port, int portnum, ib_portid_t *portid) { char portinfo[64]; void *pi = portinfo; port->portnum = portnum; if (!smp_query(pi, portid, IB_ATTR_PORT_INFO, portnum, timeout)) return -1; decode_port_info(pi, port); DEBUG("portid %s portnum %d: lid %d state %d physstate %d %s %s", portid2str(portid), portnum, port->lid, port->state, port->physstate, get_linkwidth_str(port->linkwidth), get_linkspeed_str(port->linkspeed)); return 1; } /* * Returns 0 if non switch node is found, 1 if switch is found, -1 if error. */ int get_node(Node *node, Port *port, ib_portid_t *portid) { char portinfo[64]; char switchinfo[64]; void *pi = portinfo, *ni = node->nodeinfo, *nd = node->nodedesc; void *si = switchinfo; if (!smp_query(ni, portid, IB_ATTR_NODE_INFO, 0, timeout)) return -1; mad_decode_field(ni, IB_NODE_GUID_F, &node->nodeguid); mad_decode_field(ni, IB_NODE_TYPE_F, &node->type); mad_decode_field(ni, IB_NODE_NPORTS_F, &node->numports); mad_decode_field(ni, IB_NODE_DEVID_F, &node->devid); mad_decode_field(ni, IB_NODE_VENDORID_F, &node->vendid); mad_decode_field(ni, IB_NODE_SYSTEM_GUID_F, &node->sysimgguid); mad_decode_field(ni, IB_NODE_PORT_GUID_F, &node->portguid); mad_decode_field(ni, IB_NODE_LOCAL_PORT_F, &node->localport); port->portnum = node->localport; port->portguid = node->portguid; if (!smp_query(nd, portid, IB_ATTR_NODE_DESC, 0, timeout)) return -1; if (!smp_query(pi, portid, IB_ATTR_PORT_INFO, 0, timeout)) return -1; decode_port_info(pi, port); if (node->type != SWITCH_NODE) return 0; node->smalid = port->lid; node->smalmc = port->lmc; /* after we have the sma information find out the real PortInfo for this port */ if (!smp_query(pi, portid, IB_ATTR_PORT_INFO, node->localport, timeout)) return -1; decode_port_info(pi, port); if (!smp_query(si, portid, IB_ATTR_SWITCH_INFO, 0, timeout)) node->smaenhsp0 = 0; /* assume base SP0 */ else mad_decode_field(si, IB_SW_ENHANCED_PORT0_F, &node->smaenhsp0); DEBUG("portid %s: got switch node %" PRIx64 " '%s'", portid2str(portid), node->nodeguid, node->nodedesc); return 1; } static int extend_dpath(ib_dr_path_t *path, int nextport) { if (path->cnt+2 >= sizeof(path->p)) return -1; ++path->cnt; if (path->cnt > maxhops_discovered) maxhops_discovered = path->cnt; path->p[path->cnt] = nextport; return path->cnt; } static void dump_endnode(ib_portid_t *path, char *prompt, Node *node, Port *port) { if (!dumplevel) return; fprintf(f, "%s -> %s %s {%016" PRIx64 "} portnum %d lid %d-%d\"%s\"\n", portid2str(path), prompt, (node->type <= IB_NODE_MAX ? node_type_str[node->type] : "???"), node->nodeguid, node->type == SWITCH_NODE ? 0 : port->portnum, port->lid, port->lid + (1 << port->lmc) - 1, clean_nodedesc(node->nodedesc)); } #define HASHGUID(guid) ((uint32_t)(((uint32_t)(guid) * 101) ^ ((uint32_t)((guid) >> 32) * 103))) #define HTSZ 137 static Node *nodestbl[HTSZ]; static Node * find_node(Node *new) { int hash = HASHGUID(new->nodeguid) % HTSZ; Node *node; for (node = nodestbl[hash]; node; node = node->htnext) if (node->nodeguid == new->nodeguid) return node; return NULL; } static Node * create_node(Node *temp, ib_portid_t *path, int dist) { Node *node; int hash = HASHGUID(temp->nodeguid) % HTSZ; node = malloc(sizeof(*node)); if (!node) return NULL; memcpy(node, temp, sizeof(*node)); node->dist = dist; node->path = *path; node->htnext = nodestbl[hash]; nodestbl[hash] = node; if (node->type != SWITCH_NODE) dist = MAXHOPS; /* special Ca list */ node->dnext = nodesdist[dist]; nodesdist[dist] = node; return node; } static Port * find_port(Node *node, Port *port) { Port *old; for (old = node->ports; old; old = old->next) if (old->portnum == port->portnum) return old; return NULL; } static Port * create_port(Node *node, Port *temp) { Port *port; port = malloc(sizeof(*port)); if (!port) return NULL; memcpy(port, temp, sizeof(*port)); port->node = node; port->next = node->ports; node->ports = port; return port; } static void link_ports(Node *node, Port *port, Node *remotenode, Port *remoteport) { DEBUG("linking: 0x%" PRIx64 " %p->%p:%u and 0x%" PRIx64 " %p->%p:%u", node->nodeguid, node, port, port->portnum, remotenode->nodeguid, remotenode, remoteport, remoteport->portnum); if (port->remoteport) port->remoteport->remoteport = NULL; if (remoteport->remoteport) remoteport->remoteport->remoteport = NULL; port->remoteport = remoteport; remoteport->remoteport = port; } static int handle_port(Node *node, Port *port, ib_portid_t *path, int portnum, int dist) { Node node_buf; Port port_buf; Node *remotenode, *oldnode; Port *remoteport, *oldport; memset(&node_buf, 0, sizeof(node_buf)); memset(&port_buf, 0, sizeof(port_buf)); DEBUG("handle node %p port %p:%d dist %d", node, port, portnum, dist); if (port->physstate != 5) /* LinkUp */ return -1; if (extend_dpath(&path->drpath, portnum) < 0) return -1; if (get_node(&node_buf, &port_buf, path) < 0) { IBWARN("NodeInfo on %s failed, skipping port", portid2str(path)); path->drpath.cnt--; /* restore path */ return -1; } oldnode = find_node(&node_buf); if (oldnode) remotenode = oldnode; else if (!(remotenode = create_node(&node_buf, path, dist + 1))) IBERROR("no memory"); oldport = find_port(remotenode, &port_buf); if (oldport) { remoteport = oldport; if (node != remotenode || port != remoteport) IBWARN("port moving..."); } else if (!(remoteport = create_port(remotenode, &port_buf))) IBERROR("no memory"); dump_endnode(path, oldnode ? "known remote" : "new remote", remotenode, remoteport); link_ports(node, port, remotenode, remoteport); path->drpath.cnt--; /* restore path */ return 0; } /* * Return 1 if found, 0 if not, -1 on errors. */ static int discover(ib_portid_t *from) { Node node_buf; Port port_buf; Node *node; Port *port; int i; int dist = 0; ib_portid_t *path; DEBUG("from %s", portid2str(from)); memset(&node_buf, 0, sizeof(node_buf)); memset(&port_buf, 0, sizeof(port_buf)); if (get_node(&node_buf, &port_buf, from) < 0) { IBWARN("can't reach node %s", portid2str(from)); return -1; } node = create_node(&node_buf, from, 0); if (!node) IBERROR("out of memory"); mynode = node; port = create_port(node, &port_buf); if (!port) IBERROR("out of memory"); if (node->type != SWITCH_NODE && handle_port(node, port, from, node->localport, 0) < 0) return 0; for (dist = 0; dist < MAXHOPS; dist++) { for (node = nodesdist[dist]; node; node = node->dnext) { path = &node->path; DEBUG("dist %d node %p", dist, node); dump_endnode(path, "processing", node, port); for (i = 1; i <= node->numports; i++) { if (i == node->localport) continue; if (get_port(&port_buf, i, path) < 0) { IBWARN("can't reach node %s port %d", portid2str(path), i); continue; } port = find_port(node, &port_buf); if (port) continue; port = create_port(node, &port_buf); if (!port) IBERROR("out of memory"); /* If switch, set port GUID to node GUID */ if (node->type == SWITCH_NODE) port->portguid = node->portguid; handle_port(node, port, path, i, dist); } } } return 0; } char * node_name(Node *node) { static char buf[256]; switch(node->type) { case SWITCH_NODE: sprintf(buf, "\"%s", "S"); break; case CA_NODE: sprintf(buf, "\"%s", "H"); break; case ROUTER_NODE: sprintf(buf, "\"%s", "R"); break; default: sprintf(buf, "\"%s", "?"); break; } sprintf(buf+2, "-%016" PRIx64 "\"", node->nodeguid); return buf; } void list_node(Node *node) { char *node_type; char *nodename = remap_node_name(node_name_map, node->nodeguid, node->nodedesc); switch(node->type) { case SWITCH_NODE: node_type = "Switch"; break; case CA_NODE: node_type = "Ca"; break; case ROUTER_NODE: node_type = "Router"; break; default: node_type = "???"; break; } fprintf(f, "%s\t : 0x%016" PRIx64 " ports %d devid 0x%x vendid 0x%x \"%s\"\n", node_type, node->nodeguid, node->numports, node->devid, node->vendid, nodename); free(nodename); } void out_ids(Node *node, int group, char *chname) { fprintf(f, "\nvendid=0x%x\ndevid=0x%x\n", node->vendid, node->devid); if (node->sysimgguid) fprintf(f, "sysimgguid=0x%" PRIx64, node->sysimgguid); if (group && node->chrecord && node->chrecord->chassisnum) { fprintf(f, "\t\t# Chassis %d", node->chrecord->chassisnum); if (chname) fprintf(f, " (%s)", chname); if (is_xsigo_tca(node->nodeguid) && node->ports->remoteport) fprintf(f, " slot %d", node->ports->remoteport->portnum); } fprintf(f, "\n"); } uint64_t out_chassis(int chassisnum) { uint64_t guid; fprintf(f, "\nChassis %d", chassisnum); guid = get_chassis_guid(chassisnum); if (guid) fprintf(f, " (guid 0x%" PRIx64 ")", guid); fprintf(f, "\n"); return guid; } void out_switch(Node *node, int group, char *chname) { char *str; char *nodename = NULL; out_ids(node, group, chname); fprintf(f, "switchguid=0x%" PRIx64, node->nodeguid); fprintf(f, "(%" PRIx64 ")", node->portguid); /* Currently, only if Voltaire chassis */ if (group && node->chrecord && node->chrecord->chassisnum && node->vendid == VTR_VENDOR_ID) { str = get_chassis_type(node->chrecord->chassistype); if (str) fprintf(f, "%s ", str); str = get_chassis_slot(node->chrecord->chassisslot); if (str) fprintf(f, "%s ", str); fprintf(f, "%d Chip %d", node->chrecord->slotnum, node->chrecord->anafanum); } nodename = remap_node_name(node_name_map, node->nodeguid, node->nodedesc); fprintf(f, "\nSwitch\t%d %s\t\t# \"%s\" %s port 0 lid %d lmc %d\n", node->numports, node_name(node), nodename, node->smaenhsp0 ? "enhanced" : "base", node->smalid, node->smalmc); free(nodename); } void out_ca(Node *node, int group, char *chname) { char *node_type; char *node_type2; char *nodename = remap_node_name(node_name_map, node->nodeguid, node->nodedesc); out_ids(node, group, chname); switch(node->type) { case CA_NODE: node_type = "ca"; node_type2 = "Ca"; break; case ROUTER_NODE: node_type = "rt"; node_type2 = "Rt"; break; default: node_type = "???"; node_type2 = "???"; break; } fprintf(f, "%sguid=0x%" PRIx64 "\n", node_type, node->nodeguid); fprintf(f, "%s\t%d %s\t\t# \"%s\"", node_type2, node->numports, node_name(node), nodename); if (group && is_xsigo_hca(node->nodeguid)) fprintf(f, " (scp)"); fprintf(f, "\n"); free(nodename); } static char * out_ext_port(Port *port, int group) { char *str = NULL; /* Currently, only if Voltaire chassis */ if (group && port->node->chrecord && port->node->vendid == VTR_VENDOR_ID) str = portmapstring(port); return (str); } void out_switch_port(Port *port, int group) { char *ext_port_str = NULL; char *rem_nodename = NULL; DEBUG("port %p:%d remoteport %p", port, port->portnum, port->remoteport); fprintf(f, "[%d]", port->portnum); ext_port_str = out_ext_port(port, group); if (ext_port_str) fprintf(f, "%s", ext_port_str); rem_nodename = remap_node_name(node_name_map, port->remoteport->node->nodeguid, port->remoteport->node->nodedesc); ext_port_str = out_ext_port(port->remoteport, group); fprintf(f, "\t%s[%d]%s", node_name(port->remoteport->node), port->remoteport->portnum, ext_port_str ? ext_port_str : ""); if (port->remoteport->node->type != SWITCH_NODE) fprintf(f, "(%" PRIx64 ") ", port->remoteport->portguid); fprintf(f, "\t\t# \"%s\" lid %d %s%s", rem_nodename, port->remoteport->node->type == SWITCH_NODE ? port->remoteport->node->smalid : port->remoteport->lid, get_linkwidth_str(port->linkwidth), get_linkspeed_str(port->linkspeed)); if (is_xsigo_tca(port->remoteport->portguid)) fprintf(f, " slot %d", port->portnum); else if (is_xsigo_hca(port->remoteport->portguid)) fprintf(f, " (scp)"); fprintf(f, "\n"); free(rem_nodename); } void out_ca_port(Port *port, int group) { char *str = NULL; char *rem_nodename = NULL; fprintf(f, "[%d]", port->portnum); if (port->node->type != SWITCH_NODE) fprintf(f, "(%" PRIx64 ") ", port->portguid); fprintf(f, "\t%s[%d]", node_name(port->remoteport->node), port->remoteport->portnum); str = out_ext_port(port->remoteport, group); if (str) fprintf(f, "%s", str); if (port->remoteport->node->type != SWITCH_NODE) fprintf(f, " (%" PRIx64 ") ", port->remoteport->portguid); rem_nodename = remap_node_name(node_name_map, port->remoteport->node->nodeguid, port->remoteport->node->nodedesc); fprintf(f, "\t\t# lid %d lmc %d \"%s\" lid %d %s%s\n", port->lid, port->lmc, rem_nodename, port->remoteport->node->type == SWITCH_NODE ? port->remoteport->node->smalid : port->remoteport->lid, get_linkwidth_str(port->linkwidth), get_linkspeed_str(port->linkspeed)); free(rem_nodename); } int dump_topology(int listtype, int group) { Node *node; Port *port; int i = 0, dist = 0; time_t t = time(0); uint64_t chguid; char *chname = NULL; if (!listtype) { fprintf(f, "#\n# Topology file: generated on %s#\n", ctime(&t)); fprintf(f, "# Max of %d hops discovered\n", maxhops_discovered); fprintf(f, "# Initiated from node %016" PRIx64 " port %016" PRIx64 "\n", mynode->nodeguid, mynode->portguid); } /* Make pass on switches */ if (group && !listtype) { ChassisList *ch = NULL; /* Chassis based switches first */ for (ch = chassis; ch; ch = ch->next) { int n = 0; if (!ch->chassisnum) continue; chguid = out_chassis(ch->chassisnum); if (chname) free(chname); chname = NULL; if (is_xsigo_guid(chguid)) { for (node = nodesdist[MAXHOPS]; node; node = node->dnext) { if (!node->chrecord || !node->chrecord->chassisnum) continue; if (node->chrecord->chassisnum != ch->chassisnum) continue; if (is_xsigo_hca(node->nodeguid)) { chname = remap_node_name(node_name_map, node->nodeguid, node->nodedesc); fprintf(f, "Hostname: %s\n", chname); } } } fprintf(f, "\n# Spine Nodes"); for (n = 1; n <= (SPINES_MAX_NUM+1); n++) { if (ch->spinenode[n]) { out_switch(ch->spinenode[n], group, chname); for (port = ch->spinenode[n]->ports; port; port = port->next, i++) if (port->remoteport) out_switch_port(port, group); } } fprintf(f, "\n# Line Nodes"); for (n = 1; n <= (LINES_MAX_NUM+1); n++) { if (ch->linenode[n]) { out_switch(ch->linenode[n], group, chname); for (port = ch->linenode[n]->ports; port; port = port->next, i++) if (port->remoteport) out_switch_port(port, group); } } fprintf(f, "\n# Chassis Switches"); for (dist = 0; dist <= maxhops_discovered; dist++) { for (node = nodesdist[dist]; node; node = node->dnext) { /* Non Voltaire chassis */ if (node->vendid == VTR_VENDOR_ID) continue; if (!node->chrecord || !node->chrecord->chassisnum) continue; if (node->chrecord->chassisnum != ch->chassisnum) continue; out_switch(node, group, chname); for (port = node->ports; port; port = port->next, i++) if (port->remoteport) out_switch_port(port, group); } } fprintf(f, "\n# Chassis CAs"); for (node = nodesdist[MAXHOPS]; node; node = node->dnext) { if (!node->chrecord || !node->chrecord->chassisnum) continue; if (node->chrecord->chassisnum != ch->chassisnum) continue; out_ca(node, group, chname); for (port = node->ports; port; port = port->next, i++) if (port->remoteport) out_ca_port(port, group); } } } else { for (dist = 0; dist <= maxhops_discovered; dist++) { for (node = nodesdist[dist]; node; node = node->dnext) { DEBUG("SWITCH: dist %d node %p", dist, node); if (!listtype) out_switch(node, group, chname); else { if (listtype & LIST_SWITCH_NODE) list_node(node); continue; } for (port = node->ports; port; port = port->next, i++) if (port->remoteport) out_switch_port(port, group); } } } if (chname) free(chname); chname = NULL; if (group && !listtype) { fprintf(f, "\nNon-Chassis Nodes\n"); for (dist = 0; dist <= maxhops_discovered; dist++) { for (node = nodesdist[dist]; node; node = node->dnext) { DEBUG("SWITCH: dist %d node %p", dist, node); /* Now, skip chassis based switches */ if (node->chrecord && node->chrecord->chassisnum) continue; out_switch(node, group, chname); for (port = node->ports; port; port = port->next, i++) if (port->remoteport) out_switch_port(port, group); } } } /* Make pass on CAs */ for (node = nodesdist[MAXHOPS]; node; node = node->dnext) { DEBUG("CA: dist %d node %p", dist, node); if (!listtype) { /* Now, skip chassis based CAs */ if (group && node->chrecord && node->chrecord->chassisnum) continue; out_ca(node, group, chname); } else { if (((listtype & LIST_CA_NODE) && (node->type == CA_NODE)) || ((listtype & LIST_ROUTER_NODE) && (node->type == ROUTER_NODE))) list_node(node); continue; } for (port = node->ports; port; port = port->next, i++) if (port->remoteport) out_ca_port(port, group); } if (chname) free(chname); return i; } void dump_ports_report () { int b, n = 0, p; Node *node; Port *port; // If switch and LID == 0, search of other switch ports with // valid LID and assign it to all ports of that switch for (b = 0; b <= MAXHOPS; b++) for (node = nodesdist[b]; node; node = node->dnext) if (node->type == SWITCH_NODE) { int swlid = 0; for (p = 0, port = node->ports; p < node->numports && port && !swlid; port = port->next) if (port->lid != 0) swlid = port->lid; for (p = 0, port = node->ports; p < node->numports && port; port = port->next) port->lid = swlid; } for (b = 0; b <= MAXHOPS; b++) for (node = nodesdist[b]; node; node = node->dnext) { for (p = 0, port = node->ports; p < node->numports && port; p++, port = port->next) { fprintf(stdout, "%2s %5d %2d 0x%016" PRIx64 " %s %s", node_type_str2(port->node), port->lid, port->portnum, port->portguid, get_linkwidth_str(port->linkwidth), get_linkspeed_str(port->linkspeed)); if (port->remoteport) fprintf(stdout, " - %2s %5d %2d 0x%016" PRIx64 " ( '%s' - '%s' )\n", node_type_str2(port->remoteport->node), port->remoteport->lid, port->remoteport->portnum, port->remoteport->portguid, port->node->nodedesc, port->remoteport->node->nodedesc); else fprintf(stdout, "%36s'%s'\n", "", port->node->nodedesc); } n++; } } void usage(void) { fprintf(stderr, "Usage: %s [-d(ebug)] -e(rr_show) -v(erbose) -s(how) -l(ist) -g(rouping) -H(ca_list) -S(witch_list) -R(outer_list) -V(ersion) -C ca_name -P ca_port " "-t(imeout) timeout_ms --node-name-map node-name-map] -p(orts) []\n", argv0); fprintf(stderr, " --node-name-map specify a node name map file\n"); exit(-1); } int main(int argc, char **argv) { int mgmt_classes[2] = {IB_SMI_CLASS, IB_SMI_DIRECT_CLASS}; ib_portid_t my_portid = {0}; int udebug = 0, list = 0; char *ca = 0; int ca_port = 0; int group = 0; int ports_report = 0; static char const str_opts[] = "C:P:t:devslgHSRpVhu"; static const struct option long_opts[] = { { "C", 1, 0, 'C'}, { "P", 1, 0, 'P'}, { "debug", 0, 0, 'd'}, { "err_show", 0, 0, 'e'}, { "verbose", 0, 0, 'v'}, { "show", 0, 0, 's'}, { "list", 0, 0, 'l'}, { "grouping", 0, 0, 'g'}, { "Hca_list", 0, 0, 'H'}, { "Switch_list", 0, 0, 'S'}, { "Router_list", 0, 0, 'R'}, { "timeout", 1, 0, 't'}, { "node-name-map", 1, 0, 1}, { "ports", 0, 0, 'p'}, { "Version", 0, 0, 'V'}, { "help", 0, 0, 'h'}, { "usage", 0, 0, 'u'}, { } }; f = stdout; argv0 = argv[0]; while (1) { int ch = getopt_long(argc, argv, str_opts, long_opts, NULL); if ( ch == -1 ) break; switch(ch) { case 1: node_name_map_file = strdup(optarg); break; case 'C': ca = optarg; break; case 'P': ca_port = strtoul(optarg, 0, 0); break; case 'd': ibdebug++; madrpc_show_errors(1); umad_debug(udebug); udebug++; break; case 't': timeout = strtoul(optarg, 0, 0); break; case 'v': verbose++; dumplevel++; break; case 's': dumplevel = 1; break; case 'e': madrpc_show_errors(1); break; case 'l': list = LIST_CA_NODE | LIST_SWITCH_NODE | LIST_ROUTER_NODE; break; case 'g': group = 1; break; case 'S': list = LIST_SWITCH_NODE; break; case 'H': list = LIST_CA_NODE; break; case 'R': list = LIST_ROUTER_NODE; break; case 'V': fprintf(stderr, "%s %s\n", argv0, get_build_version() ); exit(-1); case 'p': ports_report = 1; break; default: usage(); break; } } argc -= optind; argv += optind; if (argc && !(f = fopen(argv[0], "w"))) IBERROR("can't open file %s for writing", argv[0]); madrpc_init(ca, ca_port, mgmt_classes, 2); node_name_map = open_node_name_map(node_name_map_file); if (discover(&my_portid) < 0) IBERROR("discover"); if (group) chassis = group_nodes(); if (ports_report) dump_ports_report(); else dump_topology(list, group); close_node_name_map(node_name_map); exit(0); } Index: stable/9/contrib/ofed/management/infiniband-diags/src/ibroute.c =================================================================== --- stable/9/contrib/ofed/management/infiniband-diags/src/ibroute.c (revision 275448) +++ stable/9/contrib/ofed/management/infiniband-diags/src/ibroute.c (revision 275449) @@ -1,495 +1,495 @@ /* * Copyright (c) 2004-2008 Voltaire Inc. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU * General Public License (GPL) Version 2, available from the file * COPYING in the main directory of this source tree, or the * OpenIB.org BSD license below: * * Redistribution and use in source and binary forms, with or * without modification, are permitted provided that the following * conditions are met: * * - Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * - Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * */ #if HAVE_CONFIG_H # include #endif /* HAVE_CONFIG_H */ #include #include #include #include #include #include #include #include #include #include #include #include #include -#include +#include #include "ibdiag_common.h" static int dest_type = IB_DEST_LID; static int brief; static int verbose; static int dump_all; char *argv0 = "ibroute"; /*******************************************/ char * check_switch(ib_portid_t *portid, int *nports, uint64_t *guid, uint8_t *sw, char *nd) { uint8_t ni[IB_SMP_DATA_SIZE] = {0}; int type; DEBUG("checking node type"); if (!smp_query(ni, portid, IB_ATTR_NODE_INFO, 0, 0)) { xdump(stderr, "nodeinfo\n", ni, sizeof ni); return "node info failed: valid addr?"; } if (!smp_query(nd, portid, IB_ATTR_NODE_DESC, 0, 0)) return "node desc failed"; mad_decode_field(ni, IB_NODE_TYPE_F, &type); if (type != IB_NODE_SWITCH) return "not a switch"; DEBUG("Gathering information about switch"); mad_decode_field(ni, IB_NODE_NPORTS_F, nports); mad_decode_field(ni, IB_NODE_GUID_F, guid); if (!smp_query(sw, portid, IB_ATTR_SWITCH_INFO, 0, 0)) return "switch info failed: is a switch node?"; return 0; } #define IB_MLIDS_IN_BLOCK (IB_SMP_DATA_SIZE/2) int dump_mlid(char *str, int strlen, int mlid, int nports, uint16_t mft[16][IB_MLIDS_IN_BLOCK]) { uint16_t mask; int i, chunk, bit; int nonzero = 0; if (brief) { int n = 0, chunks = ALIGN(nports + 1, 16) / 16; for (i = 0; i < chunks; i++) { mask = ntohs(mft[i][mlid%IB_MLIDS_IN_BLOCK]); if (mask) nonzero++; n += snprintf(str + n, strlen - n, "%04hx", mask); if (n >= strlen) { n = strlen; break; } } if (!nonzero && !dump_all) { str[0] = 0; return 0; } return n; } for (i = 0; i <= nports; i++) { chunk = i / 16; bit = i % 16; mask = ntohs(mft[chunk][mlid%IB_MLIDS_IN_BLOCK]); if (mask) nonzero++; str[i*2] = (mask & (1 << bit)) ? 'x' : ' '; str[i*2+1] = ' '; } if (!nonzero && !dump_all) { str[0] = 0; return 0; } str[i*2] = 0; return i * 2; } uint16_t mft[16][IB_MLIDS_IN_BLOCK]; char * dump_multicast_tables(ib_portid_t *portid, int startlid, int endlid) { char nd[IB_SMP_DATA_SIZE] = {0}; uint8_t sw[IB_SMP_DATA_SIZE] = {0}; char str[512]; char *s; uint64_t nodeguid; uint32_t mod; int block, i, j, e, nports, cap, chunks; int n = 0, startblock, lastblock; if ((s = check_switch(portid, &nports, &nodeguid, sw, nd))) return s; mad_decode_field(sw, IB_SW_MCAST_FDB_CAP_F, &cap); if (!endlid || endlid > IB_MIN_MCAST_LID + cap - 1) endlid = IB_MIN_MCAST_LID + cap - 1; if (!startlid) startlid = IB_MIN_MCAST_LID; if (startlid < IB_MIN_MCAST_LID) { IBWARN("illegal start mlid %x, set to %x", startlid, IB_MIN_MCAST_LID); startlid = IB_MIN_MCAST_LID; } if (endlid > IB_MAX_MCAST_LID) { IBWARN("illegal end mlid %x, truncate to %x", endlid, IB_MAX_MCAST_LID); endlid = IB_MAX_MCAST_LID; } printf("Multicast mlids [0x%x-0x%x] of switch %s guid 0x%016" PRIx64 " (%s):\n", startlid, endlid, portid2str(portid), nodeguid, clean_nodedesc(nd)); if (brief) printf(" MLid Port Mask\n"); else { if (nports > 9) { for (i = 0, s = str; i <= nports; i++) { *s++ = (i%10) ? ' ' : '0' + i/10; *s++ = ' '; } *s = 0; printf(" %s\n", str); } for (i = 0, s = str; i <= nports; i++) s += sprintf(s, "%d ", i%10); printf(" Ports: %s\n", str); printf(" MLid\n"); } if (verbose) printf("Switch muticast mlids capability is 0x%d\n", cap); chunks = ALIGN(nports + 1, 16) / 16; startblock = startlid / IB_MLIDS_IN_BLOCK; lastblock = endlid / IB_MLIDS_IN_BLOCK; for (block = startblock; block <= lastblock; block++) { for (j = 0; j < chunks; j++) { mod = (block - IB_MIN_MCAST_LID/IB_MLIDS_IN_BLOCK) | (j << 28); DEBUG("reading block %x chunk %d mod %x", block, j, mod); if (!smp_query(mft + j, portid, IB_ATTR_MULTICASTFORWTBL, mod, 0)) return "multicast forwarding table get failed"; } i = block * IB_MLIDS_IN_BLOCK; e = i + IB_MLIDS_IN_BLOCK; if (i < startlid) i = startlid; if (e > endlid + 1) e = endlid + 1; for (; i < e; i++) { if (dump_mlid(str, sizeof str, i, nports, mft) == 0) continue; printf("0x%04x %s\n", i, str); n++; } } printf("%d %smlids dumped \n", n, dump_all ? "" : "valid "); return 0; } int dump_lid(char *str, int strlen, int lid, int valid) { char nd[IB_SMP_DATA_SIZE] = {0}; uint8_t ni[IB_SMP_DATA_SIZE] = {0}; uint8_t pi[IB_SMP_DATA_SIZE] = {0}; ib_portid_t lidport = {0}; static int last_port_lid, base_port_lid; char ntype[50], sguid[30], desc[64]; static uint64_t portguid; int baselid, lmc, type; if (brief) { str[0] = 0; return 0; } if (lid <= last_port_lid) { if (!valid) return snprintf(str, strlen, ": (path #%d - illegal port)", lid - base_port_lid); else if (!portguid) return snprintf(str, strlen, ": (path #%d out of %d)", lid - base_port_lid + 1, last_port_lid - base_port_lid + 1); else { return snprintf(str, strlen, ": (path #%d out of %d: portguid %s)", lid - base_port_lid + 1, last_port_lid - base_port_lid + 1, mad_dump_val(IB_NODE_PORT_GUID_F, sguid, sizeof sguid, &portguid)); } } if (!valid) return snprintf(str, strlen, ": (illegal port)"); portguid = 0; lidport.lid = lid; if (!smp_query(nd, &lidport, IB_ATTR_NODE_DESC, 0, 100) || !smp_query(pi, &lidport, IB_ATTR_PORT_INFO, 0, 100) || !smp_query(ni, &lidport, IB_ATTR_NODE_INFO, 0, 100)) return snprintf(str, strlen, ": (unknown node and type)"); mad_decode_field(ni, IB_NODE_PORT_GUID_F, &portguid); mad_decode_field(ni, IB_NODE_TYPE_F, &type); mad_decode_field(pi, IB_PORT_LID_F, &baselid); mad_decode_field(pi, IB_PORT_LMC_F, &lmc); if (lmc > 0) { base_port_lid = baselid; last_port_lid = baselid + (1 << lmc) - 1; } return snprintf(str, strlen, ": (%s portguid %s: %s)", mad_dump_val(IB_NODE_TYPE_F, ntype, sizeof ntype, &type), mad_dump_val(IB_NODE_PORT_GUID_F, sguid, sizeof sguid, &portguid), mad_dump_val(IB_NODE_DESC_F, desc, sizeof desc, clean_nodedesc(nd))); } char * dump_unicast_tables(ib_portid_t *portid, int startlid, int endlid) { char lft[IB_SMP_DATA_SIZE]; char nd[IB_SMP_DATA_SIZE]; uint8_t sw[IB_SMP_DATA_SIZE]; char str[200], *s; uint64_t nodeguid; int block, i, e, nports, top; int n = 0, startblock, endblock; if ((s = check_switch(portid, &nports, &nodeguid, sw, nd))) return s; mad_decode_field(sw, IB_SW_LINEAR_FDB_TOP_F, &top); if (!endlid || endlid > top) endlid = top; if (endlid > IB_MAX_UCAST_LID) { IBWARN("ilegal lft top %d, truncate to %d", endlid, IB_MAX_UCAST_LID); endlid = IB_MAX_UCAST_LID; } printf("Unicast lids [0x%x-0x%x] of switch %s guid 0x%016" PRIx64 " (%s):\n", startlid, endlid, portid2str(portid), nodeguid, clean_nodedesc(nd)); DEBUG("Switch top is 0x%x\n", top); printf(" Lid Out Destination\n"); printf(" Port Info \n"); startblock = startlid / IB_SMP_DATA_SIZE; endblock = ALIGN(endlid, IB_SMP_DATA_SIZE) / IB_SMP_DATA_SIZE; for (block = startblock; block <= endblock; block++) { DEBUG("reading block %d", block); if (!smp_query(lft, portid, IB_ATTR_LINEARFORWTBL, block, 0)) return "linear forwarding table get failed"; i = block * IB_SMP_DATA_SIZE; e = i + IB_SMP_DATA_SIZE; if (i < startlid) i = startlid; if (e > endlid + 1) e = endlid + 1; for (;i < e; i++) { unsigned outport = lft[i % IB_SMP_DATA_SIZE]; unsigned valid = (outport <= nports); if (!valid && !dump_all) continue; dump_lid(str, sizeof str, i, valid); printf("0x%04x %03u %s\n", i, outport & 0xff, str); n++; } } printf("%d %slids dumped \n", n, dump_all ? "" : "valid "); return 0; } void usage(void) { char *basename; if (!(basename = strrchr(argv0, '/'))) basename = argv0; else basename++; fprintf(stderr, "Usage: %s [-d(ebug)] -a(ll) -n(o_dests) -v(erbose) -D(irect) -G(uid) -M(ulticast) -s smlid -V(ersion) -C ca_name -P ca_port " "-t(imeout) timeout_ms] [ [ []]]\n", basename); fprintf(stderr, "\n\tUnicast examples:\n"); fprintf(stderr, "\t\t%s 4\t# dump all lids with valid out ports of switch with lid 4\n", basename); fprintf(stderr, "\t\t%s -a 4\t# same, but dump all lids, even with invalid out ports\n", basename); fprintf(stderr, "\t\t%s -n 4\t# simple dump format - no destination resolving\n", basename); fprintf(stderr, "\t\t%s 4 10\t# dump lids starting from 10\n", basename); fprintf(stderr, "\t\t%s 4 0x10 0x20\t# dump lid range\n", basename); fprintf(stderr, "\t\t%s -G 0x08f1040023\t# resolve switch by GUID\n", basename); fprintf(stderr, "\t\t%s -D 0,1\t# resolve switch by direct path\n", basename); fprintf(stderr, "\n\tMulticast examples:\n"); fprintf(stderr, "\t\t%s -M 4\t# dump all non empty mlids of switch with lid 4\n", basename); fprintf(stderr, "\t\t%s -M 4 0xc010 0xc020\t# same, but with range\n", basename); fprintf(stderr, "\t\t%s -M -n 4\t# simple dump format\n", basename); exit(-1); } int main(int argc, char **argv) { int mgmt_classes[3] = {IB_SMI_CLASS, IB_SMI_DIRECT_CLASS, IB_SA_CLASS}; ib_portid_t portid = {0}; ib_portid_t *sm_id = 0, sm_portid = {0}; int timeout; int multicast = 0, startlid = 0, endlid = 0; char *err; char *ca = 0; int ca_port = 0; static char const str_opts[] = "C:P:t:s:danvDGMVhu"; static const struct option long_opts[] = { { "C", 1, 0, 'C'}, { "P", 1, 0, 'P'}, { "debug", 0, 0, 'd'}, { "all", 0, 0, 'a'}, { "no_dests", 0, 0, 'n'}, { "verbose", 0, 0, 'v'}, { "Direct", 0, 0, 'D'}, { "Guid", 0, 0, 'G'}, { "Multicast", 0, 0, 'M'}, { "timeout", 1, 0, 't'}, { "s", 1, 0, 's'}, { "Version", 0, 0, 'V'}, { "help", 0, 0, 'h'}, { "usage", 0, 0, 'u'}, { } }; argv0 = argv[0]; while (1) { int ch = getopt_long(argc, argv, str_opts, long_opts, NULL); if ( ch == -1 ) break; switch(ch) { case 'C': ca = optarg; break; case 'P': ca_port = strtoul(optarg, 0, 0); break; case 'a': dump_all++; break; case 'd': ibdebug++; break; case 'D': dest_type = IB_DEST_DRPATH; break; case 'G': dest_type = IB_DEST_GUID; break; case 'M': multicast++; break; case 'n': brief++; break; case 's': if (ib_resolve_portid_str(&sm_portid, optarg, IB_DEST_LID, 0) < 0) IBERROR("can't resolve SM destination port %s", optarg); sm_id = &sm_portid; break; case 't': timeout = strtoul(optarg, 0, 0); madrpc_set_timeout(timeout); break; case 'v': madrpc_show_errors(1); verbose++; break; case 'V': fprintf(stderr, "%s %s\n", argv0, get_build_version() ); exit(-1); default: usage(); break; } } argc -= optind; argv += optind; if (!argc) usage(); if (argc > 1) startlid = strtoul(argv[1], 0, 0); if (argc > 2) endlid = strtoul(argv[2], 0, 0); madrpc_init(ca, ca_port, mgmt_classes, 3); if (!argc) { if (ib_resolve_self(&portid, 0, 0) < 0) IBERROR("can't resolve self addr"); } else { if (ib_resolve_portid_str(&portid, argv[0], dest_type, sm_id) < 0) IBERROR("can't resolve destination port %s", argv[1]); } if (multicast) err = dump_multicast_tables(&portid, startlid, endlid); else err = dump_unicast_tables(&portid, startlid, endlid); if (err) IBERROR("dump tables: %s", err); exit(0); } Index: stable/9/contrib/ofed/management/infiniband-diags/src/ibsendtrap.c =================================================================== --- stable/9/contrib/ofed/management/infiniband-diags/src/ibsendtrap.c (revision 275448) +++ stable/9/contrib/ofed/management/infiniband-diags/src/ibsendtrap.c (revision 275449) @@ -1,176 +1,176 @@ /* * Copyright (c) 2008 Lawrence Livermore National Security * * Produced at Lawrence Livermore National Laboratory. * Written by Ira Weiny . * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU * General Public License (GPL) Version 2, available from the file * COPYING in the main directory of this source tree, or the * OpenIB.org BSD license below: * * Redistribution and use in source and binary forms, with or * without modification, are permitted provided that the following * conditions are met: * * - Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * - Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * */ #include #include #include #include #define _GNU_SOURCE #include #include -#include +#include #include "ibdiag_common.h" char *argv0 = ""; static int send_144_node_desc_update(void) { ib_portid_t sm_port; ib_portid_t selfportid; int selfport; ib_rpc_t trap_rpc; ib_mad_notice_attr_t notice; if (ib_resolve_self(&selfportid, &selfport, NULL)) IBERROR("can't resolve self"); if (ib_resolve_smlid(&sm_port, 0)) IBERROR("can't resolve SM destination port"); memset(&trap_rpc, 0, sizeof(trap_rpc)); trap_rpc.mgtclass = IB_SMI_CLASS; trap_rpc.method = IB_MAD_METHOD_TRAP; trap_rpc.trid = mad_trid(); trap_rpc.attr.id = NOTICE; trap_rpc.datasz = IB_SMP_DATA_SIZE; trap_rpc.dataoffs = IB_SMP_DATA_OFFS; memset(¬ice, 0, sizeof(notice)); notice.generic_type = 0x80 | IB_NOTICE_TYPE_INFO; notice.g_or_v.generic.prod_type_lsb = cl_hton16(IB_NODE_TYPE_CA); notice.g_or_v.generic.trap_num = cl_hton16(144); notice.issuer_lid = cl_hton16(selfportid.lid); notice.data_details.ntc_144.lid = cl_hton16(selfportid.lid); notice.data_details.ntc_144.local_changes = TRAP_144_MASK_OTHER_LOCAL_CHANGES; notice.data_details.ntc_144.change_flgs = TRAP_144_MASK_NODE_DESCRIPTION_CHANGE; return (mad_send(&trap_rpc, &sm_port, NULL, ¬ice)); } typedef struct _trap_def { char *trap_name; int (*send_func) (void); } trap_def_t; trap_def_t traps[2] = { {"node_desc_change", send_144_node_desc_update}, {NULL, NULL} }; static void usage(void) { int i; fprintf(stderr, "Usage: %s [-hV]" " [-C ] [-P ] []\n", argv0); fprintf(stderr, " -V print version\n"); fprintf(stderr, " can be one of the following\n"); for (i = 0; traps[i].trap_name; i++) { fprintf(stderr, " %s\n", traps[i].trap_name); } fprintf(stderr, " default behavior is to send \"%s\"\n", traps[0].trap_name); exit(-1); } int send_trap(char *trap_name) { int i; for (i = 0; traps[i].trap_name; i++) { if (strcmp(traps[i].trap_name, trap_name) == 0) { return (traps[i].send_func()); } } usage(); exit(1); } int main(int argc, char **argv) { int mgmt_classes[2] = { IB_SMI_CLASS, IB_SMI_DIRECT_CLASS }; int ch = 0; char *trap_name = NULL; char *ca = NULL; int ca_port = 0; static char const str_opts[] = "hVP:C:"; static const struct option long_opts[] = { {"Version", 0, 0, 'V'}, {"P", 1, 0, 'P'}, {"C", 1, 0, 'C'}, {"help", 0, 0, 'h'}, {} }; argv0 = argv[0]; while ((ch = getopt_long(argc, argv, str_opts, long_opts, NULL)) != -1) { switch (ch) { case 'V': fprintf(stderr, "%s %s\n", argv0, get_build_version()); exit(-1); case 'C': ca = optarg; break; case 'P': ca_port = strtoul(optarg, NULL, 0); break; case 'h': default: usage(); } } argc -= optind; argv += optind; if (!argv[0]) { trap_name = traps[0].trap_name; } else { trap_name = argv[0]; } madrpc_show_errors(1); madrpc_init(ca, ca_port, mgmt_classes, 2); return (send_trap(trap_name)); } Index: stable/9/contrib/ofed/management/infiniband-diags/src/ibtracert.c =================================================================== --- stable/9/contrib/ofed/management/infiniband-diags/src/ibtracert.c (revision 275448) +++ stable/9/contrib/ofed/management/infiniband-diags/src/ibtracert.c (revision 275449) @@ -1,865 +1,865 @@ /* * Copyright (c) 2004-2008 Voltaire Inc. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU * General Public License (GPL) Version 2, available from the file * COPYING in the main directory of this source tree, or the * OpenIB.org BSD license below: * * Redistribution and use in source and binary forms, with or * without modification, are permitted provided that the following * conditions are met: * * - Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * - Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * */ #if HAVE_CONFIG_H # include #endif /* HAVE_CONFIG_H */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include -#include +#include #include "ibdiag_common.h" #define MAXHOPS 63 static char *node_type_str[] = { "???", "ca", "switch", "router", "iwarp rnic" }; static int timeout = 0; /* ms */ static int verbose; static int force; static FILE *f; char *argv0 = "ibtracert"; static char *node_name_map_file = NULL; static nn_map_t *node_name_map = NULL; typedef struct Port Port; typedef struct Switch Switch; typedef struct Node Node; struct Port { Port *next; Port *remoteport; uint64_t portguid; int portnum; int lid; int lmc; int state; int physstate; char portinfo[64]; }; struct Switch { int linearcap; int mccap; int linearFDBtop; int fdb_base; int8_t fdb[64]; char switchinfo[64]; }; struct Node { Node *htnext; Node *dnext; Port *ports; ib_portid_t path; int type; int dist; int numports; int upport; Node *upnode; uint64_t nodeguid; /* also portguid */ char nodedesc[64]; char nodeinfo[64]; }; Node *nodesdist[MAXHOPS]; uint64_t target_portguid; static int get_node(Node *node, Port *port, ib_portid_t *portid) { void *pi = port->portinfo, *ni = node->nodeinfo, *nd = node->nodedesc; char *s, *e; if (!smp_query(ni, portid, IB_ATTR_NODE_INFO, 0, timeout)) return -1; if (!smp_query(nd, portid, IB_ATTR_NODE_DESC, 0, timeout)) return -1; for (s = nd, e = s + 64; s < e; s++) { if (!*s) break; if (!isprint(*s)) *s = ' '; } if (!smp_query(pi, portid, IB_ATTR_PORT_INFO, 0, timeout)) return -1; mad_decode_field(ni, IB_NODE_GUID_F, &node->nodeguid); mad_decode_field(ni, IB_NODE_TYPE_F, &node->type); mad_decode_field(ni, IB_NODE_NPORTS_F, &node->numports); mad_decode_field(ni, IB_NODE_PORT_GUID_F, &port->portguid); mad_decode_field(ni, IB_NODE_LOCAL_PORT_F, &port->portnum); mad_decode_field(pi, IB_PORT_LID_F, &port->lid); mad_decode_field(pi, IB_PORT_LMC_F, &port->lmc); mad_decode_field(pi, IB_PORT_STATE_F, &port->state); DEBUG("portid %s: got node %" PRIx64 " '%s'", portid2str(portid), node->nodeguid, node->nodedesc); return 0; } static int switch_lookup(Switch *sw, ib_portid_t *portid, int lid) { void *si = sw->switchinfo, *fdb = sw->fdb; if (!smp_query(si, portid, IB_ATTR_SWITCH_INFO, 0, timeout)) return -1; mad_decode_field(si, IB_SW_LINEAR_FDB_CAP_F, &sw->linearcap); mad_decode_field(si, IB_SW_LINEAR_FDB_TOP_F, &sw->linearFDBtop); if (lid > sw->linearcap && lid > sw->linearFDBtop) return -1; if (!smp_query(fdb, portid, IB_ATTR_LINEARFORWTBL, lid / 64, timeout)) return -1; DEBUG("portid %s: forward lid %d to port %d", portid2str(portid), lid, sw->fdb[lid % 64]); return sw->fdb[lid % 64]; } static int sameport(Port *a, Port *b) { return a->portguid == b->portguid || (force && a->lid == b->lid); } static int extend_dpath(ib_dr_path_t *path, int nextport) { if (path->cnt+2 >= sizeof(path->p)) return -1; ++path->cnt; path->p[path->cnt] = nextport; return path->cnt; } static void dump_endnode(int dump, char *prompt, Node *node, Port *port) { char *nodename = NULL; if (!dump) return; if (dump == 1) { fprintf(f, "%s {0x%016" PRIx64 "}[%d]\n", prompt, node->nodeguid, node->type == IB_NODE_SWITCH ? 0 : port->portnum); return; } nodename = remap_node_name(node_name_map, node->nodeguid, node->nodedesc); fprintf(f, "%s %s {0x%016" PRIx64 "} portnum %d lid %u-%u \"%s\"\n", prompt, (node->type <= IB_NODE_MAX ? node_type_str[node->type] : "???"), node->nodeguid, node->type == IB_NODE_SWITCH ? 0 : port->portnum, port->lid, port->lid + (1 << port->lmc) - 1, nodename); free(nodename); } static void dump_route(int dump, Node *node, int outport, Port *port) { char *nodename = NULL; if (!dump && !verbose) return; nodename = remap_node_name(node_name_map, node->nodeguid, node->nodedesc); if (dump == 1) fprintf(f, "[%d] -> {0x%016" PRIx64 "}[%d]\n", outport, port->portguid, port->portnum); else fprintf(f, "[%d] -> %s port {0x%016" PRIx64 "}[%d] lid %u-%u \"%s\"\n", outport, (node->type <= IB_NODE_MAX ? node_type_str[node->type] : "???"), port->portguid, port->portnum, port->lid, port->lid + (1 << port->lmc) - 1, nodename); free(nodename); } static int find_route(ib_portid_t *from, ib_portid_t *to, int dump) { Node *node, fromnode, tonode, nextnode; Port *port, fromport, toport, nextport; Switch sw; int maxhops = MAXHOPS; int portnum, outport; DEBUG("from %s", portid2str(from)); if (get_node(&fromnode, &fromport, from) < 0 || get_node(&tonode, &toport, to) < 0) { IBWARN("can't reach to/from ports"); if (!force) return -1; if (to->lid > 0) toport.lid = to->lid; IBWARN("Force: look for lid %d", to->lid); } node = &fromnode; port = &fromport; portnum = port->portnum; dump_endnode(dump, "From", node, port); while (maxhops--) { if (port->state != 4) goto badport; if (sameport(port, &toport)) break; /* found */ outport = portnum; if (node->type == IB_NODE_SWITCH) { DEBUG("switch node"); if ((outport = switch_lookup(&sw, from, to->lid)) < 0 || outport > node->numports) goto badtbl; if (extend_dpath(&from->drpath, outport) < 0) goto badpath; if (get_node(&nextnode, &nextport, from) < 0) { IBWARN("can't reach port at %s", portid2str(from)); return -1; } if (outport == 0) { if (!sameport(&nextport, &toport)) goto badtbl; else break; /* found SMA port */ } } else if ((node->type == IB_NODE_CA) || (node->type == IB_NODE_ROUTER)) { int ca_src = 0; DEBUG("ca or router node"); if (!sameport(port, &fromport)) { IBWARN("can't continue: reached CA or router port %" PRIx64 ", lid %d", port->portguid, port->lid); return -1; } /* we are at CA or router "from" - go one hop back to (hopefully) a switch */ if (from->drpath.cnt > 0) { DEBUG("ca or router node - return back 1 hop"); from->drpath.cnt--; } else { ca_src = 1; if (portnum && extend_dpath(&from->drpath, portnum) < 0) goto badpath; } if (get_node(&nextnode, &nextport, from) < 0) { IBWARN("can't reach port at %s", portid2str(from)); return -1; } /* fix port num to be seen from the CA or router side */ if (!ca_src) nextport.portnum = from->drpath.p[from->drpath.cnt+1]; } port = &nextport; if (port->state != 4) goto badoutport; node = &nextnode; portnum = port->portnum; dump_route(dump, node, outport, port); } if (maxhops <= 0) { IBWARN("no route found after %d hops", MAXHOPS); return -1; } dump_endnode(dump, "To", node, port); return 0; badport: IBWARN("Bad port state found: node \"%s\" port %d state %d", clean_nodedesc(node->nodedesc), portnum, port->state); return -1; badoutport: IBWARN("Bad out port state found: node \"%s\" outport %d state %d", clean_nodedesc(node->nodedesc), outport, port->state); return -1; badtbl: IBWARN("Bad forwarding table entry found at: node \"%s\" lid entry %d is %d (top %d)", clean_nodedesc(node->nodedesc), to->lid, outport, sw.linearFDBtop); return -1; badpath: IBWARN("Direct path too long!"); return -1; } /************************** * MC span part */ #define HASHGUID(guid) ((uint32_t)(((uint32_t)(guid) * 101) ^ ((uint32_t)((guid) >> 32) * 103))) #define HTSZ 137 static int insert_node(Node *new) { static Node *nodestbl[HTSZ]; int hash = HASHGUID(new->nodeguid) % HTSZ; Node *node ; for (node = nodestbl[hash]; node; node = node->htnext) if (node->nodeguid == new->nodeguid) { DEBUG("node %" PRIx64 " already exists", new->nodeguid); return -1; } new->htnext = nodestbl[hash]; nodestbl[hash] = new; return 0; } static int get_port(Port *port, int portnum, ib_portid_t *portid) { char portinfo[64]; void *pi = portinfo; port->portnum = portnum; if (!smp_query(pi, portid, IB_ATTR_PORT_INFO, portnum, timeout)) return -1; mad_decode_field(pi, IB_PORT_LID_F, &port->lid); mad_decode_field(pi, IB_PORT_LMC_F, &port->lmc); mad_decode_field(pi, IB_PORT_STATE_F, &port->state); mad_decode_field(pi, IB_PORT_PHYS_STATE_F, &port->physstate); VERBOSE("portid %s portnum %d: lid %d state %d physstate %d", portid2str(portid), portnum, port->lid, port->state, port->physstate); return 1; } static void link_port(Port *port, Node *node) { port->next = node->ports; node->ports = port; } static int new_node(Node *node, Port *port, ib_portid_t *path, int dist) { if (port->portguid == target_portguid) { node->dist = -1; /* tag as target */ link_port(port, node); dump_endnode(verbose, "found target", node, port); return 1; /* found; */ } /* BFS search start with my self */ if (insert_node(node) < 0) return -1; /* known switch */ VERBOSE("insert dist %d node %p port %d lid %d", dist, node, port->portnum, port->lid); link_port(port, node); node->dist = dist; node->path = *path; node->dnext = nodesdist[dist]; nodesdist[dist] = node; return 0; } static int switch_mclookup(Node *node, ib_portid_t *portid, int mlid, char *map) { Switch sw; char mdb[64]; void *si = sw.switchinfo; uint16_t *msets = (uint16_t *)mdb; int maxsets, block, i, set; memset(map, 0, 256); if (!smp_query(si, portid, IB_ATTR_SWITCH_INFO, 0, timeout)) return -1; mlid -= 0xc000; mad_decode_field(si, IB_SW_MCAST_FDB_CAP_F, &sw.mccap); if (mlid > sw.mccap) return -1; block = mlid / 32; maxsets = (node->numports + 15) / 16; /* round up */ for (set = 0; set < maxsets; set++) { if (!smp_query(mdb, portid, IB_ATTR_MULTICASTFORWTBL, block | (set << 28), timeout)) return -1; for (i = 0; i < 16; i++, map++) { uint16_t mask = ntohs(msets[mlid % 32]); if (mask & (1 << i)) *map = 1; else continue; VERBOSE("Switch guid 0x%" PRIx64 ": mlid 0x%x is forwarded to port %d", node->nodeguid, mlid + 0xc000, i + set * 16); } } return 0; } /* * Return 1 if found, 0 if not, -1 on errors. */ static Node * find_mcpath(ib_portid_t *from, int mlid) { Node *node, *remotenode; Port *port, *remoteport; char map[256]; int r, i; int dist = 0, leafport = 0; ib_portid_t *path; DEBUG("from %s", portid2str(from)); if (!(node = calloc(1, sizeof(Node)))) IBERROR("out of memory"); if (!(port = calloc(1, sizeof(Port)))) IBERROR("out of memory"); if (get_node(node, port, from) < 0) { IBWARN("can't reach node %s", portid2str(from)); return 0; } node->upnode = 0; /* root */ if ((r = new_node(node, port, from, 0)) > 0) { if (node->type != IB_NODE_SWITCH) { IBWARN("ibtracert from CA to CA is unsupported"); return 0; /* ibtracert from host to itself is unsupported */ } if (switch_mclookup(node, from, mlid, map) < 0 || !map[0]) return 0; return node; } for (dist = 0; dist < MAXHOPS; dist++) { for (node = nodesdist[dist]; node; node = node->dnext) { path = &node->path; VERBOSE("dist %d node %p", dist, node); dump_endnode(verbose, "processing", node, node->ports); memset(map, 0, sizeof(map)); if (node->type != IB_NODE_SWITCH) { if (dist) continue; leafport = path->drpath.p[path->drpath.cnt]; map[port->portnum] = 1; node->upport = 0; /* starting here */ DEBUG("Starting from CA 0x%" PRIx64 " lid %d port %d (leafport %d)", node->nodeguid, port->lid, port->portnum, leafport); } else { /* switch */ /* if starting from a leaf port fix up port (up port) */ if (dist == 1 && leafport) node->upport = leafport; if (switch_mclookup(node, path, mlid, map) < 0) { IBWARN("skipping bad Switch 0x%" PRIx64 "", node->nodeguid); continue; } } for (i = 1; i <= node->numports; i++) { if (!map[i] || i == node->upport) continue; if (dist == 0 && leafport) { if (from->drpath.cnt > 0) path->drpath.cnt--; } else { if (!(port = calloc(1, sizeof(Port)))) IBERROR("out of memory"); if (get_port(port, i, path) < 0) { IBWARN("can't reach node %s port %d", portid2str(path), i); return 0; } if (port->physstate != 5) { /* LinkUP */ free(port); continue; } #if 0 link_port(port, node); #endif if (extend_dpath(&path->drpath, i) < 0) return 0; } if (!(remotenode = calloc(1, sizeof(Node)))) IBERROR("out of memory"); if (!(remoteport = calloc(1, sizeof(Port)))) IBERROR("out of memory"); if (get_node(remotenode, remoteport, path) < 0) { IBWARN("NodeInfo on %s port %d failed, skipping port", portid2str(path), i); path->drpath.cnt--; /* restore path */ free(remotenode); free(remoteport); continue; } remotenode->upnode = node; remotenode->upport = remoteport->portnum; remoteport->remoteport = port; if ((r = new_node(remotenode, remoteport, path, dist+1)) > 0) return remotenode; if (r == 0) dump_endnode(verbose, "new remote", remotenode, remoteport); else if (remotenode->type == IB_NODE_SWITCH) dump_endnode(2, "ERR: circle discovered at", remotenode, remoteport); path->drpath.cnt--; /* restore path */ } } } return 0; /* not found */ } static uint64_t find_target_portguid(ib_portid_t *to) { Node tonode; Port toport; if (get_node(&tonode, &toport, to) < 0) { IBWARN("can't find to port\n"); return -1; } return toport.portguid; } static void dump_mcpath(Node *node, int dumplevel) { char *nodename = NULL; if (node->upnode) dump_mcpath(node->upnode, dumplevel); nodename = remap_node_name(node_name_map, node->nodeguid, node->nodedesc); if (!node->dist) { printf("From %s 0x%" PRIx64 " port %d lid %u-%u \"%s\"\n", (node->type <= IB_NODE_MAX ? node_type_str[node->type] : "???"), node->nodeguid, node->ports->portnum, node->ports->lid, node->ports->lid + (1 << node->ports->lmc) - 1, nodename); goto free_name; } if (node->dist) { if (dumplevel == 1) printf("[%d] -> %s {0x%016" PRIx64 "}[%d]\n", node->ports->remoteport->portnum, (node->type <= IB_NODE_MAX ? node_type_str[node->type] : "???"), node->nodeguid, node->upport); else printf("[%d] -> %s 0x%" PRIx64 "[%d] lid %u \"%s\"\n", node->ports->remoteport->portnum, (node->type <= IB_NODE_MAX ? node_type_str[node->type] : "???"), node->nodeguid, node->upport, node->ports->lid, nodename); } if (node->dist < 0) /* target node */ printf("To %s 0x%" PRIx64 " port %d lid %u-%u \"%s\"\n", (node->type <= IB_NODE_MAX ? node_type_str[node->type] : "???"), node->nodeguid, node->ports->portnum, node->ports->lid, node->ports->lid + (1 << node->ports->lmc) - 1, nodename); free_name: free(nodename); } static int resolve_lid(ib_portid_t *portid, const void *srcport) { uint8_t portinfo[64]; uint16_t lid; if (!smp_query_via(portinfo, portid, IB_ATTR_PORT_INFO, 0, 0, srcport)) return -1; mad_decode_field(portinfo, IB_PORT_LID_F, &lid); ib_portid_set(portid, lid, 0, 0); return 0; } static void usage(void) { char *basename; if (!(basename = strrchr(argv0, '/'))) basename = argv0; else basename++; fprintf(stderr, "Usage: %s [-d(ebug) -v(erbose) -D(irect) -G(uids) -n(o_info) -C ca_name -P ca_port " "-s smlid -t(imeout) timeout_ms -m mlid --node-name-map node-name-map ] \n", basename); fprintf(stderr, "\n\tUnicast examples:\n"); fprintf(stderr, "\t\t%s 4 16\t\t\t# show path between lids 4 and 16\n", basename); fprintf(stderr, "\t\t%s -n 4 16\t\t# same, but using simple output format\n", basename); fprintf(stderr, "\t\t%s -G 0x8f1040396522d 0x002c9000100d051\t# use guid addresses\n", basename); fprintf(stderr, "\n\tMulticast example:\n"); fprintf(stderr, "\t\t%s -m 0xc000 4 16\t# show multicast path of mlid 0xc000 between lids 4 and 16\n", basename); exit(-1); } int main(int argc, char **argv) { int mgmt_classes[3] = {IB_SMI_CLASS, IB_SMI_DIRECT_CLASS, IB_SA_CLASS}; ib_portid_t my_portid = {0}; ib_portid_t src_portid = {0}; ib_portid_t dest_portid = {0}; ib_portid_t *sm_id = 0, sm_portid = {0}; int dumplevel = 2, dest_type = IB_DEST_LID, multicast = 0, mlid = 0; Node *endnode; int udebug = 0; char *ca = 0; int ca_port = 0; static char const str_opts[] = "C:P:t:s:m:dvfDGnVhu"; static const struct option long_opts[] = { { "C", 1, 0, 'C'}, { "P", 1, 0, 'P'}, { "debug", 0, 0, 'd'}, { "verbose", 0, 0, 'v'}, { "force", 0, 0, 'f'}, { "Direct", 0, 0, 'D'}, { "Guids", 0, 0, 'G'}, { "no_info", 0, 0, 'n'}, { "timeout", 1, 0, 't'}, { "s", 1, 0, 's'}, { "m", 1, 0, 'm'}, { "Version", 0, 0, 'V'}, { "help", 0, 0, 'h'}, { "usage", 0, 0, 'u'}, { "node-name-map", 1, 0, 1}, { } }; argv0 = argv[0]; f = stdout; while (1) { int ch = getopt_long(argc, argv, str_opts, long_opts, NULL); if ( ch == -1 ) break; switch(ch) { case 1: node_name_map_file = strdup(optarg); break; case 'C': ca = optarg; break; case 'P': ca_port = strtoul(optarg, 0, 0); break; case 'd': ibdebug++; madrpc_show_errors(1); umad_debug(udebug); udebug++; break; case 'D': dest_type = IB_DEST_DRPATH; break; case 'G': dest_type = IB_DEST_GUID; break; case 'm': multicast++; mlid = strtoul(optarg, 0, 0); break; case 'f': force++; break; case 'n': dumplevel = 1; break; case 's': if (ib_resolve_portid_str(&sm_portid, optarg, IB_DEST_LID, 0) < 0) IBERROR("can't resolve SM destination port %s", optarg); sm_id = &sm_portid; break; case 't': timeout = strtoul(optarg, 0, 0); madrpc_set_timeout(timeout); break; case 'v': madrpc_show_errors(1); verbose++; break; case 'V': fprintf(stderr, "%s %s\n", argv0, get_build_version() ); exit(-1); default: usage(); break; } } argc -= optind; argv += optind; if (argc < 2) usage(); madrpc_init(ca, ca_port, mgmt_classes, 3); node_name_map = open_node_name_map(node_name_map_file); if (ib_resolve_portid_str(&src_portid, argv[0], dest_type, sm_id) < 0) IBERROR("can't resolve source port %s", argv[0]); if (ib_resolve_portid_str(&dest_portid, argv[1], dest_type, sm_id) < 0) IBERROR("can't resolve destination port %s", argv[1]); if (dest_type == IB_DEST_DRPATH) { if (resolve_lid(&src_portid, NULL) < 0) IBERROR("cannot resolve lid for port \'%s\'", portid2str(&src_portid)); if (resolve_lid(&dest_portid, NULL) < 0) IBERROR("cannot resolve lid for port \'%s\'", portid2str(&dest_portid)); } if (dest_portid.lid == 0 || src_portid.lid == 0) { IBWARN("bad src/dest lid"); usage(); } if (dest_type != IB_DEST_DRPATH) { /* first find a direct path to the src port */ if (find_route(&my_portid, &src_portid, 0) < 0) IBERROR("can't find a route to the src port"); src_portid = my_portid; } if (!multicast) { if (find_route(&src_portid, &dest_portid, dumplevel) < 0) IBERROR("can't find a route from src to dest"); exit(0); } else { if (mlid < 0xc000) IBWARN("invalid MLID; must be 0xc000 or larger"); } if (!(target_portguid = find_target_portguid(&dest_portid))) IBERROR("can't reach target lid %d", dest_portid.lid); if (!(endnode = find_mcpath(&src_portid, mlid))) IBERROR("can't find a multicast route from src to dest"); /* dump multicast path */ dump_mcpath(endnode, dumplevel); close_node_name_map(node_name_map); exit(0); } Index: stable/9/contrib/ofed/management/infiniband-diags/src/saquery.c =================================================================== --- stable/9/contrib/ofed/management/infiniband-diags/src/saquery.c (revision 275448) +++ stable/9/contrib/ofed/management/infiniband-diags/src/saquery.c (revision 275449) @@ -1,1891 +1,1891 @@ /* * Copyright (c) 2006,2007 The Regents of the University of California. * Copyright (c) 2004-2008 Voltaire, Inc. All rights reserved. * Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved. * Copyright (c) 1996-2003 Intel Corporation. All rights reserved. * * Produced at Lawrence Livermore National Laboratory. * Written by Ira Weiny . * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU * General Public License (GPL) Version 2, available from the file * COPYING in the main directory of this source tree, or the * OpenIB.org BSD license below: * * Redistribution and use in source and binary forms, with or * without modification, are permitted provided that the following * conditions are met: * * - Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * - Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * */ #include #include #include #include #include #include #include #include #define _GNU_SOURCE #include #include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include #include #include "ibdiag_common.h" struct query_cmd { const char *name, *alias; ib_net16_t query_type; const char *usage; int (*handler) (const struct query_cmd * q, osm_bind_handle_t h, int argc, char *argv[]); }; char *argv0 = "saquery"; static char *node_name_map_file = NULL; static nn_map_t *node_name_map = NULL; static ib_net64_t smkey = OSM_DEFAULT_SA_KEY; /** * Declare some globals because I don't want this to be too complex. */ #define MAX_PORTS (8) #define DEFAULT_SA_TIMEOUT_MS (1000) osmv_query_res_t result; osm_log_t log_osm; osm_mad_pool_t mad_pool; osm_vendor_t *vendor = NULL; int osm_debug = 0; uint32_t sa_timeout_ms = DEFAULT_SA_TIMEOUT_MS; char *sa_hca_name = NULL; uint32_t sa_port_num = 0; enum { ALL, LID_ONLY, UNIQUE_LID_ONLY, GUID_ONLY, ALL_DESC, NAME_OF_LID, NAME_OF_GUID, } node_print_desc = ALL; char *requested_name = NULL; ib_net16_t requested_lid = 0; int requested_lid_flag = 0; ib_net64_t requested_guid = 0; int requested_guid_flag = 0; static void format_buf(char *in, char *out, unsigned size) { unsigned i; for (i = 0; i < size - 3 && *in; i++) { *out++ = *in; if (*in++ == '\n' && *in) { *out++ = '\t'; *out++ = '\t'; } } *out = '\0'; } /** * Call back for the various record requests. */ static void query_res_cb(osmv_query_res_t * res) { result = *res; } static void print_node_desc(ib_node_record_t * node_record) { ib_node_info_t *p_ni = &(node_record->node_info); ib_node_desc_t *p_nd = &(node_record->node_desc); if (p_ni->node_type == IB_NODE_TYPE_CA) { printf("%6d \"%s\"\n", cl_ntoh16(node_record->lid), clean_nodedesc((char *)p_nd->description)); } } static void print_node_record(ib_node_record_t * node_record) { ib_node_info_t *p_ni = NULL; ib_node_desc_t *p_nd = NULL; char *name; p_ni = &(node_record->node_info); p_nd = &(node_record->node_desc); switch (node_print_desc) { case LID_ONLY: case UNIQUE_LID_ONLY: printf("%d\n", cl_ntoh16(node_record->lid)); return; case GUID_ONLY: printf("0x%016" PRIx64 "\n", cl_ntoh64(p_ni->port_guid)); return; case NAME_OF_LID: case NAME_OF_GUID: name = remap_node_name(node_name_map, cl_ntoh64(p_ni->node_guid), (char *)p_nd->description); printf("%s\n", name); free(name); return; case ALL: default: break; } printf("NodeRecord dump:\n" "\t\tlid.....................0x%X\n" "\t\treserved................0x%X\n" "\t\tbase_version............0x%X\n" "\t\tclass_version...........0x%X\n" "\t\tnode_type...............%s\n" "\t\tnum_ports...............0x%X\n" "\t\tsys_guid................0x%016" PRIx64 "\n" "\t\tnode_guid...............0x%016" PRIx64 "\n" "\t\tport_guid...............0x%016" PRIx64 "\n" "\t\tpartition_cap...........0x%X\n" "\t\tdevice_id...............0x%X\n" "\t\trevision................0x%X\n" "\t\tport_num................0x%X\n" "\t\tvendor_id...............0x%X\n" "\t\tNodeDescription.........%s\n" "", cl_ntoh16(node_record->lid), cl_ntoh16(node_record->resv), p_ni->base_version, p_ni->class_version, ib_get_node_type_str(p_ni->node_type), p_ni->num_ports, cl_ntoh64(p_ni->sys_guid), cl_ntoh64(p_ni->node_guid), cl_ntoh64(p_ni->port_guid), cl_ntoh16(p_ni->partition_cap), cl_ntoh16(p_ni->device_id), cl_ntoh32(p_ni->revision), ib_node_info_get_local_port_num(p_ni), cl_ntoh32(ib_node_info_get_vendor_id(p_ni)), clean_nodedesc((char *)node_record->node_desc.description) ); } static void dump_path_record(void *data) { char gid_str[INET6_ADDRSTRLEN]; char gid_str2[INET6_ADDRSTRLEN]; ib_path_rec_t *p_pr = data; printf("PathRecord dump:\n" "\t\tservice_id..............0x%016" PRIx64 "\n" "\t\tdgid....................%s\n" "\t\tsgid....................%s\n" "\t\tdlid....................0x%X\n" "\t\tslid....................0x%X\n" "\t\thop_flow_raw............0x%X\n" "\t\ttclass..................0x%X\n" "\t\tnum_path_revers.........0x%X\n" "\t\tpkey....................0x%X\n" "\t\tqos_class...............0x%X\n" "\t\tsl......................0x%X\n" "\t\tmtu.....................0x%X\n" "\t\trate....................0x%X\n" "\t\tpkt_life................0x%X\n" "\t\tpreference..............0x%X\n" "\t\tresv2...................0x%X\n" "\t\tresv3...................0x%X\n" "", cl_ntoh64(p_pr->service_id), inet_ntop(AF_INET6, p_pr->dgid.raw, gid_str, sizeof gid_str), inet_ntop(AF_INET6, p_pr->sgid.raw, gid_str2, sizeof gid_str2), cl_ntoh16(p_pr->dlid), cl_ntoh16(p_pr->slid), cl_ntoh32(p_pr->hop_flow_raw), p_pr->tclass, p_pr->num_path, cl_ntoh16(p_pr->pkey), ib_path_rec_qos_class(p_pr), ib_path_rec_sl(p_pr), p_pr->mtu, p_pr->rate, p_pr->pkt_life, p_pr->preference, *(uint32_t *) & p_pr->resv2, *((uint16_t *) & p_pr->resv2 + 2) ); } static void dump_class_port_info(void *data) { char gid_str[INET6_ADDRSTRLEN]; char gid_str2[INET6_ADDRSTRLEN]; ib_class_port_info_t *class_port_info = data; printf("SA ClassPortInfo:\n" "\t\tBase version.............%d\n" "\t\tClass version............%d\n" "\t\tCapability mask..........0x%04X\n" "\t\tCapability mask 2........0x%08X\n" "\t\tResponse time value......0x%02X\n" "\t\tRedirect GID.............%s\n" "\t\tRedirect TC/SL/FL........0x%08X\n" "\t\tRedirect LID.............0x%04X\n" "\t\tRedirect PKey............0x%04X\n" "\t\tRedirect QP..............0x%08X\n" "\t\tRedirect QKey............0x%08X\n" "\t\tTrap GID.................%s\n" "\t\tTrap TC/SL/FL............0x%08X\n" "\t\tTrap LID.................0x%04X\n" "\t\tTrap PKey................0x%04X\n" "\t\tTrap HL/QP...............0x%08X\n" "\t\tTrap QKey................0x%08X\n" "", class_port_info->base_ver, class_port_info->class_ver, cl_ntoh16(class_port_info->cap_mask), ib_class_cap_mask2(class_port_info), ib_class_resp_time_val(class_port_info), inet_ntop(AF_INET6, &(class_port_info->redir_gid), gid_str, sizeof gid_str), cl_ntoh32(class_port_info->redir_tc_sl_fl), cl_ntoh16(class_port_info->redir_lid), cl_ntoh16(class_port_info->redir_pkey), cl_ntoh32(class_port_info->redir_qp), cl_ntoh32(class_port_info->redir_qkey), inet_ntop(AF_INET6, &(class_port_info->trap_gid), gid_str2, sizeof gid_str2), cl_ntoh32(class_port_info->trap_tc_sl_fl), cl_ntoh16(class_port_info->trap_lid), cl_ntoh16(class_port_info->trap_pkey), cl_ntoh32(class_port_info->trap_hop_qp), cl_ntoh32(class_port_info->trap_qkey) ); } static void dump_portinfo_record(void *data) { ib_portinfo_record_t *p_pir = data; const ib_port_info_t *const p_pi = &p_pir->port_info; printf("PortInfoRecord dump:\n" "\t\tEndPortLid..............0x%X\n" "\t\tPortNum.................0x%X\n" "\t\tbase_lid................0x%X\n" "\t\tmaster_sm_base_lid......0x%X\n" "\t\tcapability_mask.........0x%X\n" "", cl_ntoh16(p_pir->lid), p_pir->port_num, cl_ntoh16(p_pi->base_lid), cl_ntoh16(p_pi->master_sm_base_lid), cl_ntoh32(p_pi->capability_mask) ); } static void dump_one_portinfo_record(void *data) { char buf[2048], buf2[4096]; ib_portinfo_record_t *pir = data; ib_port_info_t *pi = &pir->port_info; mad_dump_portinfo(buf, sizeof(buf), pi, sizeof(*pi)); format_buf(buf, buf2, sizeof(buf2)); printf("PortInfoRecord dump:\n" "\tRID:\n" "\t\tEndPortLid..............%u\n" "\t\tPortNum.................0x%x\n" "\t\tReserved................0x%x\n" "\tPortInfo dump:\n\t\t%s", cl_ntoh16(pir->lid), pir->port_num, pir->resv, buf2); } static void dump_multicast_group_record(void *data) { char gid_str[INET6_ADDRSTRLEN]; ib_member_rec_t *p_mcmr = data; uint8_t sl; ib_member_get_sl_flow_hop(p_mcmr->sl_flow_hop, &sl, NULL, NULL); printf("MCMemberRecord group dump:\n" "\t\tMGID....................%s\n" "\t\tMlid....................0x%X\n" "\t\tMtu.....................0x%X\n" "\t\tpkey....................0x%X\n" "\t\tRate....................0x%X\n" "\t\tSL......................0x%X\n" "", inet_ntop(AF_INET6, p_mcmr->mgid.raw, gid_str, sizeof gid_str), cl_ntoh16(p_mcmr->mlid), p_mcmr->mtu, cl_ntoh16(p_mcmr->pkey), p_mcmr->rate, sl); } static void dump_multicast_member_record(void *data) { char gid_str[INET6_ADDRSTRLEN]; char gid_str2[INET6_ADDRSTRLEN]; ib_member_rec_t *p_mcmr = data; uint16_t mlid = cl_ntoh16(p_mcmr->mlid); int i = 0; char *node_name = ""; /* go through the node records searching for a port guid which matches * this port gid interface id. * This gives us a node name to print, if available. */ for (i = 0; i < result.result_cnt; i++) { ib_node_record_t *nr = osmv_get_query_node_rec(result.p_result_madw, i); if (nr->node_info.port_guid == p_mcmr->port_gid.unicast.interface_id) { node_name = clean_nodedesc((char *)nr->node_desc.description); break; } } if (requested_name) { if (strtol(requested_name, NULL, 0) == mlid) { printf("\t\tPortGid.................%s (%s)\n", inet_ntop(AF_INET6, p_mcmr->port_gid.raw, gid_str, sizeof gid_str), node_name); } } else { printf("MCMemberRecord member dump:\n" "\t\tMGID....................%s\n" "\t\tMlid....................0x%X\n" "\t\tPortGid.................%s\n" "\t\tScopeState..............0x%X\n" "\t\tProxyJoin...............0x%X\n" "\t\tNodeDescription.........%s\n" "", inet_ntop(AF_INET6, p_mcmr->mgid.raw, gid_str, sizeof gid_str), cl_ntoh16(p_mcmr->mlid), inet_ntop(AF_INET6, p_mcmr->port_gid.raw, gid_str2, sizeof gid_str2), p_mcmr->scope_state, p_mcmr->proxy_join, node_name); } } static void dump_service_record(void *data) { char gid_str[INET6_ADDRSTRLEN]; char buf_service_key[35]; char buf_service_name[65]; ib_service_record_t *p_sr = data; sprintf(buf_service_key, "0x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", p_sr->service_key[0], p_sr->service_key[1], p_sr->service_key[2], p_sr->service_key[3], p_sr->service_key[4], p_sr->service_key[5], p_sr->service_key[6], p_sr->service_key[7], p_sr->service_key[8], p_sr->service_key[9], p_sr->service_key[10], p_sr->service_key[11], p_sr->service_key[12], p_sr->service_key[13], p_sr->service_key[14], p_sr->service_key[15]); strncpy(buf_service_name, (char *)p_sr->service_name, 64); buf_service_name[64] = '\0'; printf("ServiceRecord dump:\n" "\t\tServiceID...............0x%016" PRIx64 "\n" "\t\tServiceGID..............%s\n" "\t\tServiceP_Key............0x%X\n" "\t\tServiceLease............0x%X\n" "\t\tServiceKey..............%s\n" "\t\tServiceName.............%s\n" "\t\tServiceData8.1..........0x%X\n" "\t\tServiceData8.2..........0x%X\n" "\t\tServiceData8.3..........0x%X\n" "\t\tServiceData8.4..........0x%X\n" "\t\tServiceData8.5..........0x%X\n" "\t\tServiceData8.6..........0x%X\n" "\t\tServiceData8.7..........0x%X\n" "\t\tServiceData8.8..........0x%X\n" "\t\tServiceData8.9..........0x%X\n" "\t\tServiceData8.10.........0x%X\n" "\t\tServiceData8.11.........0x%X\n" "\t\tServiceData8.12.........0x%X\n" "\t\tServiceData8.13.........0x%X\n" "\t\tServiceData8.14.........0x%X\n" "\t\tServiceData8.15.........0x%X\n" "\t\tServiceData8.16.........0x%X\n" "\t\tServiceData16.1.........0x%X\n" "\t\tServiceData16.2.........0x%X\n" "\t\tServiceData16.3.........0x%X\n" "\t\tServiceData16.4.........0x%X\n" "\t\tServiceData16.5.........0x%X\n" "\t\tServiceData16.6.........0x%X\n" "\t\tServiceData16.7.........0x%X\n" "\t\tServiceData16.8.........0x%X\n" "\t\tServiceData32.1.........0x%X\n" "\t\tServiceData32.2.........0x%X\n" "\t\tServiceData32.3.........0x%X\n" "\t\tServiceData32.4.........0x%X\n" "\t\tServiceData64.1.........0x%016" PRIx64 "\n" "\t\tServiceData64.2.........0x%016" PRIx64 "\n" "", cl_ntoh64(p_sr->service_id), inet_ntop(AF_INET6, p_sr->service_gid.raw, gid_str, sizeof gid_str), cl_ntoh16(p_sr->service_pkey), cl_ntoh32(p_sr->service_lease), buf_service_key, buf_service_name, p_sr->service_data8[0], p_sr->service_data8[1], p_sr->service_data8[2], p_sr->service_data8[3], p_sr->service_data8[4], p_sr->service_data8[5], p_sr->service_data8[6], p_sr->service_data8[7], p_sr->service_data8[8], p_sr->service_data8[9], p_sr->service_data8[10], p_sr->service_data8[11], p_sr->service_data8[12], p_sr->service_data8[13], p_sr->service_data8[14], p_sr->service_data8[15], cl_ntoh16(p_sr->service_data16[0]), cl_ntoh16(p_sr->service_data16[1]), cl_ntoh16(p_sr->service_data16[2]), cl_ntoh16(p_sr->service_data16[3]), cl_ntoh16(p_sr->service_data16[4]), cl_ntoh16(p_sr->service_data16[5]), cl_ntoh16(p_sr->service_data16[6]), cl_ntoh16(p_sr->service_data16[7]), cl_ntoh32(p_sr->service_data32[0]), cl_ntoh32(p_sr->service_data32[1]), cl_ntoh32(p_sr->service_data32[2]), cl_ntoh32(p_sr->service_data32[3]), cl_ntoh64(p_sr->service_data64[0]), cl_ntoh64(p_sr->service_data64[1]) ); } static void dump_inform_info_record(void *data) { char gid_str[INET6_ADDRSTRLEN]; char gid_str2[INET6_ADDRSTRLEN]; ib_inform_info_record_t *p_iir = data; uint32_t qpn; uint8_t resp_time_val; ib_inform_info_get_qpn_resp_time(p_iir->inform_info.g_or_v.generic. qpn_resp_time_val, &qpn, &resp_time_val); if (p_iir->inform_info.is_generic) { printf("InformInfoRecord dump:\n" "\t\tRID\n" "\t\tSubscriberGID...........%s\n" "\t\tSubscriberEnum..........0x%X\n" "\t\tInformInfo dump:\n" "\t\tgid.....................%s\n" "\t\tlid_range_begin.........0x%X\n" "\t\tlid_range_end...........0x%X\n" "\t\tis_generic..............0x%X\n" "\t\tsubscribe...............0x%X\n" "\t\ttrap_type...............0x%X\n" "\t\ttrap_num................%u\n" "\t\tqpn.....................0x%06X\n" "\t\tresp_time_val...........0x%X\n" "\t\tnode_type...............0x%06X\n" "", inet_ntop(AF_INET6, p_iir->subscriber_gid.raw, gid_str, sizeof gid_str), cl_ntoh16(p_iir->subscriber_enum), inet_ntop(AF_INET6, p_iir->inform_info.gid.raw, gid_str2, sizeof gid_str2), cl_ntoh16(p_iir->inform_info.lid_range_begin), cl_ntoh16(p_iir->inform_info.lid_range_end), p_iir->inform_info.is_generic, p_iir->inform_info.subscribe, cl_ntoh16(p_iir->inform_info.trap_type), cl_ntoh16(p_iir->inform_info.g_or_v.generic.trap_num), cl_ntoh32(qpn), resp_time_val, cl_ntoh32(ib_inform_info_get_prod_type (&p_iir->inform_info)) ); } else { printf("InformInfoRecord dump:\n" "\t\tRID\n" "\t\tSubscriberGID...........%s\n" "\t\tSubscriberEnum..........0x%X\n" "\t\tInformInfo dump:\n" "\t\tgid.....................%s\n" "\t\tlid_range_begin.........0x%X\n" "\t\tlid_range_end...........0x%X\n" "\t\tis_generic..............0x%X\n" "\t\tsubscribe...............0x%X\n" "\t\ttrap_type...............0x%X\n" "\t\tdev_id..................0x%X\n" "\t\tqpn.....................0x%06X\n" "\t\tresp_time_val...........0x%X\n" "\t\tvendor_id...............0x%06X\n" "", inet_ntop(AF_INET6, p_iir->subscriber_gid.raw, gid_str, sizeof gid_str), cl_ntoh16(p_iir->subscriber_enum), inet_ntop(AF_INET6, p_iir->inform_info.gid.raw, gid_str2, sizeof gid_str2), cl_ntoh16(p_iir->inform_info.lid_range_begin), cl_ntoh16(p_iir->inform_info.lid_range_end), p_iir->inform_info.is_generic, p_iir->inform_info.subscribe, cl_ntoh16(p_iir->inform_info.trap_type), cl_ntoh16(p_iir->inform_info.g_or_v.vend.dev_id), cl_ntoh32(qpn), resp_time_val, cl_ntoh32(ib_inform_info_get_prod_type (&p_iir->inform_info)) ); } } static void dump_one_link_record(void *data) { ib_link_record_t *lr = data; printf("LinkRecord dump:\n" "\t\tFromLID....................%u\n" "\t\tFromPort...................%u\n" "\t\tToPort.....................%u\n" "\t\tToLID......................%u\n", cl_ntoh16(lr->from_lid), lr->from_port_num, lr->to_port_num, cl_ntoh16(lr->to_lid)); } static void dump_one_slvl_record(void *data) { ib_slvl_table_record_t *slvl = data; ib_slvl_table_t *t = &slvl->slvl_tbl; printf("SL2VLTableRecord dump:\n" "\t\tLID........................%u\n" "\t\tInPort.....................%u\n" "\t\tOutPort....................%u\n" "\t\tSL: 0| 1| 2| 3| 4| 5| 6| 7| 8| 9|10|11|12|13|14|15|\n" "\t\tVL:%2u|%2u|%2u|%2u|%2u|%2u|%2u|%2u|%2u|%2u|%2u|%2u|%2u" "|%2u|%2u|%2u|\n", cl_ntoh16(slvl->lid), slvl->in_port_num, slvl->out_port_num, ib_slvl_table_get(t, 0), ib_slvl_table_get(t, 1), ib_slvl_table_get(t, 2), ib_slvl_table_get(t, 3), ib_slvl_table_get(t, 4), ib_slvl_table_get(t, 5), ib_slvl_table_get(t, 6), ib_slvl_table_get(t, 7), ib_slvl_table_get(t, 8), ib_slvl_table_get(t, 9), ib_slvl_table_get(t, 10), ib_slvl_table_get(t, 11), ib_slvl_table_get(t, 12), ib_slvl_table_get(t, 13), ib_slvl_table_get(t, 14), ib_slvl_table_get(t, 15)); } static void dump_one_vlarb_record(void *data) { ib_vl_arb_table_record_t *vlarb = data; ib_vl_arb_element_t *e = vlarb->vl_arb_tbl.vl_entry; int i; printf("VLArbTableRecord dump:\n" "\t\tLID........................%u\n" "\t\tPort.......................%u\n" "\t\tBlock......................%u\n", cl_ntoh16(vlarb->lid), vlarb->port_num, vlarb->block_num); for (i = 0; i < 32; i += 16) { printf("\t\tVL :%2u|%2u|%2u|%2u|%2u|%2u|%2u|%2u|" "%2u|%2u|%2u|%2u|%2u|%2u|%2u|%2u|", e[i + 0].vl, e[i + 1].vl, e[i + 2].vl, e[i + 3].vl, e[i + 4].vl, e[i + 5].vl, e[i + 6].vl, e[i + 7].vl, e[i + 8].vl, e[i + 9].vl, e[i + 10].vl, e[i + 11].vl, e[i + 12].vl, e[i + 13].vl, e[i + 14].vl, e[i + 15].vl); printf("\n\t\tWeight:%2u|%2u|%2u|%2u|%2u|%2u|%2u|%2u|" "%2u|%2u|%2u|%2u|%2u|%2u|%2u|%2u|", e[i + 0].weight, e[i + 1].weight, e[i + 2].weight, e[i + 3].weight, e[i + 4].weight, e[i + 5].weight, e[i + 6].weight, e[i + 7].weight, e[i + 8].weight, e[i + 9].weight, e[i + 10].weight, e[i + 11].weight, e[i + 12].weight, e[i + 13].weight, e[i + 14].weight, e[i + 15].weight); printf("\n"); } } static void dump_one_pkey_tbl_record(void *data) { ib_pkey_table_record_t *pktr = data; ib_net16_t *p = pktr->pkey_tbl.pkey_entry; int i; printf("PKeyTableRecord dump:\n" "\t\tLID........................%u\n" "\t\tPort.......................%u\n" "\t\tBlock......................%u\n" "\t\tPKey Table:\n", cl_ntoh16(pktr->lid), pktr->port_num, pktr->block_num); for (i = 0; i < 32; i += 8) printf("\t\t0x%04x 0x%04x 0x%04x 0x%04x" " 0x%04x 0x%04x 0x%04x 0x%04x\n", cl_ntoh16(p[i + 0]), cl_ntoh16(p[i + 1]), cl_ntoh16(p[i + 2]), cl_ntoh16(p[i + 3]), cl_ntoh16(p[i + 4]), cl_ntoh16(p[i + 5]), cl_ntoh16(p[i + 6]), cl_ntoh16(p[i + 7])); printf("\n"); } static void dump_one_lft_record(void *data) { ib_lft_record_t *lftr = data; unsigned block = cl_ntoh16(lftr->block_num); int i; printf("LFT Record dump:\n" "\t\tLID........................%u\n" "\t\tBlock......................%u\n" "\t\tLFT:\n\t\tLID\tPort Number\n", cl_ntoh16(lftr->lid), block); for (i = 0; i < 64; i++) printf("\t\t%u\t%u\n", block * 64 + i, lftr->lft[i]); printf("\n"); } static void dump_one_mft_record(void *data) { ib_mft_record_t *mftr = data; unsigned position = cl_ntoh16(mftr->position_block_num) >> 12; unsigned block = cl_ntoh16(mftr->position_block_num) & IB_MCAST_BLOCK_ID_MASK_HO; int i; printf("MFT Record dump:\n" "\t\tLID........................%u\n" "\t\tPosition...................%u\n" "\t\tBlock......................%u\n" "\t\tMFT:\n\t\tMLID\tPort Mask\n", cl_ntoh16(mftr->lid), position, block); for (i = 0; i < IB_MCAST_BLOCK_SIZE; i++) printf("\t\t0x%x\t0x%x\n", IB_LID_MCAST_START_HO + block * 64 + i, cl_ntoh16(mftr->mft[i])); printf("\n"); } static void dump_results(osmv_query_res_t * r, void (*dump_func) (void *)) { int i; for (i = 0; i < r->result_cnt; i++) { void *data = osmv_get_query_result(r->p_result_madw, i); dump_func(data); } } static void return_mad(void) { /* * Return the IB query MAD to the pool as necessary. */ if (result.p_result_madw != NULL) { osm_mad_pool_put(&mad_pool, result.p_result_madw); result.p_result_madw = NULL; } } /** * Get any record(s) */ static ib_api_status_t get_any_records(osm_bind_handle_t h, ib_net16_t attr_id, ib_net32_t attr_mod, ib_net64_t comp_mask, void *attr, ib_net16_t attr_offset, ib_net64_t sm_key) { ib_api_status_t status; osmv_query_req_t req; osmv_user_query_t user; memset(&req, 0, sizeof(req)); memset(&user, 0, sizeof(user)); user.attr_id = attr_id; user.attr_offset = attr_offset; user.attr_mod = attr_mod; user.comp_mask = comp_mask; user.p_attr = attr; req.query_type = OSMV_QUERY_USER_DEFINED; req.timeout_ms = sa_timeout_ms; req.retry_cnt = 1; req.flags = OSM_SA_FLAGS_SYNC; req.query_context = NULL; req.pfn_query_cb = query_res_cb; req.p_query_input = &user; req.sm_key = sm_key; if ((status = osmv_query_sa(h, &req)) != IB_SUCCESS) { fprintf(stderr, "Query SA failed: %s\n", ib_get_err_str(status)); return status; } if (result.status != IB_SUCCESS) { fprintf(stderr, "Query result returned: %s\n", ib_get_err_str(result.status)); return result.status; } return status; } /** * Get all the records available for requested query type. */ static ib_api_status_t get_all_records(osm_bind_handle_t h, ib_net16_t query_id, ib_net16_t attr_offset, int trusted) { return get_any_records(h, query_id, 0, 0, NULL, attr_offset, trusted ? smkey : 0); } /** * return the lid from the node descriptor (name) supplied */ static ib_api_status_t get_lid_from_name(osm_bind_handle_t h, const char *name, ib_net16_t * lid) { int i = 0; ib_node_record_t *node_record = NULL; ib_node_info_t *p_ni = NULL; ib_net16_t attr_offset = ib_get_attr_offset(sizeof(*node_record)); ib_api_status_t status; status = get_all_records(h, IB_MAD_ATTR_NODE_RECORD, attr_offset, 0); if (status != IB_SUCCESS) return (status); for (i = 0; i < result.result_cnt; i++) { node_record = osmv_get_query_node_rec(result.p_result_madw, i); p_ni = &(node_record->node_info); if (name && strncmp(name, (char *)node_record->node_desc.description, sizeof(node_record->node_desc.description)) == 0) { *lid = cl_ntoh16(node_record->lid); break; } } return_mad(); return (status); } static ib_net16_t get_lid(osm_bind_handle_t h, const char *name) { ib_net16_t rc_lid = 0; if (!name) return (0); if (isalpha(name[0])) assert(get_lid_from_name(h, name, &rc_lid) == IB_SUCCESS); else rc_lid = atoi(name); if (rc_lid == 0) fprintf(stderr, "Failed to find lid for \"%s\"\n", name); return (rc_lid); } static int parse_lid_and_ports(osm_bind_handle_t h, char *str, int *lid, int *port1, int *port2) { char *p, *e; if (port1) *port1 = -1; if (port2) *port2 = -1; p = strchr(str, '/'); if (p) *p = '\0'; if (lid) *lid = get_lid(h, str); if (!p) return 0; str = p + 1; p = strchr(str, '/'); if (p) *p = '\0'; if (port1) { *port1 = strtoul(str, &e, 0); if (e == str) *port1 = -1; } if (!p) return 0; str = p + 1; if (port2) { *port2 = strtoul(str, &e, 0); if (e == str) *port2 = -1; } return 0; } /* * Get the portinfo records available with IsSM or IsSMdisabled CapabilityMask bit on. */ static ib_api_status_t get_issm_records(osm_bind_handle_t h, ib_net32_t capability_mask) { ib_portinfo_record_t attr; memset(&attr, 0, sizeof(attr)); attr.port_info.capability_mask = capability_mask; return get_any_records(h, IB_MAD_ATTR_PORTINFO_RECORD, cl_hton32(1 << 31), IB_PIR_COMPMASK_CAPMASK, &attr, ib_get_attr_offset(sizeof(ib_portinfo_record_t)), 0); } static ib_api_status_t print_node_records(osm_bind_handle_t h) { int i = 0; ib_node_record_t *node_record = NULL; ib_net16_t attr_offset = ib_get_attr_offset(sizeof(*node_record)); ib_api_status_t status; status = get_all_records(h, IB_MAD_ATTR_NODE_RECORD, attr_offset, 0); if (status != IB_SUCCESS) return (status); if (node_print_desc == ALL_DESC) { printf(" LID \"name\"\n"); printf("================\n"); } for (i = 0; i < result.result_cnt; i++) { node_record = osmv_get_query_node_rec(result.p_result_madw, i); if (node_print_desc == ALL_DESC) { print_node_desc(node_record); } else if (node_print_desc == NAME_OF_LID) { if (requested_lid == cl_ntoh16(node_record->lid)) { print_node_record(node_record); } } else if (node_print_desc == NAME_OF_GUID) { ib_node_info_t *p_ni = &(node_record->node_info); if (requested_guid == cl_ntoh64(p_ni->port_guid)) { print_node_record(node_record); } } else { if (!requested_name || (strncmp(requested_name, (char *)node_record->node_desc.description, sizeof(node_record->node_desc. description)) == 0)) { print_node_record(node_record); if (node_print_desc == UNIQUE_LID_ONLY) { return_mad(); exit(0); } } } } return_mad(); return (status); } static ib_api_status_t get_print_path_rec_lid(osm_bind_handle_t h, ib_net16_t src_lid, ib_net16_t dst_lid) { osmv_query_req_t req; osmv_lid_pair_t lid_pair; ib_api_status_t status; lid_pair.src_lid = cl_hton16(src_lid); lid_pair.dest_lid = cl_hton16(dst_lid); memset(&req, 0, sizeof(req)); req.query_type = OSMV_QUERY_PATH_REC_BY_LIDS; req.timeout_ms = sa_timeout_ms; req.retry_cnt = 1; req.flags = OSM_SA_FLAGS_SYNC; req.query_context = NULL; req.pfn_query_cb = query_res_cb; req.p_query_input = (void *)&lid_pair; req.sm_key = 0; if ((status = osmv_query_sa(h, &req)) != IB_SUCCESS) { fprintf(stderr, "ERROR: Query SA failed: %s\n", ib_get_err_str(status)); return (status); } if (result.status != IB_SUCCESS) { fprintf(stderr, "ERROR: Query result returned: %s\n", ib_get_err_str(result.status)); return (result.status); } status = result.status; dump_results(&result, dump_path_record); return_mad(); return (status); } static ib_api_status_t get_print_path_rec_gid(osm_bind_handle_t h, const ib_gid_t * src_gid, const ib_gid_t * dst_gid) { osmv_query_req_t req; osmv_gid_pair_t gid_pair; ib_api_status_t status; gid_pair.src_gid = *src_gid; gid_pair.dest_gid = *dst_gid; memset(&req, 0, sizeof(req)); req.query_type = OSMV_QUERY_PATH_REC_BY_GIDS; req.timeout_ms = sa_timeout_ms; req.retry_cnt = 1; req.flags = OSM_SA_FLAGS_SYNC; req.query_context = NULL; req.pfn_query_cb = query_res_cb; req.p_query_input = (void *)&gid_pair; req.sm_key = 0; if ((status = osmv_query_sa(h, &req)) != IB_SUCCESS) { fprintf(stderr, "ERROR: Query SA failed: %s\n", ib_get_err_str(status)); return (status); } if (result.status != IB_SUCCESS) { fprintf(stderr, "ERROR: Query result returned: %s\n", ib_get_err_str(result.status)); return (result.status); } status = result.status; dump_results(&result, dump_path_record); return_mad(); return (status); } static ib_api_status_t get_print_class_port_info(osm_bind_handle_t h) { osmv_query_req_t req; ib_api_status_t status; memset(&req, 0, sizeof(req)); req.query_type = OSMV_QUERY_CLASS_PORT_INFO; req.timeout_ms = sa_timeout_ms; req.retry_cnt = 1; req.flags = OSM_SA_FLAGS_SYNC; req.query_context = NULL; req.pfn_query_cb = query_res_cb; req.p_query_input = NULL; req.sm_key = 0; if ((status = osmv_query_sa(h, &req)) != IB_SUCCESS) { fprintf(stderr, "ERROR: Query SA failed: %s\n", ib_get_err_str(status)); return (status); } if (result.status != IB_SUCCESS) { fprintf(stderr, "ERROR: Query result returned: %s\n", ib_get_err_str(result.status)); return (result.status); } status = result.status; dump_results(&result, dump_class_port_info); return_mad(); return (status); } static int query_path_records(const struct query_cmd *q, osm_bind_handle_t h, int argc, char *argv[]) { ib_net16_t attr_offset = ib_get_attr_offset(sizeof(ib_path_rec_t)); ib_api_status_t status; status = get_all_records(h, IB_MAD_ATTR_PATH_RECORD, attr_offset, 0); if (status != IB_SUCCESS) return (status); dump_results(&result, dump_path_record); return_mad(); return (status); } static ib_api_status_t print_issm_records(osm_bind_handle_t h) { ib_api_status_t status; /* First, get IsSM records */ status = get_issm_records(h, IB_PORT_CAP_IS_SM); if (status != IB_SUCCESS) return (status); printf("IsSM ports\n"); dump_results(&result, dump_portinfo_record); return_mad(); /* Now, get IsSMdisabled records */ status = get_issm_records(h, IB_PORT_CAP_SM_DISAB); if (status != IB_SUCCESS) return (status); printf("\nIsSMdisabled ports\n"); dump_results(&result, dump_portinfo_record); return_mad(); return (status); } static ib_api_status_t print_multicast_member_records(osm_bind_handle_t h) { osmv_query_res_t mc_group_result; ib_api_status_t status; status = get_all_records(h, IB_MAD_ATTR_MCMEMBER_RECORD, ib_get_attr_offset(sizeof(ib_member_rec_t)), 1); if (status != IB_SUCCESS) return (status); mc_group_result = result; status = get_all_records(h, IB_MAD_ATTR_NODE_RECORD, ib_get_attr_offset(sizeof(ib_node_record_t)), 0); if (status != IB_SUCCESS) goto return_mc; dump_results(&mc_group_result, dump_multicast_member_record); return_mad(); return_mc: /* return_mad for the mc_group_result */ if (mc_group_result.p_result_madw != NULL) { osm_mad_pool_put(&mad_pool, mc_group_result.p_result_madw); mc_group_result.p_result_madw = NULL; } return (status); } static ib_api_status_t print_multicast_group_records(osm_bind_handle_t h) { ib_api_status_t status; status = get_all_records(h, IB_MAD_ATTR_MCMEMBER_RECORD, ib_get_attr_offset(sizeof(ib_member_rec_t)), 0); if (status != IB_SUCCESS) return (status); dump_results(&result, dump_multicast_group_record); return_mad(); return (status); } static int query_class_port_info(const struct query_cmd *q, osm_bind_handle_t h, int argc, char *argv[]) { return get_print_class_port_info(h); } static int query_node_records(const struct query_cmd *q, osm_bind_handle_t h, int argc, char *argv[]) { return print_node_records(h); } static int query_portinfo_records(const struct query_cmd *q, osm_bind_handle_t h, int argc, char *argv[]) { ib_portinfo_record_t pir; ib_net64_t comp_mask = 0; int lid = 0, port = -1; ib_api_status_t status; if (argc > 0) parse_lid_and_ports(h, argv[0], &lid, &port, NULL); memset(&pir, 0, sizeof(pir)); if (lid > 0) { pir.lid = cl_hton16(lid); comp_mask |= IB_PIR_COMPMASK_LID; } if (port >= 0) { pir.port_num = cl_hton16(port); comp_mask |= IB_PIR_COMPMASK_PORTNUM; } status = get_any_records(h, IB_MAD_ATTR_PORTINFO_RECORD, 0, comp_mask, &pir, ib_get_attr_offset(sizeof(pir)), 0); if (status != IB_SUCCESS) return status; dump_results(&result, dump_one_portinfo_record); return_mad(); return 0; } static int query_mcmember_records(const struct query_cmd *q, osm_bind_handle_t h, int argc, char *argv[]) { return print_multicast_member_records(h); } static int query_service_records(const struct query_cmd *q, osm_bind_handle_t h, int argc, char *argv[]) { ib_net16_t attr_offset = ib_get_attr_offset(sizeof(ib_service_record_t)); ib_api_status_t status; status = get_all_records(h, IB_MAD_ATTR_SERVICE_RECORD, attr_offset, 0); if (status != IB_SUCCESS) return (status); dump_results(&result, dump_service_record); return_mad(); return (status); } static int query_informinfo_records(const struct query_cmd *q, osm_bind_handle_t h, int argc, char *argv[]) { ib_net16_t attr_offset = ib_get_attr_offset(sizeof(ib_inform_info_record_t)); ib_api_status_t status; status = get_all_records(h, IB_MAD_ATTR_INFORM_INFO_RECORD, attr_offset, 0); if (status != IB_SUCCESS) return (status); dump_results(&result, dump_inform_info_record); return_mad(); return (status); } static int query_link_records(const struct query_cmd *q, osm_bind_handle_t h, int argc, char *argv[]) { ib_link_record_t lr; ib_net64_t comp_mask = 0; int from_lid = 0, to_lid = 0, from_port = -1, to_port = -1; ib_api_status_t status; if (argc > 0) parse_lid_and_ports(h, argv[0], &from_lid, &from_port, NULL); if (argc > 1) parse_lid_and_ports(h, argv[1], &to_lid, &to_port, NULL); memset(&lr, 0, sizeof(lr)); if (from_lid > 0) { lr.from_lid = cl_hton16(from_lid); comp_mask |= IB_LR_COMPMASK_FROM_LID; } if (from_port >= 0) { lr.from_port_num = from_port; comp_mask |= IB_LR_COMPMASK_FROM_PORT; } if (to_lid > 0) { lr.to_lid = cl_hton16(to_lid); comp_mask |= IB_LR_COMPMASK_TO_LID; } if (to_port >= 0) { lr.to_port_num = to_port; comp_mask |= IB_LR_COMPMASK_TO_PORT; } status = get_any_records(h, IB_MAD_ATTR_LINK_RECORD, 0, comp_mask, &lr, ib_get_attr_offset(sizeof(lr)), 0); if (status != IB_SUCCESS) return status; dump_results(&result, dump_one_link_record); return_mad(); return status; } static int query_sl2vl_records(const struct query_cmd *q, osm_bind_handle_t h, int argc, char *argv[]) { ib_slvl_table_record_t slvl; ib_net64_t comp_mask = 0; int lid = 0, in_port = -1, out_port = -1; ib_api_status_t status; if (argc > 0) parse_lid_and_ports(h, argv[0], &lid, &in_port, &out_port); memset(&slvl, 0, sizeof(slvl)); if (lid > 0) { slvl.lid = cl_hton16(lid); comp_mask |= IB_SLVL_COMPMASK_LID; } if (in_port >= 0) { slvl.in_port_num = in_port; comp_mask |= IB_SLVL_COMPMASK_IN_PORT; } if (out_port >= 0) { slvl.out_port_num = out_port; comp_mask |= IB_SLVL_COMPMASK_OUT_PORT; } status = get_any_records(h, IB_MAD_ATTR_SLVL_RECORD, 0, comp_mask, &slvl, ib_get_attr_offset(sizeof(slvl)), 0); if (status != IB_SUCCESS) return status; dump_results(&result, dump_one_slvl_record); return_mad(); return status; } static int query_vlarb_records(const struct query_cmd *q, osm_bind_handle_t h, int argc, char *argv[]) { ib_vl_arb_table_record_t vlarb; ib_net64_t comp_mask = 0; int lid = 0, port = -1, block = -1; ib_api_status_t status; if (argc > 0) parse_lid_and_ports(h, argv[0], &lid, &port, &block); memset(&vlarb, 0, sizeof(vlarb)); if (lid > 0) { vlarb.lid = cl_hton16(lid); comp_mask |= IB_VLA_COMPMASK_LID; } if (port >= 0) { vlarb.port_num = port; comp_mask |= IB_VLA_COMPMASK_OUT_PORT; } if (block >= 0) { vlarb.block_num = block; comp_mask |= IB_VLA_COMPMASK_BLOCK; } status = get_any_records(h, IB_MAD_ATTR_VLARB_RECORD, 0, comp_mask, &vlarb, ib_get_attr_offset(sizeof(vlarb)), 0); if (status != IB_SUCCESS) return status; dump_results(&result, dump_one_vlarb_record); return_mad(); return status; } static int query_pkey_tbl_records(const struct query_cmd *q, osm_bind_handle_t h, int argc, char *argv[]) { ib_pkey_table_record_t pktr; ib_net64_t comp_mask = 0; int lid = 0, port = -1, block = -1; ib_api_status_t status; if (argc > 0) parse_lid_and_ports(h, argv[0], &lid, &port, &block); memset(&pktr, 0, sizeof(pktr)); if (lid > 0) { pktr.lid = cl_hton16(lid); comp_mask |= IB_PKEY_COMPMASK_LID; } if (port >= 0) { pktr.port_num = port; comp_mask |= IB_PKEY_COMPMASK_PORT; } if (block >= 0) { pktr.block_num = block; comp_mask |= IB_PKEY_COMPMASK_BLOCK; } status = get_any_records(h, IB_MAD_ATTR_PKEY_TBL_RECORD, 0, comp_mask, &pktr, ib_get_attr_offset(sizeof(pktr)), smkey); if (status != IB_SUCCESS) return status; dump_results(&result, dump_one_pkey_tbl_record); return_mad(); return status; } static int query_lft_records(const struct query_cmd *q, osm_bind_handle_t h, int argc, char *argv[]) { ib_lft_record_t lftr; ib_net64_t comp_mask = 0; int lid = 0, block = -1; ib_api_status_t status; if (argc > 0) parse_lid_and_ports(h, argv[0], &lid, &block, NULL); memset(&lftr, 0, sizeof(lftr)); if (lid > 0) { lftr.lid = cl_hton16(lid); comp_mask |= IB_LFTR_COMPMASK_LID; } if (block >= 0) { lftr.block_num = cl_hton16(block); comp_mask |= IB_LFTR_COMPMASK_BLOCK; } status = get_any_records(h, IB_MAD_ATTR_LFT_RECORD, 0, comp_mask, &lftr, ib_get_attr_offset(sizeof(lftr)), 0); if (status != IB_SUCCESS) return status; dump_results(&result, dump_one_lft_record); return_mad(); return status; } static int query_mft_records(const struct query_cmd *q, osm_bind_handle_t h, int argc, char *argv[]) { ib_mft_record_t mftr; ib_net64_t comp_mask = 0; int lid = 0, block = -1, position = -1; ib_api_status_t status; if (argc > 0) parse_lid_and_ports(h, argv[0], &lid, &position, &block); memset(&mftr, 0, sizeof(mftr)); if (lid > 0) { mftr.lid = cl_hton16(lid); comp_mask |= IB_MFTR_COMPMASK_LID; } if (position >= 0) { mftr.position_block_num = cl_hton16(position << 12); comp_mask |= IB_MFTR_COMPMASK_POSITION; } if (block >= 0) { mftr.position_block_num |= cl_hton16(block & IB_MCAST_BLOCK_ID_MASK_HO); comp_mask |= IB_MFTR_COMPMASK_BLOCK; } status = get_any_records(h, IB_MAD_ATTR_MFT_RECORD, 0, comp_mask, &mftr, ib_get_attr_offset(sizeof(mftr)), 0); if (status != IB_SUCCESS) return status; dump_results(&result, dump_one_mft_record); return_mad(); return status; } static osm_bind_handle_t get_bind_handle(void) { uint32_t i = 0; uint64_t port_guid = (uint64_t) - 1; osm_bind_handle_t h; ib_api_status_t status; ib_port_attr_t attr_array[MAX_PORTS]; uint32_t num_ports = MAX_PORTS; uint32_t ca_name_index = 0; complib_init(); osm_log_construct(&log_osm); if ((status = osm_log_init_v2(&log_osm, TRUE, 0x0001, NULL, 0, TRUE)) != IB_SUCCESS) { fprintf(stderr, "Failed to init osm_log: %s\n", ib_get_err_str(status)); exit(-1); } osm_log_set_level(&log_osm, OSM_LOG_NONE); if (osm_debug) osm_log_set_level(&log_osm, OSM_LOG_DEFAULT_LEVEL); vendor = osm_vendor_new(&log_osm, sa_timeout_ms); osm_mad_pool_construct(&mad_pool); if ((status = osm_mad_pool_init(&mad_pool)) != IB_SUCCESS) { fprintf(stderr, "Failed to init mad pool: %s\n", ib_get_err_str(status)); exit(-1); } if ((status = osm_vendor_get_all_port_attr(vendor, attr_array, &num_ports)) != IB_SUCCESS) { fprintf(stderr, "Failed to get port attributes: %s\n", ib_get_err_str(status)); exit(-1); } for (i = 0; i < num_ports; i++) { if (i > 1 && cl_ntoh64(attr_array[i].port_guid) != (cl_ntoh64(attr_array[i - 1].port_guid) + 1)) ca_name_index++; if (sa_port_num && sa_port_num != attr_array[i].port_num) continue; if (sa_hca_name && strcmp(sa_hca_name, vendor->ca_names[ca_name_index]) != 0) continue; if (attr_array[i].link_state == IB_LINK_ACTIVE) { port_guid = attr_array[i].port_guid; break; } } if (port_guid == (uint64_t) - 1) { fprintf(stderr, "Failed to find active port, check port status with \"ibstat\"\n"); exit(-1); } h = osmv_bind_sa(vendor, &mad_pool, port_guid); if (h == OSM_BIND_INVALID_HANDLE) { fprintf(stderr, "Failed to bind to SA\n"); exit(-1); } return h; } static void clean_up(void) { osm_mad_pool_destroy(&mad_pool); osm_vendor_delete(&vendor); } static const struct query_cmd query_cmds[] = { {"ClassPortInfo", "CPI", IB_MAD_ATTR_CLASS_PORT_INFO, NULL, query_class_port_info}, {"NodeRecord", "NR", IB_MAD_ATTR_NODE_RECORD, NULL, query_node_records}, {"PortInfoRecord", "PIR", IB_MAD_ATTR_PORTINFO_RECORD, "[[lid]/[port]]", query_portinfo_records}, {"SL2VLTableRecord", "SL2VL", IB_MAD_ATTR_SLVL_RECORD, "[[lid]/[in_port]/[out_port]]", query_sl2vl_records}, {"PKeyTableRecord", "PKTR", IB_MAD_ATTR_PKEY_TBL_RECORD, "[[lid]/[port]/[block]]", query_pkey_tbl_records}, {"VLArbitrationTableRecord", "VLAR", IB_MAD_ATTR_VLARB_RECORD, "[[lid]/[port]/[block]]", query_vlarb_records}, {"InformInfoRecord", "IIR", IB_MAD_ATTR_INFORM_INFO_RECORD, NULL, query_informinfo_records}, {"LinkRecord", "LR", IB_MAD_ATTR_LINK_RECORD, "[[from_lid]/[from_port]] [[to_lid]/[to_port]]", query_link_records}, {"ServiceRecord", "SR", IB_MAD_ATTR_SERVICE_RECORD, NULL, query_service_records}, {"PathRecord", "PR", IB_MAD_ATTR_PATH_RECORD, NULL, query_path_records}, {"MCMemberRecord", "MCMR", IB_MAD_ATTR_MCMEMBER_RECORD, NULL, query_mcmember_records}, {"LFTRecord", "LFTR", IB_MAD_ATTR_LFT_RECORD, "[[lid]/[block]]", query_lft_records}, {"MFTRecord", "MFTR", IB_MAD_ATTR_MFT_RECORD, "[[mlid]/[position]/[block]]", query_mft_records}, {0} }; static const struct query_cmd *find_query(const char *name) { const struct query_cmd *q; unsigned len = strlen(name); for (q = query_cmds; q->name; q++) if (!strncasecmp(name, q->name, len) || (q->alias && !strncasecmp(name, q->alias, len))) return q; return NULL; } static const struct query_cmd *find_query_by_type(ib_net16_t type) { const struct query_cmd *q; for (q = query_cmds; q->name; q++) if (q->query_type == type) return q; return NULL; } static void usage(void) { const struct query_cmd *q; fprintf(stderr, "Usage: %s [-h -d -p -N] [--list | -D] [-S -I -L -l -G" " -O -U -c -s -g -m --src-to-dst --sgid-to-dgid " "-C -P -t(imeout) ] [query-name] [ | | ]\n", argv0); fprintf(stderr, " Queries node records by default\n"); fprintf(stderr, " -d enable debugging\n"); fprintf(stderr, " -p get PathRecord info\n"); fprintf(stderr, " -N get NodeRecord info\n"); fprintf(stderr, " --list | -D the node desc of the CA's\n"); fprintf(stderr, " -S get ServiceRecord info\n"); fprintf(stderr, " -I get InformInfoRecord (subscription) info\n"); fprintf(stderr, " -L return the Lids of the name specified\n"); fprintf(stderr, " -l return the unique Lid of the name specified\n"); fprintf(stderr, " -G return the Guids of the name specified\n"); fprintf(stderr, " -O return name for the Lid specified\n"); fprintf(stderr, " -U return name for the Guid specified\n"); fprintf(stderr, " -c get the SA's class port info\n"); fprintf(stderr, " -s return the PortInfoRecords with isSM or " "isSMdisabled capability mask bit on\n"); fprintf(stderr, " -g get multicast group info\n"); fprintf(stderr, " -m get multicast member info\n"); fprintf(stderr, " (if multicast group specified, list member GIDs" " only for group specified\n"); fprintf(stderr, " specified, for example 'saquery -m 0xC000')\n"); fprintf(stderr, " -x get LinkRecord info\n"); fprintf(stderr, " --src-to-dst get a PathRecord for \n" " where src and dst are either node " "names or LIDs\n"); fprintf(stderr, " --sgid-to-dgid get a PathRecord for \n" " where sgid and dgid are addresses in " "IPv6 format\n"); fprintf(stderr, " -C specify the SA query HCA\n"); fprintf(stderr, " -P specify the SA query port\n"); fprintf(stderr, " --smkey specify SM_Key value for the query." " If non-numeric value \n" " (like 'x') is specified then " "saquery will prompt for a value\n"); fprintf(stderr, " -t | --timeout specify the SA query " "response timeout (default %u msec)\n", DEFAULT_SA_TIMEOUT_MS); fprintf(stderr, " --node-name-map specify a node name map\n"); fprintf(stderr, "\n Supported query names (and aliases):\n"); for (q = query_cmds; q->name; q++) fprintf(stderr, " %s (%s) %s\n", q->name, q->alias ? q->alias : "", q->usage ? q->usage : ""); fprintf(stderr, "\n"); exit(-1); } enum saquery_command { SAQUERY_CMD_QUERY, SAQUERY_CMD_NODE_RECORD, SAQUERY_CMD_PATH_RECORD, SAQUERY_CMD_CLASS_PORT_INFO, SAQUERY_CMD_ISSM, SAQUERY_CMD_MCGROUPS, SAQUERY_CMD_MCMEMBERS, }; int main(int argc, char **argv) { int ch = 0; osm_bind_handle_t h; enum saquery_command command = SAQUERY_CMD_QUERY; const struct query_cmd *q = NULL; char *src = NULL, *dst = NULL; char *sgid = NULL, *dgid = NULL; ib_net16_t query_type = 0; ib_net16_t src_lid, dst_lid; ib_api_status_t status; static char const str_opts[] = "pVNDLlGOUcSIsgmxdhP:C:t:"; static const struct option long_opts[] = { {"p", 0, 0, 'p'}, {"Version", 0, 0, 'V'}, {"N", 0, 0, 'N'}, {"L", 0, 0, 'L'}, {"l", 0, 0, 'l'}, {"G", 0, 0, 'G'}, {"O", 0, 0, 'O'}, {"U", 0, 0, 'U'}, {"s", 0, 0, 's'}, {"g", 0, 0, 'g'}, {"m", 0, 0, 'm'}, {"x", 0, 0, 'x'}, {"d", 0, 0, 'd'}, {"c", 0, 0, 'c'}, {"S", 0, 0, 'S'}, {"I", 0, 0, 'I'}, {"P", 1, 0, 'P'}, {"C", 1, 0, 'C'}, {"help", 0, 0, 'h'}, {"list", 0, 0, 'D'}, {"src-to-dst", 1, 0, 1}, {"sgid-to-dgid", 1, 0, 2}, {"timeout", 1, 0, 't'}, {"node-name-map", 1, 0, 3}, {"smkey", 1, 0, 4}, {} }; argv0 = argv[0]; while ((ch = getopt_long(argc, argv, str_opts, long_opts, NULL)) != -1) { switch (ch) { case 1: { char *opt = strdup(optarg); char *ch = strchr(opt, ':'); if (!ch) { fprintf(stderr, "ERROR: --src-to-dst :\n"); usage(); } *ch++ = '\0'; if (*opt) src = strdup(opt); if (*ch) dst = strdup(ch); free(opt); command = SAQUERY_CMD_PATH_RECORD; break; } case 2: { char *opt = strdup(optarg); char *tok1 = strtok(opt, "-"); char *tok2 = strtok(NULL, "\0"); if (tok1 && tok2) { sgid = strdup(tok1); dgid = strdup(tok2); } else { fprintf(stderr, "ERROR: --sgid-to-dgid -\n"); usage(); } free(opt); command = SAQUERY_CMD_PATH_RECORD; break; } case 3: node_name_map_file = strdup(optarg); break; case 4: if (!isxdigit(*optarg) && !(optarg = getpass("SM_Key: "))) { fprintf(stderr, "cannot get SM_Key\n"); usage(); } smkey = cl_hton64(strtoull(optarg, NULL, 0)); break; case 'p': command = SAQUERY_CMD_PATH_RECORD; break; case 'V': fprintf(stderr, "%s %s\n", argv0, get_build_version()); exit(-1); case 'D': node_print_desc = ALL_DESC; break; case 'c': command = SAQUERY_CMD_CLASS_PORT_INFO; break; case 'S': query_type = IB_MAD_ATTR_SERVICE_RECORD; break; case 'I': query_type = IB_MAD_ATTR_INFORM_INFO_RECORD; break; case 'N': command = SAQUERY_CMD_NODE_RECORD; break; case 'L': node_print_desc = LID_ONLY; break; case 'l': node_print_desc = UNIQUE_LID_ONLY; break; case 'G': node_print_desc = GUID_ONLY; break; case 'O': node_print_desc = NAME_OF_LID; break; case 'U': node_print_desc = NAME_OF_GUID; break; case 's': command = SAQUERY_CMD_ISSM; break; case 'g': command = SAQUERY_CMD_MCGROUPS; break; case 'm': command = SAQUERY_CMD_MCMEMBERS; break; case 'x': query_type = IB_MAD_ATTR_LINK_RECORD; break; case 'd': osm_debug = 1; break; case 'C': sa_hca_name = optarg; break; case 'P': sa_port_num = strtoul(optarg, NULL, 0); break; case 't': sa_timeout_ms = strtoul(optarg, NULL, 0); break; case 'h': default: usage(); } } argc -= optind; argv += optind; if (!query_type) { if (!argc || !(q = find_query(argv[0]))) query_type = IB_MAD_ATTR_NODE_RECORD; else { query_type = q->query_type; argc--; argv++; } } if (argc) { if (node_print_desc == NAME_OF_LID) { requested_lid = (ib_net16_t) strtoul(argv[0], NULL, 0); requested_lid_flag++; } else if (node_print_desc == NAME_OF_GUID) { requested_guid = (ib_net64_t) strtoul(argv[0], NULL, 0); requested_guid_flag++; } else { requested_name = argv[0]; } } if ((node_print_desc == LID_ONLY || node_print_desc == UNIQUE_LID_ONLY || node_print_desc == GUID_ONLY) && !requested_name) { fprintf(stderr, "ERROR: name not specified\n"); usage(); } if (node_print_desc == NAME_OF_LID && !requested_lid_flag) { fprintf(stderr, "ERROR: lid not specified\n"); usage(); } if (node_print_desc == NAME_OF_GUID && !requested_guid_flag) { fprintf(stderr, "ERROR: guid not specified\n"); usage(); } /* Note: lid cannot be 0; see infiniband spec 4.1.3 */ if (node_print_desc == NAME_OF_LID && !requested_lid) { fprintf(stderr, "ERROR: lid invalid\n"); usage(); } h = get_bind_handle(); node_name_map = open_node_name_map(node_name_map_file); switch (command) { case SAQUERY_CMD_NODE_RECORD: status = print_node_records(h); break; case SAQUERY_CMD_PATH_RECORD: if (src && dst) { src_lid = get_lid(h, src); dst_lid = get_lid(h, dst); printf("Path record for %s -> %s\n", src, dst); if (src_lid == 0 || dst_lid == 0) { status = IB_UNKNOWN_ERROR; } else { status = get_print_path_rec_lid(h, src_lid, dst_lid); } } else if (sgid && dgid) { struct in6_addr src_addr, dst_addr; if (inet_pton(AF_INET6, sgid, &src_addr) <= 0) { fprintf(stderr, "invalid src gid: %s\n", sgid); exit(-1); } if (inet_pton(AF_INET6, dgid, &dst_addr) <= 0) { fprintf(stderr, "invalid dst gid: %s\n", dgid); exit(-1); } status = get_print_path_rec_gid(h, (ib_gid_t *) & src_addr.s6_addr, (ib_gid_t *) & dst_addr.s6_addr); } else { status = query_path_records(q, h, 0, NULL); } break; case SAQUERY_CMD_CLASS_PORT_INFO: status = get_print_class_port_info(h); break; case SAQUERY_CMD_ISSM: status = print_issm_records(h); break; case SAQUERY_CMD_MCGROUPS: status = print_multicast_group_records(h); break; case SAQUERY_CMD_MCMEMBERS: status = print_multicast_member_records(h); break; default: if ((!q && !(q = find_query_by_type(query_type))) || !q->handler) { fprintf(stderr, "Unknown query type %d\n", ntohs(query_type)); status = IB_UNKNOWN_ERROR; } else status = q->handler(q, h, argc, argv); break; } if (src) free(src); if (dst) free(dst); clean_up(); close_node_name_map(node_name_map); return (status); } Index: stable/9/contrib/ofed/management/infiniband-diags/src/smpquery.c =================================================================== --- stable/9/contrib/ofed/management/infiniband-diags/src/smpquery.c (revision 275448) +++ stable/9/contrib/ofed/management/infiniband-diags/src/smpquery.c (revision 275449) @@ -1,538 +1,538 @@ /* * Copyright (c) 2004-2008 Voltaire Inc. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU * General Public License (GPL) Version 2, available from the file * COPYING in the main directory of this source tree, or the * OpenIB.org BSD license below: * * Redistribution and use in source and binary forms, with or * without modification, are permitted provided that the following * conditions are met: * * - Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * - Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * */ #if HAVE_CONFIG_H # include #endif /* HAVE_CONFIG_H */ #include #include #include #include #include #include #include #include #define __STDC_FORMAT_MACROS #include #include #include #include -#include +#include #include "ibdiag_common.h" #undef DEBUG #define DEBUG if (verbose>1) IBWARN static int dest_type = IB_DEST_LID; static int verbose; typedef char *(op_fn_t)(ib_portid_t *dest, char **argv, int argc); typedef struct match_rec { char *name; op_fn_t *fn; unsigned opt_portnum; } match_rec_t; static op_fn_t node_desc, node_info, port_info, switch_info, pkey_table, sl2vl_table, vlarb_table, guid_info; static const match_rec_t match_tbl[] = { { "nodeinfo", node_info }, { "nodedesc", node_desc }, { "portinfo", port_info, 1 }, { "switchinfo", switch_info }, { "pkeys", pkey_table, 1 }, { "sl2vl", sl2vl_table, 1 }, { "vlarb", vlarb_table, 1 }, { "guids", guid_info }, {0} }; char *argv0 = "smpquery"; static char *node_name_map_file = NULL; static nn_map_t *node_name_map = NULL; /*******************************************/ static char * node_desc(ib_portid_t *dest, char **argv, int argc) { int node_type, l; uint64_t node_guid; char nd[IB_SMP_DATA_SIZE]; uint8_t data[IB_SMP_DATA_SIZE]; char dots[128]; char *nodename = NULL; if (!smp_query(data, dest, IB_ATTR_NODE_INFO, 0, 0)) return "node info query failed"; mad_decode_field(data, IB_NODE_TYPE_F, &node_type); mad_decode_field(data, IB_NODE_GUID_F, &node_guid); if (!smp_query(nd, dest, IB_ATTR_NODE_DESC, 0, 0)) return "node desc query failed"; nodename = remap_node_name(node_name_map, node_guid, nd); l = strlen(nodename); if (l < 32) { memset(dots, '.', 32 - l); dots[32 - l] = '\0'; } else { dots[0] = '.'; dots[1] = '\0'; } printf("Node Description:%s%s\n", dots, nodename); free(nodename); return 0; } static char * node_info(ib_portid_t *dest, char **argv, int argc) { char buf[2048]; char data[IB_SMP_DATA_SIZE]; if (!smp_query(data, dest, IB_ATTR_NODE_INFO, 0, 0)) return "node info query failed"; mad_dump_nodeinfo(buf, sizeof buf, data, sizeof data); printf("# Node info: %s\n%s", portid2str(dest), buf); return 0; } static char * port_info(ib_portid_t *dest, char **argv, int argc) { char buf[2048]; char data[IB_SMP_DATA_SIZE]; int portnum = 0; if (argc > 0) portnum = strtol(argv[0], 0, 0); if (!smp_query(data, dest, IB_ATTR_PORT_INFO, portnum, 0)) return "port info query failed"; mad_dump_portinfo(buf, sizeof buf, data, sizeof data); printf("# Port info: %s port %d\n%s", portid2str(dest), portnum, buf); return 0; } static char * switch_info(ib_portid_t *dest, char **argv, int argc) { char buf[2048]; char data[IB_SMP_DATA_SIZE]; if (!smp_query(data, dest, IB_ATTR_SWITCH_INFO, 0, 0)) return "switch info query failed"; mad_dump_switchinfo(buf, sizeof buf, data, sizeof data); printf("# Switch info: %s\n%s", portid2str(dest), buf); return 0; } static char * pkey_table(ib_portid_t *dest, char **argv, int argc) { uint8_t data[IB_SMP_DATA_SIZE]; uint32_t i, j, k; uint16_t *p; unsigned mod; int n, t, phy_ports; int portnum = 0; if (argc > 0) portnum = strtol(argv[0], 0, 0); /* Get the partition capacity */ if (!smp_query(data, dest, IB_ATTR_NODE_INFO, 0, 0)) return "node info query failed"; mad_decode_field(data, IB_NODE_TYPE_F, &t); mad_decode_field(data, IB_NODE_NPORTS_F, &phy_ports); if (portnum > phy_ports) return "invalid port number"; if ((t == IB_NODE_SWITCH) && (portnum != 0)) { if (!smp_query(data, dest, IB_ATTR_SWITCH_INFO, 0, 0)) return "switch info failed"; mad_decode_field(data, IB_SW_PARTITION_ENFORCE_CAP_F, &n); } else mad_decode_field(data, IB_NODE_PARTITION_CAP_F, &n); for (i = 0; i < (n + 31) / 32; i++) { mod = i | (portnum << 16); if (!smp_query(data, dest, IB_ATTR_PKEY_TBL, mod, 0)) return "pkey table query failed"; if (i + 1 == (n + 31) / 32) k = ((n + 7 - i * 32) / 8) * 8; else k = 32; p = (uint16_t *) data; for (j = 0; j < k; j += 8, p += 8) { printf("%4u: 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x\n", (i * 32) + j, ntohs(p[0]), ntohs(p[1]), ntohs(p[2]), ntohs(p[3]), ntohs(p[4]), ntohs(p[5]), ntohs(p[6]), ntohs(p[7])); } } printf("%d pkeys capacity for this port\n", n); return 0; } static char *sl2vl_dump_table_entry(ib_portid_t *dest, int in, int out) { char buf[2048]; char data[IB_SMP_DATA_SIZE]; int portnum = (in << 8) | out; if (!smp_query(data, dest, IB_ATTR_SLVL_TABLE, portnum, 0)) return "slvl query failed"; mad_dump_sltovl(buf, sizeof buf, data, sizeof data); printf("ports: in %2d, out %2d: ", in, out); printf("%s", buf); return 0; } static char * sl2vl_table(ib_portid_t *dest, char **argv, int argc) { uint8_t data[IB_SMP_DATA_SIZE]; int type, num_ports, portnum = 0; int i; char *ret; if (argc > 0) portnum = strtol(argv[0], 0, 0); if (!smp_query(data, dest, IB_ATTR_NODE_INFO, 0, 0)) return "node info query failed"; mad_decode_field(data, IB_NODE_TYPE_F, &type); mad_decode_field(data, IB_NODE_NPORTS_F, &num_ports); if (portnum > num_ports) return "invalid port number"; printf("# SL2VL table: %s\n", portid2str(dest)); printf("# SL: |"); for (i = 0 ; i < 16 ; i++) printf("%2d|", i); printf("\n"); if (type != IB_NODE_SWITCH) return sl2vl_dump_table_entry(dest, 0, 0); for (i = 0 ; i <= num_ports ; i++) { ret = sl2vl_dump_table_entry(dest, i, portnum); if (ret) return ret; } return 0; } static char *vlarb_dump_table_entry(ib_portid_t *dest, int portnum, int offset, unsigned cap) { char buf[2048]; char data[IB_SMP_DATA_SIZE]; if (!smp_query(data, dest, IB_ATTR_VL_ARBITRATION, (offset << 16) | portnum, 0)) return "vl arb query failed"; mad_dump_vlarbitration(buf, sizeof(buf), data, cap * 2); printf("%s", buf); return 0; } static char *vlarb_dump_table(ib_portid_t *dest, int portnum, char *name, int offset, int cap) { char *ret; printf("# %s priority VL Arbitration Table:", name); ret = vlarb_dump_table_entry(dest, portnum, offset, cap < 32 ? cap : 32); if (!ret && cap > 32) ret = vlarb_dump_table_entry(dest, portnum, offset + 1, cap - 32); return ret; } static char * vlarb_table(ib_portid_t *dest, char **argv, int argc) { uint8_t data[IB_SMP_DATA_SIZE]; int portnum = 0; int type, enhsp0, lowcap, highcap; char *ret = 0; if (argc > 0) portnum = strtol(argv[0], 0, 0); /* port number of 0 could mean SP0 or port MAD arrives on */ if (portnum == 0) { if (!smp_query(data, dest, IB_ATTR_NODE_INFO, 0, 0)) return "node info query failed"; mad_decode_field(data, IB_NODE_TYPE_F, &type); if (type == IB_NODE_SWITCH) { if (!smp_query(data, dest, IB_ATTR_SWITCH_INFO, 0, 0)) return "switch info query failed"; mad_decode_field(data, IB_SW_ENHANCED_PORT0_F, &enhsp0); if (!enhsp0) { printf("# No VLArbitration tables (BSP0): %s port %d\n", portid2str(dest), 0); return 0; } } } if (!smp_query(data, dest, IB_ATTR_PORT_INFO, portnum, 0)) return "port info query failed"; mad_decode_field(data, IB_PORT_VL_ARBITRATION_LOW_CAP_F, &lowcap); mad_decode_field(data, IB_PORT_VL_ARBITRATION_HIGH_CAP_F,&highcap); printf("# VLArbitration tables: %s port %d LowCap %d HighCap %d\n", portid2str(dest), portnum, lowcap, highcap); if (lowcap > 0) ret = vlarb_dump_table(dest, portnum, "Low", 1, lowcap); if (!ret && highcap > 0) ret = vlarb_dump_table(dest, portnum, "High", 3, highcap); return ret; } static char * guid_info(ib_portid_t *dest, char **argv, int argc) { uint8_t data[IB_SMP_DATA_SIZE]; uint32_t i, j, k; uint64_t *p; unsigned mod; int n; /* Get the guid capacity */ if (!smp_query(data, dest, IB_ATTR_PORT_INFO, 0, 0)) return "port info failed"; mad_decode_field(data, IB_PORT_GUID_CAP_F, &n); for (i = 0; i < (n + 7) / 8; i++) { mod = i; if (!smp_query(data, dest, IB_ATTR_GUID_INFO, mod, 0)) return "guid info query failed"; if (i + 1 == (n + 7) / 8) k = ((n + 1 - i * 8) / 2) * 2; else k = 8; p = (uint64_t *) data; for (j = 0; j < k; j += 2, p += 2) { printf("%4u: 0x%016"PRIx64" 0x%016"PRIx64"\n", (i * 8) + j, ntohll(p[0]), ntohll(p[1])); } } printf("%d guids capacity for this port\n", n); return 0; } static op_fn_t * match_op(char *name) { const match_rec_t *r; for (r = match_tbl; r->name; r++) if (!strcmp(r->name, name)) return r->fn; return 0; } static void usage(void) { char *basename; const match_rec_t *r; if (!(basename = strrchr(argv0, '/'))) basename = argv0; else basename++; fprintf(stderr, "Usage: %s [-d(ebug) -e(rr_show) -v(erbose) -D(irect) -G(uid) -s smlid -V(ersion) -C ca_name -P ca_port " "-t(imeout) timeout_ms --node-name-map node-name-map] [op params]\n", basename); fprintf(stderr, "\tsupported ops:\n"); for (r = match_tbl ; r->name ; r++) { fprintf(stderr, "\t\t%s %s\n", r->name, r->opt_portnum ? " []" : ""); } fprintf(stderr, "\n\texamples:\n"); fprintf(stderr, "\t\t%s portinfo 3 1\t\t\t\t# portinfo by lid, with port modifier\n", basename); fprintf(stderr, "\t\t%s -G switchinfo 0x2C9000100D051 1\t# switchinfo by guid\n", basename); fprintf(stderr, "\t\t%s -D nodeinfo 0\t\t\t\t# nodeinfo by direct route\n", basename); fprintf(stderr, "\t\t%s -c nodeinfo 6 0,12\t\t\t# nodeinfo by combined route\n", basename); exit(-1); } int main(int argc, char **argv) { int mgmt_classes[3] = {IB_SMI_CLASS, IB_SMI_DIRECT_CLASS, IB_SA_CLASS}; ib_portid_t portid = {0}; ib_portid_t *sm_id = 0, sm_portid = {0}; extern int ibdebug; int timeout = 0, udebug = 0; char *ca = 0; int ca_port = 0; char *err; op_fn_t *fn; static char const str_opts[] = "C:P:t:s:devDcGVhu"; static const struct option long_opts[] = { { "C", 1, 0, 'C'}, { "P", 1, 0, 'P'}, { "debug", 0, 0, 'd'}, { "err_show", 0, 0, 'e'}, { "verbose", 0, 0, 'v'}, { "Direct", 0, 0, 'D'}, { "combined", 0, 0, 'c'}, { "Guid", 0, 0, 'G'}, { "smlid", 1, 0, 's'}, { "timeout", 1, 0, 't'}, { "node-name-map", 1, 0, 1}, { "Version", 0, 0, 'V'}, { "help", 0, 0, 'h'}, { "usage", 0, 0, 'u'}, { } }; argv0 = argv[0]; while (1) { int ch = getopt_long(argc, argv, str_opts, long_opts, NULL); if ( ch == -1 ) break; switch(ch) { case 1: node_name_map_file = strdup(optarg); break; case 'd': ibdebug++; madrpc_show_errors(1); umad_debug(udebug); udebug++; break; case 'e': madrpc_show_errors(1); break; case 'D': dest_type = IB_DEST_DRPATH; break; case 'c': dest_type = IB_DEST_DRSLID; break; case 'G': dest_type = IB_DEST_GUID; break; case 'C': ca = optarg; break; case 'P': ca_port = strtoul(optarg, 0, 0); break; case 's': if (ib_resolve_portid_str(&sm_portid, optarg, IB_DEST_LID, 0) < 0) IBERROR("can't resolve SM destination port %s", optarg); sm_id = &sm_portid; break; case 't': timeout = strtoul(optarg, 0, 0); madrpc_set_timeout(timeout); break; case 'v': verbose++; break; case 'V': fprintf(stderr, "%s %s\n", argv0, get_build_version() ); exit(-1); default: usage(); break; } } argc -= optind; argv += optind; if (argc < 2) usage(); if (!(fn = match_op(argv[0]))) IBERROR("operation '%s' not supported", argv[0]); madrpc_init(ca, ca_port, mgmt_classes, 3); node_name_map = open_node_name_map(node_name_map_file); if (dest_type != IB_DEST_DRSLID) { if (ib_resolve_portid_str(&portid, argv[1], dest_type, sm_id) < 0) IBERROR("can't resolve destination port %s", argv[1]); if ((err = fn(&portid, argv+2, argc-2))) IBERROR("operation %s: %s", argv[0], err); } else { char concat[64]; memset(concat, 0, 64); snprintf(concat, sizeof(concat), "%s %s", argv[1], argv[2]); if (ib_resolve_portid_str(&portid, concat, dest_type, sm_id) < 0) IBERROR("can't resolve destination port %s", concat); if ((err = fn(&portid, argv+3, argc-3))) IBERROR("operation %s: %s", argv[0], err); } close_node_name_map(node_name_map); exit(0); } Index: stable/9/contrib/ofed/usr.bin/Makefile.inc =================================================================== --- stable/9/contrib/ofed/usr.bin/Makefile.inc (revision 275448) +++ stable/9/contrib/ofed/usr.bin/Makefile.inc (revision 275449) @@ -1,4 +1,9 @@ DIAGPATH= ${.CURDIR}/../../management/infiniband-diags BINDIR?= /usr/bin CFLAGS+= -I${.CURDIR}/../../include/infiniband +CFLAGS+= -I${.CURDIR}/../../include CFLAGS+= -I${.CURDIR}/../../management/opensm/include/ +CFLAGS+= -I${.CURDIR}/../../management/opensm +CFLAGS+= -I${.CURDIR}/../../management/libibcommon/include +CFLAGS+= -I${.CURDIR}/../../management/libibumad/include +CFLAGS+= -I${.CURDIR}/../../management/libibmad/include Index: stable/9/contrib =================================================================== --- stable/9/contrib (revision 275448) +++ stable/9/contrib (revision 275449) Property changes on: stable/9/contrib ___________________________________________________________________ Modified: svn:mergeinfo ## -0,0 +0,1 ## Merged /head/contrib:r275328,275330