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