* 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 <[email protected]>
---
 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


_______________________________________________
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