d3231dc5d93001e40755e4074f517fd2035311a3
[sip-router] / cfg / cfg_struct.h
1 /*
2  * $Id$
3  *
4  * Copyright (C) 2007 iptelorg GmbH
5  *
6  * This file is part of SIP-router, a free SIP server.
7  *
8  * SIP-router 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  * SIP-router is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  *
22  * History
23  * -------
24  *  2007-12-03  Initial version (Miklos)
25  *  2008-01-24  dynamic groups are introduced in order to make
26  *              variable declaration possible in the script (Miklos)
27  */
28
29 #ifndef _CFG_STRUCT_H
30 #define _CFG_STRUCT_H
31
32 #include "../str.h"
33 #include "../atomic_ops.h"
34 #include "../mem/shm_mem.h"
35 #include "../locking.h"
36 #include "../compiler_opt.h"
37 #include "../bit_test.h"
38 #include "cfg.h"
39
40 /*! \brief Maximum number of variables within a configuration group. */
41 #define CFG_MAX_VAR_NUM 256
42
43 /*! \brief indicates that the variable has been already shmized */
44 #define cfg_var_shmized 1U
45
46 /*! \brief Structure for storing additional values of a variable.
47  * When the config is shmzied, these variables are combined in
48  * an array.
49  */
50 typedef struct _cfg_add_var {
51         struct _cfg_add_var     *next;
52         unsigned int    type;   /*!< type == 0 is also valid, it indicates that the group
53                                 must be created with the default values */
54         union {
55                 char    *ch;
56                 str     s;
57                 int     i;
58         } val;
59         unsigned int    group_id; /*!< Id of the group instance */
60         int             name_len;       /*!< Name of the variable. The variable may not be known,
61                                         for example the additional group value is set in the script
62                                         before the cfg group is declared. Hence, the pointer cannot
63                                         be stored here. */
64         char            name[1];
65 } cfg_add_var_t;
66
67 /*! \brief structure used for variable - pointer mapping */
68 typedef struct _cfg_mapping {
69         cfg_def_t       *def;           /*!< one item of the cfg structure definition */
70         int             name_len;       /*!< length of def->name */
71
72         /* additional information about the cfg variable */
73         int             pos;    /*!< position of the variable within the group starting from 0 */
74         int             offset; /*!< offest within the memory block */
75         unsigned int    flag;   /*!< flag indicating the state of the variable */
76 } cfg_mapping_t;
77
78 /*! \brief type of the group */
79 enum { CFG_GROUP_UNKNOWN = 0, CFG_GROUP_DYNAMIC, CFG_GROUP_STATIC };
80
81 /*! \brief linked list of registered groups */
82 typedef struct _cfg_group {
83         int             num;            /*!< number of variables within the group */
84         cfg_mapping_t   *mapping;       /*!< describes the mapping betweeen
85                                         the cfg variable definition and the memory block */
86         char            *vars;          /*!< pointer to the memory block where the values
87                                         are stored -- used only before the config is
88                                         shmized. */
89         cfg_add_var_t   *add_var;       /*!< Additional instances of the variables.
90                                         This linked list is used only before the config is
91                                         shmized. */
92         int             size;           /*!< size of the memory block that has to be
93                                         allocated to store the values */
94         int             meta_offset;    /*!< offset of the group within the
95                                         shmized memory block for the meta_data */
96         int             var_offset;     /*!< offset of the group within the
97                                         shmized memory block for the variables */
98         void            **handle;       /*!< per-process handle that can be used
99                                         by the modules to access the variables.
100                                         It is registered when the group is created,
101                                         and updated every time the block is replaced */
102
103         unsigned char   dynamic;        /*!< indicates whether the variables within the group
104                                         are dynamically allocated or not */
105         struct _cfg_group       *next;
106         int             name_len;
107         char            name[1];
108 } cfg_group_t;
109
110 /*! \brief One instance of the cfg group variables which stores
111  * the additional values. These values can overwrite the default values. */
112 typedef struct _cfg_group_inst {
113         unsigned int    id;             /*!< identifier of the group instance */
114         unsigned int    set[CFG_MAX_VAR_NUM/(sizeof(int)*8)];
115                                         /*!< Bitmap indicating whether or not a value is explicitely set
116                                         within this instance. If the value is not set,
117                                         then the default value is used, and copied into this instance. */
118         unsigned char   vars[1];        /*!< block for the values */
119 } cfg_group_inst_t;
120
121 /*! \bried Meta-data which is stored before each variable group
122  * within the blob. This structure is used to handle the multivalue
123  * instances of the variables, i.e. manages the array for the
124  * additional values. */
125 typedef struct _cfg_group_meta {
126         int                     num;    /*!< Number of items in the array */
127         cfg_group_inst_t        *array; /*!< Array of cfg groups with num number of items */
128 } cfg_group_meta_t;
129
130 /*! \brief single memoy block that contains all the cfg values */
131 typedef struct _cfg_block {
132         atomic_t        refcnt;         /*!< reference counter,
133                                         the block is automatically deleted
134                                         when it reaches 0 */
135         void            **replaced;     /*!< set of the strings and other memory segments
136                                         that must be freed
137                                         together with the block. The content depends
138                                         on the block that replaces this one */
139         unsigned char   vars[1];        /*!< blob that contains the values */
140 } cfg_block_t;
141
142 /*! \brief Linked list of per-child process callbacks.
143  * Each child process has a local pointer, and executes the callbacks
144  * when the pointer is not pointing to the end of the list.
145  * Items from the begginning of the list are deleted when the starter
146  * pointer is moved, and no more child process uses them.
147  */
148 typedef struct _cfg_child_cb {
149         atomic_t                refcnt; /*!< number of child processes
150                                         referring to the element */
151         atomic_t                cb_count;       /*!< This counter is used to track
152                                                  * how many times the callback needs
153                                                  * to be executed.
154                                                  * >0 the cb needs to be executed
155                                                  * <=0 the cb no longer needs to be executed
156                                                  */
157         str                     gname, name;    /*!< name of the variable that has changed */
158         cfg_on_set_child        cb;     /*!< callback function that has to be called */
159
160         struct _cfg_child_cb    *next;
161 } cfg_child_cb_t;
162
163 extern cfg_group_t      *cfg_group;
164 extern cfg_block_t      **cfg_global;
165 extern cfg_block_t      *cfg_local;
166 extern int              cfg_block_size;
167 extern gen_lock_t       *cfg_global_lock;
168 extern gen_lock_t       *cfg_writer_lock;
169 extern int              cfg_shmized;
170 extern cfg_child_cb_t   **cfg_child_cb_first;
171 extern cfg_child_cb_t   **cfg_child_cb_last;
172 extern cfg_child_cb_t   *cfg_child_cb;
173 extern int              cfg_ginst_count;
174
175 /* magic value for cfg_child_cb for processes that do not want to
176    execute per-child callbacks */
177 #define CFG_NO_CHILD_CBS ((void*)(long)(-1))
178
179 /* macros for easier variable access */
180 #define CFG_VAR_TYPE(var)       CFG_VAR_MASK((var)->def->type)
181 #define CFG_INPUT_TYPE(var)     CFG_INPUT_MASK((var)->def->type)
182
183 /* get the meta-data of a group from the block */
184 #define CFG_GROUP_META(block, group) \
185         ((cfg_group_meta_t *)((block)->vars + (group)->meta_offset))
186
187 /* get the data block of a group from the block */
188 #define CFG_GROUP_DATA(block, group) \
189         ((unsigned char *)((block)->vars + (group)->var_offset))
190
191 /* Test whether a variable is explicitely set in the group instance,
192  * or it uses the default value */
193 #define CFG_VAR_TEST(group_inst, var) \
194         bit_test((var)->pos % (sizeof(int)*8), (group_inst)->set + (var)->pos/(sizeof(int)*8))
195
196 /* Test whether a variable is explicitely set in the group instance,
197  * or it uses the default value, and set the flag. */
198 #define CFG_VAR_TEST_AND_SET(group_inst, var) \
199         bit_test_and_set((var)->pos % (sizeof(int)*8), (group_inst)->set + (var)->pos/(sizeof(int)*8))
200
201 /* Test whether a variable is explicitely set in the group instance,
202  * or it uses the default value, and reset the flag. */
203 #define CFG_VAR_TEST_AND_RESET(group_inst, var) \
204         bit_test_and_reset((var)->pos % (sizeof(int)*8), (group_inst)->set + (var)->pos/(sizeof(int)*8))
205
206 /* Return the group instance pointer from a handle,
207  * or NULL if the handle points to the default configuration block */
208 #define CFG_HANDLE_TO_GINST(h) \
209         ( (((unsigned char*)(h) < cfg_local->vars) \
210                 || ((unsigned char*)(h) > cfg_local->vars + cfg_block_size) \
211         ) ? \
212                 (cfg_group_inst_t*)((char*)(h) - (unsigned long)&((cfg_group_inst_t *)0)->vars) \
213                 : NULL )
214
215 /* initiate the cfg framework */
216 int sr_cfg_init(void);
217
218 /* destroy the memory allocated for the cfg framework */
219 void cfg_destroy(void);
220
221 /* Register num number of child processes that will
222  * keep updating their local configuration.
223  * This function needs to be called from mod_init
224  * before any child process is forked.
225  */
226 void cfg_register_child(int num);
227
228 /* per-child process init function.
229  * It needs to be called from the forked process.
230  * cfg_register_child() must be called before this function!
231  */
232 int cfg_child_init(void);
233
234 /* Child process init function that can be called
235  * without cfg_register_child().
236  * Note that the child process may miss some configuration changes.
237  */
238 int cfg_late_child_init(void);
239
240 /* per-child init function for non-cb executing processes.
241  * Mark this process as not wanting to execute any per-child config
242  * callback (it will have only limited config functionality, but is useful
243  * when a process needs only to watch some non-callback cfg. values,
244  * e.g. the main attendant process, debug and memlog).
245  * It needs to be called from the forked process.
246  * cfg_register_child must _not_ be called.
247  */
248 int cfg_child_no_cb_init(void);
249
250 /* per-child process destroy function
251  * Should be called only when the child process exits,
252  * but SER continues running.
253  *
254  * WARNING: this function call must be the very last action
255  * before the child process exits, because the local config
256  * is not available afterwards.
257  */
258 void cfg_child_destroy(void);
259
260 /* creates a new cfg group, and adds it to the linked list */
261 cfg_group_t *cfg_new_group(char *name, int name_len,
262                 int num, cfg_mapping_t *mapping,
263                 char *vars, int size, void **handle);
264
265 /* Set the values of an existing cfg group. */
266 void cfg_set_group(cfg_group_t *group,
267                 int num, cfg_mapping_t *mapping,
268                 char *vars, int size, void **handle);
269
270 /* copy the variables to shm mem */
271 int cfg_shmize(void);
272
273 /* free the memory of a config block */
274 static inline void cfg_block_free(cfg_block_t *block)
275 {
276         int     i;
277
278         /* free the changed variables */
279         if (block->replaced) {
280                 for (i=0; block->replaced[i]; i++)
281                         shm_free(block->replaced[i]);
282                 shm_free(block->replaced);
283         }
284         shm_free(block);
285 }
286
287 /* Move the group handle to the specified group instance pointed by dst_ginst.
288  * src_ginst shall point to the active group instance.
289  * Both parameters can be NULL meaning that the src/dst config is the default, 
290  * not an additional group instance.
291  * The function executes all the per-child process callbacks which are different
292  * in the two instaces.
293  */
294 void cfg_move_handle(cfg_group_t *group, cfg_group_inst_t *src_ginst, cfg_group_inst_t *dst_ginst);
295
296
297 /* lock and unlock the global cfg block -- used only at the
298  * very last step when the block is replaced */
299 #define CFG_LOCK()      lock_get(cfg_global_lock);
300 #define CFG_UNLOCK()    lock_release(cfg_global_lock);
301
302 /* lock and unlock used by the cfg drivers to make sure that
303  * only one driver process is considering replacing the global
304  * cfg block */
305 #define CFG_WRITER_LOCK()       lock_get(cfg_writer_lock);
306 #define CFG_WRITER_UNLOCK()     lock_release(cfg_writer_lock);
307
308 /* increase and decrease the reference counter of a block */
309 #define CFG_REF(block) \
310         atomic_inc(&(block)->refcnt)
311
312 #define CFG_UNREF(block) \
313         do { \
314                 if (atomic_dec_and_test(&(block)->refcnt)) \
315                         cfg_block_free(block); \
316         } while(0)
317
318 /* updates all the module handles and calls the
319  * per-child process callbacks -- not intended to be used
320  * directly, use cfg_update() instead!
321  * params:
322  *   no_cbs - if 1, do not call per child callbacks
323  */
324 static inline void cfg_update_local(int no_cbs)
325 {
326         cfg_group_t     *group;
327         cfg_child_cb_t  *last_cb;
328         cfg_child_cb_t  *prev_cb;
329
330         if (cfg_local) CFG_UNREF(cfg_local);
331         CFG_LOCK();
332         CFG_REF(*cfg_global);
333         cfg_local = *cfg_global;
334         /* the value of the last callback must be read within the lock */
335         last_cb = *cfg_child_cb_last;
336
337         /* I unlock now, because the child process can update its own private
338         config without the lock held. In the worst case, the process will get the
339         lock once more to set cfg_child_cb_first, but only one of the child
340         processes will do so, and only if a value, that has per-child process
341         callback defined, was changed. */
342         CFG_UNLOCK();
343
344         /* update the handles */
345         for (   group = cfg_group;
346                 group;
347                 group = group->next
348         )
349                 *(group->handle) = CFG_GROUP_DATA(cfg_local, group);
350
351         if (unlikely(cfg_child_cb==CFG_NO_CHILD_CBS || no_cbs))
352                 return;
353         /* call the per-process callbacks */
354         while (cfg_child_cb != last_cb) {
355                 prev_cb = cfg_child_cb;
356                 cfg_child_cb = cfg_child_cb->next;
357                 atomic_inc(&cfg_child_cb->refcnt);
358                 if (atomic_dec_and_test(&prev_cb->refcnt)) {
359                         /* No more pocess refers to this callback.
360                         Did this process block the deletion,
361                         or is there any other process that has not
362                         reached prev_cb yet? */
363                         CFG_LOCK();
364                         if (*cfg_child_cb_first == prev_cb) {
365                                 /* yes, this process was blocking the deletion */
366                                 *cfg_child_cb_first = cfg_child_cb;
367                                 CFG_UNLOCK();
368                                 shm_free(prev_cb);
369                         } else {
370                                 CFG_UNLOCK();
371                         }
372                 }
373                 if (atomic_add(&cfg_child_cb->cb_count, -1) >= 0) /* the new value is returned
374                                                                 by atomic_add() */
375                         /* execute the callback */
376                         cfg_child_cb->cb(&cfg_child_cb->gname, &cfg_child_cb->name);
377                 /* else the callback no longer needs to be executed */
378         }
379 }
380
381 /* Reset all the group handles to the default, local configuration */
382 static inline void cfg_reset_handles(void)
383 {
384         cfg_group_t     *group;
385
386         if (!cfg_local)
387                 return;
388
389         for (   group = cfg_group;
390                 group && cfg_ginst_count; /* cfg_ginst_count is decreased every time
391                                         a group handle is reset. When it reaches 0,
392                                         needless to continue the loop */
393                 group = group->next
394         ) {
395                 if (((unsigned char*)*(group->handle) < cfg_local->vars)
396                         || ((unsigned char*)*(group->handle) > cfg_local->vars + cfg_block_size)
397                 )
398                         cfg_move_handle(group,
399                                         CFG_HANDLE_TO_GINST(*(group->handle)),
400                                         NULL);
401         }
402 }
403
404 /* sets the local cfg block to the active block
405  * 
406  * If your module forks a new process that implements
407  * an infinite loop, put cfg_update() to the beginning of
408  * the cycle to make sure, that subsequent function calls see the
409  * up-to-date config set.
410  */
411 #define cfg_update() \
412         do { \
413                 if (unlikely(cfg_ginst_count)) \
414                         cfg_reset_handles(); \
415                 if (unlikely(cfg_local != *cfg_global)) \
416                         cfg_update_local(0); \
417         } while(0)
418
419 /* like cfg_update(), but does not execute callbacks
420  * (it should be used sparingly only in special cases, since it
421  *  breaks an important cfg framework feature)
422  */
423 #define cfg_update_no_cbs() \
424         do { \
425                 if (unlikely(cfg_local != *cfg_global)) \
426                         cfg_update_local(1); \
427         } while(0)
428
429 /* Reset all the group handles in the child process,
430  * i.e. move them back to the default local configuration.
431  */
432 #define cfg_reset_all() \
433         do { \
434                 if (unlikely(cfg_ginst_count)) \
435                         cfg_reset_handles(); \
436         } while(0)
437
438
439 /* searches a group by name */
440 cfg_group_t *cfg_lookup_group(char *name, int len);
441         
442 /* searches a variable definition by group and variable name */
443 int cfg_lookup_var(str *gname, str *vname,
444                         cfg_group_t **group, cfg_mapping_t **var);
445
446 /* searches a variable definition within a group by its name */
447 cfg_mapping_t *cfg_lookup_var2(cfg_group_t *group, char *name, int len);
448
449 /* clones the global config block
450  * WARNING: unsafe, cfg_writer_lock or cfg_global_lock must be held!
451  */
452 cfg_block_t *cfg_clone_global(void);
453
454 /* Clone an array of configuration group instances. */
455 cfg_group_inst_t *cfg_clone_array(cfg_group_meta_t *meta, cfg_group_t *group);
456
457 /* Extend the array of configuration group instances with one more instance.
458  * Only the ID of the new group is set, nothing else. */
459 cfg_group_inst_t *cfg_extend_array(cfg_group_meta_t *meta, cfg_group_t *group,
460                                 unsigned int group_id,
461                                 cfg_group_inst_t **new_group);
462
463 /* Remove an instance from a group array.
464  * inst must point to an instance within meta->array.
465  * *_new_array is set to the newly allocated array. */
466 int cfg_collapse_array(cfg_group_meta_t *meta, cfg_group_t *group,
467                                 cfg_group_inst_t *inst,
468                                 cfg_group_inst_t **_new_array);
469
470 /* clones a string to shared memory */
471 int cfg_clone_str(str *src, str *dst);
472
473 /* Find the group instance within the meta-data based on the group_id */
474 cfg_group_inst_t *cfg_find_group(cfg_group_meta_t *meta, int group_size, unsigned int group_id);
475
476 /* append new callbacks to the end of the child callback list
477  *
478  * WARNING: the function is unsafe, either hold CFG_LOCK(),
479  * or call the function before forking
480  */
481 void cfg_install_child_cb(cfg_child_cb_t *cb_first, cfg_child_cb_t *cb_last);
482
483 /* installs a new global config
484  *
485  * replaced is an array of strings that must be freed together
486  * with the previous global config.
487  * cb_first and cb_last define a linked list of per-child process
488  * callbacks. This list is added to the global linked list.
489  */
490 void cfg_install_global(cfg_block_t *block, void **replaced,
491                         cfg_child_cb_t *cb_first, cfg_child_cb_t *cb_last);
492
493 /* creates a structure for a per-child process callback */
494 cfg_child_cb_t *cfg_child_cb_new(str *gname, str *name,
495                         cfg_on_set_child cb,
496                         unsigned int type);
497
498 /* free the memory allocated for a child cb list */
499 void cfg_child_cb_free(cfg_child_cb_t *child_cb_first);
500
501 /* Allocate memory for a new additional variable
502  * and link it to a configuration group.
503  * type==0 results in creating a new group instance with the default values.
504  * The group is created with CFG_GROUP_UNKNOWN type if it does not exist.
505  * Note: this function is usable only before the configuration is shmized.
506  */
507 int new_add_var(str *group_name, unsigned int group_id, str *var_name,
508                                 void *val, unsigned int type);
509
510 /* Move the group handle to the specified group instance. */
511 int cfg_select(cfg_group_t *group, unsigned int id);
512
513 /* Reset the group handle to the default, local configuration */
514 int cfg_reset(cfg_group_t *group);
515
516 #endif /* _CFG_STRUCT_H */