[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