[sr-dev] git:master: uac: new rpc command - uac.reg_reload

Daniel-Constantin Mierla miconda at gmail.com
Tue Jul 22 17:35:25 CEST 2014


Module: sip-router
Branch: master
Commit: 99da07de696c1f5368bf74ea82fe7df7f8db61a0
URL:    http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=99da07de696c1f5368bf74ea82fe7df7f8db61a0

Author: Daniel-Constantin Mierla <miconda at gmail.com>
Committer: Daniel-Constantin Mierla <miconda at gmail.com>
Date:   Tue Jul 22 13:33:24 2014 +0200

uac: new rpc command - uac.reg_reload

- reload the records from database
- old records are kept for at least 150sec more to be sure no active
  registration process is using them
- therefore reload cannot executed more often than 150sec

---

 modules/uac/uac_reg.c |  164 ++++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 154 insertions(+), 10 deletions(-)

diff --git a/modules/uac/uac_reg.c b/modules/uac/uac_reg.c
index da3fdd0..f1344be 100644
--- a/modules/uac/uac_reg.c
+++ b/modules/uac/uac_reg.c
@@ -50,6 +50,7 @@
 #define UAC_REG_AUTHSENT	(1<<3)
 
 #define MAX_UACH_SIZE 2048
+#define UAC_REG_GC_INTERVAL	150
 
 typedef struct _reg_uac
 {
@@ -88,10 +89,13 @@ typedef struct _reg_entry
 typedef struct _reg_ht
 {
 	unsigned int htsize;
+	time_t stime;
 	reg_entry_t *entries;
 } reg_ht_t;
 
 static reg_ht_t *_reg_htable = NULL;
+static reg_ht_t *_reg_htable_gc = NULL;
+static gen_lock_t *_reg_htable_gc_lock = NULL;
 
 int reg_use_domain = 0;
 int reg_timer_interval = 90;
@@ -168,10 +172,50 @@ int uac_reg_init_ht(unsigned int sz)
 {
 	int i;
 
+	_reg_htable_gc_lock = (gen_lock_t*)shm_malloc(sizeof(gen_lock_t));
+	if(_reg_htable_gc_lock == NULL)
+	{
+		LM_ERR("no more shm for lock\n");
+		return -1;
+	}
+	if(lock_init(_reg_htable_gc_lock)==0)
+	{
+		LM_ERR("cannot init global lock\n");
+		shm_free((void*)_reg_htable_gc_lock);
+		return -1;
+	}
+	_reg_htable_gc = (reg_ht_t*)shm_malloc(sizeof(reg_ht_t));
+	if(_reg_htable_gc==NULL)
+	{
+		LM_ERR("no more shm\n");
+		lock_destroy(_reg_htable_gc_lock);
+		shm_free((void*)_reg_htable_gc_lock);
+		return -1;
+	}
+	memset(_reg_htable_gc, 0, sizeof(reg_ht_t));
+	_reg_htable_gc->htsize = sz;
+
+	_reg_htable_gc->entries =
+			(reg_entry_t*)shm_malloc(_reg_htable_gc->htsize*sizeof(reg_entry_t));
+	if(_reg_htable_gc->entries==NULL)
+	{
+		LM_ERR("no more shm.\n");
+		shm_free(_reg_htable_gc);
+		lock_destroy(_reg_htable_gc_lock);
+		shm_free((void*)_reg_htable_gc_lock);
+		return -1;
+	}
+	memset(_reg_htable_gc->entries, 0, _reg_htable_gc->htsize*sizeof(reg_entry_t));
+
+
 	_reg_htable = (reg_ht_t*)shm_malloc(sizeof(reg_ht_t));
 	if(_reg_htable==NULL)
 	{
 		LM_ERR("no more shm\n");
+		shm_free(_reg_htable_gc->entries);
+		shm_free(_reg_htable_gc);
+		lock_destroy(_reg_htable_gc_lock);
+		shm_free((void*)_reg_htable_gc_lock);
 		return -1;
 	}
 	memset(_reg_htable, 0, sizeof(reg_ht_t));
@@ -182,7 +226,11 @@ int uac_reg_init_ht(unsigned int sz)
 	if(_reg_htable->entries==NULL)
 	{
 		LM_ERR("no more shm.\n");
+		shm_free(_reg_htable_gc->entries);
+		shm_free(_reg_htable_gc);
 		shm_free(_reg_htable);
+		lock_destroy(_reg_htable_gc_lock);
+		shm_free((void*)_reg_htable_gc_lock);
 		return -1;
 	}
 	memset(_reg_htable->entries, 0, _reg_htable->htsize*sizeof(reg_entry_t));
@@ -199,6 +247,10 @@ int uac_reg_init_ht(unsigned int sz)
 			}
 			shm_free(_reg_htable->entries);
 			shm_free(_reg_htable);
+			shm_free(_reg_htable_gc->entries);
+			shm_free(_reg_htable_gc);
+			lock_destroy(_reg_htable_gc_lock);
+			shm_free((void*)_reg_htable_gc_lock);
 			return -1;
 		}
 	}
@@ -215,6 +267,37 @@ int uac_reg_free_ht(void)
 	reg_item_t *it = NULL;
 	reg_item_t *it0 = NULL;
 
