Module: sip-router
Branch: master
Commit: 829b7ff2e663c3ab7cc4ea95d2831eabef57b543
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=829b7ff…
Author: Daniel-Constantin Mierla <miconda(a)gmail.com>
Committer: Daniel-Constantin Mierla <miconda(a)gmail.com>
Date: Mon Dec 20 09:51:05 2010 +0100
kex: print private memory usage per process via rpc
- new rpc command pkg.stats that prints used, free and real_used metrics
per process for private memory (pkg)
- you can see how much pkg each process is eating and how much is still
available
- should be useful to track pkg memory leaks and/or trigger alerts when
there is no more pkg available
---
modules_k/kex/kex_mod.c | 18 +++-
modules_k/kex/pkg_stats.c | 249 +++++++++++++++++++++++++++++++++++++++++++++
modules_k/kex/pkg_stats.h | 39 +++++++
3 files changed, 305 insertions(+), 1 deletions(-)
diff --git a/modules_k/kex/kex_mod.c b/modules_k/kex/kex_mod.c
index d0d7525..c6b55b4 100644
--- a/modules_k/kex/kex_mod.c
+++ b/modules_k/kex/kex_mod.c
@@ -36,6 +36,7 @@
#include "km_core.h"
#include "mi_core.h"
#include "core_stats.h"
+#include "pkg_stats.h"
MODULE_VERSION
@@ -47,6 +48,7 @@ MODULE_VERSION
int w_is_myself(struct sip_msg *msg, char *uri, str *s2);
static int mod_init(void);
+static int child_init(int rank);
static void destroy(void);
static cmd_export_t cmds[]={
@@ -106,7 +108,7 @@ struct module_exports exports= {
mod_init, /* module initialization function */
0,
(destroy_function) destroy,
- 0 /* per-child init function */
+ child_init /* per-child init function */
};
/**
@@ -122,10 +124,24 @@ static int mod_init(void)
if(register_mi_stats()<0)
return -1;
#endif
+ register_pkg_proc_stats();
+ pkg_proc_stats_init_rpc();
return 0;
}
/**
+ *
+ */
+static int child_init(int rank)
+{
+ LM_DBG("rank is (%d)\n", rank);
+ if (rank==PROC_INIT)
+ return pkg_proc_stats_init();
+ return pkg_proc_stats_myinit(rank);
+}
+
+
+/**
* destroy function
*/
static void destroy(void)
diff --git a/modules_k/kex/pkg_stats.c b/modules_k/kex/pkg_stats.c
new file mode 100644
index 0000000..7a8d9c3
--- /dev/null
+++ b/modules_k/kex/pkg_stats.c
@@ -0,0 +1,249 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2010 Daniel-Constantin Mierla (
asipto.com)
+ *
+ * This file is part of Kamailio, a free SIP server.
+ *
+ * Kamailio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Kamailio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+/*!
+ * \file
+ * \brief Kamailio pkg statistics
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "../../dprint.h"
+#include "../../ut.h"
+#include "../../pt.h"
+#include "../../events.h"
+#include "../../mem/mem.h"
+#include "../../mem/shm_mem.h"
+#include "../../rpc.h"
+#include "../../rpc_lookup.h"
+
+
+/**
+ *
+ */
+typedef struct pkg_proc_stats {
+ int rank;
+ unsigned int pid;
+ unsigned int used;
+ unsigned int available;
+ unsigned int real_used;
+} pkg_proc_stats_t;
+
+/**
+ *
+ */
+static pkg_proc_stats_t *_pkg_proc_stats_list = NULL;
+
+/**
+ *
+ */
+static int _pkg_proc_stats_no = 0;
+
+/**
+ *
+ */
+int pkg_proc_stats_init(void)
+{
+ _pkg_proc_stats_no = get_max_procs();
+
+ if(_pkg_proc_stats_no<=0)
+ return -1;
+ if(_pkg_proc_stats_list!=NULL)
+ return -1;
+ _pkg_proc_stats_list = (pkg_proc_stats_t*)shm_malloc(
+ _pkg_proc_stats_no*sizeof(pkg_proc_stats_t));
+ if(_pkg_proc_stats_list==NULL)
+ return -1;
+ memset(_pkg_proc_stats_list, 0,
+ _pkg_proc_stats_no*sizeof(pkg_proc_stats_t));
+ return 0;
+}
+
+/**
+ *
+ */
+int pkg_proc_stats_myinit(int rank)
+{
+ struct mem_info info;
+ if(_pkg_proc_stats_list==NULL)
+ return -1;
+ if(process_no>=_pkg_proc_stats_no)
+ return -1;
+ _pkg_proc_stats_list[process_no].pid = (unsigned int)my_pid();
+ _pkg_proc_stats_list[process_no].rank = rank;
+
+ /* init pkg usage values */
+ pkg_info(&info);
+ _pkg_proc_stats_list[process_no].used = info.used;
+ _pkg_proc_stats_list[process_no].real_used = info.real_used;
+ return 0;
+}
+
+/**
+ *
+ */
+int pkg_proc_stats_destroy(void)
+{
+ if(_pkg_proc_stats_list==NULL)
+ return -1;
+ shm_free(_pkg_proc_stats_list);
+ _pkg_proc_stats_list = 0;
+ _pkg_proc_stats_no = 0;
+ return 0;
+}
+
+
+/**
+ *
+ */
+static int pkg_proc_update_used(void *data)
+{
+ if(_pkg_proc_stats_list==NULL)
+ return -1;
+ if(process_no>=_pkg_proc_stats_no)
+ return -1;
+ _pkg_proc_stats_list[process_no].used = (unsigned int)data;
+ return 0;
+}
+
+/**
+ *
+ */
+static int pkg_proc_update_real_used(void *data)
+{
+ if(_pkg_proc_stats_list==NULL)
+ return -1;
+ if(process_no>=_pkg_proc_stats_no)
+ return -1;
+ _pkg_proc_stats_list[process_no].real_used = (unsigned int)data;
+ _pkg_proc_stats_list[process_no].available = pkg_available();
+ return 0;
+}
+
+/**
+ *
+ */
+int register_pkg_proc_stats(void)
+{
+ sr_event_register_cb(SREV_PKG_SET_USED, pkg_proc_update_used);
+ sr_event_register_cb(SREV_PKG_SET_REAL_USED, pkg_proc_update_real_used);
+ return 0;
+}
+
+/**
+ *
+ */
+static const char* rpc_pkg_stats_doc[2] = {
+ "Private memory (pkg) statistics per process",
+ 0
+};
+
+/**
+ *
+ */
+int pkg_proc_get_pid_index(unsigned int pid)
+{
+ int i;
+ for(i=0; i<_pkg_proc_stats_no; i++)
+ {
+ if(_pkg_proc_stats_list[i].pid == pid)
+ return i;
+ }
+ return -1;
+}
+
+/**
+ *
+ */
+static void rpc_pkg_stats(rpc_t* rpc, void* ctx)
+{
+ int i;
+ int limit;
+ int lpid;
+ void* th;
+
+ if(_pkg_proc_stats_list==NULL)
+ {
+ rpc->fault(ctx, 500, "Not initialized");
+ return;
+ }
+ i = 0;
+ limit = _pkg_proc_stats_no;
+ if (rpc->scan(ctx, "*d", &lpid) == 1)
+ {
+ i = pkg_proc_get_pid_index((unsigned int)lpid);
+ if(i<0)
+ {
+ rpc->fault(ctx, 500, "No such pid");
+ return;
+ }
+ limit = i + 1;
+ }
+
+ for(; i<limit; i++)
+ {
+ /* add entry node */
+ if (rpc->add(ctx, "{", &th) < 0)
+ {
+ rpc->fault(ctx, 500, "Internal error creating rpc");
+ return;
+ }
+ if(rpc->struct_add(th, "dddddd",
+ "entry", i,
+ "pid", _pkg_proc_stats_list[i].pid,
+ "rank", _pkg_proc_stats_list[i].rank,
+ "used", _pkg_proc_stats_list[i].used,
+ "free", _pkg_proc_stats_list[i].available,
+ "real_used", _pkg_proc_stats_list[i].real_used
+ )<0)
+ {
+ rpc->fault(ctx, 500, "Internal error creating rpc");
+ return;
+ }
+ }
+}
+
+/**
+ *
+ */
+rpc_export_t kex_pkg_rpc[] = {
+ {"pkg.stats", rpc_pkg_stats, rpc_pkg_stats_doc, 0},
+ {0, 0, 0, 0}
+};
+
+/**
+ *
+ */
+int pkg_proc_stats_init_rpc(void)
+{
+ if (rpc_register_array(kex_pkg_rpc)!=0)
+ {
+ LM_ERR("failed to register RPC commands\n");
+ return -1;
+ }
+ return 0;
+}
+
diff --git a/modules_k/kex/pkg_stats.h b/modules_k/kex/pkg_stats.h
new file mode 100644
index 0000000..4f42758
--- /dev/null
+++ b/modules_k/kex/pkg_stats.h
@@ -0,0 +1,39 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2010 Daniel-Constantin Mierla (
asipto.com)
+ *
+ * This file is part of Kamailio, a free SIP server.
+ *
+ * Kamailio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Kamailio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+/*!
+ * \file
+ * \brief Kamailio pkg statistics
+ */
+
+
+#ifndef _PKG_STATS_H_
+#define _PKG_STATS_H_
+
+int pkg_proc_stats_init(void);
+int pkg_proc_stats_myinit(int rank);
+int pkg_proc_stats_destroy(void);
+int register_pkg_proc_stats(void);
+int pkg_proc_stats_init_rpc(void);
+
+#endif /*_PKG_STATS_H_*/