[sr-dev] git:master: kex: print private memory usage per process via rpc

Daniel-Constantin Mierla miconda at gmail.com
Mon Dec 20 09:54:43 CET 2010


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

Author: Daniel-Constantin Mierla <miconda at gmail.com>
Committer: Daniel-Constantin Mierla <miconda at 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_*/




More information about the sr-dev mailing list