Module: kamailio Branch: master Commit: 8f0fc94aaa6db96ef209c6136240d98ef566a004 URL: https://github.com/kamailio/kamailio/commit/8f0fc94aaa6db96ef209c6136240d98e...
Author: Daniel-Constantin Mierla miconda@gmail.com Committer: Daniel-Constantin Mierla miconda@gmail.com Date: 2017-09-14T09:21:08+02:00
tm: rpc command to clean long time expired transactions
- try hard clean after 90 seconds since lifetime elapsed
---
Modified: src/modules/tm/h_table.c Modified: src/modules/tm/h_table.h Modified: src/modules/tm/t_stats.c Modified: src/modules/tm/t_stats.h Modified: src/modules/tm/tm.c
---
Diff: https://github.com/kamailio/kamailio/commit/8f0fc94aaa6db96ef209c6136240d98e... Patch: https://github.com/kamailio/kamailio/commit/8f0fc94aaa6db96ef209c6136240d98e...
---
diff --git a/src/modules/tm/h_table.c b/src/modules/tm/h_table.c index 19b5daec0b..ee79b91fd3 100644 --- a/src/modules/tm/h_table.c +++ b/src/modules/tm/h_table.c @@ -575,3 +575,62 @@ void tm_xdata_replace(tm_xdata_t *newxd, tm_xlinks_t *bakxd) return; } } + +void tm_log_transaction(tm_cell_t *tcell, int llev, char *ltext) +{ + LOG(llev, "%s [start] transaction %p\n", ltext, tcell); + LOG(llev, "%s - tindex=%u tlabel=%u method='%.*s' from='%.*s'" + " to='%.*s' callid='%.*s' cseq='%.*s' uas_request=%s" + " tflags=%u outgoings=%u ref_count=%u lifetime=%u\n", + ltext, (unsigned)tcell->hash_index, (unsigned)tcell->label, + tcell->method.len, tcell->method.s, + tcell->from.len, tcell->from.s, + tcell->to.len, tcell->to.s, + tcell->callid.len, tcell->callid.s, + tcell->cseq_n.len, tcell->cseq_n.s, + (tcell->uas.request)?"yes":"no", + (unsigned)tcell->flags, + (unsigned)tcell->nr_of_outgoings, +#ifdef TM_DEL_UNREF + (unsigned)atomic_get(&tcell->ref_count), +#else + tcell->ref_count, +#endif + (unsigned)TICKS_TO_S(tcell->end_of_life) + ); + + LOG(llev, "%s [end] transaction %p\n", ltext, tcell); +} + +#define TM_LIFETIME_LIMIT 90 +/* clean active but very old transactions */ +void tm_clean_lifetime(void) +{ + int r; + tm_cell_t *tcell; + ticks_t texp; + + texp = get_ticks_raw() - S_TO_TICKS(TM_LIFETIME_LIMIT); + + for (r=0; r<TABLE_ENTRIES; r++) { + /* faster first try without lock */ + if(clist_empty(&_tm_table->entries[r], next_c)) { + continue; + } + lock_hash(r); + /* one more time with lock to be avoid any cpu races */ + if(clist_empty(&_tm_table->entries[r], next_c)) { + unlock_hash(r); + continue; + } + + clist_foreach(&_tm_table->entries[r], tcell, next_c) + { + if(TICKS_GT(texp, tcell->end_of_life)) { + tm_log_transaction(tcell, L_WARN, "[hard cleanup]"); + free_cell(tcell); + } + } + unlock_hash(r); + } +} diff --git a/src/modules/tm/h_table.h b/src/modules/tm/h_table.h index 904709579a..7d61ae3673 100644 --- a/src/modules/tm/h_table.h +++ b/src/modules/tm/h_table.h @@ -607,6 +607,8 @@ inline static void remove_from_hash_table_unsafe(struct cell *p_cell) t_stats_deleted(is_local(p_cell)); }
+void tm_clean_lifetime(void); + /** * backup xdata from/to msg context to local var and use T lists */ diff --git a/src/modules/tm/t_stats.c b/src/modules/tm/t_stats.c index d6ae5f52e4..6b26aedba0 100644 --- a/src/modules/tm/t_stats.c +++ b/src/modules/tm/t_stats.c @@ -252,7 +252,7 @@ void tm_rpc_hash_stats(rpc_t* rpc, void* c) #endif /* TM_HASH_STATS */ }
-/* hash statistics */ +/* list active transactions */ void tm_rpc_list(rpc_t* rpc, void* c) { int r; @@ -294,3 +294,10 @@ void tm_rpc_list(rpc_t* rpc, void* c) unlock_hash(r); } } + + +/* rpc command to clean active but very old transactions */ +void tm_rpc_clean(rpc_t* rpc, void* c) +{ + tm_clean_lifetime(); +} diff --git a/src/modules/tm/t_stats.h b/src/modules/tm/t_stats.h index 0a0057c620..bd21befd0f 100644 --- a/src/modules/tm/t_stats.h +++ b/src/modules/tm/t_stats.h @@ -150,5 +150,6 @@ void tm_rpc_hash_stats(rpc_t* rpc, void* c); typedef int (*tm_get_stats_f)(struct t_proc_stats *all); int tm_get_stats(struct t_proc_stats *all); void tm_rpc_list(rpc_t* rpc, void* c); +void tm_rpc_clean(rpc_t* rpc, void* c);
#endif diff --git a/src/modules/tm/tm.c b/src/modules/tm/tm.c index 7adaa8796d..9bc1695a0f 100644 --- a/src/modules/tm/tm.c +++ b/src/modules/tm/tm.c @@ -2521,6 +2521,11 @@ static const char* tm_rpc_list_doc[2] = { 0 };
+static const char* tm_rpc_clean_doc[2] = { + "Clean expired (lifetime exceeded) transactions.", + 0 +}; +
/* rpc exports */ static rpc_export_t tm_rpc[] = { @@ -2532,6 +2537,7 @@ static rpc_export_t tm_rpc[] = { {"tm.t_uac_start", rpc_t_uac_start, rpc_t_uac_start_doc, 0 }, {"tm.t_uac_wait", rpc_t_uac_wait, rpc_t_uac_wait_doc, RET_ARRAY}, {"tm.list", tm_rpc_list, tm_rpc_list_doc, RET_ARRAY}, + {"tm.clean", tm_rpc_clean, tm_rpc_clean_doc, 0}, {0, 0, 0, 0} };
On donderdag 14 september 2017 09:23:42 CEST Daniel-Constantin Mierla wrote:
tm: rpc command to clean long time expired transactions
- try hard clean after 90 seconds since lifetime elapsed
Why an RPC function? Shouldn't these transactions be automatically cleaned by kamailio? Wouldn't integrating this in the already existing tm timer functions be a better solution?
On 22.09.17 17:51, Alex Hermann wrote:
On donderdag 14 september 2017 09:23:42 CEST Daniel-Constantin Mierla wrote:
tm: rpc command to clean long time expired transactions
- try hard clean after 90 seconds since lifetime elapsed
Why an RPC function? Shouldn't these transactions be automatically cleaned by kamailio? Wouldn't integrating this in the already existing tm timer functions be a better solution?
This is to help troubleshooting issue #1220.
Daniel