Module: sip-router
Branch: master
Commit: fc444f6f95e373d93a8698a09571a9e67939b632
URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=fc444f6…
Author: Miklos Tirpak <miklos(a)iptel.org>
Committer: Miklos Tirpak <miklos(a)iptel.org>
Date: Tue Jan 4 16:21:04 2011 +0100
cfg framework: cfg_group_inst_exists() added
The function checkes whether or not a group instance exists.
---
cfg/cfg_ctx.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
cfg/cfg_ctx.h | 7 +++++++
2 files changed, 57 insertions(+), 0 deletions(-)
diff --git a/cfg/cfg_ctx.c b/cfg/cfg_ctx.c
index 53d881a..b90201a 100644
--- a/cfg/cfg_ctx.c
+++ b/cfg/cfg_ctx.c
@@ -1648,6 +1648,56 @@ error:
return -1;
}
+/* Check the existance of a group instance.
+ * return value:
+ * 1: exists
+ * 0: does not exist
+ */
+int cfg_group_inst_exists(cfg_ctx_t *ctx, str *group_name, unsigned int group_id)
+{
+ cfg_group_t *group;
+ cfg_add_var_t *add_var;
+ int found;
+
+ /* verify the context even if we do not need it now
+ to make sure that a cfg driver has called the function
+ (very very weak security) */
+ if (!ctx) {
+ LOG(L_ERR, "ERROR: cfg_group_inst_exists(): context is undefined\n");
+ return 0;
+ }
+
+ if (!(group = cfg_lookup_group(group_name->s, group_name->len))) {
+ LOG(L_ERR, "ERROR: cfg_group_inst_exists(): group not found\n");
+ return 0;
+ }
+
+ if (!cfg_shmized) {
+ /* group instances are stored in the additional variable list
+ * before forking */
+ found = 0;
+ for ( add_var = group->add_var;
+ add_var;
+ add_var = add_var->next
+ )
+ if (add_var->group_id == group_id) {
+ found = 1;
+ break;
+ }
+
+ } else {
+ /* make sure that nobody else replaces the global config meantime */
+ CFG_WRITER_LOCK();
+ found = (cfg_find_group(CFG_GROUP_META(*cfg_global, group),
+ group->size,
+ group_id)
+ != NULL);
+ CFG_WRITER_UNLOCK();
+ }
+
+ return found;
+}
+
/* Apply the changes to a group instance as long as the additional variable
* belongs to the specified group_id. *add_var_p is moved to the next additional
* variable, and all the consumed variables are freed.
diff --git a/cfg/cfg_ctx.h b/cfg/cfg_ctx.h
index 359f590..33b9b18 100644
--- a/cfg/cfg_ctx.h
+++ b/cfg/cfg_ctx.h
@@ -198,6 +198,13 @@ int cfg_add_group_inst(cfg_ctx_t *ctx, str *group_name, unsigned int group_id);
/* Delete an instance of a group */
int cfg_del_group_inst(cfg_ctx_t *ctx, str *group_name, unsigned int group_id);
+/* Check the existance of a group instance.
+ * return value:
+ * 1: exists
+ * 0: does not exist
+ */
+int cfg_group_inst_exists(cfg_ctx_t *ctx, str *group_name, unsigned int group_id);
+
/* Apply the changes to a group instance as long as the additional variable
* belongs to the specified group_id. *add_var_p is moved to the next additional
* variable, and all the consumed variables are freed.
Module: sip-router
Branch: master
Commit: 7d7264e23619fddcf0fb91a4868631b07af6494d
URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=7d7264e…
Author: Miklos Tirpak <miklos(a)iptel.org>
Committer: Miklos Tirpak <miklos(a)iptel.org>
Date: Wed Jan 5 14:57:14 2011 +0100
cfg framework: group instance values can be deleted
Added support for deleting a single value from a group instance.
The value is reset to the default value in this case, it follows the
changes of the default value.
Related functions:
- cfg_del_now()
- cfg_del_delayed()
---
cfg/cfg.h | 1 +
cfg/cfg_ctx.c | 247 ++++++++++++++++++++++++++++++++++++++----------------
cfg/cfg_ctx.h | 9 ++
cfg/cfg_struct.h | 5 +
4 files changed, 188 insertions(+), 74 deletions(-)
Diff: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commitdiff;h=7d7…
Module: sip-router
Branch: master
Commit: cd29cc777996b8100680fb8ea96eb302e21f8c4c
URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=cd29cc7…
Author: Miklos Tirpak <miklos(a)iptel.org>
Committer: Miklos Tirpak <miklos(a)iptel.org>
Date: Wed Jan 5 15:10:06 2011 +0100
cfg_rpc: RPC commands for value deletion
Two RPC commands added for deleting a configuration value from
a group instance:
cfg.del group[id] var
cfg.del_delayed group[id] var
---
modules/cfg_rpc/README | 11 +++++++++
modules/cfg_rpc/cfg_rpc.c | 50 +++++++++++++++++++++++++++++++++++++++++++
modules/cfg_rpc/doc/rpc.xml | 22 +++++++++++++++++++
3 files changed, 83 insertions(+), 0 deletions(-)
diff --git a/modules/cfg_rpc/README b/modules/cfg_rpc/README
index 3bec8f0..9c71c66 100644
--- a/modules/cfg_rpc/README
+++ b/modules/cfg_rpc/README
@@ -35,6 +35,11 @@ Miklos Tirpak
The function accepts three parameters: group name, variable name,
int/string value. The group name can optionally contain the group
instance id, for example foo[5].
+ * cfg.del - Delete the value of a configuration variable from a group
+ instance and commit the change immediately. The value is reset to
+ the default value and it follows the changes of that. The function
+ accepts two parameters: group name, variable name. The group name
+ must contain the group instance id, for example foo[5].
* cfg.set_delayed_int - Prepare the change of a configuration
variable, but does not commit the new value yet. The function
accepts three parameters: group name, variable name, integer value.
@@ -51,6 +56,12 @@ Miklos Tirpak
type of the value provided. The function accepts three parameters:
group name, variable name, int/string value. The group name can
optionally contain the group instance id, for example foo[5].
+ * cfg.del_delayed - Prepare the deletion of the value of a
+ configuration variable from a group instance, but does not commit
+ the change yet. The value is reset to the default value and it
+ follows the changes of that. The function accepts two parameters:
+ group name, variable name. The group name must contain the group
+ instance id, for example foo[5].
* cfg.commit - Commit the previously prepared configuration changes.
The function does not have any parameters.
* cfg.rollback - Drop the prepared configuration changes. The
diff --git a/modules/cfg_rpc/cfg_rpc.c b/modules/cfg_rpc/cfg_rpc.c
index 23cba03..31cc901 100644
--- a/modules/cfg_rpc/cfg_rpc.c
+++ b/modules/cfg_rpc/cfg_rpc.c
@@ -156,6 +156,30 @@ static void rpc_set(rpc_t* rpc, void* c)
}
}
+static const char* rpc_del_now_doc[2] = {
+ "Delete the value of a configuration variable from a group instance and commit the change immediately",
+ 0
+};
+
+static void rpc_del(rpc_t* rpc, void* c)
+{
+ str group, var;
+ unsigned int *group_id;
+
+ if (rpc->scan(c, "SS", &group, &var) < 2)
+ return;
+
+ if (get_group_id(&group, &group_id) || !group_id) {
+ rpc->fault(c, 400, "Wrong group syntax. Use \"group[id]\"");
+ return;
+ }
+
+ if (cfg_del_now(ctx, &group, group_id, &var)) {
+ rpc->fault(c, 400, "Failed to delete the value");
+ return;
+ }
+}
+
static const char* rpc_set_delayed_doc[2] = {
"Prepare the change of a configuration variable, but does not commit the new value yet",
0
@@ -229,6 +253,30 @@ static void rpc_set_delayed(rpc_t* rpc, void* c)
}
}
+static const char* rpc_del_delayed_doc[2] = {
+ "Prepare the deletion of the value of a configuration variable from a group instance, but does not commit the change yet",
+ 0
+};
+
+static void rpc_del_delayed(rpc_t* rpc, void* c)
+{
+ str group, var;
+ unsigned int *group_id;
+
+ if (rpc->scan(c, "SS", &group, &var) < 2)
+ return;
+
+ if (get_group_id(&group, &group_id) || !group_id) {
+ rpc->fault(c, 400, "Wrong group syntax. Use \"group[id]\"");
+ return;
+ }
+
+ if (cfg_del_delayed(ctx, &group, group_id, &var)) {
+ rpc->fault(c, 400, "Failed to delete the value");
+ return;
+ }
+}
+
static const char* rpc_commit_doc[2] = {
"Commit the previously prepared configuration changes",
0
@@ -488,9 +536,11 @@ static rpc_export_t rpc_calls[] = {
{"cfg.set", rpc_set, rpc_set_now_doc, 0},
{"cfg.set_now_int", rpc_set_now_int, rpc_set_now_doc, 0},
{"cfg.set_now_string", rpc_set_now_string, rpc_set_now_doc, 0},
+ {"cfg.del", rpc_del, rpc_del_now_doc, 0},
{"cfg.set_delayed", rpc_set_delayed, rpc_set_delayed_doc, 0},
{"cfg.set_delayed_int", rpc_set_delayed_int, rpc_set_delayed_doc, 0},
{"cfg.set_delayed_string", rpc_set_delayed_string, rpc_set_delayed_doc, 0},
+ {"cfg.del_delayed", rpc_del_delayed, rpc_del_delayed_doc, 0},
{"cfg.commit", rpc_commit, rpc_commit_doc, 0},
{"cfg.rollback", rpc_rollback, rpc_rollback_doc, 0},
{"cfg.get", rpc_get, rpc_get_doc, 0},
diff --git a/modules/cfg_rpc/doc/rpc.xml b/modules/cfg_rpc/doc/rpc.xml
index 4491184..ae3c548 100644
--- a/modules/cfg_rpc/doc/rpc.xml
+++ b/modules/cfg_rpc/doc/rpc.xml
@@ -41,6 +41,17 @@
</listitem>
<listitem>
<para>
+ <emphasis>cfg.del</emphasis> - Delete the value of
+ a configuration variable from a group instance and commit the change immediately.
+ The value is reset to the default value and it follows the changes
+ of that.
+ The function accepts two parameters: group name, variable
+ name. The group name must contain the
+ group instance id, for example foo[5].
+ </para>
+ </listitem>
+ <listitem>
+ <para>
<emphasis>cfg.set_delayed_int</emphasis> - Prepare the change of
a configuration variable, but does not commit the new value yet.
The function accepts three parameters: group name, variable
@@ -70,6 +81,17 @@
</listitem>
<listitem>
<para>
+ <emphasis>cfg.del_delayed</emphasis> - Prepare the deletion of the value of
+ a configuration variable from a group instance, but does not commit the change yet.
+ The value is reset to the default value and it follows the changes
+ of that.
+ The function accepts two parameters: group name, variable
+ name. The group name must contain the
+ group instance id, for example foo[5].
+ </para>
+ </listitem>
+ <listitem>
+ <para>
<emphasis>cfg.commit</emphasis> - Commit the previously
prepared configuration changes. The function does not have
any parameters.
Module: sip-router
Branch: master
Commit: 628e975416ba291f7158520e5cc92d0b0cb6826e
URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=628e975…
Author: Miklos Tirpak <miklos(a)iptel.org>
Committer: Miklos Tirpak <miklos(a)iptel.org>
Date: Wed Jan 5 11:40:20 2011 +0100
bit test: bit_test_and_reset() added
The function returns the bit found at offset position
in a bitstring and resets the bit to 0.
---
bit_test.h | 42 ++++++++++++++++++++++++++++++++++++++++++
1 files changed, 42 insertions(+), 0 deletions(-)
diff --git a/bit_test.h b/bit_test.h
index 534e502..9f83215 100644
--- a/bit_test.h
+++ b/bit_test.h
@@ -18,6 +18,7 @@
* History
* -------
* 2010-04-26 Initial version (Miklos)
+ * 2011-01-05 bit_test_and_reset added (Miklos)
*/
/* Bit test functions:
@@ -30,6 +31,11 @@
* in a bitstring pointed by addr, and sets
* the bit at the given offset.
*
+ * - int bit_test_and_reset(int offset, unsigned int *addr)
+ * Returns the bit found at offset position
+ * in a bitstring pointed by addr, and resets
+ * the bit at the given offset.
+ *
* Note that 0 <= offset <= 128, Make sure that addr points to
* a large enough memory area.
*/
@@ -86,6 +92,24 @@ static inline int bit_test_and_set(int offset, unsigned int *addr)
return (int)v;
}
+/* Returns the bit found at offset position in the bitstring
+ * pointed by addr and resets it to 0.
+ * Note that the CPU can access 4 bytes starting from addr,
+ * hence 0 <= offset < 128 holds. Make sure that addr points
+ * to a memory area that is large enough.
+ */
+static inline int bit_test_and_reset(int offset, unsigned int *addr)
+{
+ unsigned char v;
+
+ asm volatile(
+ " btr %2, %1 \n\t"
+ " setc %0 \n\t"
+ : "=qm" (v) : "m" (*addr), "r" (offset)
+ );
+ return (int)v;
+}
+
#else /* BIT_TEST_ASM */
/* Returns the bit found at offset position in the bitstring
@@ -116,6 +140,24 @@ static inline int bit_test_and_set(int offset, unsigned int *addr)
return res;
}
+/* Returns the bit found at offset position in the bitstring
+ * pointed by addr and resets it to 0.
+ * Note that offset can be grater than 32, make sure that addr points
+ * to a memory area that is large enough.
+ */
+static inline int bit_test_and_reset(int offset, unsigned int *addr)
+{
+ unsigned int *i;
+ int mask, res;
+
+ i = addr + offset/32;
+ mask = 1U << (offset % 32);
+ res = ((*i) & mask) ? 1 : 0;
+ (*i) &= ~mask;
+
+ return res;
+}
+
#endif /* BIT_TEST_ASM */
#endif /* #ifndef _BIT_TEST_H */
Module: sip-router
Branch: master
Commit: 47daa2e1174376fa94b858ea9473b868161e7341
URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=47daa2e…
Author: Miklos Tirpak <miklos(a)iptel.org>
Committer: Miklos Tirpak <miklos(a)iptel.org>
Date: Tue Jan 4 11:14:30 2011 +0100
cfg framework: mem leak in del_group_inst is corrected
cfg_del_group_inst() did not free the strings that were
set within the group instance. When the group instance was
deleted, the strings left allocated.
---
cfg/cfg_ctx.c | 36 +++++++++++++++++++++++++++++++++---
1 files changed, 33 insertions(+), 3 deletions(-)
diff --git a/cfg/cfg_ctx.c b/cfg/cfg_ctx.c
index b23925c..5fe2dc6 100644
--- a/cfg/cfg_ctx.c
+++ b/cfg/cfg_ctx.c
@@ -1521,6 +1521,8 @@ int cfg_del_group_inst(cfg_ctx_t *ctx, str *group_name, unsigned int group_id)
cfg_block_t *block = NULL;
void **replaced = NULL;
cfg_group_inst_t *new_array = NULL, *group_inst;
+ cfg_mapping_t *var;
+ int i, num;
/* verify the context even if we do not need it now
to make sure that a cfg driver has called the function
@@ -1571,13 +1573,41 @@ int cfg_del_group_inst(cfg_ctx_t *ctx, str *group_name, unsigned int group_id)
/* prepare the array of the replaced strings,
and replaced group instances,
they will be freed when the old block is freed */
- replaced = (void **)shm_malloc(sizeof(void *) * 2);
+
+ /* count the number of strings that has to be freed */
+ num = 0;
+ for (i = 0; i < group->num; i++) {
+ var = &group->mapping[i];
+ if (CFG_VAR_TEST(group_inst, var)
+ && ((CFG_VAR_TYPE(var) == CFG_VAR_STRING) || (CFG_VAR_TYPE(var) == CFG_VAR_STR))
+ && (*(char **)(group_inst->vars + var->offset) != NULL)
+ )
+ num++;
+ }
+
+ replaced = (void **)shm_malloc(sizeof(void *) * (num + 2));
if (!replaced) {
LOG(L_ERR, "ERROR: cfg_del_group_inst(): not enough shm memory\n");
goto error;
}
- replaced[0] = CFG_GROUP_META(*cfg_global, group)->array;
- replaced[1] = NULL;
+
+ if (num) {
+ /* There was at least one string to free, go though the list again */
+ num = 0;
+ for (i = 0; i < group->num; i++) {
+ var = &group->mapping[i];
+ if (CFG_VAR_TEST(group_inst, var)
+ && ((CFG_VAR_TYPE(var) == CFG_VAR_STRING) || (CFG_VAR_TYPE(var) == CFG_VAR_STR))
+ && (*(char **)(group_inst->vars + var->offset) != NULL)
+ ) {
+ replaced[num] = *(char **)(group_inst->vars + var->offset);
+ num++;
+ }
+ }
+ }
+
+ replaced[num] = CFG_GROUP_META(*cfg_global, group)->array;
+ replaced[num+1] = NULL;
}
/* replace the global config with the new one */
cfg_install_global(block, replaced, NULL, NULL);
Module: sip-router
Branch: master
Commit: 106ab4610b48140a5a5e99a520b53a12bd0a2478
URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=106ab46…
Author: Miklos Tirpak <miklos(a)iptel.org>
Committer: Miklos Tirpak <miklos(a)iptel.org>
Date: Tue Jan 4 11:28:53 2011 +0100
cfg framework: crash when adding a new group instance
A log message trying to print a NULL variable name caused
a crash when a new group instance was added before forking
without any variable.
---
cfg/cfg_struct.c | 11 ++++++++++-
1 files changed, 10 insertions(+), 1 deletions(-)
diff --git a/cfg/cfg_struct.c b/cfg/cfg_struct.c
index 1cf1848..6e93379 100644
--- a/cfg/cfg_struct.c
+++ b/cfg/cfg_struct.c
@@ -876,10 +876,19 @@ int new_add_var(str *group_name, unsigned int group_id, str *var_name,
cfg_add_var_t *add_var = NULL, **add_var_p;
int len;
- LOG(L_DBG, "DEBUG: new_add_var(): declaring a new variable instance %.*s[%u].%.*s\n",
+ if (type && (!var_name || !val)) {
+ LOG(L_ERR, "ERROR: new_add_var(): Missing variable/value specification\n");
+ goto error;
+ }
+ if (type)
+ LOG(L_DBG, "DEBUG: new_add_var(): declaring a new variable instance %.*s[%u].%.*s\n",
group_name->len, group_name->s,
group_id,
var_name->len, var_name->s);
+ else
+ LOG(L_DBG, "DEBUG: new_add_var(): declaring a new group instance %.*s[%u]\n",
+ group_name->len, group_name->s,
+ group_id);
if (cfg_shmized) {
LOG(L_ERR, "ERROR: new_add_var(): too late, the configuration has already been shmized\n");
Module: sip-router
Branch: master
Commit: 1dcfdfbd0360a38f4b7e3f9075de6b19d1847cb4
URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=1dcfdfb…
Author: Miklos Tirpak <miklos(a)iptel.org>
Committer: Miklos Tirpak <miklos(a)iptel.org>
Date: Mon Jan 3 12:22:46 2011 +0100
cfg framework: add/del_group_inst updates the local config
add/del_group_inst() updates the local configuration to
make sure that cfg_set_*() sees the change when it immediately
follows the group intance modification.
---
cfg/cfg_ctx.c | 10 ++++++++++
1 files changed, 10 insertions(+), 0 deletions(-)
diff --git a/cfg/cfg_ctx.c b/cfg/cfg_ctx.c
index d3ea6fe..b23925c 100644
--- a/cfg/cfg_ctx.c
+++ b/cfg/cfg_ctx.c
@@ -1494,6 +1494,11 @@ int cfg_add_group_inst(cfg_ctx_t *ctx, str *group_name, unsigned int group_id)
group_name->len, group_name->s,
group_id);
+ /* Make sure that cfg_set_*() sees the change when
+ * the function is immediately called after the group
+ * instance has been added. */
+ cfg_update();
+
return 0;
error:
CFG_WRITER_UNLOCK();
@@ -1583,6 +1588,11 @@ int cfg_del_group_inst(cfg_ctx_t *ctx, str *group_name, unsigned int group_id)
group_name->len, group_name->s,
group_id);
+ /* Make sure that cfg_set_*() sees the change when
+ * the function is immediately called after the group
+ * instance has been deleted. */
+ cfg_update();
+
return 0;
error:
CFG_WRITER_UNLOCK();