1/* 2 * Copyright (c) 2008 Voltaire, Inc. All rights reserved. 3 * Copyright (c) 2007 The Regents of the University of California. 4 * 5 * This software is available to you under a choice of one of two 6 * licenses. You may choose to be licensed under the terms of the GNU 7 * General Public License (GPL) Version 2, available from the file 8 * COPYING in the main directory of this source tree, or the 9 * OpenIB.org BSD license below: 10 * 11 * Redistribution and use in source and binary forms, with or 12 * without modification, are permitted provided that the following 13 * conditions are met: 14 * 15 * - Redistributions of source code must retain the above 16 * copyright notice, this list of conditions and the following 17 * disclaimer. 18 * 19 * - Redistributions in binary form must reproduce the above 20 * copyright notice, this list of conditions and the following 21 * disclaimer in the documentation and/or other materials 22 * provided with the distribution. 23 * 24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 31 * SOFTWARE. 32 * 33 */ 34 35/****h* OpenSM Event plugin interface 36* DESCRIPTION 37* Database interface to record subnet events 38* 39* Implementations of this object _MUST_ be thread safe. 40* 41* AUTHOR 42* Ira Weiny, LLNL 43* 44*********/ 45 46#if HAVE_CONFIG_H 47# include <config.h> 48#endif /* HAVE_CONFIG_H */ 49 50#include <stdlib.h> 51#include <dlfcn.h> 52#include <opensm/osm_event_plugin.h> 53#include <opensm/osm_opensm.h> 54 55#if defined(PATH_MAX) 56#define OSM_PATH_MAX (PATH_MAX + 1) 57#elif defined (_POSIX_PATH_MAX) 58#define OSM_PATH_MAX (_POSIX_PATH_MAX + 1) 59#else 60#define OSM_PATH_MAX 256 61#endif 62 63/** 64 * functions 65 */ 66osm_epi_plugin_t *osm_epi_construct(osm_opensm_t *osm, char *plugin_name) 67{ 68 char lib_name[OSM_PATH_MAX]; 69 struct old_if { unsigned ver; } *old_impl; 70 osm_epi_plugin_t *rc = NULL; 71 72 if (!plugin_name || !*plugin_name) 73 return (NULL); 74 75 /* find the plugin */ 76 snprintf(lib_name, OSM_PATH_MAX, "lib%s.so", plugin_name); 77 78 rc = malloc(sizeof(*rc)); 79 if (!rc) 80 return (NULL); 81 82 rc->handle = dlopen(lib_name, RTLD_LAZY); 83 if (!rc->handle) { 84 OSM_LOG(&osm->log, OSM_LOG_ERROR, 85 "Failed to open event plugin \"%s\" : \"%s\"\n", 86 lib_name, dlerror()); 87 goto DLOPENFAIL; 88 } 89 90 rc->impl = 91 (osm_event_plugin_t *) dlsym(rc->handle, 92 OSM_EVENT_PLUGIN_IMPL_NAME); 93 if (!rc->impl) { 94 OSM_LOG(&osm->log, OSM_LOG_ERROR, 95 "Failed to find \"%s\" symbol in \"%s\" : \"%s\"\n", 96 OSM_EVENT_PLUGIN_IMPL_NAME, lib_name, dlerror()); 97 goto Exit; 98 } 99 100 /* check for old interface */ 101 old_impl = (struct old_if *) rc->impl; 102 if (old_impl->ver == OSM_ORIG_EVENT_PLUGIN_INTERFACE_VER) { 103 OSM_LOG(&osm->log, OSM_LOG_ERROR, "Error loading plugin: " 104 "\'%s\' contains a depricated interface version %d\n" 105 " Please recompile with the new interface.\n", 106 plugin_name, old_impl->ver); 107 goto Exit; 108 } 109 110 /* Check the version to make sure this module will work with us */ 111 if (strcmp(rc->impl->osm_version, osm->osm_version)) { 112 OSM_LOG(&osm->log, OSM_LOG_ERROR, "Error loading plugin" 113 " \'%s\': OpenSM version mismatch - plugin was built" 114 " against %s version of OpenSM. Skip loading.\n", 115 plugin_name, rc->impl->osm_version); 116 goto Exit; 117 } 118 119 if (!rc->impl->create) { 120 OSM_LOG(&osm->log, OSM_LOG_ERROR, 121 "Error loading plugin \'%s\': no create() method.\n", 122 plugin_name); 123 goto Exit; 124 } 125 126 rc->plugin_data = rc->impl->create(osm); 127 128 if (!rc->plugin_data) 129 goto Exit; 130 131 rc->plugin_name = strdup(plugin_name); 132 return (rc); 133 134Exit: 135 dlclose(rc->handle); 136DLOPENFAIL: 137 free(rc); 138 return (NULL); 139} 140 141void osm_epi_destroy(osm_epi_plugin_t * plugin) 142{ 143 if (plugin) { 144 if (plugin->impl->delete) 145 plugin->impl->delete(plugin->plugin_data); 146 dlclose(plugin->handle); 147 free(plugin->plugin_name); 148 free(plugin); 149 } 150} 151