[sr-dev] git:tirpi/cfg_framework_multivalue: cfg framework: CFG_GROUP_UNKNOWN group type

Miklos Tirpak miklos at iptel.org
Tue Sep 28 11:51:08 CEST 2010


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

Author: Miklos Tirpak <miklos at iptel.org>
Committer: Miklos Tirpak <miklos at iptel.org>
Date:   Tue Sep 21 14:42:55 2010 +0200

cfg framework: CFG_GROUP_UNKNOWN group type

group->dynamic can take 3 values from now:
- CFG_GROUP_STATIC: static group declared by a module or the core
- CFG_GROUP_DYNAMIC: dynamic group declared from the script
- CFG_GROUP_UNKNOWN: not yet known group type. Such group can exist if
	additional group instances are set in the group, but the group
	itself has not been declared yet. This is the case
	for instance if the group instance is set from the script
	but the group is declared from a mod_init function.

Variable name is added to struct _cfg_add_var. The variables may not be
known when additional group instances need to be added, hence, they
can be referred only by name.

---

 cfg/cfg.c        |   31 +++++++++++++++++++------------
 cfg/cfg_ctx.c    |    2 +-
 cfg/cfg_script.c |    8 +++++---
 cfg/cfg_struct.c |   25 +++++++++++++++++++++----
 cfg/cfg_struct.h |   20 +++++++++++++++++---
 5 files changed, 63 insertions(+), 23 deletions(-)