+	if(_reg_htable_gc_lock != NULL)
+	{
+		lock_destroy(_reg_htable_gc_lock);
+		shm_free((void*)_reg_htable_gc_lock);
+		_reg_htable_gc_lock = NULL;
+	}
+	if(_reg_htable_gc!=NULL)
+	{
+		for(i=0; i<_reg_htable_gc->htsize; i++)
+		{
+			it = _reg_htable_gc->entries[i].byuuid;
+			while(it)
+			{
+				it0 = it;
+				it = it->next;
+				shm_free(it0);
+			}
+			it = _reg_htable_gc->entries[i].byuser;
+			while(it)
+			{
+				it0 = it;
+				it = it->next;
+				shm_free(it0->r);
+				shm_free(it0);
+			}
+		}
+		shm_free(_reg_htable_gc->entries);
+		shm_free(_reg_htable_gc);
+		_reg_htable_gc = NULL;
+	}
+
 	if(_reg_htable==NULL)
 	{
 		LM_DBG("no hash table\n");
@@ -250,31 +333,30 @@ int uac_reg_free_ht(void)
 /**
  *
  */
-int uac_reg_reset_ht(void)
+int uac_reg_reset_ht_gc(void)
 {
 	int i;
 	reg_item_t *it = NULL;
 	reg_item_t *it0 = NULL;
 
-	if(_reg_htable==NULL)
+	if(_reg_htable_gc==NULL)
 	{
 		LM_DBG("no hash table\n");
 		return -1;
 	}
-	for(i=0; i<_reg_htable->htsize; i++)
+	for(i=0; i<_reg_htable_gc->htsize; i++)
 	{
-		lock_get(&_reg_htable->entries[i].lock);
 		/* free entries */
-		it = _reg_htable->entries[i].byuuid;
+		it = _reg_htable_gc->entries[i].byuuid;
 		while(it)
 		{
 			it0 = it;
 			it = it->next;
 			shm_free(it0);
 		}
-		_reg_htable->entries[i].byuuid = NULL;
-		_reg_htable->entries[i].isize=0;
-		it = _reg_htable->entries[i].byuser;
+		_reg_htable_gc->entries[i].byuuid = NULL;
+		_reg_htable_gc->entries[i].isize=0;
+		it = _reg_htable_gc->entries[i].byuser;
 		while(it)
 		{
 			it0 = it;
@@ -282,10 +364,48 @@ int uac_reg_reset_ht(void)
 			shm_free(it0->r);
 			shm_free(it0);
 		}
+		_reg_htable_gc->entries[i].byuser = NULL;
+		_reg_htable_gc->entries[i].usize = 0;
+	}
+	return 0;
+}
+
+/**
+ *
+ */
+int uac_reg_ht_shift(void)
+{
+	time_t tn;
+	int i;
+
+	if(_reg_htable==NULL || _reg_htable_gc==NULL)
+	{
+		LM_ERR("data struct invalid\n");
+		return -1;
+	}
+	tn = time(NULL);
+
+	lock_get(_reg_htable_gc_lock);
+	if(_reg_htable_gc->stime > tn-UAC_REG_GC_INTERVAL) {
+		lock_release(_reg_htable_gc_lock);
+		LM_ERR("shifting the memory table is not possible in less than %d\n", UAC_REG_GC_INTERVAL);
+		return -1;
+	}
+	uac_reg_reset_ht_gc();
+	for(i=0; i<_reg_htable->htsize; i++)
+	{
+		/* shift entries */
+		_reg_htable_gc->entries[i].byuuid = _reg_htable->entries[i].byuuid;
+		_reg_htable_gc->entries[i].byuser = _reg_htable->entries[i].byuser;
+		_reg_htable_gc->stime = time(NULL);
+
+		/* reset active table entries */
+		_reg_htable->entries[i].byuuid = NULL;
+		_reg_htable->entries[i].isize=0;
 		_reg_htable->entries[i].byuser = NULL;
 		_reg_htable->entries[i].usize = 0;
-		lock_release(&_reg_htable->entries[i].lock);
 	}
+	lock_release(_reg_htable_gc_lock);
 	return 0;
 }
 
@@ -989,12 +1109,16 @@ int uac_reg_load_db(void)
 		}
 	}  while(RES_ROW_N(db_res)>0);
 	reg_dbf.free_result(reg_db_con, db_res);
+	reg_dbf.close(reg_db_con);
 
 done:
 	return 0;
 
 error:
-	reg_dbf.free_result(reg_db_con, db_res);
+	if (reg_db_con) {
+		reg_dbf.free_result(reg_db_con, db_res);
+		reg_dbf.close(reg_db_con);
+	}
 	return -1;
 }
 
@@ -1385,13 +1509,33 @@ static void rpc_uac_reg_disable(rpc_t* rpc, void* ctx)
 	rpc_uac_reg_update_flag(rpc, ctx, 0, UAC_REG_DISABLED);
 }
 
+static const char* rpc_uac_reg_reload_doc[2] = {
+	"Reload records from database.",
+	0
+};
 
+static void rpc_uac_reg_reload(rpc_t* rpc, void* ctx)
+{
+	int ret;
+	if(uac_reg_ht_shift()<0) {
+		rpc->fault(ctx, 500, "Failed to shift records - check log messages");
+		return;
+	}
+	lock_get(_reg_htable_gc_lock);
+	ret =  uac_reg_load_db();
+	lock_release(_reg_htable_gc_lock);
+	if(ret<0) {
+		rpc->fault(ctx, 500, "Failed to reload records - check log messages");
+		return;
+	}
+}
 
 rpc_export_t uac_reg_rpc[] = {
 	{"uac.reg_dump", rpc_uac_reg_dump, rpc_uac_reg_dump_doc, 0},
 	{"uac.reg_info", rpc_uac_reg_info, rpc_uac_reg_info_doc, 0},
 	{"uac.reg_enable",  rpc_uac_reg_enable,  rpc_uac_reg_enable_doc,  0},
 	{"uac.reg_disable", rpc_uac_reg_disable, rpc_uac_reg_disable_doc, 0},
+	{"uac.reg_reload",  rpc_uac_reg_reload,  rpc_uac_reg_reload_doc,  0},
 	{0, 0, 0, 0}
 };
 




More information about the sr-dev mailing list