blob: 42f203eeb98a4fdbd28dc3b793cf67be5b5d2454 [file] [log] [blame]
#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 = (swaptbl_t*)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);
}