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

SNMP编程

开发平台:

Unix_Linux

  1. #include <net-snmp/net-snmp-config.h>   /* local SNMP configuration details */
  2. #if HAVE_STRING_H
  3. #include <string.h>
  4. #endif
  5. #if HAVE_STDLIB_H
  6. #include <stdlib.h>
  7. #endif
  8. #include <sys/types.h>
  9. #if HAVE_DMALLOC_H
  10. #include <dmalloc.h>
  11. #endif
  12. #include <net-snmp/net-snmp-includes.h>
  13. #include <net-snmp/agent/net-snmp-agent-includes.h>
  14. #include <net-snmp/agent/auto_nlist.h>
  15. #include "util_funcs.h"         /* utility function declarations */
  16. #include "memory.h"             /* the module-specific header */
  17. #include "memory_solaris2.h"    /* the module-specific header */
  18. #include <kstat.h>
  19. #include <sys/stat.h>
  20. #include <sys/swap.h>
  21. #include <unistd.h>
  22. #define MAXSTRSIZE 80
  23. int             minimumswap;
  24. static char     errmsg[1024];
  25. /****************************
  26.  * Kstat specific variables *
  27.  ****************************/
  28. extern kstat_ctl_t *kstat_fd;   /* defined in kernel_sunos5.c */
  29. kstat_t        *ksp1, *ksp2;
  30. kstat_named_t  *kn, *kn2;
  31. static FindVarMethod var_extensible_mem;
  32. static long     getFreeSwap(void);
  33. static long     getTotalFree(void);
  34. static long     getTotalSwap(void);
  35. void
  36. init_memory_solaris2(void)
  37. {
  38.     struct variable2 extensible_mem_variables[] = {
  39.         {MIBINDEX, ASN_INTEGER, RONLY, var_extensible_mem, 1, {MIBINDEX}},
  40.         {ERRORNAME, ASN_OCTET_STR, RONLY, var_extensible_mem, 1,
  41.          {ERRORNAME}},
  42.         {MEMTOTALSWAP, ASN_INTEGER, RONLY, var_extensible_mem, 1,
  43.          {MEMTOTALSWAP}},
  44.         {MEMAVAILSWAP, ASN_INTEGER, RONLY, var_extensible_mem, 1,
  45.          {MEMAVAILSWAP}},
  46.         {MEMTOTALREAL, ASN_INTEGER, RONLY, var_extensible_mem, 1,
  47.          {MEMTOTALREAL}},
  48.         {MEMAVAILREAL, ASN_INTEGER, RONLY, var_extensible_mem, 1,
  49.          {MEMAVAILREAL}},
  50.         {MEMTOTALSWAPTXT, ASN_INTEGER, RONLY, var_extensible_mem, 1,
  51.          {MEMTOTALSWAPTXT}},
  52.         {MEMUSEDSWAPTXT, ASN_INTEGER, RONLY, var_extensible_mem, 1,
  53.          {MEMUSEDSWAPTXT}},
  54.         {MEMTOTALREALTXT, ASN_INTEGER, RONLY, var_extensible_mem, 1,
  55.          {MEMTOTALREALTXT}},
  56.         {MEMUSEDREALTXT, ASN_INTEGER, RONLY, var_extensible_mem, 1,
  57.          {MEMUSEDREALTXT}},
  58.         {MEMTOTALFREE, ASN_INTEGER, RONLY, var_extensible_mem, 1,
  59.          {MEMTOTALFREE}},
  60.         {MEMSWAPMINIMUM, ASN_INTEGER, RONLY, var_extensible_mem, 1,
  61.          {MEMSWAPMINIMUM}},
  62.         {MEMSHARED, ASN_INTEGER, RONLY, var_extensible_mem, 1,
  63.          {MEMSHARED}},
  64.         {MEMBUFFER, ASN_INTEGER, RONLY, var_extensible_mem, 1,
  65.          {MEMBUFFER}},
  66.         {MEMCACHED, ASN_INTEGER, RONLY, var_extensible_mem, 1,
  67.          {MEMCACHED}},
  68.         {ERRORFLAG, ASN_INTEGER, RONLY, var_extensible_mem, 1,
  69.          {ERRORFLAG}},
  70.         {ERRORMSG, ASN_OCTET_STR, RONLY, var_extensible_mem, 1, {ERRORMSG}}
  71.     };
  72.     /*
  73.      * Define the OID pointer to the top of the mib tree that we're
  74.      * registering underneath 
  75.      */
  76.     oid             mem_variables_oid[] = { UCDAVIS_MIB, MEMMIBNUM };
  77.     /*
  78.      * register ourselves with the agent to handle our mib tree 
  79.      */
  80.     REGISTER_MIB("ucd-snmp/memory", extensible_mem_variables, variable2,
  81.                  mem_variables_oid);
  82.     snmpd_register_config_handler("swap", memory_parse_config,
  83.                                   memory_free_config, "min-avail");
  84.     if (kstat_fd == 0) {
  85.         kstat_fd = kstat_open();
  86.         if (kstat_fd == 0) {
  87.             snmp_log_perror("kstat_open");
  88.         }
  89.     }
  90. }
  91. static u_char  *
  92. var_extensible_mem(struct variable *vp,
  93.                    oid * name,
  94.                    size_t * length,
  95.                    int exact,
  96.                    size_t * var_len, WriteMethod ** write_method)
  97. {
  98.     static long     long_ret;
  99.     /*
  100.      * Initialize the return value to 0 
  101.      */
  102.     long_ret = 0;
  103.     if (header_generic(vp, name, length, exact, var_len, write_method))
  104.         return (NULL);
  105.     switch (vp->magic) {
  106.     case MIBINDEX:
  107.         long_ret = 0;
  108.         return ((u_char *) (&long_ret));
  109.     case ERRORNAME:            /* dummy name */
  110.         sprintf(errmsg, "swap");
  111.         *var_len = strlen(errmsg);
  112.         return ((u_char *) (errmsg));
  113.     case MEMTOTALSWAP:
  114.         long_ret = getTotalSwap() * (getpagesize() / 1024);
  115.         return ((u_char *) (&long_ret));
  116.     case MEMAVAILSWAP:
  117.         long_ret = getFreeSwap() * (getpagesize() / 1024);
  118.         return ((u_char *) (&long_ret));
  119.     case MEMSWAPMINIMUM:
  120.         long_ret = minimumswap;
  121.         return ((u_char *) (&long_ret));
  122.     case MEMTOTALREAL:
  123. #ifdef _SC_PHYS_PAGES
  124.         long_ret = sysconf(_SC_PHYS_PAGES) * (getpagesize()/1024);
  125. #else
  126.         ksp1 = kstat_lookup(kstat_fd, "unix", 0, "system_pages");
  127.         kstat_read(kstat_fd, ksp1, 0);
  128.         kn = kstat_data_lookup(ksp1, "physmem");
  129.         long_ret = kn->value.ul * (getpagesize() / 1024);
  130. #endif
  131.         return ((u_char *) (&long_ret));
  132.     case MEMAVAILREAL:
  133. #ifdef _SC_AVPHYS_PAGES
  134.         long_ret = sysconf(_SC_AVPHYS_PAGES) * (getpagesize()/1024);
  135. #else
  136.         long_ret =
  137.             (getTotalFree() - getFreeSwap()) * (getpagesize() / 1024);
  138. #endif
  139.         return ((u_char *) (&long_ret));
  140.     case MEMTOTALFREE:
  141.         long_ret = getTotalFree() * (getpagesize() / 1024);
  142.         return ((u_char *) (&long_ret));
  143.     case ERRORFLAG:
  144.         long_ret = getTotalFree() * (getpagesize() / 1024);
  145.         long_ret = (long_ret > minimumswap) ? 0 : 1;
  146.         return ((u_char *) (&long_ret));
  147.     case ERRORMSG:
  148.         long_ret = getTotalFree() * (getpagesize() / 1024);
  149.         if ((long_ret > minimumswap) ? 0 : 1)
  150.             sprintf(errmsg, "Running out of swap space (%ld)", long_ret);
  151.         else
  152.             errmsg[0] = 0;
  153.         *var_len = strlen(errmsg);
  154.         return ((u_char *) (errmsg));
  155.     }
  156.     return (NULL);
  157. }
  158. #define DEFAULTMINIMUMSWAP 16000        /* kilobytes */
  159. void
  160. memory_parse_config(const char *token, char *cptr)
  161. {
  162.     minimumswap = atoi(cptr);
  163. }
  164. void
  165. memory_free_config(void)
  166. {
  167.     minimumswap = DEFAULTMINIMUMSWAP;
  168. }
  169. long
  170. getTotalSwap(void)
  171. {
  172.     long            total_mem;
  173.     size_t          num;
  174.     int             i, n;
  175.     swaptbl_t      *s;
  176.     char           *strtab;
  177.     total_mem = 0;
  178.     num = swapctl(SC_GETNSWP, 0);
  179.     s = malloc(num * sizeof(swapent_t) + sizeof(struct swaptable));
  180.     if (s) {
  181.         strtab = (char *) malloc((num + 1) * MAXSTRSIZE);
  182.         if (strtab) {
  183.             for (i = 0; i < (num + 1); i++) {
  184.                 s->swt_ent[i].ste_path = strtab + (i * MAXSTRSIZE);
  185.             }
  186.             s->swt_n = num + 1;
  187.             n = swapctl(SC_LIST, s);
  188.             for (i = 0; i < n; i++)
  189.                 total_mem += s->swt_ent[i].ste_pages;
  190.             free(strtab);
  191.         }
  192.         free(s);
  193.     }
  194.     return (total_mem);
  195. }
  196. /*
  197.  * returns -1 if malloc fails.
  198.  */
  199. static long
  200. getFreeSwap(void)
  201. {
  202.     long            free_mem = -1;
  203.     size_t          num;
  204.     int             i, n;
  205.     swaptbl_t      *s;
  206.     char           *strtab;
  207.     num = swapctl(SC_GETNSWP, 0);
  208.     s = malloc(num * sizeof(swapent_t) + sizeof(struct swaptable));
  209.     if (s) {
  210.         strtab = (char *) malloc((num + 1) * MAXSTRSIZE);
  211.         if (strtab) {
  212.             free_mem = 0;
  213.             for (i = 0; i < (num + 1); i++) {
  214.                 s->swt_ent[i].ste_path = strtab + (i * MAXSTRSIZE);
  215.             }
  216.             s->swt_n = num + 1;
  217.             n = swapctl(SC_LIST, s);
  218.             for (i = 0; i < n; i++)
  219.                 free_mem += s->swt_ent[i].ste_free;
  220.             free(strtab);
  221.         }
  222.         free(s);
  223.     }
  224.     return (free_mem);
  225. }
  226. static long
  227. getTotalFree(void)
  228. {
  229.     unsigned long   free_mem, allocated, reserved, available, used_size;
  230.     struct anoninfo ai;
  231.     if (-1 == swapctl(SC_AINFO, &ai)) {
  232.         snmp_log_perror("swapctl(SC_AINFO)");
  233. return 0;
  234.     }
  235.     allocated = ai.ani_max - ai.ani_free;
  236.     reserved = (ai.ani_resv - allocated);
  237.     available = (ai.ani_max - ai.ani_resv);     /* K-byte */
  238.     free_mem = used_size = reserved + allocated;
  239.     free_mem = available;
  240.     return (free_mem);
  241. }