~ubuntu-branches/ubuntu/trusty/net-snmp/trusty

« back to all changes in this revision

Viewing changes to agent/mibgroup/ucd-snmp/vmstat.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2004-09-13 12:06:21 UTC
  • Revision ID: james.westby@ubuntu.com-20040913120621-g952ntonlleihcvm
Tags: upstream-5.1.1
ImportĀ upstreamĀ versionĀ 5.1.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <net-snmp/net-snmp-config.h>
 
2
 
 
3
#if HAVE_LIMITS_H
 
4
#include <limits.h>
 
5
#endif
 
6
#if HAVE_STDLIB_H
 
7
#include <stdlib.h>
 
8
#endif
 
9
#if HAVE_UNISTD_H
 
10
#include <unistd.h>
 
11
#endif
 
12
#if HAVE_FCNTL_H
 
13
#include <fcntl.h>
 
14
#endif
 
15
#include <ctype.h>
 
16
#include <signal.h>
 
17
#if HAVE_MACHINE_PARAM_H
 
18
#include <machine/param.h>
 
19
#endif
 
20
#if HAVE_SYS_VMMETER_H
 
21
#if !defined(bsdi2) && !defined(netbsd1)
 
22
#include <sys/vmmeter.h>
 
23
#endif
 
24
#endif
 
25
#if HAVE_SYS_CONF_H
 
26
#include <sys/conf.h>
 
27
#endif
 
28
#if HAVE_SYS_FS_H
 
29
#include <sys/fs.h>
 
30
#else
 
31
#if HAVE_UFS_FS_H
 
32
#include <ufs/fs.h>
 
33
#else
 
34
#ifdef HAVE_SYS_STAT_H
 
35
#include <sys/stat.h>
 
36
#endif
 
37
#ifdef HAVE_SYS_VNODE_H
 
38
#include <sys/vnode.h>
 
39
#endif
 
40
#ifdef HAVE_UFS_UFS_QUOTA_H
 
41
#include <ufs/ufs/quota.h>
 
42
#endif
 
43
#ifdef HAVE_UFS_UFS_INODE_H
 
44
#include <ufs/ufs/inode.h>
 
45
#endif
 
46
#if HAVE_UFS_FFS_FS_H
 
47
#include <ufs/ffs/fs.h>
 
48
#endif
 
49
#endif
 
50
#endif
 
51
#if HAVE_MTAB_H
 
52
#include <mtab.h>
 
53
#endif
 
54
#include <sys/stat.h>
 
55
#include <errno.h>
 
56
#if HAVE_FSTAB_H
 
57
#include <fstab.h>
 
58
#endif
 
59
#if HAVE_SYS_STATVFS_H
 
60
#include <sys/statvfs.h>
 
61
#endif
 
62
#if HAVE_SYS_VFS_H
 
63
#include <sys/vfs.h>
 
64
#endif
 
65
#if (!defined(HAVE_STATVFS)) && defined(HAVE_STATFS)
 
66
#if HAVE_SYS_PARAM_H
 
67
#include <sys/param.h>
 
68
#endif
 
69
#if HAVE_SYS_MOUNT_H
 
70
#include <sys/mount.h>
 
71
#endif
 
72
#if HAVE_SYS_SYSCTL_H
 
73
#include <sys/sysctl.h>
 
74
#endif
 
75
#define statvfs statfs
 
76
#endif
 
77
#if HAVE_VM_SWAP_PAGER_H
 
78
#include <vm/swap_pager.h>
 
79
#endif
 
80
#if HAVE_SYS_FIXPOINT_H
 
81
#include <sys/fixpoint.h>
 
82
#endif
 
83
#if HAVE_MALLOC_H
 
84
#include <malloc.h>
 
85
#endif
 
86
#if HAVE_STRING_H
 
87
#include <string.h>
 
88
#else
 
89
#include <strings.h>
 
90
#endif
 
91
#if TIME_WITH_SYS_TIME
 
92
# include <sys/time.h>
 
93
# include <time.h>
 
94
#else
 
95
# if HAVE_SYS_TIME_H
 
96
#  include <sys/time.h>
 
97
# else
 
98
#  include <time.h>
 
99
# endif
 
100
#endif
 
101
 
 
102
#include <net-snmp/net-snmp-includes.h>
 
103
#include <net-snmp/agent/net-snmp-agent-includes.h>
 
104
#include <net-snmp/agent/auto_nlist.h>
 
105
 
 
106
#include "mibdefs.h"
 
107
#include "struct.h"
 
108
#include "util_funcs.h"
 
109
#include "vmstat.h"
 