diff --git a/cfg/cfg.c b/cfg/cfg.c
index c718f5a..88a34b2 100644
--- a/cfg/cfg.c
+++ b/cfg/cfg.c
@@ -43,6 +43,7 @@ int cfg_declare(char *group_name, cfg_def_t *def, void *values, int def_size,
 {
 	int	i, num, size, group_name_len;
 	cfg_mapping_t	*mapping = NULL;
+	cfg_group_t	*group;
 	int types;
 
 	/* check the number of the variables */
@@ -142,18 +143,24 @@ int cfg_declare(char *group_name, cfg_def_t *def, void *values, int def_size,
 
 	group_name_len = strlen(group_name);
 	/* check for duplicates */
-	if (cfg_lookup_group(group_name, group_name_len)) {
-		LOG(L_ERR, "ERROR: register_cfg_def(): "
-			"configuration group has been already declared: %s\n",
-			group_name);
-		goto error;
+	if ((group = cfg_lookup_group(group_name, group_name_len))) {
+		if (group->dynamic != CFG_GROUP_UNKNOWN) {
+			/* conflict with another module/core group, or with a dynamic group */
+			LOG(L_ERR, "ERROR: register_cfg_def(): "
+				"configuration group has been already declared: %s\n",
+				group_name);
+			goto error;
+		}
+		/* An empty group is found which does not have any variable yet */
+		cfg_set_group(group, num, mapping, values, size, handle);
+	} else {
+		/* create a new group
+		I will allocate memory in shm mem for the variables later in a single block,
+		when we know the size of all the registered groups. */
+		if (!(group = cfg_new_group(group_name, group_name_len, num, mapping, values, size, handle)))
+			goto error;
 	}
-
-	/* create a new group
-	I will allocate memory in shm mem for the variables later in a single block,
-	when we know the size of all the registered groups. */
-	if (!cfg_new_group(group_name, group_name_len, num, mapping, values, size, handle))
-		goto error;
+	group->dynamic = CFG_GROUP_STATIC;
 
 	/* The cfg variables are ready to use, let us set the handle
 	before passing the new definitions to the drivers.
@@ -226,7 +233,7 @@ void **cfg_get_handle(char *gname)
 	cfg_group_t	*group;
 
 	group = cfg_lookup_group(gname, strlen(gname));
-	if (!group || group->dynamic) return NULL;
+	if (!group || (group->dynamic != CFG_GROUP_STATIC)) return NULL;
 
 	return group->handle;
 }
diff --git a/cfg/cfg_ctx.c b/cfg/cfg_ctx.c
index 94f5878..5fa961d 100644
--- a/cfg/cfg_ctx.c
+++ b/cfg/cfg_ctx.c
@@ -77,7 +77,7 @@ int cfg_register_ctx(cfg_ctx_t **handle, cfg_on_declare on_declare_cb)
 		) {
 			/* dynamic groups are not ready, the callback
 			will be called later when the group is fixed-up */
-			if (group->dynamic) continue;
+			if (group->dynamic != CFG_GROUP_STATIC) continue;
 
 			gname.s = group->name;
 			gname.len = group->name_len;
diff --git a/cfg/cfg_script.c b/cfg/cfg_script.c
index 8340206..58b6cd9 100644
--- a/cfg/cfg_script.c
+++ b/cfg/cfg_script.c
@@ -56,14 +56,14 @@ cfg_script_var_t *new_cfg_script_var(char *gname, char *vname, unsigned int type
 	/* the group may have been already declared */
 	group = cfg_lookup_group(gname, gname_len);
 	if (group) {
-		if (group->dynamic == 0) {
+		if (group->dynamic == CFG_GROUP_STATIC) {
 			/* the group has been already declared by a module or by the core */
 			LOG(L_ERR, "ERROR: new_cfg_script_var(): "
 				"configuration group has been already declared: %s\n",
 				gname);
 			return NULL;
 		}
-		/* the dynamic group is found */
+		/* the dynamic or empty group is found */
 		/* verify that the variable does not exist */
 		for (	var = (cfg_script_var_t *)group->vars;
 			var;
@@ -76,6 +76,8 @@ cfg_script_var_t *new_cfg_script_var(char *gname, char *vname, unsigned int type
 				return NULL;
 			}
 		}
+		if (group->dynamic == CFG_GROUP_UNKNOWN)
+			group->dynamic = CFG_GROUP_DYNAMIC;
 
 	} else {
 		/* create a new group with NULL values, we will fix it later,
@@ -85,7 +87,7 @@ cfg_script_var_t *new_cfg_script_var(char *gname, char *vname, unsigned int type
 					NULL /* vars */, 0 /* size */, NULL /* handle */);
 					
 		if (!group) goto error;
-		group->dynamic = 1;
+		group->dynamic = CFG_GROUP_DYNAMIC;
 	}
 
 	switch (type) {
diff --git a/cfg/cfg_struct.c b/cfg/cfg_struct.c
index 9d5f008..d34ed06 100644
--- a/cfg/cfg_struct.c
+++ b/cfg/cfg_struct.c
@@ -98,6 +98,18 @@ cfg_group_t *cfg_new_group(char *name, int name_len,
 	return group;
 }
 
+/* Set the values of an existing cfg group. */
+void cfg_set_group(cfg_group_t *group,
+		int num, cfg_mapping_t *mapping,
+		char *vars, int size, void **handle)
+{
+	group->num = num;
+	group->mapping = mapping;
+	group->vars = vars;
+	group->size = size;
+	group->handle = handle;
+}
+
 /* clones a string to shared memory
  * (src and dst can be the same)
  */
@@ -200,7 +212,7 @@ int cfg_shmize(void)
 
 	block = (cfg_block_t*)shm_malloc(sizeof(cfg_block_t)+size-1);
 	if (!block) {
-		LOG(L_ERR, "ERROR: cfg_clone_str(): not enough shm memory\n");
+		LOG(L_ERR, "ERROR: cfg_shmize(): not enough shm memory\n");
 		goto error;
 	}
 	memset(block, 0, sizeof(cfg_block_t)+size-1);
@@ -211,13 +223,13 @@ int cfg_shmize(void)
 		group;
 		group=group->next
 	) {
-		if (group->dynamic == 0) {
+		if (group->dynamic == CFG_GROUP_STATIC) {
 			/* clone the strings to shm mem */
 			if (cfg_shmize_strings(group)) goto error;
 
 			/* copy the values to the new block */
 			memcpy(CFG_GROUP_DATA(block, group), group->vars, group->size);
-		} else {
+		} else if (group->dynamic == CFG_GROUP_DYNAMIC) {
 			/* The group was declared with NULL values,
 			 * we have to fix it up.
 			 * The fixup function takes care about the values,
@@ -232,6 +244,11 @@ int cfg_shmize(void)
 			cfg_notify_drivers(group->name, group->name_len,
 					group->mapping->def);
 			*(group->handle) = NULL;
+		} else {
+			LOG(L_ERR, "ERROR: cfg_shmize(): Configuration group is declared "
+					"without any variable: %.*s\n",
+					group->name_len, group->name);
+			goto error;
 		}
 	}
 	/* try to fixup the selects that failed to be fixed-up previously */
@@ -273,7 +290,7 @@ static void cfg_destory_groups(unsigned char *block)
 						if (old_string) shm_free(old_string);
 				}
 
-		if (group->dynamic) {
+		if (group->dynamic == CFG_GROUP_DYNAMIC) {
 			/* the group was dynamically allocated */
 			cfg_script_destroy(group);
 		} else {
diff --git a/cfg/cfg_struct.h b/cfg/cfg_struct.h
index 5f1fa0a..37d56ca 100644
--- a/cfg/cfg_struct.h
+++ b/cfg/cfg_struct.h
@@ -48,13 +48,19 @@
  * an array.
  */
 typedef struct _cfg_add_var {
-	unsigned int	type;
+	struct _cfg_add_var	*next;
+	unsigned int	type;	/*!< type == 0 is also valid, it indicates that the group
+				must be created with the default values */
 	union {
 		str	s;
 		int	i;
 	} val;
 	unsigned int	group_id; /*!< Id of the group instance */
-	struct _cfg_add_var	*next;
+	int		name_len;	/*!< Name of the variable. The variable may not be known,
+					for example the additional group value is set in the script
+					before the cfg group is declared. Hence, the pointer cannot
+					be stored here. */
+	char		name[1];
 } cfg_add_var_t;
 
 /*! \brief structure used for variable - pointer mapping */
@@ -68,6 +74,9 @@ typedef struct _cfg_mapping {
 	unsigned int	flag;	/*!< flag indicating the state of the variable */
 } cfg_mapping_t;
 
+/*! \brief type of the group */
+enum { CFG_GROUP_UNKNOWN = 0, CFG_GROUP_DYNAMIC, CFG_GROUP_STATIC };
+
 /*! \brief linked list of registered groups */
 typedef struct _cfg_group {
 	int		num;		/*!< number of variables within the group */
@@ -93,7 +102,7 @@ typedef struct _cfg_group {
 	unsigned char	dynamic;	/*!< indicates whether the variables within the group
 					are dynamically	allocated or not */
 	struct _cfg_group	*next;
-	int		name_len;	
+	int		name_len;
 	char		name[1];
 } cfg_group_t;
 
@@ -236,6 +245,11 @@ cfg_group_t *cfg_new_group(char *name, int name_len,
 		int num, cfg_mapping_t *mapping,
 		char *vars, int size, void **handle);
 
+/* Set the values of an existing cfg group. */
+void cfg_set_group(cfg_group_t *group,
+		int num, cfg_mapping_t *mapping,
+		char *vars, int size, void **handle);
+
 /* copy the variables to shm mem */
 int cfg_shmize(void);
 




More information about the sr-dev mailing list