Module: sip-router Branch: master Commit: df8b1cf011e0ecf4c9f06578ddc6b991fd1444c4 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=df8b1cf0...
Author: Miklos Tirpak miklos@iptel.org Committer: Miklos Tirpak miklos@iptel.org Date: Mon Jul 13 16:36:36 2009 +0200
cfg framework: fix the group handles in the main process
The main process does not have a local configuration, it has access only to the config values that were set before forking. As a result, the group handles cannot ponint to the shared memory address because the shared memory block may be freed later by one of the child processes. This problem resulted sometimes in a core dump after the processes were killed when the main process tried to access a variable from shared mem which was no longer available.
---
cfg/cfg_script.c | 1 - cfg/cfg_select.c | 9 +++++++++ cfg/cfg_struct.c | 12 +++++++----- 3 files changed, 16 insertions(+), 6 deletions(-)
diff --git a/cfg/cfg_script.c b/cfg/cfg_script.c index 39a4068..8804e40 100644 --- a/cfg/cfg_script.c +++ b/cfg/cfg_script.c @@ -143,7 +143,6 @@ error: /* fix-up the dynamically declared group: * - allocate memory for the arrays * - set the values within the memory block - * - notify the drivers about the new group */ int cfg_script_fixup(cfg_group_t *group, unsigned char *block) { diff --git a/cfg/cfg_select.c b/cfg/cfg_select.c index 4374aa6..d8871ba 100644 --- a/cfg/cfg_select.c +++ b/cfg/cfg_select.c @@ -203,6 +203,10 @@ int select_cfg_var(str *res, select_t *s, struct sip_msg *msg) /* use the module's handle to access the variable, so the variables are read from the local config */ p = *(group->handle) + var->offset; + if (p == NULL) + return -1; /* The group is not yet ready. + * (Trying to read the value from the + * main process that has no local configuration) */
switch (CFG_VAR_TYPE(var)) { case CFG_VAR_INT: @@ -295,9 +299,14 @@ unsigned int read_cfg_var(struct cfg_read_handle *read_handle, void **val) group = (cfg_group_t *)(read_handle->group); var = (cfg_mapping_t *)(read_handle->var);
+ /* use the module's handle to access the variable, so the variables are read from the local config */ p = *(group->handle) + var->offset; + if (p == NULL) + return 0; /* The group is not yet ready. + * (Trying to read the value from the + * main process that has no local configuration) */
switch (CFG_VAR_TYPE(var)) { case CFG_VAR_INT: diff --git a/cfg/cfg_struct.c b/cfg/cfg_struct.c index 533228b..4f28dfe 100644 --- a/cfg/cfg_struct.c +++ b/cfg/cfg_struct.c @@ -194,21 +194,23 @@ int cfg_shmize(void) /* clone the strings to shm mem */ if (cfg_shmize_strings(group)) goto error;
- /* copy the values to the new block, - and update the module's handle */ + /* copy the values to the new block */ memcpy(block->vars+group->offset, group->vars, group->size); - *(group->handle) = block->vars+group->offset; } else { /* The group was declared with NULL values, * we have to fix it up. * The fixup function takes care about the values, * it fills up the block */ if (cfg_script_fixup(group, block->vars+group->offset)) goto error; - *(group->handle) = block->vars+group->offset;
- /* notify the drivers about the new config definition */ + /* Notify the drivers about the new config definition. + * Temporary set the group handle so that the drivers have a chance to + * overwrite the default values. The handle must be reset after this + * because the main process does not have a local configuration. */ + *(group->handle) = block->vars+group->offset; cfg_notify_drivers(group->name, group->name_len, group->mapping->def); + *(group->handle) = NULL; } } /* try to fixup the selects that failed to be fixed-up previously */