1 #include <net-snmp/net-snmp-config.h>
13 #if HAVE_MACHINE_PARAM_H
14 #include <machine/param.h>
17 #include <sys/param.h>
19 #if HAVE_SYS_VMMETER_H
20 #if !(defined(bsdi2) || defined(netbsd1))
21 #include <sys/vmmeter.h>
39 #ifdef HAVE_SYS_STAT_H
42 #ifdef HAVE_SYS_VNODE_H
43 #include <sys/vnode.h>
45 #ifdef HAVE_UFS_UFS_QUOTA_H
46 #include <ufs/ufs/quota.h>
48 #ifdef HAVE_UFS_UFS_INODE_H
49 #include <ufs/ufs/inode.h>
52 #include <ufs/ffs/fs.h>
65 #include <sys/statfs.h>
67 #if HAVE_SYS_STATVFS_H
68 #include <sys/statvfs.h>
73 #if (!defined(HAVE_STATVFS)) && defined(HAVE_STATFS)
75 #include <sys/mount.h>
78 #include <sys/sysctl.h>
80 #define statvfs statfs
85 #if HAVE_VM_SWAP_PAGER_H
86 #include <vm/swap_pager.h>
88 #if HAVE_SYS_FIXPOINT_H
89 #include <sys/fixpoint.h>
91 #if HAVE_SYS_LOADAVG_H
92 #include <sys/loadavg.h>
100 #if TIME_WITH_SYS_TIME
102 # include <sys/timeb.h>
104 # include <sys/time.h>
109 # include <sys/time.h>
118 #include <sys/mc_vmparam.h>
120 #if defined(hpux10) || defined(hpux11)
121 #include <sys/pstat.h>
124 #include <net-snmp/net-snmp-includes.h>
125 #include <net-snmp/agent/net-snmp-agent-includes.h>
126 #include <net-snmp/agent/auto_nlist.h>
130 #include "util_funcs.h"
140 * define the structure we're going to ask the agent to register our
143 struct variable2 extensible_loadave_variables[] = {
144 {MIBINDEX, ASN_INTEGER, RONLY, var_extensible_loadave, 1,
146 {ERRORNAME, ASN_OCTET_STR, RONLY, var_extensible_loadave, 1,
148 {LOADAVE, ASN_OCTET_STR, RONLY, var_extensible_loadave, 1,
150 {LOADMAXVAL, ASN_OCTET_STR, RONLY, var_extensible_loadave, 1,
152 {LOADAVEINT, ASN_INTEGER, RONLY, var_extensible_loadave, 1,
154 #ifdef OPAQUE_SPECIAL_TYPES
155 {LOADAVEFLOAT, ASN_OPAQUE_FLOAT, RONLY, var_extensible_loadave, 1,
158 {ERRORFLAG, ASN_INTEGER, RONLY, var_extensible_loadave, 1,
160 {ERRORMSG, ASN_OCTET_STR, RONLY, var_extensible_loadave, 1,
165 * Define the OID pointer to the top of the mib tree that we're
166 * registering underneath
168 oid loadave_variables_oid[] =
169 { UCDAVIS_MIB, LOADAVEMIBNUM, 1 };
172 * register ourselves with the agent to handle our mib tree
174 REGISTER_MIB("ucd-snmp/loadave", extensible_loadave_variables,
175 variable2, loadave_variables_oid);
177 snmpd_register_config_handler("load", loadave_parse_config,
179 "max1 [max5] [max15]");
183 loadave_parse_config(const char *token, char *cptr)
187 for (i = 0; i <= 2; i++) {
189 maxload[i] = atof(cptr);
191 maxload[i] = maxload[i - 1];
192 cptr = skip_not_white(cptr);
193 cptr = skip_white(cptr);
198 loadave_free_config(void)
202 for (i = 0; i <= 2; i++)
203 maxload[i] = DEFMAXLOADAVE;
207 * try to get load average
208 * Inputs: pointer to array of doubles, number of elements in array
209 * Returns: 0=array has values, -1=error occurred.
212 try_getloadavg(double *r_ave, size_t s_ave)
214 double *pave = r_ave;
215 #ifdef HAVE_SYS_FIXPOINT_H
218 #if (defined(ultrix) || defined(sun) || defined(__alpha) || defined(dynix))
220 #if (defined(sun) || defined(__alpha) || defined(dynix))
222 if (s_ave > 3) /* bounds check */
224 #define FIX_TO_DBL(_IN) (((double) _IN)/((double) FSCALE))
230 #if defined(hpux10) || defined(hpux11)
231 struct pst_dynamic pst_buf;
235 #ifdef HAVE_GETLOADAVG
236 if (getloadavg(pave, s_ave) == -1)
240 FILE *in = fopen("/proc/loadavg", "r");
242 snmp_log(LOG_ERR, "snmpd: cannot open /proc/loadavg\n");
245 fscanf(in, "%lf %lf %lf", pave, (pave + 1), (pave + 2));
248 #elif (defined(ultrix) || defined(sun) || defined(__alpha) || defined(dynix))
249 if (auto_nlist(LOADAVE_SYMBOL, (char *) favenrun, sizeof(favenrun)) ==
252 for (i = 0; i < s_ave; i++)
253 *(pave + i) = FIX_TO_DBL(favenrun[i]);
254 #elif defined(hpux10) || defined(hpux11)
255 if (pstat_getdynamic(&pst_buf, sizeof(struct pst_dynamic), 1, 0) < 0)
257 r_ave[0] = pst_buf.psd_avg_1_min;
258 r_ave[1] = pst_buf.psd_avg_5_min;
259 r_ave[2] = pst_buf.psd_avg_15_min;
260 #elif !defined(cygwin)
263 if (auto_nlist(LOADAVE_SYMBOL, (char *) favenrun, sizeof(favenrun)) ==
266 r_ave[0] = favenrun[0] / 65536.0;
267 r_ave[1] = favenrun[1] / 65536.0;
268 r_ave[2] = favenrun[2] / 65536.0;
271 if (auto_nlist(LOADAVE_SYMBOL, (char *) pave, sizeof(double) * s_ave)
279 * To calculate this, we need to compare
280 * successive values of the kernel array
281 * '_cp_times', and calculate the resulting
282 * percentage changes.
283 * This calculation needs to be performed
284 * regularly - perhaps as a background process.
286 * See the source to 'top' for full details.
288 * The linux SNMP HostRes implementation
289 * uses 'avenrun[0]*100' as an approximation.
290 * This is less than accurate, but has the
291 * advantage of being simple to implement!
293 * I'm also assuming a single processor
299 var_extensible_loadave(struct variable * vp,
303 size_t * var_len, WriteMethod ** write_method)
306 static long long_ret;
307 static float float_ret;
308 static char errmsg[300];
310 if (header_simple_table
311 (vp, name, length, exact, var_len, write_method, 3))
315 long_ret = name[*length - 1];
316 return ((u_char *) (&long_ret));
318 sprintf(errmsg, "Load-%d", ((name[*length - 1] == 1) ? 1 :
319 ((name[*length - 1] == 2) ? 5 : 15)));
320 *var_len = strlen(errmsg);
321 return ((u_char *) (errmsg));
323 if (try_getloadavg(&avenrun[0], sizeof(avenrun) / sizeof(avenrun[0]))
329 sprintf(errmsg, "%.2f", avenrun[name[*length - 1] - 1]);
330 *var_len = strlen(errmsg);
331 return ((u_char *) (errmsg));
333 sprintf(errmsg, "%.2f", maxload[name[*length - 1] - 1]);
334 *var_len = strlen(errmsg);
335 return ((u_char *) (errmsg));
337 long_ret = (u_long) (avenrun[name[*length - 1] - 1] * 100);
338 return ((u_char *) (&long_ret));
339 #ifdef OPAQUE_SPECIAL_TYPES
341 float_ret = (float) avenrun[name[*length - 1] - 1];
342 *var_len = sizeof(float_ret);
343 return ((u_char *) (&float_ret));
346 long_ret = (maxload[name[*length - 1] - 1] != 0 &&
347 avenrun[name[*length - 1] - 1] >=
348 maxload[name[*length - 1] - 1]) ? 1 : 0;
349 return ((u_char *) (&long_ret));
351 if (maxload[name[*length - 1] - 1] != 0 &&
352 avenrun[name[*length - 1] - 1] >=
353 maxload[name[*length - 1] - 1]) {
354 sprintf(errmsg, "%d min Load Average too high (= %.2f)",
355 (name[*length - 1] ==
356 1) ? 1 : ((name[*length - 1] == 2) ? 5 : 15),
357 avenrun[name[*length - 1] - 1]);
361 *var_len = strlen(errmsg);
362 return ((u_char *) errmsg);