[sr-dev] git:master: cfg framework: fix the group handles in the main process

Miklos Tirpak miklos at iptel.org
Mon Jul 13 16:59:43 CEST 2009


Module: sip-router
Branch: master
Commit: df8b1cf011e0ecf4c9f06578ddc6b991fd1444c4
URL:    http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=df8b1cf011e0ecf4c9f06578ddc6b991fd1444c4

Author: Miklos Tirpak <miklos at iptel.org>
Committer: Miklos Tirpak <miklos at 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 */




More information about the sr-dev mailing list