stick a *next pointer into struct osm_routing_engine.  Rearchitect
routing engine usage as a list instead of a single struct.

Al

-- 
Albert Chu
[EMAIL PROTECTED]
925-422-5311
Computer Scientist
High Performance Systems Division
Lawrence Livermore National Laboratory
>From 0cc04e2660a57a2b7b03e449563cc19bc5446811 Mon Sep 17 00:00:00 2001
From: Albert Chu <[EMAIL PROTECTED]>
Date: Fri, 12 Sep 2008 14:22:42 -0700
Subject: [PATCH] rearchitect osm_routing_engine as a list data structure


Signed-off-by: Albert Chu <[EMAIL PROTECTED]>
---
 opensm/include/opensm/osm_opensm.h |   10 +++-
 opensm/opensm/osm_opensm.c         |   73 +++++++++++++++++++++++++++++++-----
 opensm/opensm/osm_ucast_mgr.c      |   56 ++++++++++++++++++---------
 3 files changed, 108 insertions(+), 31 deletions(-)

diff --git a/opensm/include/opensm/osm_opensm.h b/opensm/include/opensm/osm_opensm.h
index a1c255b..6990307 100644
--- a/opensm/include/opensm/osm_opensm.h
+++ b/opensm/include/opensm/osm_opensm.h
@@ -126,6 +126,7 @@ struct osm_routing_engine {
 	int (*ucast_build_fwd_tables) (void *context);
 	void (*ucast_dump_tables) (void *context);
 	void (*delete) (void *context);
+	struct osm_routing_engine *next;
 };
 /*
 * FIELDS
@@ -148,6 +149,9 @@ struct osm_routing_engine {
 *	delete
 *		The delete method, may be used for routing engine
 *		internals cleanup.
+*
+*	next
+*		Pointer to next routing engine in the list.
 */
 
 /****s* OpenSM: OpenSM/osm_opensm_t
@@ -178,7 +182,7 @@ typedef struct osm_opensm {
 	osm_log_t log;
 	cl_dispatcher_t disp;
 	cl_plock_t lock;
-	struct osm_routing_engine routing_engine;
+	struct osm_routing_engine *routing_engine_list;
 	osm_routing_engine_type_t routing_engine_used;
 	osm_stats_t stats;
 	osm_console_t console;
@@ -221,8 +225,8 @@ typedef struct osm_opensm {
 *	lock
 *		Shared lock guarding most OpenSM structures.
 *
-*	routing_engine
-*		Routing engine; will be initialized then used.
+*	routing_engine_list
+*		List of routing engines that should be tried for use.
 *
 *	routing_engine_used
 *		Indicates which routing engine was used to route a subnet.
diff --git a/opensm/opensm/osm_opensm.c b/opensm/opensm/osm_opensm.c
index 48e75f5..5b49d0a 100644
--- a/opensm/opensm/osm_opensm.c
+++ b/opensm/opensm/osm_opensm.c
@@ -135,36 +135,72 @@ osm_routing_engine_type_t osm_routing_engine_type(IN const char *str)
 
 /**********************************************************************
  **********************************************************************/
