2 * Host Resources MIB - storage group implementation - hr_storage.c
6 #include <net-snmp/net-snmp-config.h>
12 #if TIME_WITH_SYS_TIME
14 # include <sys/timeb.h>
16 # include <sys/time.h>
21 # include <sys/time.h>
29 #if (!defined(KERNEL) || defined(MACH_USER_API)) && defined(HAVE_SYS_VMMETER_H) /*OS X does not #include <sys/vmmeter.h> if (defined(KERNEL) && !defined(MACH_USER_API)) */
30 #include <sys/vmmeter.h>
35 #if HAVE_MACHINE_TYPES_H
36 #include <machine/types.h>
38 #if HAVE_SYS_VMMETER_H
39 #include <sys/vmmeter.h>
41 #if HAVE_VM_VM_PARAM_H
42 #include <vm/vm_param.h>
45 #if HAVE_SYS_VMPARAM_H
46 #include <sys/vmparam.h>
49 #include <sys/vmmac.h>
51 #if HAVE_SYS_VMMETER_H
52 #include <sys/vmmeter.h>
54 #if HAVE_SYS_VMSYSTM_H
55 #include <sys/vmsystm.h>
60 #if defined(MBPOOL_SYMBOL) && defined(MCLPOOL_SYMBOL)
64 #undef HAVE_SYS_POOL_H
71 #include <sys/sysctl.h>
72 #if defined(CTL_HW) && defined(HW_PAGESIZE)
75 #if defined(CTL_VM) && defined(VM_METER)
79 #endif /* ifndef dynix */
82 #include "hr_storage.h"
83 #include "hr_filesys.h"
84 #include <net-snmp/agent/auto_nlist.h>
90 #include <sys/mnttab.h>
92 #if HAVE_SYS_STATVFS_H
93 #include <sys/statvfs.h>
103 #include <sys/mount.h>
105 #ifdef HAVE_MACHINE_PARAM_H
106 #include <machine/param.h>
108 #include <sys/stat.h>
110 #if defined(hpux10) || defined(hpux11)
111 #include <sys/pstat.h>
113 #if defined(solaris2)
115 #include <sys/swap.h>
125 #include <net-snmp/utilities.h>
126 #include <net-snmp/output_api.h>
129 #include "kernel_sunos5.h"
132 #include <net-snmp/agent/agent_read_config.h>
133 #include <net-snmp/library/read_config.h>
135 #define HRSTORE_MONOTONICALLY_INCREASING
137 /*********************
139 * Kernel & interface information,
140 * and internal forward declarations
142 *********************/
147 extern struct mnttab *HRFS_entry;
148 #define HRFS_mount mnt_mountp
149 #define HRFS_statfs statvfs
151 #elif defined(HAVE_STATVFS)
153 extern struct mntent *HRFS_entry;
155 #define HRFS_statfs statvfs
156 #define HRFS_mount mnt_dir
158 #elif defined(HAVE_GETFSSTAT)
160 extern struct statfs *HRFS_entry;
162 #define HRFS_statfs statfs
163 #define HRFS_mount f_mntonname
167 extern struct mntent *HRFS_entry;
168 #define HRFS_mount mnt_dir
169 #define HRFS_statfs statfs
173 static int physmem, pagesize;
174 static void parse_storage_config(const char *, char *);
176 /*********************
178 * Initialisation & common implementation functions
180 *********************/
181 int Get_Next_HR_Store(void);
182 void Init_HR_Store(void);
183 int header_hrstore(struct variable *, oid *, size_t *, int,
184 size_t *, WriteMethod **);
185 int header_hrstoreEntry(struct variable *, oid *, size_t *,
186 int, size_t *, WriteMethod **);
189 int linux_mem(int, int);
193 void sol_get_swapinfo(int *, int *);
196 #define HRSTORE_MEMSIZE 1
197 #define HRSTORE_INDEX 2
198 #define HRSTORE_TYPE 3
199 #define HRSTORE_DESCR 4
200 #define HRSTORE_UNITS 5
201 #define HRSTORE_SIZE 6
202 #define HRSTORE_USED 7
203 #define HRSTORE_FAILS 8
205 struct variable4 hrstore_variables[] = {
206 {HRSTORE_MEMSIZE, ASN_INTEGER, RONLY, var_hrstore, 1, {2}},
207 {HRSTORE_INDEX, ASN_INTEGER, RONLY, var_hrstore, 3, {3, 1, 1}},
208 {HRSTORE_TYPE, ASN_OBJECT_ID, RONLY, var_hrstore, 3, {3, 1, 2}},
209 {HRSTORE_DESCR, ASN_OCTET_STR, RONLY, var_hrstore, 3, {3, 1, 3}},
210 {HRSTORE_UNITS, ASN_INTEGER, RONLY, var_hrstore, 3, {3, 1, 4}},
211 {HRSTORE_SIZE, ASN_INTEGER, RONLY, var_hrstore, 3, {3, 1, 5}},
212 {HRSTORE_USED, ASN_INTEGER, RONLY, var_hrstore, 3, {3, 1, 6}},
213 {HRSTORE_FAILS, ASN_COUNTER, RONLY, var_hrstore, 3, {3, 1, 7}}
215 oid hrstore_variables_oid[] = { 1, 3, 6, 1, 2, 1, 25, 2 };
219 init_hr_storage(void)
224 #elif defined(hpux10) || defined(hpux11)
225 struct pst_static pst_buf;
231 len = sizeof(physmem);
232 if (sysctl(mib, 2, &physmem, &len, NULL, 0) == -1)
233 snmp_log_perror("sysctl: physmem");
234 mib[1] = HW_PAGESIZE;
235 len = sizeof(pagesize);
236 if (sysctl(mib, 2, &pagesize, &len, NULL, 0) == -1)
237 snmp_log_perror("sysctl: pagesize");
239 #elif defined(hpux10) || defined(hpux11)
240 if (pstat_getstatic(&pst_buf, sizeof(struct pst_static), 1, 0) < 0) {
241 perror("pstat_getstatic");
243 physmem = pst_buf.physical_memory;
244 pagesize = pst_buf.page_size;
246 #else /* !USE_SYSCTL && !hpux10 && !hpux11 */
247 #ifdef HAVE_GETPAGESIZE
248 pagesize = getpagesize();
249 #elif defined(_SC_PAGESIZE)
250 pagesize = sysconf(_SC_PAGESIZE);
251 #elif defined(PGSHIFT)
252 pagesize = 1 << PGSHIFT;
253 #elif defined(PAGE_SHIFT)
254 pagesize = 1 << PAGE_SHIFT;
255 #elif defined(PAGE_SIZE)
256 pagesize = PAGE_SIZE;
260 stat("/proc/kcore", &kc_buf);
261 pagesize = kc_buf.st_size / 1024; /* 4K too large ? */
266 #ifdef _SC_PHYS_PAGES
267 physmem = sysconf(_SC_PHYS_PAGES);
270 physmem = sysconf(_SC_PHYSMEM);
272 auto_nlist(PHYSMEM_SYMBOL, (char *) &physmem, sizeof(physmem));
275 #endif /* !USE_SYSCTL && !hpux10 && !hpux11 */
276 #ifdef TOTAL_MEMORY_SYMBOL
277 auto_nlist(TOTAL_MEMORY_SYMBOL, 0, 0);
280 auto_nlist(MBSTAT_SYMBOL, 0, 0);
283 REGISTER_MIB("host/hr_storage", hrstore_variables, variable4,
284 hrstore_variables_oid);
286 snmpd_register_config_handler("storageUseNFS", parse_storage_config, NULL,
287 "1 | 2\t\t(1 = enable, 2 = disable)");
290 static int storageUseNFS = 0; /* initially disabled */
293 parse_storage_config(const char *token, char *cptr)
298 val = strtok(cptr, " \t");
300 config_perror("Missing FLAG parameter in storageUseNFS");
304 if (ival < 1 || ival > 2) {
305 config_perror("storageUseNFS must be 1 or 2");
308 storageUseNFS = (ival == 1) ? 1 : 0;
314 * vp IN - pointer to variable entry that points here
315 * name IN/OUT - IN/name requested, OUT/name found
316 * length IN/OUT - length of IN/OUT oid's
317 * exact IN - TRUE if an exact match was requested
318 * var_len OUT - length of variable or 0 if function returned
324 header_hrstore(struct variable *vp,
327 int exact, size_t * var_len, WriteMethod ** write_method)
329 #define HRSTORE_NAME_LENGTH 9
330 oid newname[MAX_OID_LEN];
333 DEBUGMSGTL(("host/hr_storage", "var_hrstore: "));
334 DEBUGMSGOID(("host/hr_storage", name, *length));
335 DEBUGMSG(("host/hr_storage", " %d\n", exact));
337 memcpy((char *) newname, (char *) vp->name, vp->namelen * sizeof(oid));
338 newname[HRSTORE_NAME_LENGTH] = 0;
339 result = snmp_oid_compare(name, *length, newname, vp->namelen + 1);
340 if ((exact && (result != 0)) || (!exact && (result >= 0)))
341 return (MATCH_FAILED);
342 memcpy((char *) name, (char *) newname,
343 (vp->namelen + 1) * sizeof(oid));
344 *length = vp->namelen + 1;
347 *var_len = sizeof(long); /* default to 'long' results */
348 return (MATCH_SUCCEEDED);
352 header_hrstoreEntry(struct variable *vp,
356 size_t * var_len, WriteMethod ** write_method)
358 #define HRSTORE_ENTRY_NAME_LENGTH 11
359 oid newname[MAX_OID_LEN];
360 int storage_idx, LowIndex = -1;
363 DEBUGMSGTL(("host/hr_storage", "var_hrstoreEntry: "));
364 DEBUGMSGOID(("host/hr_storage", name, *length));
365 DEBUGMSG(("host/hr_storage", " %d\n", exact));
367 memcpy((char *) newname, (char *) vp->name,
368 (int) vp->namelen * sizeof(oid));
370 * Find "next" storage entry
375 storage_idx = Get_Next_HR_Store();
376 DEBUGMSG(("host/hr_storage", "(index %d ....", storage_idx));
377 if (storage_idx == -1)
379 newname[HRSTORE_ENTRY_NAME_LENGTH] = storage_idx;
380 DEBUGMSGOID(("host/hr_storage", newname, *length));
381 DEBUGMSG(("host/hr_storage", "\n"));
382 result = snmp_oid_compare(name, *length, newname, vp->namelen + 1);
383 if (exact && (result == 0)) {
384 LowIndex = storage_idx;
386 * Save storage status information
390 if ((!exact && (result < 0)) &&
391 (LowIndex == -1 || storage_idx < LowIndex)) {
392 LowIndex = storage_idx;
394 * Save storage status information
396 #ifdef HRSTORE_MONOTONICALLY_INCREASING
402 if (LowIndex == -1) {
403 DEBUGMSGTL(("host/hr_storage", "... index out of range\n"));
404 return (MATCH_FAILED);
407 memcpy((char *) name, (char *) newname,
408 ((int) vp->namelen + 1) * sizeof(oid));
409 *length = vp->namelen + 1;
411 *var_len = sizeof(long); /* default to 'long' results */
413 DEBUGMSGTL(("host/hr_storage", "... get storage stats "));
414 DEBUGMSGOID(("host/hr_storage", name, *length));
415 DEBUGMSG(("host/hr_storage", "\n"));
419 oid storage_type_id[] = { 1, 3, 6, 1, 2, 1, 25, 2, 1, 1 }; /* hrStorageOther */
420 int storage_type_len =
421 sizeof(storage_type_id) / sizeof(storage_type_id[0]);
423 /*********************
425 * System specific implementation functions
427 *********************/
429 static const char *hrs_descr[] = {
431 "Real Memory", /* HRS_TYPE_MEM */
432 "Swap Space", /* HRS_TYPE_SWAP */
433 "Memory Buffers" /* HRS_TYPE_MBUF */
439 var_hrstore(struct variable *vp,
442 int exact, size_t * var_len, WriteMethod ** write_method)
446 #if defined(solaris2)
448 int swap_total, swap_used;
449 #elif defined(hpux10) || defined(hpux11)
450 struct pst_dynamic pst_buf;
451 #elif defined(TOTAL_MEMORY_SYMBOL) || defined(USE_SYSCTL_VM)
452 struct vmtotal memory_totals;
455 struct pool mbpool, mclpool;
459 struct mbstat mbstat;
462 static char string[100];
463 struct HRFS_statfs stat_buf;
465 if (vp->magic == HRSTORE_MEMSIZE) {
466 if (header_hrstore(vp, name, length, exact, var_len, write_method)
472 header_hrstoreEntry(vp, name, length, exact, var_len,
474 if (store_idx == MATCH_FAILED)
477 if (store_idx < HRS_TYPE_FS_MAX) {
478 if (HRFS_statfs(HRFS_entry->HRFS_mount, &stat_buf) < 0)
481 #if !defined(linux) && !defined(solaris2)
489 size_t len = sizeof(memory_totals);
492 sysctl(mib, 2, &memory_totals, &len, NULL, 0);
494 #elif defined(hpux10) || defined(hpux11)
495 pstat_getdynamic(&pst_buf, sizeof(struct pst_dynamic), 1, 0);
496 #elif defined(TOTAL_MEMORY_SYMBOL)
497 auto_nlist(TOTAL_MEMORY_SYMBOL, (char *) &memory_totals,
498 sizeof(struct vmtotal));
501 #if !defined(hpux10) && !defined(hpux11)
504 auto_nlist(MBPOOL_SYMBOL, (char *) &mbpool,
506 auto_nlist(MCLPOOL_SYMBOL, (char *) &mclpool,
510 auto_nlist(MBSTAT_SYMBOL, (char *) &mbstat,
514 #endif /* !hpux10 && !hpux11 */
518 #endif /* !linux && !solaris2 */
524 case HRSTORE_MEMSIZE:
525 long_return = physmem * (pagesize / 1024);
526 return (u_char *) & long_return;
529 long_return = store_idx;
530 return (u_char *) & long_return;
532 if (store_idx < HRS_TYPE_FS_MAX)
533 if (storageUseNFS && Check_HR_FileSys_NFS())
534 storage_type_id[storage_type_len - 1] = 10; /* Network Disk */
536 storage_type_id[storage_type_len - 1] = 4; /* Assume fixed */
540 storage_type_id[storage_type_len - 1] = 2; /* RAM */
543 storage_type_id[storage_type_len - 1] = 3; /* Virtual Mem */
546 storage_type_id[storage_type_len - 1] = 1; /* Other */
549 storage_type_id[storage_type_len - 1] = 1; /* Other */
552 *var_len = sizeof(storage_type_id);
553 return (u_char *) storage_type_id;
555 if (store_idx < HRS_TYPE_FS_MAX) {
556 strncpy(string, HRFS_entry->HRFS_mount, sizeof(string)-1);
557 string[ sizeof(string)-1 ] = 0;
558 *var_len = strlen(string);
559 return (u_char *) string;
561 store_idx = store_idx - HRS_TYPE_FS_MAX;
562 *var_len = strlen(hrs_descr[store_idx]);
563 return (u_char *) hrs_descr[store_idx];
566 if (store_idx < HRS_TYPE_FS_MAX)
567 #if STRUCT_STATVFS_HAS_F_FRSIZE
568 long_return = stat_buf.f_frsize;
570 long_return = stat_buf.f_bsize;
576 #if defined(USE_SYSCTL) || defined(solaris2)
577 long_return = pagesize;
581 long_return = 1024; /* Report in Kb */
595 long_return = 1024; /* As likely as any! */
598 return (u_char *) & long_return;
600 if (store_idx < HRS_TYPE_FS_MAX)
601 long_return = stat_buf.f_blocks;
607 long_return = linux_mem(store_idx, HRSTORE_SIZE);
609 #elif defined(solaris2)
611 long_return = physmem;
614 sol_get_swapinfo(&swap_total, &swap_used);
615 long_return = swap_total;
617 #elif defined(hpux10) || defined(hpux11)
619 long_return = pst_buf.psd_rm;
622 long_return = pst_buf.psd_vm;
624 #elif defined(TOTAL_MEMORY_SYMBOL) || defined(USE_SYSCTL_VM)
626 long_return = memory_totals.t_rm;
629 long_return = memory_totals.t_vm;
631 #else /* !linux && !solaris2 && !hpux10 && !hpux11 && ... */
633 long_return = physmem;
646 sizeof(mbstat.m_mtypes) / sizeof(mbstat.m_mtypes[0]);
648 long_return += mbstat.m_mtypes[i];
649 #elif defined(MBSTAT_SYMBOL)
650 long_return = mbstat.m_mbufs;
651 #elif defined(NO_DUMMY_VALUES)
657 #endif /* !linux && !solaris2 && !hpux10 && !hpux11 && ... */
665 return (u_char *) & long_return;
667 if (store_idx < HRS_TYPE_FS_MAX)
668 long_return = (stat_buf.f_blocks - stat_buf.f_bfree);
674 long_return = linux_mem(store_idx, HRSTORE_USED);
676 #elif defined(solaris2)
678 getKstatInt("unix", "system_pages", "freemem", &freemem);
679 long_return = physmem - freemem;
682 sol_get_swapinfo(&swap_total, &swap_used);
683 long_return = swap_used;
685 #elif defined(hpux10) || defined(hpux11)
687 long_return = pst_buf.psd_arm;
690 long_return = pst_buf.psd_avm;
692 #elif defined(TOTAL_MEMORY_SYMBOL) || defined(USE_SYSCTL_VM)
694 long_return = memory_totals.t_arm;
697 long_return = memory_totals.t_avm;
699 #endif /* linux || solaris2 || hpux10 || hpux11 || ... */
701 #if !defined(linux) && !defined(solaris2) && !defined(hpux10) && !defined(hpux11)
704 long_return = (mbpool.pr_nget - mbpool.pr_nput)
705 * mbpool.pr_size + (mclpool.pr_nget - mclpool.pr_nput)
707 #elif defined(MBSTAT_SYMBOL)
708 long_return = mbstat.m_clusters - mbstat.m_clfree; /* unlikely, but... */
709 #elif defined(NO_DUMMY_VALUES)
715 #endif /* !linux && !solaris2 && !hpux10 && !hpux11 && ... */
723 return (u_char *) & long_return;
725 if (store_idx < HRS_TYPE_FS_MAX)
736 #if !defined(linux) && !defined(solaris2) && !defined(hpux10) && !defined(hpux11) && defined(MBSTAT_SYMBOL)
738 long_return = mbstat.m_drops;
740 #endif /* !linux && !solaris2 && !hpux10 && !hpux11 && MBSTAT_SYMBOL */
748 return (u_char *) & long_return;
750 DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_hrstore\n",
757 /*********************
759 * Internal implementation functions
761 *********************/
763 static int FS_storage;
764 static int HRS_index;
771 FS_storage = 1; /* Start with file-based storage */
775 Get_Next_HR_Store(void)
781 if (FS_storage == 1) {
782 HRS_index = Get_Next_HR_FileSys();
786 FS_storage = 0; /* End of filesystems */
787 HRS_index = HRS_TYPE_FS_MAX;
791 * 'Other' storage types
794 #if !defined(solaris2) && !defined(hpux10) && !defined(hpux11)
795 if (HRS_index < HRS_TYPE_MAX)
799 if (HRS_index < HRS_TYPE_MBUF)
808 linux_mem(int mem_type, int size_or_used)
812 int size = -1, used = -1;
814 if ((fp = fopen("/proc/meminfo", "r")) == NULL)
817 while (fgets(buf, sizeof(buf), fp) != NULL) {
818 if ((!strncmp(buf, "Mem:", 4) && mem_type == HRS_TYPE_MEM) ||
819 (!strncmp(buf, "Swap:", 5) && mem_type == HRS_TYPE_SWAP)) {
820 sscanf(buf, "%*s %d %d", &size, &used);
826 return (size_or_used == HRSTORE_SIZE ? size : used) / 1024;
833 sol_get_swapinfo(int *totalP, int *usedP)
835 struct anoninfo ainfo;
837 if (swapctl(SC_AINFO, &ainfo) < 0) {
838 *totalP = *usedP = 0;
842 *totalP = ainfo.ani_max;
843 *usedP = ainfo.ani_resv;
845 #endif /* solaris2 */