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