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 */ 68 osm_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 136 Exit: 137 dlclose(rc->handle); 138 DLOPENFAIL: 139 free(rc); 140 return NULL; 141 } 142 143 void 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