[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