Skip to content

Commit

Permalink
dialog: fix a bug in local profiles counting
Browse files Browse the repository at this point in the history
Fix the counting of local profiles with value when profile replication
is active. Altough the /b profiles were counted correctly, the same
mechanism would be aplied also for other profiles that were not shared,
resulting in a bad value.
  • Loading branch information
rvlad-patrascu committed May 8, 2019
1 parent 6816fa9 commit 3abb14d
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 27 deletions.
35 changes: 29 additions & 6 deletions modules/dialog/dlg_profile.c
Expand Up @@ -665,7 +665,8 @@ static void destroy_linker(struct dlg_profile_link *l, struct dlg_cell *dlg,
dest = map_find( entry, l->value );
if( dest )
{
prof_val_local_dec(dest, dlg);
prof_val_local_dec(dest, dlg,
l->profile->repl_type==REPL_CACHEDB);

if( *dest == 0 )
{
Expand Down Expand Up @@ -799,7 +800,8 @@ static void link_dlg_profile(struct dlg_profile_link *linker,
}
/* if we accept replicated stuff, we have to allocate the
* structure for it and treat the counter differently */
prof_val_local_inc(dest, dlg);
prof_val_local_inc(dest, dlg,
linker->profile->repl_type==REPL_PROTOBIN);
}
else {
cnt = get_local_counter(&linker->profile->noval_local_counters[hash], dlg);
Expand Down Expand Up @@ -1045,7 +1047,8 @@ unsigned int get_profile_size(struct dlg_profile_table *profile, str *value)
goto next_val;
}

n += prof_val_get_count(dest, 0);
n += prof_val_get_count(dest, 0,
profile->repl_type == REPL_PROTOBIN);
next_val:
if (iterator_next(&it) < 0)
break;
Expand Down Expand Up @@ -1080,7 +1083,8 @@ unsigned int get_profile_size(struct dlg_profile_table *profile, str *value)

dest = map_find(entry,*value);
if( dest )
n = prof_val_get_count(dest, 0);
n = prof_val_get_count(dest, 0,
profile->repl_type == REPL_PROTOBIN);

lock_set_release( profile->locks, i);

Expand Down Expand Up @@ -1218,7 +1222,23 @@ static inline int add_val_to_rpl(void * param, str key, void * val)

if (add_mi_string(val_item, MI_SSTR("value"), key.s , key.len) < 0)
return -1;
if (add_mi_number(val_item, MI_SSTR("count"), prof_val_get_count(&val, 0)) < 0)
if (add_mi_number(val_item, MI_SSTR("count"), prof_val_get_count(&val, 0, 0)) < 0)
return -1;

return 0;
}

static inline int add_val_to_rpl_r(void * param, str key, void * val)
{
mi_item_t *val_item;

val_item = add_mi_object((mi_item_t *)param, NULL, 0);
if (!val_item)
return -1;

if (add_mi_string(val_item, MI_SSTR("value"), key.s , key.len) < 0)
return -1;
if (add_mi_number(val_item, MI_SSTR("count"), prof_val_get_count(&val, 0, 1)) < 0)
return -1;

return 0;
Expand Down Expand Up @@ -1271,7 +1291,10 @@ mi_response_t *mi_get_profile_values(const mi_params_t *params,
for( i=0; i<profile->size; i++ )
{
lock_set_get( profile->locks, i);
ret |= map_for_each(profile->entries[i], add_val_to_rpl, resp_arr);
if (profile->repl_type == REPL_PROTOBIN)
ret |= map_for_each(profile->entries[i], add_val_to_rpl_r, resp_arr);
else
ret |= map_for_each(profile->entries[i], add_val_to_rpl, resp_arr);
lock_set_release( profile->locks, i);
}
}
Expand Down
39 changes: 19 additions & 20 deletions modules/dialog/dlg_repl_profile.h
Expand Up @@ -147,12 +147,13 @@ static inline void remove_local_counter(struct prof_local_count **list,
shm_free(cnt);
}

static inline void prof_val_local_inc(void **pv_info, struct dlg_cell *dlg)
static inline void prof_val_local_inc(void **pv_info, struct dlg_cell *dlg,
int is_repl)
{
prof_value_info_t *pvi;
struct prof_local_count *cnt;

if (profile_repl_cluster) {
if (is_repl && profile_repl_cluster) {
/* if info does not exist, create it */
if (!*pv_info) {
pvi = shm_malloc(sizeof(prof_value_info_t));
Expand Down Expand Up @@ -180,33 +181,30 @@ static inline void prof_val_local_inc(void **pv_info, struct dlg_cell *dlg)
}
}

/* @all - all counters(including dialogs tagged as backup) */
/* This function is used only for /b profiles
* @all - all counters(including dialogs tagged as backup) */
static inline int prof_val_get_local_count(void **pv_info, int all)
{
prof_value_info_t *pvi;
struct prof_local_count *cnt;
int n = 0;

if (profile_repl_cluster) {
pvi = (prof_value_info_t *)(*pv_info);
for (cnt = pvi->local_counters; cnt; cnt = cnt->next)
if (!all && dialog_repl_cluster) {
/* don't count dialogs for which we have a backup role */
if (cnt->dlg && (get_shtag_state(cnt->dlg) != SHTAG_STATE_BACKUP))
n += cnt->n;
} else
pvi = (prof_value_info_t *)(*pv_info);
for (cnt = pvi->local_counters; cnt; cnt = cnt->next)
if (!all && dialog_repl_cluster) {
/* don't count dialogs for which we have a backup role */
if (cnt->dlg && (get_shtag_state(cnt->dlg) != SHTAG_STATE_BACKUP))
n += cnt->n;
return n;
} else {
return (int)(long)(*pv_info);
}
} else
n += cnt->n;
return n;
}

/* @all - all counters(including local dialogs tagged as backup) */
static inline int prof_val_get_count(void **pv_info, int all)
static inline int prof_val_get_count(void **pv_info, int all, int is_repl)
{
prof_value_info_t *pvi;
if (profile_repl_cluster) {
if (is_repl && profile_repl_cluster) {
pvi = (prof_value_info_t *)(*pv_info);
return prof_val_get_local_count(pv_info, all) +
replicate_profiles_count(pvi->rcv_counters);
Expand All @@ -215,18 +213,19 @@ static inline int prof_val_get_count(void **pv_info, int all)
}
}

static inline void prof_val_local_dec(void **pv_info, struct dlg_cell *dlg)
static inline void prof_val_local_dec(void **pv_info, struct dlg_cell *dlg,
int is_repl)
{
prof_value_info_t *pvi;

if (profile_repl_cluster) {
if (is_repl && profile_repl_cluster) {
pvi = (prof_value_info_t *)(*pv_info);

remove_local_counter(&pvi->local_counters, dlg);

/* check all the other counters(local + received) to see if we should
* delete the profile */
if (prof_val_get_count(pv_info, 1) == 0) {
if (prof_val_get_count(pv_info, 1, 1) == 0) {
free_profile_val_t(pvi);
*pv_info = 0;
}
Expand Down
2 changes: 1 addition & 1 deletion modules/dialog/dlg_replication.c
Expand Up @@ -1170,7 +1170,7 @@ static void clean_profiles(unsigned int ticks, void *param)
LM_ERR("[BUG] bogus map[%d] state\n", i);
goto next_val;
}
count = prof_val_get_count(dst, 1);
count = prof_val_get_count(dst, 1, 1);
if (!count) {
del = it;
if (iterator_next(&it) < 0)
Expand Down

0 comments on commit 3abb14d

Please sign in to comment.