summaryrefslogtreecommitdiff
path: root/qa/pmdas/dynamic
diff options
context:
space:
mode:
Diffstat (limited to 'qa/pmdas/dynamic')
-rw-r--r--qa/pmdas/dynamic/GNUmakefile29
-rw-r--r--qa/pmdas/dynamic/GNUmakefile.install39
-rwxr-xr-xqa/pmdas/dynamic/Install16
-rwxr-xr-xqa/pmdas/dynamic/Remove14
-rw-r--r--qa/pmdas/dynamic/domain.h1
-rw-r--r--qa/pmdas/dynamic/dynamic.c420
-rw-r--r--qa/pmdas/dynamic/help25
-rw-r--r--qa/pmdas/dynamic/pmns18
-rw-r--r--qa/pmdas/dynamic/root5
9 files changed, 567 insertions, 0 deletions
diff --git a/qa/pmdas/dynamic/GNUmakefile b/qa/pmdas/dynamic/GNUmakefile
new file mode 100644
index 0000000..ef4e8f4
--- /dev/null
+++ b/qa/pmdas/dynamic/GNUmakefile
@@ -0,0 +1,29 @@
+#
+# Copyright (c) 2012 Red Hat.
+#
+
+TOPDIR = ../../..
+include $(TOPDIR)/src/include/builddefs
+
+TESTDIR = $(PCP_VAR_DIR)/testsuite/pmdas/dynamic
+
+CFILES = dynamic.c
+CMDTARGET = pmdadynamic
+TARGETS = $(LIBTARGET) $(CMDTARGET)
+MYFILES = domain.h help pmns root
+MYSCRIPTS = Install Remove
+LSRCFILES = $(MYSCRIPTS) $(MYFILES) GNUmakefile.install
+LDIRT = help.pag help.dir
+
+LLDFLAGS = $(PCP_LIBS)
+LLDLIBS = $(PCP_PMDALIB)
+
+default default_pcp setup: $(TARGETS)
+
+install install_pcp:
+ $(INSTALL) -m 755 -d $(TESTDIR)
+ $(INSTALL) -m 644 $(CFILES) $(MYFILES) $(TESTDIR)
+ $(INSTALL) -m 755 $(MYSCRIPTS) $(TARGETS) $(TESTDIR)
+ $(INSTALL) -m 644 GNUmakefile.install $(TESTDIR)/GNUmakefile
+
+include $(BUILDRULES)
diff --git a/qa/pmdas/dynamic/GNUmakefile.install b/qa/pmdas/dynamic/GNUmakefile.install
new file mode 100644
index 0000000..5606aef
--- /dev/null
+++ b/qa/pmdas/dynamic/GNUmakefile.install
@@ -0,0 +1,39 @@
+#!gmake
+#
+# Copyright (c) 2009 Aconex. All Rights Reserved.
+#
+
+SHELL = sh
+
+ifdef PCP_CONF
+include $(PCP_CONF)
+else
+include $(PCP_DIR)/etc/pcp.conf
+endif
+include $(PCP_INC_DIR)/builddefs
+
+# remove -Lpath and -Ipath options from builddefs CFLAGS value
+#
+PCP_LIBS =
+TMP := $(CFLAGS:-I%=)
+ifdef PCP_DIR
+# put -Ipath and -Lpath back but use paths for run-time environment
+#
+CFLAGS = $(TMP) -I$(PCP_INC_DIR)/..
+LDFLAGS = -L$(PCP_LIB_DIR)
+else
+CFLAGS = $(TMP)
+endif
+
+CFILES = dynamic.c
+CMDTARGET = pmdadynamic
+TARGETS = $(LIBTARGET) $(CMDTARGET)
+LDIRT = *.log help.dir help.pag
+
+LLDLIBS = -lpcp_pmda -lpcp $(LIB_FOR_MATH) $(LIB_FOR_DLOPEN) $(LIB_FOR_PTHREADS)
+
+default default_pcp setup:: $(TARGETS)
+
+install install_pcp:
+
+include $(PCP_INC_DIR)/buildrules
diff --git a/qa/pmdas/dynamic/Install b/qa/pmdas/dynamic/Install
new file mode 100755
index 0000000..17eec23
--- /dev/null
+++ b/qa/pmdas/dynamic/Install
@@ -0,0 +1,16 @@
+#!/bin/sh
+#
+# Copyright (c) 1997-2002 Silicon Graphics, Inc. All Rights Reserved.
+#
+
+. /etc/pcp.env
+. $PCP_SHARE_DIR/lib/pmdaproc.sh
+PCP_PMDAS_DIR=${PCP_VAR_DIR}/testsuite/pmdas
+
+iam=dynamic
+dso_opt=false
+pmda_interface=4
+
+pmdaSetup
+pmdaInstall
+exit 0
diff --git a/qa/pmdas/dynamic/Remove b/qa/pmdas/dynamic/Remove
new file mode 100755
index 0000000..c29b0a7
--- /dev/null
+++ b/qa/pmdas/dynamic/Remove
@@ -0,0 +1,14 @@
+#!/bin/sh
+#
+# Copyright (c) 1997-2002 Silicon Graphics, Inc. All Rights Reserved.
+#
+# Remove the dynamic PMDA
+#
+
+. /etc/pcp.env
+. $PCP_SHARE_DIR/lib/pmdaproc.sh
+
+iam=dynamic
+pmdaSetup
+pmdaRemove
+exit 0
diff --git a/qa/pmdas/dynamic/domain.h b/qa/pmdas/dynamic/domain.h
new file mode 100644
index 0000000..b17087b
--- /dev/null
+++ b/qa/pmdas/dynamic/domain.h
@@ -0,0 +1 @@
+#define DYNAMIC 247
diff --git a/qa/pmdas/dynamic/dynamic.c b/qa/pmdas/dynamic/dynamic.c
new file mode 100644
index 0000000..05c73ec
--- /dev/null
+++ b/qa/pmdas/dynamic/dynamic.c
@@ -0,0 +1,420 @@
+/*
+ * Dynamic PMDA for testing dynamic indom support
+ *
+ * Copyright (c) 1995-2002 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <stdio.h>
+#include <syslog.h>
+#include <errno.h>
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+#include <pcp/pmda.h>
+#include "domain.h"
+
+/*
+ * Dynamic PMDA
+ *
+ * This PMDA has several metrics with a single dynamic indom.
+ * This indom can be controlled by several storable metrics.
+ *
+ * Metrics
+ *
+ * dynamic.numinst - number of instances in the indom right now
+ * dynamic.discrete - discrete metric
+ * dynamic.instant - instantaneous metric
+ * dynamic.counter - counter metric
+ * dynamic.control.add - add an instance
+ * dynamic.control.del - delete an instance
+ *
+ */
+
+/* data and function prototypes for dynamic instance domain handling */
+struct Dynamic {
+ int id;
+ char name[16];
+ unsigned counter;
+};
+
+/*
+ * list of instances
+ */
+
+static struct Dynamic *insts = NULL;
+static pmdaInstid *instids = NULL;
+static unsigned numInsts = 0;
+static unsigned sizeInsts = 0;
+
+/*
+ * list of instance domains
+ */
+
+static pmdaIndom indomtab[] = {
+#define DYNAMIC_INDOM 0
+ { DYNAMIC_INDOM, 0, NULL }
+};
+
+/*
+ * all metrics supported in this PMDA - one table entry for each
+ */
+
+static pmdaMetric metrictab[] = {
+/* numinsts */
+ { NULL,
+ { PMDA_PMID(0,0), PM_TYPE_U32, PM_INDOM_NULL, PM_SEM_INSTANT,
+ PMDA_PMUNITS(0,0,0,0,0,0) }, },
+/* discrete */
+ { NULL,
+ { PMDA_PMID(0,1), PM_TYPE_STRING, DYNAMIC_INDOM, PM_SEM_DISCRETE,
+ PMDA_PMUNITS(0,0,0,0,0,0) }, },
+/* instant */
+ { NULL,
+ { PMDA_PMID(0,2), PM_TYPE_U32, DYNAMIC_INDOM, PM_SEM_INSTANT,
+ PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, },
+/* counter */
+ { NULL,
+ { PMDA_PMID(0,3), PM_TYPE_U32, DYNAMIC_INDOM, PM_SEM_COUNTER,
+ PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, },
+/* control.add */
+ { NULL,
+ { PMDA_PMID(1,4), PM_TYPE_32, PM_INDOM_NULL, PM_SEM_INSTANT,
+ PMDA_PMUNITS(0,0,0,0,0,0) }, },
+/* control.del */
+ { NULL,
+ { PMDA_PMID(1,5), PM_TYPE_32, PM_INDOM_NULL, PM_SEM_INSTANT,
+ PMDA_PMUNITS(0,0,0,0,0,0) }, },
+};
+
+/*
+ * callback provided to pmdaFetch
+ */
+static int
+dynamic_fetchCallBack(pmdaMetric *mdesc, unsigned int inst, pmAtomValue *atom)
+{
+ __pmID_int *idp = (__pmID_int *)&(mdesc->m_desc.pmid);
+
+ if (inst != PM_IN_NULL &&
+ !(idp->cluster == 0 && idp->item >= 1 && idp->item <= 3))
+ return PM_ERR_INST;
+
+ __pmNotifyErr(LOG_DEBUG, "dynamic_fetch: %d.%d[%d]\n",
+ idp->cluster, idp->item, inst);
+
+ if (idp->cluster == 0) {
+ switch (idp->item) {
+ case 0: /* numinst */
+ atom->ul = numInsts;
+ break;
+
+ case 1: /* discrete */
+ if (inst < sizeInsts)
+ if (insts[inst].id >= 0)
+ atom->cp = insts[inst].name;
+ else
+ return PM_ERR_INST;
+ else
+ return PM_ERR_INST;
+ break;
+
+ case 2: /* instant */
+ if (inst < sizeInsts)
+ if (insts[inst].id >= 0)
+ atom->ul = insts[inst].counter;
+ else
+ return PM_ERR_INST;
+ else
+ return PM_ERR_INST;
+ break;
+
+ case 3: /* counter */
+ if (inst < sizeInsts)
+ if (insts[inst].id >= 0)
+ atom->ul = insts[inst].counter;
+ else
+ return PM_ERR_INST;
+ else
+ return PM_ERR_INST;
+ break;
+
+ default:
+ return PM_ERR_PMID;
+ }
+ }
+ else if (idp->cluster == 1) { /* dynamic.control */
+ switch(idp->item) {
+ case 4: /* add */
+ atom->ul = sizeInsts;
+ break;
+
+ case 5: /* del */
+ atom->ul = sizeInsts - numInsts;
+ break;
+
+ default:
+ return PM_ERR_PMID;
+ }
+ }
+ else
+ return PM_ERR_PMID;
+
+ return 1;
+}
+
+/*
+ * wrapper for pmdaFetch which increments the counters for each instance
+ */
+static int
+dynamic_fetch(int numpmid, pmID pmidlist[], pmResult **resp, pmdaExt *pmda)
+{
+ int i;
+
+ for (i = 0; i < sizeInsts; i++)
+ if (insts[i].id >= 0)
+ insts[i].counter += insts[i].id;
+
+ return pmdaFetch(numpmid, pmidlist, resp, pmda);
+}
+
+/*
+ * add or delete an instance
+ */
+/*ARGSUSED*/
+static int
+dynamic_store(pmResult *result, pmdaExt *pmda)
+{
+ int i;
+ int j;
+ int changed = 0;
+ int sts = 0;
+ int val;
+ pmValueSet *vsp = NULL;
+ __pmID_int *pmidp = NULL;
+
+ for (i = 0; i < result->numpmid; i++) {
+ vsp = result->vset[i];
+ pmidp = (__pmID_int *)&vsp->pmid;
+
+ if (pmidp->cluster == 1) { /* all storable metrics are cluster 1 */
+
+ switch (pmidp->item) {
+ case 4: /* add */
+
+ val = vsp->vlist[0].value.lval;
+ if (val < 0) {
+ sts = PM_ERR_SIGN;
+ }
+ else if (val < sizeInsts) {
+ if (insts[val].id >= 0) {
+ sts = PM_ERR_INST;
+ }
+ else {
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_APPL0)
+ __pmNotifyErr(LOG_DEBUG,
+ "dynamic_store: Adding instance %d (size = %d)\n",
+ val, sizeInsts);
+#endif
+
+ insts[val].id = val;
+ insts[val].counter = 0;
+ numInsts++;
+ changed = 1;
+ }
+ }
+ else {
+ insts = (struct Dynamic*)realloc(insts, (val + 1) * sizeof(struct Dynamic));
+ if (insts == NULL) {
+ __pmNotifyErr(LOG_ERR,
+ "dynamic_store: Unable to realloc %d bytes\n",
+ (int)(val * sizeof(struct Dynamic)));
+ sizeInsts = 0;
+ numInsts = 0;
+ changed = 1;
+ sts = PM_ERR_TOOBIG;
+ }
+ else {
+ for (i = sizeInsts; i <= val; i++) {
+ insts[i].id = -1;
+ sprintf(insts[i].name, "%d", i);
+ insts[i].counter = 0;
+ }
+ insts[val].id = val;
+ changed = 1;
+ sizeInsts = val + 1;
+ numInsts++;
+
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_APPL0)
+ __pmNotifyErr(LOG_DEBUG,
+ "dynamic_store: Adding instance %d (size = %d)\n",
+ val, sizeInsts);
+#endif
+ }
+ }
+ break;
+
+ case 5: /* del */
+ val = vsp->vlist[0].value.lval;
+ if (val < 0) { /* delete all */
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_APPL0)
+ __pmNotifyErr(LOG_DEBUG,
+ "dynamic_store: Removing all instances\n");
+#endif
+
+ for (i = 0; i < sizeInsts; i++) {
+ insts[i].id = -1;
+ insts[i].counter = 0;
+ }
+ numInsts = 0;
+ changed = 1;
+ }
+ else if (val < sizeInsts) {
+ if (insts[val].id < 0) {
+ sts = PM_ERR_INST;
+ }
+ else {
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_APPL0)
+ __pmNotifyErr(LOG_DEBUG,
+ "dynamic_store: Removing instance %d\n",
+ val);
+#endif
+ insts[val].id = -1;
+ insts[val].counter = 0;
+ changed = 1;
+ numInsts--;
+ }
+ }
+ else
+ sts = PM_ERR_INST;
+ break;
+
+ default:
+ sts = PM_ERR_PMID;
+ break;
+ }
+ }
+ else if (pmidp->cluster == 0 && pmidp->item <= 3) {
+ sts = -EACCES;
+ break;
+ }
+ else {
+ sts = PM_ERR_PMID;
+ break;
+ }
+ }
+
+ if (changed) {
+
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_APPL0)
+ __pmNotifyErr(LOG_DEBUG,
+ "dynamic_store: Resizing to %d instances\n",
+ numInsts);
+#endif
+
+ if (numInsts > 0) {
+ instids = (pmdaInstid *)realloc(instids,
+ numInsts * sizeof(pmdaInstid));
+ if (instids == NULL) {
+ __pmNotifyErr(LOG_ERR,
+ "dynamic_store: Could not realloc %d bytes\n",
+ (int)(numInsts * sizeof(pmdaInstid)));
+ sts = PM_ERR_TOOBIG;
+ }
+ else {
+ for (i = 0, j = 0; i < sizeInsts; i++) {
+ if (insts[i].id >= 0) {
+ instids[j].i_inst = insts[i].id;
+ instids[j].i_name = insts[i].name;
+
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_APPL1)
+ __pmNotifyErr(LOG_DEBUG,
+ "dynamic_store: [%d] %d \"%s\"\n",
+ j, instids[j].i_inst,
+ instids[j].i_name);
+#endif
+
+ j++;
+ }
+ }
+ indomtab[DYNAMIC_INDOM].it_numinst = numInsts;
+ indomtab[DYNAMIC_INDOM].it_set = instids;
+ }
+ }
+ else {
+ indomtab[DYNAMIC_INDOM].it_numinst = 0;
+ indomtab[DYNAMIC_INDOM].it_set = NULL;
+ }
+ }
+
+ return sts;
+}
+
+/*
+ * Initialise the agent (both daemon and DSO).
+ */
+void
+dynamic_init(pmdaInterface *dp)
+{
+ if (dp->status != 0)
+ return;
+
+ dp->version.two.fetch = dynamic_fetch;
+ dp->version.two.store = dynamic_store;
+
+ pmdaSetFetchCallBack(dp, dynamic_fetchCallBack);
+
+ pmdaInit(dp, indomtab, sizeof(indomtab)/sizeof(indomtab[0]), metrictab,
+ sizeof(metrictab)/sizeof(metrictab[0]));
+}
+
+static void
+usage(void)
+{
+ fprintf(stderr, "Usage: %s [options]\n\n", pmProgname);
+ fputs("Options:\n"
+ " -d domain use domain (numeric) for metrics domain of PMDA\n"
+ " -l logfile write log into logfile rather than using default log name\n"
+ "\nExactly one of the following options may appear:\n"
+ " -i port expect PMCD to connect on given inet port (number or name)\n"
+ " -p expect PMCD to supply stdin/stdout (pipe)\n"
+ " -u socket expect PMCD to connect on given unix domain socket\n"
+ " -6 port expect PMCD to connect on given ipv6 port (number or name)\n",
+ stderr);
+ exit(1);
+}
+
+/*
+ * Set up the agent if running as a daemon.
+ */
+int
+main(int argc, char **argv)
+{
+ int sep = __pmPathSeparator();
+ int err = 0;
+ pmdaInterface dispatch;
+ char helppath[MAXPATHLEN];
+
+ __pmSetProgname(argv[0]);
+ snprintf(helppath, sizeof(helppath),
+ "%s%c" "testsuite" "%c" "pmdas" "%c" "dynamic" "%c" "help",
+ pmGetConfig("PCP_VAR_DIR"), sep, sep, sep, sep);
+ pmdaDaemon(&dispatch, PMDA_INTERFACE_4, pmProgname, DYNAMIC,
+ "dynamic.log", helppath);
+
+ if (pmdaGetOpt(argc, argv, "D:d:h:i:l:pu:6:?", &dispatch, &err) != EOF)
+ err++;
+
+ if (err)
+ usage();
+
+ pmdaOpenLog(&dispatch);
+ dynamic_init(&dispatch);
+ pmdaConnect(&dispatch);
+ pmdaMain(&dispatch);
+
+ exit(0);
+}
diff --git a/qa/pmdas/dynamic/help b/qa/pmdas/dynamic/help
new file mode 100644
index 0000000..110151e
--- /dev/null
+++ b/qa/pmdas/dynamic/help
@@ -0,0 +1,25 @@
+#
+# dynamic help file
+#
+
+@ dynamic.numinsts number of instances
+The number of instances currently being exported
+
+@ dynamic.discrete instance id as a string
+The instance identifier exported as a string
+
+@ dynamic.instant counter as a instaneous value
+The counter for the instance exported as an instaneous value
+
+@ dynamic.counter counter as a counter
+The counter for the instance exported as a counter
+
+@ dynamic.control.add add an instance
+Storing the instance id of an instance not currently exported
+will all that instance to the indom.
+
+@ dynamic.control.del delete an instance
+Storing the instance id of an instance that is currently being
+exported will remove that instance from the indom. Storing a negative
+number will cause all instances to be removed.
+
diff --git a/qa/pmdas/dynamic/pmns b/qa/pmdas/dynamic/pmns
new file mode 100644
index 0000000..aa81933
--- /dev/null
+++ b/qa/pmdas/dynamic/pmns
@@ -0,0 +1,18 @@
+/*
+ * Metrics for a dynamic PMDA
+ */
+
+#include <stdpmid>
+
+dynamic {
+ numinsts DYNAMIC:0:0
+ discrete DYNAMIC:0:1
+ instant DYNAMIC:0:2
+ counter DYNAMIC:0:3
+ control
+}
+
+dynamic.control {
+ add DYNAMIC:1:4
+ del DYNAMIC:1:5
+}
diff --git a/qa/pmdas/dynamic/root b/qa/pmdas/dynamic/root
new file mode 100644
index 0000000..22fccee
--- /dev/null
+++ b/qa/pmdas/dynamic/root
@@ -0,0 +1,5 @@
+root {
+ dynamic
+}
+
+#include "pmns"