+static void append_routing_engine(osm_opensm_t * p_osm,
+				  struct osm_routing_engine *routing_engine)
+{
+	struct osm_routing_engine *p_routing_engine;
+
+	routing_engine->next = NULL;
+
+	if (!p_osm->routing_engine_list) {
+		p_osm->routing_engine_list = routing_engine;
+		return;
+	}
+
+	p_routing_engine = p_osm->routing_engine_list;
+	while (p_routing_engine->next)
+		p_routing_engine = p_routing_engine->next;
+
+	p_routing_engine->next = routing_engine;
+}
+
 static void setup_routing_engine(osm_opensm_t * p_osm, const char *name)
 {
+	struct osm_routing_engine *routing_engine = NULL;
 	const struct routing_engine_module *r;
 
+	routing_engine = malloc(sizeof(struct osm_routing_engine));
+	if (!routing_engine) {
+		OSM_LOG(&p_osm->log, OSM_LOG_VERBOSE,
+			"routing engine memory allocation failed\n");
+		return;
+	}
+	memset(routing_engine, '\0', sizeof(struct osm_routing_engine));
+
 	if (!name) {
-		osm_ucast_minhop_setup(&p_osm->routing_engine, p_osm);
+		osm_ucast_minhop_setup(routing_engine, p_osm);
+		append_routing_engine(p_osm, routing_engine);
 		return;
 	}
 
 	for (r = routing_modules; r->name && *r->name; r++) {
 		if (!strcmp(r->name, name)) {
-			p_osm->routing_engine.name = r->name;
-			if (r->setup(&p_osm->routing_engine, p_osm)) {
+			routing_engine->name = r->name;
+			if (r->setup(routing_engine, p_osm)) {
 				OSM_LOG(&p_osm->log, OSM_LOG_VERBOSE,
 					"setup of routing"
 					" engine \'%s\' failed\n", name);
-				break;
+				return;
 			}
 			OSM_LOG(&p_osm->log, OSM_LOG_DEBUG,
 				"\'%s\' routing engine set up\n",
-				p_osm->routing_engine.name);
+				routing_engine->name);
+			append_routing_engine(p_osm, routing_engine);
 			return;
 		}
 	}
 
 	OSM_LOG(&p_osm->log, OSM_LOG_VERBOSE,
-		"cannot find or setup routing engine"
-		" \'%s\'. Minhop will be used instead\n",
+		"cannot find or setup routing engine \'%s\'",
 		name);
-	osm_ucast_minhop_setup(&p_osm->routing_engine, p_osm);
+}
+
+static void setup_default_routing_engine(osm_opensm_t * p_osm)
+{
+	setup_routing_engine(p_osm, NULL);
+
+	OSM_LOG(&p_osm->log, OSM_LOG_VERBOSE,
+		"Minhop configured as default routing\n");
 }
 
 /**********************************************************************
@@ -184,6 +220,21 @@ void osm_opensm_construct(IN osm_opensm_t * const p_osm)
 
 /**********************************************************************
  **********************************************************************/
