summaryrefslogtreecommitdiff
path: root/agent/mibgroup/ucd-snmp/vmstat_freebsd2.c
diff options
context:
space:
mode:
Diffstat (limited to 'agent/mibgroup/ucd-snmp/vmstat_freebsd2.c')
-rw-r--r--agent/mibgroup/ucd-snmp/vmstat_freebsd2.c400
1 files changed, 400 insertions, 0 deletions
diff --git a/agent/mibgroup/ucd-snmp/vmstat_freebsd2.c b/agent/mibgroup/ucd-snmp/vmstat_freebsd2.c
new file mode 100644
index 0000000..3de89b2
--- /dev/null
+++ b/agent/mibgroup/ucd-snmp/vmstat_freebsd2.c
@@ -0,0 +1,400 @@
+/*
+ * vmstat_freebsd2.c
+ */
+
+#include <net-snmp/net-snmp-config.h>
+
+/*
+ * Ripped from /usr/scr/usr.bin/vmstat/vmstat.c (covering all bases)
+ */
+#include <sys/param.h>
+#include <sys/time.h>
+#if defined(dragonfly)
+#include <sys/user.h>
+#else
+#include <sys/proc.h>
+#endif
+#if defined(freebsd5) && __FreeBSD_version >= 500101
+#include <sys/resource.h>
+#elif defined(dragonfly)
+#include <kinfo.h>
+#else
+#include <sys/dkstat.h>
+#endif
+#ifdef freebsd5
+#include <sys/bio.h>
+#endif
+#include <sys/buf.h>
+#include <sys/uio.h>
+#include <sys/namei.h>
+#include <sys/malloc.h>
+#include <sys/signal.h>
+#include <sys/fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/sysctl.h>
+#include <sys/vmmeter.h>
+
+#if HAVE_SYS_VMPARAM_H
+#include <sys/vmparam.h>
+#else
+#include <vm/vm_param.h>
+#endif
+
+#include <time.h>
+#include <nlist.h>
+#include <kvm.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <paths.h>
+#include <limits.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 "util_funcs/header_generic.h"
+#include "vmstat.h"
+#include "vmstat_freebsd2.h"
+
+
+/*
+ * nlist symbols
+ */
+#define CPTIME_SYMBOL "cp_time"
+#define SUM_SYMBOL "cnt"
+#define INTRCNT_SYMBOL "intrcnt"
+#define EINTRCNT_SYMBOL "eintrcnt"
+#define BOOTTIME_SYMBOL "boottime"
+
+/*
+ * Number of interrupts
+ */
+#define INT_COUNT 10
+
+/*
+ * CPU percentage
+ */
+#define CPU_PRC 100
+
+FindVarMethod var_extensible_vmstat;
+
+void
+init_vmstat_freebsd2(void)
+{
+
+ struct variable2 extensible_vmstat_variables[] = {
+ {MIBINDEX, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
+ var_extensible_vmstat, 1, {MIBINDEX}},
+ {ERRORNAME, ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY,
+ var_extensible_vmstat, 1, {ERRORNAME}},
+ {SWAPIN, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
+ var_extensible_vmstat, 1, {SWAPIN}},
+ {SWAPOUT, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
+ var_extensible_vmstat, 1, {SWAPOUT}},
+ {IOSENT, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
+ var_extensible_vmstat, 1, {IOSENT}},
+ {IORECEIVE, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
+ var_extensible_vmstat, 1, {IORECEIVE}},
+ {SYSINTERRUPTS, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
+ var_extensible_vmstat, 1, {SYSINTERRUPTS}},
+ {SYSCONTEXT, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
+ var_extensible_vmstat, 1, {SYSCONTEXT}},
+ {CPUUSER, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
+ var_extensible_vmstat, 1, {CPUUSER}},
+ {CPUSYSTEM, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
+ var_extensible_vmstat, 1, {CPUSYSTEM}},
+ {CPUIDLE, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
+ var_extensible_vmstat, 1, {CPUIDLE}},
+ {CPURAWUSER, ASN_COUNTER, NETSNMP_OLDAPI_RONLY,
+ var_extensible_vmstat, 1, {CPURAWUSER}},
+ {CPURAWNICE, ASN_COUNTER, NETSNMP_OLDAPI_RONLY,
+ var_extensible_vmstat, 1, {CPURAWNICE}},
+ {CPURAWSYSTEM, ASN_COUNTER, NETSNMP_OLDAPI_RONLY,
+ var_extensible_vmstat, 1, {CPURAWSYSTEM}},
+ {CPURAWIDLE, ASN_COUNTER, NETSNMP_OLDAPI_RONLY,
+ var_extensible_vmstat, 1, {CPURAWIDLE}},
+ {CPURAWKERNEL, ASN_COUNTER, NETSNMP_OLDAPI_RONLY,
+ var_extensible_vmstat, 1, {CPURAWKERNEL}},
+ {CPURAWINTR, ASN_COUNTER, NETSNMP_OLDAPI_RONLY,
+ var_extensible_vmstat, 1, {CPURAWINTR}},
+ {SYSRAWINTERRUPTS, ASN_COUNTER, NETSNMP_OLDAPI_RONLY,
+ var_extensible_vmstat, 1, {SYSRAWINTERRUPTS}},
+ {SYSRAWCONTEXT, ASN_COUNTER, NETSNMP_OLDAPI_RONLY,
+ var_extensible_vmstat, 1, {SYSRAWCONTEXT}},
+ /*
+ * Future use:
+ */
+ /*
+ * {ERRORFLAG, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
+ * var_extensible_vmstat, 1, {ERRORFLAG }},
+ * {ERRORMSG, ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY,
+ * var_extensible_vmstat, 1, {ERRORMSG }}
+ */
+ };
+
+ /*
+ * Define the OID pointer to the top of the mib tree that we're
+ * registering underneath
+ */
+ oid vmstat_variables_oid[] = { NETSNMP_UCDAVIS_MIB, 11 };
+
+ /*
+ * register ourselves with the agent to handle our mib tree
+ */
+ REGISTER_MIB("ucd-snmp/vmstat", extensible_vmstat_variables, variable2,
+ vmstat_variables_oid);
+
+}
+
+
+long
+getuptime(void)
+{
+ static time_t now, boottime;
+ time_t uptime;
+
+ if (boottime == 0)
+ auto_nlist(BOOTTIME_SYMBOL, (char *) &boottime, sizeof(boottime));
+
+ time(&now);
+ uptime = now - boottime;
+
+ return (uptime);
+}
+
+unsigned char *
+var_extensible_vmstat(struct variable *vp,
+ oid * name,
+ size_t * length,
+ int exact,
+ size_t * var_len, WriteMethod ** write_method)
+{
+
+ int loop;
+
+ time_t time_new = getuptime();
+ static time_t time_old;
+ static time_t time_diff;
+
+#if defined(dragonfly)
+ static struct kinfo_cputime cpu_old, cpu_new, cpu_diff;
+ static uint64_t cpu_total;
+ uint64_t cpu_sum;
+ static int pagesize;
+#else
+ static long cpu_old[CPUSTATES];
+ static long cpu_new[CPUSTATES];
+ static long cpu_diff[CPUSTATES];
+ static long cpu_total;
+ long cpu_sum;
+#endif
+ double cpu_prc;
+
+ static struct vmmeter mem_old, mem_new;
+
+ static long long_ret;
+ static char errmsg[300];
+
+#if defined(dragonfly)
+ if (pagesize == 0)
+ pagesize = getpagesize() >> 10;
+#endif
+
+ long_ret = 0; /* set to 0 as default */
+
+ if (header_generic(vp, name, length, exact, var_len, write_method))
+ return (NULL);
+
+ /*
+ * Update structures (only if time has passed)
+ */
+ if (time_new != time_old) {
+ time_diff = time_new - time_old;
+ time_old = time_new;
+
+ /*
+ * CPU usage
+ */
+
+ cpu_total = 0;
+
+#if defined(dragonfly)
+ kinfo_get_sched_cputime(&cpu_new);
+#define CP_UPDATE(field) cpu_diff.field = cpu_new.field - cpu_old.field; cpu_total += cpu_diff.field;
+ CP_UPDATE(cp_user);
+ CP_UPDATE(cp_nice);
+ CP_UPDATE(cp_sys);
+ CP_UPDATE(cp_intr);
+ CP_UPDATE(cp_idle);
+ cpu_old = cpu_new;
+#undef CP_UPDATE
+#else
+ auto_nlist(CPTIME_SYMBOL, (char *) cpu_new, sizeof(cpu_new));
+
+ for (loop = 0; loop < CPUSTATES; loop++) {
+ cpu_diff[loop] = cpu_new[loop] - cpu_old[loop];
+ cpu_old[loop] = cpu_new[loop];
+ cpu_total += cpu_diff[loop];
+ }
+#endif
+
+ if (cpu_total == 0)
+ cpu_total = 1;
+
+ /*
+ * Memory info
+ */
+ mem_old = mem_new;
+ auto_nlist(SUM_SYMBOL, (char *) &mem_new, sizeof(mem_new));
+ }
+
+ /*
+ * Rate macro
+ */
+#define rate(x) (((x)+ time_diff/2) / time_diff)
+
+ /*
+ * Page-to-kb macro
+ */
+#if defined(dragonfly)
+#define ptok(p) ((p) * pagesize)
+#else
+#define ptok(p) ((p) * (mem_new.v_page_size >> 10))
+#endif
+
+ switch (vp->magic) {
+ case MIBINDEX:
+ long_ret = 1;
+ return ((u_char *) (&long_ret));
+ case ERRORNAME: /* dummy name */
+ sprintf(errmsg, "systemStats");
+ *var_len = strlen(errmsg);
+ return ((u_char *) (errmsg));
+ case SWAPIN:
+#if defined(openbsd2) || defined(darwin)
+ long_ret = ptok(mem_new.v_swpin - mem_old.v_swpin);
+#else
+ long_ret = ptok(mem_new.v_swappgsin - mem_old.v_swappgsin +
+ mem_new.v_vnodepgsin - mem_old.v_vnodepgsin);
+#endif
+ long_ret = rate(long_ret);
+ return ((u_char *) (&long_ret));
+ case SWAPOUT:
+#if defined(openbsd2) || defined(darwin)
+ long_ret = ptok(mem_new.v_swpout - mem_old.v_swpout);
+#else
+ long_ret = ptok(mem_new.v_swappgsout - mem_old.v_swappgsout +
+ mem_new.v_vnodepgsout - mem_old.v_vnodepgsout);
+#endif
+ long_ret = rate(long_ret);
+ return ((u_char *) (&long_ret));
+ case IOSENT:
+#if NETSNMP_NO_DUMMY_VALUES
+ return NULL;
+#endif
+ long_ret = -1;
+ return ((u_char *) (&long_ret));
+ case IORECEIVE:
+#if NETSNMP_NO_DUMMY_VALUES
+ return NULL;
+#endif
+ long_ret = -1;
+ return ((u_char *) (&long_ret));
+ case SYSINTERRUPTS:
+ long_ret = rate(mem_new.v_intr - mem_old.v_intr);
+ return ((u_char *) (&long_ret));
+ case SYSCONTEXT:
+ long_ret = rate(mem_new.v_swtch - mem_old.v_swtch);
+ return ((u_char *) (&long_ret));
+ case CPUUSER:
+#if defined(dragonfly)
+ cpu_sum = cpu_diff.cp_user + cpu_diff.cp_nice;
+#else
+ cpu_sum = cpu_diff[CP_USER] + cpu_diff[CP_NICE];
+#endif
+ cpu_prc = (float) cpu_sum / (float) cpu_total;
+ long_ret = cpu_prc * CPU_PRC;
+ return ((u_char *) (&long_ret));
+ case CPUSYSTEM:
+#if defined(dragonfly)
+ cpu_sum = cpu_diff.cp_sys + cpu_diff.cp_intr;
+#else
+ cpu_sum = cpu_diff[CP_SYS] + cpu_diff[CP_INTR];
+#endif
+ cpu_prc = (float) cpu_sum / (float) cpu_total;
+ long_ret = cpu_prc * CPU_PRC;
+ return ((u_char *) (&long_ret));
+ case CPUIDLE:
+#if defined(dragonfly)
+ cpu_sum = cpu_diff.cp_idle;
+#else
+ cpu_sum = cpu_diff[CP_IDLE];
+#endif
+ cpu_prc = (float) cpu_sum / (float) cpu_total;
+ long_ret = cpu_prc * CPU_PRC;
+ return ((u_char *) (&long_ret));
+ case CPURAWUSER:
+#if defined(dragonfly)
+ long_ret = cpu_new.cp_user;
+#else
+ long_ret = cpu_new[CP_USER];
+#endif
+ return ((u_char *) (&long_ret));
+ case CPURAWNICE:
+#if defined(dragonfly)
+ long_ret = cpu_new.cp_nice;
+#else
+ long_ret = cpu_new[CP_NICE];
+#endif
+ return ((u_char *) (&long_ret));
+ case CPURAWSYSTEM:
+#if defined(dragonfly)
+ long_ret = cpu_new.cp_sys + cpu_new.cp_nice;
+#else
+ long_ret = cpu_new[CP_SYS] + cpu_new[CP_INTR];
+#endif
+ return ((u_char *) (&long_ret));
+ case CPURAWIDLE:
+#if defined(dragonfly)
+ long_ret = cpu_new.cp_idle;
+#else
+ long_ret = cpu_new[CP_IDLE];
+#endif
+ return ((u_char *) (&long_ret));
+ case CPURAWKERNEL:
+#if defined(dragonfly)
+ long_ret = cpu_new.cp_sys;
+#else
+ long_ret = cpu_new[CP_SYS];
+#endif
+ return ((u_char *) (&long_ret));
+ case CPURAWINTR:
+#if defined(dragonfly)
+ long_ret = cpu_new.cp_intr;
+#else
+ long_ret = cpu_new[CP_INTR];
+#endif
+ return ((u_char *) (&long_ret));
+ case SYSRAWINTERRUPTS:
+ long_ret = mem_new.v_intr;
+ return ((u_char *) (&long_ret));
+ case SYSRAWCONTEXT:
+ long_ret = mem_new.v_swtch;
+ return ((u_char *) (&long_ret));
+ /*
+ * reserved for future use
+ */
+ /*
+ * case ERRORFLAG:
+ * return((u_char *) (&long_ret));
+ * case ERRORMSG:
+ * return((u_char *) (&long_ret));
+ */
+ }
+ return NULL;
+}