Skip to content

Commit

Permalink
db_flatstore: Fix another race condition around MI 'flat_rotate'
Browse files Browse the repository at this point in the history
This race condition was related to invoking 'flat_rotate' 2+ times
during the same second (UNIX timestamp).  Due to the way the
timestamping logic was implemented, this could lead to files NOT being
rotated at all on the 2nd 'flat_rotate', which falls in the same second.

Although very rare, this race condition could lead to massive CDR loss,
since all CDRs between 2nd and 3rd 'flat_rotate' commands have a great
chance of being fully lost (unread and discarded).

(cherry picked from commit e180b15)
  • Loading branch information
liviuchircu committed Nov 8, 2022
1 parent dcc7cbd commit bcc3837
Show file tree
Hide file tree
Showing 4 changed files with 13 additions and 20 deletions.
4 changes: 1 addition & 3 deletions modules/db_flatstore/flat_mi.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,8 @@ rw_lock_t *rotate_lock;
mi_response_t *mi_flat_rotate_cmd(const mi_params_t *params,
struct mi_handler *async_hdl)
{
time_t now = time(NULL);

lock_start_write(rotate_lock);
*flat_rotate = now;
(*flat_rotate)++;
lock_stop_write(rotate_lock);

return init_mi_result_ok();
Expand Down
4 changes: 2 additions & 2 deletions modules/db_flatstore/flatstore.c
Original file line number Diff line number Diff line change
Expand Up @@ -339,9 +339,9 @@ int flat_db_insert(const db_con_t* h, const db_key_t* k, const db_val_t* v,

lock_start_read(rotate_lock);

if (local_timestamp < *flat_rotate) {
if (my_rotate < *flat_rotate) {
flat_rotate_logs();
local_timestamp = *flat_rotate;
my_rotate = *flat_rotate;
}

if ( !h || !CON_TAIL(h) || (f=CON_FILE(h))==NULL ) {
Expand Down
16 changes: 6 additions & 10 deletions modules/db_flatstore/flatstore_mod.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,10 @@ str flat_prefix_s = {0,0};
pv_elem_t *flat_prefix = NULL;

/*
* Timestamp of the last log rotation request from
* the FIFO interface
* Counter for the last log rotation request from the MI interface
*/
time_t* flat_rotate;

time_t local_timestamp;
unsigned long long *flat_rotate;
unsigned long long my_rotate;

/*
* Flatstore database module interface
Expand Down Expand Up @@ -141,14 +139,12 @@ static int mod_init(void)
return -1;
}

flat_rotate = (time_t*)shm_malloc(sizeof(time_t));
flat_rotate = shm_malloc(sizeof *flat_rotate);
if (!flat_rotate) {
LM_ERR("no shared memory left\n");
return -1;
}

*flat_rotate = time(0);
local_timestamp = *flat_rotate;
*flat_rotate = 0;

if (!(rotate_lock = lock_init_rw())) {
LM_ERR("oom\n");
Expand Down Expand Up @@ -176,7 +172,7 @@ static int mod_init(void)

static void mod_destroy(void)
{
if (flat_rotate) shm_free(flat_rotate);
shm_free(flat_rotate);
}


Expand Down
9 changes: 4 additions & 5 deletions modules/db_flatstore/flatstore_mod.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,17 +51,16 @@ extern char* flat_delimiter;


/*
* The timestamp of log rotation request from
* the FIFO interface
* Counter for the last log rotation request from the MI interface
*/
extern time_t* flat_rotate;
extern unsigned long long *flat_rotate;


/*
* Local timestamp marking the time of the
* Local counter marking the time of the
* last log rotation in the process
*/
extern time_t local_timestamp;
extern unsigned long long my_rotate;


/*
Expand Down

0 comments on commit bcc3837

Please sign in to comment.