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

SNMP编程

开发平台:

Unix_Linux

  1. /*
  2.  * memory_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. #include <sys/dkstat.h>
  12. #ifdef freebsd5
  13. #include <sys/bio.h>
  14. #endif
  15. #include <sys/buf.h>
  16. #include <sys/uio.h>
  17. #include <sys/namei.h>
  18. #include <sys/malloc.h>
  19. #include <sys/signal.h>
  20. #include <sys/fcntl.h>
  21. #include <sys/ioctl.h>
  22. #include <sys/sysctl.h>
  23. #include <sys/vmmeter.h>
  24. #if HAVE_SYS_VMPARAM_H
  25. #include <sys/vmparam.h>
  26. #else
  27. #include <vm/vm_param.h>
  28. #endif
  29. #include <time.h>
  30. #include <nlist.h>
  31. #include <kvm.h>
  32. #include <errno.h>
  33. #include <unistd.h>
  34. #include <stdio.h>
  35. #include <ctype.h>
  36. #include <stdlib.h>
  37. #include <string.h>
  38. #include <paths.h>
  39. #include <limits.h>
  40. #if HAVE_DMALLOC_H
  41. #include <dmalloc.h>
  42. #endif
  43. #include <net-snmp/net-snmp-includes.h>
  44. #include <net-snmp/agent/net-snmp-agent-includes.h>
  45. #include <net-snmp/agent/auto_nlist.h>
  46. #include "util_funcs.h"
  47. #include "memory.h"
  48. #include "memory_freebsd2.h"
  49. /*
  50.  * nlist symbols 
  51.  */
  52. #define SUM_SYMBOL      "cnt"
  53. #ifndef openbsd2
  54. #define BUFSPACE_SYMBOL "bufspace"
  55. #endif
  56. /*
  57.  * Default swap warning limit (kb) 
  58.  */
  59. #define DEFAULTMINIMUMSWAP 16000
  60. /*
  61.  * Swap warning limit 
  62.  */
  63. long            minimumswap;
  64. /*
  65.  * Swap info 
  66.  */
  67. quad_t          swapTotal;
  68. quad_t          swapUsed;
  69. quad_t          swapFree;
  70. static FindVarMethod var_extensible_mem;
  71. void
  72. init_memory_freebsd2(void)
  73. {
  74.     struct variable2 extensible_mem_variables[] = {
  75.         {MIBINDEX, ASN_INTEGER, RONLY, var_extensible_mem, 1, {MIBINDEX}},
  76.         {ERRORNAME, ASN_OCTET_STR, RONLY, var_extensible_mem, 1,
  77.          {ERRORNAME}},
  78.         {MEMTOTALSWAP, ASN_INTEGER, RONLY, var_extensible_mem, 1,
  79.          {MEMTOTALSWAP}},
  80.         {MEMAVAILSWAP, ASN_INTEGER, RONLY, var_extensible_mem, 1,
  81.          {MEMAVAILSWAP}},
  82.         {MEMTOTALREAL, ASN_INTEGER, RONLY, var_extensible_mem, 1,
  83.          {MEMTOTALREAL}},
  84.         {MEMAVAILREAL, ASN_INTEGER, RONLY, var_extensible_mem, 1,
  85.          {MEMAVAILREAL}},
  86.         {MEMTOTALSWAPTXT, ASN_INTEGER, RONLY, var_extensible_mem, 1,
  87.          {MEMTOTALSWAPTXT}},
  88.         {MEMUSEDSWAPTXT, ASN_INTEGER, RONLY, var_extensible_mem, 1,
  89.          {MEMUSEDSWAPTXT}},
  90.         {MEMTOTALREALTXT, ASN_INTEGER, RONLY, var_extensible_mem, 1,
  91.          {MEMTOTALREALTXT}},
  92.         {MEMUSEDREALTXT, ASN_INTEGER, RONLY, var_extensible_mem, 1,
  93.          {MEMUSEDREALTXT}},
  94.         {MEMTOTALFREE, ASN_INTEGER, RONLY, var_extensible_mem, 1,
  95.          {MEMTOTALFREE}},
  96.         {MEMSWAPMINIMUM, ASN_INTEGER, RONLY, var_extensible_mem, 1,
  97.          {MEMSWAPMINIMUM}},
  98.         {MEMSHARED, ASN_INTEGER, RONLY, var_extensible_mem, 1,
  99.          {MEMSHARED}},
  100.         {MEMBUFFER, ASN_INTEGER, RONLY, var_extensible_mem, 1,
  101.          {MEMBUFFER}},
  102.         {MEMCACHED, ASN_INTEGER, RONLY, var_extensible_mem, 1,
  103.          {MEMCACHED}},
  104.         {ERRORFLAG, ASN_INTEGER, RONLY, var_extensible_mem, 1,
  105.          {ERRORFLAG}},
  106.         {ERRORMSG, ASN_OCTET_STR, RONLY, var_extensible_mem, 1, {ERRORMSG}}
  107.     };
  108.     /*
  109.      * Define the OID pointer to the top of the mib tree that we're
  110.      * registering underneath 
  111.      */
  112.     oid             mem_variables_oid[] = { UCDAVIS_MIB, MEMMIBNUM };
  113.     /*
  114.      * register ourselves with the agent to handle our mib tree 
  115.      */
  116.     REGISTER_MIB("ucd-snmp/memory", extensible_mem_variables, variable2,
  117.                  mem_variables_oid);
  118.     snmpd_register_config_handler("swap", memory_parse_config,
  119.                                   memory_free_config, "min-avail");
  120. }
  121. void
  122. memory_parse_config(const char *token, char *cptr)
  123. {
  124.     minimumswap = atoi(cptr);
  125. }
  126. void
  127. memory_free_config(void)
  128. {
  129.     minimumswap = DEFAULTMINIMUMSWAP;
  130. }
  131. #ifndef freebsd4
  132. /*
  133.  * Executes swapinfo and parses last line 
  134.  */
  135. /*
  136.  * This is just way too ugly ;) 
  137.  */
  138. void
  139. swapmode(void)
  140. {
  141.     struct extensible ext;
  142.     int             fd;
  143.     FILE           *file;
  144.     strcpy(ext.command, "/usr/sbin/swapinfo -k");
  145.     if ((fd = get_exec_output(&ext)) != -1) {
  146.         file = fdopen(fd, "r");
  147.         while (fgets(ext.output, sizeof(ext.output), file) != NULL);
  148.         fclose(file);
  149.         wait_on_exec(&ext);
  150.         sscanf(ext.output, "%*s%*d%qd%qd", &swapUsed, &swapFree);
  151.         swapTotal = swapUsed + swapFree;
  152.     }
  153. }
  154. #else
  155. /*
  156.  * swapmode is based on a program called swapinfo written
  157.  * by Kevin Lahey <kml@rokkaku.atl.ga.us>.
  158.  */
  159. #include <sys/conf.h>
  160. void
  161. swapmode(void)
  162. {
  163.     int             pagesize;
  164.     int             i, n;
  165.     static kvm_t   *kd = NULL;
  166.     struct kvm_swap kswap[16];
  167.     if (kd == NULL)
  168.         kd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, NULL);
  169.     n = kvm_getswapinfo(kd, kswap, sizeof(kswap) / sizeof(kswap[0]), 0);
  170.     swapUsed = swapTotal = swapFree = 0;
  171.     /*
  172.      * Count up free swap space. 
  173.      */
  174.     for (i = 0; i < n; ++i)
  175.         swapFree += kswap[i].ksw_total - kswap[i].ksw_used;
  176.     /*
  177.      * Count up total swap space 
  178.      */
  179.     for (i = 0; i < n; i++)
  180.         swapTotal += kswap[i].ksw_total;
  181.     /*
  182.      * Calculate used swap space 
  183.      */
  184.     swapUsed = swapTotal - swapFree;
  185.     /*
  186.      * Convert to kb 
  187.      */
  188.     pagesize = getpagesize() / 1024;
  189.     swapTotal *= pagesize;
  190.     swapUsed *= pagesize;
  191.     swapFree *= pagesize;
  192. }
  193. #endif
  194. /*
  195.  * var_extensible_mem(...
  196.  * Arguments:
  197.  * vp     IN      - pointer to variable entry that points here
  198.  * name    IN/OUT  - IN/name requested, OUT/name found
  199.  * length  IN/OUT  - length of IN/OUT oid's 
  200.  * exact   IN      - TRUE if an exact match was requested
  201.  * var_len OUT     - length of variable or 0 if function returned
  202.  * write_method
  203.  * 
  204.  */
  205. static unsigned char *
  206. var_extensible_mem(struct variable *vp,
  207.                    oid * name,
  208.                    size_t * length,
  209.                    int exact,
  210.                    size_t * var_len, WriteMethod ** write_method)
  211. {
  212.     static long     long_ret;
  213.     static char     errmsg[1024];
  214.     static struct vmmeter mem;
  215.     static struct vmtotal total;
  216.     size_t          total_size = sizeof(total);
  217.     int             total_mib[] = { CTL_VM, VM_METER };
  218.     u_long          phys_mem;
  219.     size_t          phys_mem_size = sizeof(phys_mem);
  220.     int             phys_mem_mib[] = { CTL_HW, HW_USERMEM };
  221. #ifdef BUFSPACE_SYMBOL
  222.     long            bufspace;
  223. #endif
  224.     if (header_generic(vp, name, length, exact, var_len, write_method))
  225.         return (NULL);
  226.     /*
  227.      * Memory info 
  228.      */
  229.     auto_nlist(SUM_SYMBOL, (char *) &mem, sizeof(mem));
  230.     sysctl(total_mib, 2, &total, &total_size, NULL, 0);
  231.     /*
  232.      * Swap info 
  233.      */
  234.     swapmode();
  235.     /*
  236.      * getSwap(); 
  237.      */
  238.     /*
  239.      * Physical memory 
  240.      */
  241.     sysctl(phys_mem_mib, 2, &phys_mem, &phys_mem_size, NULL, 0);
  242. #ifdef BUFSPACE_SYMBOL
  243.     /*
  244.      * Buffer space 
  245.      */
  246.     auto_nlist(BUFSPACE_SYMBOL, (char *) &bufspace, sizeof(bufspace));
  247. #endif
  248.     long_ret = 0;               /* set to 0 as default */
  249.     /*
  250.      * Page-to-kb macro 
  251.      */
  252. #define ptok(p) ((p) * (mem.v_page_size >> 10))
  253.     switch (vp->magic) {
  254.     case MIBINDEX:
  255.         long_ret = 0;
  256.         return ((u_char *) (&long_ret));
  257.     case ERRORNAME:            /* dummy name */
  258.         sprintf(errmsg, "swap");
  259.         *var_len = strlen(errmsg);
  260.         return ((u_char *) (errmsg));
  261.     case MEMTOTALSWAP:
  262.         long_ret = swapTotal;
  263.         return ((u_char *) (&long_ret));
  264.     case MEMAVAILSWAP:         /* FREE swap memory */
  265.         long_ret = swapFree;
  266.         return ((u_char *) (&long_ret));
  267.     case MEMTOTALREAL:
  268.         long_ret = phys_mem >> 10;
  269.         return ((u_char *) (&long_ret));
  270.     case MEMAVAILREAL:         /* FREE real memory */
  271.         long_ret = ptok(mem.v_free_count);
  272.         return ((u_char *) (&long_ret));
  273.         /*
  274.          * these are not implemented 
  275.          */
  276.     case MEMTOTALSWAPTXT:
  277.     case MEMUSEDSWAPTXT:
  278.     case MEMTOTALREALTXT:
  279.     case MEMUSEDREALTXT:
  280. #if NO_DUMMY_VALUES
  281.         return NULL;
  282. #endif
  283.         long_ret = -1;
  284.         return ((u_char *) (&long_ret));
  285.     case MEMTOTALFREE:
  286.         long_ret = ptok((int) total.t_free);
  287.         return ((u_char *) (&long_ret));
  288.     case MEMSWAPMINIMUM:
  289.         long_ret = minimumswap;
  290.         return ((u_char *) (&long_ret));
  291.     case MEMSHARED:
  292.         long_ret = ptok(total.t_vmshr +
  293.                         total.t_avmshr + total.t_rmshr + total.t_armshr);
  294.         return ((u_char *) (&long_ret));
  295. #ifdef BUFSPACE_SYMBOL
  296.     case MEMBUFFER:
  297.         long_ret = bufspace >> 10;
  298.         return ((u_char *) (&long_ret));
  299. #endif
  300. #ifndef openbsd2
  301.     case MEMCACHED:
  302. #ifdef darwin
  303.         long_ret = ptok(mem.v_lookups);
  304. #else
  305.         long_ret = ptok(mem.v_cache_count);
  306. #endif
  307.         return ((u_char *) (&long_ret));
  308. #endif
  309.     case ERRORFLAG:
  310.         long_ret = (swapFree > minimumswap) ? 0 : 1;
  311.         return ((u_char *) (&long_ret));
  312.     case ERRORMSG:
  313.         if (swapFree < minimumswap)
  314.             sprintf(errmsg, "Running out of swap space (%qd)", swapFree);
  315.         else
  316.             errmsg[0] = 0;
  317.         *var_len = strlen(errmsg);
  318.         return ((u_char *) (errmsg));
  319.     }
  320.     return NULL;
  321. }