[ofa-general] [PATCH 1/2] opensm/osm_opensm.c: Added routing plugin interface.

Vincent Ficet jean-vincent.ficet at bull.net
Thu Jun 11 00:38:58 PDT 2009


	* Added a plugin interface for routing algorithms similar to event plugins
	* When a routing algorithm name cannot be found in the routing_engine_module,
	  we try to open the file and load a struct using dlopen.
	* Plugin have to:
		- be named libPLUGIN_NAME.so
		- export a osm_routing_plugin_t struct named OSM_ROUTING_PLUGIN_IMPL_NAME that contains
			- osm_version equal to OSM_VERSION
			- a setup function which fills the routing_engine methods

Signed-off-by: Jean-Vincent Ficet <jean-vincent.ficet at bull.net>
---
 opensm/include/opensm/osm_opensm.h |   38 +++++++++++++-
 opensm/opensm/osm_event_plugin.c   |    8 ---
 opensm/opensm/osm_opensm.c         |   98 ++++++++++++++++++++++++++++++++++--
 3 files changed, 131 insertions(+), 13 deletions(-)

diff --git a/opensm/include/opensm/osm_opensm.h b/opensm/include/opensm/osm_opensm.h
index c121be4..b540fe0 100644
--- a/opensm/include/opensm/osm_opensm.h
+++ b/opensm/include/opensm/osm_opensm.h
@@ -70,6 +70,14 @@
 #endif				/* __cplusplus */
 
 BEGIN_C_DECLS
+/* Defines for routing and event plugin names */
+#if defined(PATH_MAX)
+#define OSM_PATH_MAX	(PATH_MAX + 1)
+#elif defined (_POSIX_PATH_MAX)
+#define OSM_PATH_MAX	(_POSIX_PATH_MAX + 1)
+#else
+#define OSM_PATH_MAX	256
+#endif
 /****h* OpenSM/OpenSM
 * NAME
 *	OpenSM
@@ -105,7 +113,7 @@ typedef enum _osm_routing_engine_type {
 	OSM_ROUTING_ENGINE_TYPE_FTREE,
 	OSM_ROUTING_ENGINE_TYPE_LASH,
 	OSM_ROUTING_ENGINE_TYPE_DOR,
-	OSM_ROUTING_ENGINE_TYPE_UNKNOWN
+	OSM_ROUTING_ENGINE_TYPE_EXTERNAL
 } osm_routing_engine_type_t;
 /***********/
 
@@ -126,6 +134,7 @@ struct osm_routing_engine {
 	int (*ucast_build_fwd_tables) (void *context);
 	void (*ucast_dump_tables) (void *context);
 	void (*delete) (void *context);
+	void *handle;
 	struct osm_routing_engine *next;
 };
 /*
@@ -150,6 +159,9 @@ struct osm_routing_engine {
 *		The delete method, may be used for routing engine
 *		internals cleanup.
 *
+*      handle
+*             Pointer to the handle (if it exists) for plugin routing algorithms.
+*
 *	next
 *		Pointer to next routing engine in the list.
 */
@@ -237,6 +249,30 @@ typedef struct osm_opensm {
 * SEE ALSO
 *********/
 
+/****s* OpenSM: OpenSM/osm_routing_plugin_t
+* NAME
+*	struct osm_routing_plugin_t
+*
+* DESCRIPTION
+*	OpenSM routing plugin definition.
+* NOTES
+*	Routing plugin should export a osm_routing_plugin_t named OSM_EVENT_PLUGIN_IMPL_NAME
+*/
+#define OSM_ROUTING_PLUGIN_IMPL_NAME "osm_routing_plugin"
+typedef struct _osm_routing_plugin_t {
+	const char *osm_version;
+	int (*setup) (struct osm_routing_engine *, osm_opensm_t *);
+} osm_routing_plugin_t;
+/*
+* FIELDS
+*	osm_version
+*		osm_version the plugin was built on.
+*
+*	setup
+*		Plugin setup function which fills the osm_routing_engine with routing methods.
+*
+*/
+
 /****f* OpenSM: OpenSM/osm_opensm_construct
 * NAME
 *	osm_opensm_construct
diff --git a/opensm/opensm/osm_event_plugin.c b/opensm/opensm/osm_event_plugin.c
index c77494e..6c5ef05 100644
--- a/opensm/opensm/osm_event_plugin.c
+++ b/opensm/opensm/osm_event_plugin.c
@@ -52,14 +52,6 @@
 #include <opensm/osm_event_plugin.h>
 #include <opensm/osm_opensm.h>
 
-#if defined(PATH_MAX)
-#define OSM_PATH_MAX	(PATH_MAX + 1)
-#elif defined (_POSIX_PATH_MAX)
-#define OSM_PATH_MAX	(_POSIX_PATH_MAX + 1)
-#else
-#define OSM_PATH_MAX	256
-#endif
-
 /**
  * functions
  */
diff --git a/opensm/opensm/osm_opensm.c b/opensm/opensm/osm_opensm.c
index 50d1349..61d57bf 100644
--- a/opensm/opensm/osm_opensm.c
+++ b/opensm/opensm/osm_opensm.c
@@ -47,6 +47,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <dlfcn.h>
 #include <complib/cl_dispatcher.h>
 #include <complib/cl_passivelock.h>
 #include <vendor/osm_vendor_api.h>
@@ -103,7 +104,7 @@ const char *osm_routing_engine_type_str(IN osm_routing_engine_type_t type)
 	default:
 		break;
 	}
