# BRCM_VERSION=3
[bcm963xx.git] / userapps / opensource / net-snmp / agent / mibgroup / ucd-snmp / vmstat_netbsd1.c
1 /*
2  * vmstat_netbsd1.c
3  */
4
5 #include <net-snmp/net-snmp-config.h>
6
7 /*
8  * Ripped from /usr/scr/usr.bin/vmstat/vmstat.c (covering all bases) 
9  */
10 #include <sys/param.h>
11 #include <sys/time.h>
12 #include <sys/proc.h>
13 #include <sys/dkstat.h>
14 #include <sys/buf.h>
15 #include <sys/uio.h>
16 #include <sys/namei.h>
17 #include <sys/malloc.h>
18 #include <sys/signal.h>
19 #include <sys/fcntl.h>
20 #include <sys/ioctl.h>
21 #include <sys/sysctl.h>
22 #include <sys/vmmeter.h>
23 #include <sys/sched.h>
24
25 #if defined(HAVE_UVM_UVM_PARAM_H) && defined(HAVE_UVM_UVM_EXTERN_H)
26 #include <uvm/uvm_param.h>
27 #include <uvm/uvm_extern.h>
28 #elif defined(HAVE_VM_VM_PARAM_H) && defined(HAVE_VM_VM_EXTERN_H)
29 #include <vm/vm_param.h>
30 #include <vm/vm_extern.h>
31 #else
32 #error vmstat_netbsd1.c: Is this really a NetBSD system?
33 #endif
34
35 #include <time.h>
36 #include <nlist.h>
37 #include <kvm.h>
38 #include <errno.h>
39 #include <unistd.h>
40 #include <stdio.h>
41 #include <ctype.h>
42 #include <stdlib.h>
43 #include <string.h>
44 #include <paths.h>
45 #include <limits.h>
46
47
48 #include <net-snmp/net-snmp-includes.h>
49 #include <net-snmp/agent/net-snmp-agent-includes.h>
50 #include <net-snmp/agent/auto_nlist.h>
51
52 #include "util_funcs.h"
53 #include "vmstat.h"
54
55 /*
56  * CPU percentage 
57  */
58 #define CPU_PRC         100
59 #define CPTIME_SYMBOL   "cp_time"
60 #define BOOTTIME_SYMBOL "boottime"
61
62 FindVarMethod var_extensible_vmstat;
63
64 void
65 init_vmstat_netbsd1(void)
66 {
67
68     struct variable2 extensible_vmstat_variables[] = {
69         {MIBINDEX, ASN_INTEGER, RONLY, var_extensible_vmstat, 1,
70          {MIBINDEX}},
71         {ERRORNAME, ASN_OCTET_STR, RONLY, var_extensible_vmstat, 1,
72          {ERRORNAME}},
73         {SWAPIN, ASN_INTEGER, RONLY, var_extensible_vmstat, 1, {SWAPIN}},
74         {SWAPOUT, ASN_INTEGER, RONLY, var_extensible_vmstat, 1, {SWAPOUT}},
75         {IOSENT, ASN_INTEGER, RONLY, var_extensible_vmstat, 1, {IOSENT}},
76         {IORECEIVE, ASN_INTEGER, RONLY, var_extensible_vmstat, 1,
77          {IORECEIVE}},
78         {SYSINTERRUPTS, ASN_INTEGER, RONLY, var_extensible_vmstat, 1,
79          {SYSINTERRUPTS}},
80         {SYSCONTEXT, ASN_INTEGER, RONLY, var_extensible_vmstat, 1,
81          {SYSCONTEXT}},
82         {CPUUSER, ASN_INTEGER, RONLY, var_extensible_vmstat, 1, {CPUUSER}},
83         {CPUSYSTEM, ASN_INTEGER, RONLY, var_extensible_vmstat, 1,
84          {CPUSYSTEM}},
85         {CPUIDLE, ASN_INTEGER, RONLY, var_extensible_vmstat, 1, {CPUIDLE}},
86         {CPURAWUSER, ASN_COUNTER, RONLY, var_extensible_vmstat, 1,
87          {CPURAWUSER}},
88         {CPURAWNICE, ASN_COUNTER, RONLY, var_extensible_vmstat, 1,
89          {CPURAWNICE}},
90         {CPURAWSYSTEM, ASN_COUNTER, RONLY, var_extensible_vmstat, 1,
91          {CPURAWSYSTEM}},
92         {CPURAWIDLE, ASN_COUNTER, RONLY, var_extensible_vmstat, 1,
93          {CPURAWIDLE}},
94         {CPURAWKERNEL, ASN_COUNTER, RONLY, var_extensible_vmstat, 1,
95          {CPURAWKERNEL}},
96         {CPURAWINTR, ASN_COUNTER, RONLY, var_extensible_vmstat, 1,
97          {CPURAWINTR}},
98
99         /*
100          * Future use: 
101          */
102         /*
103          * {ERRORFLAG, ASN_INTEGER, RONLY, var_extensible_vmstat, 1, {ERRORFLAG }},
104          * {ERRORMSG, ASN_OCTET_STR, RONLY, var_extensible_vmstat, 1, {ERRORMSG }}
105          */
106     };
107
108     /*
109      * Define the OID pointer to the top of the mib tree that we're
110      * registering underneath 
111      */
112     oid             vmstat_variables_oid[] = { UCDAVIS_MIB, 11 };
113
114     /*
115      * register ourselves with the agent to handle our mib tree 
116      */
117     REGISTER_MIB("ucd-snmp/vmstat", extensible_vmstat_variables, variable2,
118                  vmstat_variables_oid);
119
120 }
121
122
123 long
124 getuptime(void)
125 {
126     static time_t   now, boottime;
127     time_t          uptime;
128
129     if (boottime == 0)
130         auto_nlist(BOOTTIME_SYMBOL, (char *) &boottime, sizeof(boottime));
131
132     time(&now);
133     uptime = now - boottime;
134
135     return (uptime);
136 }
137
138 unsigned char  *
139 var_extensible_vmstat(struct variable *vp,
140                       oid * name,
141                       size_t * length,
142                       int exact,
143                       size_t * var_len, WriteMethod ** write_method)
144 {
145
146     int             loop;
147
148     time_t          time_new = getuptime();
149     static time_t   time_old;
150     static time_t   time_diff;
151
152 #if defined(KERN_CP_TIME)
153     static u_int64_t cpu_old[CPUSTATES];
154     static u_int64_t cpu_new[CPUSTATES];
155     static u_int64_t cpu_diff[CPUSTATES];
156     static u_int64_t cpu_total;
157 #elif defined(KERN_CPTIME)
158     static long     cpu_old[CPUSTATES];
159     static long     cpu_new[CPUSTATES];
160     static long     cpu_diff[CPUSTATES];
161     static long     cpu_total;
162 #else
163     static long     cpu_old[CPUSTATES];
164     static long     cpu_new[CPUSTATES];
165     static long     cpu_diff[CPUSTATES];
166     static long     cpu_total;
167 #endif
168     long            cpu_sum;
169     double          cpu_prc;
170
171     static struct uvmexp mem_old, mem_new;
172     int             mem_mib[] = { CTL_VM, VM_UVMEXP };
173     int             mem_size = sizeof(struct uvmexp);
174
175     static long     long_ret;
176     static char     errmsg[300];
177
178     long_ret = 0;               /* set to 0 as default */
179
180     if (header_generic(vp, name, length, exact, var_len, write_method))
181         return (NULL);
182
183     /*
184      * Update structures (only if time has passed) 
185      */
186     if (time_new != time_old) {
187 #ifdef KERN_CP_TIME
188         int             mib[2] = { CTL_KERN, KERN_CP_TIME };
189         int             ssize = sizeof(cpu_new);
190
191         if (sysctl(mib, 2, cpu_new, &ssize, NULL, 0) < 0)
192             memset(cpu_new, 0, sizeof(cpu_new));
193 #elif defined(KERN_CPTIME)
194         int             mib[2] = { CTL_KERN, KERN_CPTIME };
195         int             ssize = sizeof(cpu_new);
196
197         if (sysctl(mib, 2, cpu_new, &ssize, NULL, 0) < 0)
198             memset(cpu_new, 0, sizeof(cpu_new));
199 #else
200         /*
201          * CPU usage 
202          */
203         auto_nlist(CPTIME_SYMBOL, (char *) cpu_new, sizeof(cpu_new));
204 #endif
205
206         time_diff = time_new - time_old;
207         time_old = time_new;
208
209         cpu_total = 0;
210
211         for (loop = 0; loop < CPUSTATES; loop++) {
212             cpu_diff[loop] = cpu_new[loop] - cpu_old[loop];
213             cpu_old[loop] = cpu_new[loop];
214             cpu_total += cpu_diff[loop];
215         }
216
217         if (cpu_total == 0)
218             cpu_total = 1;
219
220         /*
221          * Memory info 
222          */
223         mem_old = mem_new;
224         sysctl(mem_mib, 2, &mem_new, &mem_size, NULL, 0);
225     }
226
227     /*
228      * Rate macro 
229      */
230 #define rate(x) (((x)+ time_diff/2) / time_diff)
231
232     /*
233      * Page-to-kb macro 
234      */
235 #define ptok(p) ((p) * (mem_new.pagesize >> 10))
236
237     switch (vp->magic) {
238     case MIBINDEX:
239         long_ret = 1;
240         return ((u_char *) (&long_ret));
241     case ERRORNAME:            /* dummy name */
242         sprintf(errmsg, "systemStats");
243         *var_len = strlen(errmsg);
244         return ((u_char *) (errmsg));
245     case SWAPIN:
246         long_ret = ptok(mem_new.swapins - mem_old.swapins);
247         long_ret = rate(long_ret);
248         return ((u_char *) (&long_ret));
249     case SWAPOUT:
250         long_ret = ptok(mem_new.swapouts - mem_old.swapouts);
251         long_ret = rate(long_ret);
252         return ((u_char *) (&long_ret));
253     case IOSENT:
254 #if NO_DUMMY_VALUES
255         return NULL;
256 #endif
257         long_ret = -1;
258         return ((u_char *) (&long_ret));
259     case IORECEIVE:
260 #if NO_DUMMY_VALUES
261         return NULL;
262 #endif
263         long_ret = -1;
264         return ((u_char *) (&long_ret));
265     case SYSINTERRUPTS:
266         long_ret = rate(mem_new.intrs - mem_old.intrs);
267         return ((u_char *) (&long_ret));
268     case SYSCONTEXT:
269         long_ret = rate(mem_new.swtch - mem_old.swtch);
270         return ((u_char *) (&long_ret));
271     case CPUUSER:
272         cpu_sum = cpu_diff[CP_USER] + cpu_diff[CP_NICE];
273         cpu_prc = (float) cpu_sum / (float) cpu_total;
274         long_ret = cpu_prc * CPU_PRC;
275         return ((u_char *) (&long_ret));
276     case CPUSYSTEM:
277         cpu_sum = cpu_diff[CP_SYS] + cpu_diff[CP_INTR];
278         cpu_prc = (float) cpu_sum / (float) cpu_total;
279         long_ret = cpu_prc * CPU_PRC;
280         return ((u_char *) (&long_ret));
281     case CPUIDLE:
282         cpu_sum = cpu_diff[CP_IDLE];
283         cpu_prc = (float) cpu_sum / (float) cpu_total;
284         long_ret = cpu_prc * CPU_PRC;
285         return ((u_char *) (&long_ret));
286     case CPURAWUSER:
287         long_ret = cpu_new[CP_USER];
288         return ((u_char *) (&long_ret));
289     case CPURAWNICE:
290         long_ret = cpu_new[CP_NICE];
291         return ((u_char *) (&long_ret));
292     case CPURAWSYSTEM:
293         long_ret = cpu_new[CP_SYS] + cpu_new[CP_INTR];
294         return ((u_char *) (&long_ret));
295     case CPURAWIDLE:
296         long_ret = cpu_new[CP_IDLE];
297         return ((u_char *) (&long_ret));
298     case CPURAWKERNEL:
299         long_ret = cpu_new[CP_SYS];
300         return ((u_char *) (&long_ret));
301     case CPURAWINTR:
302         long_ret = cpu_new[CP_INTR];
303         return ((u_char *) (&long_ret));
304         /*
305          * reserved for future use 
306          */
307         /*
308          * case ERRORFLAG:
309          * return((u_char *) (&long_ret));
310          * case ERRORMSG:
311          * return((u_char *) (&long_ret));
312          */
313     }
314     return NULL;
315 }