OSDN Git Service

Update INSTALL.ja.utf-8 for new release.
[ultramonkey-l7/ultramonkey-l7-v2.git] / src / module.c
1 /*
2  * @file  module.c
3  * @brief the framework module of manage shared object 
4  * @brief it enables dynamic loading of shared object 
5  *
6  * L7VSD: Linux Virtual Server for Layer7 Load Balancing
7  * Copyright (C) 2005  NTT COMWARE Corporation.
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22  * 02110-1301 USA
23  *
24  **********************************************************************/
25
26 #ifndef _GNU_SOURCE
27 #define _GNU_SOURCE
28 #endif /* _GNU_SOURCE */
29
30 #include <sys/param.h>
31 #include <sys/types.h>
32 #include <dlfcn.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <glib.h>
36 #include "logger_wrapper.h"
37 #include "l7vs_module.h"
38 #include "l7vs.h"
39
40 #define L7VS_MODULE_INITFN            "init"
41
42 #if defined(LOGGER_PROCESS_VSD)
43 const LOG_CATEGORY_TAG loggerCategory = LOG_CAT_L7VSD_MODULE;
44 const LOG_CATEGORY_TAG loggerCategorySysMem = LOG_CAT_L7VSD_SYSTEM_MEMORY;
45 #else
46 const LOG_CATEGORY_TAG loggerCategory = LOG_CAT_L7VSADM_MODULE;
47 const LOG_CATEGORY_TAG loggerCategorySysMem = LOG_CAT_L7VSADM_COMMON;
48 #endif
49
50 char l7vs_module_path[MAXPATHLEN];
51
52 /*!
53  * Module initialize function.
54  * @param modpath [in] Module directory path.
55  * @retval 0  Success.
56  * @retval -1 Module directory path string is too long.
57  */
58 int
59 l7vs_module_init(char *modpath)
60 {
61         int return_value = 0;
62
63         /*-------- DEBUG LOG --------*/
64         if( LOG_LV_DEBUG == logger_get_log_level( loggerCategory ) ){
65                 LOGGER_PUT_LOG_DEBUG(loggerCategory,1,
66                     "in_function: int l7vs_module_init(void* modpath): modpath=\"%s\"", modpath);
67         }
68         /*------ DEBUG LOG END ------*/
69
70         if (modpath == NULL) {
71                 strcpy(l7vs_module_path, L7VS_MODULE_PATH);
72         } else {
73                 if (strlen(modpath) > sizeof(l7vs_module_path) - 1) {
74                         return_value = -1;
75                         goto init_out;
76                 }
77                 strcpy(l7vs_module_path, modpath);
78         }
79
80 init_out:
81         /*-------- DEBUG LOG --------*/
82         if( LOG_LV_DEBUG == logger_get_log_level( loggerCategory ) ){
83                 LOGGER_PUT_LOG_DEBUG(loggerCategory,2,
84                     "out_function: int l7vs_module_init(void* modpath): return_value=%d", return_value);
85         }
86         /*------ DEBUG LOG END ------*/
87
88         return return_value;
89 }
90
91 /*!
92  * Module finalize function.
93  */
94 void
95 l7vs_module_fini(void)
96 {
97         /*-------- DEBUG LOG --------*/
98         if( LOG_LV_DEBUG == logger_get_log_level( loggerCategory ) ){
99                 LOGGER_PUT_LOG_DEBUG(loggerCategory,3,
100                     "in_function: void l7vs_module_fini(void)");
101         }
102         /*------ DEBUG LOG END ------*/
103
104         /*-------- DEBUG LOG --------*/
105         if( LOG_LV_DEBUG == logger_get_log_level( loggerCategory ) ){
106                 LOGGER_PUT_LOG_DEBUG(loggerCategory,4,
107                     "out_function: void l7vs_module_fini(void)");
108         }
109         /*------ DEBUG LOG END ------*/
110 }
111
112 /*!
113  * Module load function.
114  * @param modname [in] Module name.
115  * @param type [in] Module type(protomod or sched).
116  * @retern Loaded module struct.
117  */
118 void *
119 l7vs_module_load(char *modname, char *type)
120 {
121         void* h;
122         void* modhandle;
123         char* modpath;
124         void* (*initf)(void *);
125         void* return_value = NULL;
126
127         /*-------- DEBUG LOG --------*/
128         if( LOG_LV_DEBUG == logger_get_log_level( loggerCategory ) ){
129                 LOGGER_PUT_LOG_DEBUG(loggerCategory,5,
130                     "in_function: void* l7vs_module_load(char* modname, char* type): modname=\"%s\", type=\"%s\"",
131                     modname, type);
132         }
133         /*------ DEBUG LOG END ------*/
134
135         /* check null */
136         if (modname == NULL) {
137                 LOGGER_PUT_LOG_ERROR(loggerCategory,1,
138                     "Arg(modname) is NULL pointer.");
139                 goto load_out;
140         }
141         if (type == NULL) {
142                 LOGGER_PUT_LOG_ERROR(loggerCategory,2,
143                     "Arg(type) is NULL pointer.");
144                 goto load_out;
145         }
146
147         modpath = (char *) malloc(strlen(l7vs_module_path) + strlen(type) + strlen(modname) + 6);
148
149         /*-------- DEBUG LOG --------*/
150         if( LOG_LV_DEBUG == logger_get_log_level( loggerCategorySysMem ) ){
151                 LOGGER_PUT_LOG_DEBUG(loggerCategorySysMem,11, "malloc: addr=%p, size=%ld",
152                     modpath, (unsigned long int) strlen(l7vs_module_path) + strlen(type) + strlen(modname) + 6);
153         }
154         /*------ DEBUG LOG END ------*/
155
156         if (modpath == NULL) {
157                 LOGGER_PUT_LOG_ERROR(loggerCategorySysMem,15,
158                     "Could not allocate memory.");
159                 goto load_out;
160         }
161         sprintf(modpath, "%s/%s_%s.so", l7vs_module_path, type, modname);
162
163         h = dlopen(modpath, RTLD_LAZY);
164         if (h == NULL) {
165                 LOGGER_PUT_LOG_ERROR(loggerCategory,3,
166                     "Could not open %s module: %s", modpath, dlerror());
167
168                 /*-------- DEBUG LOG --------*/
169                 if( LOG_LV_DEBUG == logger_get_log_level( loggerCategorySysMem ) ){
170                         LOGGER_PUT_LOG_DEBUG(loggerCategorySysMem,12, "free: %p", modpath);
171                 }
172                 /*------ DEBUG LOG END ------*/
173
174                 free(modpath);
175                 modpath = NULL;
176                 goto load_out;
177         }
178
179         /*-------- DEBUG LOG --------*/
180         if( LOG_LV_DEBUG == logger_get_log_level( loggerCategorySysMem ) ){
181                 LOGGER_PUT_LOG_DEBUG(loggerCategorySysMem,13, "free: %p", modpath);
182         }
183         /*------ DEBUG LOG END ------*/
184
185         free(modpath);
186         modpath = NULL;
187
188         *(void **) (&initf) = dlsym(h, L7VS_MODULE_INITFN);
189         if (initf == NULL) {
190                 LOGGER_PUT_LOG_ERROR(loggerCategory,4,
191                     "Could not find symbol %s: %s", L7VS_MODULE_INITFN, dlerror());
192                 dlclose(h);
193                 goto load_out;
194         }
195
196         modhandle = (*initf)(h);
197         if (modhandle == NULL) {
198                 LOGGER_PUT_LOG_ERROR(loggerCategory,5,
199                     "Module initialization failed.");
200                 dlclose(h);
201                 goto load_out;
202         }
203
204         return_value = modhandle;
205
206 load_out:
207         /*-------- DEBUG LOG --------*/
208         if( LOG_LV_DEBUG == logger_get_log_level( loggerCategory ) ){
209                 LOGGER_PUT_LOG_DEBUG(loggerCategory,6,
210                     "out_function: void* l7vs_module_load(char* modname, char* type): return_value=%p",
211                     return_value);
212         }
213         /*------ DEBUG LOG END ------*/
214
215         return return_value;
216 }
217
218 /*!
219  * Module unload function.
220  * @param handle [in] Module handle.
221  */
222 void
223 l7vs_module_unload(void *handle)
224 {
225         /*-------- DEBUG LOG --------*/
226         if( LOG_LV_DEBUG == logger_get_log_level( loggerCategory ) ){
227                 LOGGER_PUT_LOG_DEBUG(loggerCategory,7,
228                     "in_function: void l7vs_module_unload(void* handle): handle=%p", handle);
229         }
230         /*------ DEBUG LOG END ------*/
231
232         /* check null */
233         if (handle == NULL) {
234                 LOGGER_PUT_LOG_ERROR(loggerCategory,6,
235                     "Arg(handle) is NULL pointer.");
236                 goto unload_out;
237         }
238         dlclose(handle);
239
240 unload_out:
241         /*-------- DEBUG LOG --------*/
242         if( LOG_LV_DEBUG == logger_get_log_level( loggerCategory ) ){
243                 LOGGER_PUT_LOG_DEBUG(loggerCategory,8,
244                     "out_function: void l7vs_module_unload(void* handle)");
245         }
246         /*------ DEBUG LOG END ------*/
247 }
248
249 /*!
250  * Register module to list function.
251  * @param modlist [in,out] Registerd module list.
252  * @param mod [in] Loaded module.
253  */
254 void
255 l7vs_module_register(GList **modlist, void *mod)
256 {
257         /*-------- DEBUG LOG --------*/
258         if( LOG_LV_DEBUG == logger_get_log_level( loggerCategory ) ){
259                 LOGGER_PUT_LOG_DEBUG(loggerCategory,9,
260                     "in_function: void l7vs_module_register(GList** modlist, void* mod): "
261                     "modlist=%p, mod=%p", modlist, mod);
262         }
263         /*------ DEBUG LOG END ------*/
264
265         /* check null */
266         if (modlist == NULL) {
267                 LOGGER_PUT_LOG_ERROR(loggerCategory,7,
268                     "Arg(modlist) is NULL pointer.");
269                 goto register_out;
270         }
271         if (mod == NULL) {
272                 LOGGER_PUT_LOG_ERROR(loggerCategory,8,
273                     "Arg(mod) is NULL pointer.");
274                 goto register_out;
275         }
276         *modlist = g_list_append(*modlist, (gpointer)mod);
277
278 register_out:
279         /*-------- DEBUG LOG --------*/
280         if( LOG_LV_DEBUG == logger_get_log_level( loggerCategory ) ){
281                 LOGGER_PUT_LOG_DEBUG(loggerCategory,10,
282                     "out_function: void l7vs_module_register(GList** modlist, void* mod)");
283         }
284         /*------ DEBUG LOG END ------*/
285 }
286
287 /*!
288  * Remove module from list function.
289  * @param modlist [in,out] Registerd module list.
290  * @param mod [in] Loaded module.
291  */
292 void
293 l7vs_module_remove(GList **modlist, void *mod)
294 {
295         /*-------- DEBUG LOG --------*/
296         if( LOG_LV_DEBUG == logger_get_log_level( loggerCategory ) ){
297                 LOGGER_PUT_LOG_DEBUG(loggerCategory,11,
298                     "in_function: void l7vs_module_remove(GList** modlist, void* mod): "
299                     "modlist=%p, mod=%p", modlist, mod);
300         }
301         /*------ DEBUG LOG END ------*/
302
303         /* check null */
304         if (modlist == NULL) {
305                 LOGGER_PUT_LOG_ERROR(loggerCategory,9,
306                     "Arg(modlist) is NULL pointer.");
307                 goto remove_out;
308         }
309         if (mod == NULL) {
310                 LOGGER_PUT_LOG_ERROR(loggerCategory,10,
311                     "Arg(mod) is NULL pointer.");
312                 goto remove_out;
313         }
314         *modlist = g_list_remove(*modlist, mod);
315
316 remove_out:
317         /*-------- DEBUG LOG --------*/
318         if( LOG_LV_DEBUG == logger_get_log_level( loggerCategory ) ){
319                 LOGGER_PUT_LOG_DEBUG(loggerCategory,12,
320                     "out_function: void l7vs_module_remove(GList** modlist, void* mod)");
321         }
322         /*------ DEBUG LOG END ------*/
323 }
324
325 /*!
326  * Lookup module from list function.
327  * @param modname [in] Module name.
328  * @param key [in] Lookup keyword.
329  * @param cmp [in] Lookup function.
330  * @retern Found module.
331  */
332 void *
333 l7vs_module_lookup(GList *modlist, void *key, GCompareFunc cmp)
334 {
335         /*-------- DEBUG LOG --------*/
336         if( LOG_LV_DEBUG == logger_get_log_level( loggerCategory ) ){
337                 LOGGER_PUT_LOG_DEBUG(loggerCategory,13,
338                     "in_function: void* l7vs_module_lookup(GList* modlist, void* key, GCompareFunc cmp): "
339                     "modlist=%p, key=%p, cmp=%p", modlist, key, cmp);
340         }
341         /*------ DEBUG LOG END ------*/
342
343         GList* l;
344         void*  return_value = NULL;
345
346         /* check null */
347         if (modlist == NULL) {
348                 goto lookup_out;
349         }
350         if (key == NULL) {
351                 LOGGER_PUT_LOG_ERROR(loggerCategory,12,
352                     "Arg(key) is NULL pointer.");
353                 goto lookup_out;
354         }
355         if (cmp == NULL) {
356                 LOGGER_PUT_LOG_ERROR(loggerCategory,13,
357                     "Arg(cmp) is NULL pointer.");
358                 goto lookup_out;
359         }
360
361         l = g_list_find_custom(modlist, (gpointer)key, cmp);
362         if (l == NULL) {
363                 goto lookup_out;
364         }
365         return_value = (void *)l->data;
366
367 lookup_out:
368         /*-------- DEBUG LOG --------*/
369         if( LOG_LV_DEBUG == logger_get_log_level( loggerCategory ) ){
370                 LOGGER_PUT_LOG_DEBUG(loggerCategory,14,
371                     "out_function: void* l7vs_module_lookup(GList* modlist, void* key, GCompareFunc cmp): "
372                     "return_value=%p", return_value);
373         }
374         /*------ DEBUG LOG END ------*/
375
376         return return_value;
377 }