@cfg_get.<group_name>.<var_name> is documented
[sip-router] / doc / cfg.txt
1 # $Id$
2 #
3 # History:
4 # --------
5 # 2007-12-06:   Created by Miklos
6
7 SER Configuration Framework
8
9 1. Overview
10 ===============================================================================
11
12 The configuration framework can be used by SER core and by the modules,
13 to get and set internal variables on-the-fly, and eliminate SER restarts
14 whenever it is possible.
15
16 The core and the modules can declare configuration variables, and can
17 retrieve the value of the variables at any time without performance
18 overhead. The framework makes sure that the variables do not change
19 during the SIP message processing, the child processes see a snapshot
20 of the variables with constant values. The variable, that is changed by
21 a cfg driver module, will be automatically replaced by the framework
22 the next time a SIP message is started to be processed.
23   
24 The drivers can change the values of all the variables by names with or
25 without the need of commit. That means a kind of transaction support,
26 the framework can keep track of the changes (per driver) until they
27 are committed or rolled-back.
28
29 2. Using the framework in a module
30 ===============================================================================
31
32 Make sure that the run-time change of the variable cannot cause troubles.
33 You can expect the variable change before a SIP message is processed,
34 or before a timer fires, but it will never change during the function
35 calls.
36
37 1. Include the header file:
38
39 #include "../../cfg/cfg.h"
40
41 -------------------------------------------------------------------------------
42
43 2. Define a structure that contains the variables, the structure name
44 must begin with "cfg_group_" followed by the group name: (The group name
45 is typically the module name, but a single module can register more than
46 one groups as well.)
47
48 struct cfg_group_foo {
49         int     i;
50         char    *ch;
51         str     s;
52         void    *p;
53 };
54
55 -------------------------------------------------------------------------------
56
57 3. Set the default values:
58
59 static struct cfg_group_foo default_cfg = {
60         -1,
61         "mystring",
62         {"interoperability", 16},
63         NULL,
64 };
65
66 -------------------------------------------------------------------------------
67
68 4. Export the variables over the module interface if you wish:
69
70 static param_export_t params[] = {
71         {"i",   PARAM_INT,      &default_cfg.i},
72         {"ch",  PARAM_STRING,   &default_cfg.ch},
73         {"s",   PARAM_STR,      &default_cfg.s},
74         {0, 0, 0}
75 };
76
77 -------------------------------------------------------------------------------
78
79 5. Declare a void* handle that will be used to access the config group:
80
81 static void     *cfg_handle = &default_cfg;
82
83 -------------------------------------------------------------------------------
84
85 6. Describe the structure you defined at step 2 for the framework:
86
87 static cfg_def_t cfg_def[] = {
88         {"int", CFG_VAR_INT, -10, 10, 0, 0, "integer for testing"},
89         {"ch", CFG_VAR_STRING, 0, 0, 0, 0, "string for testing"},
90         {"s", CFG_VAR_STR, 0, 0, 0, 0, "str for testing"},
91         {"p", CFG_VAR_POINTER | CFG_INPUT_STRING, 0, 0, fixup_p, fixup_child_p, "pointer for testing"},
92         {0, 0, 0, 0, 0, 0, 0},
93 };
94
95 Each row consists of the following items:
96
97 - name that will be used by the drivers to refer to the variable
98 - flag indicating the variable and the input type, that is accepted
99   by the fixup function
100
101   Valid variable types are:
102         - CFG_VAR_INT           = int
103         - CFG_VAR_STRING        = char*
104         - CFG_VAR_STR           = str
105         - CFG_VAR_POINTER       = void*
106
107   Valid input types are:
108         - CFG_INPUT_INT         = int
109         - CFG_INPUT_STRING      = char*
110         - CFG_INPUT_STR         = str*
111
112 - minimum value for integers (optional)
113 - maximum value for integers (optional)
114 - fixup function (optional) that is called when the variable is going to be
115   changed by a driver. The module still uses the old value until the change
116   is committed, and the next SIP message is started to be processed, however
117   the new, not-yet-committed values can be accessed by using the temporary
118   handle within the fixup function. String and str values are cloned to
119   shm memory by the framework. The callback type is:
120
121   typedef int (*cfg_on_change)(void *temp_handle, str *var_name, void **value);
122
123 - per-child process callback function (optional) that is called by each child
124   process separately, after the new values have been committed, and the
125   child process is updating its local configuration. The old value will no
126   longer be used by the process. (Useful for fix-ups that cannot be done
127   in shm memory, for example regexp compilation.)
128
129   typedef void (*cfg_on_set_child)(str *var_name);
130
131 - description of the variable
132
133 -------------------------------------------------------------------------------
134
135 7. Declare the configuration group in mod_init:
136
137 static int mod_init(void)
138 {
139         if (cfg_declare("foo", cfg_def, &default_cfg, cfg_size(foo),
140                          &cfg_handle)
141         ) {
142                 /* error */
143                 return -1;
144         }
145         ...
146 }
147
148 -------------------------------------------------------------------------------
149
150 8. The variables can be accessed any time by the group name and handle:
151
152 cfg_get(foo, cfg_handle, i)
153 cfg_get(foo, cfg_handle, ch)
154 cfg_get(foo, cfg_handle, s)
155 cfg_get(foo, cfg_handle, p)
156
157
158 3. Using the framework in the core
159 ===============================================================================
160
161 There is basically no difference between the modules and the core, the core can
162 register any number of groups just like a module. A group called "core" has
163 been already registered, have a look at the cfg_core.* files.
164
165
166 4. Drivers
167 ===============================================================================
168
169 Drivers can change the values of the configuration variables run-time, they can
170 implement RPC calls or database backend for example.
171 The framework is multi-process safe, more drivers (or a single driver with
172 multiple processes) can modify the configuration at the same time.
173
174 1. Create a context for the driver
175
176 #include "../../cfg/cfg_ctx.h"
177
178 static cfg_ctx_t        *ctx = NULL;
179
180 static void on_declare(str *group_name, cfg_def_t *definition)
181 {
182         ...
183 }
184
185 static int mod_init(void)
186 {
187         ctx = cfg_register_ctx(on_declare);
188         if (!ctx) {
189                 /* error */
190                 return -1;
191         }
192         ...
193 }
194
195 The callback function, on_declare(), is called every time a new configuration
196 group is registered, so the driver has a chance to know which groups and
197 variables are present, and can immediately modify them.
198
199 -------------------------------------------------------------------------------
200
201 2. Get the value of a variable by name:
202
203 cfg_get_by_name()
204
205 -------------------------------------------------------------------------------
206
207 3. Set the value of a variable without the need of explicit commit:
208
209 cfg_set_now()
210
211 wrapper functions:
212
213 cfg_set_now_int()
214 cfg_set_now_string()
215
216 -------------------------------------------------------------------------------
217
218 4. Set the value of a variable, but does not commit the change:
219
220 cfg_set_delayed()
221
222 wrapper functions:
223
224 cfg_set_delayed_int()
225 cfg_set_delayed_string()
226
227 More changes can be done, and committed at once.
228
229 -------------------------------------------------------------------------------
230
231 5. Commit or roll back the previously prepared changes:
232
233 cfg_commit()
234 cfg_rollback()
235
236 -------------------------------------------------------------------------------
237
238 6. Get the description of a variable:
239
240 cfg_help()
241
242 -------------------------------------------------------------------------------
243
244 7. Get the list of group definitions:
245
246 void    *h;
247 str     gname;
248 cfg_def_t       *def;
249
250 cfg_get_group_init(&h);
251 while(cfg_get_group_next(&h, &gname, &def)) {
252         ...
253 }
254
255 -------------------------------------------------------------------------------
256
257 8. Get the list of pending changes that have not been committed yet:
258
259 void            *h;
260 str             gname, vname;
261 void            *old_val, *new_val;
262 unsigned int    val_type;
263
264 if (cfg_diff_init(ctx, &h)) return -1;
265 while(cfg_diff_next(&h,
266                 &gname, &vname,
267                 &old_val, &new_val,
268                 &val_type)
269 ) {
270         ...
271 }
272 cfg_diff_release(ctx);
273
274
275 5. Refreshing the configuration
276 ===============================================================================
277
278 There is no need to refresh the configuration in the modules, the core takes
279 care of it, unless the module forks a new process that runs in an endless
280 loop. In this case, it is the task of the forked child process to periodically
281 update its own local configuration the following way:
282
283
284 #include "../../cfg/cfg_struct.h"
285
286 void loop_forever(void)
287 {
288         while(1) {
289                 /* update the local config */
290                 cfg_update();
291                 ...
292         }
293 }
294
295 int child_init(int rank)
296 {
297         int     pid;
298
299         pid = fork_process(PROC_NOCHLDINIT, "foo", 1);
300         if (pid == 0) {
301                 /* This is the child process */
302
303                 /* initialize the config framework */
304                 if (cfg_child_init()) return -1;
305
306                 loop_forever(); /* never returns */
307         }
308         ...
309 }
310
311 The local configuration must be destroyed only when the child process exits,
312 but SER continues running, so the module keeps forking and destroying child
313 processes runtime. Calling the configuration destroy function must be the
314 very last action of the child process before it exists:
315
316 int new_process(void)
317 {
318         int     pid;
319
320         pid = fork();
321
322         if (pid == 0) {
323                 /* This is the child process */
324
325                 /* initialize the config framework */
326                 if (cfg_child_init()) return -1;
327
328                 loop_forever(); /* the function may return */
329
330                 /* destroy the local config */
331                 cfg_child_destroy();
332                 exit(0);
333         }
334 }
335
336 Note, that the configuration should be refreshed even if the module does not
337 declare any config variable, because other modules and the core may need the
338 up-to-date config.
339
340
341 6. Accessing the configuration values in the script
342 ===============================================================================
343
344 The values can be accessed via select calls:
345
346 @cfg_get.<group_name>.<var_name>