summaryrefslogtreecommitdiff
path: root/src/pmdas/mailq
diff options
context:
space:
mode:
Diffstat (limited to 'src/pmdas/mailq')
-rw-r--r--src/pmdas/mailq/GNUmakefile49
-rw-r--r--src/pmdas/mailq/Install117
-rw-r--r--src/pmdas/mailq/README48
-rw-r--r--src/pmdas/mailq/Remove38
-rw-r--r--src/pmdas/mailq/help52
-rw-r--r--src/pmdas/mailq/mailq.c401
-rw-r--r--src/pmdas/mailq/pmlogconf.summary5
-rw-r--r--src/pmdas/mailq/pmns24
-rw-r--r--src/pmdas/mailq/root10
9 files changed, 744 insertions, 0 deletions
diff --git a/src/pmdas/mailq/GNUmakefile b/src/pmdas/mailq/GNUmakefile
new file mode 100644
index 0000000..1794f1a
--- /dev/null
+++ b/src/pmdas/mailq/GNUmakefile
@@ -0,0 +1,49 @@
+#
+# Copyright (c) 2000-2001,2004 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.
+#
+
+TOPDIR = ../../..
+include $(TOPDIR)/src/include/builddefs
+
+IAM = mailq
+DOMAIN = MAILQ
+
+CMDTARGET = pmdamailq$(EXECSUFFIX)
+CFILES = mailq.c
+DFILES = README
+LSRCFILES = Install Remove root help pmns $(DFILES) pmlogconf.summary
+LLDLIBS = $(PCP_PMDALIB) $(LIB_FOR_REGEX)
+
+PMDADIR = $(PCP_PMDAS_DIR)/$(IAM)
+LDIRT = domain.h *.log *.dir *.pag so_locations
+
+default: $(CMDTARGET)
+
+include $(BUILDRULES)
+
+install: default
+ $(INSTALL) -m 755 -d $(PMDADIR)
+ $(INSTALL) -m 755 $(CMDTARGET) $(PMDADIR)/$(CMDTARGET)
+ $(INSTALL) -m 755 Install Remove $(PMDADIR)
+ $(INSTALL) -m 644 $(DFILES) root help pmns domain.h $(PMDADIR)
+ $(INSTALL) -m 755 -d $(PCP_VAR_DIR)/config/pmlogconf/$(IAM)
+ $(INSTALL) -m 644 pmlogconf.summary $(PCP_VAR_DIR)/config/pmlogconf/$(IAM)/summary
+
+mailq.o: domain.h
+
+domain.h: ../../pmns/stdpmid
+ $(DOMAIN_MAKERULE)
+
+default_pcp: default
+
+install_pcp: install
diff --git a/src/pmdas/mailq/Install b/src/pmdas/mailq/Install
new file mode 100644
index 0000000..efe1fd5
--- /dev/null
+++ b/src/pmdas/mailq/Install
@@ -0,0 +1,117 @@
+#! /bin/sh
+#
+# Copyright (c) 1997-2000,2003 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.
+#
+# Install the mailq PMDA and/or PMNS
+#
+
+. $PCP_DIR/etc/pcp.env
+. $PCP_SHARE_DIR/lib/pmdaproc.sh
+
+iam=mailq
+pmda_interface=2
+forced_restart=false
+
+# Do it
+#
+pmdaSetup
+
+if $do_pmda
+then
+
+ dso_opt=false
+ socket_opt=false
+ pipe_opt=true
+
+ mqueue=""
+ chk=""
+
+ if [ -f /etc/sendmail.cf ]
+ then
+ chk=`sed -n '/^O *QueueDirectory *= */s///p' /etc/sendmail.cf`
+ [ -z "$chk" ] && chk=`sed -n '/^O *Q *\//s//\//p' /etc/sendmail.cf`
+ fi
+
+ if [ ! -z "$chk" -a -d "$chk" ]
+ then
+ mqueue="$chk"
+ else
+ mqueue=/var/spool/mqueue
+ fi
+
+ while true
+ do
+ $PCP_ECHO_PROG $PCP_ECHO_N 'Mail queue directory ['"$mqueue"'] '"$PCP_ECHO_C"
+ read ans
+ [ -z "$ans" ] && break
+ if [ -d "$ans" ]
+ then
+ mqueue="$ans"
+ break
+ fi
+ echo "Error: \"$ans\" is not a directory"
+ done
+
+ echo
+ regex=""
+ $PCP_ECHO_PROG $PCP_ECHO_N 'Mail basename regex ['"$regex"'] '"$PCP_ECHO_C"
+ read regex
+ [ -z "$regex" ] || args="$args -r $regex"
+
+ echo
+ args="$args $mqueue"
+
+ while true
+ do
+ echo 'The default delay thresholds for grouping the pending mail items are:'
+ echo ' 1 hour, 4 hours, 8 hours, 1 day, 3 days and 7 days'
+ echo
+ $PCP_ECHO_PROG $PCP_ECHO_N 'Do you wish to use the default delay thresholds [y]? '"$PCP_ECHO_C"
+ read ans
+ if [ -z "$ans" -o "$ans" = "y" -o "$ans" = "Y" ]
+ then
+ break
+ else
+ bucketlist=''
+ while true
+ do
+ $PCP_ECHO_PROG $PCP_ECHO_N 'Threshold? [return if no more] '"$PCP_ECHO_C"
+ read ans
+ [ -z "$ans" ] && break
+ # strip blanks so args in pmcd.conf get passed correctly to
+ # the mailqpmda binary
+ #
+ ans=`echo "$ans" | sed -e 's/ //g'`
+ if [ -z "$bucketlist" ]
+ then
+ bucketlist="$ans"
+ else
+ bucketlist="$bucketlist,$ans"
+ fi
+ done
+ if [ ! -z "$bucketlist" ]
+ then
+ args="$args -b $bucketlist"
+ break
+ fi
+ echo
+ echo 'Error: you must specify at least one threshold'
+ echo
+ fi
+ done
+ echo
+fi
+
+pmdaInstall
+
+exit 0
diff --git a/src/pmdas/mailq/README b/src/pmdas/mailq/README
new file mode 100644
index 0000000..08bbfb6
--- /dev/null
+++ b/src/pmdas/mailq/README
@@ -0,0 +1,48 @@
+Mailq PMDA
+==========
+
+This PMDA exports information about the sendmail(1) queue.
+
+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 mailq
+
+Installation
+============
+
+ + # cd $PCP_PMDAS_DIR/mailq
+
+ + 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.
+
+De-installation
+===============
+
+ + Simply use
+
+ # cd $PCP_PMDAS_DIR/mailq
+ # ./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/mailq.log) should be checked for any warnings
+ or errors.
diff --git a/src/pmdas/mailq/Remove b/src/pmdas/mailq/Remove
new file mode 100644
index 0000000..77da216
--- /dev/null
+++ b/src/pmdas/mailq/Remove
@@ -0,0 +1,38 @@
+#! /bin/sh
+#
+# Copyright (c) 1997 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.
+#
+# 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
+#
+# Remove the mailq PMDA
+#
+
+# Get standard environment
+. $PCP_DIR/etc/pcp.env
+
+# Get the common procedures and variable assignments
+#
+. $PCP_SHARE_DIR/lib/pmdaproc.sh
+
+# The name of the PMDA
+#
+iam=mailq
+
+# Do it
+#
+pmdaSetup
+pmdaRemove
+
+exit 0
diff --git a/src/pmdas/mailq/help b/src/pmdas/mailq/help
new file mode 100644
index 0000000..29a1792
--- /dev/null
+++ b/src/pmdas/mailq/help
@@ -0,0 +1,52 @@
+#
+# Copyright (c) 2000-2004 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.
+#
+# 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
+#
+# mailq 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
+#
+
+@ MAILQ.1 Instance domain used to "bin" messages based on how long they have been deferred
+
+
+@ mailq.length Number of messages in the queue
+The total number of messages in the mail queue.
+
+@ mailq.deferred Histogram of pending messages based on how long they have been deferred
+Counts of the number of messages in the sendmail queue grouped by
+how long the mail delivery has been deferred.
+
+The groups are based on the how long a message has been in the
+queue:
+ 1-week at least a week
+ 3-days at least 3 days and less than a week
+ 1-day at least one day and less than 3 days
+ 8-hours more than 8 hours and less than one day
+ 4-hours between 4 and 8 hours
+ 1-hour between 1 and 4 hours
+ recent less than an hour
diff --git a/src/pmdas/mailq/mailq.c b/src/pmdas/mailq/mailq.c
new file mode 100644
index 0000000..8d82fcd
--- /dev/null
+++ b/src/pmdas/mailq/mailq.c
@@ -0,0 +1,401 @@
+/*
+ * Mailq PMDA
+ *
+ * Copyright (c) 2012,2014 Red Hat.
+ * Copyright (c) 1997-2000,2003 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 "pmapi.h"
+#include "impl.h"
+#include "pmda.h"
+#include "domain.h"
+#ifdef HAVE_REGEX_H
+#include <regex.h>
+#endif
+#include <sys/stat.h>
+
+/*
+ * histogram for binning messages based on queue time
+ */
+typedef struct {
+ long count; /* number in this bin */
+ time_t delay; /* in queue for at least this long (seconds) */
+} histo_t;
+
+static histo_t *histo;
+static int numhisto;
+static int queue;
+
+/*
+ * list of instances - indexes must match histo[] above
+ */
+static pmdaInstid *_delay;
+
+static char *queuedir = "/var/spool/mqueue";
+static char startdir[MAXPATHLEN];
+static char *username;
+
+static char *regexstring;
+static regex_t mq_regex;
+
+/*
+ * list of instance domains
+ */
+static pmdaIndom indomtab[] = {
+#define DELAY_INDOM 0
+ { DELAY_INDOM, 0, NULL },
+};
+
+/*
+ * all metrics supported in this PMDA - one table entry for each
+ */
+static pmdaMetric metrictab[] = {
+/* length */
+ { NULL,
+ { PMDA_PMID(0,0), PM_TYPE_U32, PM_INDOM_NULL, PM_SEM_INSTANT,
+ PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, },
+/* deferred */
+ { NULL,
+ { PMDA_PMID(0,1), PM_TYPE_U32, DELAY_INDOM, PM_SEM_INSTANT,
+ PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, },
+};
+
+static int
+mailq_histogram(char *option)
+{
+ struct timeval tv;
+ char *errmsg;
+ char *q;
+ int sts;
+
+ q = strtok(option, ",");
+ while (q != NULL) {
+ if ((sts = pmParseInterval((const char *)q, &tv, &errmsg)) < 0) {
+ pmprintf("%s: bad historgram bins argument:\n%s\n", pmProgname, errmsg);
+ free(errmsg);
+ return -EINVAL;
+ }
+ numhisto++;
+ histo = (histo_t *)realloc(histo, numhisto * sizeof(histo[0]));
+ if (histo == NULL)
+ __pmNoMem("histo", numhisto * sizeof(histo[0]), PM_FATAL_ERR);
+ histo[numhisto-1].delay = tv.tv_sec;
+ q = strtok(NULL, ",");
+ }
+ return 0;
+}
+
+static int
+compare_delay(const void *a, const void *b)
+{
+ histo_t *ha = (histo_t *)a;
+ histo_t *hb = (histo_t *)b;
+
+ return hb->delay - ha->delay;
+}
+
+/*
+ * callback provided to pmdaFetch
+ */
+static int
+mailq_fetchCallBack(pmdaMetric *mdesc, unsigned int inst, pmAtomValue *atom)
+{
+ __pmID_int *idp = (__pmID_int *)&(mdesc->m_desc.pmid);
+ int b;
+
+ if (idp->cluster == 0) {
+ if (idp->item == 0) { /* mailq.length */
+ if (inst == PM_IN_NULL)
+ atom->ul = queue;
+ else
+ return PM_ERR_INST;
+ }
+ else if (idp->item == 1) { /* mailq.deferred */
+ /* inst is unsigned, so always >= 0 */
+ for (b = 0; b < numhisto; b++) {
+ if (histo[b].delay == inst) break;
+ }
+ if (b < numhisto)
+ atom->ul = histo[b].count;
+ else
+ return PM_ERR_INST;
+ }
+ else
+ return PM_ERR_PMID;
+ }
+ else
+ return PM_ERR_PMID;
+
+ return 0;
+}
+
+/*
+ * wrapper for pmdaFetch which refreshes the metrics
+ */
+static int
+mailq_fetch(int numpmid, pmID pmidlist[], pmResult **resp, pmdaExt *pmda)
+{
+ static int warn = 0;
+ int num;
+ int i;
+ int b;
+ struct stat sbuf;
+ time_t now;
+ static time_t last_refresh = 0;
+ time_t waiting;
+ char *p;
+ struct dirent **list;
+
+ time(&now);
+
+ /* clip refresh rate to at most once per 30 seconds */
+ if (now - last_refresh > 30) {
+ last_refresh = now;
+
+ queue = 0;
+ for (b = 0; b < numhisto; b++)
+ histo[b].count = 0;
+
+ if (chdir(queuedir) < 0) {
+ if (warn == 0) {
+ __pmNotifyErr(LOG_ERR, "chdir(\"%s\") failed: %s\n",
+ queuedir, osstrerror());
+ warn = 1;
+ }
+ }
+ else {
+ if (warn == 1) {
+ __pmNotifyErr(LOG_INFO, "chdir(\"%s\") success\n", queuedir);
+ warn = 0;
+ }
+
+ num = scandir(".", &list, NULL, NULL);
+
+ for (i = 0; i < num; i++) {
+ p = list[i]->d_name;
+ /* only file names that match the regular expression */
+ if (regexstring && regexec(&mq_regex, list[i]->d_name, 0, NULL, 0))
+ continue;
+ else if (!regexstring && (*p != 'd' || *(p+1) != 'f'))
+ continue;
+ if (stat(p, &sbuf) != 0) {
+ /*
+ * ENOENT expected sometimes if sendmail is doing its job
+ */
+ if (oserror() == ENOENT)
+ continue;
+ fprintf(stderr, "stat(\"%s\"): %s\n", p, osstrerror());
+ continue;
+ }
+ if (sbuf.st_size > 0 && S_ISREG(sbuf.st_mode)) {
+ /* really in the queue */
+#if defined(HAVE_ST_MTIME_WITH_E)
+ waiting = now - sbuf.st_mtime;
+#elif defined(HAVE_ST_MTIME_WITH_SPEC)
+ waiting = now - sbuf.st_mtimespec.tv_sec;
+#else
+ waiting = now - sbuf.st_mtim.tv_sec;
+#endif
+ for (b = 0; b < numhisto; b++) {
+ if (waiting >= histo[b].delay) {
+ histo[b].count++;
+ break;
+ }
+ }
+ queue++;
+ }
+ }
+ for (i = 0; i < num; i++)
+ free(list[i]);
+ if (num > 0)
+ free(list);
+ }
+ if (chdir(startdir) < 0) {
+ __pmNotifyErr(LOG_ERR, "chdir(\"%s\") failed: %s\n",
+ startdir, osstrerror());
+ }
+ }
+
+ return pmdaFetch(numpmid, pmidlist, resp, pmda);
+}
+
+/*
+ * Initialise the agent (daemon only).
+ */
+void
+mailq_init(pmdaInterface *dp)
+{
+ if (dp->status != 0)
+ return;
+
+ __pmSetProcessIdentity(username);
+ dp->version.two.fetch = mailq_fetch;
+ pmdaSetFetchCallBack(dp, mailq_fetchCallBack);
+ pmdaInit(dp, indomtab, sizeof(indomtab)/sizeof(indomtab[0]), metrictab,
+ sizeof(metrictab)/sizeof(metrictab[0]));
+}
+
+pmdaInterface dispatch;
+
+pmLongOptions longopts[] = {
+ PMDA_OPTIONS_HEADER("Options"),
+ PMOPT_DEBUG,
+ { "binlist", 1, 'b', "TIMES", "comma-separated histogram bins times" },
+ PMDAOPT_DOMAIN,
+ PMDAOPT_LOGFILE,
+ { "regex", 1, 'r', "RE", "regular expression for matching mail file names" },
+ PMDAOPT_USERNAME,
+ PMOPT_HELP,
+ PMDA_OPTIONS_END
+};
+
+pmdaOptions opts = {
+ .short_options = "b:D:d:l:r:U:?",
+ .long_options = longopts,
+ .short_usage = "[options] [queuedir]",
+};
+
+/*
+ * Set up the agent, running as a daemon.
+ */
+int
+main(int argc, char **argv)
+{
+ int sep = __pmPathSeparator();
+ int c;
+ int i;
+ char namebuf[30];
+ char mypath[MAXPATHLEN];
+
+ __pmSetProgname(argv[0]);
+ __pmGetUsername(&username);
+
+ if (getcwd(startdir, sizeof(startdir)) == NULL) {
+ fprintf(stderr, "%s: getcwd() failed: %s\n",
+ pmProgname, pmErrStr(-oserror()));
+ exit(1);
+ }
+
+ snprintf(mypath, sizeof(mypath), "%s%c" "mailq" "%c" "help",
+ pmGetConfig("PCP_PMDAS_DIR"), sep, sep);
+ pmdaDaemon(&dispatch, PMDA_INTERFACE_2, pmProgname, MAILQ,
+ "mailq.log", mypath);
+
+ while ((c = pmdaGetOptions(argc, argv, &opts, &dispatch)) != EOF) {
+ switch (c) {
+ case 'b':
+ if (mailq_histogram(opts.optarg) < 0)
+ opts.errors++;
+ break;
+
+ case 'r':
+ regexstring = opts.optarg;
+ c = regcomp(&mq_regex, regexstring, REG_EXTENDED | REG_NOSUB);
+ if (c != 0) {
+ regerror(c, &mq_regex, mypath, sizeof(mypath));
+ pmprintf("%s: cannot compile regular expression: %s\n",
+ pmProgname, mypath);
+ opts.errors++;
+ }
+ break;
+ }
+ }
+
+ if (opts.optind == argc - 1)
+ queuedir = argv[opts.optind];
+ else if (opts.optind != argc)
+ opts.errors++;
+
+ if (opts.errors) {
+ pmdaUsageMessage(&opts);
+ exit(1);
+ }
+
+ if (opts.username)
+ username = opts.username;
+
+ if (histo == NULL) {
+ /* default histo bins, if not already done above ... */
+ numhisto = 7;
+ histo = (histo_t *)malloc(numhisto * sizeof(histo[0]));
+ if (histo == NULL) {
+ __pmNoMem("histo", numhisto * sizeof(histo[0]), PM_FATAL_ERR);
+ }
+ histo[0].delay = 7 * 24 * 3600;
+ histo[1].delay = 3 * 24 * 3600;
+ histo[2].delay = 24 * 3600;
+ histo[3].delay = 8 * 3600;
+ histo[4].delay = 4 * 3600;
+ histo[5].delay = 1 * 3600;
+ histo[6].delay = 0;
+ }
+ else {
+ /* need to add last one and sort on descending time */
+ numhisto++;
+ histo = (histo_t *)realloc(histo, numhisto * sizeof(histo[0]));
+ if (histo == NULL) {
+ __pmNoMem("histo", numhisto * sizeof(histo[0]), PM_FATAL_ERR);
+ }
+ histo[numhisto-1].delay = 0;
+ qsort(histo, numhisto, sizeof(histo[0]), compare_delay);
+ }
+
+ _delay = (pmdaInstid *)malloc(numhisto * sizeof(_delay[0]));
+ if (_delay == NULL)
+ __pmNoMem("_delay", numhisto * sizeof(_delay[0]), PM_FATAL_ERR);
+
+ for (i = 0; i < numhisto; i++) {
+ time_t tmp;
+ _delay[i].i_inst = histo[i].delay;
+ histo[i].count = 0;
+ if (histo[i].delay == 0)
+ sprintf(namebuf, "recent");
+ else if (histo[i].delay < 60)
+ sprintf(namebuf, "%d-secs", (int)histo[i].delay);
+ else if (histo[i].delay < 60 * 60) {
+ tmp = histo[i].delay / 60;
+ if (tmp <= 1)
+ sprintf(namebuf, "1-min");
+ else
+ sprintf(namebuf, "%d-mins", (int)tmp);
+ }
+ else if (histo[i].delay < 24 * 60 * 60) {
+ tmp = histo[i].delay / (60 * 60);
+ if (tmp <= 1)
+ sprintf(namebuf, "1-hour");
+ else
+ sprintf(namebuf, "%d-hours", (int)tmp);
+ }
+ else {
+ tmp = histo[i].delay / (24 * 60 * 60);
+ if (tmp <= 1)
+ sprintf(namebuf, "1-day");
+ else
+ sprintf(namebuf, "%d-days", (int)tmp);
+ }
+ _delay[i].i_name = strdup(namebuf);
+ if (_delay[i].i_name == NULL) {
+ __pmNoMem("_delay[i].i_name", strlen(namebuf), PM_FATAL_ERR);
+ }
+ }
+
+ indomtab[DELAY_INDOM].it_numinst = numhisto;
+ indomtab[DELAY_INDOM].it_set = _delay;
+
+ pmdaOpenLog(&dispatch);
+ mailq_init(&dispatch);
+ pmdaConnect(&dispatch);
+ pmdaMain(&dispatch);
+
+ exit(0);
+}
diff --git a/src/pmdas/mailq/pmlogconf.summary b/src/pmdas/mailq/pmlogconf.summary
new file mode 100644
index 0000000..a0534a0
--- /dev/null
+++ b/src/pmdas/mailq/pmlogconf.summary
@@ -0,0 +1,5 @@
+#pmlogconf-setup 2.0
+ident mailq PMDA summary information
+probe mailq.length exists ? include : exclude
+ mailq.length
+ mailq.deferred
diff --git a/src/pmdas/mailq/pmns b/src/pmdas/mailq/pmns
new file mode 100644
index 0000000..3de37aa
--- /dev/null
+++ b/src/pmdas/mailq/pmns
@@ -0,0 +1,24 @@
+/*
+ * Metrics for mailq PMDA
+ *
+ * Copyright (c) 2000-2004 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.
+ *
+ * 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
+ */
+
+mailq {
+ length MAILQ:0:0
+ deferred MAILQ:0:1
+}
diff --git a/src/pmdas/mailq/root b/src/pmdas/mailq/root
new file mode 100644
index 0000000..eab4db5
--- /dev/null
+++ b/src/pmdas/mailq/root
@@ -0,0 +1,10 @@
+/*
+ * fake "root" for validating the local PMNS subtree
+ */
+
+#include <stdpmid>
+
+root { mailq }
+
+#include "pmns"
+