vmstat_netbsd1.c
上传用户:wxp200602
上传日期:2007-10-30
资源大小:4028k
文件大小:9k
源码类别:

SNMP编程

开发平台:

Unix_Linux

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