Hi, The following patch adds a new module called "ipc", which gathers data from the OS IPC resources, like semaphores in use, message queues or bytes in shared memory.
It's useful when some applications get an IPC resource, but do not unlock it on exit. The module was developed from master branch version, and was tested in Linux and AIX7, but might work fine for AIX5 and 6 too. The AIX port was developed by Manuel L. Sanmartin, so credits for him. Enjoy! -- Regards, Andrés J. Díaz
diff --git a/README b/README
index 811c594..37e7149 100644
--- a/README
+++ b/README
@@ -103,6 +103,10 @@ Features
Interface traffic: Number of octets, packets and errors for each
interface.
+ - ipc
+ IPC counters: semaphores used, number of allocated segments in shared
+ memory and more.
+
- iptables
Iptables' counters: Number of bytes that were matched by a certain
iptables rule.
diff --git a/configure.in b/configure.in
index 8db24ca..d7a47b8 100644
--- a/configure.in
+++ b/configure.in
@@ -4327,6 +4327,7 @@ plugin_curl_xml="no"
plugin_df="no"
plugin_disk="no"
plugin_entropy="no"
+plugin_ipc="no"
plugin_interface="no"
plugin_ipmi="no"
plugin_ipvs="no"
@@ -4362,6 +4363,7 @@ then
plugin_cpu="yes"
plugin_cpufreq="yes"
plugin_disk="yes"
+ plugin_ipc="yes"
plugin_entropy="yes"
plugin_interface="yes"
plugin_irq="yes"
@@ -4636,6 +4638,7 @@ AC_PLUGIN([filecount], [yes], [Count files in directories])
AC_PLUGIN([fscache], [$plugin_fscache], [fscache statistics])
AC_PLUGIN([gmond], [$with_libganglia], [Ganglia plugin])
AC_PLUGIN([hddtemp], [yes], [Query hddtempd])
+AC_PLUGIN([ipc], [$plugin_ipc], [IPC statistics])
AC_PLUGIN([interface], [$plugin_interface], [Interface traffic statistics])
AC_PLUGIN([ipmi], [$plugin_ipmi], [IPMI sensor statistics])
AC_PLUGIN([iptables], [$with_libiptc], [IPTables rule counters])
@@ -4963,6 +4966,7 @@ Configuration:
fscache . . . . . . . $enable_fscache
gmond . . . . . . . . $enable_gmond
hddtemp . . . . . . . $enable_hddtemp
+ ipc . . . . . . . . . $enable_ipc
interface . . . . . . $enable_interface
ipmi . . . . . . . . $enable_ipmi
iptables . . . . . . $enable_iptables
diff --git a/src/Makefile.am b/src/Makefile.am
index 5728144..524400c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -469,6 +469,14 @@ collectd_LDADD += "-dlopen" ipvs.la
collectd_DEPENDENCIES += ipvs.la
endif
+if BUILD_PLUGIN_IPC
+pkglib_LTLIBRARIES += ipc.la
+ipc_la_SOURCES = ipc.c
+ipc_la_LDFLAGS = -module -avoid-version
+collectd_LDADD += "-dlopen" ipc.la
+collectd_DEPENDENCIES += ipc.la
+endif
+
if BUILD_PLUGIN_IRQ
pkglib_LTLIBRARIES += irq.la
irq_la_SOURCES = irq.c
diff --git a/src/collectd.conf.in b/src/collectd.conf.in
index 94cf2a9..e9fa46c 100644
--- a/src/collectd.conf.in
+++ b/src/collectd.conf.in
@@ -79,6 +79,7 @@
#@BUILD_PLUGIN_GMOND_TRUE@LoadPlugin gmond
#@BUILD_PLUGIN_HDDTEMP_TRUE@LoadPlugin hddtemp
@BUILD_PLUGIN_INTERFACE_TRUE@@BUILD_PLUGIN_INTERFACE_TRUE@LoadPlugin interface
+@BUILD_PLUGIN_IPC_TRUE@@BUILD_PLUGIN_IPC_TRUE@LoadPlugin ipc
#@BUILD_PLUGIN_IPTABLES_TRUE@LoadPlugin iptables
#@BUILD_PLUGIN_IPMI_TRUE@LoadPlugin ipmi
#@BUILD_PLUGIN_IPVS_TRUE@LoadPlugin ipvs
diff --git a/src/ipc.c b/src/ipc.c
new file mode 100644
index 0000000..c10cdb1
--- /dev/null
+++ b/src/ipc.c
@@ -0,0 +1,308 @@
+/**
+ * collectd - src/ipc.c, based on src/memcached.c
+ * Copyright (C) 2010 Andres J. Diaz <[email protected]>
+ * Copyright (C) 2010 Manuel L. Sanmartin <[email protected]>
+ *
+ * This program 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.
+ *
+ * This program 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.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors:
+ * Andres J. Diaz <[email protected]>
+ * Manuel L. Sanmartin <manuel.luis@gmail>
+ **/
+
+/* Many of this code is based on busybox ipc implementation, which is:
+ * (C) Rodney Radford <[email protected]> and distributed under GPLv2.
+ */
+
+#include "collectd.h"
+#include "common.h"
+#include "plugin.h"
+#include "configfile.h"
+
+#if KERNEL_LINUX
+ /* X/OPEN tells us to use <sys/{types,ipc,sem}.h> for semctl() */
+ /* X/OPEN tells us to use <sys/{types,ipc,msg}.h> for msgctl() */
+ /* X/OPEN tells us to use <sys/{types,ipc,shm}.h> for shmctl() */
+# include <sys/types.h>
+# include <sys/ipc.h>
+# include <sys/sem.h>
+# include <sys/msg.h>
+# include <sys/shm.h>
+
+ /* For older kernels the same holds for the defines below */
+# ifndef MSG_STAT
+# define MSG_STAT 11
+# define MSG_INFO 12
+# endif
+
+# ifndef SHM_STAT
+# define SHM_STAT 13
+# define SHM_INFO 14
+ struct shm_info {
+ int used_ids;
+ ulong shm_tot; /* total allocated shm */
+ ulong shm_rss; /* total resident shm */
+ ulong shm_swp; /* total swapped shm */
+ ulong swap_attempts;
+ ulong swap_successes;
+ };
+# endif
+
+# ifndef SEM_STAT
+# define SEM_STAT 18
+# define SEM_INFO 19
+# endif
+
+ /* The last arg of semctl is a union semun, but where is it defined?
+ X/OPEN tells us to define it ourselves, but until recently
+ Linux include files would also define it. */
+# if defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)
+ /* union semun is defined by including <sys/sem.h> */
+# else
+ /* according to X/OPEN we have to define it ourselves */
+ union semun {
+ int val;
+ struct semid_ds *buf;
+ unsigned short *array;
+ struct seminfo *__buf;
+ };
+# endif
+static long pagesize_g;
+/* #endif KERNEL_LINUX */
+#elif KERNEL_AIX
+# include <sys/ipc_info.h>
+/* #endif KERNEL_AIX */
+#else
+# error "No applicable input method."
+#endif
+
+__attribute__ ((nonnull(1)))
+static void ipc_submit_g (const char *type, gauge_t value) /* {{{ */
+{
+ value_t values[1];
+ value_list_t vl = VALUE_LIST_INIT;
+
+ values[0].gauge = value;
+
+ vl.values = values;
+ vl.values_len = 1;
+ sstrncpy (vl.host, hostname_g, sizeof (vl.host));
+ sstrncpy (vl.plugin, "ipc", sizeof (vl.plugin));
+ sstrncpy (vl.type, type, sizeof (vl.type));
+
+ plugin_dispatch_values (&vl);
+} /* }}} */
+
+#if KERNEL_AIX
+static caddr_t ipc_get_info (cid_t cid, int cmd, int version, int stsize, int *nmemb) /* {{{ */
+{
+ int size = 0;
+ caddr_t buff = NULL;
+
+ if (get_ipc_info(cid, cmd, version, buff, &size) < 0)
+ {
+ if (errno != ENOSPC) {
+ char errbuf[1024];
+ WARNING ("ipc plugin: get_ipc_info: %s",
+ sstrerror (errno, errbuf, sizeof (errbuf)));
+ return (NULL);
+ }
+ }
+
+ if (size == 0)
+ return NULL;
+
+ if (size % stsize) {
+ ERROR ("ipc plugin: ipc_get_info: missmatch struct size and buffer size");
+ return (NULL);
+ }
+
+ *nmemb = size / stsize;
+
+ buff = (caddr_t)malloc (size);
+ if (buff == NULL) {
+ ERROR ("ipc plugin: ipc_get_info malloc failed.");
+ return (NULL);
+ }
+
+ if (get_ipc_info(cid, cmd, version, buff, &size) < 0)
+ {
+ char errbuf[1024];
+ WARNING ("ipc plugin: get_ipc_info: %s",
+ sstrerror (errno, errbuf, sizeof (errbuf)));
+ free(buff);
+ return (NULL);
+ }
+
+ return buff;
+} /* }}} */
+#endif /* KERNEL_AIX */
+
+static int ipc_read_sem (void) /* {{{ */
+{
+#if KERNEL_LINUX
+ struct seminfo seminfo;
+ union semun arg;
+
+ arg.array = (ushort *) (void *) &seminfo;
+
+ if ( semctl(0, 0, SEM_INFO, arg) < 0 )
+ {
+ ERROR("Kernel is not configured for semaphores");
+ return (-1);
+ }
+
+ ipc_submit_g("sem_used_arrays", seminfo.semusz);
+ ipc_submit_g("sem_used", seminfo.semaem);
+
+/* #endif KERNEL_LINUX */
+#elif KERNEL_AIX
+ ipcinfo_sem_t *ipcinfo_sem;
+ unsigned short sem_nsems=0;
+ unsigned short sems=0;
+ int i,n;
+
+ ipcinfo_sem = (ipcinfo_sem_t *)ipc_get_info(0,
+ GET_IPCINFO_SEM_ALL, IPCINFO_SEM_VERSION, sizeof(ipcinfo_sem_t), &n);
+ if (ipcinfo_sem == NULL)
+ return -1;
+
+ for (i=0; i<n; i++) {
+ sem_nsems += ipcinfo_sem[i].sem_nsems;
+ sems++;
+ }
+ free(ipcinfo_sem);
+
+ ipc_submit_g("sem_used_arrays", sem_nsems);
+ ipc_submit_g("sem_used", sems);
+#endif /* KERNEL_AIX */
+
+ return (0);
+}
+/* }}} */
+
+static int ipc_read_shm (void) /* {{{ */
+{
+#if KERNEL_LINUX
+ struct shm_info shm_info;
+ pagesize_g = sysconf(_SC_PAGESIZE);
+
+ if ( shmctl(0, SHM_INFO, (struct shmid_ds *) (void *) &shm_info) < 0 )
+ {
+ ERROR("Kernel is not configured for shared memory");
+ return (-1);
+ }
+ ipc_submit_g("shm_segments", shm_info.used_ids);
+ ipc_submit_g("shm_bytes_total", shm_info.shm_tot * pagesize_g);
+ ipc_submit_g("shm_bytes_rss", shm_info.shm_rss * pagesize_g);
+ ipc_submit_g("shm_bytes_swapped", shm_info.shm_swp * pagesize_g);
+/* #endif KERNEL_LINUX */
+#elif KERNEL_AIX
+ ipcinfo_shm_t *ipcinfo_shm;
+ ipcinfo_shm_t *pshm;
+ unsigned int shm_segments=0;
+ size64_t shm_bytes=0;
+ int i,n;
+
+ ipcinfo_shm = (ipcinfo_shm_t *)ipc_get_info(0,
+ GET_IPCINFO_SHM_ALL, IPCINFO_SHM_VERSION, sizeof(ipcinfo_shm_t), &n);
+ if (ipcinfo_shm == NULL)
+ return -1;
+
+ for (i=0, pshm=ipcinfo_shm; i<n; i++, pshm++) {
+ shm_segments++;
+ shm_bytes += pshm->shm_segsz;
+ }
+ free(ipcinfo_shm);
+
+ ipc_submit_g("shm_segments", shm_segments);
+ ipc_submit_g("shm_bytes_total", shm_bytes);
+
+#endif /* KERNEL_AIX */
+ return (0);
+}
+/* }}} */
+
+static int ipc_read_msg (void) /* {{{ */
+{
+#if KERNEL_LINUX
+ struct msginfo msginfo;
+
+ if ( msgctl(0, MSG_INFO, (struct msqid_ds *) (void *) &msginfo) < 0 )
+ {
+ ERROR("Kernel is not configured for message queues");
+ return (-1);
+ }
+ ipc_submit_g("msg_alloc_queues", msginfo.msgmni);
+ ipc_submit_g("msg_used_headers", msginfo.msgmap);
+ ipc_submit_g("msg_used_space", msginfo.msgtql);
+/* #endif KERNEL_LINUX */
+#elif KERNEL_AIX
+ ipcinfo_msg_t *ipcinfo_msg;
+ uint32_t msg_used_space=0;
+ uint32_t msg_alloc_queues=0;
+ msgqnum32_t msg_qnum=0;
+ int i,n;
+
+ ipcinfo_msg = (ipcinfo_msg_t *)ipc_get_info(0,
+ GET_IPCINFO_MSG_ALL, IPCINFO_MSG_VERSION, sizeof(ipcinfo_msg_t), &n);
+ if (ipcinfo_msg == NULL)
+ return -1;
+
+ for (i=0; i<n; i++) {
+ msg_alloc_queues++;
+ msg_used_space += ipcinfo_msg[i].msg_cbytes;
+ msg_qnum += ipcinfo_msg[i].msg_qnum;
+ }
+ free(ipcinfo_msg);
+
+ ipc_submit_g("msg_alloc_queues", msg_alloc_queues);
+ ipc_submit_g("msg_used_headers", msg_qnum);
+ ipc_submit_g("msg_used_space", msg_used_space);
+#endif /* KERNEL_AIX */
+ return (0);
+}
+/* }}} */
+
+static int ipc_read (void) /* {{{ */
+{
+ int x = 0;
+ x |= ipc_read_shm();
+ x |= ipc_read_sem();
+ x |= ipc_read_msg();
+
+ return (x);
+}
+/* }}} */
+
+#ifdef KERNEL_LINUX
+static int ipc_init (void) /* {{{ */
+{
+ pagesize_g = sysconf(_SC_PAGESIZE);
+ return (0);
+}
+/* }}} */
+#endif /* KERNEL_LINUX */
+
+void module_register (void) /* {{{ */
+{
+#ifdef KERNEL_LINUX
+ plugin_register_init ("ipc", ipc_init);
+#endif
+ plugin_register_read ("ipc", ipc_read);
+}
+/* }}} */
+
+/* vim: set sw=2 sts=2 et fdm=marker : */
diff --git a/src/types.db b/src/types.db
index e6345ab..1fb1062 100644
--- a/src/types.db
+++ b/src/types.db
@@ -90,6 +90,9 @@ memcached_items value:GAUGE:0:U
memcached_octets rx:DERIVE:0:U, tx:DERIVE:0:U
memcached_ops value:DERIVE:0:U
memory value:GAUGE:0:281474976710656
+msg_alloc_queues value:GAUGE:0:9223372036854775807
+msg_used_headers value:GAUGE:0:9223372036854775807
+msg_used_space value:GAUGE:0:9223372036854775807
multimeter value:GAUGE:U:U
mysql_commands value:DERIVE:0:U
mysql_handler value:DERIVE:0:U
@@ -136,7 +139,13 @@ response_time value:GAUGE:0:U
route_etx value:GAUGE:0:U
route_metric value:GAUGE:0:U
routes value:GAUGE:0:U
-serial_octets rx:DERIVE:0:U, tx:DERIVE:0:U
+sem_used value:GAUGE:0:9223372036854775807
+sem_used_arrays value:GAUGE:0:9223372036854775807
+serial_octets rx:DERIVE:0:U, tx:DERIVE:0:U
+shm_segments value:GAUGE:0:281474976710656
+shm_bytes_total value:GAUGE:0:9223372036854775807
+shm_bytes_rss value:GAUGE:0:9223372036854775807
+shm_bytes_swapped value:GAUGE:0:9223372036854775807
signal_noise value:GAUGE:U:0
signal_power value:GAUGE:U:0
signal_quality value:GAUGE:0:U
signature.asc
Description: PGP signature
_______________________________________________ collectd mailing list [email protected] http://mailman.verplant.org/listinfo/collectd
