Module: sip-router
Branch: master
Commit: 41f77159c5851bb36ad12abecc2faf58602d6935
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=41f7715…
Author: Alex Balashov <abalashov(a)evaristesys.com>
Committer: Alex Balashov <abalashov(a)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;
+}
+