Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cfgutils lock #3808

Merged
merged 3 commits into from
Apr 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
30 changes: 24 additions & 6 deletions src/modules/app_lua_sr/app_lua_sr_exp.c
Original file line number Diff line number Diff line change
Expand Up @@ -2783,20 +2783,29 @@ static const luaL_Reg _sr_sanity_Map[] = {
static int lua_sr_cfgutils_lock(lua_State *L)
{
int ret;
str lkey;
str lkey, lkey2;

if(!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_CFGUTILS)) {
LM_WARN("weird: cfgutils function executed but module not "
"registered\n");
return app_lua_return_error(L);
}
if(lua_gettop(L) != 1) {
ret = lua_gettop(L);
if(ret < 1 || ret > 3) {
LM_WARN("invalid number of parameters from Lua\n");
return app_lua_return_error(L);
}
if(ret > 1) {
lkey2.s = (char *)lua_tostring(L, -1);
lkey2.len = strlen(lkey2.s);
}
lkey.s = (char *)lua_tostring(L, -1);
lkey.len = strlen(lkey.s);
ret = _lua_cfgutilsb.mlock(&lkey);
if(ret > 1) {
ret = _lua_cfgutilsb.mlock(&lkey, &lkey2);
} else {
ret = _lua_cfgutilsb.mlock(&lkey, NULL);
}

return app_lua_return_int(L, ret);
}
Expand All @@ -2808,20 +2817,29 @@ static int lua_sr_cfgutils_lock(lua_State *L)
static int lua_sr_cfgutils_unlock(lua_State *L)
{
int ret;
str lkey;
str lkey, lkey2;

if(!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_CFGUTILS)) {
LM_WARN("weird: cfgutils function executed but module not "
"registered\n");
return app_lua_return_error(L);
}
if(lua_gettop(L) != 1) {
ret = lua_gettop(L);
if(ret < 1 || ret > 3) {
LM_WARN("invalid number of parameters from Lua\n");
return app_lua_return_error(L);
}
if(ret > 1) {
lkey2.s = (char *)lua_tostring(L, -1);
lkey2.len = strlen(lkey2.s);
}
lkey.s = (char *)lua_tostring(L, -1);
lkey.len = strlen(lkey.s);
ret = _lua_cfgutilsb.munlock(&lkey);
if(ret > 1) {
ret = _lua_cfgutilsb.munlock(&lkey, &lkey2);
} else {
ret = _lua_cfgutilsb.munlock(&lkey, NULL);
}

return app_lua_return_int(L, ret);
}
Expand Down
4 changes: 2 additions & 2 deletions src/modules/cfgutils/api.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@

#include "../../core/str.h"

typedef int (*cfgutils_lock_f)(str *lkey);
typedef int (*cfgutils_unlock_f)(str *lkey);
typedef int (*cfgutils_lock_f)(str *lkey, str *lkey2);
typedef int (*cfgutils_unlock_f)(str *lkey, str *lkey2);

/**
* @brief CFGUTILS API structure
Expand Down
103 changes: 79 additions & 24 deletions src/modules/cfgutils/cfgutils.c
Original file line number Diff line number Diff line change
Expand Up @@ -145,10 +145,15 @@ static cmd_export_t cmds[] = {
ANY_ROUTE},
{"is_gflag", (cmd_function)is_gflag, 1, fixup_gflags, 0, ANY_ROUTE},
{"lock", (cmd_function)w_cfg_lock, 1, fixup_spve_null, 0, ANY_ROUTE},
{"lock", (cmd_function)w_cfg_lock, 2, fixup_spve_spve, 0, ANY_ROUTE},
{"unlock", (cmd_function)w_cfg_unlock, 1, fixup_spve_null, 0,
ANY_ROUTE},
{"unlock", (cmd_function)w_cfg_unlock, 2, fixup_spve_spve, 0,
ANY_ROUTE},
{"trylock", (cmd_function)w_cfg_trylock, 1, fixup_spve_null, 0,
ANY_ROUTE},
{"trylock", (cmd_function)w_cfg_trylock, 2, fixup_spve_spve, 0,
ANY_ROUTE},
{"core_hash", (cmd_function)w_core_hash, 3, fixup_core_hash, 0,
ANY_ROUTE},
{"check_route_exists", (cmd_function)w_check_route_exists, 1,
Expand Down Expand Up @@ -669,19 +674,34 @@ static int ki_shm_summary(sip_msg_t *msg)
return 1;
}

static int cfg_lock_helper(str *lkey, int mode)
static int cfg_lock_helper(str *lkey, str *lkey2, int mode)
{
unsigned int pos;
str *key2 = NULL;

if(lkey2 && lkey2->len > 0) {
key2 = lkey2;
}

if(_cfg_lock_set == NULL) {
LM_ERR("lock set not initialized (attempt to do op: %d on: %.*s) -"
" see param lock_set_size\n",
mode, lkey->len, lkey->s);
if(key2) {
LM_ERR("lock set not initialized (attempt to do op: %d on:[%.*s "
"%.*s]) - see param lock_set_size\n",
mode, STR_FMT(lkey), STR_FMT(lkey2));
} else {
LM_ERR("lock set not initialized (attempt to do op: %d on:[%.*s]) "
"- see param lock_set_size\n",
mode, STR_FMT(lkey));
}
return -1;
}
pos = core_case_hash(lkey, 0, _cfg_lock_size);

LM_DBG("cfg_lock mode %d on %u (%.*s)\n", mode, pos, lkey->len, lkey->s);
pos = core_case_hash(lkey, key2, _cfg_lock_size);
if(key2) {
LM_DBG("cfg_lock mode %d on %u (%.*s %.*s)\n", mode, pos, STR_FMT(lkey),
STR_FMT(lkey2));
} else {
LM_DBG("cfg_lock mode %d on %u (%.*s)\n", mode, pos, STR_FMT(lkey));
}

if(mode == 0) {
/* Lock */
Expand All @@ -707,45 +727,65 @@ static int cfg_lock_helper(str *lkey, int mode)

static int cfg_lock(sip_msg_t *msg, str *lkey)
{
return cfg_lock_helper(lkey, 0);
return cfg_lock_helper(lkey, NULL, 0);
}

static int cfg_unlock(sip_msg_t *msg, str *lkey)
{
return cfg_lock_helper(lkey, 1);
return cfg_lock_helper(lkey, NULL, 1);
}

static int cfg_trylock(sip_msg_t *msg, str *lkey)
{
return cfg_lock_helper(lkey, 2);
return cfg_lock_helper(lkey, NULL, 2);
}

static int w_cfg_lock_wrapper(struct sip_msg *msg, gparam_p key, int mode)
static int cfg_lock_key2(sip_msg_t *msg, str *lkey, str *lkey2)
{
str s;
return cfg_lock_helper(lkey, lkey2, 0);
}

static int cfg_unlock_key2(sip_msg_t *msg, str *lkey, str *lkey2)
{
return cfg_lock_helper(lkey, lkey2, 1);
}

static int cfg_trylock_key2(sip_msg_t *msg, str *lkey, str *lkey2)
{
return cfg_lock_helper(lkey, lkey2, 2);
}

static int w_cfg_lock_wrapper(
struct sip_msg *msg, gparam_p key, gparam_p key2, int mode)
{
str s1, s2;
if(key == NULL) {
return -1;
}
if(fixup_get_svalue(msg, key, &s) != 0) {
if(fixup_get_svalue(msg, key, &s1) != 0) {
LM_ERR("cannot get first parameter\n");
return -1;
}
return cfg_lock_helper(&s, mode);
if(key2 != NULL && fixup_get_svalue(msg, key2, &s2) != 0) {
LM_ERR("cannot get second parameter\n");
return -1;
}
return cfg_lock_helper(&s1, &s2, mode);
}

static int w_cfg_lock(struct sip_msg *msg, char *key, char *s2)
static int w_cfg_lock(struct sip_msg *msg, char *key, char *key2)
{
return w_cfg_lock_wrapper(msg, (gparam_p)key, 0);
return w_cfg_lock_wrapper(msg, (gparam_p)key, (gparam_p)key2, 0);
}

static int w_cfg_unlock(struct sip_msg *msg, char *key, char *s2)
static int w_cfg_unlock(struct sip_msg *msg, char *key, char *key2)
{
return w_cfg_lock_wrapper(msg, (gparam_p)key, 1);
return w_cfg_lock_wrapper(msg, (gparam_p)key, (gparam_p)key2, 1);
}

static int w_cfg_trylock(struct sip_msg *msg, char *key, char *s2)
static int w_cfg_trylock(struct sip_msg *msg, char *key, char *key2)
{
return w_cfg_lock_wrapper(msg, (gparam_p)key, 2);
return w_cfg_lock_wrapper(msg, (gparam_p)key, (gparam_p)key2, 2);
}

/*! Check if a route block exists - only request routes
Expand Down Expand Up @@ -903,17 +943,17 @@ static void mod_destroy(void)
/**
*
*/
int cfgutils_lock(str *lkey)
int cfgutils_lock(str *lkey, str *lkey2)
{
return cfg_lock_helper(lkey, 0);
return cfg_lock_helper(lkey, lkey2, 0);
}

/**
*
*/
int cfgutils_unlock(str *lkey)
int cfgutils_unlock(str *lkey, str *lkey2)
{
return cfg_lock_helper(lkey, 1);
return cfg_lock_helper(lkey, lkey2, 1);
}

static int fixup_core_hash(void **param, int param_no)
Expand Down Expand Up @@ -995,16 +1035,31 @@ static sr_kemi_t sr_kemi_cfgutils_exports[] = {
{ SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
},
{ str_init("cfgutils"), str_init("lock"),
SR_KEMIP_INT, cfg_lock_key2,
{ SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
},
{ str_init("cfgutils"), str_init("unlock"),
SR_KEMIP_INT, cfg_unlock,
{ SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
},
{ str_init("cfgutils"), str_init("unlock"),
SR_KEMIP_INT, cfg_unlock_key2,
{ SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
},
{ str_init("cfgutils"), str_init("trylock"),
SR_KEMIP_INT, cfg_trylock,
{ SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
},
{ str_init("cfgutils"), str_init("trylock"),
SR_KEMIP_INT, cfg_trylock_key2,
{ SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
},
{ str_init("cfgutils"), str_init("rand_set_prob"),
SR_KEMIP_INT, ki_rand_set_prob,
{ SR_KEMIP_INT, SR_KEMIP_NONE, SR_KEMIP_NONE,
Expand Down
18 changes: 13 additions & 5 deletions src/modules/cfgutils/doc/cfgutils_admin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -485,10 +485,10 @@ if(is_gflag("4"))
</example>
</section>
<section id="cfgutils.f.lock">
<title><function moreinfo="none">lock(key)</function></title>
<title><function moreinfo="none">lock(key [, key2])</function></title>
<para>
Lock the key. Can be used to synchronize operations in config file,
a hash id is computed over the key and appropriate lock is set in the
a hash id is computed over the keys and appropriate lock is set in the
lock array controlled by parameter "lock_set_size". Do not use lock()
after another lock() unless you are sure the keys hit different array
entries.
Expand All @@ -497,6 +497,9 @@ if(is_gflag("4"))
<quote>key</quote> can be static string or string with PVs.
</para>
<para>
<quote>key2</quote> is optional and can be static string or string with PVs.
</para>
<para>
This function can be used from REQUEST_ROUTE, FAILURE_ROUTE,
ONREPLY_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE.
</para>
Expand All @@ -510,7 +513,7 @@ lock("$rU");
</example>
</section>
<section id="cfgutils.f.trylock">
<title><function moreinfo="none">trylock(key)</function></title>
<title><function moreinfo="none">trylock(key [, key2])</function></title>
<para>
Try to lock the key. If the lock can not be obtained (possibly already locked),
the function returns an error and script execution continues.
Expand All @@ -519,6 +522,9 @@ lock("$rU");
<quote>key</quote> can be static string or string with PVs.
</para>
<para>
<quote>key2</quote> is optional and can be static string or string with PVs.
</para>
<para>
This function can be used from REQUEST_ROUTE, FAILURE_ROUTE,
ONREPLY_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE.
</para>
Expand All @@ -535,14 +541,17 @@ if (trylock("$rU")) {
</example>
</section>
<section id="cfgutils.f.unlock">
<title><function moreinfo="none">unlock(key)</function></title>
<title><function moreinfo="none">unlock(key [, key2])</function></title>
<para>
Unlock the key.
</para>
<para>
<quote>key</quote> can be static string or string with PVs.
</para>
<para>
<quote>key2</quote> is optional and can be static string or string with PVs.
</para>
<para>
This function can be used from REQUEST_ROUTE, FAILURE_ROUTE,
ONREPLY_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE.
</para>
Expand Down Expand Up @@ -854,4 +863,3 @@ if (rand_event()) {
</section>
</section>
</chapter>