The diff below is the next rev of my earlier UCD-SNMP-MIB diff.  It
fixes some mistakes in the MIB declaration/naming, implements laConfig
as a read-write value, and adds the systemState section of the MIB.
It does not implement the "cooked" 1-minute-average values in
systemState, just the ss*Raw* values, since the cooked values are all
marked as being deprecated in the MIB anyway.

I wasn't quite sure of how to implement laConfig's state.  If my
approach below was wrong, please let me know a better way and I'll fix
it.


Thanks,
Seth



Index: mib.c
===================================================================
RCS file: /home/seth/code/obsd/cvsync/src/usr.sbin/snmpd/mib.c,v
retrieving revision 1.55
diff -u -p -r1.55 mib.c
--- mib.c       19 Jun 2012 18:43:27 -0000      1.55
+++ mib.c       24 Jun 2012 05:25:31 -0000
@@ -3364,6 +3364,361 @@ 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_ucdloadTable(struct oid *oid, struct ber_oid *o, struct
ber_element **elm);
+int    mib_setlaconfig(struct oid *oid, struct ber_oid *o, struct
ber_element **elm);
+int    mib_ucdsystemStats(struct oid *oid, struct ber_oid *o, struct
ber_element **elm);
+
+static struct oid ucdsnmp_mib[] = {
+       { MIB(ucDavis),                         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_ucdloadTable },
+       { MIB(laNames),                         OID_TRD, mib_ucdloadTable },
+       { MIB(laLoad),                          OID_TRD, mib_ucdloadTable },
+       { MIB(laConfig),                        OID_TRW, mib_ucdloadTable,
+           mib_setlaconfig },
+       { MIB(laLoadInt),                       OID_TRD, mib_ucdloadTable },
+       { MIB(laErrorFlag),                     OID_TRD, mib_ucdloadTable },
+       { MIB(laErrMessage),                    OID_TRD, mib_ucdloadTable },
+       { MIB(ssIndex),                         OID_RD, mib_ucdsystemStats },
+       { MIB(ssErrorName),                     OID_RD, mib_ucdsystemStats },
+       { MIB(ssCpuRawUser),                    OID_RD, mib_ucdsystemStats },
+       { MIB(ssCpuRawNice),                    OID_RD, mib_ucdsystemStats },
+       { MIB(ssCpuRawSystem),                  OID_RD, mib_ucdsystemStats },
+       { MIB(ssCpuRawIdle),                    OID_RD, mib_ucdsystemStats },
+       { MIB(ssCpuRawKernel),                  OID_RD, mib_ucdsystemStats },
+       { MIB(ssCpuRawInterrupt),               OID_RD, mib_ucdsystemStats },
+       { MIB(ssIORawSent),                     OID_RD, mib_ucdsystemStats },
+       { MIB(ssIORawReceived),                 OID_RD, mib_ucdsystemStats },
+       { MIB(ssRawInterrupts),                 OID_RD, mib_ucdsystemStats },
+       { MIB(ssRawContexts),                   OID_RD, mib_ucdsystemStats },
+       { MIB(ssRawSwapIn),                     OID_RD, mib_ucdsystemStats },
+       { MIB(ssRawSwapOut),                    OID_RD, mib_ucdsystemStats },
+       { MIBEND }
+};
+
+/* Taken from net-snmp */
+#define DEFAULTMINIMUMSWAP      16000
+#define ptok(p) ((p) * (uvm.pagesize >> 10))
+
+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);
+
+       switch (o->bo_id[OIDIDX_memory]) {
+       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);
+}
+
+/* values taken from net-snmp's default config */
+static double laconfig[3] = { 12.0, 10.0, 5.0 };
+
+int
+mib_ucdloadTable(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
+{
+       struct ber_element      *ber = *elm;
+       double                   avg[3];
+       u_int32_t                idx;
+       int                      samples, ret;
+       char                    *str;
+
+       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", laconfig[idx - 1])) == -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 - 1] > laconfig[idx - 1])
+                       ber = ber_add_integer(ber, 1);
+               else
+                       ber = ber_add_integer(ber, 0);
+               break;
+       case 101: /* laErrMessage */
+               if (avg[idx - 1] > laconfig[idx - 1])
+                       ber = ber_add_string(ber, "Load Average too high");
+               else
+                       ber = ber_add_string(ber, "");
+               break;
+       default:
+               return (-1);
+       }
+
+       return (0);
+}
+
+int
+mib_setlaconfig(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
+{
+       char                    *str;
+       u_int32_t                idx;
+       double                   t;
+
+       /* Get and verify the current row index */
+       idx = o->bo_id[OIDIDX_laTableEntry];
+
+       if (idx < 1 || idx > sizeofa(laconfig))
+               return (1);
+
+       if (ber_get_string(*elm, &str) == -1)
+               return (-1);
+
+       if ((t = atof(str)) <= 0)
+               return (-1);
+
+       laconfig[idx - 1] = t;
+       return (0);
+}
+
+int
+mib_ucdsystemStats(struct oid *oid, struct ber_oid *o, struct
ber_element **elm)
+{
+       struct ber_element      *ber = *elm;
+       struct diskstats        *stats;
+       struct uvmexp            uvm;
+       u_int64_t                blocks;
+       long                     cp_time[CPUSTATES];
+       size_t                   len;
+       int                      diskcount, i;
+       int                      mib[] = { CTL_KERN, KERN_CPTIME };
+
+       len = sizeof(cp_time);
+       if (sysctl(mib, sizeofa(mib), &cp_time, &len, NULL, 0) == -1)
+               return (-1);
+
+       mib[0] = CTL_VM;
+       mib[1] = VM_UVMEXP;
+       len = sizeof(uvm);
+       if (sysctl(mib, sizeofa(mib), &uvm, &len, NULL, 0) == -1)
+               return (-1);
+
+       mib[0] = CTL_HW;
+       mib[1] = HW_DISKCOUNT;
+       len = sizeof(diskcount);
+       if (sysctl(mib, sizeofa(mib), &diskcount, &len, NULL, 0) == -1)
+               return (-1);
+
+       stats = calloc(diskcount, sizeof(*stats));
+       if (stats == NULL)
+               return (-1);
+       /* We know len won't overflow, otherwise calloc() would have failed. */
+       len = diskcount * sizeof(*stats);
+       mib[1] = HW_DISKSTATS;
+       if (sysctl(mib, sizeofa(mib), stats, &len, NULL, 0) == -1) {
+               free(stats);
+               return (-1);
+       }
+
+       switch (o->bo_id[OIDIDX_systemStats]) {
+       case 1: /* ssIndex */
+               ber = ber_add_integer(ber, 1);
+               break;
+       case 2: /* ssErrorName */
+               ber = ber_add_string(ber, "systemStats");
+               break;
+       case 50: /* ssCpuRawUser */
+               ber = ber_add_integer(ber, cp_time[CP_USER]);
+               ber_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER32);
+               break;
+       case 51: /* ssCpuRawNice */
+               ber = ber_add_integer(ber, cp_time[CP_NICE]);
+               ber_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER32);
+               break;
+       case 52: /* ssCpuRawSystem */
+               ber = ber_add_integer(ber, cp_time[CP_SYS] + cp_time[CP_INTR]);
+               ber_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER32);
+               break;
+       case 53: /* ssCpuRawIdle */
+               ber = ber_add_integer(ber, cp_time[CP_IDLE]);
+               ber_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER32);
+               break;
+       case 55: /* ssCpuRawKernel */
+               ber = ber_add_integer(ber, cp_time[CP_SYS]);
+               ber_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER32);
+               break;
+       case 56: /* ssCpuRawInterrupt */
+               ber = ber_add_integer(ber, cp_time[CP_INTR]);
+               ber_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER32);
+               break;
+       case 57: /* ssIORawSent */
+               blocks = 0;
+               for (i = 0; i < diskcount; i++)
+                       blocks += stats[i].ds_wbytes;
+               blocks /= MAXBSIZE;
+               ber = ber_add_integer(ber, (u_int32_t)blocks);
+               ber_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER32);
+               break;
+       case 58: /* ssIORawReceived */
+               blocks = 0;
+               for (i = 0; i < diskcount; i++)
+                       blocks += stats[i].ds_rbytes;
+               blocks /= MAXBSIZE;
+               ber = ber_add_integer(ber, (u_int32_t)blocks);
+               ber_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER32);
+               break;
+       case 59: /* ssRawInterrupts */
+               ber = ber_add_integer(ber, uvm.intrs);
+               ber_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER32);
+               break;
+       case 60: /* ssRawContexts */
+               ber = ber_add_integer(ber, uvm.swtch);
+               ber_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER32);
+               break;
+       case 62: /* ssRawSwapIn */
+               ber = ber_add_integer(ber, ptok(uvm.pgswapin));
+               ber_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER32);
+               break;
+       case 63: /* ssRawSwapOut */
+               ber = ber_add_integer(ber, ptok(uvm.pgswapout));
+               ber_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER32);
+               break;
+       default:
+               free(stats);
+               return (-1);
+       }
+
+       free(stats);
+       return (0);
+}
+
+/*
  * Defined in UCD-DISKIO-MIB.txt.
  */