110
 
 
111
FindVarMethod var_extensible_vmstat;
 
112
 
 
113
void
 
114
init_vmstat(void)
 
115
{
 
116
    struct variable2 extensible_vmstat_variables[] = {
 
117
        {MIBINDEX, ASN_INTEGER, RONLY, var_extensible_vmstat, 1,
 
118
         {MIBINDEX}},
 
119
        {ERRORNAME, ASN_OCTET_STR, RONLY, var_extensible_vmstat, 1,
 
120
         {ERRORNAME}},
 
121
        {SWAPIN, ASN_INTEGER, RONLY, var_extensible_vmstat, 1, {SWAPIN}},
 
122
        {SWAPOUT, ASN_INTEGER, RONLY, var_extensible_vmstat, 1, {SWAPOUT}},
 
123
        {IOSENT, ASN_INTEGER, RONLY, var_extensible_vmstat, 1, {IOSENT}},
 
124
        {IORECEIVE, ASN_INTEGER, RONLY, var_extensible_vmstat, 1,
 
125
         {IORECEIVE}},
 
126
        {SYSINTERRUPTS, ASN_INTEGER, RONLY, var_extensible_vmstat, 1,
 
127
         {SYSINTERRUPTS}},
 
128
        {SYSCONTEXT, ASN_INTEGER, RONLY, var_extensible_vmstat, 1,
 
129
         {SYSCONTEXT}},
 
130
        {CPUUSER, ASN_INTEGER, RONLY, var_extensible_vmstat, 1, {CPUUSER}},
 
131
        {CPUSYSTEM, ASN_INTEGER, RONLY, var_extensible_vmstat, 1,
 
132
         {CPUSYSTEM}},
 
133
        {CPUIDLE, ASN_INTEGER, RONLY, var_extensible_vmstat, 1, {CPUIDLE}},
 
134
        {CPURAWUSER, ASN_COUNTER, RONLY, var_extensible_vmstat, 1,
 
135
         {CPURAWUSER}},
 
136
        {CPURAWNICE, ASN_COUNTER, RONLY, var_extensible_vmstat, 1,
 
137
         {CPURAWNICE}},
 
138
        {CPURAWSYSTEM, ASN_COUNTER, RONLY, var_extensible_vmstat, 1,
 
139
         {CPURAWSYSTEM}},
 
140
        {CPURAWIDLE, ASN_COUNTER, RONLY, var_extensible_vmstat, 1,
 
141
         {CPURAWIDLE}},
 
142
        /*
 
143
         * Future use: 
 
144
         */
 
145
        /*
 
146
         * {ERRORFLAG, ASN_INTEGER, RONLY, var_extensible_vmstat, 1, {ERRORFLAG }},
 
147
         * {ERRORMSG, ASN_OCTET_STR, RONLY, var_extensible_vmstat, 1, {ERRORMSG }}
 
148
         */
 
149
    };
 
150
 
 
151
    /*
 
152
     * Define the OID pointer to the top of the mib tree that we're
 
153
     * registering underneath 
 
154
     */
 
155
    oid             vmstat_variables_oid[] = { UCDAVIS_MIB, 11 };
 
156
 
 
157
    /*
 
158
     * register ourselves with the agent to handle our mib tree 
 
159
     */
 
160
    REGISTER_MIB("ucd-snmp/vmstat", extensible_vmstat_variables, variable2,
 
161
                 vmstat_variables_oid);
 
162
 
 
163
}
 
164
 
 
165
 
 
166
 
 
167
#define VMSTAT_FILE "/proc/stat"
 
168
 
 
169
void
 
170
getstat(unsigned long *cuse, unsigned long *cice, unsigned long *csys,
 
171
        unsigned long *cide, unsigned *pin, unsigned *pout,
 
172
        unsigned *swpin, unsigned *swpout, unsigned *itot, unsigned *i1,
 
173
        unsigned *ct)
 
