Browse code

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.

Miklos Tirpak authored on 21/09/2010 12:42:55
Showing 5 changed files
... ...
@@ -43,6 +43,7 @@ int cfg_declare(char *group_name, cfg_def_t *def, void *values, int def_size,
43 43
 {
44 44
 	int	i, num, size, group_name_len;
45 45
 	cfg_mapping_t	*mapping = NULL;
46
+	cfg_group_t	*group;
46 47
 	int types;
47 48
 
48 49
 	/* 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,
142 143
 
143 144
 	group_name_len = strlen(group_name);
144 145
 	/* check for duplicates */
145
-	if (cfg_lookup_group(group_name, group_name_len)) {
146
-		LOG(L_ERR, "ERROR: register_cfg_def(): "
147
-			"configuration group has been already declared: %s\n",
148
-			group_name);
149
-		goto error;
146
+	if ((group = cfg_lookup_group(group_name, group_name_len))) {
147
+		if (group->dynamic != CFG_GROUP_UNKNOWN) {
148
+			/* conflict with another module/core group, or with a dynamic group */
149
+			LOG(L_ERR, "ERROR: register_cfg_def(): "
150
+				"configuration group has been already declared: %s\n",
151
+				group_name);
152
+			goto error;
153
+		}
154
+		/* An empty group is found which does not have any variable yet */
155
+		cfg_set_group(group, num, mapping, values, size, handle);
156
+	} else {
157
+		/* create a new group
158
+		I will allocate memory in shm mem for the variables later in a single block,
159
+		when we know the size of all the registered groups. */
160
+		if (!(group = cfg_new_group(group_name, group_name_len, num, mapping, values, size, handle)))
161
+			goto error;
150 162
 	}
151
-
152
-	/* create a new group
153
-	I will allocate memory in shm mem for the variables later in a single block,
154
-	when we know the size of all the registered groups. */
155
-	if (!cfg_new_group(group_name, group_name_len, num, mapping, values, size, handle))
156
-		goto error;
163
+	group->dynamic = CFG_GROUP_STATIC;
157 164
 
158 165
 	/* The cfg variables are ready to use, let us set the handle
159 166
 	before passing the new definitions to the drivers.
... ...
@@ -226,7 +233,7 @@ void **cfg_get_handle(char *gname)
226 233
 	cfg_group_t	*group;
227 234
 
228 235
 	group = cfg_lookup_group(gname, strlen(gname));
229
-	if (!group || group->dynamic) return NULL;
236
+	if (!group || (group->dynamic != CFG_GROUP_STATIC)) return NULL;
230 237
 
231 238
 	return group->handle;
232 239
 }
... ...
@@ -77,7 +77,7 @@ int cfg_register_ctx(cfg_ctx_t **handle, cfg_on_declare on_declare_cb)
77 77
 		) {
78 78
 			/* dynamic groups are not ready, the callback
79 79
 			will be called later when the group is fixed-up */
80
-			if (group->dynamic) continue;
80
+			if (group->dynamic != CFG_GROUP_STATIC) continue;
81 81
 
82 82
 			gname.s = group->name;
83 83
 			gname.len = group->name_len;
... ...
@@ -56,14 +56,14 @@ cfg_script_var_t *new_cfg_script_var(char *gname, char *vname, unsigned int type
56 56
 	/* the group may have been already declared */
57 57
 	group = cfg_lookup_group(gname, gname_len);
58 58
 	if (group) {
59
-		if (group->dynamic == 0) {
59
+		if (group->dynamic == CFG_GROUP_STATIC) {
60 60
 			/* the group has been already declared by a module or by the core */
61 61
 			LOG(L_ERR, "ERROR: new_cfg_script_var(): "
62 62
 				"configuration group has been already declared: %s\n",
63 63
 				gname);
64 64
 			return NULL;
65 65
 		}
66
-		/* the dynamic group is found */
66
+		/* the dynamic or empty group is found */
67 67
 		/* verify that the variable does not exist */
68 68
 		for (	var = (cfg_script_var_t *)group->vars;
69 69
 			var;
... ...
@@ -76,6 +76,8 @@ cfg_script_var_t *new_cfg_script_var(char *gname, char *vname, unsigned int type
76 76
 				return NULL;
77 77
 			}
78 78
 		}
79
+		if (group->dynamic == CFG_GROUP_UNKNOWN)
80
+			group->dynamic = CFG_GROUP_DYNAMIC;
79 81
 
80 82
 	} else {
81 83
 		/* 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
85 87
 					NULL /* vars */, 0 /* size */, NULL /* handle */);
86 88
 					
87 89
 		if (!group) goto error;
88
-		group->dynamic = 1;
90
+		group->dynamic = CFG_GROUP_DYNAMIC;
89 91
 	}
90 92
 
91 93
 	switch (type) {
... ...
@@ -98,6 +98,18 @@ cfg_group_t *cfg_new_group(char *name, int name_len,
98 98
 	return group;
99 99
 }
100 100
 
101
+/* Set the values of an existing cfg group. */
102
+void cfg_set_group(cfg_group_t *group,
103
+		int num, cfg_mapping_t *mapping,
104
+		char *vars, int size, void **handle)
105
+{
106
+	group->num = num;
107
+	group->mapping = mapping;
108
+	group->vars = vars;
109
+	group->size = size;
110
+	group->handle = handle;
111
+}
112
+
101 113
 /* clones a string to shared memory
102 114
  * (src and dst can be the same)
103 115
  */
... ...
@@ -200,7 +212,7 @@ int cfg_shmize(void)
200 212
 
201 213
 	block = (cfg_block_t*)shm_malloc(sizeof(cfg_block_t)+size-1);
202 214
 	if (!block) {
203
-		LOG(L_ERR, "ERROR: cfg_clone_str(): not enough shm memory\n");
215
+		LOG(L_ERR, "ERROR: cfg_shmize(): not enough shm memory\n");
204 216
 		goto error;
205 217
 	}
206 218
 	memset(block, 0, sizeof(cfg_block_t)+size-1);
... ...
@@ -211,13 +223,13 @@ int cfg_shmize(void)
211 223
 		group;
212 224
 		group=group->next
213 225
 	) {
214
-		if (group->dynamic == 0) {
226
+		if (group->dynamic == CFG_GROUP_STATIC) {
215 227
 			/* clone the strings to shm mem */
216 228
 			if (cfg_shmize_strings(group)) goto error;
217 229
 
218 230
 			/* copy the values to the new block */
219 231
 			memcpy(CFG_GROUP_DATA(block, group), group->vars, group->size);
220
-		} else {
232
+		} else if (group->dynamic == CFG_GROUP_DYNAMIC) {
221 233
 			/* The group was declared with NULL values,
222 234
 			 * we have to fix it up.
223 235
 			 * The fixup function takes care about the values,
... ...
@@ -232,6 +244,11 @@ int cfg_shmize(void)
232 244
 			cfg_notify_drivers(group->name, group->name_len,
233 245
 					group->mapping->def);
234 246
 			*(group->handle) = NULL;
247
+		} else {
248
+			LOG(L_ERR, "ERROR: cfg_shmize(): Configuration group is declared "
249
+					"without any variable: %.*s\n",
250
+					group->name_len, group->name);
251
+			goto error;
235 252
 		}
236 253
 	}
237 254
 	/* try to fixup the selects that failed to be fixed-up previously */
... ...
@@ -273,7 +290,7 @@ static void cfg_destory_groups(unsigned char *block)
273 290
 						if (old_string) shm_free(old_string);
274 291
 				}
275 292
 
276
-		if (group->dynamic) {
293
+		if (group->dynamic == CFG_GROUP_DYNAMIC) {
277 294
 			/* the group was dynamically allocated */
278 295
 			cfg_script_destroy(group);
279 296
 		} else {
... ...
@@ -48,13 +48,19 @@
48 48
  * an array.
49 49
  */
50 50
 typedef struct _cfg_add_var {
51
-	unsigned int	type;
51
+	struct _cfg_add_var	*next;
52
+	unsigned int	type;	/*!< type == 0 is also valid, it indicates that the group
53
+				must be created with the default values */
52 54
 	union {
53 55
 		str	s;
54 56
 		int	i;
55 57
 	} val;
56 58
 	unsigned int	group_id; /*!< Id of the group instance */
57
-	struct _cfg_add_var	*next;
59
+	int		name_len;	/*!< Name of the variable. The variable may not be known,
60
+					for example the additional group value is set in the script
61
+					before the cfg group is declared. Hence, the pointer cannot
62
+					be stored here. */
63
+	char		name[1];
58 64
 } cfg_add_var_t;
59 65
 
60 66
 /*! \brief structure used for variable - pointer mapping */
... ...
@@ -68,6 +74,9 @@ typedef struct _cfg_mapping {
68 74
 	unsigned int	flag;	/*!< flag indicating the state of the variable */
69 75
 } cfg_mapping_t;
70 76
 
77
+/*! \brief type of the group */
78
+enum { CFG_GROUP_UNKNOWN = 0, CFG_GROUP_DYNAMIC, CFG_GROUP_STATIC };
79
+
71 80
 /*! \brief linked list of registered groups */
72 81
 typedef struct _cfg_group {
73 82
 	int		num;		/*!< number of variables within the group */
... ...
@@ -93,7 +102,7 @@ typedef struct _cfg_group {
93 102
 	unsigned char	dynamic;	/*!< indicates whether the variables within the group
94 103
 					are dynamically	allocated or not */
95 104
 	struct _cfg_group	*next;
96
-	int		name_len;	
105
+	int		name_len;
97 106
 	char		name[1];
98 107
 } cfg_group_t;
99 108
 
... ...
@@ -236,6 +245,11 @@ cfg_group_t *cfg_new_group(char *name, int name_len,
236 245
 		int num, cfg_mapping_t *mapping,
237 246
 		char *vars, int size, void **handle);
238 247
 
248
+/* Set the values of an existing cfg group. */
249
+void cfg_set_group(cfg_group_t *group,
250
+		int num, cfg_mapping_t *mapping,
251
+		char *vars, int size, void **handle);
252
+
239 253
 /* copy the variables to shm mem */
240 254
 int cfg_shmize(void);
241 255