cfg framework: fix shutdown crash for non registered modules
[sip-router] / cfg / cfg_struct.h
1 /*
2  * $Id$
3  *
4  * Copyright (C) 2007 iptelorg GmbH
5  *
6  * This file is part of ser, a free SIP server.
7  *
8  * ser is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version
12  *
13  * For a license to use the ser software under conditions
14  * other than those described here, or to purchase support for this
15  * software, please contact iptel.org by e-mail at the following addresses:
16  *    info@iptel.org
17  *
18  * ser is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26  *
27  * History
28  * -------
29  *  2007-12-03  Initial version (Miklos)
30  *  2008-01-24  dynamic groups are introduced in order to make
31  *              variable declaration possible in the script (Miklos)
32  */
33
34 #ifndef _CFG_STRUCT_H
35 #define _CFG_STRUCT_H
36
37 #include "../str.h"
38 #include "../atomic_ops.h"
39 #include "../mem/shm_mem.h"
40 #include "../locking.h"
41 #include "../compiler_opt.h"
42 #include "cfg.h"
43
44 /* indicates that the variable has been already shmized */
45 #define cfg_var_shmized 1U
46
47 /* structure used for variable - pointer mapping */
48 typedef struct _cfg_mapping {
49         cfg_def_t       *def;           /* one item of the cfg structure definition */
50         int             name_len;       /* length of def->name */
51
52         /* additional information about the cfg variable */
53         int             offset; /* offest within the memory block */
54         unsigned int    flag;   /* flag indicating the state of the variable */
55 } cfg_mapping_t;
56
57 /* linked list of registered groups */
58 typedef struct _cfg_group {
59         int             num;            /* number of variables within the group */
60         cfg_mapping_t   *mapping;       /* describes the mapping betweeen
61                                         the cfg variable definition and the memory block */
62         char            *vars;          /* pointer to the memory block where the values
63                                         are stored -- used only before the config is
64                                         shmized. */
65         int             size;           /* size of the memory block that has to be
66                                         allocated to store the values */
67         int             offset;         /* offset of the group within the
68                                         shmized memory block */
69         void            **handle;       /* per-process handle that can be used
70                                         by the modules to access the variables.
71                                         It is registered when the group is created,
72                                         and updated every time the block is replaced */
73
74         unsigned char   dynamic;        /* indicates whether the variables within the group
75                                         are dynamically allocated or not */
76         struct _cfg_group       *next;
77         int             name_len;       
78         char            name[1];
79 } cfg_group_t;
80
81 /* single memoy block that contains all the cfg values */
82 typedef struct _cfg_block {
83         atomic_t        refcnt;         /* reference counter,
84                                         the block is automatically deleted
85                                         when it reaches 0 */
86         char            **replaced;     /* set of the strings that must be freed
87                                         together with the block. The content depends
88                                         on the block that replaces this one */
89         unsigned char   vars[1];        /* blob that contains the values */
90 } cfg_block_t;
91
92 /* Linked list of per-child process callbacks.
93  * Each child process has a local pointer, and executes the callbacks
94  * when the pointer is not pointing to the end of the list.
95  * Items from the begginning of the list are deleted when the starter
96  * pointer is moved, and no more child process uses them.
97  */
98 typedef struct _cfg_child_cb {
99         atomic_t                refcnt; /* number of child processes
100                                         referring to the element */
101         atomic_t                cb_count;       /* This counter is used to track
102                                                  * how many times the callback needs
103                                                  * to be executed.
104                                                  * >0 the cb needs to be executed
105                                                  * <=0 the cb no longer needs to be executed
106                                                  */
107         str                     gname, name;    /* name of the variable that has changed */
108         cfg_on_set_child        cb;     /* callback function that has to be called */
109
110         struct _cfg_child_cb    *next;
111 } cfg_child_cb_t;
112
113 extern cfg_group_t      *cfg_group;
114 extern cfg_block_t      **cfg_global;
115 extern cfg_block_t      *cfg_local;
116 extern gen_lock_t       *cfg_global_lock;
117 extern gen_lock_t       *cfg_writer_lock;
118 extern int              cfg_shmized;
119 extern cfg_child_cb_t   **cfg_child_cb_first;
120 extern cfg_child_cb_t   **cfg_child_cb_last;
121 extern cfg_child_cb_t   *cfg_child_cb;
122
123 /* magic value for cfg_child_cb for processes that do not want to
124    execute per-child callbacks */
125 #define CFG_NO_CHILD_CBS ((void*)(long)(-1))
126
127 /* macros for easier variable access */
128 #define CFG_VAR_TYPE(var)       CFG_VAR_MASK((var)->def->type)
129 #define CFG_INPUT_TYPE(var)     CFG_INPUT_MASK((var)->def->type)
130
131 /* initiate the cfg framework */
132 int sr_cfg_init(void);
133
134 /* destroy the memory allocated for the cfg framework */
135 void cfg_destroy(void);
136
137 /* Register num number of child processes that will
138  * keep updating their local configuration.
139  * This function needs to be called from mod_init
140  * before any child process is forked.
141  */
142 void cfg_register_child(int num);
143
144 /* per-child process init function.
145  * It needs to be called from the forked process.
146  * cfg_register_child() must be called before this function!
147  */
148 int cfg_child_init(void);
149
150 /* Child process init function that can be called
151  * without cfg_register_child().
152  * Note that the child process may miss some configuration changes.
153  */
154 int cfg_late_child_init(void);
155
156 /* per-child init function for non-cb executing processes.
157  * Mark this process as not wanting to execute any per-child config
158  * callback (it will have only limited config functionality, but is useful
159  * when a process needs only to watch some non-callback cfg. values,
160  * e.g. the main attendant process, debug and memlog).
161  * It needs to be called from the forked process.
162  * cfg_register_child must _not_ be called.
163  */
164 int cfg_child_no_cb_init(void);
165
166 /* per-child process destroy function
167  * Should be called only when the child process exits,
168  * but SER continues running.
169  *
170  * WARNING: this function call must be the very last action
171  * before the child process exits, because the local config
172  * is not available afterwards.
173  */
174 void cfg_child_destroy(void);
175
176 /* creates a new cfg group, and adds it to the linked list */
177 cfg_group_t *cfg_new_group(char *name, int name_len,
178                 int num, cfg_mapping_t *mapping,
179                 char *vars, int size, void **handle);
180
181 /* copy the variables to shm mem */
182 int cfg_shmize(void);
183
184 /* free the memory of a config block */
185 static inline void cfg_block_free(cfg_block_t *block)
186 {
187         int     i;
188
189         /* free the changed variables */
190         if (block->replaced) {
191                 for (i=0; block->replaced[i]; i++)
192                         shm_free(block->replaced[i]);
193                 shm_free(block->replaced);
194         }
195         shm_free(block);
196 }
197
198 /* lock and unlock the global cfg block -- used only at the
199  * very last step when the block is replaced */
200 #define CFG_LOCK()      lock_get(cfg_global_lock);
201 #define CFG_UNLOCK()    lock_release(cfg_global_lock);
202
203 /* lock and unlock used by the cfg drivers to make sure that
204  * only one driver process is considering replacing the global
205  * cfg block */
206 #define CFG_WRITER_LOCK()       lock_get(cfg_writer_lock);
207 #define CFG_WRITER_UNLOCK()     lock_release(cfg_writer_lock);
208
209 /* increase and decrease the reference counter of a block */
210 #define CFG_REF(block) \
211         atomic_inc(&(block)->refcnt)
212
213 #define CFG_UNREF(block) \
214         do { \
215                 if (atomic_dec_and_test(&(block)->refcnt)) \
216                         cfg_block_free(block); \
217         } while(0)
218
219 /* updates all the module handles and calls the
220  * per-child process callbacks -- not intended to be used
221  * directly, use cfg_update() instead!
222  * params:
223  *   no_cbs - if 1, do not call per child callbacks
224  */
225 static inline void cfg_update_local(int no_cbs)
226 {
227         cfg_group_t     *group;
228         cfg_child_cb_t  *last_cb;
229         cfg_child_cb_t  *prev_cb;
230
231         if (cfg_local) CFG_UNREF(cfg_local);
232         CFG_LOCK();
233         CFG_REF(*cfg_global);
234         cfg_local = *cfg_global;
235         /* the value of the last callback must be read within the lock */
236         last_cb = *cfg_child_cb_last;
237
238         /* I unlock now, because the child process can update its own private
239         config without the lock held. In the worst case, the process will get the
240         lock once more to set cfg_child_cb_first, but only one of the child
241         processes will do so, and only if a value, that has per-child process
242         callback defined, was changed. */
243         CFG_UNLOCK();
244
245         /* update the handles */
246         for (   group = cfg_group;
247                 group;
248                 group = group->next
249         )
250                 *(group->handle) = cfg_local->vars + group->offset;
251
252         if (unlikely(cfg_child_cb==CFG_NO_CHILD_CBS || no_cbs))
253                 return;
254         /* call the per-process callbacks */
255         while (cfg_child_cb != last_cb) {
256                 prev_cb = cfg_child_cb;
257                 cfg_child_cb = cfg_child_cb->next;
258                 atomic_inc(&cfg_child_cb->refcnt);
259                 if (atomic_dec_and_test(&prev_cb->refcnt)) {
260                         /* No more pocess refers to this callback.
261                         Did this process block the deletion,
262                         or is there any other process that has not
263                         reached prev_cb yet? */
264                         CFG_LOCK();
265                         if (*cfg_child_cb_first == prev_cb) {
266                                 /* yes, this process was blocking the deletion */
267                                 *cfg_child_cb_first = cfg_child_cb;
268                                 CFG_UNLOCK();
269                                 shm_free(prev_cb);
270                         } else {
271                                 CFG_UNLOCK();
272                         }
273                 }
274                 if (atomic_add(&cfg_child_cb->cb_count, -1) >= 0) /* the new value is returned
275                                                                 by atomic_add() */
276                         /* execute the callback */
277                         cfg_child_cb->cb(&cfg_child_cb->gname, &cfg_child_cb->name);
278                 /* else the callback no longer needs to be executed */
279         }
280 }
281
282 /* sets the local cfg block to the active block
283  * 
284  * If your module forks a new process that implements
285  * an infinite loop, put cfg_update() to the beginning of
286  * the cycle to make sure, that subsequent function calls see the
287  * up-to-date config set.
288  */
289 #define cfg_update() \
290         do { \
291                 if (unlikely(cfg_local != *cfg_global)) \
292                         cfg_update_local(0); \
293         } while(0)
294
295 /* like cfg_update(), but does not execute callbacks
296  * (it should be used sparingly only in special cases, since it
297  *  breaks an important cfg framework feature)
298  */
299 #define cfg_update_no_cbs() \
300         do { \
301                 if (unlikely(cfg_local != *cfg_global)) \
302                         cfg_update_local(1); \
303         } while(0)
304
305 /* searches a group by name */
306 cfg_group_t *cfg_lookup_group(char *name, int len);
307         
308 /* searches a variable definition by group and variable name */
309 int cfg_lookup_var(str *gname, str *vname,
310                         cfg_group_t **group, cfg_mapping_t **var);
311
312 /* clones the global config block */
313 cfg_block_t *cfg_clone_global(void);
314
315 /* clones a string to shared memory */
316 int cfg_clone_str(str *src, str *dst);
317
318 /* append new callbacks to the end of the child callback list
319  *
320  * WARNING: the function is unsafe, either hold CFG_LOCK(),
321  * or call the function before forking
322  */
323 void cfg_install_child_cb(cfg_child_cb_t *cb_first, cfg_child_cb_t *cb_last);
324
325 /* installs a new global config
326  *
327  * replaced is an array of strings that must be freed together
328  * with the previous global config.
329  * cb_first and cb_last define a linked list of per-child process
330  * callbacks. This list is added to the global linked list.
331  */
332 void cfg_install_global(cfg_block_t *block, char **replaced,
333                         cfg_child_cb_t *cb_first, cfg_child_cb_t *cb_last);
334
335 /* creates a structure for a per-child process callback */
336 cfg_child_cb_t *cfg_child_cb_new(str *gname, str *name,
337                         cfg_on_set_child cb,
338                         unsigned int type);
339
340 /* free the memory allocated for a child cb list */
341 void cfg_child_cb_free(cfg_child_cb_t *child_cb_first);
342
343 #endif /* _CFG_STRUCT_H */