174
{
 
175
    int             statfd;
 
176
    int             first = 1;
 
177
    static char    *buff = NULL;
 
178
    static int      bsize = 0;
 
179
 
 
180
    if ((statfd = open(VMSTAT_FILE, O_RDONLY, 0)) != -1) {
 
181
        char           *b;
 
182
        if (bsize == 0) {
 
183
            bsize = 128;
 
184
            buff = malloc(bsize);
 
185
        }
 
186
        while (read(statfd, buff, bsize) == bsize) {
 
187
            bsize += 256;
 
188
            buff = realloc(buff, bsize);
 
189
            DEBUGMSGTL(("vmstat", "/proc/stat buffer increased to %d\n", bsize));
 
190
            close(statfd);
 
191
            statfd = open(VMSTAT_FILE, O_RDONLY, 0);
 
192
        }
 
193
        close(statfd);
 
194
        *itot = 0;
 
195
        *i1 = 1;                /* ensure assert below will fail if the sscanf bombs */
 
196
        b = strstr(buff, "cpu ");
 
197
        if (b)
 
198
            sscanf(b, "cpu  %lu %lu %lu %lu", cuse, cice, csys, cide);
 
199
        else {
 
200
            if (first)
 
201
                snmp_log(LOG_ERR, "No cpu line in /proc/stat\n");
 
202
            *cuse = *cice = *csys = *cide = 0;
 
203
        }
 
204
        b = strstr(buff, "page ");
 
205
        if (b)
 
206
            sscanf(b, "page %u %u", pin, pout);
 
207
        else {
 
208
            if (first)
 
209
                snmp_log(LOG_ERR, "No page line in /proc/stat\n");
 
210
            *pin = *pout = 0;
 
211
        }
 
212
        b = strstr(buff, "swap ");
 
213
        if (b)
 
214
            sscanf(b, "swap %u %u", swpin, swpout);
 
215
        else {
 
216
            if (first)
 
217
                snmp_log(LOG_ERR, "No swap line in /proc/stat\n");
 
218
            *swpin = *swpout = 0;
 
219
        }
 
220
        b = strstr(buff, "intr ");
 
221
        if (b)
 
222
            sscanf(b, "intr %u %u", itot, i1);
 
223
        else {
 
224
            if (first)
 
225
                snmp_log(LOG_ERR, "No intr line in /proc/stat\n");
 
226
            *itot = 0;
 
227
        }
 
228
        b = strstr(buff, "ctxt ");
 
229
        if (b)
 
230
            sscanf(b, "ctxt %u", ct);
 
231
        else {
 
232
            if (first)
 
233
                snmp_log(LOG_ERR, "No ctxt line in /proc/stat\n");
 
234
            *ct = 0;
 
235
        }
 
236
        first = 0;
 
237
    } else {
 
238
        snmp_log_perror(VMSTAT_FILE);
 
239
    }
 
240
}
 
241
 
 
242
enum vmstat_index { swapin = 0, swapout,
 
243
    iosent, ioreceive,
 
244
    sysinterrupts, syscontext,
 
245
    cpuuser, cpusystem, cpuidle,
 
246
    cpurawuser, cpurawnice,
 
247
    cpurawsystem, cpurawidle
 
248
};
 
249
 
 
250
unsigned
 
251
vmstat(int iindex)
 
252
{
 
253
    unsigned long   cpu_use[2], cpu_nic[2], cpu_sys[2], cpu_idl[2];
 
254
    double          duse, dsys, didl, ddiv, divo2;
 
255
    double          druse, drnic, drsys, dridl;
 
256
    unsigned int    pgpgin[2], pgpgout[2], pswpin[2], pswpout[2];
 
257
    unsigned int    inter[2], ticks[2], ctxt[2];
 
258
    unsigned int    hertz;
 
259
 
 
260
    getstat(cpu_use, cpu_nic, cpu_sys, cpu_idl,
 
261
            pgpgin, pgpgout, pswpin, pswpout, inter, ticks, ctxt);
 
262
    duse = *(cpu_use) + *(cpu_nic);
 
263
    dsys = *(cpu_sys);
 
264
    didl = (*(cpu_idl));
 
265
    ddiv = (duse + dsys + didl);
 
266
    hertz = sysconf(_SC_CLK_TCK);  /* get ticks/s from system */
 
267
    divo2 = ddiv / 2;
 
268
    druse = *(cpu_use);
 
269
    drnic = *(cpu_nic);
 
270
    drsys = *(cpu_sys);
 
271
    dridl = (*(cpu_idl));
 
272
 
 
273
    switch (iindex) {
 
274
    case swapin:
 
275
        return (*(pswpin)  * 4 * hertz + divo2) / ddiv;
 
276
    case swapout:
 
277
        return (*(pswpout) * 4 * hertz + divo2) / ddiv;
 
278
    case iosent:
 
279
        return (*(pgpgin)      * hertz + divo2) / ddiv;
 
280
    case ioreceive:
 
281
        return (*(pgpgout)     * hertz + divo2) / ddiv;
 
282
    case sysinterrupts:
 
283
        return (*(inter)       * hertz + divo2) / ddiv;
 
284
    case syscontext:
 
285
        return (*(ctxt)        * hertz + divo2) / ddiv;
 
286
    case cpuuser:
 
287
        return (100 * duse / ddiv);
 
288
    case cpusystem:
 
289
        return (100 * dsys / ddiv);
 
290
    case cpuidle:
 
291
        return (100 * didl / ddiv);
 
292
    case cpurawuser:
 
293
        return druse;
 
294
    case cpurawnice:
 
295
        return drnic;
 
296
    case cpurawsystem:
 
297
        return drsys;
 
298
    case cpurawidle:
 
299
        return dridl;
 
300
    default:
 
301
        return -1;
 
302
    }
 
303
}
 
