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

SNMP编程

开发平台:

Unix_Linux

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