cfg.txt 14 KB

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