304
 
 
305
unsigned char  *
 
306
var_extensible_vmstat(struct variable *vp,
 
307
                      oid * name,
 
308
                      size_t * length,
 
309
                      int exact,
 
310
                      size_t * var_len, WriteMethod ** write_method)
 
311
{
 
312
 
 
313
    static long     long_ret;
 
314
    static char     errmsg[300];
 
315
#ifndef linux
 
316
    struct vmtotal  total;
 
317
#endif
 
318
 
 
319
    long_ret = 0;               /* set to 0 as default */
 
320
 
 
321
    if (header_generic(vp, name, length, exact, var_len, write_method))
 
322
        return (NULL);
 
323
    switch (vp->magic) {
 
324
    case MIBINDEX:
 
325
        long_ret = 1;
 
326
        return ((u_char *) (&long_ret));
 
327
    case ERRORNAME:            /* dummy name */
 
328
        sprintf(errmsg, "systemStats");
 
329
        *var_len = strlen(errmsg);
 
330
        return ((u_char *) (errmsg));
 
331
    case SWAPIN:
 
332
#ifdef linux
 
333
        long_ret = vmstat(swapin);
 
334
#endif
 
335
        return ((u_char *) (&long_ret));
 
336
    case SWAPOUT:
 
337
#ifdef linux
 
338
        long_ret = vmstat(swapout);
 
339
#endif
 
340
        return ((u_char *) (&long_ret));
 
341
    case IOSENT:
 
342
#ifdef linux
 
343
        long_ret = vmstat(iosent);
 
344
#endif
 
345
        return ((u_char *) (&long_ret));
 
346
    case IORECEIVE:
 
347
#ifdef linux
 
348
        long_ret = vmstat(ioreceive);
 
349
#endif
 
350
        return ((u_char *) (&long_ret));
 
351
    case SYSINTERRUPTS:
 
352
#ifdef linux
 
353
        long_ret = vmstat(sysinterrupts);
 
354
#endif
 
355
        return ((u_char *) (&long_ret));
 
356
    case SYSCONTEXT:
 
357
#ifdef linux
 
358
        long_ret = vmstat(syscontext);
 
359
#endif
 
360
        return ((u_char *) (&long_ret));
 
361
    case CPUUSER:
 
362
#ifdef linux
 
363
        long_ret = vmstat(cpuuser);
 
364
#endif
 
365
        return ((u_char *) (&long_ret));
 
366
    case CPUSYSTEM:
 
367
#ifdef linux
 
368
        long_ret = vmstat(cpusystem);
 
369
#endif
 
370
        return ((u_char *) (&long_ret));
 
371
    case CPUIDLE:
 
372
#ifdef linux
 
373
        long_ret = vmstat(cpuidle);
 
374
#endif
 
375
        return ((u_char *) (&long_ret));
 
376
    case CPURAWUSER:
 
377
#ifdef linux
 
378
        long_ret = vmstat(cpurawuser);
 
379
#endif
 
380
        return ((u_char *) (&long_ret));
 
381
    case CPURAWNICE:
 
382
#ifdef linux
 
383
        long_ret = vmstat(cpurawnice);
 
384
#endif
 
385
        return ((u_char *) (&long_ret));
 
386
    case CPURAWSYSTEM:
 
387
#ifdef linux
 
388
        long_ret = vmstat(cpurawsystem);
 
389
#endif
 
390
        return ((u_char *) (&long_ret));
 
391
    case CPURAWIDLE:
 
392
#ifdef linux
 
393
        long_ret = vmstat(cpurawidle);
 
394
#endif
 
395
        return ((u_char *) (&long_ret));
 
396
        /*
 
397
         * reserved for future use 
 
398
         */
 
399
        /*
 
400
         * case ERRORFLAG:
 
401
         * return((u_char *) (&long_ret));
 
402
         * case ERRORMSG:
 
403
         * return((u_char *) (&long_ret));
 
404
         */
 
405
    }
 
406
    return NULL;
 
407
}