summaryrefslogtreecommitdiff
path: root/agent/mibgroup/hardware/cpu/cpu_pcp.c
diff options
context:
space:
mode:
Diffstat (limited to 'agent/mibgroup/hardware/cpu/cpu_pcp.c')
-rw-r--r--agent/mibgroup/hardware/cpu/cpu_pcp.c191
1 files changed, 191 insertions, 0 deletions
diff --git a/agent/mibgroup/hardware/cpu/cpu_pcp.c b/agent/mibgroup/hardware/cpu/cpu_pcp.c
new file mode 100644
index 0000000..94c7b5c
--- /dev/null
+++ b/agent/mibgroup/hardware/cpu/cpu_pcp.c
@@ -0,0 +1,191 @@
+/*
+ * pcp interface
+ * e.g. IRIX
+ */
+#include <net-snmp/net-snmp-config.h>
+#include <net-snmp/net-snmp-includes.h>
+#include <net-snmp/agent/net-snmp-agent-includes.h>
+#include <net-snmp/agent/hardware/cpu.h>
+
+#include <unistd.h>
+#include <pcp/pmapi.h>
+
+/*
+ * Performance Metrics Name Space Map
+ * Built by pmgenmap from the file irix_kernstats.pcp
+ */
+char *kernstats[] = {
+#define NCPU 0
+ "hinv.ncpu",
+#define CPUTYPE 1
+ "hinv.cputype",
+#define CPUIDLE 2
+ "kernel.all.cpu.idle",
+#define CPUINTR 3
+ "kernel.all.cpu.intr",
+#define CPUSYS 4
+ "kernel.all.cpu.sys",
+#define CPUUSER 5
+ "kernel.all.cpu.user",
+#define CPUWAIT 6
+ "kernel.all.cpu.wait.total",
+#define PAGESIN 7
+ "swap.pagesin",
+#define PAGESOUT 8
+ "swap.pagesout",
+#define SWAPIN 9
+ "swap.in",
+#define SWAPOUT 10
+ "swap.out",
+#define INTR 11
+ "kernel.all.intr.non_vme",
+#define CTXT 12
+ "kernel.all.kswitch"
+};
+
+# define MAX_MID 17
+
+pmResult *resp;
+pmID pmidlist[MAX_MID];
+int numpmid;
+int pmInitDone = 0;
+
+/* initialize pcp if necessary */
+void init_pcp () {
+ int err;
+
+ if (pmInitDone == 1) {
+ return;
+ }
+
+ snmp_log_perror("Initializing pcp");
+ numpmid = sizeof(kernstats)/sizeof(kernstats[0]);
+
+ /* Load default namespace */
+ if ((err=pmLoadNameSpace(PM_NS_DEFAULT)) < 0) {
+ snmp_log_perror("pmLoadNameSpace returned an error.");
+ snmp_log_perror(pmErrStr(err));
+ exit (1);
+ }
+
+ /* get mappings between internal IDs and external IDs */
+ if ((err=pmLookupName(numpmid, kernstats, pmidlist)) < 0) {
+ snmp_log_perror("pmLookupName returned an error.");
+ snmp_log_perror(pmErrStr(err));
+ exit (1);
+ }
+
+ /* specify a context to use */
+ /* a type of PM_CONTEXT_HOST lets you specify a hostname */
+ /* a type of PM_CONTEXT_LOCAL should ignore the string param */
+ if ((err=pmNewContext(PM_CONTEXT_LOCAL,"localhost")) < 0) {
+ snmp_log_perror("pmNewContext returned error opening a LOCAL Context");
+ snmp_log_perror(pmErrStr(err));
+
+ if ((err=pmNewContext(PM_CONTEXT_HOST,"localhost")) < 0) {
+ snmp_log_perror("pmNewContext returned error opening a HOST Context");
+ snmp_log_perror(pmErrStr(err));
+ exit(1);
+ }
+ }
+ snmp_log_perror ("done initializing pcp");
+ pmInitDone = 1;
+}
+
+ /*
+ * Initialise the list of CPUs on the system
+ * (including descriptions)
+ */
+void init_cpu_pcp( void ) {
+ int i, n = 0;
+ char tstr[1024];
+ int err;
+ netsnmp_cpu_info *cpu;
+
+ init_pcp();
+
+ /* At this stage, pmidlist contains the PMID for my metrics of interest */
+
+ cpu = netsnmp_cpu_get_byIdx( -1, 1 );
+ strcpy(cpu->name, "Overall CPU statistics");
+
+ if ((err=pmFetch(numpmid, pmidlist, &resp)) < 0) {
+ snmp_log_perror ("init_cpu_pcp: pmFetch returned error");
+ snmp_log_perror (pmErrStr(err));
+ exit (1);
+ }
+ cpu_num = resp->vset[NCPU]->vlist[0].value.lval;
+ pmFreeResult(resp);
+
+ for (i=0; i<cpu_num ; i++) {
+ cpu = netsnmp_cpu_get_byIdx( i, 1 );
+ sprintf(tstr, "cpu%d",i);
+ strcpy(cpu->name, tstr);
+ strcpy(cpu->descr, "An electronic chip that makes the computer work");
+ }
+}
+
+/*void _cpu_load_swap_etc( char *buff, netsnmp_cpu_info *cpu );*/
+
+ /*
+ * Load the latest CPU usage statistics
+ */
+int netsnmp_cpu_arch_load( netsnmp_cache *cache, void *magic ) {
+ int err;
+ /*static char *buff = NULL;*/
+ static int first = 1;
+ netsnmp_cpu_info* cpu;
+
+ init_pcp();
+
+ /*
+ * CPU statistics (overall and per-CPU)
+ */
+ if ((err=pmFetch(numpmid, pmidlist, &resp)) < 0) {
+ snmp_log_perror ("netsnmp_cpu_arch_load: pmFetch returned an error.");
+ snmp_log_perror (pmErrStr(err));
+ exit (1);
+ }
+
+ cpu = netsnmp_cpu_get_byIdx( -1, 0 );
+ if (!cpu) {
+ snmp_log_perror ("netsnmp_cpu_arch_load: netsnmp_cpu_get_byIdx failed!");
+ exit(1);
+ }
+
+ cpu->wait_ticks = (unsigned long long)resp->vset[CPUWAIT]->vlist[0].value.lval / 10;
+ cpu->intrpt_ticks = (unsigned long long)resp->vset[CPUINTR]->vlist[0].value.lval / 10;
+ /*cpu->sirq_ticks = (unsigned long)csoftll / 10;*/
+ cpu->user_ticks = (unsigned long long)resp->vset[CPUUSER]->vlist[0].value.lval / 10;
+ /*cpu->nice_ticks = (unsigned long)cicell / 10;*/
+ cpu->sys_ticks = (unsigned long long)resp->vset[CPUSYS]->vlist[0].value.lval / 10;
+ cpu->idle_ticks = (unsigned long long)resp->vset[CPUIDLE]->vlist[0].value.lval / 10;
+
+
+ /*
+ * Interrupt/Context Switch statistics
+ * XXX - Do these really belong here ?
+ */
+ /*cpu = netsnmp_cpu_get_byIdx( -1, 0 );*/
+ /*_cpu_load_swap_etc( buff, cpu );*/
+ cpu->pageIn = (unsigned long long)resp->vset[PAGESIN]->vlist[0].value.lval;
+ cpu->pageOut = (unsigned long long)resp->vset[PAGESOUT]->vlist[0].value.lval;
+ cpu->swapIn = (unsigned long long)resp->vset[SWAPIN]->vlist[0].value.lval;
+ cpu->swapOut = (unsigned long long)resp->vset[SWAPOUT]->vlist[0].value.lval;
+ cpu->nInterrupts = (unsigned long long)resp->vset[INTR]->vlist[0].value.lval;
+ cpu->nCtxSwitches = (unsigned long long)resp->vset[CTXT]->vlist[0].value.lval;
+
+ /*
+ * XXX - TODO: extract per-CPU statistics
+ * (Into separate netsnmp_cpu_info data structures)
+ */
+
+ /* free pcp response */
+ pmFreeResult(resp);
+
+ first = 0;
+ return 0;
+}
+
+
+