1219820Sjeff/* 2219820Sjeff * Copyright (c) 2008 Voltaire, Inc. All rights reserved. 3219820Sjeff * Copyright (c) 2007 The Regents of the University of California. 4219820Sjeff * 5219820Sjeff * This software is available to you under a choice of one of two 6219820Sjeff * licenses. You may choose to be licensed under the terms of the GNU 7219820Sjeff * General Public License (GPL) Version 2, available from the file 8219820Sjeff * COPYING in the main directory of this source tree, or the 9219820Sjeff * OpenIB.org BSD license below: 10219820Sjeff * 11219820Sjeff * Redistribution and use in source and binary forms, with or 12219820Sjeff * without modification, are permitted provided that the following 13219820Sjeff * conditions are met: 14219820Sjeff * 15219820Sjeff * - Redistributions of source code must retain the above 16219820Sjeff * copyright notice, this list of conditions and the following 17219820Sjeff * disclaimer. 18219820Sjeff * 19219820Sjeff * - Redistributions in binary form must reproduce the above 20219820Sjeff * copyright notice, this list of conditions and the following 21219820Sjeff * disclaimer in the documentation and/or other materials 22219820Sjeff * provided with the distribution. 23219820Sjeff * 24219820Sjeff * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 25219820Sjeff * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 26219820Sjeff * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 27219820Sjeff * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 28219820Sjeff * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 29219820Sjeff * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 30219820Sjeff * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 31219820Sjeff * SOFTWARE. 32219820Sjeff * 33219820Sjeff */ 34219820Sjeff 35219820Sjeff/****h* OpenSM Event plugin interface 36219820Sjeff* DESCRIPTION 37219820Sjeff* Database interface to record subnet events 38219820Sjeff* 39219820Sjeff* Implementations of this object _MUST_ be thread safe. 40219820Sjeff* 41219820Sjeff* AUTHOR 42219820Sjeff* Ira Weiny, LLNL 43219820Sjeff* 44219820Sjeff*********/ 45219820Sjeff 46219820Sjeff#if HAVE_CONFIG_H 47219820Sjeff# include <config.h> 48219820Sjeff#endif /* HAVE_CONFIG_H */ 49219820Sjeff 50219820Sjeff#include <stdlib.h> 51219820Sjeff#include <dlfcn.h> 52219820Sjeff#include <opensm/osm_event_plugin.h> 53219820Sjeff#include <opensm/osm_opensm.h> 54219820Sjeff 55219820Sjeff#if defined(PATH_MAX) 56219820Sjeff#define OSM_PATH_MAX (PATH_MAX + 1) 57219820Sjeff#elif defined (_POSIX_PATH_MAX) 58219820Sjeff#define OSM_PATH_MAX (_POSIX_PATH_MAX + 1) 59219820Sjeff#else 60219820Sjeff#define OSM_PATH_MAX 256 61219820Sjeff#endif 62219820Sjeff 63219820Sjeff/** 64219820Sjeff * functions 65219820Sjeff */ 66219820Sjeffosm_epi_plugin_t *osm_epi_construct(osm_opensm_t *osm, char *plugin_name) 67219820Sjeff{ 68219820Sjeff char lib_name[OSM_PATH_MAX]; 69219820Sjeff struct old_if { unsigned ver; } *old_impl; 70219820Sjeff osm_epi_plugin_t *rc = NULL; 71219820Sjeff 72219820Sjeff if (!plugin_name || !*plugin_name) 73219820Sjeff return (NULL); 74219820Sjeff 75219820Sjeff /* find the plugin */ 76219820Sjeff snprintf(lib_name, OSM_PATH_MAX, "lib%s.so", plugin_name); 77219820Sjeff 78219820Sjeff rc = malloc(sizeof(*rc)); 79219820Sjeff if (!rc) 80219820Sjeff return (NULL); 81219820Sjeff 82219820Sjeff rc->handle = dlopen(lib_name, RTLD_LAZY); 83219820Sjeff if (!rc->handle) { 84219820Sjeff OSM_LOG(&osm->log, OSM_LOG_ERROR, 85219820Sjeff "Failed to open event plugin \"%s\" : \"%s\"\n", 86219820Sjeff lib_name, dlerror()); 87219820Sjeff goto DLOPENFAIL; 88219820Sjeff } 89219820Sjeff 90219820Sjeff rc->impl = 91219820Sjeff (osm_event_plugin_t *) dlsym(rc->handle, 92219820Sjeff OSM_EVENT_PLUGIN_IMPL_NAME); 93219820Sjeff if (!rc->impl) { 94219820Sjeff OSM_LOG(&osm->log, OSM_LOG_ERROR, 95219820Sjeff "Failed to find \"%s\" symbol in \"%s\" : \"%s\"\n", 96219820Sjeff OSM_EVENT_PLUGIN_IMPL_NAME, lib_name, dlerror()); 97219820Sjeff goto Exit; 98219820Sjeff } 99219820Sjeff 100219820Sjeff /* check for old interface */ 101219820Sjeff old_impl = (struct old_if *) rc->impl; 102219820Sjeff if (old_impl->ver == OSM_ORIG_EVENT_PLUGIN_INTERFACE_VER) { 103219820Sjeff OSM_LOG(&osm->log, OSM_LOG_ERROR, "Error loading plugin: " 104219820Sjeff "\'%s\' contains a depricated interface version %d\n" 105219820Sjeff " Please recompile with the new interface.\n", 106219820Sjeff plugin_name, old_impl->ver); 107219820Sjeff goto Exit; 108219820Sjeff } 109219820Sjeff 110219820Sjeff /* Check the version to make sure this module will work with us */ 111219820Sjeff if (strcmp(rc->impl->osm_version, osm->osm_version)) { 112219820Sjeff OSM_LOG(&osm->log, OSM_LOG_ERROR, "Error loading plugin" 113219820Sjeff " \'%s\': OpenSM version mismatch - plugin was built" 114219820Sjeff " against %s version of OpenSM. Skip loading.\n", 115219820Sjeff plugin_name, rc->impl->osm_version); 116219820Sjeff goto Exit; 117219820Sjeff } 118219820Sjeff 119219820Sjeff if (!rc->impl->create) { 120219820Sjeff OSM_LOG(&osm->log, OSM_LOG_ERROR, 121219820Sjeff "Error loading plugin \'%s\': no create() method.\n", 122219820Sjeff plugin_name); 123219820Sjeff goto Exit; 124219820Sjeff } 125219820Sjeff 126219820Sjeff rc->plugin_data = rc->impl->create(osm); 127219820Sjeff 128219820Sjeff if (!rc->plugin_data) 129219820Sjeff goto Exit; 130219820Sjeff 131219820Sjeff rc->plugin_name = strdup(plugin_name); 132219820Sjeff return (rc); 133219820Sjeff 134219820SjeffExit: 135219820Sjeff dlclose(rc->handle); 136219820SjeffDLOPENFAIL: 137219820Sjeff free(rc); 138219820Sjeff return (NULL); 139219820Sjeff} 140219820Sjeff 141219820Sjeffvoid osm_epi_destroy(osm_epi_plugin_t * plugin) 142219820Sjeff{ 143219820Sjeff if (plugin) { 144219820Sjeff if (plugin->impl->delete) 145219820Sjeff plugin->impl->delete(plugin->plugin_data); 146219820Sjeff dlclose(plugin->handle); 147219820Sjeff free(plugin->plugin_name); 148219820Sjeff free(plugin); 149219820Sjeff } 150219820Sjeff} 151