1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ 2 /* 3 * Copyright (c) 2015 Cisco Systems, Inc. All rights reserved. 4 * Copyright (c) 2015 Los Alamos National Security, LLC. All rights 5 * reserved. 6 * $COPYRIGHT$ 7 * 8 * Additional copyrights may follow 9 * 10 * $HEADER$ 11 */ 12 13 /** 14 * @file 15 * 16 * Dynamic library framework 17 * 18 * General Description: 19 * 20 * This framework provides portable access to dlopen- and dlsym-like 21 * functionality, very similar to Libtool's libltdl. Indeed, one of 22 * the components in this framework will use libltdl, if it is 23 * present/available. However, on some common types systems where 24 * libltdl headers and libraries are *not* available, we can support 25 * plugins via this simple framework. 26 * 27 * This is a compile-time framework: a single component will be 28 * selected by the priority that its configure.m4 provides. All other 29 * components will be ignored (i.e., not built/not part of the 30 * installation). Meaning: the static_components of the dl framework 31 * will always contain 0 or 1 components. 32 * 33 * SIDENOTE: Open MPI used to embed libltdl. However, as of early 34 * 2015, this became problematic, for a variety of complex and 35 * uninteresting reasons (see the following if you care about the 36 * details: https://github.com/open-mpi/ompi/issues/311, 37 * http://debbugs.gnu.org/cgi/bugreport.cgi?bug=19370, 38 * https://github.com/open-mpi/ompi/pull/366, 39 * https://github.com/open-mpi/ompi/pull/390). That being said, we, 40 * as a developer community, still wanted to be able to natively use 41 * DSOs by default. A small/simple framework for DL functionality, 42 * along with a simple component that supports dlopen/dlsym on POSIX 43 * platforms and another component that natively uses libltdl seemed 44 * like a good solution. 45 */ 46 47 #ifndef OPAL_MCA_DL_DL_H 48 #define OPAL_MCA_DL_DL_H 49 50 #include "opal_config.h" 51 52 #include "opal/mca/mca.h" 53 #include "opal/mca/base/base.h" 54 55 BEGIN_C_DECLS 56 57 /** 58 * Handle for an opened file 59 */ 60 struct opal_dl_handle_t; 61 typedef struct opal_dl_handle_t opal_dl_handle_t; 62 63 /** 64 * Dynamically open the file specified. 65 * 66 * Arguments: 67 * fname = Base filename to open. If NULL, open this process. 68 * use_ext = If true, try various filename suffixes that are 69 * relevant on this platform (e.g., .so, .dll, .dylib). If 70 * false, just use exactly whatever was passed as fname. 71 * private = If true, open the file in a private namespace. 72 * Otherwise, open the file in a global namespace. 73 * handle = Upon successful open, a handle to the opened file will 74 * be returned. 75 * err_msg= if non-NULL and !=OPAL_SUCCESS is returned, will point to a 76 * string error message 77 * 78 * Returns: 79 * OPAL_SUCCESS on success, or OPAL_ERROR 80 * 81 * Space for the handle must be allocated by the module (it can be 82 * freed during the call to opal_dl_base_module_dlclose_fn_t). 83 * 84 * The err_msg points to an internal string and should not be altered 85 * or freed by the caller. The contents of the err_msg string may 86 * change after successive calls to opal_dl API calls. 87 */ 88 typedef int (*opal_dl_base_module_open_fn_t) 89 (const char *fname, bool use_ext, bool private_namespace, 90 opal_dl_handle_t **handle, char **err_msg); 91 92 /** 93 * Lookup a symbol in an opened file. 94 * 95 * Arguments: 96 * handle = handle of a previously dynamically opened file 97 * symbol = name of the symbol to lookup 98 * ptr = if found, a pointer to the symbol. Otherwise, NULL. 99 * err_msg= if non-NULL and !=OPAL_SUCCESS is returned, will point to a 100 * string error message 101 * Returns: 102 * OPAL_SUCCESS on success, or OPAL_ERROR 103 * 104 * 105 * The err_msg points to an internal string and should not be altered 106 * or freed by the caller. The contents of the err_msg string may 107 * change after successive calls to opal_dl API calls. 108 */ 109 typedef int (*opal_dl_base_module_lookup_fn_t) 110 (opal_dl_handle_t *handle, const char *symbol, void **ptr, char **err_msg); 111 112 /** 113 * Dynamically close a previously dynamically-opened file. 114 * 115 * Arguments: 116 * handle = handle of a previously dynamically opened file. 117 * Returns: 118 * OPAL_SUCCESS on success, or OPAL_ERROR 119 * 120 * This function should close the file and free and resources 121 * associated with it (e.g., whatever is cached on the handle). 122 */ 123 typedef int (*opal_dl_base_module_close_fn_t) 124 (opal_dl_handle_t *handle); 125 126 /** 127 * Search through a path of directories, invoking a callback on each 128 * unique regular (non-Libtool) file basename found (e.g., will only 129 * be invoked once for the files "foo.la" and "foo.so", with the 130 * parameter "foo"). 131 * 132 * Arguments: 133 * path = OPAL_ENV_SEP-delimited list of directories 134 * cb_func= function to invoke on each filename found 135 * data = context for callback function 136 * Returns: 137 * OPAL_SUCESS on success, OPAL_ERR* otherwise 138 */ 139 typedef int (*opal_dl_base_module_foreachfile_fn_t) 140 (const char *search_path, 141 int (*cb_func)(const char *filename, void *context), 142 void *context); 143 144 /** 145 * Structure for DL components. 146 */ 147 struct opal_dl_base_component_1_0_0_t { 148 /** MCA base component */ 149 mca_base_component_t base_version; 150 /** MCA base data */ 151 mca_base_component_data_t base_data; 152 153 /** Default priority */ 154 int priority; 155 }; 156 typedef struct opal_dl_base_component_1_0_0_t opal_dl_base_component_1_0_0_t; 157 typedef struct opal_dl_base_component_1_0_0_t opal_dl_base_component_t; 158 159 /** 160 * Structure for DL modules 161 */ 162 struct opal_dl_base_module_1_0_0_t { 163 mca_base_module_2_0_0_t super; 164 165 /** Open / close */ 166 opal_dl_base_module_open_fn_t open; 167 opal_dl_base_module_close_fn_t close; 168 169 /** Lookup a symbol */ 170 opal_dl_base_module_lookup_fn_t lookup; 171 172 /** Iterate looking for files */ 173 opal_dl_base_module_foreachfile_fn_t foreachfile; 174 }; 175 typedef struct opal_dl_base_module_1_0_0_t opal_dl_base_module_1_0_0_t; 176 typedef struct opal_dl_base_module_1_0_0_t opal_dl_base_module_t; 177 178 /** 179 * Macro for use in components that are of type DL 180 */ 181 #define OPAL_DL_BASE_VERSION_1_0_0 \ 182 OPAL_MCA_BASE_VERSION_2_1_0("dl", 1, 0, 0) 183 184 END_C_DECLS 185 186 #endif /* OPAL_MCA_DL_DL_H */