summaryrefslogtreecommitdiff
path: root/agent/mibgroup/ucd-snmp/vmstat.c
diff options
context:
space:
mode:
Diffstat (limited to 'agent/mibgroup/ucd-snmp/vmstat.c')
-rw-r--r--agent/mibgroup/ucd-snmp/vmstat.c279
1 files changed, 279 insertions, 0 deletions
diff --git a/agent/mibgroup/ucd-snmp/vmstat.c b/agent/mibgroup/ucd-snmp/vmstat.c
new file mode 100644
index 0000000..d52a5b6
--- /dev/null
+++ b/agent/mibgroup/ucd-snmp/vmstat.c
@@ -0,0 +1,279 @@
+#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/auto_nlist.h>
+
+#include <net-snmp/agent/hardware/cpu.h>
+#include "vmstat.h"
+
+FindVarMethod var_extensible_vmstat;
+
+
+
+void
+init_vmstat(void)
+{
+ const oid vmstat_oid[] = { NETSNMP_UCDAVIS_MIB, 11 };
+
+ DEBUGMSGTL(("vmstat", "Initializing\n"));
+ netsnmp_register_scalar_group(
+ netsnmp_create_handler_registration("vmstat", vmstat_handler,
+ vmstat_oid, OID_LENGTH(vmstat_oid),
+ HANDLER_CAN_RONLY),
+ MIBINDEX, CPURAWGUESTNICE);
+}
+
+
+int
+vmstat_handler(netsnmp_mib_handler *handler,
+ netsnmp_handler_registration *reginfo,
+ netsnmp_agent_request_info *reqinfo,
+ netsnmp_request_info *requests)
+{
+ oid obj;
+ unsigned long long value = 0;
+ char cp[300];
+ netsnmp_cpu_info *info = netsnmp_cpu_get_byIdx( -1, 0 );
+
+ switch (reqinfo->mode) {
+ case MODE_GET:
+ obj = requests->requestvb->name[ requests->requestvb->name_length-2 ];
+
+ switch (obj) {
+ case MIBINDEX: /* dummy value */
+ snmp_set_var_typed_integer(requests->requestvb, ASN_INTEGER, 1);
+ break;
+
+ case ERRORNAME: /* dummy name */
+ sprintf(cp, "systemStats");
+ snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR,
+ cp, strlen(cp));
+ break;
+
+/*
+ case IOSENT:
+ long_ret = vmstat(iosent);
+ return ((u_char *) (&long_ret));
+ case IORECEIVE:
+ long_ret = vmstat(ioreceive);
+ return ((u_char *) (&long_ret));
+ case IORAWSENT:
+ long_ret = vmstat(rawiosent);
+ return ((u_char *) (&long_ret));
+ case IORAWRECEIVE:
+ long_ret = vmstat(rawioreceive);
+ return ((u_char *) (&long_ret));
+*/
+
+ /*
+ * Raw CPU statistics
+ * Taken directly from the (overall) cpu_info structure.
+ *
+ * XXX - Need some form of flag to skip objects that
+ * aren't supported on a given architecture.
+ */
+ case CPURAWUSER:
+ snmp_set_var_typed_integer(requests->requestvb, ASN_COUNTER,
+ info->user_ticks & 0xffffffff);
+ break;
+ case CPURAWNICE:
+ snmp_set_var_typed_integer(requests->requestvb, ASN_COUNTER,
+ info->nice_ticks & 0xffffffff);
+ break;
+ case CPURAWSYSTEM:
+ /*
+ * Some architecture have traditionally reported a
+ * combination of CPU statistics for this object.
+ * The CPU HAL module uses 'sys2_ticks' for this,
+ * so use this value in preference to 'sys_ticks'
+ * if it has a non-zero value.
+ */
+ snmp_set_var_typed_integer(requests->requestvb, ASN_COUNTER,
+ (info->sys2_ticks ?
+ info->sys2_ticks :
+ info->sys_ticks ) & 0xffffffff);
+ break;
+ case CPURAWIDLE:
+ snmp_set_var_typed_integer(requests->requestvb, ASN_COUNTER,
+ info->idle_ticks & 0xffffffff);
+ break;
+ case CPURAWWAIT:
+ snmp_set_var_typed_integer(requests->requestvb, ASN_COUNTER,
+ info->wait_ticks & 0xffffffff);
+ break;
+ case CPURAWKERNEL:
+ snmp_set_var_typed_integer(requests->requestvb, ASN_COUNTER,
+ info->kern_ticks & 0xffffffff);
+ break;
+ case CPURAWINTR:
+ snmp_set_var_typed_integer(requests->requestvb, ASN_COUNTER,
+ info->intrpt_ticks & 0xffffffff);
+ break;
+ case CPURAWSOFTIRQ:
+ snmp_set_var_typed_integer(requests->requestvb, ASN_COUNTER,
+ info->sirq_ticks & 0xffffffff);
+ break;
+ case CPURAWSTEAL:
+ snmp_set_var_typed_integer(requests->requestvb, ASN_COUNTER,
+ info->steal_ticks & 0xffffffff);
+ break;
+ case CPURAWGUEST:
+ snmp_set_var_typed_integer(requests->requestvb, ASN_COUNTER,
+ info->guest_ticks & 0xffffffff);
+ break;
+ case CPURAWGUESTNICE:
+ snmp_set_var_typed_integer(requests->requestvb, ASN_COUNTER,
+ info->guestnice_ticks & 0xffffffff);
+ break;
+
+ /*
+ * 'Cooked' CPU statistics
+ * Percentage usage of the specified statistic calculated
+ * over the period (1 min) that history is being kept for.
+ *
+ * This is actually a change of behaviour for some architectures,
+ * but:
+ * a) It ensures consistency across all systems
+ * a) It matches the definition of the MIB objects
+ *
+ * Note that this value will only be reported once the agent
+ * has a full minute's history collected.
+ */
+ case CPUUSER:
+ if ( info->history && info->history[0].total_hist ) {
+ value = (info->user_ticks - info->history[0].user_hist)*100;
+ if ( info->total_ticks - info->history[0].total_hist)
+ value /= (info->total_ticks - info->history[0].total_hist);
+ else
+ value = 0; /* or skip this entry */
+ snmp_set_var_typed_integer(requests->requestvb,
+ ASN_INTEGER, value & 0x7fffffff);
+ }
+ break;
+ case CPUSYSTEM:
+ if ( info->history && info->history[0].total_hist ) {
+ /* or sys2_ticks ??? */
+ value = (info->sys_ticks - info->history[0].sys_hist)*100;
+ if ( info->total_ticks - info->history[0].total_hist)
+ value /= (info->total_ticks - info->history[0].total_hist);
+ else
+ value = 0; /* or skip this entry */
+ snmp_set_var_typed_integer(requests->requestvb,
+ ASN_INTEGER, value & 0x7fffffff);
+ }
+ break;
+ case CPUIDLE:
+ if ( info->history && info->history[0].total_hist ) {
+ value = (info->idle_ticks - info->history[0].idle_hist)*100;
+ if ( info->total_ticks - info->history[0].total_hist)
+ value /= (info->total_ticks - info->history[0].total_hist);
+ else
+ value = 0; /* or skip this entry */
+ snmp_set_var_typed_integer(requests->requestvb,
+ ASN_INTEGER, value & 0x7fffffff);
+ }
+ break;
+
+ /*
+ * Similarly for the Interrupt and Context switch statistics
+ * (raw and per-second, calculated over the last minute)
+ */
+ case SYSRAWINTERRUPTS:
+ snmp_set_var_typed_integer(requests->requestvb, ASN_COUNTER,
+ info->nInterrupts & 0xffffffff);
+ break;
+ case SYSRAWCONTEXT:
+ snmp_set_var_typed_integer(requests->requestvb, ASN_COUNTER,
+ info->nCtxSwitches & 0xffffffff);
+ break;
+ case SYSINTERRUPTS:
+ if ( info->history && info->history[0].total_hist ) {
+ value = (info->nInterrupts - info->history[0].intr_hist)/60;
+ snmp_set_var_typed_integer(requests->requestvb,
+ ASN_INTEGER, value & 0x7fffffff);
+ }
+ break;
+ case SYSCONTEXT:
+ if ( info->history && info->history[0].total_hist ) {
+ value = (info->nCtxSwitches - info->history[0].ctx_hist)/60;
+ snmp_set_var_typed_integer(requests->requestvb,
+ ASN_INTEGER, value & 0x7fffffff);
+ }
+ break;
+
+ /*
+ * Similarly for the Swap statistics...
+ */
+ case RAWSWAPIN:
+ snmp_set_var_typed_integer(requests->requestvb, ASN_COUNTER,
+ info->swapIn & 0xffffffff);
+ break;
+ case RAWSWAPOUT:
+ snmp_set_var_typed_integer(requests->requestvb, ASN_COUNTER,
+ info->swapOut & 0xffffffff);
+ break;
+ case SWAPIN:
+ if ( info->history && info->history[0].total_hist ) {
+ value = (info->swapIn - info->history[0].swpi_hist)/60;
+ /* ??? value *= PAGE_SIZE; */
+ snmp_set_var_typed_integer(requests->requestvb,
+ ASN_INTEGER, value & 0x7fffffff);
+ }
+ break;
+ case SWAPOUT:
+ if ( info->history && info->history[0].total_hist ) {
+ value = (info->swapOut - info->history[0].swpo_hist)/60;
+ /* ??? value *= PAGE_SIZE; */
+ snmp_set_var_typed_integer(requests->requestvb,
+ ASN_INTEGER, value & 0x7fffffff);
+ }
+ break;
+
+ /*
+ * ... and the I/O statistics.
+ */
+ case IORAWSENT:
+ snmp_set_var_typed_integer(requests->requestvb, ASN_COUNTER,
+ info->pageOut & 0xffffffff);
+ break;
+ case IORAWRECEIVE:
+ snmp_set_var_typed_integer(requests->requestvb, ASN_COUNTER,
+ info->pageIn & 0xffffffff);
+ break;
+ case IOSENT:
+ if ( info->history && info->history[0].total_hist ) {
+ value = (info->pageOut - info->history[0].pageo_hist)/60;
+ snmp_set_var_typed_integer(requests->requestvb,
+ ASN_INTEGER, value & 0x7fffffff);
+ }
+ break;
+ case IORECEIVE:
+ if ( info->history && info->history[0].total_hist ) {
+ value = (info->pageIn - info->history[0].pagei_hist)/60;
+ snmp_set_var_typed_integer(requests->requestvb,
+ ASN_INTEGER, value & 0x7fffffff);
+ }
+ break;
+
+ default:
+/*
+ XXX - The systemStats group is "holely", so walking it would
+ trigger this message repeatedly. We really need a form
+ of the table column registration mechanism, that would
+ work with scalar groups.
+ snmp_log(LOG_ERR,
+ "unknown object (%d) in vmstat_handler\n", (int)obj);
+ */
+ break;
+ }
+ break;
+
+ default:
+ snmp_log(LOG_ERR,
+ "unknown mode (%d) in vmstat_handler\n",
+ reqinfo->mode);
+ return SNMP_ERR_GENERR;
+ }
+
+ return SNMP_ERR_NOERROR;
+}