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?


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       16 Jun 2012 19:29:51 -0000
@@ -3364,6 +3364,131 @@ 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);
+
+static struct oid ucdmemory_mib[] = {
+       { MIB(ucdMemory),                       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 },
+       { 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_ucdMemory]) {
+       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);
+}
+
+/*
 * Defined in UCD-DISKIO-MIB.txt.
 */

@@ -3546,6 +3671,9 @@ mib_init(void)

        /* BRIDGE-MIB */
        smi_mibtree(bridge_mib);
+
+       /* UCD-SNMP-MIB */
+       smi_mibtree(ucdmemory_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       16 Jun 2012 19:29:51 -0000
@@ -397,6 +397,23 @@
#define MIB_vantronix                   MIB_enterprises, 26766
#define MIB_openBSD                     MIB_enterprises, 30155

+/* UCD-SNMP-MIB */
+#define MIB_ucdMemory                  MIB_ucDavis, 4
+#define OIDIDX_ucdMemory               8
+#define MIB_memIndex                   MIB_ucdMemory, 1
+#define MIB_memErrorName               MIB_ucdMemory, 2
+#define MIB_memTotalSwap               MIB_ucdMemory, 3
+#define MIB_memAvailSwap               MIB_ucdMemory, 4
+#define MIB_memTotalReal               MIB_ucdMemory, 5
+#define MIB_memAvailReal               MIB_ucdMemory, 6
+#define MIB_memTotalFree               MIB_ucdMemory, 11
+#define MIB_memMinimumSwap             MIB_ucdMemory, 12
+#define MIB_memShared                  MIB_ucdMemory, 13
+#define MIB_memBuffer                  MIB_ucdMemory, 14
+#define MIB_memCached                  MIB_ucdMemory, 15
+#define MIB_memSwapError               MIB_ucdMemory, 100
+#define MIB_memSwapErrorMsg            MIB_ucdMemory, 101
+
/* UCD-DISKIO-MIB */
#define MIB_ucdExperimental             MIB_ucDavis, 13
#define MIB_ucdDiskIOMIB                MIB_ucdExperimental, 15
@@ -908,6 +925,21 @@
        { MIBDECL(microSystems) },                      \
        { MIBDECL(vantronix) },                         \
        { MIBDECL(openBSD) },                           \
+                                                       \
+       { MIBDECL(ucdMemory) },                         \
+       { 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(ucdExperimental) },                   \
        { MIBDECL(ucdDiskIOMIB) },                      \

Reply via email to