[sr-dev] git:master: mqueue: Added MI command to get current size of mqueue.

Alex Balashov abalashov at evaristesys.com
Tue Jul 24 02:11:06 CEST 2012


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

Author: Alex Balashov <abalashov at evaristesys.com>
Committer: Alex Balashov <abalashov at evaristesys.com>
Date:   Mon Jul 23 19:53:41 2012 -0400

mqueue: Added MI command to get current size of mqueue.

There is currently no runtime visibility into the size of a given mqueue.
To address this, added an MI command 'mq_get_size' that can return the size
of an mqueue by name.  Example:

   diminuendo-1:~/sip-router/modules/mqueue# kamctl fifo mq_get_size r_write
   mqueue::  name=r_write size=1

---

 modules/mqueue/Makefile     |    1 +
 modules/mqueue/mqueue_api.c |   16 ++++++++
 modules/mqueue/mqueue_api.h |    2 +
 modules/mqueue/mqueue_mod.c |   82 ++++++++++++++++++++++++++++++++++++++++++-
 4 files changed, 100 insertions(+), 1 deletions(-)

diff --git a/modules/mqueue/Makefile b/modules/mqueue/Makefile
index bbf4862..02a5329 100644
--- a/modules/mqueue/Makefile
+++ b/modules/mqueue/Makefile
@@ -10,6 +10,7 @@ LIBS=
 DEFS+=-DOPENSER_MOD_INTERFACE
 
 SERLIBPATH=../../lib
+SER_LIBS+=$(SERLIBPATH)/kmi/kmi
 SER_LIBS+=$(SERLIBPATH)/kcore/kcore
 
 include ../../Makefile.modules
diff --git a/modules/mqueue/mqueue_api.c b/modules/mqueue/mqueue_api.c
index 7f856f4..4a36909 100644
--- a/modules/mqueue/mqueue_api.c
+++ b/modules/mqueue/mqueue_api.c
@@ -456,3 +456,19 @@ int pv_get_mqv(struct sip_msg *msg, pv_param_t *param,
 	return pv_get_strval(msg, param, res, &mp->item->val);
 }
 
+/* Return head->csize for a given queue */
+
+int _mq_get_csize(str *name) 
+{
+	mq_head_t *mh = mq_head_get(name);
+	int mqueue_size = 0;
+
+	if(mh == NULL)
+		return -1;
+
+	lock_get(&mh->lock);
+	mqueue_size = mh->csize;
+	lock_release(&mh->lock);
+
+	return mqueue_size;
+}
diff --git a/modules/mqueue/mqueue_api.h b/modules/mqueue/mqueue_api.h
index 04ad1e4..cb695f1 100644
--- a/modules/mqueue/mqueue_api.h
+++ b/modules/mqueue/mqueue_api.h
@@ -41,5 +41,7 @@ int mq_head_fetch(str *name);
 void mq_pv_free(str *name);
 int mq_item_add(str *qname, str *key, str *val);
 
+int _mq_get_csize(str *);
+
 #endif
 
diff --git a/modules/mqueue/mqueue_mod.c b/modules/mqueue/mqueue_mod.c
index 458701c..1559c51 100644
--- a/modules/mqueue/mqueue_mod.c
+++ b/modules/mqueue/mqueue_mod.c
@@ -32,6 +32,7 @@
 #include "../../ut.h"
 #include "../../pvar.h"
 #include "../../mod_fix.h"
+#include "../../lib/kmi/mi.h"
 #include "../../parser/parse_param.h"
 #include "../../shm_init.h"
 
@@ -50,6 +51,8 @@ int mq_param(modparam_t type, void *val);
 static int fixup_mq_add(void** param, int param_no);
 static int bind_mq(mq_api_t* api);
 
+static struct mi_root *mq_mi_get_size(struct mi_root *, void *);
+
 static pv_export_t mod_pvs[] = {
 	{ {"mqk", sizeof("mqk")-1}, PVT_OTHER, pv_get_mqk, 0,
 		pv_parse_mq_name, 0, 0, 0 },
@@ -58,6 +61,10 @@ static pv_export_t mod_pvs[] = {
 	{ {0, 0}, 0, 0, 0, 0, 0, 0, 0 }
 };
 
+static mi_export_t mi_cmds[] = {
+	{ "mq_get_size",	mq_mi_get_size,	0, 0, 0},
+	{ 0, 0, 0, 0, 0}
+};
 
 static cmd_export_t cmds[]={
 	{"mq_fetch", (cmd_function)w_mq_fetch, 1, fixup_spve_null,
@@ -82,7 +89,7 @@ struct module_exports exports = {
 	cmds,
 	params,
 	0,
-	0,              /* exported MI functions */
+	mi_cmds,        /* exported MI functions */
 	mod_pvs,        /* exported pseudo-variables */
 	0,              /* extra processes */
 	mod_init,       /* module initialization function */
@@ -100,6 +107,12 @@ static int mod_init(void)
 {
 	if(!mq_head_defined())
 		LM_WARN("no mqueue defined\n");
+
+	if(register_mi_mod(exports.name, mi_cmds) != 0) {
+		LM_ERR("failed to register MI commands\n");
+		return 1;
+	}
+
 	return 0;
 }
 
@@ -237,3 +250,70 @@ static int bind_mq(mq_api_t* api)
 	api->add = mq_item_add;
 	return 0;
 }
+
+/* Return the size of the specified mqueue */
+
+static struct mi_root *mq_mi_get_size(struct mi_root *cmd_tree, 
+				      void *param)
+{
+	static struct mi_node	*node = NULL, *rpl = NULL;
+	static struct mi_root	*rpl_tree = NULL;
+	static struct mi_attr	*attr = NULL;
+	str			mqueue_name;
+	int			mqueue_sz = 0;
+	char			*p = NULL;
+	int			len = 0;
+
+	if((node = cmd_tree->node.kids) == NULL) {
+		return init_mi_tree(400, MI_MISSING_PARM_S, 
+					 MI_MISSING_PARM_LEN);
+	}
+
+	mqueue_name = node->value;
+
+	if(mqueue_name.len <= 0 || mqueue_name.s == NULL) {
+		LM_ERR("bad mqueue name\n");
+		return init_mi_tree(500, MI_SSTR("bad mqueue name"));
+	}
+
+	mqueue_sz = _mq_get_csize(&mqueue_name);
+
+	if(mqueue_sz < 0) {
+		LM_ERR("no such mqueue\n");
+		return init_mi_tree(404, MI_SSTR("no such mqueue"));
+	}
+
+	rpl_tree = init_mi_tree(200, MI_OK_S, MI_OK_LEN);
+
+	if(rpl_tree == NULL) 
+		return 0;
+
+	rpl = &rpl_tree->node;
+
+	node = add_mi_node_child(rpl, MI_DUP_VALUE, "mqueue", strlen("mqueue"),
+				 NULL, 0);
+
+	if(node == NULL) {
+		free_mi_tree(rpl_tree);
+		return NULL;
+	}
+
+	attr = add_mi_attr(node, MI_DUP_VALUE, "name", strlen("name"),
+			   mqueue_name.s, mqueue_name.len);
+
+	if(attr == NULL) goto error;
+
+	p = int2str((unsigned long) mqueue_sz, &len);	
+
+	attr = add_mi_attr(node, MI_DUP_VALUE, "size", strlen("size"), 
+			   p, len);
+
+	if(attr == NULL) goto error;
+
+	return rpl_tree;
+
+error:
+	free_mi_tree(rpl_tree);
+	return NULL;
+}
+




More information about the sr-dev mailing list