On Sat, Jun 16, 2012 at 4:32 PM, Seth Wright <s...@crosse.org> 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) },                      \

Reply via email to