summaryrefslogtreecommitdiff
path: root/src/pmdas/lustrecomm
diff options
context:
space:
mode:
authorIgor Pashev <pashev.igor@gmail.com>2014-10-26 12:33:50 +0400
committerIgor Pashev <pashev.igor@gmail.com>2014-10-26 12:33:50 +0400
commit47e6e7c84f008a53061e661f31ae96629bc694ef (patch)
tree648a07f3b5b9d67ce19b0fd72e8caa1175c98f1a /src/pmdas/lustrecomm
downloadpcp-debian.tar.gz
Debian 3.9.10debian/3.9.10debian
Diffstat (limited to 'src/pmdas/lustrecomm')
-rw-r--r--src/pmdas/lustrecomm/GNUmakefile63
-rwxr-xr-xsrc/pmdas/lustrecomm/Install27
-rw-r--r--src/pmdas/lustrecomm/README60
-rwxr-xr-xsrc/pmdas/lustrecomm/Remove38
-rw-r--r--src/pmdas/lustrecomm/TODO3
-rw-r--r--src/pmdas/lustrecomm/file_indexed.c96
-rw-r--r--src/pmdas/lustrecomm/file_single.c104
-rw-r--r--src/pmdas/lustrecomm/help106
-rw-r--r--src/pmdas/lustrecomm/libreadfiles.h59
-rw-r--r--src/pmdas/lustrecomm/lustrecomm.c304
-rw-r--r--src/pmdas/lustrecomm/pmns47
-rw-r--r--src/pmdas/lustrecomm/pmns.v487
-rw-r--r--src/pmdas/lustrecomm/refresh_file.c85
-rw-r--r--src/pmdas/lustrecomm/root10
-rw-r--r--src/pmdas/lustrecomm/timespec_routines.c48
15 files changed, 1137 insertions, 0 deletions
diff --git a/src/pmdas/lustrecomm/GNUmakefile b/src/pmdas/lustrecomm/GNUmakefile
new file mode 100644
index 0000000..d7ae6e0
--- /dev/null
+++ b/src/pmdas/lustrecomm/GNUmakefile
@@ -0,0 +1,63 @@
+#
+# Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved.
+#
+# Author: Scott Emery <emery@sgi.com>
+#
+# 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.
+#
+
+TOPDIR = ../../..
+include $(TOPDIR)/src/include/builddefs
+
+IAM = lustrecomm
+DOMAIN = LUSTRECOMM
+PMDADIR = $(PCP_PMDAS_DIR)/$(IAM)
+
+DFILES = README
+HFILES = libreadfiles.h
+CFILES = $(IAM).c file_indexed.c file_single.c refresh_file.c timespec_routines.c
+
+LIBTARGET = pmda_$(IAM).so
+CMDTARGET = pmda$(IAM)
+TARGETS = $(CMDTARGET)
+#TARGETS = $(LIBTARGET)
+
+LDOPTS =
+LSRCFILES = Install Remove README help pmns root
+LLDLIBS = $(PCP_PMDALIB) $(LIB_FOR_RT)
+LCFLAGS = -I.
+
+LDIRT = domain.h *.o $(IAM).log pmda$(IAM) pmda_$(IAM).so
+
+default: build-me
+
+include $(BUILDRULES)
+
+ifeq "$(TARGET_OS)" "linux"
+build-me: domain.h $(TARGETS)
+
+install: default
+ $(INSTALL) -m 755 -d $(PMDADIR)
+ $(INSTALL) -m 755 $(CMDTARGET) $(PMDADIR)/$(CMDTARGET)
+ #$(INSTALL) -m 755 $(LIBTARGET) $(PMDADIR)/$(LIBTARGET)
+ $(INSTALL) -m 755 Install Remove $(PMDADIR)
+ $(INSTALL) -m 644 $(DFILES) root pmns domain.h help $(PMDADIR)
+else
+build-me:
+install:
+endif
+
+default_pcp: default
+
+install_pcp: install
+
+domain.h: ../../pmns/stdpmid
+ $(DOMAIN_MAKERULE)
diff --git a/src/pmdas/lustrecomm/Install b/src/pmdas/lustrecomm/Install
new file mode 100755
index 0000000..d712c24
--- /dev/null
+++ b/src/pmdas/lustrecomm/Install
@@ -0,0 +1,27 @@
+#! /bin/sh
+#
+# Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved.
+#
+# Author: Scott Emery <emery@sgi.com>
+#
+# 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.
+#
+
+. /etc/pcp.env
+. $PCP_SHARE_DIR/lib/pmdaproc.sh
+
+iam=lustrecomm
+pmda_interface=2
+forced_restart=false
+
+pmdaSetup
+pmdaInstall
+exit 0
diff --git a/src/pmdas/lustrecomm/README b/src/pmdas/lustrecomm/README
new file mode 100644
index 0000000..467cd80
--- /dev/null
+++ b/src/pmdas/lustrecomm/README
@@ -0,0 +1,60 @@
+lustrecomm PMDA
+===============
+
+This PMDA collects statistics common to all lustre implementations,
+the statistics found in /proc/lustre and /proc/lnet
+
+Note:
+ This PMDA may be remade from source and hence requires IDO (or
+ more specifically a C compiler) to be installed.
+
+ Uses of make(1) may fail (without removing or clobbering files)
+ if the C compiler cannot be found. This is most likely to
+ happen when running the PMDA ./Install script.
+
+ The only remedial action is to install the C compiler, or
+ hand-craft changes to the Makefile.
+
+Metrics
+=======
+
+The file ./help contains descriptions for all of the metrics exported
+by this PMDA.
+
+Once the PMDA has been installed, the following command will list all
+the available metrics and their explanatory "help" text:
+
+ $ pminfo -fT lustrecomm
+
+Installation
+============
+
+ + # cd $PCP_PMDAS_DIR/lustrecomm
+
+ + Check that there is no clash in the Performance Metrics Domain
+ defined in ./domain.h and the other PMDAs currently in use (see
+ $PCP_PMCDCONF_PATH). If there is, edit ./domain.h to choose another
+ domain number.
+
+ + Then simply use
+
+ # ./Install
+
+ and choose both the "collector" and "monitor" installation
+ configuration options -- everything else is automated.
+
+De-installation
+===============
+
+ + Simply use
+
+ # cd $PCP_PMDAS_DIR/lustrecomm
+ # ./Remove
+
+Troubleshooting
+===============
+
+ + After installing or restarting the agent, the PMCD log file
+ ($PCP_LOG_DIR/pmcd/pmcd.log) and the PMDA log file
+ ($PCP_LOG_DIR/pmcd/trivial.log) should be checked for any warnings
+ or errors.
diff --git a/src/pmdas/lustrecomm/Remove b/src/pmdas/lustrecomm/Remove
new file mode 100755
index 0000000..7ed7151
--- /dev/null
+++ b/src/pmdas/lustrecomm/Remove
@@ -0,0 +1,38 @@
+#! /bin/sh
+#
+# Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved.
+#
+# Author: Scott Emery <emery@sgi.com>
+#
+# 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+
+# source the PCP configuration environment variables
+. /etc/pcp.env
+
+# Get the common procedures and variable assignments
+#
+. $PCP_SHARE_DIR/lib/pmdaproc.sh
+
+# The name of the PMDA
+#
+iam=lustrecomm
+
+# Do it
+#
+pmdaSetup
+pmdaRemove
+
+exit 0
diff --git a/src/pmdas/lustrecomm/TODO b/src/pmdas/lustrecomm/TODO
new file mode 100644
index 0000000..33b1860
--- /dev/null
+++ b/src/pmdas/lustrecomm/TODO
@@ -0,0 +1,3 @@
+
+v4 - add nis and peers
+
diff --git a/src/pmdas/lustrecomm/file_indexed.c b/src/pmdas/lustrecomm/file_indexed.c
new file mode 100644
index 0000000..2f11c88
--- /dev/null
+++ b/src/pmdas/lustrecomm/file_indexed.c
@@ -0,0 +1,96 @@
+/*
+ * Lustre common /proc PMDA
+ *
+ * Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * Author: Scott Emery <emery@sgi.com>
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libreadfiles.h"
+
+
+/* int file_indexed (struct file_state *f_s,
+ * int type, int base, void *vpp, int index)
+ * - Get single value from file containing multiple values
+ * struct file_state *f_s - struct for access to single file
+ * type - PCP type described by the PMAPI PM_TYPE_* enum
+ * base - for integer types, base as stored in the file
+ * - for string and aggregate types, size of memory pointed to
+ * ---------------- size may be changed by realloc
+ * vpp - pointer to pointer to storage allocated to contain value
+ * - pointed to pointer may change
+ * ---------------- pointer may be changed by realloc
+ * index - value is the n'th strtok token in the file
+ * consider specifying token seperator, default whitespace is fine for now
+ */
+int file_indexed (struct file_state *f_s, int type, int *base, void **vpp, int index)
+{
+ int i;
+ char *cp, *sp;
+
+ /* reload file if it hasn't been reloaded in x */
+ if (refresh_file( f_s ) <0 ) {
+ __pmNotifyErr(LOG_ERR, "file_indexed: refresh_file error");
+ return -1;
+ }
+ /* file_indexed assumes that the file contains one line
+ * if the file may ever contain more than one line, consider file_arrayed
+ * (if that ever gets written)
+ * strtok to the appropriate spot
+ * strtok screws up the target string, so make a copy of the file data
+ */
+ cp = malloc ( f_s->datas );
+ strcpy ( cp, f_s->datap );
+ sp = strtok( cp, " " );
+ for (i = 0; i < index; i++){
+ sp = strtok( NULL, " ");
+ }
+ /* otherwise, a lot like file_single (see below)
+ * one would eventually write a configure script to make
+ * sure that the right routines are used below.. defining
+ * a STRTO32 and STRTOU32, etc.
+ */
+ switch (type) {
+ case PM_TYPE_32:
+ *((long *)(*vpp)) = strtol(sp,0,*base);
+ break;
+ case PM_TYPE_U32:
+ *((unsigned long *)(*vpp)) = strtoul(sp,0,*base);
+ break;
+ case PM_TYPE_64:
+ *((long long *)(*vpp)) = strtoll(sp,0,*base);
+ break;
+ case PM_TYPE_U64:
+ *((unsigned long long *)(*vpp)) = strtoull(sp,0,*base);
+ break;
+ case PM_TYPE_FLOAT:
+ *((float *)(*vpp)) = strtof(sp,0);
+ break;
+ case PM_TYPE_DOUBLE:
+ *((double *)(*vpp)) = strtod(sp,0);
+ break;
+ default:
+ fprintf(stderr,"file_indexed: type %s not supported\n", pmTypeStr(type));
+ break;
+ }
+ /* so, write it up and slice and dice */
+ free (cp);
+
+ return 0;
+}
+
+
diff --git a/src/pmdas/lustrecomm/file_single.c b/src/pmdas/lustrecomm/file_single.c
new file mode 100644
index 0000000..2f135d2
--- /dev/null
+++ b/src/pmdas/lustrecomm/file_single.c
@@ -0,0 +1,104 @@
+/*
+ * Lustre common /proc PMDA
+ *
+ * Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * Author: Scott Emery <emery@sgi.com>
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libreadfiles.h"
+
+
+/* file_single (char *filename, int type, int *base, void **vpp)
+ * - Get a value from a file containing single value
+ * filename - name of file
+ * type - PCP type described by the PMAPI PM_TYPE_* enum
+ * base - for integer types, base as stored in the file
+ * - for string and aggregate types, size of memory pointed to
+ * ---------------- size may be changed by realloc
+ * vpp - pointer to pointer to storage allocated to contain value
+ * - pointed to pointer may change
+ * ---------------- pointer may be changed by realloc
+ * allocating and deallocating space for value is the responsibility
+ * of the caller
+ */
+int file_single (char *filename, int type, int *base, void **vpp)
+{
+ int fd;
+ int n;
+ /* overlarge */
+ char b[80] = { 0 };
+
+ /* Read in the file into the buffer b */
+ if (( fd = open (filename, O_RDONLY)) < 0) {
+ perror("file_single: open");
+ return -1;
+ }
+ /* Okay this presents a problem vis a vis some lustre proc files.
+ * While the present scheme is adequate for lustre common in most
+ * cases, some lustre proc files have *ridiculously* large amounts
+ * of data stored in them. Need to come up with some dynamic
+ * memory buffer system for other lustre PMDAs
+ */
+ switch (type) {
+ case PM_TYPE_32:
+ case PM_TYPE_U32:
+ case PM_TYPE_64:
+ case PM_TYPE_U64:
+ case PM_TYPE_FLOAT:
+ case PM_TYPE_DOUBLE:
+ if ((n = read (fd, b, sizeof(b))) < 0 ){
+ perror("file_single: read");
+ close(fd);
+ return -1;
+ }
+ close(fd);
+ break;
+ default:
+ fprintf(stderr,"file_single: type %s not supported\n", pmTypeStr(type));
+ close(fd);
+ return -1;
+
+ }
+ /* One would eventually write a configure script to make
+ * sure that the right routines are used below.. defining
+ * a STRTO32 and STRTOU32, etc.
+ */
+ switch (type) {
+ case PM_TYPE_32:
+ *((long *)(*vpp)) = strtol(b,0,*base);
+ break;
+ case PM_TYPE_U32:
+ *((unsigned long *)(*vpp)) = strtoul(b,0,*base);
+ break;
+ case PM_TYPE_64:
+ *((long long *)(*vpp)) = strtoll(b,0,*base);
+ break;
+ case PM_TYPE_U64:
+ *((unsigned long long *)(*vpp)) = strtoull(b,0,*base);
+ break;
+ case PM_TYPE_FLOAT:
+ *((float *)(*vpp)) = strtof(b,0);
+ break;
+ case PM_TYPE_DOUBLE:
+ *((double *)(*vpp)) = strtod(b,0);
+ break;
+ }
+ return 0;
+}
+
+
diff --git a/src/pmdas/lustrecomm/help b/src/pmdas/lustrecomm/help
new file mode 100644
index 0000000..2d86915
--- /dev/null
+++ b/src/pmdas/lustrecomm/help
@@ -0,0 +1,106 @@
+#
+# Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved.
+#
+# Author: Scott Emery <emery@sgi.com>
+#
+# 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+#
+# lustrecomm PMDA help file in the ASCII format
+#
+# lines beginning with a # are ignored
+# lines beginning @ introduce a new entry of the form
+# @ metric_name oneline-text
+# help test goes
+# here over multiple lines
+# ...
+#
+# the metric_name is decoded against the default PMNS -- as a special case,
+# a name of the form NNN.MM (for numeric NNN and MM) is interpreted as an
+# instance domain identification, and the text describes the instance domain
+#
+# blank lines before the @ line are ignored
+#
+
+@ lustrecomm.timeout contents of /proc/sys/lustre/timeout
+The time period that a client waits for a server to complete an RPC
+(default in 1.6 is 100s). Servers wait half this time for a normal
+client RPC to compelte and a quarter of this time for a single
+bulk request to complete. The client pings recoverable targets
+(MDS and OSTs) at one quarter of the timeout, and the server
+waits on and a half times the timeout before evicting a client
+for being "stale". (source: Lustre 1.6 Operations Manual)
+
+@ lustrecomm.ldlm_timeout contents of /proc/sys/lustre/ldlm_timeout
+This is the time period for which a server will wait for a client
+to reply to an initial AST (lock cancellation request). The default
+is 20s for an OST and 6s for an MDS. (source: Lustre 1.6 Operations
+Manual)
+
+@ lustrecomm.dump_on_timeout contents of /proc/sys/lustre/ldlm_timeout
+A 1 triggers dumps of the Lustre debug log when timeouts occur.
+Default value 0. (source: Lustre 1.6 Operations Manual)
+
+@ lustrecomm.lustre_memused contents of /proc/sys/lustre/memused
+lustre/obdclass/linux/linux-sysctl.c: &proc_memory_alloc
+lustre/include/obd_support.h: obd_memory_sum()
+Total bytes allocated by Lustre (inferred from lustre/include/obd_support.h)
+
+@ lustrecomm.lnet_memused contents of /proc/sys/lnet/memused
+lnet/libcfs/linux/linux-proc.c: (int *)&libcfs_kmemory.counter
+Total bytes allocated by LNET. (inferred from lustre/include/obd_support.h)
+
+@ lustrecomm.stats.msgs_alloc first number from /proc/sys/lnet/stats
+routerstat source file: messages currently allocated (first number after M)
+
+@ lustrecomm.stats.msgs_max second number from /proc/sys/lnet/stats
+routerstat source file: messages maximum (highwater mark) (second
+number after M)
+
+@ lustrecomm.stats.errors third number from /proc/sys/lnet/stats
+routerstat source file: errors (number after E)
+
+@ lustrecomm.stats.send_count fourth number from /proc/sys/lnet/stats
+routerstat source file: send_count (raw data from which second number
+after S is derived).
+
+@ lustrecomm.stats.recv_count fifth number from /proc/sys/lnet/stats
+routerstat source file: recv_count (raw data from which second number
+after R is derived)
+
+@ lustrecomm.stats.route_count sixth number from /proc/sys/lnet/stats
+routerstat source file: route_count (raw data from which second number
+after R is derived)
+
+@ lustrecomm.stats.drop_count seventh number from /proc/sys/lnet/stats
+routerstat source file: drop_count (raw data from which second number
+after D is derived)
+
+@ lustrecomm.stats.send_length eigth number from /proc/sys/lnet/stats
+routerstat source file: send_length (raw data from which first number
+after S is derived)
+
+@ lustrecomm.stats.recv_length ninth number from /proc/sys/lnet/stats
+routerstat source file: recv_length (raw data from which first number
+after S is derived)
+
+@ lustrecomm.stats.route_length tenth number from /proc/sys/lnet/stats
+routerstat source file: route_length (raw data from which first number
+after R is derived)
+
+@ lustrecomm.stats.drop_length eleventh number from /proc/sys/lnet/stats
+routerstat source file: drop_length (raw data from which first number
+after D is derived)
+
diff --git a/src/pmdas/lustrecomm/libreadfiles.h b/src/pmdas/lustrecomm/libreadfiles.h
new file mode 100644
index 0000000..121dcdf
--- /dev/null
+++ b/src/pmdas/lustrecomm/libreadfiles.h
@@ -0,0 +1,59 @@
+/*
+ * Lustre common /proc PMDA
+ *
+ * Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * Author: Scott Emery <emery@sgi.com>
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+
+#include <sys/types.h>
+#include "pmapi.h"
+#include "impl.h"
+#include "pmda.h"
+#include <fcntl.h>
+#include <unistd.h>
+#include <time.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <time.h>
+
+struct file_state {
+ struct timespec ts;
+ char *filename;
+ int fd;
+ int datas;
+ void *datap;
+};
+
+#define BUFFERBLOCK 4096
+
+#ifndef FILE_TIME_OFFSET
+extern struct timespec file_time_offset;
+#endif
+
+/* timespec_routines.c */
+extern struct timespec timespec_add (struct timespec *a, struct timespec *b);
+extern int timespec_le ( struct timespec *lhs, struct timespec *rhs);
+/* refresh_file.c */
+extern int refresh_file( struct file_state *f_s );
+/* file_indexed.c */
+extern int file_indexed (struct file_state *f_s, int type, int *base, void **vpp, int index);
+/* file_single.c */
+extern int file_single (char *filename, int type, int *base, void **vpp);
+
+
diff --git a/src/pmdas/lustrecomm/lustrecomm.c b/src/pmdas/lustrecomm/lustrecomm.c
new file mode 100644
index 0000000..9b4b9df
--- /dev/null
+++ b/src/pmdas/lustrecomm/lustrecomm.c
@@ -0,0 +1,304 @@
+/*
+ * Lustre common /proc PMDA
+ *
+ * Original author: Scott Emery <emery@sgi.com>
+ *
+ * Copyright (c) 2012,2014 Red Hat.
+ * Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "libreadfiles.h"
+#include <stdio.h>
+#include "domain.h"
+
+
+/*
+ * Lustrecomm PMDA
+ *
+ * This PMDA gathers Lustre statistics from /proc, it is constructed using
+ * libpcp_pmda.
+ *
+ *
+ * Metrics
+ * lustrecomm.time - time in seconds since the 1st of Jan, 1970.
+ */
+
+#define PROC_SYS_LNET_STATS 0
+#define PROC_SYS_LNET_NIS 1
+#define PROC_SYS_LNET_PEERS 2
+#define FILESTATETABSIZE 3
+
+/*
+ * all metrics supported in this PMDA - one table entry for each
+ */
+
+static pmdaMetric metrictab[] = {
+/* timeout */
+ { NULL,
+ { PMDA_PMID(0,0), PM_TYPE_32, PM_INDOM_NULL, PM_SEM_DISCRETE,
+ PMDA_PMUNITS(0, 0, 1, 0, 0, PM_COUNT_ONE) } },
+/* ldlm_timeout */
+ { NULL,
+ { PMDA_PMID(0,1), PM_TYPE_32, PM_INDOM_NULL, PM_SEM_DISCRETE,
+ PMDA_PMUNITS(0, 0, 1, 0, 0, PM_COUNT_ONE) } },
+/* dump_on_timeout */
+ { NULL,
+ { PMDA_PMID(0,2), PM_TYPE_32, PM_INDOM_NULL, PM_SEM_DISCRETE,
+ PMDA_PMUNITS(0, 0, 1, 0, 0, PM_COUNT_ONE) } },
+/* lustre_memused */
+ { NULL,
+ { PMDA_PMID(0,3), PM_TYPE_32, PM_INDOM_NULL, PM_SEM_INSTANT,
+ PMDA_PMUNITS(1, 0, 0, PM_SPACE_BYTE, 0, 0) } },
+/* lnet_memused */
+ { NULL,
+ { PMDA_PMID(0,4), PM_TYPE_32, PM_INDOM_NULL, PM_SEM_INSTANT,
+ PMDA_PMUNITS(1, 0, 0, PM_SPACE_BYTE, 0, 0) } },
+/* data pulled from /proc/sys/lnet/stats */
+/*0 42 0 22407486 23426580 0 0 135850271989 472430974209 0 0*/
+/* stats.msgs_alloc */
+ { NULL,
+ { PMDA_PMID(1,0), PM_TYPE_32, PM_INDOM_NULL, PM_SEM_INSTANT,
+ PMDA_PMUNITS(1, 0, 0, PM_SPACE_BYTE, 0, 0) } },
+/* stats.msgs_max */
+ { NULL,
+ { PMDA_PMID(1,1), PM_TYPE_32, PM_INDOM_NULL, PM_SEM_INSTANT,
+ PMDA_PMUNITS(1, 0, 0, PM_SPACE_BYTE, 0, 0) } },
+/* stats.errors */
+ { NULL,
+ { PMDA_PMID(1,2), PM_TYPE_32, PM_INDOM_NULL, PM_SEM_INSTANT,
+ PMDA_PMUNITS(1, 0, 0, PM_SPACE_BYTE, 0, 0) } },
+/* stats.send_count */
+ { NULL,
+ { PMDA_PMID(1,3), PM_TYPE_32, PM_INDOM_NULL, PM_SEM_INSTANT,
+ PMDA_PMUNITS(1, 0, 0, PM_SPACE_BYTE, 0, 0) } },
+/* stats.recv_count */
+ { NULL,
+ { PMDA_PMID(1,4), PM_TYPE_32, PM_INDOM_NULL, PM_SEM_INSTANT,
+ PMDA_PMUNITS(1, 0, 0, PM_SPACE_BYTE, 0, 0) } },
+/* stats.route_count */
+ { NULL,
+ { PMDA_PMID(1,5), PM_TYPE_32, PM_INDOM_NULL, PM_SEM_INSTANT,
+ PMDA_PMUNITS(1, 0, 0, PM_SPACE_BYTE, 0, 0) } },
+/* stats.drop_count */
+ { NULL,
+ { PMDA_PMID(1,6), PM_TYPE_32, PM_INDOM_NULL, PM_SEM_INSTANT,
+ PMDA_PMUNITS(1, 0, 0, PM_SPACE_BYTE, 0, 0) } },
+/* stats.send_length */
+ { NULL,
+ { PMDA_PMID(1,7), PM_TYPE_64, PM_INDOM_NULL, PM_SEM_COUNTER,
+ PMDA_PMUNITS(1, 0, 0, PM_SPACE_BYTE, 0, 0) } },
+/* stats.recv_length */
+ { NULL,
+ { PMDA_PMID(1,8), PM_TYPE_64, PM_INDOM_NULL, PM_SEM_INSTANT,
+ PMDA_PMUNITS(1, 0, 0, PM_SPACE_BYTE, 0, 0) } },
+/* stats.route_length */
+ { NULL,
+ { PMDA_PMID(1,9), PM_TYPE_64, PM_INDOM_NULL, PM_SEM_INSTANT,
+ PMDA_PMUNITS(1, 0, 0, PM_SPACE_BYTE, 0, 0) } },
+/* stats.drop_length */
+ { NULL,
+ { PMDA_PMID(1,10), PM_TYPE_64, PM_INDOM_NULL, PM_SEM_INSTANT,
+ PMDA_PMUNITS(1, 0, 0, PM_SPACE_BYTE, 0, 0) } }
+
+};
+
+struct file_state filestatetab[] = {
+ { { 0 , 0 } , "/proc/sys/lnet/stats", 0, 0, NULL},
+ { { 0 , 0 } , "/proc/sys/lnet/nis", 0, 0, NULL},
+ { { 0 , 0 } , "/proc/sys/lnet/peers", 0, 0, NULL}
+};
+
+static int isDSO = 1; /* =0 I am a daemon */
+static char mypath[MAXPATHLEN];
+static char *username;
+
+/*
+ * callback provided to pmdaFetch
+ */
+
+static int
+lustrecomm_fetchCallBack(pmdaMetric *mdesc, unsigned int inst, pmAtomValue *atom)
+{
+ __pmID_int *idp = (__pmID_int *)&(mdesc->m_desc.pmid);
+ void *vp;
+
+ /* check for PMID errors */
+ if ( !((idp->cluster == 0) && (idp->item <= 4)) &&
+ !((idp->cluster == 1) && (idp->item <= 10)) )
+ return PM_ERR_PMID;
+ else if (inst != PM_IN_NULL)
+ return PM_ERR_INST;
+
+ /* refresh and store data */
+ if (idp->cluster == 0) {
+ vp = malloc (4);
+ int aux = 10;
+ /* not saving any time fussing with "how recent", just do it */
+ switch (idp->item) {
+ case 0:
+ /* consider mdesc->m_desc.type */
+ /* problem: the way it's stored in PCP isn't necessarily */
+ /* the way it's presented by the OS */
+ file_single("/proc/sys/lustre/timeout", PM_TYPE_32, &aux, &vp);
+ atom->l = *((long *) vp);
+ break;
+ case 1:
+ file_single("/proc/sys/lustre/ldlm_timeout", PM_TYPE_32, &aux, &vp);
+ atom->l = *((long *) vp);
+ break;
+ case 2:
+ file_single("/proc/sys/lustre/dump_on_timeout", PM_TYPE_32, &aux, &vp);
+ atom->l = *((long *) vp);
+ break;
+ case 3:
+ file_single("/proc/sys/lustre/memused", PM_TYPE_32, &aux, &vp);
+ atom->l = *((long *) vp);
+ break;
+ case 4:
+ file_single("/proc/sys/lnet/lnet_memused", PM_TYPE_32, &aux, &vp);
+ atom->l = *((long *) vp);
+ break;
+ default:
+ printf ("PMID %d:%d non-existant\n",idp->cluster,idp->item);
+ break;
+ }
+ free (vp);
+ }
+ if (idp->cluster == 1) {
+ vp = malloc (4);
+ int aux = 10;
+
+ switch(idp->item) {
+ case 0:
+ file_indexed(&filestatetab[PROC_SYS_LNET_STATS], PM_TYPE_32,&aux, &vp, 0);
+ atom->l = *((long *) vp);
+ break;
+ case 1:
+ file_indexed(&filestatetab[PROC_SYS_LNET_STATS], PM_TYPE_32,&aux, &vp, 1);
+ atom->l = *((long *) vp);
+ break;
+ case 2:
+ file_indexed(&filestatetab[PROC_SYS_LNET_STATS], PM_TYPE_32,&aux, &vp, 2);
+ atom->l = *((long *) vp);
+ break;
+ case 3:
+ file_indexed(&filestatetab[PROC_SYS_LNET_STATS], PM_TYPE_32,&aux, &vp, 3);
+ atom->l = *((long *) vp);
+ break;
+ case 4:
+ file_indexed(&filestatetab[PROC_SYS_LNET_STATS], PM_TYPE_32,&aux, &vp, 4);
+ atom->l = *((long *) vp);
+ break;
+ case 5:
+ file_indexed(&filestatetab[PROC_SYS_LNET_STATS], PM_TYPE_32,&aux, &vp, 5);
+ atom->l = *((long *) vp);
+ break;
+ case 6:
+ file_indexed(&filestatetab[PROC_SYS_LNET_STATS], PM_TYPE_32,&aux, &vp, 6);
+ atom->l = *((long *) vp);
+ break;
+ case 7:
+ file_indexed(&filestatetab[PROC_SYS_LNET_STATS], PM_TYPE_64,&aux, &vp, 7);
+ atom->l = *((long *) vp);
+ break;
+ case 8:
+ file_indexed(&filestatetab[PROC_SYS_LNET_STATS], PM_TYPE_64,&aux, &vp, 8);
+ atom->l = *((long *) vp);
+ break;
+ case 9:
+ file_indexed(&filestatetab[PROC_SYS_LNET_STATS], PM_TYPE_64,&aux, &vp, 9);
+ atom->l = *((long *) vp);
+ break;
+ case 10:
+ file_indexed(&filestatetab[PROC_SYS_LNET_STATS], PM_TYPE_64,&aux, &vp, 10);
+ atom->l = *((long *) vp);
+ break;
+ default:
+ break;
+ }
+ free(vp);
+ }
+ return 0;
+}
+
+/*
+ * Initialise the agent (both daemon and DSO).
+ */
+void
+lustrecomm_init(pmdaInterface *dp)
+{
+ if (isDSO) {
+ int sep = __pmPathSeparator();
+ snprintf(mypath, sizeof(mypath), "%s%c" "lustrecomm" "%c" "help",
+ pmGetConfig("PCP_PMDAS_DIR"), sep, sep);
+ pmdaDSO(dp, PMDA_INTERFACE_2, "lustrecomm DSO", mypath);
+ } else {
+ __pmSetProcessIdentity(username);
+ }
+
+ if (dp->status != 0)
+ return;
+
+ pmdaSetFetchCallBack(dp, lustrecomm_fetchCallBack);
+
+ pmdaInit(dp, NULL, 0,
+ metrictab, sizeof(metrictab)/sizeof(metrictab[0]));
+}
+
+pmLongOptions longopts[] = {
+ PMDA_OPTIONS_HEADER("Options"),
+ PMOPT_DEBUG,
+ PMDAOPT_DOMAIN,
+ PMDAOPT_LOGFILE,
+ PMDAOPT_USERNAME,
+ PMOPT_HELP,
+ PMDA_OPTIONS_END
+};
+
+pmdaOptions opts = {
+ .short_options = "D:d:l:U:?",
+ .long_options = longopts,
+};
+
+/*
+ * Set up the agent if running as a daemon.
+ */
+int
+main(int argc, char **argv)
+{
+ int sep = __pmPathSeparator();
+ pmdaInterface desc;
+
+ isDSO = 0;
+ __pmSetProgname(argv[0]);
+ __pmGetUsername(&username);
+
+ snprintf(mypath, sizeof(mypath), "%s%c" "lustrecomm" "%c" "help",
+ pmGetConfig("PCP_PMDAS_DIR"), sep, sep);
+ pmdaDaemon(&desc, PMDA_INTERFACE_2, pmProgname, LUSTRECOMM,
+ "lustrecomm.log", mypath);
+
+ pmdaGetOptions(argc, argv, &opts, &desc);
+ if (opts.errors) {
+ pmdaUsageMessage(&opts);
+ exit(1);
+ }
+ if (opts.username)
+ username = opts.username;
+
+ pmdaOpenLog(&desc);
+ lustrecomm_init(&desc);
+ pmdaConnect(&desc);
+ pmdaMain(&desc);
+ exit(0);
+}
diff --git a/src/pmdas/lustrecomm/pmns b/src/pmdas/lustrecomm/pmns
new file mode 100644
index 0000000..49a999f
--- /dev/null
+++ b/src/pmdas/lustrecomm/pmns
@@ -0,0 +1,47 @@
+/*
+ * Metrics for lustrecomm PMDA
+ *
+ * Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * Author: Scott Emery <emery@sgi.com>
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+lustrecomm {
+ timeout LUSTRECOMM:0:0
+ ldlm_timeout LUSTRECOMM:0:1
+ dump_on_timeout LUSTRECOMM:0:2
+ lustre_memused LUSTRECOMM:0:3
+ lnet_memused LUSTRECOMM:0:4
+ stats
+}
+
+lustrecomm.stats {
+/* data pulled from /proc/sys/lnet/stats */
+/*0 42 0 22407486 23426580 0 0 135850271989 472430974209 0 0*/
+ msgs_alloc LUSTRECOMM:1:0
+ msgs_max LUSTRECOMM:1:1
+ errors LUSTRECOMM:1:2
+ send_count LUSTRECOMM:1:3
+ recv_count LUSTRECOMM:1:4
+ route_count LUSTRECOMM:1:5
+ drop_count LUSTRECOMM:1:6
+ send_length LUSTRECOMM:1:7
+ recv_length LUSTRECOMM:1:8
+ route_length LUSTRECOMM:1:9
+ drop_length LUSTRECOMM:1:10
+}
+
diff --git a/src/pmdas/lustrecomm/pmns.v4 b/src/pmdas/lustrecomm/pmns.v4
new file mode 100644
index 0000000..e702751
--- /dev/null
+++ b/src/pmdas/lustrecomm/pmns.v4
@@ -0,0 +1,87 @@
+/*
+ * Metrics for lustrecomm PMDA
+ *
+ * Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * Author: Scott Emery <emery@sgi.com>
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+lustrecomm {
+ timeout LUSTRECOMM:0:0
+ ldlm_timeout LUSTRECOMM:0:1
+ dump_on_timeout LUSTRECOMM:0:2
+ lustre_memused LUSTRECOMM:0:3
+ lnet_memused LUSTRECOMM:0:4
+ stats
+}
+
+lustrecomm.stats {
+/* data pulled from /proc/sys/lnet/stats */
+/*0 42 0 22407486 23426580 0 0 135850271989 472430974209 0 0*/
+ msgs_alloc LUSTRECOMM:1:0
+ msgs_max LUSTRECOMM:1:1
+ errors LUSTRECOMM:1:2
+ send_count LUSTRECOMM:1:3
+ recv_count LUSTRECOMM:1:4
+ route_count LUSTRECOMM:1:5
+ drop_count LUSTRECOMM:1:6
+ send_length LUSTRECOMM:1:7
+ recv_length LUSTRECOMM:1:8
+ route_length LUSTRECOMM:1:9
+ drop_length LUSTRECOMM:1:10
+}
+
+lustrecomm.nis {
+/* data pulled from /proc/sys/lnet/nis */
+/* nid refs peer max tx min */
+/* 0@lo 2 0 0 0 0 */
+/* 10.149.0.1@o2ib 13 8 64 64 26 */
+
+ nid LUSTRECOMM:2:1
+ refs LUSTRECOMM:2:2
+ peer LUSTRECOMM:2:3
+ max LUSTRECOMM:2:4
+ tx LUSTRECOMM:2:5
+ tx_min LUSTRECOMM:2:6
+ active LUSTRECOMM:2:7
+/* subtracting max - tx yields the nubmer of sends currently active*/
+/* a large or increasing number of active sends may be a problem */
+}
+
+lustrecomm.peers {
+/* data pulled from /proc/sys/lnet/peers */
+/* nid refs state max rtr min tx min queue */
+/* 10.149.2.15@o2ib 1 ~rtr 8 8 8 8 0 0 */
+/* 10.149.2.29@o2ib 1 ~rtr 8 8 8 8 -26 0 */
+ nid LUSTRECOMM:3:0
+ refs LUSTRECOMM:3:1
+ state LUSTRECOMM:3:2
+ max LUSTRECOMM:3:3
+ rtr LUSTRECOMM:3:4
+ rtr_min LUSTRECOMM:3:5
+ tx LUSTRECOMM:3:6
+ tx_min LUSTRECOMM:3:7
+ queue LUSTRECOMM:3:8
+ in_progress LUSTRECOMM:3:9
+/* if rtr/tx is less than max, there are operations in progress. The number
+ of operations is equal to rtr or tx subtraced from max.
+*/
+ blocking LUSTRECOMM:2:10
+/* if rtr/tx is greater than max, there are operations blocking */
+}
+
+
diff --git a/src/pmdas/lustrecomm/refresh_file.c b/src/pmdas/lustrecomm/refresh_file.c
new file mode 100644
index 0000000..86ca16f
--- /dev/null
+++ b/src/pmdas/lustrecomm/refresh_file.c
@@ -0,0 +1,85 @@
+/*
+ * Lustre common /proc PMDA
+ *
+ * Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * Author: Scott Emery <emery@sgi.com>
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+
+#define FILE_TIME_OFFSET 1
+
+#include "libreadfiles.h"
+
+static struct timespec file_time_offset = { 0 , 900000000 };
+
+
+int refresh_file( struct file_state *f_s ){
+ struct timespec now, tmp;
+ int i = 0;
+
+ if (f_s->datap) {
+ /* get time */
+ if ( clock_gettime(CLOCK_MONOTONIC, &now) < 0 ) {
+ /* if we don't know what time it is */
+ /* there's nothing we can do with this */
+ return 0;
+ }
+ /* if time since last refresh > delta */
+ tmp = timespec_add( &f_s->ts, &file_time_offset);
+ if ( timespec_le( &now, &tmp) ) {
+ /* file is recent */
+ return 0;
+ }
+ f_s->ts = now;
+ /* clear old data, make errors obvious, autoterm trailing strings */
+ memset ( f_s->datap, 0, f_s->datas );
+ }
+ /* if fd is null open file */
+ if ( f_s->fd <= 0) {
+ if (( f_s->fd = open (f_s->filename, O_RDONLY)) < 0) {
+ perror("refresh_file: open");
+ return -1;
+ }
+ }
+ if ( lseek (f_s->fd, 0, SEEK_SET) < 0 ) {
+ perror("refresh_file: initial seek");
+ return -1;
+ }
+ /* only grow, never shrink... what would be the point? */
+ while (f_s->datap && (i = read (f_s->fd, f_s->datap, f_s->datas)) >= f_s->datas ){
+ /* oh heck, what do I do if this fails? */
+ f_s->datas += BUFFERBLOCK;
+ if ((f_s->datap = realloc(f_s->datap, f_s->datas)) == NULL){
+ free((char *)f_s->datap);
+ perror("refresh_file: realloc");
+ return -1;
+ }
+ if ( lseek (f_s->fd, 0, SEEK_SET) < 0 ) {
+ perror("refresh_file: subsequent seek");
+ return -1;
+ }
+ }
+ if (i < 0 ){
+ /* read failed */
+ perror("refresh_file: file read failed");
+ return -1;
+ }
+ return 0;
+}
+
+
diff --git a/src/pmdas/lustrecomm/root b/src/pmdas/lustrecomm/root
new file mode 100644
index 0000000..bf7781c
--- /dev/null
+++ b/src/pmdas/lustrecomm/root
@@ -0,0 +1,10 @@
+/*
+ * fake "root" for validating the local PMNS subtree
+ */
+
+#include <stdpmid>
+
+root { lustrecomm }
+
+#include "pmns"
+
diff --git a/src/pmdas/lustrecomm/timespec_routines.c b/src/pmdas/lustrecomm/timespec_routines.c
new file mode 100644
index 0000000..976be2a
--- /dev/null
+++ b/src/pmdas/lustrecomm/timespec_routines.c
@@ -0,0 +1,48 @@
+/*
+ * Lustre common /proc PMDA
+ *
+ * Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * Author: Scott Emery <emery@sgi.com>
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <time.h>
+
+
+struct timespec timespec_add (struct timespec *a, struct timespec *b){
+ struct timespec tret;
+
+ tret.tv_nsec = (a->tv_nsec + b->tv_nsec) % 1000000000;
+ tret.tv_sec = a->tv_sec + b->tv_sec +
+ ((a->tv_nsec + b->tv_nsec)/1000000000);
+ return tret;
+}
+
+int timespec_le ( struct timespec *lhs, struct timespec *rhs) {
+ if (rhs->tv_sec < lhs->tv_sec) {
+ /* false */
+ return 0;
+ }
+ if (lhs->tv_sec == rhs->tv_sec) {
+ if (rhs->tv_nsec < lhs->tv_nsec) {
+ /* false */
+ return 0;
+ }
+ }
+ return 1;
+}
+