diff options
Diffstat (limited to 'agent/mibgroup/ucd-snmp/vmstat.c')
-rw-r--r-- | agent/mibgroup/ucd-snmp/vmstat.c | 257 |
1 files changed, 257 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..f51efea --- /dev/null +++ b/agent/mibgroup/ucd-snmp/vmstat.c @@ -0,0 +1,257 @@ +#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) +{ + static 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, RAWSWAPOUT); +} + + +int +vmstat_handler(netsnmp_mib_handler *handler, + netsnmp_handler_registration *reginfo, + netsnmp_agent_request_info *reqinfo, + netsnmp_request_info *requests) +{ + oid obj; + 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; + + /* + * '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; + value /= (info->total_ticks - info->history[0].total_hist); + snmp_set_var_typed_integer(requests->requestvb, + ASN_INTEGER, value); + } + break; + case CPUSYSTEM: + if ( info->history && info->history[0].total_hist ) { + /* or sys2_ticks ??? */ + value = (info->sys_ticks - info->history[0].sys_hist)*100; + value /= (info->total_ticks - info->history[0].total_hist); + snmp_set_var_typed_integer(requests->requestvb, + ASN_INTEGER, value); + } + break; + case CPUIDLE: + if ( info->history && info->history[0].total_hist ) { + value = (info->idle_ticks - info->history[0].idle_hist)*100; + value /= (info->total_ticks - info->history[0].total_hist); + snmp_set_var_typed_integer(requests->requestvb, + ASN_INTEGER, value); + } + 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); + } + 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); + } + 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); + } + 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); + } + 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); + } + 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); + } + 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; +} |