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