On Sat, Jun 16, 2012 at 4:32 PM, Seth Wright <[email protected]> wrote:
> Matthew's UCD-DISKIO-MIB patch got me interested in adding support for
> the UCD-SNMP-MIB in snmpd. This is a first pass and only covers the
> mem* objects. I'd appreciate it if someone who knows more than me
> about the uvm sysctls could check it over; specifically, the
> memShared, memBuffers, and memCached objects. Net-SNMP doesn't define
> those objects for NetBSD, but I wanted to take a stab and implementing
> them if possible, so I did some research (and yes, a little guesswork)
> and came up with something that seems to work. (Actually, the
> memShared code came from the net-snmp code for FreeBSD.)
>
> I've got this running on a Zenoss-monitored server right now and the
> stats look right, but I'd appreciate it if other SNMP users could test
> it out, too.
>
> $ snmpwalk -v2c -c[...] it-mirror1 .1.3.6.1.4.1.2021.4
> UCD-SNMP-MIB::memIndex.0 = INTEGER: 0
> UCD-SNMP-MIB::memErrorName.0 = STRING: swap
> UCD-SNMP-MIB::memTotalSwap.0 = INTEGER: 6851384
> UCD-SNMP-MIB::memAvailSwap.0 = INTEGER: 6851384
> UCD-SNMP-MIB::memTotalReal.0 = INTEGER: 20965696
> UCD-SNMP-MIB::memAvailReal.0 = INTEGER: 16962728
> UCD-SNMP-MIB::memTotalFree.0 = INTEGER: 23814112
> UCD-SNMP-MIB::memMinimumSwap.0 = INTEGER: 16000
> UCD-SNMP-MIB::memShared.0 = INTEGER: 0
> UCD-SNMP-MIB::memBuffer.0 = INTEGER: 0
> UCD-SNMP-MIB::memCached.0 = INTEGER: 2593976
> UCD-SNMP-MIB::memSwapError.0 = INTEGER: 0
> UCD-SNMP-MIB::memSwapErrorMsg.0 = STRING:
>
>
> ok?
So, here's an updated diff. I was a bit shortsighted when it came to
naming some things the first go-round, so I fixed that. I also
implemented the laLoad table--minus laLoadFloat--for what that's
worth:
$ walk it-mirror1 .1.3.6.1.4.1.2021.10
UCD-SNMP-MIB::laIndex.1 = INTEGER: 1
UCD-SNMP-MIB::laIndex.2 = INTEGER: 2
UCD-SNMP-MIB::laIndex.3 = INTEGER: 3
UCD-SNMP-MIB::laNames.1 = STRING: Load-1
UCD-SNMP-MIB::laNames.2 = STRING: Load-5
UCD-SNMP-MIB::laNames.3 = STRING: Load-15
UCD-SNMP-MIB::laLoad.1 = STRING: 0.68
UCD-SNMP-MIB::laLoad.2 = STRING: 0.59
UCD-SNMP-MIB::laLoad.3 = STRING: 0.51
UCD-SNMP-MIB::laConfig.1 = STRING: 12.00
UCD-SNMP-MIB::laConfig.2 = STRING: 12.00
UCD-SNMP-MIB::laConfig.3 = STRING: 12.00
UCD-SNMP-MIB::laLoadInt.1 = INTEGER: 67
UCD-SNMP-MIB::laLoadInt.2 = INTEGER: 58
UCD-SNMP-MIB::laLoadInt.3 = INTEGER: 50
UCD-SNMP-MIB::laErrorFlag.1 = INTEGER: 0
UCD-SNMP-MIB::laErrorFlag.2 = INTEGER: 0
UCD-SNMP-MIB::laErrorFlag.3 = INTEGER: 0
UCD-SNMP-MIB::laErrMessage.1 = STRING:
UCD-SNMP-MIB::laErrMessage.2 = STRING:
UCD-SNMP-MIB::laErrMessage.3 = STRING:
Thanks for looking / testing / feedback.
Index: mib.c
===================================================================
RCS file: /cvs/src/usr.sbin/snmpd/mib.c,v
retrieving revision 1.54
diff -u -p -r1.54 mib.c
--- mib.c 14 Jun 2012 17:31:32 -0000 1.54
+++ mib.c 17 Jun 2012 03:11:12 -0000
@@ -3364,6 +3364,212 @@ mib_ipfroute(struct oid *oid, struct ber
}
/*
+ * Defined in UCD-SNMP-MIB.txt
+ */
+
+int mib_ucdmemory(struct oid *oid, struct ber_oid *o, struct
ber_element **elm);
+int mib_ucdloadavg(struct oid *oid, struct ber_oid *o, struct
ber_element **elm);
+
+static struct oid ucdsnmp_mib[] = {
+ { MIB(ucdSNMPMIB), OID_MIB },
+ { MIB(memIndex), OID_RD, mib_ucdmemory },
+ { MIB(memErrorName), OID_RD, mib_ucdmemory },
+ { MIB(memTotalSwap), OID_RD, mib_ucdmemory },
+ { MIB(memAvailSwap), OID_RD, mib_ucdmemory },
+ { MIB(memTotalReal), OID_RD, mib_ucdmemory },
+ { MIB(memAvailReal), OID_RD, mib_ucdmemory },
+ { MIB(memTotalFree), OID_RD, mib_ucdmemory },
+ { MIB(memMinimumSwap), OID_RD, mib_ucdmemory },
+ { MIB(memShared), OID_RD, mib_ucdmemory },
+ { MIB(memBuffer), OID_RD, mib_ucdmemory },
+ { MIB(memCached), OID_RD, mib_ucdmemory },
+ { MIB(memSwapError), OID_RD, mib_ucdmemory },
+ { MIB(memSwapErrorMsg), OID_RD, mib_ucdmemory },
+ { MIB(laIndex), OID_TRD, mib_ucdloadavg },
+ { MIB(laNames), OID_TRD, mib_ucdloadavg },
+ { MIB(laLoad), OID_TRD, mib_ucdloadavg },
+ { MIB(laConfig), OID_TRD, mib_ucdloadavg },
+ { MIB(laLoadInt), OID_TRD, mib_ucdloadavg },
+ { MIB(laErrorFlag), OID_TRD, mib_ucdloadavg },
+ { MIB(laErrMessage), OID_TRD, mib_ucdloadavg },
+ { MIBEND }
+};
+
+/* Taken from net-snmp */
+#define DEFAULTMINIMUMSWAP 16000
+
+int
+mib_ucdmemory(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
+{
+ struct ber_element *ber = *elm;
+ struct bcachestats bcstats;
+ struct uvmexp uvm;
+ struct vmtotal vmmeter;
+ u_int64_t physmem;
+ size_t len;
+ int mib[] = { CTL_VM, VM_UVMEXP };
+ int bcstats_mib[] = { CTL_VFS, VFS_GENERIC,
VFS_BCACHESTAT };
+ int size, inuse, total;
+
+ len = sizeof(uvm);
+ if (sysctl(mib, sizeofa(mib), &uvm, &len, NULL, 0) == -1)
+ return (-1);
+
+ mib[1] = VM_METER;
+ len = sizeof(vmmeter);
+ if (sysctl(mib, sizeofa(mib), &vmmeter, &len, NULL, 0) == -1)
+ return (-1);
+
+ mib[0] = CTL_HW;
+ mib[1] = HW_PHYSMEM64;
+ len = sizeof(physmem);
+ if (sysctl(mib, sizeofa(mib), &physmem, &len, NULL, 0) == -1)
+ return (-1);
+
+ len = sizeof(bcstats);
+ if (sysctl(bcstats_mib, sizeofa(bcstats_mib), &bcstats, &len, NULL, 0)
==
-1)
+ return (-1);
+
+#define ptok(p) ((p) * (uvm.pagesize >> 10))
+
+ switch (o->bo_id[OIDIDX_ucdSNMPMIB]) {
+ case 1: /* memIndex */
+ ber = ber_add_integer(ber, 0);
+ break;
+ case 2: /* memErrorName */
+ ber = ber_add_string(ber, "swap");
+ break;
+ case 3: /* memTotalSwap */
+ size = ptok(uvm.swpages);
+ ber = ber_add_integer(ber, size);
+ break;
+ case 4: /* memAvailSwap */
+ inuse = ptok(uvm.swpginuse);
+ total = ptok(uvm.swpages);
+ ber = ber_add_integer(ber, total - inuse);
+ break;
+ case 5: /* memTotalReal */
+ size = physmem >> 10;
+ ber = ber_add_integer(ber, size);
+ break;
+ case 6: /* memAvailReal */
+ ber = ber_add_integer(ber, ptok(uvm.free));
+ break;
+ case 11: /* memTotalFree */
+ total = ptok(uvm.free + uvm.swpages - uvm.swpginuse);
+ ber = ber_add_integer(ber, total);
+ break;
+ case 12: /* memMinimumSwap */
+ ber = ber_add_integer(ber, DEFAULTMINIMUMSWAP);
+ break;
+ case 13: /* memShared */
+ total = ptok(vmmeter.t_vmshr + vmmeter.t_avmshr +
+ vmmeter.t_rmshr + vmmeter.t_armshr);
+ ber = ber_add_integer(ber, total);
+ break;
+ case 14: /* memBuffer */
+ ber = ber_add_integer(ber, ptok(uvm.vnodepages));
+ break;
+ case 15: /* memCached */
+ ber = ber_add_integer(ber, ptok(bcstats.numbufpages));
+ break;
+ case 100: /* memSwapError */
+ inuse = ptok(uvm.swpginuse);
+ total = ptok(uvm.swpages);
+ if ((total - inuse) < DEFAULTMINIMUMSWAP)
+ ber = ber_add_integer(ber, 1);
+ else
+ ber = ber_add_integer(ber, 0);
+ break;
+ case 101: /* memSwapErrorMsg */
+ inuse = ptok(uvm.swpginuse);
+ total = ptok(uvm.swpages);
+ if ((total - inuse) < DEFAULTMINIMUMSWAP)
+ ber = ber_add_string(ber, "Running out of swap space");
+ else
+ ber = ber_add_string(ber, "");
+ break;
+ default:
+ return (-1);
+ }
+
+ return (0);
+}
+
+/* taken from net-snmp */
+#define DEFMAXLOADAVE 12.0
+
+int
+mib_ucdloadavg(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
+{
+ struct ber_element *ber = *elm;
+ char *str;
+ int samples, ret;
+ u_int32_t idx;
+ double avg[3];
+
+ if ((samples = getloadavg(avg, 3)) == -1)
+ return (-1);
+
+ /* Get and verify the current row index */
+ idx = o->bo_id[OIDIDX_laTableEntry];
+ if (idx > (u_int32_t)samples)
+ return (1);
+
+ /* Tables need to prepend the OID on their own */
+ o->bo_id[OIDIDX_laTableEntry] = idx;
+ ber = ber_add_oid(ber, o);
+
+ switch (o->bo_id[OIDIDX_laTable]) {
+ case 1: /* laIndex */
+ ber = ber_add_integer(ber, idx);
+ break;
+ case 2: /* laNames */
+ if (idx == 1)
+ ret = asprintf(&str, "Load-1");
+ else if (idx == 2)
+ ret = asprintf(&str, "Load-5");
+ else
+ ret = asprintf(&str, "Load-15");
+
+ if (ret == -1)
+ return (-1);
+ ber = ber_add_string(ber, str);
+ break;
+ case 3: /* laLoad */
+ if ((asprintf(&str, "%.2f", avg[idx-1])) == -1)
+ return (-1);
+ ber = ber_add_string(ber, str);
+ break;
+ case 4: /* laConfig */
+ if ((asprintf(&str, "%.2f", DEFMAXLOADAVE)) == -1)
+ return (-1);
+ ber = ber_add_string(ber, str);
+ break;
+ case 5: /* laLoadInt */
+ ber = ber_add_integer(ber, (int)(avg[idx-1] * 100));
+ break;
+ case 100: /* laErrorFlag */
+ if (avg[idx] > DEFMAXLOADAVE)
+ ber = ber_add_integer(ber, 1);
+ else
+ ber = ber_add_integer(ber, 0);
+ break;
+ case 101: /* laErrMessage */
+ if (avg[idx] > DEFMAXLOADAVE)
+ ber = ber_add_string(ber, "Load Average too high");
+ else
+ ber = ber_add_string(ber, "");
+ break;
+ default:
+ return (-1);
+ }
+
+ return (0);
+}
+
+
+/*
* Defined in UCD-DISKIO-MIB.txt.
*/
@@ -3546,6 +3752,9 @@ mib_init(void)
/* BRIDGE-MIB */
smi_mibtree(bridge_mib);
+
+ /* UCD-SNMP-MIB */
+ smi_mibtree(ucdsnmp_mib);
/* UCD-DISKIO-MIB */
smi_mibtree(diskio_mib);
Index: mib.h
===================================================================
RCS file: /cvs/src/usr.sbin/snmpd/mib.h,v
retrieving revision 1.26
diff -u -p -r1.26 mib.h
--- mib.h 14 Jun 2012 17:31:32 -0000 1.26
+++ mib.h 17 Jun 2012 03:11:12 -0000
@@ -397,6 +397,35 @@
#define MIB_vantronix MIB_enterprises, 26766
#define MIB_openBSD MIB_enterprises, 30155
+/* UCD-SNMP-MIB */
+#define MIB_ucdSNMPMIB MIB_ucDavis, 4
+#define OIDIDX_ucdSNMPMIB 8
+#define MIB_memIndex MIB_ucdSNMPMIB, 1
+#define MIB_memErrorName MIB_ucdSNMPMIB, 2
+#define MIB_memTotalSwap MIB_ucdSNMPMIB, 3
+#define MIB_memAvailSwap MIB_ucdSNMPMIB, 4
+#define MIB_memTotalReal MIB_ucdSNMPMIB, 5
+#define MIB_memAvailReal MIB_ucdSNMPMIB, 6
+#define MIB_memTotalFree MIB_ucdSNMPMIB, 11
+#define MIB_memMinimumSwap MIB_ucdSNMPMIB, 12
+#define MIB_memShared MIB_ucdSNMPMIB, 13
+#define MIB_memBuffer MIB_ucdSNMPMIB, 14
+#define MIB_memCached MIB_ucdSNMPMIB, 15
+#define MIB_memSwapError MIB_ucdSNMPMIB, 100
+#define MIB_memSwapErrorMsg MIB_ucdSNMPMIB, 101
+#define MIB_laTable MIB_ucDavis, 10
+#define MIB_laEntry MIB_laTable, 1
+#define OIDIDX_laTable 9
+#define OIDIDX_laTableEntry 10
+#define MIB_laIndex MIB_laEntry, 1
+#define MIB_laNames MIB_laEntry, 2
+#define MIB_laLoad MIB_laEntry, 3
+#define MIB_laConfig MIB_laEntry, 4
+#define MIB_laLoadInt MIB_laEntry, 5
+#define MIB_laErrorFlag MIB_laEntry, 100
+#define MIB_laErrMessage MIB_laEntry, 101
+
+
/* UCD-DISKIO-MIB */
#define MIB_ucdExperimental MIB_ucDavis, 13
#define MIB_ucdDiskIOMIB MIB_ucdExperimental, 15
@@ -908,6 +937,30 @@
{ MIBDECL(microSystems) }, \
{ MIBDECL(vantronix) }, \
{ MIBDECL(openBSD) }, \
+ \
+ { MIBDECL(ucdSNMPMIB) }, \
+ { MIBDECL(memIndex) }, \
+ { MIBDECL(memErrorName) }, \
+ { MIBDECL(memTotalSwap) }, \
+ { MIBDECL(memAvailSwap) }, \
+ { MIBDECL(memTotalReal) }, \
+ { MIBDECL(memAvailReal) }, \
+ { MIBDECL(memTotalFree) }, \
+ { MIBDECL(memMinimumSwap) }, \
+ { MIBDECL(memShared) }, \
+ { MIBDECL(memBuffer) }, \
+ { MIBDECL(memCached) }, \
+ { MIBDECL(memSwapError) }, \
+ { MIBDECL(memSwapErrorMsg) }, \
+ { MIBDECL(laTable) }, \
+ { MIBDECL(laEntry) }, \
+ { MIBDECL(laIndex) }, \
+ { MIBDECL(laNames) }, \
+ { MIBDECL(laLoad) }, \
+ { MIBDECL(laConfig) }, \
+ { MIBDECL(laLoadInt) }, \
+ { MIBDECL(laErrorFlag) }, \
+ { MIBDECL(laErrMessage) }, \
\
{ MIBDECL(ucdExperimental) }, \
{ MIBDECL(ucdDiskIOMIB) }, \