blob: 33f5412c73bea9b35049e41ac15dd13bedcb9eb7 [file] [log] [blame]
Dave Shieldfe5f3db2002-02-06 16:44:26 +00001/*
2 * vmstat_dynix.c
3 * UCD SNMP module for systemStats section of UCD-SNMP-MIB for Dynix
4 * Patrick Hess <phess@phess.best.vwh.net>
5 *
6 * This is just a port of the vmstat_solaris2 code Version 0.7
7 *
8 */
9
Wes Hardaker6d1f6022002-04-20 07:08:20 +000010/*
11 * To make lint skip the debug code and stop complaining
12 */
Dave Shieldfe5f3db2002-02-06 16:44:26 +000013#ifdef __lint
Thomas Anderse7563bf2006-09-15 00:48:50 +000014#define NETSNMP_NO_DEBUGGING 1
Dave Shieldfe5f3db2002-02-06 16:44:26 +000015#endif
16
17#define __NO_ASM_MACRO 1
18
Wes Hardaker6d1f6022002-04-20 07:08:20 +000019/*
20 * Includes start here
21 */
Dave Shield7437a302002-07-16 15:48:49 +000022#include <net-snmp/net-snmp-config.h>
Dave Shieldfe5f3db2002-02-06 16:44:26 +000023
Wes Hardaker6d1f6022002-04-20 07:08:20 +000024/*
25 * Standard includes
26 */
Dave Shieldfe5f3db2002-02-06 16:44:26 +000027#include <sys/tmp_ctl.h>
28#include <sys/sysperf.h>
29#include <sys/vmmeter.h>
30#include <unistd.h>
31#include <string.h>
Wes Hardaker6d1f6022002-04-20 07:08:20 +000032
Dave Shield1f17c992002-02-08 15:45:13 +000033#include <net-snmp/net-snmp-includes.h>
34#include <net-snmp/agent/net-snmp-agent-includes.h>
Dave Shieldfe5f3db2002-02-06 16:44:26 +000035
Dave Shieldfe5f3db2002-02-06 16:44:26 +000036#include "mibdefs.h"
Magnus Fromreide610d95f2008-05-20 23:00:28 +000037#include "util_funcs/header_generic.h"
Dave Shieldfe5f3db2002-02-06 16:44:26 +000038
Wes Hardaker6d1f6022002-04-20 07:08:20 +000039/*
40 * Header file for this module
41 */
Dave Shieldfe5f3db2002-02-06 16:44:26 +000042#include "vmstat.h"
43#include "vmstat_dynix.h"
44
Wes Hardaker6d1f6022002-04-20 07:08:20 +000045/*
46 * Includes end here
47 */
Dave Shieldfe5f3db2002-02-06 16:44:26 +000048
49
Wes Hardaker6d1f6022002-04-20 07:08:20 +000050/*
51 * Global structures start here
52 */
Dave Shieldfe5f3db2002-02-06 16:44:26 +000053
Wes Hardaker6d1f6022002-04-20 07:08:20 +000054/*
55 * A structure to save data gathered from the kernel kstat interface to.
56 */
57/*
58 * We used to have the sys/sysinfo.h cpu_stat_t here but we did not need
59 */
60/*
61 * all of it, some in a different size and some additional ones so we build
62 */
63/*
64 * our own
65 */
66struct cpu_stat_snapshot {
67 time_t css_time;
68 unsigned int css_cpus;
69 unsigned long long css_swapin;
70 unsigned long long css_swapout;
71 unsigned long long css_blocks_read;
72 unsigned long long css_blocks_write;
73 unsigned long long css_interrupts;
74 unsigned long long css_context_sw;
75 unsigned long long css_cpu[V_CPU_STATES];
Dave Shieldfe5f3db2002-02-06 16:44:26 +000076};
Wes Hardaker6d1f6022002-04-20 07:08:20 +000077
78/*
79 * Global structures end here
80 */
Dave Shieldfe5f3db2002-02-06 16:44:26 +000081
82
Wes Hardaker6d1f6022002-04-20 07:08:20 +000083/*
84 * Global variables start here
85 */
Dave Shieldfe5f3db2002-02-06 16:44:26 +000086
Wes Hardaker6d1f6022002-04-20 07:08:20 +000087/*
88 * Variables for the calculated values, filled in update_stats
89 */
90/*
91 * Need to be global since we need them in more than one function
92 */
93static ulong swapin;
94static ulong swapout;
95static ulong blocks_read;
96static ulong blocks_write;
97static ulong interrupts;
98static ulong context_sw;
Dave Shieldfe5f3db2002-02-06 16:44:26 +000099
Wes Hardaker6d1f6022002-04-20 07:08:20 +0000100/*
101 * Since MIB wants V_CPU_SYSTEM, which is V_CPU_KERNEL + V_CPU_STREAM
102 */
103static long cpu_perc[V_CPU_STATES + 1];
Dave Shieldfe5f3db2002-02-06 16:44:26 +0000104
Wes Hardaker6d1f6022002-04-20 07:08:20 +0000105/*
106 * How many snapshots we have already taken, needed for the first
107 */
108/*
109 * POLL_INTERVAL * POLL_VALUES seconds of agent running
110 */
Dave Shieldfe5f3db2002-02-06 16:44:26 +0000111static unsigned int number_of_snapshots;
112
Wes Hardaker6d1f6022002-04-20 07:08:20 +0000113/*
114 * The place to store the snapshots of system data in
115 */
116static struct cpu_stat_snapshot snapshot[POLL_VALUES + 1];
Dave Shieldfe5f3db2002-02-06 16:44:26 +0000117
Wes Hardaker6d1f6022002-04-20 07:08:20 +0000118/*
119 * And one for the raw counters, which we fill when the raw values are
120 */
121/*
122 * requested, as opposed to the absolute values, which are taken every
123 */
124/*
125 * POLL_INTERVAL seconds and calculated over POLL_INTERVAL * POLL_VALUES time
126 */
Dave Shieldfe5f3db2002-02-06 16:44:26 +0000127static struct cpu_stat_snapshot raw_values;
128
Wes Hardaker6d1f6022002-04-20 07:08:20 +0000129/*
130 * Global variables end here
131 */
Dave Shieldfe5f3db2002-02-06 16:44:26 +0000132
133
Wes Hardaker6d1f6022002-04-20 07:08:20 +0000134/*
135 * Functions start here
136 */
Dave Shieldfe5f3db2002-02-06 16:44:26 +0000137
Wes Hardaker6d1f6022002-04-20 07:08:20 +0000138/*
139 * Function prototype
140 */
141static void update_stats(unsigned int registrationNumber,
142 void *clientarg);
143static int take_snapshot(struct cpu_stat_snapshot *css);
Dave Shieldfe5f3db2002-02-06 16:44:26 +0000144
Wes Hardaker6d1f6022002-04-20 07:08:20 +0000145/*
146 * init_vmstat_dynix starts here
147 */
148/*
149 * Init function for this module, from prototype
150 */
151/*
152 * Defines variables handled by this module, defines root OID for
153 */
154/*
155 * this module and registers it with the agent
156 */
Dave Shieldfe5f3db2002-02-06 16:44:26 +0000157
Dave Shield9fbc4a32002-05-23 08:39:41 +0000158FindVarMethod var_extensible_vmstat;
Dave Shieldfe5f3db2002-02-06 16:44:26 +0000159
Wes Hardaker6d1f6022002-04-20 07:08:20 +0000160void
161init_vmstat_dynix(void)
Dave Shieldfe5f3db2002-02-06 16:44:26 +0000162{
Wes Hardaker6d1f6022002-04-20 07:08:20 +0000163
Dave Shieldfe5f3db2002-02-06 16:44:26 +0000164 /*
Wes Hardaker6d1f6022002-04-20 07:08:20 +0000165 * Which variables do we service ?
166 */
167 struct variable2 extensible_vmstat_variables[] = {
Magnus Fromreide2e597ff2008-10-21 21:10:43 +0000168 {MIBINDEX, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
169 var_extensible_vmstat, 1, {MIBINDEX}},
170 {ERRORNAME, ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY,
171 var_extensible_vmstat, 1, {ERRORNAME}},
172 {SWAPIN, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
173 var_extensible_vmstat, 1, {SWAPIN}},
174 {SWAPOUT, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
175 var_extensible_vmstat, 1, {SWAPOUT}},
176 {IOSENT, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
177 var_extensible_vmstat, 1, {IOSENT}},
178 {IORECEIVE, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
179 var_extensible_vmstat, 1, {IORECEIVE}},
180 {SYSINTERRUPTS, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
181 var_extensible_vmstat, 1, {SYSINTERRUPTS}},
182 {SYSCONTEXT, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
183 var_extensible_vmstat, 1, {SYSCONTEXT}},
184 {CPUUSER, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
185 var_extensible_vmstat, 1, {CPUUSER}},
186 {CPUSYSTEM, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
187 var_extensible_vmstat, 1, {CPUSYSTEM}},
188 {CPUIDLE, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
189 var_extensible_vmstat, 1, {CPUIDLE}},
190 {CPURAWUSER, ASN_COUNTER, NETSNMP_OLDAPI_RONLY,
191 var_extensible_vmstat, 1, {CPURAWUSER}},
192 {CPURAWSYSTEM, ASN_COUNTER, NETSNMP_OLDAPI_RONLY,
193 var_extensible_vmstat, 1, {CPURAWSYSTEM}},
194 {CPURAWIDLE, ASN_COUNTER, NETSNMP_OLDAPI_RONLY,
195 var_extensible_vmstat, 1, {CPURAWIDLE}},
196 {CPURAWWAIT, ASN_COUNTER, NETSNMP_OLDAPI_RONLY,
197 var_extensible_vmstat, 1, {CPURAWWAIT}},
198 {CPURAWKERNEL, ASN_COUNTER, NETSNMP_OLDAPI_RONLY,
199 var_extensible_vmstat, 1, {CPURAWKERNEL}},
200 {IORAWSENT, ASN_COUNTER, NETSNMP_OLDAPI_RONLY,
201 var_extensible_vmstat, 1, {IORAWSENT}},
202 {IORAWRECEIVE, ASN_COUNTER, NETSNMP_OLDAPI_RONLY,
203 var_extensible_vmstat, 1, {IORAWRECEIVE}},
Wes Hardaker6d1f6022002-04-20 07:08:20 +0000204 /*
205 * Future use:
206 */
207 /*
Magnus Fromreide2e597ff2008-10-21 21:10:43 +0000208 * {ERRORFLAG, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
209 * var_extensible_vmstat, 1, {ERRORFLAG }},
210 * {ERRORMSG, ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY,
211 * var_extensible_vmstat, 1, {ERRORMSG }}
Wes Hardaker6d1f6022002-04-20 07:08:20 +0000212 */
213 };
Dave Shieldfe5f3db2002-02-06 16:44:26 +0000214
Dave Shieldfe5f3db2002-02-06 16:44:26 +0000215 /*
Wes Hardaker6d1f6022002-04-20 07:08:20 +0000216 * Define the OID pointer to the top of the mib tree that we're
217 */
218 /*
219 * registering underneath
220 */
Thomas Anderse7563bf2006-09-15 00:48:50 +0000221 oid vmstat_variables_oid[] = { NETSNMP_UCDAVIS_MIB, 11 };
Dave Shieldfe5f3db2002-02-06 16:44:26 +0000222
Wes Hardaker6d1f6022002-04-20 07:08:20 +0000223 /*
224 * register ourselves with the agent to handle our mib tree
225 */
226 /*
227 * LINTED Trust me, I know what I'm doing
228 */
229 REGISTER_MIB("ucd-snmp/vmstat", extensible_vmstat_variables, variable2,
230 vmstat_variables_oid);
Dave Shieldfe5f3db2002-02-06 16:44:26 +0000231
Wes Hardaker6d1f6022002-04-20 07:08:20 +0000232 /*
233 * Start with some useful data
234 */
235 update_stats(0, NULL);
236
237 /*
238 * update_stats is run every POLL_INTERVAL seconds using this routine
239 */
240 /*
241 * (see 'man snmp_alarm')
242 */
243 /*
244 * This is only executed once to get some useful data in the beginning
245 */
246 if (snmp_alarm_register(5, NULL, update_stats, NULL) == 0) {
247 snmp_log(LOG_WARNING,
248 "vmstat_dynix (init): snmp_alarm_register failed.\n");
249 }
250 /*
251 * This is the one that runs update_stats every POLL_INTERVAL seconds
252 */
253 if (snmp_alarm_register(POLL_INTERVAL, SA_REPEAT, update_stats, NULL)
254 == 0) {
255 snmp_log(LOG_ERR,
256 "vmstat_dynix (init): snmp_alarm_register failed, cannot service requests.\n");
257 }
258
259} /* init_vmstat_dynix ends here */
260
261/*
262 * Data collection function take_snapshot starts here
263 */
264/*
265 * Get data from kernel and save into the snapshot strutcs
266 */
267/*
268 * Argument is the snapshot struct to save to. Global anyway, but looks nicer
269 */
270static int
271take_snapshot(struct cpu_stat_snapshot *css)
272{
273 /*
274 * Variables start here
275 */
276
277 /*
278 * Counters
279 */
280 unsigned int cpu_num = 0;
281
282 /*
283 * Low resolution time counter
284 */
285 time_t current_time;
286
287 /*
288 * see sys/sysperf.h, holds CPU data
289 */
290 exp_vmmeter_t *cs, *origcs = 0;
291
292 /*
293 * size of the cs struct
294 */
295 size_t vminfo_size;
296
297 /*
298 * The usual stuff to count on, err, by
299 */
300 int i;
301 int engnum = 0;
302
303 /*
304 * Variables end here
305 */
306
307 /*
308 * Function starts here
309 */
310
311 /*
312 * Get time
313 */
314 current_time = time(0);
315
316 /*
317 * If we have just gotten the data, return the values from last run (skip if-clause)
318 */
319 /*
320 * This happens on a snmpwalk request.
321 */
322 /*
323 * if we just did it less than 2 seconds ago
324 */
325 /*
326 * Jumps into if-clause either when snapshot is empty or when too old
327 */
328
329 if ((css->css_time == 0) || (current_time > css->css_time + 2)) {
330 /*
331 * Make sure we clean up before we put new data into snapshot
332 */
333 memset(css, 0, sizeof *css);
334
335 /*
336 * Get the number of CPUs we gather data from
337 */
338 if ((cpu_num = tmp_ctl(TMP_NENG, 0)) < 0) {
339 snmp_log(LOG_ERR,
340 "vmstat_dynix: (take snapshot) bad tmp_ctl return\n");
341 return (-1);
342 }
343 css->css_cpus = cpu_num;
344
345 vminfo_size = cpu_num * sizeof(exp_vmmeter_t);
346
347 if (!(cs = (exp_vmmeter_t *) malloc(vminfo_size))) {
348 snmp_log(LOG_ERR,
349 "vmstat_dynix: (take_snapshot) bad malloc return\n");
350 return (-1);
351 }
352 origcs = cs;
353
354 /*
355 * Update timer
356 */
357 css->css_time = current_time;
358
359 /*
360 * Read data from kernel into cs structure
361 */
362 /*
363 * cs is the buffer we are writing to and
364 */
365 /*
366 * vminfo_size is the size of the cs struct
367 */
368 if ((getkerndata(VMMETER_DATAID, cs, vminfo_size)) < 0) {
369 snmp_log(LOG_ERR,
370 "vmstat_dynix (take_snapshot): getkerndata failure.");
371 return (-1);
372 }
373
374 /*
375 * Get the data from each CPU
376 */
377 /*
378 * We walk through the whole vmmeter struct and sum up all the found stats,
379 */
380 /*
381 * there's one for every CPU in a machine
382 */
383 /*
384 * Okay... you can't laugh at this! I'm a C-hack, not a C-coder. :)
385 */
386 while (engnum < cpu_num) {
387
388 /*
389 * Get the data from the cs structure and sum it up in our own structure
390 */
391 css->css_swapin += (unsigned long long) cs->v_swpin;
392 css->css_swapout += (unsigned long long) cs->v_swpout;
393 css->css_blocks_read += (unsigned long long) cs->v_phread;
394 css->css_blocks_write += (unsigned long long) cs->v_phwrite;
395 css->css_interrupts += (unsigned long long) cs->v_intr;
396 css->css_context_sw += (unsigned long long) cs->v_swtch;
397
398 /*
399 * We need a for-loop for the CPU STATE values
400 */
401 for (i = 0; i < V_CPU_STATES; i++) {
402 css->css_cpu[i] += (unsigned long long) cs->v_time[i];
403 } /* end for */
404
405 cs++;
406 engnum++;
407 } /* end while */
408 }
409
410 free((void *) origcs);
411
412 /*
413 * All engines running at warp speed, no problems (if there are any engines, that is)
414 */
415 return (cpu_num > 0 ? 0 : -1);
416} /* take_snapshot ends here */
417
418/*
419 * This gets called every POLL_INTERVAL seconds to update the snapshots. It takes a new snapshot and
420 */
421/*
422 * drops the oldest one. This way we move the time window so we always take the values over
423 */
424/*
425 * POLL_INTERVAL * POLL_VALUES seconds and update the data used every POLL_INTERVAL seconds
426 */
427/*
428 * The alarm timer is in the init function of this module (snmp_alarm_register)
429 */
430/*
431 * ARGSUSED0
432 */
433static void
434update_stats(unsigned int registrationNumber, void *clientarg)
435{
436 /*
437 * The time between the samples we compare
438 */
439 time_t time_diff;
440
441 /*
442 * Easier to use these than the snapshots, short hand pointers
443 */
444 struct cpu_stat_snapshot *css_old, *css_new;
445
446 /*
447 * The usual stuff to count on, err, by
448 */
449 int i;
450
451 /*
452 * The sum of the CPU ticks that have passed on the different CPU states, so we can calculate
453 */
454 /*
455 * the percentages of each state
456 */
457 unsigned long long cpu_sum = 0;
458
459 DEBUGMSGTL(("ucd-snmp/vmstat_dynix.c:update_stats",
460 "updating stats\n"));
461
462 /*
463 * Take the current snapshot
464 */
465 if (take_snapshot(&snapshot[0]) == -1) {
466 snmp_log(LOG_WARNING,
467 "vmstat_dynix (update_stats): Something went wrong with take_snapshot.");
468 return;
469 }
470
471 /*
472 * Do we have some data we can use ? An issue right after the start of the agent
473 */
474 if (number_of_snapshots > 0) {
475 /*
476 * Huh, the number of CPUs changed during run time. That is indeed s.th. worth noting, we
477 */
478 /*
479 * output a humorous (more or less) syslog message and need to retake the snapshots
480 */
481 if (snapshot[0].css_cpus != snapshot[1].css_cpus) {
482 if (snapshot[0].css_cpus > snapshot[1].css_cpus) {
483 snmp_log(LOG_NOTICE,
484 "vmstat_dynix (update_stats): Cool ! Number of CPUs increased, must be hot-pluggable.");
485 } else {
486 snmp_log(LOG_NOTICE,
487 "vmstat_dynix (update_stats): Lost at least one CPU, RIP.");
488 }
489 /*
490 * Make all snapshots but the current one invalid
491 */
492 number_of_snapshots = 1;
493 /*
494 * Move the current one in the "first" [1] slot
495 */
496 memmove(&snapshot[1], &snapshot[0], sizeof snapshot[0]);
497 /*
498 * Erase the current one
499 */
500 memset(&snapshot[0], 0, sizeof snapshot[0]);
501 /*
502 * Try to get a new snapshot in five seconds so we can return s.th. useful
503 */
504 if (snmp_alarm_register(5, NULL, update_stats, NULL) == 0) {
505 snmp_log(LOG_WARNING,
506 "vmstat_dynix (update_stats): snmp_alarm_register failed.\n");
507 }
508 return;
509 }
510
511 /*
512 * Short hand pointers
513 */
514 css_new = &snapshot[0];
515 css_old = &snapshot[number_of_snapshots];
516
517 /*
518 * How much time has passed between the snapshots we get the values from ?
519 */
520 /*
521 * Time is in seconds
522 */
523 time_diff =
524 snapshot[0].css_time - snapshot[number_of_snapshots].css_time;
525
526 if (time_diff == 0)
527 DEBUGMSGTL(("ucd-snmp/vmstat_dynix.c:update_stats",
528 "time_diff is ZERO... watch for the segfault\n"));
529
530 DEBUGMSGTL(("ucd-snmp/vmstat_dynix.c:update_stats",
531 "time_diff: %lld\n", time_diff));
532
533 /*
534 * swapin and swapout are in pages, MIB wants kB/s,so we just need to get kB and seconds
535 */
536 /*
537 * For the others we need to get value per second
538 */
539 /*
540 * decided to use sysconf(_SC_PAGESIZE) instead to get around an #ifndef (I don't like those)
541 */
542 /*
543 * LINTED cast needed, really
544 */
545 swapin =
546 (uint_t) ((css_new->css_swapin -
547 css_old->css_swapin) * (time_t) 1000 *
548 sysconf(_SC_PAGESIZE) / 1024 / time_diff);
549 /*
550 * LINTED cast needed, really
551 */
552 swapout =
553 (uint_t) ((css_new->css_swapout -
554 css_old->css_swapout) * (time_t) 1000 *
555 sysconf(_SC_PAGESIZE) / 1024 / time_diff);
556 /*
557 * LINTED cast needed, really
558 */
559 blocks_read =
560 (uint_t) ((css_new->css_blocks_read -
561 css_old->css_blocks_read) * (time_t) 1000 /
562 time_diff);
563 /*
564 * LINTED cast needed, really
565 */
566 blocks_write =
567 (uint_t) ((css_new->css_blocks_write -
568 css_old->css_blocks_write) * (time_t) 1000 /
569 time_diff);
570 /*
571 * LINTED cast needed, really
572 */
573 interrupts =
574 (uint_t) ((css_new->css_interrupts -
575 css_old->css_interrupts) * (time_t) 1000 /
576 time_diff);
577 /*
578 * LINTED cast needed, really
579 */
580 context_sw =
581 (uint_t) ((css_new->css_context_sw -
582 css_old->css_context_sw) * (time_t) 1000 /
583 time_diff);
584
585 /*
586 * Loop thru all the V_CPU_STATES and get the differences
587 */
588 for (i = 0; i < V_CPU_STATES; i++) {
589 cpu_sum += (css_new->css_cpu[i] - css_old->css_cpu[i]);
590 }
591
592 /*
593 * Now calculate the absolute percentage values
594 */
595 /*
596 * Looks somewhat complicated sometimes but tries to get around using floats to increase speed
597 */
598 for (i = 0; i < V_CPU_STATES; i++) {
599 /*
600 * Since we don't return fractions we use + 0.5 to get between 99 and 101 percent adding the values
601 */
602 /*
603 * together, otherwise we would get less than 100 most of the time
604 */
605 /*
606 * LINTED has to be 'long'
607 */
608 cpu_perc[i] =
609 (long) (((css_new->css_cpu[i] -
610 css_old->css_cpu[i]) * 100 +
611 (cpu_sum / 2)) / cpu_sum);
612 }
613
614 /*
615 * As said before, MIB wants V_CPU_SYSTEM which is V_CPU_KERNEL + V_CPU_STREAM
616 */
617 /*
618 * LINTED has to be 'long'
619 */
620 cpu_perc[V_CPU_SYSTEM] =
621 (long) ((((css_new->css_cpu[V_CPU_KERNEL] -
622 css_old->css_cpu[V_CPU_KERNEL])
623 + (css_new->css_cpu[V_CPU_STREAM] -
624 css_old->css_cpu[V_CPU_STREAM]))
625 * 100 + (cpu_sum / 2)) / cpu_sum);
626 }
627
628 /*
629 * Make the current one the first one and move the whole thing one place down
630 */
631 memmove(&snapshot[1], &snapshot[0],
632 (size_t) (((char *) &snapshot[POLL_VALUES]) -
633 ((char *) &snapshot[0])));
634
635 /*
636 * Erase the current one
637 */
638 memset(&snapshot[0], 0, sizeof snapshot[0]);
639
640 /*
641 * Only important on start up, we keep track of how many snapshots we have taken so far
642 */
643 if (number_of_snapshots < POLL_VALUES) {
644 number_of_snapshots++;
645 }
646} /* update_stats ends here */
647
648/*
649 * *var_extensible_vmstat starts here
650 */
651/*
652 * The guts of the module, this routine gets called to service a request
653 */
Dave Shield9fbc4a32002-05-23 08:39:41 +0000654unsigned char *
Wes Hardaker6d1f6022002-04-20 07:08:20 +0000655var_extensible_vmstat(struct variable *vp,
656 oid * name,
657 size_t * length,
658 int exact,
659 size_t * var_len, WriteMethod ** write_method)
660{
661 /*
662 * Needed for returning the values
663 */
664 static long long_ret;
665 static char errmsg[300];
666
667 /*
668 * set to 0 as default
669 */
670 long_ret = 0;
671
672 /*
673 * generic check whether the options passed make sense and whether the
674 */
675 /*
676 * right variable is requested
677 */
678 if (header_generic(vp, name, length, exact, var_len, write_method) !=
679 MATCH_SUCCEEDED) {
680 return (NULL);
681 }
682
683 /*
684 * The function that actually returns s.th.
685 */
686 switch (vp->magic) {
687 case MIBINDEX:
688 long_ret = 1;
689 return ((u_char *) (&long_ret));
690 case ERRORNAME: /* dummy name */
691 sprintf(errmsg, "systemStats");
692 *var_len = strlen(errmsg);
693 return ((u_char *) (errmsg));
694 case SWAPIN:
695 return ((u_char *) (&swapin));
696 case SWAPOUT:
697 return ((u_char *) (&swapout));
698 case IOSENT:
699 return ((u_char *) (&blocks_write));
700 case IORECEIVE:
701 return ((u_char *) (&blocks_read));
702 case SYSINTERRUPTS:
703 return ((u_char *) (&interrupts));
704 case SYSCONTEXT:
705 return ((u_char *) (&context_sw));
706 case CPUUSER:
707 return ((u_char *) (&cpu_perc[V_CPU_USER]));
708 case CPUSYSTEM:
709 return ((u_char *) (&cpu_perc[V_CPU_SYSTEM]));
710 case CPUIDLE:
711 return ((u_char *) (&cpu_perc[V_CPU_IDLE]));
712 case CPURAWUSER:
713 take_snapshot(&raw_values);
714 /*
715 * LINTED has to be 'long'
716 */
717 long_ret =
718 (long) (raw_values.css_cpu[V_CPU_USER] / raw_values.css_cpus);
719 return ((u_char *) (&long_ret));
720 /*
721 * We are missing CPURAWNICE, Dynix does not account for this in the kernel so this OID can not
722 */
723 /*
724 * be returned. Also, these values will roll over sooner or later and then return inaccurate data
725 */
726 /*
727 * but the MIB wants Integer32 so we cannot put a counter here
728 */
729 /*
730 * (Has been changed to Counter32 in the latest MIB version!)
731 */
732 case CPURAWSYSTEM:
733 take_snapshot(&raw_values);
734 /*
735 * LINTED has to be 'long'
736 */
737 long_ret =
738 (long) ((raw_values.css_cpu[V_CPU_KERNEL] +
739 raw_values.css_cpu[V_CPU_STREAM]) /
740 raw_values.css_cpus);
741 return ((u_char *) (&long_ret));
742 case CPURAWIDLE:
743 take_snapshot(&raw_values);
744 /*
745 * LINTED has to be 'long'
746 */
747 long_ret =
748 (long) (raw_values.css_cpu[V_CPU_IDLE] / raw_values.css_cpus);
749 return ((u_char *) (&long_ret));
750 case CPURAWWAIT:
751 take_snapshot(&raw_values);
752 /*
753 * LINTED has to be 'long'
754 */
755 long_ret =
756 (long) (raw_values.css_cpu[V_CPU_STREAM] /
757 raw_values.css_cpus);
758 return ((u_char *) (&long_ret));
759 case CPURAWKERNEL:
760 take_snapshot(&raw_values);
761 /*
762 * LINTED has to be 'long'
763 */
764 long_ret =
765 (long) (raw_values.css_cpu[V_CPU_KERNEL] /
766 raw_values.css_cpus);
767 return ((u_char *) (&long_ret));
768 case IORAWSENT:
769 long_ret = (long) (raw_values.css_blocks_write);
770 return ((u_char *) (&long_ret));
771 case IORAWRECEIVE:
772 long_ret = (long) (raw_values.css_blocks_read);
773 return ((u_char *) (&long_ret));
774
775 /*
776 * reserved for future use
777 */
778 /*
779 * case ERRORFLAG:
780 * return((u_char *) (&long_ret));
781 * case ERRORMSG:
782 * return((u_char *) (&long_ret));
783 */
784 default:
785 snmp_log(LOG_ERR,
786 "vmstat_dynix: Error in request, no match found.\n");
787 }
788 return (NULL);
789} /* *var_extensible_vmstat ends here */
790
791/*
792 * Functions end here
793 */
794
795/*
796 * Program ends here
797 */