diff options
Diffstat (limited to 'src/pmdas/cisco/cisco.c')
-rw-r--r-- | src/pmdas/cisco/cisco.c | 265 |
1 files changed, 265 insertions, 0 deletions
diff --git a/src/pmdas/cisco/cisco.c b/src/pmdas/cisco/cisco.c new file mode 100644 index 0000000..f303480 --- /dev/null +++ b/src/pmdas/cisco/cisco.c @@ -0,0 +1,265 @@ +/* + * Copyright (c) 1995-2000 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 + */ + +#include <ctype.h> +#include <signal.h> +#include "cisco.h" +#if defined(HAVE_SYS_RESOURCE_H) +#include <sys/resource.h> +#endif +#if defined(HAVE_SYS_WAIT_H) +#include <sys/wait.h> +#endif +#if defined(HAVE_PTHREAD_H) +#include <pthread.h> +#endif +#if defined(HAVE_PRCTL_H) +#include <sys/prctl.h> +#endif + +extern int refreshdelay; + +#ifdef HAVE_SPROC +static pid_t sproc_pid = 0; +#elif defined (HAVE_PTHREAD_H) +#include <pthread.h> +static pthread_t sproc_pid; +#else +#error "Need sproc or pthreads here!" +#endif + +/* + * all metrics supported in this PMD - one table entry for each + */ +static pmdaMetric metrictab[] = { + /* 0,0 ... for direct map, sigh */ + { NULL, { PMDA_PMID(0,0), 0, 0, 0, PMDA_PMUNITS(0,0,0,0,0,0) } }, + /* bytes-in */ + { NULL, { PMDA_PMID(0,1), PM_TYPE_U64, CISCO_INDOM, PM_SEM_COUNTER, + PMDA_PMUNITS(1,0,0,PM_SPACE_BYTE,0,0) } }, + /* bytes-out */ + { NULL, { PMDA_PMID(0,2), PM_TYPE_U64, CISCO_INDOM, PM_SEM_COUNTER, + PMDA_PMUNITS(1,0,0,PM_SPACE_BYTE,0,0) } }, + /* rate-in */ + { NULL, { PMDA_PMID(0,3), PM_TYPE_U32, CISCO_INDOM, PM_SEM_INSTANT, + PMDA_PMUNITS(1,-1,0,PM_SPACE_BYTE,PM_TIME_SEC,0) } }, + /* rate-out */ + { NULL, { PMDA_PMID(0,4), PM_TYPE_U32, CISCO_INDOM, PM_SEM_INSTANT, + PMDA_PMUNITS(1,-1,0,PM_SPACE_BYTE,PM_TIME_SEC,0) } }, + /* bandwidth */ + { NULL, { PMDA_PMID(0,5), PM_TYPE_U32, CISCO_INDOM, PM_SEM_DISCRETE, + PMDA_PMUNITS(1,-1,0,PM_SPACE_BYTE,PM_TIME_SEC,0) } }, + /* bytes_out_bcast */ + { NULL, { PMDA_PMID(0,6), PM_TYPE_U64, CISCO_INDOM, PM_SEM_COUNTER, + PMDA_PMUNITS(1,0,0,PM_SPACE_BYTE,0,0) } }, + + }; + +/* filled in from command line args in main() ... */ +pmdaIndom indomtab[] = { + { 0, 0, 0 }, +}; + +#ifdef HAVE_SPROC +static RETSIGTYPE +onhup(int s) +{ + signal(SIGHUP, onhup); + exit(0); +} +#endif + +/* + * the sproc starts here to refresh the metric values periodically + */ +void +refresh(void *dummy) +{ + int i; + +#ifdef HAVE_SPROC +#if HAVE_PRCTL + signal(SIGHUP, onhup); +#if HAVE_PR_TERMCHILD + prctl(PR_TERMCHILD); /* SIGHUP when the parent dies */ +#elif HAVE_PR_SET_PDEATHSIG + prctl(PR_SET_PDEATHSIG, SIGHUP); +#endif +#endif +#endif + +#ifdef PCP_DEBUG + if (pmDebug & DBG_TRACE_APPL0) { + fprintf(stderr, "Starting sproc ...\n"); + for (i = 0; i < n_cisco; i++) { + int j; + + fprintf(stderr, "cisco[%d] host: %s username: %s passwd: %s prompt: %s intf:", + i, cisco[i].host, cisco[i].username, cisco[i].passwd, cisco[i].prompt); + + for (j = 0; j < n_intf; j++) { + if (intf[j].cp == (cisco+i)) + fprintf(stderr, " %d-%s", j, intf[j].interface); + } + fputc('\n', stderr); + } + } +#endif + + for ( ; ; ) { + for (i = 0; i < n_intf; i++) { + if (grab_cisco(intf+i) != -1) { + intf[i].fetched = 1; + } + else + intf[i].fetched = 0; + } + + if (parse_only) + exit(0); + + for (i = 0; i < n_cisco; i++) { + if (cisco[i].fout != NULL) { +#ifdef PCP_DEBUG + if (pmDebug & DBG_TRACE_APPL0) + fprintf(stderr, "... %s voluntary disconnect fout=%d\n", cisco[i].host, fileno(cisco[i].fout)); +#endif + /* close CISCO telnet session */ +#ifdef PCP_DEBUG + if (pmDebug & DBG_TRACE_APPL1) { + fprintf(stderr, "Send: exit\n"); + } +#endif + fprintf(cisco[i].fout, "exit\n"); + fclose(cisco[i].fout); + cisco[i].fout = NULL; + } + if (cisco[i].fin != NULL) { +#ifdef PCP_DEBUG + if (pmDebug & DBG_TRACE_APPL0) + fprintf(stderr, "... %s close fin=%d\n", cisco[i].host, fileno(cisco[i].fin)); +#endif + fclose(cisco[i].fin); + cisco[i].fin = NULL; + } + } + + sleep(refreshdelay); + } +} + +static int +cisco_fetchCallBack(pmdaMetric *mdesc, unsigned int inst, pmAtomValue *avp) +{ + __pmID_int *idp = (__pmID_int *)&(mdesc->m_desc.pmid); + +#ifndef HAVE_SPROC + /* Check is refresh thread is still with us */ + int err; + + if ( (err = pthread_kill (sproc_pid, 0)) != 0 ) { + exit (1); + } +#endif + + if (!intf[inst].fetched) + return PM_ERR_AGAIN; + + switch (idp->item) { + + case 1: /* bytes_in */ + if (intf[inst].bytes_in == -1) return 0; + avp->ull = intf[inst].bytes_in; + break; + + case 2: /* bytes_out */ + if (intf[inst].bytes_out == -1) return 0; + avp->ull = intf[inst].bytes_out; + break; + + case 3: /* rate_in */ + if (intf[inst].rate_in == -1) return 0; + avp->ul = intf[inst].rate_in; + break; + + case 4: /* rate_out */ + if (intf[inst].rate_out == -1) return 0; + avp->ul = intf[inst].rate_out; + break; + + case 5: /* bandwidth */ + if (intf[inst].bandwidth == -1) return 0; + avp->ul = intf[inst].bandwidth; + break; + + case 6: /* bytes_out_bcast */ + if (intf[inst].bytes_out_bcast == -1) return 0; + avp->ull = intf[inst].bytes_out_bcast; + break; + + default: + return PM_ERR_PMID; + } + + return 1; +} + +void +cisco_init(pmdaInterface *dp) +{ + int i; + + pmdaSetFetchCallBack(dp, cisco_fetchCallBack); + + pmdaInit(dp, indomtab, sizeof(indomtab)/sizeof(indomtab[0]), metrictab, + sizeof(metrictab)/sizeof(metrictab[0])); + + for (i = 0; i < n_intf; i++) + intf[i].fetched = 0; + + /* start the sproc for async fetches */ +#ifdef HAVE_SPROC + i = sproc_pid = sproc(refresh, PR_SADDR); +#elif defined (HAVE_PTHREAD_H) + i = pthread_create(&sproc_pid, NULL, (void (*))refresh, NULL); +#else +#error "Need sproc or pthread here!" +#endif + + if (i < 0) + dp->status = i; + else + dp->status = 0; +} + +void +cisco_done(void) +{ + int i; + + if (sproc_pid > 0) { +#ifndef HAVE_SPROC + pthread_kill(sproc_pid, SIGHUP); +#else + kill(sproc_pid, SIGHUP); +#endif + while (wait(&i) >= 0) + ; + } +} + |