5 #include <net-snmp/net-snmp-config.h>
9 * Ripped from /usr/scr/usr.bin/vmstat/vmstat.c (covering all bases)
11 #include <sys/param.h>
14 #include <sys/dkstat.h>
20 #include <sys/namei.h>
21 #include <sys/malloc.h>
22 #include <sys/signal.h>
23 #include <sys/fcntl.h>
24 #include <sys/ioctl.h>
25 #include <sys/sysctl.h>
26 #include <sys/vmmeter.h>
28 #if HAVE_SYS_VMPARAM_H
29 #include <sys/vmparam.h>
31 #include <vm/vm_param.h>
50 #include <net-snmp/net-snmp-includes.h>
51 #include <net-snmp/agent/net-snmp-agent-includes.h>
52 #include <net-snmp/agent/auto_nlist.h>
54 #include "util_funcs.h"
56 #include "memory_freebsd2.h"
61 #define SUM_SYMBOL "cnt"
63 #define BUFSPACE_SYMBOL "bufspace"
67 * Default swap warning limit (kb)
69 #define DEFAULTMINIMUMSWAP 16000
83 static FindVarMethod var_extensible_mem;
86 init_memory_freebsd2(void)
89 struct variable2 extensible_mem_variables[] = {
90 {MIBINDEX, ASN_INTEGER, RONLY, var_extensible_mem, 1, {MIBINDEX}},
91 {ERRORNAME, ASN_OCTET_STR, RONLY, var_extensible_mem, 1,
93 {MEMTOTALSWAP, ASN_INTEGER, RONLY, var_extensible_mem, 1,
95 {MEMAVAILSWAP, ASN_INTEGER, RONLY, var_extensible_mem, 1,
97 {MEMTOTALREAL, ASN_INTEGER, RONLY, var_extensible_mem, 1,
99 {MEMAVAILREAL, ASN_INTEGER, RONLY, var_extensible_mem, 1,
101 {MEMTOTALSWAPTXT, ASN_INTEGER, RONLY, var_extensible_mem, 1,
103 {MEMUSEDSWAPTXT, ASN_INTEGER, RONLY, var_extensible_mem, 1,
105 {MEMTOTALREALTXT, ASN_INTEGER, RONLY, var_extensible_mem, 1,
107 {MEMUSEDREALTXT, ASN_INTEGER, RONLY, var_extensible_mem, 1,
109 {MEMTOTALFREE, ASN_INTEGER, RONLY, var_extensible_mem, 1,
111 {MEMSWAPMINIMUM, ASN_INTEGER, RONLY, var_extensible_mem, 1,
113 {MEMSHARED, ASN_INTEGER, RONLY, var_extensible_mem, 1,
115 {MEMBUFFER, ASN_INTEGER, RONLY, var_extensible_mem, 1,
117 {MEMCACHED, ASN_INTEGER, RONLY, var_extensible_mem, 1,
119 {ERRORFLAG, ASN_INTEGER, RONLY, var_extensible_mem, 1,
121 {ERRORMSG, ASN_OCTET_STR, RONLY, var_extensible_mem, 1, {ERRORMSG}}
125 * Define the OID pointer to the top of the mib tree that we're
126 * registering underneath
128 oid mem_variables_oid[] = { UCDAVIS_MIB, MEMMIBNUM };
131 * register ourselves with the agent to handle our mib tree
133 REGISTER_MIB("ucd-snmp/memory", extensible_mem_variables, variable2,
136 snmpd_register_config_handler("swap", memory_parse_config,
137 memory_free_config, "min-avail");
142 memory_parse_config(const char *token, char *cptr)
144 minimumswap = atoi(cptr);
148 memory_free_config(void)
150 minimumswap = DEFAULTMINIMUMSWAP;
155 * Executes swapinfo and parses last line
158 * This is just way too ugly ;)
164 struct extensible ext;
168 strcpy(ext.command, "/usr/sbin/swapinfo -k");
170 if ((fd = get_exec_output(&ext)) != -1) {
171 file = fdopen(fd, "r");
173 while (fgets(ext.output, sizeof(ext.output), file) != NULL);
178 sscanf(ext.output, "%*s%*d%qd%qd", &swapUsed, &swapFree);
180 swapTotal = swapUsed + swapFree;
185 * swapmode is based on a program called swapinfo written
186 * by Kevin Lahey <kml@rokkaku.atl.ga.us>.
189 #include <sys/conf.h>
191 #define NSWDEV_SYMBOL "nswdev"
192 #define DMMAX_SYMBOL "dmmax"
193 #define SWDEVT_SYMBOL "swdevt"
198 int nswdev, dmmax, pagesize;
201 static kvm_t *kd = NULL;
202 struct kvm_swap kswap[16];
205 kd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, NULL);
207 auto_nlist(NSWDEV_SYMBOL, (char *) &nswdev, sizeof(nswdev));
208 auto_nlist(DMMAX_SYMBOL, (char *) &dmmax, sizeof(dmmax));
210 sw = (struct swdevt *) malloc(nswdev * sizeof(*sw));
214 auto_nlist(SWDEVT_SYMBOL, (char *) sw, nswdev * sizeof(*sw));
216 n = kvm_getswapinfo(kd, kswap, sizeof(kswap) / sizeof(kswap[0]), 0);
218 swapUsed = swapTotal = swapFree = 0;
220 * Count up free swap space.
222 for (i = 0; i < n; ++i)
223 swapFree += kswap[i].ksw_total - kswap[i].ksw_used;
226 * Count up total swap space
228 for (i = 0; i < n; i++)
229 swapTotal += kswap[i].ksw_total;
232 * Calculate used swap space
234 swapUsed = swapTotal - swapFree;
239 pagesize = getpagesize() / 1024;
241 swapTotal *= pagesize;
242 swapUsed *= pagesize;
243 swapFree *= pagesize;
251 * var_extensible_mem(...
253 * vp IN - pointer to variable entry that points here
254 * name IN/OUT - IN/name requested, OUT/name found
255 * length IN/OUT - length of IN/OUT oid's
256 * exact IN - TRUE if an exact match was requested
257 * var_len OUT - length of variable or 0 if function returned
262 static unsigned char *
263 var_extensible_mem(struct variable *vp,
267 size_t * var_len, WriteMethod ** write_method)
269 static long long_ret;
270 static char errmsg[300];
272 static struct vmmeter mem;
273 static struct vmtotal total;
274 size_t total_size = sizeof(total);
275 int total_mib[] = { CTL_VM, VM_METER };
278 size_t phys_mem_size = sizeof(phys_mem);
279 int phys_mem_mib[] = { CTL_HW, HW_USERMEM };
281 #ifdef BUFSPACE_SYMBOL
285 if (header_generic(vp, name, length, exact, var_len, write_method))
291 auto_nlist(SUM_SYMBOL, (char *) &mem, sizeof(mem));
292 sysctl(total_mib, 2, &total, &total_size, NULL, 0);
305 sysctl(phys_mem_mib, 2, &phys_mem, &phys_mem_size, NULL, 0);
307 #ifdef BUFSPACE_SYMBOL
311 auto_nlist(BUFSPACE_SYMBOL, (char *) &bufspace, sizeof(bufspace));
314 long_ret = 0; /* set to 0 as default */
319 #define ptok(p) ((p) * (mem.v_page_size >> 10))
324 return ((u_char *) (&long_ret));
325 case ERRORNAME: /* dummy name */
326 sprintf(errmsg, "swap");
327 *var_len = strlen(errmsg);
328 return ((u_char *) (errmsg));
330 long_ret = swapTotal;
331 return ((u_char *) (&long_ret));
332 case MEMAVAILSWAP: /* FREE swap memory */
334 return ((u_char *) (&long_ret));
336 long_ret = phys_mem >> 10;
337 return ((u_char *) (&long_ret));
338 case MEMAVAILREAL: /* FREE real memory */
339 long_ret = ptok(mem.v_free_count);
340 return ((u_char *) (&long_ret));
343 * these are not implemented
345 case MEMTOTALSWAPTXT:
347 case MEMTOTALREALTXT:
353 return ((u_char *) (&long_ret));
356 long_ret = ptok((int) total.t_free);
357 return ((u_char *) (&long_ret));
359 long_ret = minimumswap;
360 return ((u_char *) (&long_ret));
362 long_ret = ptok(total.t_vmshr +
363 total.t_avmshr + total.t_rmshr + total.t_armshr);
364 return ((u_char *) (&long_ret));
365 #ifdef BUFSPACE_SYMBOL
367 long_ret = bufspace >> 10;
368 return ((u_char *) (&long_ret));
373 long_ret = ptok(mem.v_lookups);
375 long_ret = ptok(mem.v_cache_count);
377 return ((u_char *) (&long_ret));
380 long_ret = (swapFree > minimumswap) ? 0 : 1;
381 return ((u_char *) (&long_ret));
383 if (swapFree < minimumswap)
384 sprintf(errmsg, "Running out of swap space (%qd)", swapFree);
387 *var_len = strlen(errmsg);
388 return ((u_char *) (errmsg));