/[pdpsoft]/trunk/grid-mw-security/ees/src/plugin_manager/plugin_manager.c
ViewVC logotype

Contents of /trunk/grid-mw-security/ees/src/plugin_manager/plugin_manager.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1145 - (show annotations) (download) (as text)
Thu Nov 19 14:40:54 2009 UTC (12 years, 2 months ago) by aramv
File MIME type: text/x-chdr
File size: 9124 byte(s)
Managed to build a tree of pointers to plugins in the plugin manager. The plugin tree is based on the string-based tree the parser has created
1 #include "plugin_manager.h"
2 #include "_plugin_manager.h"
3
4 /** Starts the plugin manager (only initializes values to NULL)
5 */
6 EES_RC start_plugin_manager(){
7 plugin_list = NULL;
8 _running_plugin = NULL;
9 return EES_SUCCESS;
10 }
11
12 /** Prepares the supplied plugin by name, initializes the struct with these values
13 * \post the plugin node is ready to be passed to the initialize_plugin function
14 */
15 eef_plugindl_t * prepare_plugin(int argc, char** argv){
16 eef_plugindl_t * current_plugin = NULL;
17 int i = 0;
18
19 /* current plugin struct */
20 if((current_plugin = calloc(1,sizeof(eef_plugindl_t)))){
21
22 strncpy(current_plugin->pluginname, argv[0], FILENAME_MAX);
23 current_plugin->init_argc = argc;
24 for(i = 0; i < argc; i++){
25 current_plugin->init_argv[i] = (char*) strdup(argv[i]);
26 }
27 current_plugin->next = NULL;
28
29 /* cleanup */
30 for(i = 0; i < argc; i++){
31 free(argv[i]);
32 }
33 free(argv);
34
35 /* print information */
36 /*print_eef_plugin(LOG_DEBUG, current_plugin);*/
37
38 /* return plugin struct */
39 return current_plugin;
40 }
41 return NULL;
42 }
43
44 /** Calls prepare_plugin() to build a plugin struct and adds it to the plugin_list
45 */
46 EES_RC add_plugin(int argc, char* argv[]){
47 eef_plugindl_t *last_plugin = NULL, *current_plugin = NULL;
48 /* prepare_plugin returns NULL if plugin failed to load. */
49 if((current_plugin = prepare_plugin(argc, argv)) != NULL){
50 /* append plugin to the end of the list */
51 if(plugin_list == NULL){
52 plugin_list = current_plugin;
53 } else {
54 last_plugin = plugin_list;
55 /* TODO don't iterate list */
56 while(last_plugin->next != NULL){
57 last_plugin = last_plugin->next;
58 }
59 last_plugin->next = current_plugin;
60 }
61 /*print_eef_plugin(LOG_INFO, current_plugin);*/
62 return EES_SUCCESS;
63 }
64 return EES_FAILURE;
65 }
66
67 /** Wrapper for dlsym with error logging. Adapted from lcmaps_pluginmanager.c get_procsymbol
68 */
69 eef_proc_t get_procsymbol(void* handle, char* symname){
70 eef_proc_t symhandle;
71 char* errstring;
72
73 /* dlsym returns void pointer (data pointer) whereas we need to cast to a function pointer.
74 This is a known problem. See: http://www.opengroup.org/onlinepubs/009695399/functions/dlsym.html#tag_03_112_08
75 Although gcc will produce a warning this seems to work on most platforms
76 */
77 symhandle = dlsym(handle,symname);
78
79 if((errstring = dlerror()) != NULL){
80 eef_log(0, "ees.get_procsymbol(): dlsym error %s\n", errstring);
81 return NULL;
82 }
83
84 return symhandle;
85 }
86
87 /** Returns a plugin from the list by name, or NULL if not found
88 */
89 eef_plugindl_t* get_plugin(char* plugin_name){
90 eef_plugindl_t * current_plugin = plugin_list;
91 /* iterate plugin_list until plugin is found */
92 while(current_plugin != NULL){
93 if(strcmp(current_plugin->pluginname, plugin_name) == 0){
94 return current_plugin;
95 }
96 current_plugin = current_plugin->next;
97 }
98 return NULL;
99 }
100
101 /* Initializes all the plugins
102 * Returns EES_SUCCESS or EES_FAILURE if a plugin failed to load.*/
103 EES_RC initialize_plugins(){
104 eef_plugindl_t* node = plugin_list;
105 local_module_dir = get_modules_path();
106 while(node != NULL){
107 if(initialize_plugin(node) == EES_FAILURE){
108 return EES_FAILURE;
109 }
110 node = node->next;
111 }
112 return EES_SUCCESS;
113 }
114
115 /** Initializes the supplied plugin node, which already holds the plugin name and arguments
116 * \post the plugin node is initialized and its functions are linked and accessible
117 */
118 EES_RC initialize_plugin(eef_plugindl_t* plugin){
119 size_t max_plugin_name = FILENAME_MAX - strlen(local_module_dir);
120 eef_log(LOG_DEBUG, "Using modules path: %s\n", local_module_dir);
121
122 if(strlen(local_module_dir) >= FILENAME_MAX){
123 return EES_FAILURE;
124 }
125 memset(abs_plugin_path, 0, FILENAME_MAX);
126
127 /*TODO make safer */
128 if(!(strncat(abs_plugin_path, local_module_dir, strlen(local_module_dir)) && \
129 strncat(abs_plugin_path, plugin->init_argv[0], max_plugin_name)
130 /*&& strcat(abs_plugin_path, ".mod")*/
131 )){
132 return EES_FAILURE;
133 }
134
135 eef_log(LOG_DEBUG, "Loading plugin %s\n", abs_plugin_path);
136
137 /* load plugin handle */
138 plugin->handle = dlopen(abs_plugin_path, RTLD_NOW);
139
140 if(!plugin->handle){
141 eef_log(LOG_ERR, "Failed to acquire handle on plugin: %s\n", abs_plugin_path);
142 eef_log(LOG_ERR, "%s\n", dlerror());
143 return EES_FAILURE;
144 }
145
146 eef_log(LOG_DEBUG,"Linking plugin: %s\n", abs_plugin_path);
147
148 plugin->procs[INITPROC] = NULL;
149 plugin->procs[RUNPROC] = NULL;
150 plugin->procs[TERMPROC] = NULL;
151
152 /* link function pointers */
153 plugin->procs[INITPROC] = get_procsymbol(plugin->handle, "plugin_initialize");
154 if(plugin->procs[INITPROC] == NULL){
155 eef_log(LOG_ERR,"ees.mod-PluginInit(): plugin %s not compliant\n", plugin->pluginname);
156 return EES_FAILURE;
157 }
158
159 plugin->procs[RUNPROC] = get_procsymbol(plugin->handle, "plugin_run");
160 if(plugin->procs[RUNPROC] == NULL){
161 eef_log(LOG_ERR, "ees.runPlugin\n");
162 return EES_FAILURE;
163 }
164
165 plugin->procs[TERMPROC] = get_procsymbol(plugin->handle, "plugin_terminate");
166 if(plugin->procs[TERMPROC] == NULL){
167 eef_log(LOG_ERR, "ees.termPlugin\n");
168 return EES_FAILURE;
169 }
170
171 set_running_plugin(plugin);
172
173 init_fnc_ptr = plugin->procs[INITPROC];
174 /* call function pointer */
175 if(init_fnc_ptr(plugin->init_argc, plugin->init_argv) == EES_PL_SUCCESS){
176 return EES_SUCCESS;
177 } else {
178 eef_log(LOG_ERR, "Failed to initialize plugin %s\n", abs_plugin_path);
179 }
180
181 bzero(abs_plugin_path, strlen(abs_plugin_path) + 1);
182
183 return EES_FAILURE;
184 }
185
186 /* Runs all the plugins
187 * Returns EES_SUCCESS if a plugin branch executed successfully.*/
188 EES_RC run_plugins(void){
189 eef_plugindl_t *node = plugin_list;
190 while(node != NULL){
191 if(run_plugin(node->pluginname) == EES_FAILURE){
192 return EES_FAILURE;
193 }
194 node = node->next;
195 }
196 return EES_SUCCESS;
197 }
198
199 /** Calls the plugin's run method
200 */
201 EES_RC run_plugin(char* plugin_name){
202 eef_plugindl_t * current_plugin;
203 current_plugin = get_plugin(plugin_name);
204 run_fnc_ptr = current_plugin->procs[RUNPROC];
205 eef_log(LOG_DEBUG, "Run method for %s linked at %p\n", plugin_name, run_fnc_ptr);
206 set_running_plugin(current_plugin);
207 run_fnc_ptr();
208 return EES_SUCCESS;
209 }
210
211 /* Terminates all the plugins
212 * Returns EES_SUCCESS if all plugins terminated successfully.*/
213 EES_RC term_plugins(void){
214 eef_plugindl_t *node = plugin_list;
215 while(node != NULL){
216 if(term_plugin(node->pluginname) == EES_FAILURE){
217 return EES_FAILURE;
218 }
219 node = node->next;
220 }
221 return EES_SUCCESS;
222 }
223
224 /** Calls the plugin's term method
225 */
226 EES_RC term_plugin(char* plugin_name){
227 eef_plugindl_t * current_plugin;
228 current_plugin = get_plugin(plugin_name);
229 term_fnc_ptr = current_plugin->procs[TERMPROC];
230 eef_log(LOG_DEBUG, "Run method for %s linked at %p\n", plugin_name, term_fnc_ptr);
231 set_running_plugin(current_plugin);
232 term_fnc_ptr();
233 return EES_SUCCESS;
234 }
235
236 /** Stops the plugin manager, calling clean_plugin_list
237 */
238 EES_RC stop_plugin_manager(){
239 if((term_plugins() == EES_SUCCESS) && (clean_plugin_list(plugin_list) == EES_SUCCESS)){
240 return EES_SUCCESS;
241 }
242 return EES_FAILURE;
243 }
244
245 /** Cleans the list of plugins, unlinking all the dlopened modules and freeing the structs
246 * \post The plugin list is empty
247 */
248 EES_RC clean_plugin_list(eef_plugindl_t * list){
249 eef_plugindl_t * plugin_entry=NULL;
250 eef_plugindl_t * plugin_next=NULL;
251 int i;
252 plugin_entry=list;
253
254 /* iterate plugin_list */
255 while(plugin_entry!=NULL){
256 if(plugin_entry->handle != NULL){
257 /* Valgrind can't trace modules past their dlclose-ing. See: http://valgrind.org/docs/manual/faq.html#faq.unhelpful */
258 if(!getenv("VALGRIND")){
259 if((dlclose(plugin_entry->handle))){
260 eef_log(0, "dlclose error %s while cleaning up plugin list\n", dlerror());
261 return EES_FAILURE;
262 }
263 } else {
264 eef_log(LOG_DEBUG, "Running in valgrind, not dlclose'ing plugins\n");
265 }
266 }
267
268 /* free argv array */
269 for(i = 0; i < plugin_entry->init_argc; i++){
270 free(plugin_entry->init_argv[i]);
271 }
272
273 /* free current struct and move to next plugin */
274 plugin_next = plugin_entry->next;
275 free(plugin_entry);
276 plugin_entry = plugin_next;
277 }
278 return EES_SUCCESS;
279 }
280
281
282 /** Prints the information from the plugin struct to the eef_log function with a specified debug level
283 */
284 EES_RC print_eef_plugin(int debug_lvl, eef_plugindl_t *plugin){
285 int i = 0;
286 /*eef_log(debug_lvl, "plugin name : %s\n", plugin->pluginname);*/
287 /*eef_log(debug_lvl, "plugin argc : %i\n", plugin->init_argc);*/
288 for(i = 1; i < plugin->init_argc; i++){
289 eef_log(debug_lvl, "plugin %s: argv[%i] : %s\n", plugin->init_argv[0] , i, plugin->init_argv[i]);
290 }
291 return EES_SUCCESS;
292 }
293
294 /** Internal method to keep track of which plugin is currently executing (used by AOS to determine ownership of data)
295 */
296 eef_plugindl_t * get_running_plugin(){
297 return _running_plugin;
298 }
299
300 /** Internal method to keep track of which plugin is currently executing
301 */
302 void set_running_plugin(eef_plugindl_t * plugin){
303 _running_plugin = plugin;
304 }
305

grid.support@nikhef.nl
ViewVC Help
Powered by ViewVC 1.1.28