diff options
Diffstat (limited to 'qa/pmdas/dynamic')
-rw-r--r-- | qa/pmdas/dynamic/GNUmakefile | 29 | ||||
-rw-r--r-- | qa/pmdas/dynamic/GNUmakefile.install | 39 | ||||
-rwxr-xr-x | qa/pmdas/dynamic/Install | 16 | ||||
-rwxr-xr-x | qa/pmdas/dynamic/Remove | 14 | ||||
-rw-r--r-- | qa/pmdas/dynamic/domain.h | 1 | ||||
-rw-r--r-- | qa/pmdas/dynamic/dynamic.c | 420 | ||||
-rw-r--r-- | qa/pmdas/dynamic/help | 25 | ||||
-rw-r--r-- | qa/pmdas/dynamic/pmns | 18 | ||||
-rw-r--r-- | qa/pmdas/dynamic/root | 5 |
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" |