Module: kamailio
Branch: master
Commit: 8f0fc94aaa6db96ef209c6136240d98ef566a004
URL:
https://github.com/kamailio/kamailio/commit/8f0fc94aaa6db96ef209c6136240d98…
Author: Daniel-Constantin Mierla <miconda(a)gmail.com>
Committer: Daniel-Constantin Mierla <miconda(a)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/8f0fc94aaa6db96ef209c6136240d98…
Patch:
https://github.com/kamailio/kamailio/commit/8f0fc94aaa6db96ef209c6136240d98…
---
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}
};