1/* 2 * Copyright (c) 2008-2009 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_file_ids.h> 53#define FILE_ID OSM_FILE_EVENT_PLUGIN_C 54#include <opensm/osm_event_plugin.h> 55#include <opensm/osm_opensm.h> 56 57#if defined(PATH_MAX) 58#define OSM_PATH_MAX (PATH_MAX + 1) 59#elif defined (_POSIX_PATH_MAX) 60#define OSM_PATH_MAX (_POSIX_PATH_MAX + 1) 61#else 62#define OSM_PATH_MAX 256 63#endif 64 65/** 66 * functions 67 */ 68osm_epi_plugin_t *osm_epi_construct(osm_opensm_t *osm, char *plugin_name) 69{ 70 char lib_name[OSM_PATH_MAX]; 71 struct old_if { unsigned ver; } *old_impl; 72 osm_epi_plugin_t *rc = NULL; 73 74 if (!plugin_name || !*plugin_name) 75 return NULL; 76 77 /* find the plugin */ 78 snprintf(lib_name, sizeof(lib_name), "lib%s.so", plugin_name); 79 80 rc = malloc(sizeof(*rc)); 81 if (!rc) 82 return NULL; 83 84 rc->handle = dlopen(lib_name, RTLD_LAZY); 85 if (!rc->handle) { 86 OSM_LOG(&osm->log, OSM_LOG_ERROR, 87 "Failed to open event plugin \"%s\" : \"%s\"\n", 88 lib_name, dlerror()); 89 goto DLOPENFAIL; 90 } 91 92 rc->impl = 93 (osm_event_plugin_t *) dlsym(rc->handle, 94 OSM_EVENT_PLUGIN_IMPL_NAME); 95 if (!rc->impl) { 96 OSM_LOG(&osm->log, OSM_LOG_ERROR, 97 "Failed to find \"%s\" symbol in \"%s\" : \"%s\"\n", 98 OSM_EVENT_PLUGIN_IMPL_NAME, lib_name, dlerror()); 99 goto Exit; 100 } 101 102 /* check for old interface */ 103 old_impl = (struct old_if *) rc->impl; 104 if (old_impl->ver == OSM_ORIG_EVENT_PLUGIN_INTERFACE_VER) { 105 OSM_LOG(&osm->log, OSM_LOG_ERROR, "Error loading plugin: " 106 "\'%s\' contains a depricated interface version %d\n" 107 " Please recompile with the new interface.\n", 108 plugin_name, old_impl->ver); 109 goto Exit; 110 } 111 112 /* Check the version to make sure this module will work with us */ 113 if (strcmp(rc->impl->osm_version, osm->osm_version)) { 114 OSM_LOG(&osm->log, OSM_LOG_ERROR, "Error loading plugin" 115 " \'%s\': OpenSM version mismatch - plugin was built" 116 " against %s version of OpenSM. Skip loading.\n", 117 plugin_name, rc->impl->osm_version); 118 goto Exit; 119 } 120 121 if (!rc->impl->create) { 122 OSM_LOG(&osm->log, OSM_LOG_ERROR, 123 "Error loading plugin \'%s\': no create() method.\n", 124 plugin_name); 125 goto Exit; 126 } 127 128 rc->plugin_data = rc->impl->create(osm); 129 130 if (!rc->plugin_data) 131 goto Exit; 132 133 rc->plugin_name = strdup(plugin_name); 134 return rc; 135 136Exit: 137 dlclose(rc->handle); 138DLOPENFAIL: 139 free(rc); 140 return NULL; 141} 142 143void osm_epi_destroy(osm_epi_plugin_t * plugin) 144{ 145 if (plugin) { 146 if (plugin->impl->delete) 147 plugin->impl->delete(plugin->plugin_data); 148 dlclose(plugin->handle); 149 free(plugin->plugin_name); 150 free(plugin); 151 } 152} 153