@@ -3547,6 +3902,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: /home/seth/code/obsd/cvsync/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       24 Jun 2012 03:19:27 -0000
@@ -397,6 +397,51 @@
 #define MIB_vantronix                  MIB_enterprises, 26766
 #define MIB_openBSD                    MIB_enterprises, 30155

+/* UCD-SNMP-MIB */
+#define MIB_memory                     MIB_ucDavis, 4
+#define OIDIDX_memory                  8
+#define MIB_memIndex                   MIB_memory, 1
+#define MIB_memErrorName               MIB_memory, 2
+#define MIB_memTotalSwap               MIB_memory, 3
+#define MIB_memAvailSwap               MIB_memory, 4
+#define MIB_memTotalReal               MIB_memory, 5
+#define MIB_memAvailReal               MIB_memory, 6
+#define MIB_memTotalFree               MIB_memory, 11
+#define MIB_memMinimumSwap             MIB_memory, 12
+#define MIB_memShared                  MIB_memory, 13
+#define MIB_memBuffer                  MIB_memory, 14
+#define MIB_memCached                  MIB_memory, 15
+#define MIB_memSwapError               MIB_memory, 100
+#define MIB_memSwapErrorMsg            MIB_memory, 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
+#define MIB_systemStats                        MIB_ucDavis, 11
+#define OIDIDX_systemStats             8
+#define MIB_ssIndex                    MIB_systemStats, 1
+#define MIB_ssErrorName                        MIB_systemStats, 2
+#define MIB_ssCpuRawUser               MIB_systemStats, 50
+#define MIB_ssCpuRawNice               MIB_systemStats, 51
+#define MIB_ssCpuRawSystem             MIB_systemStats, 52
+#define MIB_ssCpuRawIdle               MIB_systemStats, 53
+#define MIB_ssCpuRawKernel             MIB_systemStats, 55
+#define MIB_ssCpuRawInterrupt          MIB_systemStats, 56
+#define MIB_ssIORawSent                        MIB_systemStats, 57
+#define MIB_ssIORawReceived            MIB_systemStats, 58
+#define MIB_ssRawInterrupts            MIB_systemStats, 59
+#define MIB_ssRawContexts              MIB_systemStats, 60
+#define MIB_ssRawSwapIn                        MIB_systemStats, 62
+#define MIB_ssRawSwapOut               MIB_systemStats, 63
+
+
 /* UCD-DISKIO-MIB */
 #define MIB_ucdExperimental            MIB_ucDavis, 13
 #define MIB_ucdDiskIOMIB               MIB_ucdExperimental, 15
