diff options
author | Igor Pashev <pashev.igor@gmail.com> | 2014-10-26 12:33:50 +0400 |
---|---|---|
committer | Igor Pashev <pashev.igor@gmail.com> | 2014-10-26 12:33:50 +0400 |
commit | 47e6e7c84f008a53061e661f31ae96629bc694ef (patch) | |
tree | 648a07f3b5b9d67ce19b0fd72e8caa1175c98f1a /src/pmdas/jbd2/pmda.c | |
download | pcp-debian.tar.gz |
Debian 3.9.10debian/3.9.10debian
Diffstat (limited to 'src/pmdas/jbd2/pmda.c')
-rw-r--r-- | src/pmdas/jbd2/pmda.c | 322 |
1 files changed, 322 insertions, 0 deletions
diff --git a/src/pmdas/jbd2/pmda.c b/src/pmdas/jbd2/pmda.c new file mode 100644 index 0000000..3c2dcba --- /dev/null +++ b/src/pmdas/jbd2/pmda.c @@ -0,0 +1,322 @@ +/* + * Journal Block Device v2 PMDA + * + * Copyright (c) 2013-2014 Red Hat. + * + * 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" +#include "convert.h" +#include "proc_jbd2.h" + +static int _isDSO = 1; /* =0 I am a daemon */ +static char *prefix = "/proc/fs/jbd2"; +static char *username; + +#define JBD2_INDOM 0 +#define INDOM(i) (indomtab[i].it_indom) +static pmdaIndom indomtab[] = { + { JBD2_INDOM, 0, NULL }, /* cached */ +}; + +static pmdaMetric metrictab[] = { + +/* jbd2.njournals */ + { NULL, { PMDA_PMID(0,0), PM_TYPE_U32, PM_INDOM_NULL, + PM_SEM_INSTANT, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, + +/* jbd2.transaction.count */ + { NULL, { PMDA_PMID(0,1), KERNEL_ULONG, JBD2_INDOM, + PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* jbd2.transaction.requested */ + { NULL, { PMDA_PMID(0,2), KERNEL_ULONG, JBD2_INDOM, + PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* jbd2.transaction.max_blocks */ + { NULL, { PMDA_PMID(0,3), PM_TYPE_U32, JBD2_INDOM, + PM_SEM_INSTANT, PMDA_PMUNITS(0,0,0,0,0,0) }, }, + +/* jbd2.transaction.total.time.waiting */ + { NULL, { PMDA_PMID(0,4), PM_TYPE_U64, JBD2_INDOM, + PM_SEM_COUNTER, PMDA_PMUNITS(0,1,0,0,PM_TIME_MSEC,0) }, }, +/* jbd2.transaction.total.time.request_delay */ + { NULL, { PMDA_PMID(0,5), PM_TYPE_U64, JBD2_INDOM, + PM_SEM_COUNTER, PMDA_PMUNITS(0,1,0,0,PM_TIME_MSEC,0) }, }, +/* jbd2.transaction.total.time.running */ + { NULL, { PMDA_PMID(0,6), PM_TYPE_U64, JBD2_INDOM, + PM_SEM_COUNTER, PMDA_PMUNITS(0,1,0,0,PM_TIME_MSEC,0) }, }, +/* jbd2.transaction.total.time.being_locked */ + { NULL, { PMDA_PMID(0,7), PM_TYPE_U64, JBD2_INDOM, + PM_SEM_COUNTER, PMDA_PMUNITS(0,1,0,0,PM_TIME_MSEC,0) }, }, +/* jbd2.transaction.total.time.flushing_ordered_mode_data */ + { NULL, { PMDA_PMID(0,8), PM_TYPE_U64, JBD2_INDOM, + PM_SEM_COUNTER, PMDA_PMUNITS(0,1,0,0,PM_TIME_MSEC,0) }, }, +/* jbd2.transaction.total.time.logging */ + { NULL, { PMDA_PMID(0,9), PM_TYPE_U64, JBD2_INDOM, + PM_SEM_COUNTER, PMDA_PMUNITS(0,1,0,0,PM_TIME_MSEC,0) }, }, +/* jbd2.transaction.total.blocks */ + { NULL, { PMDA_PMID(0,10), PM_TYPE_U64, JBD2_INDOM, + PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* jbd2.transaction.total.blocks_logged */ + { NULL, { PMDA_PMID(0,11), PM_TYPE_U64, JBD2_INDOM, + PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* jbd2.transaction.total.handles */ + { NULL, { PMDA_PMID(0,12), PM_TYPE_U64, JBD2_INDOM, + PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, + +/* jbd2.transaction.average.time.waiting */ + { NULL, { PMDA_PMID(0,13), PM_TYPE_U32, JBD2_INDOM, + PM_SEM_INSTANT, PMDA_PMUNITS(0,1,0,0,PM_TIME_MSEC,0) }, }, +/* jbd2.transaction.average.time.request_delay */ + { NULL, { PMDA_PMID(0,14), PM_TYPE_U32, JBD2_INDOM, + PM_SEM_INSTANT, PMDA_PMUNITS(0,1,0,0,PM_TIME_MSEC,0) }, }, +/* jbd2.transaction.average.time.running */ + { NULL, { PMDA_PMID(0,15), PM_TYPE_U32, JBD2_INDOM, + PM_SEM_INSTANT, PMDA_PMUNITS(0,1,0,0,PM_TIME_MSEC,0) }, }, +/* jbd2.transaction.average.time.being_locked */ + { NULL, { PMDA_PMID(0,16), PM_TYPE_U32, JBD2_INDOM, + PM_SEM_INSTANT, PMDA_PMUNITS(0,1,0,0,PM_TIME_MSEC,0) }, }, +/* jbd2.transaction.average.time.flushing_ordered_mode_data */ + { NULL, { PMDA_PMID(0,17), PM_TYPE_U32, JBD2_INDOM, + PM_SEM_INSTANT, PMDA_PMUNITS(0,1,0,0,PM_TIME_MSEC,0) }, }, +/* jbd2.transaction.average.time.logging */ + { NULL, { PMDA_PMID(0,18), PM_TYPE_U32, JBD2_INDOM, + PM_SEM_INSTANT, PMDA_PMUNITS(0,1,0,0,PM_TIME_MSEC,0) }, }, +/* jbd2.transaction.average.time.committing */ + { NULL, { PMDA_PMID(0,19), PM_TYPE_U64, JBD2_INDOM, + PM_SEM_INSTANT, PMDA_PMUNITS(0,1,0,0,PM_TIME_USEC,0) }, }, +/* jbd2.transaction.average.blocks */ + { NULL, { PMDA_PMID(0,20), KERNEL_ULONG, JBD2_INDOM, + PM_SEM_INSTANT, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* jbd2.transaction.average.blocks_logged */ + { NULL, { PMDA_PMID(0,21), KERNEL_ULONG, JBD2_INDOM, + PM_SEM_INSTANT, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* jbd2.transaction.average.handles */ + { NULL, { PMDA_PMID(0,22), KERNEL_ULONG, JBD2_INDOM, + PM_SEM_INSTANT, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +}; + +static int +jbd2_instance(pmInDom indom, int inst, char *name, __pmInResult **result, pmdaExt *pmda) +{ + refresh_jbd2(prefix, INDOM(JBD2_INDOM)); + return pmdaInstance(indom, inst, name, result, pmda); +} + +static int +jbd2_fetch(int numpmid, pmID pmidlist[], pmResult **resp, pmdaExt *pmda) +{ + refresh_jbd2(prefix, INDOM(JBD2_INDOM)); + return pmdaFetch(numpmid, pmidlist, resp, pmda); +} + +static int +jbd2_fetchCallBack(pmdaMetric *mdesc, unsigned int inst, pmAtomValue *atom) +{ + __pmID_int *idp = (__pmID_int *)&(mdesc->m_desc.pmid); + int sts; + proc_jbd2_t *jbd2; + + switch (idp->cluster) { + case 0: + if (!idp->item) { /* jbd2.njournals */ + atom->ul = pmdaCacheOp(INDOM(JBD2_INDOM), PMDA_CACHE_SIZE_ACTIVE); + break; + } + + /* lookup the instance (journal device) */ + sts = pmdaCacheLookup(INDOM(JBD2_INDOM), inst, NULL, (void **)&jbd2); + if (sts < 0) + return sts; + if (sts != PMDA_CACHE_ACTIVE) + return PM_ERR_INST; + if (jbd2->version < 2) + return 0; + + switch (idp->item) { + + case 1: /* transaction.count */ + _pm_assign_ulong(atom, jbd2->tid); + break; + case 2: /* transaction.requested */ + if (jbd2->version < 3) + return 0; + _pm_assign_ulong(atom, jbd2->requested); + break; + case 3: /* transaction.max_blocks */ + atom->ul = jbd2->max_buffers; + break; + + case 4: /* transaction.total.time.waiting */ + atom->ull = jbd2->waiting * jbd2->tid; + break; + case 5: /* transaction.total.time.request_delay */ + if (jbd2->version < 3) + return 0; + atom->ull = jbd2->request_delay * jbd2->requested; + break; + case 6: /* transaction.total.time.running */ + atom->ull = jbd2->running * jbd2->tid; + break; + case 7: /* transaction.total.time.being_locked */ + atom->ull = jbd2->locked * jbd2->tid; + break; + case 8: /* transaction.total.time.flushing_ordered_mode_data */ + atom->ull = jbd2->flushing * jbd2->tid; + break; + case 9: /* transaction.total.time.logging */ + atom->ull = jbd2->logging * jbd2->tid; + break; + case 10: /* transaction.total.blocks */ + atom->ull = jbd2->blocks * jbd2->tid; + break; + case 11: /* transaction.total.blocks_logged */ + atom->ull = jbd2->blocks_logged * jbd2->tid; + break; + case 12: /* transaction.total.handles */ + atom->ull = jbd2->handles * jbd2->tid; + break; + + case 13: /* transaction.average.time.waiting */ + atom->ul = jbd2->waiting; + break; + case 14: /* transaction.total.time.request_delay */ + if (jbd2->version < 3) + return 0; + atom->ul = jbd2->request_delay; + break; + case 15: /* transaction.total.time.running */ + atom->ul = jbd2->running; + break; + case 16: /* transaction.total.time.being_locked */ + atom->ul = jbd2->locked; + break; + case 17: /* transaction.total.time.flushing_ordered_mode_data */ + atom->ul = jbd2->flushing; + break; + case 18: /* transaction.total.time.logging */ + atom->ul = jbd2->logging; + break; + case 19: /* transaction.average.time.committing */ + atom->ull = jbd2->average_commit_time; + break; + case 20: /* transaction.total.blocks */ + _pm_assign_ulong(atom, jbd2->blocks); + break; + case 21: /* transaction.total.blocks_logged */ + _pm_assign_ulong(atom, jbd2->blocks_logged); + break; + case 22: /* transaction.total.handles */ + _pm_assign_ulong(atom, jbd2->handles); + break; + + default: + return PM_ERR_PMID; + } + break; + + default: /* unknown cluster */ + return PM_ERR_PMID; + } + + return 1; +} + +/* + * Initialise the agent (both daemon and DSO). + */ +void +__PMDA_INIT_CALL +jbd2_init(pmdaInterface *dp) +{ + size_t nmetrics, nindoms; + + if (_isDSO) { + char helppath[MAXPATHLEN]; + int sep = __pmPathSeparator(); + snprintf(helppath, sizeof(helppath), "%s%c" "jbd2" "%c" "help", + pmGetConfig("PCP_PMDAS_DIR"), sep, sep); + pmdaDSO(dp, PMDA_INTERFACE_4, "jbd2 DSO", helppath); + } else { + __pmSetProcessIdentity(username); + } + + if (dp->status != 0) + return; + + dp->version.four.instance = jbd2_instance; + dp->version.four.fetch = jbd2_fetch; + pmdaSetFetchCallBack(dp, jbd2_fetchCallBack); + + nindoms = sizeof(indomtab)/sizeof(indomtab[0]); + nmetrics = sizeof(metrictab)/sizeof(metrictab[0]); + + pmdaSetFlags(dp, PMDA_EXT_FLAG_DIRECT); + pmdaInit(dp, indomtab, nindoms, metrictab, nmetrics); +} + +pmLongOptions longopts[] = { + PMDA_OPTIONS_HEADER("Options"), + PMOPT_DEBUG, + PMDAOPT_DOMAIN, + PMDAOPT_LOGFILE, + { "", 1, 'j', "PATH", "path to stats files (default \"/proc/fs/jbd2\")" }, + PMDAOPT_USERNAME, + PMOPT_HELP, + PMDA_OPTIONS_END +}; + +pmdaOptions opts = { + .short_options = "D:d:l:j:U:?", + .long_options = longopts, +}; + +/* + * Set up the agent if running as a daemon. + */ +int +main(int argc, char **argv) +{ + int c, sep = __pmPathSeparator(); + pmdaInterface dispatch; + char help[MAXPATHLEN]; + + _isDSO = 0; + __pmSetProgname(argv[0]); + __pmGetUsername(&username); + + snprintf(help, sizeof(help), "%s%c" "jbd2" "%c" "help", + pmGetConfig("PCP_PMDAS_DIR"), sep, sep); + pmdaDaemon(&dispatch, PMDA_INTERFACE_4, pmProgname, JBD2, "jbd2.log", help); + + while ((c = pmdaGetOptions(argc, argv, &opts, &dispatch)) != EOF) { + switch(c) { + case 'j': + prefix = opts.optarg; + break; + } + } + if (opts.errors) { + pmdaUsageMessage(&opts); + exit(1); + } + if (opts.username) + username = opts.username; + + pmdaOpenLog(&dispatch); + jbd2_init(&dispatch); + pmdaConnect(&dispatch); + pmdaMain(&dispatch); + exit(0); +} |