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) }, \