@@ -908,6 +953,45 @@
        { MIBDECL(microSystems) },                      \
        { MIBDECL(vantronix) },                         \
        { MIBDECL(openBSD) },                           \
+                                                       \
+       { MIBDECL(memory) },                            \
+       { 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(systemStats) },                       \
+       { MIBDECL(ssIndex) },                           \
+       { MIBDECL(ssErrorName) },                       \
+       { MIBDECL(ssCpuRawUser) },                      \
+       { MIBDECL(ssCpuRawNice) },                      \
+       { MIBDECL(ssCpuRawSystem) },                    \
+       { MIBDECL(ssCpuRawIdle) },                      \
+       { MIBDECL(ssCpuRawKernel) },                    \
+       { MIBDECL(ssCpuRawInterrupt) },                 \
+       { MIBDECL(ssIORawSent) },                       \
+       { MIBDECL(ssIORawReceived) },                   \
+       { MIBDECL(ssRawInterrupts) },                   \
+       { MIBDECL(ssRawContexts) },                     \
+       { MIBDECL(ssRawSwapIn) },                       \
+       { MIBDECL(ssRawSwapOut) },                      \
                                                        \
        { MIBDECL(ucdExperimental) },                   \
        { MIBDECL(ucdDiskIOMIB) },                      \

Reply via email to