+static void _osm_opensm_routing_engine_destroy(IN osm_opensm_t * const p_osm)
+{
+	struct osm_routing_engine *p_routing_engine;
+
+	if (!p_osm->routing_engine_list)
+		return;
+
+	p_routing_engine = p_osm->routing_engine_list;
+	while (p_routing_engine) {
+		if (p_routing_engine->delete)
+			p_routing_engine->delete(p_routing_engine->context);
+		p_routing_engine = p_routing_engine->next;
+	}
+}
+
 void osm_opensm_destroy(IN osm_opensm_t * const p_osm)
 {
 	/* in case of shutdown through exit proc - no ^C */
@@ -221,8 +272,7 @@ void osm_opensm_destroy(IN osm_opensm_t * const p_osm)
 	osm_sa_db_file_dump(p_osm);
 
 	/* do the destruction in reverse order as init */
-	if (p_osm->routing_engine.delete)
-		p_osm->routing_engine.delete(p_osm->routing_engine.context);
+	_osm_opensm_routing_engine_destroy(p_osm);
 	osm_sa_destroy(&p_osm->sa);
 	osm_sm_destroy(&p_osm->sm);
 #ifdef ENABLE_OSM_PERF_MGR
@@ -384,6 +434,9 @@ osm_opensm_init(IN osm_opensm_t * const p_osm,
 
 	setup_routing_engine(p_osm, p_opt->routing_engine_name);
 
+	if (!p_osm->routing_engine_list)
+		setup_default_routing_engine(p_osm);
+
 	p_osm->routing_engine_used = OSM_ROUTING_ENGINE_TYPE_NONE;
 
 	p_osm->node_name_map = open_node_name_map(p_opt->node_name_map_name);
diff --git a/opensm/opensm/osm_ucast_mgr.c b/opensm/opensm/osm_ucast_mgr.c
index b8272ee..f905eab 100644
--- a/opensm/opensm/osm_ucast_mgr.c
+++ b/opensm/opensm/osm_ucast_mgr.c
@@ -245,20 +245,48 @@ static int ucast_mgr_setup_all_switches(osm_subn_t * p_subn)
 
 /**********************************************************************
  **********************************************************************/
+int _osm_ucast_mgr_route(struct osm_routing_engine *p_routing_eng,
+			 osm_opensm_t *p_osm)
+{
+	int blm = -1;
+	int ubft = -1;
+
+	CL_ASSERT(p_routing_eng->build_lid_matrices);
+	CL_ASSERT(p_routing_eng->ucast_build_fwd_tables);
+
+	blm = p_routing_eng->build_lid_matrices(p_routing_eng->context);
+
+	/*
+	   Now that the lid matrices have been built, we can
+	   build and download the switch forwarding tables.
+	 */
+	if (!blm)
+		ubft = p_routing_eng->ucast_build_fwd_tables(p_routing_eng->context);
+
+	if (!blm && !ubft) {
+		p_osm->routing_engine_used =
+		    osm_routing_engine_type(p_routing_eng->name);
+		return 0;
+	}
+
+	OSM_LOG(&p_osm->log, OSM_LOG_DEBUG,
+		"failed to route using routing algorithm %s\n",
+		p_routing_eng->name);
+	return -1;
+}
+
 osm_signal_t osm_ucast_mgr_process(IN osm_ucast_mgr_t * const p_mgr)
 {
 	osm_opensm_t *p_osm;
 	struct osm_routing_engine *p_routing_eng;
 	osm_signal_t signal = OSM_SIGNAL_DONE;
 	cl_qmap_t *p_sw_guid_tbl;
-	int blm = -1;
-	int ubft = -1;
 
 	OSM_LOG_ENTER(p_mgr->p_log);
 
 	p_sw_guid_tbl = &p_mgr->p_subn->sw_guid_tbl;
 	p_osm = p_mgr->p_subn->p_osm;
-	p_routing_eng = &p_osm->routing_engine;
+	p_routing_eng = p_osm->routing_engine_list;
 
 	CL_PLOCK_EXCL_ACQUIRE(p_mgr->p_lock);
 
@@ -271,22 +299,14 @@ osm_signal_t osm_ucast_mgr_process(IN osm_ucast_mgr_t * const p_mgr)
 
 	p_mgr->any_change = FALSE;
 
-	CL_ASSERT(p_routing_eng->build_lid_matrices);
-	CL_ASSERT(p_routing_eng->ucast_build_fwd_tables);
-
-	blm = p_routing_eng->build_lid_matrices(p_routing_eng->context);
-
-	/*
-	   Now that the lid matrices have been built, we can
-	   build and download the switch forwarding tables.
-	 */
-	if (!blm)
-		ubft = p_routing_eng->ucast_build_fwd_tables(p_routing_eng->context);
+	p_osm->routing_engine_used = OSM_ROUTING_ENGINE_TYPE_NONE;
+	while (p_routing_eng) {
+		if (!_osm_ucast_mgr_route(p_routing_eng, p_osm))
+			break;
+		p_routing_eng = p_routing_eng->next;
+	}
 
-	if (!blm && !ubft)
-		p_osm->routing_engine_used =
-		    osm_routing_engine_type(p_routing_eng->name);
-	else {
+	if (p_osm->routing_engine_used == OSM_ROUTING_ENGINE_TYPE_NONE) {
 		/* If configured routing algorithm failed, use default MinHop */
 		osm_ucast_minhop_no_failure_build_lid_matrices(p_osm);
 		osm_ucast_minhop_no_failure_build_fwd_tables(p_osm);
-- 
1.5.4.5

_______________________________________________
general mailing list
[email protected]
http://lists.openfabrics.org/cgi-bin/mailman/listinfo/general

To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general

Reply via email to