[openib-general] [PATCH 6 of 7] branch 1.0, management/diags: main trunk updates
Jack Morgenstein
jackm at mellanox.co.il
Thu Mar 30 06:51:32 PST 2006
management/diags: updating branch 1.0 from main trunk.
Index: include/grouping.h
===================================================================
--- include/grouping.h (.../branches/1.0/src/userspace/management/diags)
(revision 0)
+++ include/grouping.h (.../trunk/src/userspace/management/diags) (revision
6101)
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2004-2006 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.
+ *
+ * $Id$
+ */
+
+#ifndef _GROUPING_H_
+#define _GROUPING_H_
+
+/*========================================================*/
+/* FABRIC SCANNER SPECIFIC DATA */
+/*========================================================*/
+
+#define SPINES_MAX_NUM 12
+#define LINES_MAX_NUM 36
+
+typedef struct ChassisList ChassisList;
+typedef struct AllChassisList AllChassisList;
+
+struct ChassisList {
+ ChassisList *next;
+ uint64_t chassisguid;
+ int chassisnum;
+ int chassistype;
+ int nodecount; /* used for grouping by SystemImageGUID */
+ Node *spinenode[SPINES_MAX_NUM + 1];
+ Node *linenode[LINES_MAX_NUM + 1];
+};
+
+struct AllChassisList {
+ ChassisList *first;
+ ChassisList *current;
+ ChassisList *last;
+};
+
+/*========================================================*/
+/* CHASSIS RECOGNITION SPECIFIC DATA */
+/*========================================================*/
+
+/* Device IDs */
+#define VTR_DEVID_IB_FC_ROUTER 0x5a00
+#define VTR_DEVID_IB_IP_ROUTER 0x5a01
+#define VTR_DEVID_ISR9600_SPINE 0x5a02
+#define VTR_DEVID_ISR9600_LEAF 0x5a03
+#define VTR_DEVID_HCA1 0x5a04
+#define VTR_DEVID_HCA2 0x5a44
+#define VTR_DEVID_HCA3 0x6278
+#define VTR_DEVID_SW_6IB4 0x5a05
+#define VTR_DEVID_ISR9024 0x5a06
+#define VTR_DEVID_ISR9288 0x5a07
+#define VTR_DEVID_SLB24 0x5a09
+#define VTR_DEVID_SFB12 0x5a08
+#define VTR_DEVID_SFB4 0x5a0b
+#define VTR_DEVID_ISR9024_12 0x5a0c
+#define VTR_DEVID_SLB8 0x5a0d
+#define VTR_DEVID_RLX_SWITCH_BLADE 0x5a20
+#define VTR_DEVID_ISR9024_DDR 0x5a31
+#define VTR_DEVID_SFB12_DDR 0x5a32
+#define VTR_DEVID_SFB4_DDR 0x5a33
+#define VTR_DEVID_SLB24_DDR 0x5a34
+
+enum ChassisType { UNRESOLVED_CT, ISR9288_CT, ISR9096_CT };
+enum ChassisSlot { UNRESOLVED_CS, LINE_CS, SPINE_CS, SRBD_CS };
+
+#endif /* _GROUPING_H_ */
Property changes on: include/grouping.h
___________________________________________________________________
Name: svn:keywords
+ Id
Index: include/ibnetdiscover.h
===================================================================
--- include/ibnetdiscover.h (.../branches/1.0/src/userspace/management/diags)
(revision 0)
+++ include/ibnetdiscover.h (.../trunk/src/userspace/management/diags)
(revision 6101)
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2004-2006 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.
+ *
+ * $Id$
+ */
+
+#ifndef _IBNETDISCOVER_H_
+#define _IBNETDISCOVER_H_
+
+#define MAXHOPS 63
+#define CA_NODE 1
+#define SWITCH_NODE 2
+
+/* Vendor IDs */
+#define VTR_VENDOR_ID 0x8f1
+#define TS_VENDOR_ID 0x5ad
+
+
+typedef struct Port Port;
+typedef struct Node Node;
+typedef struct ChassisRecord ChassisRecord;
+
+struct ChassisRecord {
+ ChassisRecord *next;
+
+ unsigned char chassisnum;
+ unsigned char anafanum;
+ unsigned char slotnum;
+ unsigned char chassistype;
+ unsigned char chassisslot;
+};
+
+struct Port {
+ Port *next;
+ uint64_t portguid;
+ int portnum;
+ int lid;
+ int lmc;
+ int state;
+ int physstate;
+
+ Node *node;
+ Port *remoteport; /* null if SMA */
+};
+
+struct Node {
+ Node *htnext;
+ Node *dnext;
+ Port *ports;
+ ib_portid_t path;
+ int type;
+ int dist;
+ int numports;
+ int localport;
+ int smalid;
+ uint32_t devid;
+ uint32_t vendid;
+ uint64_t sysimgguid;
+ uint64_t nodeguid;
+ uint64_t portguid;
+ char nodedesc[64];
+ uint8_t nodeinfo[64];
+
+ ChassisRecord *chrecord;
+};
+
+#endif /* _IBNETDISCOVER_H_ */
Property changes on: include/ibnetdiscover.h
___________________________________________________________________
Name: svn:keywords
+ Id
Index: src/ibnetdiscover.c
===================================================================
--- src/ibnetdiscover.c (.../branches/1.0/src/userspace/management/diags)
(revision 6101)
+++ src/ibnetdiscover.c (.../trunk/src/userspace/management/diags) (revision
6101)
@@ -49,21 +49,33 @@
#include <umad.h>
#include <mad.h>
-#define MAXHOPS 63
-#define CA_NODE 1
-#define SWITCH_NODE 2
+#include "ibnetdiscover.h"
static int timeout = 2000; /* ms */
static int dumplevel = 0;
+static int chassisnum = 0;
static int verbose;
static FILE *f;
+extern void group_nodes();
+extern char *portmapstring(Port *port);
+extern char *get_chassis_type(unsigned char chassistype);
+extern char *get_chassis_slot(unsigned char chassisslot);
+extern uint64_t get_chassis_guid(unsigned char chassisnum);
+
+
#undef DEBUG
-#define DEBUG if (verbose>1) IBWARN
+#define DEBUG if (verbose > 1) IBWARN
#define IBERROR(fmt, args...) iberror(__FUNCTION__, fmt, ## args)
static char *argv0 = "ibnetdiscover";
+Node *nodesdist[MAXHOPS+1]; /* last is Ca list */
+Node *mynode;
+Port *myport;
+int maxhops_discovered = 0;
+
+
void
iberror(const char *fn, char *msg, ...)
{
@@ -87,46 +99,6 @@ iberror(const char *fn, char *msg, ...)
exit(-1);
}
-typedef struct Port Port;
-typedef struct Node Node;
-
-struct Port {
- Port *next;
- uint64_t portguid;
- int portnum;
- int lid;
- int lmc;
- int state;
- int physstate;
-
- Node *node;
- Port *remoteport; /* null if SMA */
-};
-
-struct Node {
- Node *htnext;
- Node *dnext;
- Port *ports;
- ib_portid_t path;
- int type;
- int dist;
- int numports;
- int localport;
- int smalid;
- uint32_t devid;
- uint32_t vendid;
- uint64_t sysimgguid;
- uint64_t nodeguid;
- uint64_t portguid;
- char nodedesc[64];
- uint8_t nodeinfo[64];
-};
-
-Node *nodesdist[MAXHOPS+1]; /* last is Ca list */
-Node *mynode;
-Port *myport;
-int maxhops_discovered = 0;
-
int
get_port(Port *port, int portnum, ib_portid_t *portid)
{
@@ -497,14 +469,64 @@ out_ids(Node *node)
}
void
-out_switch(Node *node)
+out_chassis(Node *node)
{
+ uint64_t guid;
+
+ /* GUID is not in ChassisRecord!!! */
+ /* First, find chassis for this node in ChassisList */
+ if (!node->chrecord->chassisnum)
+ return;
+ fprintf(f, "\nChassis %d", node->chrecord->chassisnum);
+ guid = get_chassis_guid(node->chrecord->chassisnum);
+ if (guid) {
+#if __WORDSIZE == 64
+ fprintf(f, " (guid 0x%lx)", guid);
+#else
+ fprintf(f, " (guid 0x%Lx)", guid);
+#endif
+ }
+ fprintf(f, "\n");
+}
+
+void
+out_switch(Node *node, int group)
+{
+ char *str;
+
+ if (group) {
+ if (node->chrecord) {
+ /* Start of a new chassis ? */
+ if (node->chrecord->chassisnum != chassisnum) {
+ chassisnum++;
+ out_chassis(node);
+ }
+ }
+ }
+
out_ids(node);
#if __WORDSIZE == 64
- fprintf(f, "%s=0x%lx\n", "switchguid", node->nodeguid);
+ fprintf(f, "%s=0x%lx", "switchguid", node->nodeguid);
#else
- fprintf(f, "%s=0x%Lx\n", "switchguid", node->nodeguid);
+ fprintf(f, "%s=0x%Lx", "switchguid", node->nodeguid);
#endif
+ if (group) {
+ if (node->chrecord) {
+ if (node->chrecord->chassisnum) {
+ fprintf(f, "\t\t# Chassis %d ", node->chrecord->chassisnum);
+ /* Currently, only if Voltaire chassis */
+ if (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);
+ }
+ }
+ }
+ }
fprintf(f, "\nSwitch\t%d %s\t\t# %s port 0 lid %d\n",
node->numports, node_name(node),
@@ -525,25 +547,44 @@ out_ca(Node *node)
clean_nodedesc(node->nodedesc));
}
+static void out_ext_port(Port *port, int group)
+{
+ char *str;
+
+ if (group) {
+ if (port->node->chrecord && port->node->vendid == VTR_VENDOR_ID) {
+ /* Currently, only if Voltaire chassis */
+ str = portmapstring(port);
+ if (str)
+ fprintf(f, "%s", str);
+ }
+ }
+}
+
void
-out_switch_port(Port *port)
+out_switch_port(Port *port, int group)
{
DEBUG("port %p:%d remoteport %p", port, port->portnum, port->remoteport);
- fprintf(f, "[%d]\t%s[%d]\t\t\n",
- port->portnum, node_name(port->remoteport->node),
+ fprintf(f, "[%d]", port->portnum);
+ out_ext_port(port, group);
+ fprintf(f, "\t%s[%d]", node_name(port->remoteport->node),
port->remoteport->portnum);
+ out_ext_port(port->remoteport, group);
+ fprintf(f, "\t\t\n");
}
void
-out_ca_port(Port *port)
+out_ca_port(Port *port, int group)
{
- fprintf(f, "[%d]\t%s[%d]\t\t# lid %d lmc %d\n",
- port->portnum, node_name(port->remoteport->node),
- port->remoteport->portnum, port->lid, port->lmc);
+ fprintf(f, "[%d]\t%s[%d]", port->portnum,
+ node_name(port->remoteport->node),
+ port->remoteport->portnum);
+ out_ext_port(port->remoteport, group);
+ fprintf(f, "\t\t# lid %d lmc %d\n", port->lid, port->lmc);
}
int
-dump_topology(int listtype)
+dump_topology(int listtype, int group)
{
Node *node;
Port *port;
@@ -567,7 +608,7 @@ dump_topology(int listtype)
DEBUG("SWITCH: dist %d node %p", dist, node);
if (!listtype)
- out_switch(node);
+ out_switch(node, group);
else {
if (listtype & SWITCH_NODE)
list_node(node);
@@ -576,7 +617,7 @@ dump_topology(int listtype)
for (port = node->ports; port; port = port->next, i++)
if (port->remoteport)
- out_switch_port(port);
+ out_switch_port(port, group);
}
}
@@ -594,7 +635,7 @@ dump_topology(int listtype)
for (port = node->ports; port; port = port->next, i++)
if (port->remoteport)
- out_ca_port(port);
+ out_ca_port(port, group);
}
return i;
@@ -602,8 +643,8 @@ dump_topology(int listtype)
void
usage(void)
-{
- fprintf(stderr, "Usage: %s [-d(ebug)] -e(rr_show) -v(erbose) -s(how) -l(ist)
-H(ca_list) -S(witch_list) -V(ersion) -C ca_name -P ca_port "
+{
+ fprintf(stderr, "Usage: %s [-d(ebug)] -e(rr_show) -v(erbose) -s(how) -l(ist)
-g(rouping) -H(ca_list) -S(witch_list) -V(ersion) -C ca_name -P ca_port "
"-t(imeout) timeout_ms] [<netfile>]\n",
argv0);
exit(-1);
@@ -618,8 +659,9 @@ main(int argc, char **argv)
int udebug = 0, list = 0;
char *ca = 0;
int ca_port = 0;
+ int group = 0;
- static char const str_opts[] = "C:P:t:devslHSVhu";
+ static char const str_opts[] = "C:P:t:devslgHSVhu";
static const struct option long_opts[] = {
{ "C", 1, 0, 'C'},
{ "P", 1, 0, 'P'},
@@ -628,6 +670,7 @@ main(int argc, char **argv)
{ "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'},
{ "timeout", 1, 0, 't'},
@@ -674,6 +717,9 @@ main(int argc, char **argv)
case 'l':
list = CA_NODE | SWITCH_NODE;
break;
+ case 'g':
+ group = 1;
+ break;
case 'S':
list = SWITCH_NODE;
break;
@@ -700,7 +746,10 @@ main(int argc, char **argv)
if (discover(&my_portid) < 0)
IBERROR("discover failed");
- dump_topology(list);
+ if (group)
+ group_nodes();
+
+ dump_topology(list, group);
exit(0);
}
Index: src/saquery.c
===================================================================
--- src/saquery.c (.../branches/1.0/src/userspace/management/diags) (revision
0)
+++ src/saquery.c (.../trunk/src/userspace/management/diags) (revision 6101)
@@ -0,0 +1,422 @@
+/*
+ * Copyright (c) 2006 The Regents of the University of California.
+ * Copyright (c) 2004-2006 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 <weiny2 at llnl.gov>.
+ *
+ * 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.
+ *
+ * $Id$
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <assert.h>
+
+#define _GNU_SOURCE
+#include <getopt.h>
+
+#include <infiniband/opensm/osm_log.h>
+#include <infiniband/vendor/osm_vendor_api.h>
+#include <infiniband/vendor/osm_vendor_sa_api.h>
+#include <infiniband/opensm/osm_mad_pool.h>
+
+static char *argv0 = "saquery";
+
+/**
+ * Declare some globals because I don't want this to be too complex.
+ */
+#define MAX_PORTS (8)
+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;
+
+enum {
+ ALL,
+ LID_ONLY,
+ GUID_ONLY,
+} node_print_desc = ALL;
+
+char *requested_name = NULL;
+ib_net16_t query_type = IB_MAD_ATTR_NODE_RECORD;
+
+/**
+ * Call back for the node record request.
+ */
+void
+query_res_cb(osmv_query_res_t *res)
+{
+ result = *res;
+}
+
+void
+print_node_record(ib_node_record_t *node_record)
+{
+ ib_node_info_t *p_ni = NULL;
+ p_ni = &(node_record->node_info);
+
+ switch (node_print_desc) {
+ case 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 ALL:
+ default:
+ break;
+ }
+
+ printf("NodeRecord dump:\n"
+ "\t\t\t\tRID\n"
+ "\t\t\t\tLid.....................0x%X\n"
+ "\t\t\t\tReserved................0x%X\n"
+ "\t\t\t\tNodeInfoDump\n"
+ "\t\t\t\tbase_version............0x%X\n"
+ "\t\t\t\tclass_version...........0x%X\n"
+ "\t\t\t\tnode_type...............%s\n"
+ "\t\t\t\tnum_ports...............0x%X\n"
+ "\t\t\t\tsys_guid................0x%016" PRIx64 "\n"
+ "\t\t\t\tnode_guid...............0x%016" PRIx64 "\n"
+ "\t\t\t\tport_guid...............0x%016" PRIx64 "\n"
+ "\t\t\t\tpartition_cap...........0x%X\n"
+ "\t\t\t\tdevice_id...............0x%X\n"
+ "\t\t\t\trevision................0x%X\n"
+ "\t\t\t\tport_num................0x%X\n"
+ "\t\t\t\tvendor_id...............0x%X\n"
+ "\t\t\t\tNodeDescription\n"
+ "\t\t\t\t%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 )),
+ node_record->node_desc.description
+ );
+}
+
+void
+print_path_record(ib_path_rec_t *p_pr)
+{
+ printf("PathRecord dump:\n"
+ "\t\t\t\tresv0...................0x%016" PRIx64 "\n"
+ "\t\t\t\tdgid....................0x%016" PRIx64 " : "
+ "0x%016" PRIx64 "\n"
+ "\t\t\t\tsgid....................0x%016" PRIx64 " : "
+ "0x%016" PRIx64 "\n"
+ "\t\t\t\tdlid....................0x%X\n"
+ "\t\t\t\tslid....................0x%X\n"
+ "\t\t\t\thop_flow_raw............0x%X\n"
+ "\t\t\t\ttclass..................0x%X\n"
+ "\t\t\t\tnum_path_revers.........0x%X\n"
+ "\t\t\t\tpkey....................0x%X\n"
+ "\t\t\t\tsl......................0x%X\n"
+ "\t\t\t\tmtu.....................0x%X\n"
+ "\t\t\t\trate....................0x%X\n"
+ "\t\t\t\tpkt_life................0x%X\n"
+ "\t\t\t\tpreference..............0x%X\n"
+ "\t\t\t\tresv2...................0x%X\n"
+ "\t\t\t\tresv3...................0x%X\n"
+ "",
+ *(uint64_t*)p_pr->resv0,
+ cl_ntoh64( p_pr->dgid.unicast.prefix ),
+ cl_ntoh64( p_pr->dgid.unicast.interface_id ),
+ cl_ntoh64( p_pr->sgid.unicast.prefix ),
+ cl_ntoh64( p_pr->sgid.unicast.interface_id ),
+ 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 ),
+ cl_ntoh16( p_pr->sl ),
+ 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
+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 the node records available.
+ */
+static ib_api_status_t
+get_all_records(osm_bind_handle_t bind_handle,
+ ib_net16_t query_id,
+ ib_net16_t attr_offset)
+{
+ ib_api_status_t status;
+ osmv_query_req_t req;
+ osmv_user_query_t user;
+
+ cl_memclr( &req, sizeof( req ) );
+ cl_memclr( &user, sizeof( user ) );
+
+ user.attr_id = query_id;
+ user.attr_offset = attr_offset;
+
+ req.query_type = OSMV_QUERY_USER_DEFINED;
+ req.timeout_ms = 100;
+ 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 = 0;
+
+ if ((status = osmv_query_sa(bind_handle, &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);
+}
+
+static ib_api_status_t
+print_node_records(osm_bind_handle_t bind_handle)
+{
+ int i = 0;
+ ib_node_record_t *node_record = NULL;
+#if 0
+ ib_net16_t attr_offset = ib_get_attr_offset(sizeof(*node_record));
+#else
+ ib_net16_t attr_offset = 0;
+#endif
+ ib_api_status_t status;
+
+ status = get_all_records(bind_handle, IB_MAD_ATTR_NODE_RECORD,
attr_offset);
+ 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);
+ if (!requested_name ||
+ (strcmp(requested_name,
+ node_record->node_desc.description) == 0))
+ print_node_record(node_record);
+ }
+ return_mad();
+ return (status);
+}
+
+static ib_api_status_t
+print_path_records(osm_bind_handle_t bind_handle)
+{
+ int i = 0;
+ ib_path_rec_t *path_record = NULL;
+#if 0
+ ib_net16_t attr_offset = ib_get_attr_offset(sizeof(*path_record));
+#else
+ ib_net16_t attr_offset = 0;
+#endif
+ ib_api_status_t status;
+
+ status = get_all_records(bind_handle, IB_MAD_ATTR_PATH_RECORD, attr_offset);
+ if (status != IB_SUCCESS)
+ return (status);
+
+ for (i = 0; i < result.result_cnt; i++) {
+ path_record = osmv_get_query_path_rec(result.p_result_madw, i);
+ print_path_record(path_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 bind_handle;
+ ib_api_status_t status;
+ ib_port_attr_t attr_array[MAX_PORTS];
+ uint32_t num_ports = MAX_PORTS;
+
+ osm_log_construct(&log_osm);
+ if ((status = osm_log_init( &log_osm, TRUE,
+ 0x0001, NULL, 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, 100);
+ osm_mad_pool_construct(&mad_pool);
+ if ((status = osm_mad_pool_init(&mad_pool, &log_osm)) != 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 (attr_array[i].link_state == IB_LINK_ACTIVE)
+ port_guid = attr_array[i].port_guid;
+ }
+
+ if (port_guid == (uint64_t)-1) {
+ fprintf(stderr, "Failed to find active port, check port status with
\"ibstat\"\n");
+ exit (-1);
+ }
+
+ bind_handle = osmv_bind_sa(vendor, &mad_pool, port_guid);
+
+ if (bind_handle == OSM_BIND_INVALID_HANDLE) {
+ fprintf(stderr, "Failed to bind to SA\n");
+ exit(-1);
+ }
+ return (bind_handle);
+}
+
+static void
+clean_up(void)
+{
+ osm_mad_pool_destroy(&mad_pool);
+ osm_vendor_delete(&vendor);
+}
+
+void
+usage(void)
+{
+ fprintf(stderr, "Usage: %s [-h -d -P -L -G][<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, " -L Return just the Lid of the name specified\n");
+ fprintf(stderr, " -G Return just the Guid of the name specified\n");
+ exit(-1);
+}
+
+int
+main(int argc, char **argv)
+{
+ int ch = 0;
+ osm_bind_handle_t bind_handle;
+
+ static char const str_opts[] = "PLGdbh";
+ static const struct option long_opts [] = {
+ {"P", 0, 0, 'P'},
+ {"L", 0, 0, 'L'},
+ {"G", 0, 0, 'G'},
+ {"d", 0, 0, 'd'},
+ {"b", 0, 0, 'b'},
+ {"help", 0, 0, 'h'},
+ { }
+ };
+
+ argv0 = argv[0];
+
+ while ((ch = getopt_long(argc, argv, str_opts, long_opts, NULL)) != -1) {
+ switch (ch) {
+ case 'P':
+ query_type = IB_MAD_ATTR_PATH_RECORD;
+ break;
+ case 'L':
+ node_print_desc = LID_ONLY;
+ break;
+ case 'G':
+ node_print_desc = GUID_ONLY;
+ break;
+ case 'd':
+ osm_debug = 1;
+ break;
+ case 'h':
+ default:
+ usage();
+ }
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (argc)
+ requested_name = argv[0];
+
+ bind_handle = get_bind_handle();
+
+ switch (query_type) {
+ case IB_MAD_ATTR_NODE_RECORD:
+ print_node_records(bind_handle);
+ break;
+ case IB_MAD_ATTR_PATH_RECORD:
+ print_path_records(bind_handle);
+ break;
+ default:
+ fprintf(stderr, "Unknown query type %d\n", query_type);
+ break;
+ }
+
+ clean_up();
+ return (0);
+}
+
Property changes on: src/saquery.c
___________________________________________________________________
Name: svn:keywords
+ Id
Index: src/grouping.c
===================================================================
--- src/grouping.c (.../branches/1.0/src/userspace/management/diags) (revision
0)
+++ src/grouping.c (.../trunk/src/userspace/management/diags) (revision 6101)
@@ -0,0 +1,644 @@
+/*
+ * Copyright (c) 2004-2006 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.
+ *
+ * $Id$
+ */
+
+/*========================================================*/
+/* FABRIC SCANNER SPECIFIC DATA */
+/*========================================================*/
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <stdint.h>
+
+#include <common.h>
+#include <mad.h>
+
+#include "ibnetdiscover.h"
+#include "grouping.h"
+
+#define OUT_BUFFER_SIZE 16
+
+
+extern Node *nodesdist[MAXHOPS+1]; /* last is CA list */
+extern Node *mynode;
+extern Port *myport;
+extern int maxhops_discovered;
+
+AllChassisList mylist;
+
+char *ChassisTypeStr[3] = { "", "ISR9288", "ISR9096" };
+char *ChassisSlotStr[4] = { "", "Line", "Spine", "SRBD" };
+
+
+char *get_chassis_type(unsigned char chassistype)
+{
+ if (chassistype == UNRESOLVED_CT || chassistype > ISR9096_CT)
+ return NULL;
+ return ChassisTypeStr[chassistype];
+}
+
+char *get_chassis_slot(unsigned char chassisslot)
+{
+ if (chassisslot == UNRESOLVED_CS || chassisslot > SRBD_CS)
+ return NULL;
+ return ChassisSlotStr[chassisslot];
+}
+
+static struct ChassisList *find_chassisnum(unsigned char chassisnum)
+{
+ ChassisList *current;
+
+ for (current = mylist.first; current; current = current->next) {
+ if (current->chassisnum == chassisnum)
+ return current;
+ }
+
+ return NULL;
+}
+
+static uint64_t topspin_chassisguid(uint64_t guid)
+{
+ /* Byte 3 in system image GUID is chassis type, and */
+ /* Byte 4 is location ID (slot) so just mask off byte 4 */
+ return guid & 0xffffffff00ffffff;
+}
+
+static uint64_t get_chassisguid(uint64_t guid, uint32_t vendid)
+{
+ if (vendid == TS_VENDOR_ID)
+ return topspin_chassisguid(guid);
+ else
+ return guid;
+}
+
+static struct ChassisList *find_chassisguid(uint64_t guid, uint32_t vendid)
+{
+ ChassisList *current;
+ uint64_t chguid;
+
+ chguid = get_chassisguid(guid, vendid);
+ for (current = mylist.first; current; current = current->next) {
+ if (current->chassisguid == chguid)
+ return current;
+ }
+
+ return NULL;
+}
+
+uint64_t get_chassis_guid(unsigned char chassisnum)
+{
+ ChassisList *chassis;
+
+ chassis = find_chassisnum(chassisnum);
+ if (chassis)
+ return chassis->chassisguid;
+ else
+ return 0;
+}
+
+static int is_router(Node *node)
+{
+ return (node->devid == VTR_DEVID_IB_FC_ROUTER ||
+ node->devid == VTR_DEVID_IB_IP_ROUTER);
+}
+
+static int is_spine_9096(Node *node)
+{
+ return (node->devid == VTR_DEVID_SFB4 ||
+ node->devid == VTR_DEVID_SFB4_DDR);
+}
+
+static int is_spine_9288(Node *node)
+{
+ return (node->devid == VTR_DEVID_SFB12 ||
+ node->devid == VTR_DEVID_SFB12_DDR);
+}
+
+static int is_spine(Node *node)
+{
+ return (is_spine_9096(node) || is_spine_9288(node));
+}
+
+static int is_line_24(Node *node)
+{
+ return (node->devid == VTR_DEVID_SLB24 ||
+ node->devid == VTR_DEVID_SLB24_DDR);
+}
+
+static int is_line_8(Node *node)
+{
+ return (node->devid == VTR_DEVID_SLB8);
+}
+
+static int is_line(Node *node)
+{
+ return (is_line_24(node) || is_line_8(node));
+}
+
+static int is_chassis_switch(Node *node)
+{
+ return (is_spine(node) || is_line(node));
+}
+
+/* this struct's helps find Line (Anafa) slot number while using spine
portnum */
+int line_slot_2_sfb4[25] = { 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3,
3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4 };
+int anafa_line_slot_2_sfb4[25] = { 0, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1,
1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2 };
+int line_slot_2_sfb12[25] = { 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7,
7, 8, 8, 9, 9,10, 10, 11, 11, 12, 12 };
+int anafa_line_slot_2_sfb12[25] = { 0, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1,
2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2 };
+
+/* IPR FCR modules connectivity while using sFB4 port as reference */
+int ipr_slot_2_sfb4_port[25] = { 0, 3, 2, 1, 3, 2, 1, 3, 2, 1, 3, 2, 1, 3,
2, 1, 3, 2, 1, 3, 2, 1, 3, 2, 1 };
+
+/* this struct's helps find Spine (Anafa) slot number while using spine
portnum */
+int spine12_slot_2_slb[25] = { 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+int anafa_spine12_slot_2_slb[25]= { 0, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+int spine4_slot_2_slb[25] = { 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+int anafa_spine4_slot_2_slb[25] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+/* reference { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 }; */
+
+static void get_sfb_slot(Node *node, Port *lineport)
+{
+ ChassisRecord *ch = node->chrecord;
+
+ ch->chassisslot = SPINE_CS;
+ if (is_spine_9096(node)) {
+ ch->chassistype = ISR9096_CT;
+ ch->slotnum = spine4_slot_2_slb[lineport->portnum];
+ ch->anafanum = anafa_spine4_slot_2_slb[lineport->portnum];
+ } else {
+ ch->chassistype = ISR9288_CT;
+ ch->slotnum = spine12_slot_2_slb[lineport->portnum];
+ ch->anafanum = anafa_spine12_slot_2_slb[lineport->portnum];
+ }
+}
+
+static void get_router_slot(Node *node, Port *spineport)
+{
+ ChassisRecord *ch = node->chrecord;
+ int guessnum = 0;
+
+ if (!ch) {
+ if (!(node->chrecord = calloc(1, sizeof(ChassisRecord))))
+ IBPANIC("out of mem");
+ ch = node->chrecord;
+ }
+
+ ch->chassisslot = SRBD_CS;
+ if (is_spine_9096(spineport->node)) {
+ ch->chassistype = ISR9096_CT;
+ ch->slotnum = line_slot_2_sfb4[spineport->portnum];
+ ch->anafanum = ipr_slot_2_sfb4_port[spineport->portnum];
+ } else {
+ ch->chassistype = ISR9288_CT;
+ ch->slotnum = line_slot_2_sfb12[spineport->portnum];
+ /* this is a smart guess based on nodeguids order on sFB-12 module */
+ guessnum = spineport->node->nodeguid % 4;
+ /* module 1 <--> remote anafa 3 */
+ /* module 2 <--> remote anafa 2 */
+ /* module 3 <--> remote anafa 1 */
+ ch->anafanum = (guessnum == 3 ? 1 : (guessnum == 1 ? 3 : 2));
+ }
+}
+
+static void get_slb_slot(ChassisRecord *ch, Port *spineport)
+{
+ ch->chassisslot = LINE_CS;
+ if (is_spine_9096(spineport->node)) {
+ ch->chassistype = ISR9096_CT;
+ ch->slotnum = line_slot_2_sfb4[spineport->portnum];
+ ch->anafanum = anafa_line_slot_2_sfb4[spineport->portnum];
+ } else {
+ ch->chassistype = ISR9288_CT;
+ ch->slotnum = line_slot_2_sfb12[spineport->portnum];
+ ch->anafanum = anafa_line_slot_2_sfb12[spineport->portnum];
+ }
+}
+
+/*
+ This function called for every Voltaire node in fabric
+ It could be optimized so, but time overhead is very small
+ and its only diag.util
+*/
+static void fill_chassis_record(Node *node)
+{
+ Port *port;
+ Node *remnode = 0;
+ ChassisRecord *ch = 0;
+
+ if (node->chrecord) /* somehow this node has already been passed */
+ return;
+
+ if (!(node->chrecord = calloc(1, sizeof(ChassisRecord))))
+ IBPANIC("out of mem");
+
+ ch = node->chrecord;
+
+ /* node is router only in case of using unique lid */
+ /* (which is lid of chassis router port) */
+ /* in such case node->ports is actually a requested port... */
+ if (is_router(node) && is_spine(node->ports->remoteport->node))
+ get_router_slot(node, node->ports->remoteport);
+ else if (is_spine(node)) {
+ for (port = node->ports; port; port = port->next) {
+ if (!port->remoteport)
+ continue;
+ remnode = port->remoteport->node;
+ if (remnode->type != SWITCH_NODE) {
+ if (!remnode->chrecord)
+ get_router_slot(remnode, port);
+ continue;
+ }
+ if (!ch->chassistype)
+ /* we assume here that remoteport belongs to line */
+ get_sfb_slot(node, port->remoteport);
+
+ /* we could break here, but need to find if more routers connected */
+ }
+
+ } else if (is_line(node)) {
+ for (port = node->ports; port; port = port->next) {
+ if (port->portnum > 12)
+ continue;
+ if (!port->remoteport)
+ continue;
+ /* we assume here that remoteport belongs to spine */
+ get_slb_slot(ch, port->remoteport);
+ break;
+ }
+ }
+
+ return;
+}
+
+static int get_line_index(Node *node)
+{
+ int retval = 3 * (node->chrecord->slotnum - 1) + node->chrecord->anafanum;
+
+ if (retval > LINES_MAX_NUM || retval < 1)
+ IBPANIC("Grouping: Internal error");
+ return retval;
+}
+
+static int get_spine_index(Node *node)
+{
+ int retval;
+
+ if (is_spine_9288(node))
+ retval = 3 * (node->chrecord->slotnum - 1) + node->chrecord->anafanum;
+ else
+ retval = node->chrecord->slotnum;
+
+ if (retval > SPINES_MAX_NUM || retval < 1)
+ IBPANIC("Grouping: Internal error");
+ return retval;
+}
+
+static void insert_line_router(Node *node, ChassisList *chassislist)
+{
+ int i = get_line_index(node);
+
+ if (chassislist->linenode[i])
+ return; /* already filled slot */
+
+ chassislist->linenode[i] = node;
+ node->chrecord->chassisnum = chassislist->chassisnum;
+}
+
+static void insert_spine(Node *node, ChassisList *chassislist)
+{
+ int i = get_spine_index(node);
+
+ if (chassislist->spinenode[i])
+ return; /* already filled slot */
+
+ chassislist->spinenode[i] = node;
+ node->chrecord->chassisnum = chassislist->chassisnum;
+}
+
+static void pass_on_lines_catch_spines(ChassisList *chassislist)
+{
+ Node *node, *remnode;
+ Port *port;
+ int i;
+
+ for (i = 1; i <= LINES_MAX_NUM; i++) {
+ node = chassislist->linenode[i];
+
+ if (!(node && is_line(node)))
+ continue; /* empty slot or router */
+
+ for (port = node->ports; port; port = port->next) {
+ if (port->portnum > 12)
+ continue;
+
+ if (!port->remoteport)
+ continue;
+ remnode = port->remoteport->node;
+
+ if (!remnode->chrecord)
+ continue; /* some error - spine not initialized ? FIXME */
+ insert_spine(remnode, chassislist);
+ }
+ }
+}
+
+static void pass_on_spines_catch_lines(ChassisList *chassislist)
+{
+ Node *node, *remnode;
+ Port *port;
+ int i;
+
+ for (i = 1; i <= SPINES_MAX_NUM; i++) {
+ node = chassislist->spinenode[i];
+ if (!node)
+ continue; /* empty slot */
+ for (port = node->ports; port; port = port->next) {
+ if (!port->remoteport)
+ continue;
+ remnode = port->remoteport->node;
+
+ if (!remnode->chrecord)
+ continue; /* some error - line/router not initialized ? FIXME */
+ insert_line_router(remnode, chassislist);
+ }
+ }
+}
+
+/*
+ Stupid interpolation algorithm...
+ But nothing to do - have to be compliant with VoltaireSM/NMS
+*/
+static void pass_on_spines_interpolate_chguid(ChassisList *chassislist)
+{
+ Node *node;
+ int i;
+
+ for (i = 1; i <= SPINES_MAX_NUM; i++) {
+ node = chassislist->spinenode[i];
+ if (!node)
+ continue; /* skip the empty slots */
+
+ /* take first guid less one: consistent with SM... */
+ chassislist->chassisguid = node->nodeguid - 1;
+ break;
+ }
+}
+
+/*
+ This function fills chassislist structure with all nodes
+ in that chassis
+ chassislist structure = structure of one standalone chassis
+*/
+static void build_chassis(Node *node, ChassisList *chassislist)
+{
+ Node *remnode = 0;
+ Port *port = 0;
+
+ /* we get here with node = chassis_spine */
+ chassislist->chassistype = node->chrecord->chassistype;
+ insert_spine(node, chassislist);
+
+ /* loop: pass on all ports of node */
+ for (port = node->ports; port; port = port->next) {
+ if (!port->remoteport)
+ continue;
+ remnode = port->remoteport->node;
+
+ if (!remnode->chrecord)
+ continue; /* some error - line or router not initialized ? FIXME */
+
+ insert_line_router(remnode, chassislist);
+ }
+
+ pass_on_lines_catch_spines(chassislist);
+ /* this pass needed for to catch routers, since routers connected only */
+ /* to spines in slot 1 or 4 and we could miss them first time */
+ pass_on_spines_catch_lines(chassislist);
+
+ /* additional 2 passes needed for to overcome a problem of pure "in-chassis"
*/
+ /* connectivity - extra pass to ensure that all related chips/modules */
+ /* inserted into the chassislist */
+ pass_on_lines_catch_spines(chassislist);
+ pass_on_spines_catch_lines(chassislist);
+ pass_on_spines_interpolate_chguid(chassislist);
+}
+
+/*========================================================*/
+/* INTERNAL TO EXTERNAL PORT MAPPING */
+/*========================================================*/
+
+/*
+Description : On ISR9288/9096 external ports indexing
+ is not matching the internal ( anafa ) port
+ indexes. Use this MAP to translate the data you get from
+ the OpenIB diagnostics (smpquery, ibroute, ibtracert, etc.)
+
+
+Module : sLB-24
+ anafa 1 anafa 2
+ext port | 13 14 15 16 17 18 | 19 20 21 22 23 24
+int port | 22 23 24 18 17 16 | 22 23 24 18 17 16
+ext port | 1 2 3 4 5 6 | 7 8 9 10 11 12
+int port | 19 20 21 15 14 13 | 19 20 21 15 14 13
+------------------------------------------------
+
+Module : sLB-8
+ anafa 1 anafa 2
+ext port | 13 14 15 16 17 18 | 19 20 21 22 23 24
+int port | 24 23 22 18 17 16 | 24 23 22 18 17 16
+ext port | 1 2 3 4 5 6 | 7 8 9 10 11 12
+int port | 21 20 19 15 14 13 | 21 20 19 15 14 13
+
+----------->
+ anafa 1 anafa 2
+ext port | - - 5 - - 6 | - - 7 - - 8
+int port | 24 23 22 18 17 16 | 24 23 22 18 17 16
+ext port | - - 1 - - 2 | - - 3 - - 4
+int port | 21 20 19 15 14 13 | 21 20 19 15 14 13
+------------------------------------------------
+
+*/
+
+int int2ext_map_slb24[2][25] = {
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 5, 4, 18, 17, 16, 1, 2, 3,
13, 14, 15 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 11, 10, 24, 23, 22, 7, 8,
9, 19, 20, 21 }
+ };
+int int2ext_map_slb8[2][25] = {
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 6, 6, 6, 1, 1, 1, 5,
5, 5 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 8, 8, 8, 3, 3, 3, 7,
7, 7 }
+ };
+/* reference { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23, 24 }; */
+
+/*
+ This function relevant only for line modules/chips
+ Returns string with external port index
+*/
+char *portmapstring(Port *port)
+{
+ static char mapping[OUT_BUFFER_SIZE];
+ ChassisRecord *ch = port->node->chrecord;
+ int portnum = port->portnum;
+ int chipnum = 0;
+ int pindex = 0;
+ Node *node = port->node;
+
+ if (!ch || !is_line(node) || (portnum < 13 || portnum > 24))
+ return NULL;
+
+ if (ch->anafanum < 1 || ch->anafanum > 2)
+ return NULL;
+
+ memset(mapping, 0, sizeof(mapping));
+
+ chipnum = ch->anafanum - 1;
+
+ if (is_line_24(node))
+ pindex = int2ext_map_slb24[chipnum][portnum];
+ else
+ pindex = int2ext_map_slb8[chipnum][portnum];
+
+ sprintf(mapping, "[ext %d]", pindex);
+
+ return mapping;
+}
+
+static void add_chassislist()
+{
+ if (!(mylist.current = calloc(1, sizeof(ChassisList))))
+ IBPANIC("out of mem");
+
+ if (mylist.first == NULL) {
+ mylist.first = mylist.current;
+ mylist.last = mylist.current;
+ } else {
+ mylist.last->next = mylist.current;
+ mylist.current->next = NULL;
+ mylist.last = mylist.current;
+ }
+}
+
+/*
+ Main grouping function
+ Algorithm:
+ 1. pass on every Voltaire node
+ 2. catch spine chip for every Voltaire node
+ 2.1 build/interpolate chassis around this chip
+ 2.2 go to 1.
+ 3. pass on non Voltaire nodes (SystemImageGUID based grouping)
+ 4. now group non Voltaire nodes by SystemImageGUID
+*/
+void group_nodes()
+{
+ Node *node;
+ int dist;
+ int chassisnum = 0;
+ struct ChassisList *chassis;
+
+ mylist.first = NULL;
+ mylist.current = NULL;
+ mylist.last = NULL;
+
+ /* first pass on switches and build for every Voltaire node */
+ /* an appropriate chassis record (slotnum and position) */
+ /* according to internal connectivity */
+ /* not very efficient but clear code so... */
+ for (dist = 0; dist <= maxhops_discovered; dist++) {
+ for (node = nodesdist[dist]; node; node = node->dnext) {
+ if (node->vendid == VTR_VENDOR_ID)
+ fill_chassis_record(node);
+ }
+ }
+
+ /* separate every Voltaire chassis from each other and build linked list of
them */
+ /* algorithm: catch spine and find all surrounding nodes */
+ for (dist = 0; dist <= maxhops_discovered; dist++) {
+ for (node = nodesdist[dist]; node; node = node->dnext) {
+ if (node->vendid != VTR_VENDOR_ID)
+ continue;
+ if (!node->chrecord || node->chrecord->chassisnum || !is_spine(node))
+ continue;
+
+ add_chassislist();
+ mylist.current->chassisnum = ++chassisnum;
+ build_chassis(node, mylist.current);
+
+ }
+ }
+
+ /* now make pass on nodes for chassis which are not Voltaire */
+ /* grouped by common SystemImageGUID */
+ for (dist = 0; dist <= maxhops_discovered; dist++) {
+ for (node = nodesdist[dist]; node; node = node->dnext) {
+ if (node->vendid == VTR_VENDOR_ID)
+ continue;
+ if (node->sysimgguid) {
+ chassis = find_chassisguid(node->sysimgguid,
+ node->vendid);
+ if (chassis)
+ chassis->nodecount++;
+ else {
+ /* Possible new chassis */
+ add_chassislist();
+ mylist.current->chassisguid = get_chassisguid(node->sysimgguid,
node->vendid);
+ mylist.current->nodecount = 1;
+ }
+ }
+ }
+ }
+
+ /* now, make another pass to see which nodes are part of chassis */
+ /* (defined as chassis->nodecount > 1) */
+ for (dist = 0; dist <= maxhops_discovered; dist++) {
+ for (node = nodesdist[dist]; node; node = node->dnext) {
+ if (node->vendid == VTR_VENDOR_ID)
+ continue;
+
+ if (node->sysimgguid) {
+ chassis = find_chassisguid(node->sysimgguid,
+ node->vendid);
+ if (chassis && chassis->nodecount > 1) {
+ if (!chassis->chassisnum)
+ chassis->chassisnum = ++chassisnum;
+ if (!node->chrecord) {
+ if (!(node->chrecord = calloc(1, sizeof(ChassisRecord))))
+ IBPANIC("out of mem");
+ node->chrecord->chassisnum = chassis->chassisnum;
+ }
+ }
+ }
+ }
+ }
+
+}
Property changes on: src/grouping.c
___________________________________________________________________
Name: svn:keywords
+ Id
Index: Makefile.am
===================================================================
--- Makefile.am (.../branches/1.0/src/userspace/management/diags) (revision
6101)
+++ Makefile.am (.../trunk/src/userspace/management/diags) (revision 6101)
@@ -1,6 +1,7 @@
# $Id$
-INCLUDES = -I$(srcdir)/../libibcommon/include/infiniband \
+INCLUDES = -I include \
+ -I$(srcdir)/../libibcommon/include/infiniband \
-I$(srcdir)/../libibumad/include/infiniband \
-I$(srcdir)/../libibmad/include/infiniband \
-I$(includedir)/infiniband
@@ -24,7 +25,7 @@ src_ibaddr_CFLAGS = -Wall
# $(libdir)/libibmad.la
# src_ibaddr_LDFLAGS = -Wl,--rpath -Wl,$(libdir)
-src_ibnetdiscover_SOURCES = src/ibnetdiscover.c
+src_ibnetdiscover_SOURCES = src/ibnetdiscover.c src/grouping.c
src_ibnetdiscover_CFLAGS = -Wall
# src_ibnetdiscover_LDADD = $(libdir)/libibcommon.la \
# $(libdir)/libibumad.la \
@@ -100,7 +101,7 @@ src_smpquery_CFLAGS = -Wall
# $(libdir)/libibmad.la
# src_smpquery_LDFLAGS = -Wl,--rpath -Wl,$(libdir)
-EXTRA_DIST = scripts diags.spec.in
+EXTRA_DIST = scripts include diags.spec.in
dist-hook: diags.spec
cp diags.spec $(distdir)
Property changes on:
___________________________________________________________________
Name: svn:ignore
+ aclocal.m4
autom4te.cache
config.h
config.h.in
config.log
config.status
configure
.deps
libtool
Makefile
Makefile.in
stamp-h1
More information about the general
mailing list