-	return "unknown";
+	return "external";
 }
 
 /**********************************************************************
@@ -129,7 +130,7 @@ osm_routing_engine_type_t osm_routing_engine_type(IN const char *str)
 	else if (!strcasecmp(str, "dor"))
 		return OSM_ROUTING_ENGINE_TYPE_DOR;
 	else
-		return OSM_ROUTING_ENGINE_TYPE_UNKNOWN;
+		return OSM_ROUTING_ENGINE_TYPE_EXTERNAL;
 }
 
 /**********************************************************************
@@ -153,7 +154,88 @@ static void append_routing_engine(osm_opensm_t *osm,
 	r->next = routing_engine;
 }
 
-static void setup_routing_engine(osm_opensm_t *osm, const char *name)
+static void setup_plugin_routing_engine(osm_opensm_t * osm, const char *name)
+{
+	struct osm_routing_engine *re;
+	void *handle;
+	char lib_name[OSM_PATH_MAX];
+	osm_routing_plugin_t *routing_plugin;
+
+	snprintf(lib_name, sizeof(lib_name), "lib%s.so", name);
+	handle = dlopen(lib_name, RTLD_LAZY);
+	if (!handle) {
+		OSM_LOG(&osm->log, OSM_LOG_ERROR,
+			"cannot find or setup routing engine \'%s\'\n", name);
+		return;
+	}
+
+	/* Allocate and initialize the routing engine struct */
+	re = malloc(sizeof(struct osm_routing_engine));
+	if (!re) {
+		OSM_LOG(&osm->log, OSM_LOG_VERBOSE,
+			"memory allocation failed\n");
+		goto Exit_handle;
+	}
+	memset(re, 0, sizeof(struct osm_routing_engine));
+
+	/* Loading setup function from plugin */
+	routing_plugin =
+	    (osm_routing_plugin_t *) dlsym(handle,
+					   OSM_ROUTING_PLUGIN_IMPL_NAME);
+	if (!routing_plugin) {
+		OSM_LOG(&osm->log, OSM_LOG_ERROR,
+			"Failed to find \"%s\" symbol in \"%s\" : \"%s\"\n",
+			OSM_ROUTING_PLUGIN_IMPL_NAME, lib_name, dlerror());
+		goto Exit;
+	}
+
+	/* Check the version to make sure this module will work with us */
+	if (strcmp(routing_plugin->osm_version, osm->osm_version)) {
+		OSM_LOG(&osm->log, OSM_LOG_ERROR, "Error loading routing plugin"
+			" \'%s\': OpenSM version mismatch - plugin was built"
+			" against %s version of OpenSM. Skip loading.\n",
+			name, routing_plugin->osm_version);
+		goto Exit;
+	}
+
+	/* Check for the setup method */
+	if (!routing_plugin->setup) {
+		OSM_LOG(&osm->log, OSM_LOG_ERROR,
+			"Error loading routing_plugin \'%s\': no setup() method.\n",
+			name);
+		goto Exit;
+	}
+
+	/* Configure routing_engine struct */
+	re->name = strdup(name);
+	if (!re->name) {
+		OSM_LOG(&osm->log, OSM_LOG_VERBOSE,
+			"memory allocation failed\n");
+		goto Exit;
+	}
+	if (routing_plugin->setup(re, osm)) {
+		OSM_LOG(&osm->log, OSM_LOG_VERBOSE,
+			"setup of routing" " engine \'%s\' failed\n", name);
+		goto Exit_name;
+	}
+	re->handle = handle;
+
+	OSM_LOG(&osm->log, OSM_LOG_DEBUG,
+		"\'%s\' routing engine set up\n", re->name);
+	append_routing_engine(osm, re);
+
+	return;
+
+Exit_name:
+	free((char *)re->name);
+Exit:
+	free(re);
+Exit_handle:
+	dlclose(handle);
+	return;
+}
+
+static void setup_routing_engine(osm_opensm_t * osm, const char *name)
 {
 	struct osm_routing_engine *re;
 	const struct routing_engine_module *m;
@@ -182,8 +264,12 @@ static void setup_routing_engine(osm_opensm_t *osm, const char *name)
 		}
 	}
 
+	/* As the algorithm is not in OpenSM, we try to load it using dlopen */
 	OSM_LOG(&osm->log, OSM_LOG_ERROR,
-		"cannot find or setup routing engine \'%s\'\n", name);
+		" \'%s\' is a not a standard OpenSM algorithm. Trying to open it as a routing plugin\n",
+		name);
+	setup_plugin_routing_engine(osm, name);
+
 }
 
 static void setup_routing_engines(osm_opensm_t *osm, const char *engine_names)
@@ -234,6 +320,10 @@ static void destroy_routing_engines(osm_opensm_t *osm)
 		next = r->next;
 		if (r->delete)
 			r->delete(r->context);
+		if (r->handle) {
+			free((char *)r->name);
+			dlclose(r->handle);
+		}
 		free(r);
 	}
 }
-- 
1.6.2.rc1.30.gd43c





More information about the general mailing list