summaryrefslogtreecommitdiff
path: root/agent/mibgroup/hardware/memory/memory_solaris.c
diff options
context:
space:
mode:
Diffstat (limited to 'agent/mibgroup/hardware/memory/memory_solaris.c')
-rw-r--r--agent/mibgroup/hardware/memory/memory_solaris.c172
1 files changed, 172 insertions, 0 deletions
diff --git a/agent/mibgroup/hardware/memory/memory_solaris.c b/agent/mibgroup/hardware/memory/memory_solaris.c
new file mode 100644
index 0000000..3dfff8b
--- /dev/null
+++ b/agent/mibgroup/hardware/memory/memory_solaris.c
@@ -0,0 +1,172 @@
+#include <net-snmp/net-snmp-config.h>
+#include <net-snmp/net-snmp-includes.h>
+#include <net-snmp/agent/net-snmp-agent-includes.h>
+#include <net-snmp/agent/hardware/memory.h>
+
+#include <unistd.h>
+#include <kstat.h>
+#include <sys/stat.h>
+#include <sys/swap.h>
+
+#ifndef MAXSTRSIZE
+#define MAXSTRSIZE 1024
+#endif
+
+void getSwapInfo(long *total_mem, long *free_mem);
+
+
+ /*
+ * Load the latest memory usage statistics
+ */
+int netsnmp_mem_arch_load( netsnmp_cache *cache, void *magic ) {
+
+#ifndef _SC_PHYS_PAGES
+ extern kstat_ctl_t *kstat_fd; /* defined in kernel_sunos5.c */
+ kstat_t *ksp1;
+ kstat_named_t *kn;
+#endif
+#ifdef SC_AINFO
+ struct anoninfo ai;
+#endif
+
+ long phys_mem = 0;
+ long phys_free = 0;
+ long swap_pages = 0;
+ long swap_free = 0;
+ long pagesize = 0;
+ netsnmp_memory_info *mem;
+
+ /*
+ * Retrieve the memory information from the underlying O/S...
+ */
+ pagesize = getpagesize();
+ getSwapInfo( &swap_pages, &swap_free );
+#ifdef SC_AINFO
+ swapctl(SC_AINFO, &ai);
+#endif
+#ifdef _SC_PHYS_PAGES
+ phys_mem = sysconf(_SC_PHYS_PAGES);
+ phys_free = sysconf(_SC_AVPHYS_PAGES);
+#else
+ ksp1 = kstat_lookup(kstat_fd, "unix", 0, "system_pages");
+ kstat_read(kstat_fd, ksp1, 0);
+ kn = kstat_data_lookup(ksp1, "physmem");
+ phys_mem = kn->value.ul;
+#ifdef SC_AINFO
+ phys_free = (ai.ani_max - ai.ani_resv) - swap_free;
+#else
+ phys_free = -1;
+#endif
+#endif
+
+ /*
+ * ... and save this in a standard form.
+ */
+ mem = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_PHYSMEM, 1 );
+ if (!mem) {
+ snmp_log_perror("No Memory info entry");
+ } else {
+ if (!mem->descr)
+ mem->descr = strdup( "Physical memory" );
+ mem->units = pagesize;
+ mem->size = phys_mem;
+ mem->free = phys_free;
+ mem->other = -1;
+ }
+
+#ifdef SC_AINFO
+ mem = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_VIRTMEM, 1 );
+ if (!mem) {
+ snmp_log_perror("No Virtual Memory info entry");
+ } else {
+ if (!mem->descr)
+ mem->descr = strdup( " Virtual memory" );
+ mem->units = pagesize; /* or 1024? */
+ mem->size = ai.ani_max;
+ mem->free = (ai.ani_max - ai.ani_resv);
+ mem->other = -1;
+ }
+#endif
+
+ mem = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_SWAP, 1 );
+ if (!mem) {
+ snmp_log_perror("No Swap info entry");
+ } else {
+ if (!mem->descr)
+ mem->descr = strdup( "Swap space" );
+ mem->units = pagesize;
+ mem->size = swap_pages;
+ mem->free = swap_free;
+ mem->other = -1;
+ }
+
+/*
+ mem = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_MISC, 1 );
+ if (!mem) {
+ snmp_log_perror("No Buffer, etc info entry");
+ } else {
+ mem->units = getpagesize();
+ mem->size = -1;
+ mem->free = getTotalFree();
+ mem->other = -1;
+ }
+*/
+
+ return 0;
+}
+
+/*
+ * Adapted from UCD implementation
+ */
+void
+getSwapInfo(long *total_mem, long *total_free)
+{
+ size_t num;
+ int i, n;
+ swaptbl_t *s;
+ netsnmp_memory_info *mem;
+ char *strtab;
+ char buf[1024];
+
+ num = swapctl(SC_GETNSWP, 0);
+ s = malloc(num * sizeof(swapent_t) + sizeof(struct swaptable));
+ if (!s)
+ return;
+
+ strtab = (char *) malloc((num + 1) * MAXSTRSIZE);
+ if (!strtab) {
+ free(s);
+ return;
+ }
+
+ for (i = 0; i < (num + 1); i++) {
+ s->swt_ent[i].ste_path = strtab + (i * MAXSTRSIZE);
+ }
+ s->swt_n = num + 1;
+ n = swapctl(SC_LIST, s);
+
+ if (n > 1) {
+ for (i = 0; i < n; ++i) {
+ mem = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_SWAP+1+i, 1 );
+ if (!mem)
+ continue;
+ if (!mem->descr) {
+ sprintf(buf, "swap #%d %s", i, s->swt_ent[i].ste_path);
+ mem->descr = strdup( buf );
+ }
+ mem->units = getpagesize();
+ mem->size = s->swt_ent[i].ste_pages;
+ mem->free = s->swt_ent[i].ste_free;
+ mem->other = -1;
+ *total_mem += mem->size;
+ *total_free += mem->free;
+ }
+ }
+ else {
+ *total_mem = s->swt_ent[0].ste_pages;
+ *total_free = s->swt_ent[0].ste_free;
+ }
+
+ free(strtab);
+ free(s);
+}