diff options
Diffstat (limited to 'src/pmdas/lustrecomm/lustrecomm.c')
-rw-r--r-- | src/pmdas/lustrecomm/lustrecomm.c | 304 |
1 files changed, 304 insertions, 0 deletions
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); +} |