[sr-dev] git:master:8f0fc94a: tm: rpc command to clean long time expired transactions

Daniel-Constantin Mierla miconda at gmail.com
Thu Sep 14 09:23:42 CEST 2017


Module: kamailio
Branch: master
Commit: 8f0fc94aaa6db96ef209c6136240d98ef566a004
URL: https://github.com/kamailio/kamailio/commit/8f0fc94aaa6db96ef209c6136240d98ef566a004

Author: Daniel-Constantin Mierla <miconda at gmail.com>
Committer: Daniel-Constantin Mierla <miconda at 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/8f0fc94aaa6db96ef209c6136240d98ef566a004.diff
Patch: https://github.com/kamailio/kamailio/commit/8f0fc94aaa6db96ef209c6136240d98ef566a004.patch

---

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}
 };
 




More information about the sr-dev mailing list