JNIEXPORT jlong JNICALL Java_sun_management_OperatingSystemImpl_getFreePhysicalMemorySize (JNIEnv *env, jobject mbean) { #ifdef __APPLE__ mach_msg_type_number_t count; vm_statistics_data_t vm_stats; kern_return_t res; count = HOST_VM_INFO_COUNT; res = host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&vm_stats, &count); if (res != KERN_SUCCESS) { throw_internal_error(env, "host_statistics failed"); return -1; } return (jlong)vm_stats.free_count * page_size; #elif defined(_ALLBSD_SOURCE) /* * XXBSDL no way to do it in FreeBSD */ // throw_internal_error(env, "unimplemented in FreeBSD") return (128 * MB); #elif defined(_AIX) perfstat_memory_total_t memory_info; if (-1 != perfstat_memory_total(NULL, &memory_info, sizeof(perfstat_memory_total_t), 1)) { return (jlong)(memory_info.real_free * 4L * 1024L); } return -1; #else // solaris / linux jlong num_avail_physical_pages = sysconf(_SC_AVPHYS_PAGES); return (num_avail_physical_pages * page_size); #endif }
JNIEXPORT jlong JNICALL Java_sun_management_OperatingSystemImpl_getTotalPhysicalMemorySize (JNIEnv *env, jobject mbean) { #ifdef _ALLBSD_SOURCE jlong result = 0; int mib[2]; size_t rlen; mib[0] = CTL_HW; mib[1] = HW_MEMSIZE; rlen = sizeof(result); if (sysctl(mib, 2, &result, &rlen, NULL, 0) != 0) { throw_internal_error(env, "sysctl failed"); return -1; } return result; #elif defined(_AIX) perfstat_memory_total_t memory_info; if (-1 != perfstat_memory_total(NULL, &memory_info, sizeof(perfstat_memory_total_t), 1)) { return (jlong)(memory_info.real_total * 4L * 1024L); } return -1; #else // solaris / linux jlong num_physical_pages = sysconf(_SC_PHYS_PAGES); return (num_physical_pages * page_size); #endif }
uint64_t uv_get_free_memory(void) { perfstat_memory_total_t mem_total; int result = perfstat_memory_total(NULL, &mem_total, sizeof(mem_total), 1); if (result == -1) { return 0; } return mem_total.real_free * 4096; }
void print_memory(void) { perfstat_memory_total_t minfo; perfstat_memory_total(NULL, &minfo, sizeof(perfstat_memory_total_t), 1); printf("RealMemory:\t%3.1fM\n", minfo.real_total / 256.0); printf("FreeMemory:\t%3.1fM\n", minfo.real_free / 256.0); }
static long getFreeReal(void) { long free_mem = -1; perfstat_memory_total_t mem; if(perfstat_memory_total((perfstat_id_t *)NULL, &mem, sizeof(perfstat_memory_total_t), 1) >= 1) { free_mem = mem.real_free; } return (free_mem); }
static long getTotalReal(void) { long total_mem = -1; perfstat_memory_total_t mem; if(perfstat_memory_total((perfstat_id_t *)NULL, &mem, sizeof(perfstat_memory_total_t), 1) >= 1) { total_mem = mem.real_total; } return (total_mem); }
static int VM_MEMORY_CACHED(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result) { #if defined(HAVE_LIBPERFSTAT) /* AIX 6.1 */ perfstat_memory_total_t m; zbx_uint64_t value; if (-1 == perfstat_memory_total(NULL, &m, sizeof(m), 1)) return SYSINFO_RET_FAIL; value = (zbx_uint64_t)m.numperm; /* number of frames used for files (in 4KB pages) */ value <<= 12; SET_UI64_RESULT(result, value); return SYSINFO_RET_OK; #elif defined(HAVE_PROC) FILE *f = NULL; char *t; char c[MAX_STRING_LEN]; zbx_uint64_t res = 0; if( NULL == ( f = fopen("/proc/meminfo","r"))) { return SYSINFO_RET_FAIL; } while(NULL!=fgets(c,MAX_STRING_LEN,f)) { if(strncmp(c,"Cached:",7) == 0) { t=(char *)strtok(c," "); t=(char *)strtok(NULL," "); sscanf(t, ZBX_FS_UI64, &res ); t=(char *)strtok(NULL," "); if(strcasecmp(t,"kb")) res <<= 10; else if(strcasecmp(t, "mb")) res <<= 20; else if(strcasecmp(t, "gb")) res <<= 30; else if(strcasecmp(t, "tb")) res <<= 40; break; } } zbx_fclose(f); SET_UI64_RESULT(result, res); return SYSINFO_RET_OK; #else return SYSINFO_RET_FAIL; #endif }
boolean_t init_process_info_sysdep(void) { perfstat_memory_total_t mem; if (perfstat_memory_total(NULL, &mem, sizeof(perfstat_memory_total_t), 1) < 1) { LogError("system statistic error -- perfstat_memory_total failed: %s\n", STRERROR); return false; } page_size = getpagesize(); systeminfo.mem_kbyte_max = (unsigned long)(mem.real_total * (page_size / 1024)); systeminfo.cpus = sysconf(_SC_NPROCESSORS_ONLN); return true; }
int SYSTEM_SWAP_SIZE(AGENT_REQUEST *request, AGENT_RESULT *result) { #ifdef HAVE_LIBPERFSTAT perfstat_memory_total_t mem; char *swapdev, *mode; if (2 < request->nparam) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Too many parameters.")); return SYSINFO_RET_FAIL; } swapdev = get_rparam(request, 0); mode = get_rparam(request, 1); if (NULL != swapdev && '\0' != *swapdev && 0 != strcmp(swapdev, "all")) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid first parameter.")); return SYSINFO_RET_FAIL; } if (1 != perfstat_memory_total(NULL, &mem, sizeof(perfstat_memory_total_t), 1)) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain system information: %s", zbx_strerror(errno))); return SYSINFO_RET_FAIL; } if (NULL == mode || '\0' == *mode || 0 == strcmp(mode, "free")) SET_UI64_RESULT(result, mem.pgsp_free << ZBX_PERFSTAT_PAGE_SHIFT); else if (0 == strcmp(mode, "total")) SET_UI64_RESULT(result, mem.pgsp_total << ZBX_PERFSTAT_PAGE_SHIFT); else if (0 == strcmp(mode, "used")) SET_UI64_RESULT(result, (mem.pgsp_total - mem.pgsp_free) << ZBX_PERFSTAT_PAGE_SHIFT); else if (0 == strcmp(mode, "pfree")) SET_DBL_RESULT(result, mem.pgsp_total ? 100.0 * (mem.pgsp_free / (double)mem.pgsp_total) : 0.0); else if (0 == strcmp(mode, "pused")) SET_DBL_RESULT(result, mem.pgsp_total ? 100.0 - 100.0 * (mem.pgsp_free / (double)mem.pgsp_total) : 0.0); else { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter.")); return SYSINFO_RET_FAIL; } return SYSINFO_RET_OK; #else SET_MSG_RESULT(result, zbx_strdup(NULL, "Agent was compiled without support for Perfstat API.")); return SYSINFO_RET_FAIL; #endif }
/** * This routine returns kbyte of real memory in use. * @return: true if successful, false if failed (or not available) */ boolean_t used_system_memory_sysdep(SystemInfo_T *si) { perfstat_memory_total_t mem; /* Memory */ if (perfstat_memory_total(NULL, &mem, sizeof(perfstat_memory_total_t), 1) < 1) { LogError("system statistic error -- perfstat_memory_total failed: %s\n", STRERROR); return false; } si->total_mem_kbyte = (unsigned long)((mem.real_total - mem.real_free - mem.numperm) * (page_size / 1024)); /* Swap */ si->swap_kbyte_max = (unsigned long)(mem.pgsp_total * 4); /* 4kB blocks */ si->total_swap_kbyte = (unsigned long)((mem.pgsp_total - mem.pgsp_free) * 4); /* 4kB blocks */ return true; }
static int swap_read (void) /* {{{ */ { if(perfstat_memory_total(NULL, &pmemory, sizeof(perfstat_memory_total_t), 1) < 0) { char errbuf[1024]; WARNING ("memory plugin: perfstat_memory_total failed: %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } swap_submit_gauge (NULL, "used", (gauge_t) (pmemory.pgsp_total - pmemory.pgsp_free) * pagesize); swap_submit_gauge (NULL, "free", (gauge_t) pmemory.pgsp_free * pagesize ); swap_submit_gauge (NULL, "reserved", (gauge_t) pmemory.pgsp_rsvd * pagesize); swap_submit_derive (NULL, "in", (derive_t) pmemory.pgspins * pagesize); swap_submit_derive (NULL, "out", (derive_t) pmemory.pgspouts * pagesize); return (0); } /* }}} int swap_read */
int get_mem_data(struct mem_data * _mem) { perfstat_memory_total_t meminfo; int ps; ps=getpagesize(); perfstat_memory_total(NULL, &meminfo, sizeof meminfo, 1); _mem->t = ps * meminfo.real_total / 1024; _mem->c = ps * meminfo.real_pinned / 1024; _mem->f = ps * meminfo.real_free / 1024; _mem->swi = ps * meminfo.pgspins / 1024; _mem->swo = ps * meminfo.pgspouts / 1024; _mem->swt = ps * meminfo.pgsp_total / 1024; _mem->swu = ps * (meminfo.pgsp_total- meminfo.pgsp_free) / 1024; _mem->a = _mem->t - _mem->c - _mem->f; return 0; }
static sg_error sg_get_swap_stats_int(sg_swap_stats *swap_stats_buf) { #ifdef HPUX #define SWAP_BATCH 5 struct pst_swapinfo pstat_swapinfo[SWAP_BATCH]; int swapidx = 0; int num, i; #elif defined(SOLARIS) # if defined(HAVE_STRUCT_SWAPTABLE) struct swaptable *swtbl; int nswap, i; # elif defined(HAVE_STRUCT_ANONINFO) struct anoninfo ai; # endif #elif defined(LINUX) || defined(CYGWIN) FILE *f; #define LINE_BUF_SIZE 256 char line_buf[LINE_BUF_SIZE]; unsigned long long value; unsigned matches = 0; #elif defined(HAVE_STRUCT_XSWDEV) struct xswdev xsw; struct xswdev *xswbuf = NULL, *xswptr = NULL; int n; int mib[16]; size_t mibsize, size; #elif defined(HAVE_STRUCT_XSW_USAGE) int mib[2] = {CTL_VM, VM_SWAPUSAGE}; struct xsw_usage xsw; size_t mibsize = 2, size = sizeof(xsw); #elif defined(HAVE_STRUCT_UVMEXP_SYSCTL) && defined(VM_UVMEXP2) int mib[2] = { CTL_VM, VM_UVMEXP2 }; struct uvmexp_sysctl uvm; size_t size = sizeof(uvm); #elif defined(HAVE_STRUCT_UVMEXP) && defined(VM_UVMEXP) int mib[2] = { CTL_VM, VM_UVMEXP }; struct uvmexp uvm; size_t size = sizeof(uvm); #elif defined(ALLBSD) /* fallback if no reasonable API is supported */ struct kvm_swap swapinfo; kvm_t *kvmd; #elif defined(AIX) perfstat_memory_total_t mem; #elif defined(WIN32) MEMORYSTATUSEX memstats; #endif swap_stats_buf->total = 0; swap_stats_buf->used = 0; swap_stats_buf->free = 0; #ifdef HPUX for(;;) { num = pstat_getswap(pstat_swapinfo, sizeof pstat_swapinfo[0], SWAP_BATCH, swapidx); if (num == -1) { RETURN_WITH_SET_ERROR_WITH_ERRNO("swap", SG_ERROR_PSTAT, "pstat_getswap"); } else if (num == 0) { break; } for (i = 0; i < num; ++i) { struct pst_swapinfo *si = &pstat_swapinfo[i]; if ((si->pss_flags & SW_ENABLED) != SW_ENABLED) continue; if ((si->pss_flags & SW_BLOCK) == SW_BLOCK) { swap_stats_buf->total += ((long long) si->pss_nblksavail) * 1024LL; swap_stats_buf->used += ((long long) si->pss_nfpgs) * 1024LL; swap_stats_buf->free = swap_stats_buf->total - swap_stats_buf->used; } if ((si->pss_flags & SW_FS) == SW_FS) { swap_stats_buf->total += ((long long) si->pss_limit) * 1024LL; swap_stats_buf->used += ((long long) si->pss_allocated) * 1024LL; swap_stats_buf->free = swap_stats_buf->total - swap_stats_buf->used; } } swapidx = pstat_swapinfo[num - 1].pss_idx + 1; } #elif defined(AIX) /* return code is number of structures returned */ if(perfstat_memory_total(NULL, &mem, sizeof(perfstat_memory_total_t), 1) != 1) { RETURN_WITH_SET_ERROR_WITH_ERRNO("swap", SG_ERROR_SYSCTLBYNAME, "perfstat_memory_total"); } swap_stats_buf->total = ((long long)mem.pgsp_total) * sys_page_size; swap_stats_buf->free = ((long long)mem.pgsp_free) * sys_page_size; swap_stats_buf->used = swap_stats_buf->total - swap_stats_buf->free; #elif defined(SOLARIS) # if defined(HAVE_STRUCT_SWAPTABLE) again: if( ( nswap = swapctl(SC_GETNSWP, 0) ) == -1 ) { RETURN_WITH_SET_ERROR_WITH_ERRNO("swap", SG_ERROR_SWAPCTL, NULL); } if( nswap != 0 ) { char *buf = sg_malloc( nswap * sizeof(char) * (PATH_MAX+1) + 1 ); if( NULL == buf ) { RETURN_FROM_PREVIOUS_ERROR( "swap", sg_get_error() ); } swtbl = sg_malloc( sizeof(*swtbl) + ( nswap * sizeof(swtbl->swt_ent[0]) ) ); if( NULL == swtbl ) { free(buf); RETURN_FROM_PREVIOUS_ERROR( "swap", sg_get_error() ); } memset( buf, 0, nswap * sizeof(char) * (PATH_MAX+1) + 1 ); memset( swtbl, 0, sizeof(*swtbl) + ( nswap * sizeof(swtbl->swt_ent[0]) ) ); for( i = 0; i < nswap; ++i ) swtbl->swt_ent[i].ste_path = buf + (i * (PATH_MAX+1)); swtbl->swt_n = nswap; if ((i = swapctl(SC_LIST, swtbl)) < 0) { free( buf ); free( swtbl ); RETURN_WITH_SET_ERROR_WITH_ERRNO("swap", SG_ERROR_SWAPCTL, NULL); } if( i > nswap ) { free( swtbl ); free( buf ); goto again; } for( i = 0; i < nswap; ++i ) { swap_stats_buf->total = swtbl->swt_ent[i].ste_pages; swap_stats_buf->free = swtbl->swt_ent[i].ste_free; } free( swtbl ); free( buf ); swap_stats_buf->total *= sys_page_size; swap_stats_buf->free *= sys_page_size; swap_stats_buf->used = swap_stats_buf->total - swap_stats_buf->free; } # elif defined(HAVE_STRUCT_ANONINFO) if (swapctl(SC_AINFO, &ai) == -1) { RETURN_WITH_SET_ERROR_WITH_ERRNO("swap", SG_ERROR_SWAPCTL, NULL); } swap_stats_buf->total = ai.ani_max; swap_stats_buf->total *= sys_page_size; swap_stats_buf->used = ai.ani_resv; swap_stats_buf->used *= sys_page_size; swap_stats_buf->free = swap_stats_buf->total - swap_stats_buf->used; # else RETURN_WITH_SET_ERROR("swap", SG_ERROR_UNSUPPORTED, OS_TYPE); # endif #elif defined(LINUX) || defined(CYGWIN) if ((f = fopen("/proc/meminfo", "r")) == NULL) { RETURN_WITH_SET_ERROR_WITH_ERRNO("swap", SG_ERROR_OPEN, "/proc/meminfo"); } while( (matches < 2) && (fgets(line_buf, sizeof(line_buf), f) != NULL) ) { if (sscanf(line_buf, "%*s %llu kB", &value) != 1) continue; value *= 1024; if (strncmp(line_buf, "SwapTotal:", 10) == 0) { swap_stats_buf->total = value; ++matches; } else if (strncmp(line_buf, "SwapFree:", 9) == 0) { swap_stats_buf->free = value; ++matches; } } fclose(f); if( matches < 2 ) { RETURN_WITH_SET_ERROR( "swap", SG_ERROR_PARSE, "/proc/meminfo" ); } swap_stats_buf->used = swap_stats_buf->total - swap_stats_buf->free; #elif defined(HAVE_STRUCT_XSWDEV) mibsize = 2; if( swapinfo_array ) { size = 0; if( sysctl( swapinfo_mib, 2, NULL, &size, NULL, 0 ) < 0 ) { RETURN_WITH_SET_ERROR_WITH_ERRNO("swap", SG_ERROR_SYSCTL, swapinfo_sysctl_name); } if( NULL == ( xswbuf = sg_malloc( size ) ) ) { RETURN_FROM_PREVIOUS_ERROR( "swap", sg_get_error() ); } if( sysctl( swapinfo_mib, 2, xswbuf, &size, NULL, 0 ) < 0 ) { RETURN_WITH_SET_ERROR_WITH_ERRNO("swap", SG_ERROR_SYSCTL, swapinfo_sysctl_name); } } else { mib[0] = swapinfo_mib[0]; mib[1] = swapinfo_mib[1]; } for (n = 0; ; ++n) { if( !swapinfo_array ) { mib[mibsize] = n; size = sizeof(xsw); if (sysctl(mib, (unsigned)(mibsize + 1), &xsw, &size, NULL, 0) < 0) { if (errno == ENOENT) break; free( xswbuf ); RETURN_WITH_SET_ERROR_WITH_ERRNO("swap", SG_ERROR_SYSCTL, swapinfo_sysctl_name); } xswptr = &xsw; } # if defined(HAVE_STRUCT_XSWDEV_SIZE) else { if( ((size_t)n) >= (size / xswbuf->xsw_size) ) break; xswptr = xswbuf + n; } if( xswptr == NULL ) { RETURN_WITH_SET_ERROR("swap", SG_ERROR_MEMSTATUS, "no swap status"); } # ifdef XSWDEV_VERSION if( xswptr->xsw_version != XSWDEV_VERSION ) { free( xswbuf ); RETURN_WITH_SET_ERROR("swap", SG_ERROR_XSW_VER_MISMATCH, NULL); } # endif # endif swap_stats_buf->total += (unsigned long long) xswptr->xsw_nblks; swap_stats_buf->used += (unsigned long long) xswptr->xsw_used; } free( xswbuf ); swap_stats_buf->total *= (size_t)sys_page_size; swap_stats_buf->used *= (size_t)sys_page_size; if( 0 == swap_stats_buf->free ) swap_stats_buf->free = swap_stats_buf->total - swap_stats_buf->used; else swap_stats_buf->free *= (size_t)sys_page_size; #elif defined(HAVE_STRUCT_XSW_USAGE) if (sysctl(mib, (unsigned)mibsize, &xsw, &size, NULL, 0) < 0) { RETURN_WITH_SET_ERROR_WITH_ERRNO("swap", SG_ERROR_SYSCTL, "CTL_VM.VM_SWAPUSAGE" ); } swap_stats_buf->total = (unsigned long long) xsw.xsu_total; swap_stats_buf->used = (unsigned long long) xsw.xsu_used; swap_stats_buf->free = (unsigned long long) xsw.xsu_avail; #elif defined(HAVE_STRUCT_UVMEXP_SYSCTL) && defined(VM_UVMEXP2) if (sysctl(mib, 2, &uvm, &size, NULL, 0) < 0) { RETURN_WITH_SET_ERROR_WITH_ERRNO("swap", SG_ERROR_SYSCTL, "CTL_VM.VM_UVMEXP2"); } swap_stats_buf->total = uvm.pagesize * uvm.swpages; swap_stats_buf->used = uvm.pagesize * uvm.swpginuse; /* XXX swpgonly ? */ swap_stats_buf->free = swap_stats_buf->total - swap_stats_buf->used; #elif defined(HAVE_STRUCT_UVMEXP) && defined(VM_UVMEXP) if (sysctl(mib, 2, &uvm, &size, NULL, 0) < 0) { RETURN_WITH_SET_ERROR_WITH_ERRNO("swap", SG_ERROR_SYSCTL, "CTL_VM.VM_UVMEXP"); } swap_stats_buf->total = (unsigned long long)uvm.pagesize * (unsigned long long)uvm.swpages; swap_stats_buf->used = (unsigned long long)uvm.pagesize * (unsigned long long)uvm.swpginuse; /* XXX swpgonly ? */ swap_stats_buf->free = swap_stats_buf->total - swap_stats_buf->used; #elif defined(ALLBSD) /* XXX probably not mt-safe! */ kvmd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, NULL); if(kvmd == NULL) { RETURN_WITH_SET_ERROR("swap", SG_ERROR_KVM_OPENFILES, NULL); } if ((kvm_getswapinfo(kvmd, &swapinfo, 1,0)) == -1) { kvm_close( kvmd ); RETURN_WITH_SET_ERROR("swap", SG_ERROR_KVM_GETSWAPINFO, NULL); } swap_stats_buf->total = (long long)swapinfo.ksw_total; swap_stats_buf->used = (long long)swapinfo.ksw_used; kvm_close( kvmd ); swap_stats_buf->total *= sys_page_size; swap_stats_buf->used *= sys_page_size; swap_stats_buf->free = swap_stats_buf->total - swap_stats_buf->used; #elif defined(WIN32) memstats.dwLength = sizeof(memstats); if (!GlobalMemoryStatusEx(&memstats)) { RETURN_WITH_SET_ERROR_WITH_ERRNO("swap", SG_ERROR_MEMSTATUS, "GloblaMemoryStatusEx"); } /* the PageFile stats include Phys memory "minus an overhead". * Due to this unknown "overhead" there's no way to extract just page * file use from these numbers */ swap_stats_buf->total = memstats.ullTotalPageFile; swap_stats_buf->free = memstats.ullAvailPageFile; swap_stats_buf->used = swap_stats_buf->total - swap_stats_buf->free; #else RETURN_WITH_SET_ERROR("swap", SG_ERROR_UNSUPPORTED, OS_TYPE); #endif swap_stats_buf->systime = time(NULL); return SG_ERROR_NONE; }
static sg_error sg_get_mem_stats_int(sg_mem_stats *mem_stats_buf) { #ifdef HPUX struct pst_static pstat_static; struct pst_dynamic pstat_dynamic; #elif defined(SOLARIS) # ifdef _SC_PHYS_PAGES long phystotal; long physav; # else kstat_ctl_t *kc; kstat_t *ksp; kstat_named_t *kn; # endif #elif defined(LINUX) || defined(CYGWIN) #define LINE_BUF_SIZE 256 char *line_ptr, line_buf[LINE_BUF_SIZE]; long long value; FILE *f; #elif defined(HAVE_HOST_STATISTICS) || defined(HAVE_HOST_STATISTICS64) # if defined(HAVE_HOST_STATISTICS64) struct vm_statistics64 vm_stats; # else struct vm_statistics vm_stats; # endif mach_msg_type_number_t count; kern_return_t rc; #elif defined(HAVE_STRUCT_UVMEXP_SYSCTL) && defined(VM_UVMEXP2) int mib[2]; struct uvmexp_sysctl uvm; size_t size = sizeof(uvm); #elif defined(HAVE_STRUCT_UVMEXP) && defined(VM_UVMEXP) int mib[2]; struct uvmexp uvm; size_t size = sizeof(uvm); #elif defined(FREEBSD) || defined(DFBSD) size_t size; unsigned int total_count; unsigned int free_count; unsigned int cache_count; unsigned int inactive_count; #elif defined(HAVE_STRUCT_VMTOTAL) struct vmtotal vmtotal; size_t size; #if defined(HW_PHYSMEM) || defined(HW_USERMEM) int mib[2]; # if defined(HW_PHYSMEM) u_long total_mem; # endif # if defined(HW_USERMEM) u_long user_mem; # endif #endif #elif defined(AIX) perfstat_memory_total_t mem; #elif defined(WIN32) MEMORYSTATUSEX memstats; #endif #if defined(HPUX) if (pstat_getdynamic(&pstat_dynamic, sizeof(pstat_dynamic), 1, 0) == -1) { RETURN_WITH_SET_ERROR_WITH_ERRNO("mem", SG_ERROR_PSTAT, "pstat_dynamic"); } /* * from man pstat_getstatic: * * pstat_getstatic() returns information about the system. Although * this data usually does not change frequently, it may change while * the system is running due to manually or automatically generated * administrative changes in the associated kernel tunables, online * addition/deletion of resources, or other events. There is one * global instance of this context. * * ==> Can't hold this value globally static. */ if( pstat_getstatic(&pstat_static, sizeof(pstat_static), 1, 0) == -1 ) { RETURN_WITH_SET_ERROR_WITH_ERRNO("mem", SG_ERROR_PSTAT, "pstat_static"); } mem_stats_buf->total = ((long long) pstat_static.physical_memory) * pstat_static.page_size; mem_stats_buf->free = ((long long) pstat_dynamic.psd_free) * pstat_static.page_size; mem_stats_buf->used = mem_stats_buf->total - mem_stats_buf->free; #elif defined(AIX) /* return code is number of structures returned */ if(perfstat_memory_total(NULL, &mem, sizeof(perfstat_memory_total_t), 1) != 1) { RETURN_WITH_SET_ERROR_WITH_ERRNO("mem", SG_ERROR_SYSCTLBYNAME, "perfstat_memory_total"); } mem_stats_buf->total = (unsigned long long) mem.real_total; mem_stats_buf->total *= sys_page_size; mem_stats_buf->used = (unsigned long long) mem.real_inuse; mem_stats_buf->used *= sys_page_size; mem_stats_buf->cache = (unsigned long long) mem.numperm; mem_stats_buf->cache *= sys_page_size; mem_stats_buf->free = (unsigned long long) mem.real_free; mem_stats_buf->free *= sys_page_size; #elif defined(SOLARIS) # ifdef _SC_PHYS_PAGES if( ( phystotal = sysconf(_SC_PHYS_PAGES) ) < 0 ) { RETURN_WITH_SET_ERROR_WITH_ERRNO("mem", SG_ERROR_SYSCONF, "_SC_PHYS_PAGES"); } if( ( physav = sysconf(_SC_AVPHYS_PAGES) ) < 0 ) { RETURN_WITH_SET_ERROR_WITH_ERRNO("mem", SG_ERROR_SYSCONF, "_SC_AVPHYS_PAGES"); } mem_stats_buf->total = ((unsigned long long)phystotal) * ((unsigned long long)sys_page_size); mem_stats_buf->free = ((unsigned long long)physav) * ((unsigned long long)sys_page_size); # else if( (kc = kstat_open()) == NULL ) { RETURN_WITH_SET_ERROR("mem", SG_ERROR_KSTAT_OPEN, NULL); } if((ksp=kstat_lookup(kc, "unix", 0, "system_pages")) == NULL) { RETURN_WITH_SET_ERROR("mem", SG_ERROR_KSTAT_LOOKUP, "unix,0,system_pages"); } if (kstat_read(kc, ksp, 0) == -1) { RETURN_WITH_SET_ERROR("mem", SG_ERROR_KSTAT_READ, NULL); } if((kn=kstat_data_lookup(ksp, "physmem")) == NULL) { RETURN_WITH_SET_ERROR("mem", SG_ERROR_KSTAT_DATA_LOOKUP, "physmem"); } mem_stats_buf->total = ((unsigned long long)kn->value.ul) * ((unsigned long long)sys_page_size); if((kn=kstat_data_lookup(ksp, "freemem")) == NULL) { RETURN_WITH_SET_ERROR("mem", SG_ERROR_KSTAT_DATA_LOOKUP, "freemem"); } mem_stats_buf->free = ((unsigned long long)kn->value.ul) * ((unsigned long long)sys_page_size); kstat_close(kc); # endif mem_stats_buf->used = mem_stats_buf->total - mem_stats_buf->free; mem_stats_buf->cache = 0; #elif defined(LINUX) || defined(CYGWIN) if ((f = fopen("/proc/meminfo", "r")) == NULL) { RETURN_WITH_SET_ERROR_WITH_ERRNO("mem", SG_ERROR_OPEN, "/proc/meminfo"); } #define MEM_TOTAL_PREFIX "MemTotal:" #define MEM_FREE_PREFIX "MemFree:" #define MEM_CACHED_PREFIX "Cached:" while ((line_ptr = fgets(line_buf, sizeof(line_buf), f)) != NULL) { if ( sscanf(line_buf, "%*s %lld kB", &value) != 1) continue; if (strncmp(line_buf, MEM_TOTAL_PREFIX, sizeof(MEM_TOTAL_PREFIX) - 1) == 0) mem_stats_buf->total = value; else if (strncmp(line_buf, MEM_FREE_PREFIX, sizeof(MEM_FREE_PREFIX) - 1) == 0) mem_stats_buf->free = value; else if (strncmp(line_buf, MEM_CACHED_PREFIX, sizeof(MEM_CACHED_PREFIX) - 1) == 0) mem_stats_buf->cache = value; } mem_stats_buf->free += mem_stats_buf->cache; mem_stats_buf->total *= 1024; mem_stats_buf->free *= 1024; mem_stats_buf->cache *= 1024; #undef MEM_TOTAL_PREFIX #undef MEM_FREE_PREFIX #undef MEM_CACHED_PREFIX fclose(f); mem_stats_buf->used = mem_stats_buf->total - mem_stats_buf->free; #elif defined(HAVE_STRUCT_UVMEXP_SYSCTL) && defined(VM_UVMEXP2) mib[0] = CTL_VM; mib[1] = VM_UVMEXP2; if (sysctl(mib, 2, &uvm, &size, NULL, 0) < 0) { RETURN_WITH_SET_ERROR_WITH_ERRNO("mem", SG_ERROR_SYSCTL, "CTL_VM.VM_UVMEXP2"); } mem_stats_buf->total = uvm.npages; mem_stats_buf->cache = uvm.filepages + uvm.execpages; mem_stats_buf->free = uvm.free + mem_stats_buf->cache; mem_stats_buf->total *= uvm.pagesize; mem_stats_buf->cache *= uvm.pagesize; mem_stats_buf->free *= uvm.pagesize; mem_stats_buf->used = mem_stats_buf->total - mem_stats_buf->free; #elif defined(HAVE_STRUCT_UVMEXP) && defined(VM_UVMEXP) mib[0] = CTL_VM; mib[1] = VM_UVMEXP; if (sysctl(mib, 2, &uvm, &size, NULL, 0) < 0) { RETURN_WITH_SET_ERROR_WITH_ERRNO("mem", SG_ERROR_SYSCTL, "CTL_VM.VM_UVMEXP"); } mem_stats_buf->total = uvm.npages; mem_stats_buf->cache = 0; # if defined(HAVE_STRUCT_UVMEXP_FILEPAGES) mem_stats_buf->cache += uvm.filepages; # endif # if defined(HAVE_STRUCT_UVMEXP_EXECPAGES) mem_stats_buf->cache += uvm.execpages; # endif mem_stats_buf->free = uvm.free + mem_stats_buf->cache; mem_stats_buf->total *= uvm.pagesize; mem_stats_buf->cache *= uvm.pagesize; mem_stats_buf->free *= uvm.pagesize; mem_stats_buf->used = mem_stats_buf->total - mem_stats_buf->free; #elif defined(HAVE_HOST_STATISTICS) || defined(HAVE_HOST_STATISTICS64) # if defined(HAVE_HOST_STATISTICS64) count = HOST_VM_INFO64_COUNT; rc = host_statistics64(self_host_port, HOST_VM_INFO64, (host_info64_t)(&vm_stats), &count); # else count = HOST_VM_INFO_COUNT; rc = host_statistics(self_host_port, HOST_VM_INFO, (host_info_t)(&vm_stats), &count); # endif if( rc != KERN_SUCCESS ) { RETURN_WITH_SET_ERROR_WITH_ERRNO_CODE( "mem", SG_ERROR_MACHCALL, rc, "host_statistics" ); } /* * XXX check host_info(host_basic_info) ... for memory_size */ mem_stats_buf->free = vm_stats.free_count - vm_stats.speculative_count; mem_stats_buf->free += vm_stats.inactive_count; mem_stats_buf->free *= (size_t)sys_page_size; mem_stats_buf->total = vm_stats.active_count + vm_stats.wire_count + vm_stats.inactive_count + vm_stats.free_count; mem_stats_buf->total *= (size_t)sys_page_size; mem_stats_buf->used = mem_stats_buf->total - mem_stats_buf->free; mem_stats_buf->cache = 0; #elif defined(FREEBSD) || defined(DFBSD) /*returns pages*/ size = sizeof(total_count); if (sysctlbyname("vm.stats.vm.v_page_count", &total_count, &size, NULL, 0) < 0) { RETURN_WITH_SET_ERROR_WITH_ERRNO("mem", SG_ERROR_SYSCTLBYNAME, "vm.stats.vm.v_page_count"); } /*returns pages*/ size = sizeof(free_count); if (sysctlbyname("vm.stats.vm.v_free_count", &free_count, &size, NULL, 0) < 0) { RETURN_WITH_SET_ERROR_WITH_ERRNO("mem", SG_ERROR_SYSCTLBYNAME, "vm.stats.vm.v_free_count"); } size = sizeof(inactive_count); if (sysctlbyname("vm.stats.vm.v_inactive_count", &inactive_count , &size, NULL, 0) < 0) { RETURN_WITH_SET_ERROR_WITH_ERRNO("mem", SG_ERROR_SYSCTLBYNAME, "vm.stats.vm.v_inactive_count"); } size = sizeof(cache_count); if (sysctlbyname("vm.stats.vm.v_cache_count", &cache_count, &size, NULL, 0) < 0) { RETURN_WITH_SET_ERROR_WITH_ERRNO("mem", SG_ERROR_SYSCTLBYNAME, "vm.stats.vm.v_cache_count"); } /* Of couse nothing is ever that simple :) And I have inactive pages to * deal with too. So I'm going to add them to free memory :) */ mem_stats_buf->cache = (size_t)cache_count; mem_stats_buf->cache *= (size_t)sys_page_size; mem_stats_buf->total = (size_t)total_count; mem_stats_buf->total *= (size_t)sys_page_size; mem_stats_buf->free = (size_t)free_count + inactive_count + cache_count; mem_stats_buf->free *= (size_t)sys_page_size; mem_stats_buf->used = mem_stats_buf->total - mem_stats_buf->free; #elif defined(WIN32) memstats.dwLength = sizeof(memstats); if (!GlobalMemoryStatusEx(&memstats)) { RETURN_WITH_SET_ERROR_WITH_ERRNO("mem", SG_ERROR_MEMSTATUS, NULL); } mem_stats_buf->free = memstats.ullAvailPhys; mem_stats_buf->total = memstats.ullTotalPhys; mem_stats_buf->used = mem_stat.total - mem_stat.free; if(read_counter_large(SG_WIN32_MEM_CACHE, &mem_stats_buf->cache)) mem_stats_buf->cache = 0; #elif defined(HAVE_STRUCT_VMTOTAL) /* The code in this section is based on the code in the OpenBSD * top utility, located at src/usr.bin/top/machine.c in the * OpenBSD source tree. * * For fun, and like OpenBSD top, we will do the multiplication * converting the memory stats in pages to bytes in base 2. */ size = sizeof(vmtotal); if (sysctl(vmtotal_mib, 2, &vmtotal, &size, NULL, 0) < 0) { RETURN_WITH_SET_ERROR_WITH_ERRNO("mem", SG_ERROR_SYSCTLBYNAME, "vm.vmtotal"); } /* Convert the raw stats to bytes, and return these to the caller */ mem_stats_buf->used = (unsigned long long)vmtotal.t_rm; /* total real mem in use */ mem_stats_buf->used *= sys_page_size; /* XXX scan top source to look how it determines cache size */ mem_stats_buf->cache = 0; /* no cache stats */ mem_stats_buf->free = (unsigned long long)vmtotal.t_free; /* free memory pages */ mem_stats_buf->free *= sys_page_size; # ifdef HW_PHYSMEM mib[0] = CTL_HW; mib[1] = HW_PHYSMEM; size = sizeof(total_mem); if (sysctl(mib, 2, &total_mem, &size, NULL, 0) < 0) { RETURN_WITH_SET_ERROR_WITH_ERRNO("mem", SG_ERROR_SYSCTL, "CTL_HW.HW_PHYSMEM"); } mem_stats_buf->total = total_mem; # else mem_stats_buf->total = (mem_stats_buf->used + mem_stats_buf->free); # endif # ifdef HW_USERMEM mib[0] = CTL_HW; mib[1] = HW_USERMEM; size = sizeof(user_mem); if (sysctl(mib, 2, &user_mem, &size, NULL, 0) < 0) { RETURN_WITH_SET_ERROR_WITH_ERRNO("mem", SG_ERROR_SYSCTL, "CTL_HW.HW_USERMEM"); } mem_stats_buf->used += total_mem - user_mem; # endif #else RETURN_WITH_SET_ERROR("mem", SG_ERROR_UNSUPPORTED, OS_TYPE); #endif mem_stats_buf->systime = time(NULL); return SG_ERROR_NONE; }
static void update_vmstat(ZBX_VMSTAT_DATA *vmstat) { #if defined(HAVE_LIBPERFSTAT) int now; zbx_uint64_t dlcpu_us, dlcpu_sy, dlcpu_id, dlcpu_wa, lcputime; perfstat_memory_total_t memstats; perfstat_cpu_total_t cpustats; perfstat_disk_total_t diskstats; #ifdef _AIXVERSION_530 zbx_uint64_t dpcpu_us, dpcpu_sy, dpcpu_id, dpcpu_wa, pcputime, dtimebase; zbx_uint64_t delta_purr, entitled_purr, unused_purr, r1, r2; perfstat_partition_total_t lparstats; #ifdef HAVE_AIXOSLEVEL_530006 zbx_uint64_t didle_donated_purr, dbusy_donated_purr, didle_stolen_purr, dbusy_stolen_purr; #endif /* HAVE_AIXOSLEVEL_530006 */ #endif /* _AIXVERSION_530 */ now = (int)time(NULL); /* retrieve the metrics * Upon successful completion, the number of structures filled is returned. * If unsuccessful, a value of -1 is returned and the errno global variable is set */ #ifdef _AIXVERSION_530 if (-1 == perfstat_partition_total(NULL, &lparstats, sizeof(lparstats), 1)) { zabbix_log(LOG_LEVEL_DEBUG, "perfstat_partition_total: %s", zbx_strerror(errno)); return; } #endif if (-1 == perfstat_cpu_total(NULL, &cpustats, sizeof(cpustats), 1)) { zabbix_log(LOG_LEVEL_DEBUG, "perfstat_cpu_total: %s", zbx_strerror(errno)); return; } if (-1 == perfstat_memory_total(NULL, &memstats, sizeof(memstats), 1)) { zabbix_log(LOG_LEVEL_DEBUG, "perfstat_memory_total: %s", zbx_strerror(errno)); return; } if (-1 == perfstat_disk_total(NULL, &diskstats, sizeof(diskstats), 1)) { zabbix_log(LOG_LEVEL_DEBUG, "perfstat_disk_total: %s", zbx_strerror(errno)); return; } if (last_clock && now > last_clock) { /* --- kthr --- */ vmstat->kthr_r = (double)(cpustats.runque - last_runque) / (double)(now - last_clock); vmstat->kthr_b = (double)(cpustats.swpque - last_swpque) / (double)(now - last_clock); /* --- page --- */ vmstat->fi = (double)(memstats.pgins - last_pgins) / (double)(now - last_clock); vmstat->fo = (double)(memstats.pgouts - last_pgouts) / (double)(now - last_clock); vmstat->pi = (double)(memstats.pgspins - last_pgspins) / (double)(now - last_clock); vmstat->po = (double)(memstats.pgspouts - last_pgspouts) / (double)(now - last_clock); vmstat->fr = (double)(memstats.cycles - last_cycles) / (double)(now - last_clock); vmstat->sr = (double)(memstats.scans - last_scans) / (double)(now - last_clock); /* -- faults -- */ vmstat->in = (double)(cpustats.devintrs - last_devintrs) / (double)(now - last_clock); vmstat->sy = (double)(cpustats.syscall - last_syscall) / (double)(now - last_clock); vmstat->cs = (double)(cpustats.pswitch - last_pswitch) / (double)(now - last_clock); #ifdef _AIXVERSION_530 /* --- cpu ---- */ dpcpu_us = lparstats.puser - last_puser; dpcpu_sy = lparstats.psys - last_psys; dpcpu_id = lparstats.pidle - last_pidle; dpcpu_wa = lparstats.pwait - last_pwait; delta_purr = pcputime = dpcpu_us + dpcpu_sy + dpcpu_id + dpcpu_wa; #endif /* _AIXVERSION_530 */ dlcpu_us = cpustats.user - last_user; dlcpu_sy = cpustats.sys - last_sys; dlcpu_id = cpustats.idle - last_idle; dlcpu_wa = cpustats.wait - last_wait; lcputime = dlcpu_us + dlcpu_sy + dlcpu_id + dlcpu_wa; #ifdef _AIXVERSION_530 /* Distribute the donated and stolen purr to the existing purr buckets in case if donation is enabled. */ #ifdef HAVE_AIXOSLEVEL_530006 if (lparstats.type.b.donate_enabled) { didle_donated_purr = lparstats.idle_donated_purr - last_idle_donated_purr; dbusy_donated_purr = lparstats.busy_donated_purr - last_busy_donated_purr; didle_stolen_purr = lparstats.idle_stolen_purr - last_idle_stolen_purr; dbusy_stolen_purr = lparstats.busy_stolen_purr - last_busy_stolen_purr; if (0 != dlcpu_id + dlcpu_wa) { r1 = dlcpu_id / (dlcpu_id + dlcpu_wa); r2 = dlcpu_wa / (dlcpu_id + dlcpu_wa); } else r1 = r2 = 0; dpcpu_us += didle_donated_purr * r1 + didle_stolen_purr * r1; dpcpu_wa += didle_donated_purr * r2 + didle_stolen_purr * r2; dpcpu_sy += dbusy_donated_purr + dbusy_stolen_purr; delta_purr += didle_donated_purr + dbusy_donated_purr + didle_stolen_purr + dbusy_stolen_purr; pcputime = delta_purr; } #endif /* HAVE_AIXOSLEVEL_530006 */ dtimebase = lparstats.timebase_last - last_timebase_last; vmstat->ent = (double)lparstats.entitled_proc_capacity / 100.0; if (lparstats.type.b.shared_enabled) { entitled_purr = dtimebase * vmstat->ent; if (entitled_purr < delta_purr) { /* when above entitlement, use consumption in percentages */ entitled_purr = delta_purr; } unused_purr = entitled_purr - delta_purr; /* distribute unused purr in wait and idle proportionally to logical wait and idle */ if (0 != dlcpu_wa + dlcpu_id) { dpcpu_wa += unused_purr * ((double)dlcpu_wa / (double)(dlcpu_wa + dlcpu_id)); dpcpu_id += unused_purr * ((double)dlcpu_id / (double)(dlcpu_wa + dlcpu_id)); } pcputime = entitled_purr; } /* Physical Processor Utilization */ vmstat->cpu_us = (double)dpcpu_us * 100.0 / (double)pcputime; vmstat->cpu_sy = (double)dpcpu_sy * 100.0 / (double)pcputime; vmstat->cpu_id = (double)dpcpu_id * 100.0 / (double)pcputime; vmstat->cpu_wa = (double)dpcpu_wa * 100.0 / (double)pcputime; if (lparstats.type.b.shared_enabled) { /* Physical Processor Consumed */ vmstat->cpu_pc = (double)delta_purr / (double)dtimebase; /* Percentage of Entitlement Consumed */ vmstat->cpu_ec = (double)(vmstat->cpu_pc / vmstat->ent) * 100.0; /* Logical Processor Utilization */ vmstat->cpu_lbusy = (double)(dlcpu_us + dlcpu_sy) * 100.0 / (double)lcputime; if (lparstats.type.b.pool_util_authority) { /* Available Pool Processor (app) */ vmstat->cpu_app = (double)(lparstats.pool_idle_time - last_pool_idle_time) / (XINTFRAC * (double)dtimebase); } } #else /* not _AIXVERSION_530 */ /* Physical Processor Utilization */ vmstat->cpu_us = (double)dlcpu_us * 100.0 / (double)lcputime; vmstat->cpu_sy = (double)dlcpu_sy * 100.0 / (double)lcputime; vmstat->cpu_id = (double)dlcpu_id * 100.0 / (double)lcputime; vmstat->cpu_wa = (double)dlcpu_wa * 100.0 / (double)lcputime; #endif /* _AIXVERSION_530 */ /* --- disk --- */ vmstat->disk_bps = 512 * ((diskstats.wblks - last_wblks) + (diskstats.rblks - last_rblks)) / (now - last_clock); vmstat->disk_tps = (double)(diskstats.xfers - last_xfers) / (double)(now - last_clock); /* -- memory -- */ #ifdef HAVE_AIXOSLEVEL_520004 vmstat->mem_avm = (zbx_uint64_t)memstats.virt_active; /* Active virtual pages. Virtual pages are considered active if they have been accessed */ #endif vmstat->mem_fre = (zbx_uint64_t)memstats.real_free; /* free real memory (in 4KB pages) */ } else { #ifdef _AIXVERSION_530 vmstat->shared_enabled = (unsigned char)lparstats.type.b.shared_enabled; vmstat->pool_util_authority = (unsigned char)lparstats.type.b.pool_util_authority; #endif #ifdef HAVE_AIXOSLEVEL_520004 vmstat->aix52stats = 1; #endif } /* saving last values */ last_clock = now; /* --- kthr -- */ last_runque = (zbx_uint64_t)cpustats.runque; last_swpque = (zbx_uint64_t)cpustats.swpque; /* --- page --- */ last_pgins = (zbx_uint64_t)memstats.pgins; last_pgouts = (zbx_uint64_t)memstats.pgouts; last_pgspins = (zbx_uint64_t)memstats.pgspins; last_pgspouts = (zbx_uint64_t)memstats.pgspouts; last_cycles = (zbx_uint64_t)memstats.cycles; last_scans = (zbx_uint64_t)memstats.scans; /* -- faults -- */ last_devintrs = (zbx_uint64_t)cpustats.devintrs; last_syscall = (zbx_uint64_t)cpustats.syscall; last_pswitch = (zbx_uint64_t)cpustats.pswitch; /* --- cpu ---- */ #ifdef _AIXVERSION_530 last_puser = (zbx_uint64_t)lparstats.puser; last_psys = (zbx_uint64_t)lparstats.psys; last_pidle = (zbx_uint64_t)lparstats.pidle; last_pwait = (zbx_uint64_t)lparstats.pwait; last_timebase_last = (zbx_uint64_t)lparstats.timebase_last; last_pool_idle_time = (zbx_uint64_t)lparstats.pool_idle_time; #ifdef HAVE_AIXOSLEVEL_530006 last_idle_donated_purr = (zbx_uint64_t)lparstats.idle_donated_purr; last_busy_donated_purr = (zbx_uint64_t)lparstats.busy_donated_purr; last_idle_stolen_purr = (zbx_uint64_t)lparstats.idle_stolen_purr; last_busy_stolen_purr = (zbx_uint64_t)lparstats.busy_stolen_purr; #endif /* HAVE_AIXOSLEVEL_530006 */ #endif /* _AIXVERSION_530 */ last_user = (zbx_uint64_t)cpustats.user; last_sys = (zbx_uint64_t)cpustats.sys; last_idle = (zbx_uint64_t)cpustats.idle; last_wait = (zbx_uint64_t)cpustats.wait; last_xfers = (zbx_uint64_t)diskstats.xfers; last_wblks = (zbx_uint64_t)diskstats.wblks; last_rblks = (zbx_uint64_t)diskstats.rblks; #endif /* HAVE_LIBPERFSTAT */ }
static sg_error sg_get_page_stats_int(sg_page_stats *page_stats_buf){ #ifdef SOLARIS kstat_ctl_t *kc; kstat_t *ksp; cpu_stat_t cs; #elif defined(LINUX) || defined(CYGWIN) FILE *f; #define LINE_BUF_SIZE 256 char line_buf[LINE_BUF_SIZE]; #elif defined(HAVE_HOST_STATISTICS) || defined(HAVE_HOST_STATISTICS64) # if defined(HAVE_HOST_STATISTICS64) struct vm_statistics64 vm_stats; # else struct vm_statistics vm_stats; # endif mach_msg_type_number_t count; kern_return_t rc; #elif defined(HAVE_STRUCT_UVMEXP_SYSCTL) && defined(VM_UVMEXP2) int mib[2]; struct uvmexp_sysctl uvm; size_t size = sizeof(uvm); #elif defined(HAVE_STRUCT_UVMEXP) && defined(VM_UVMEXP) int mib[2]; struct uvmexp uvm; size_t size = sizeof(uvm); #elif defined(FREEBSD) || defined(DFBSD) size_t size; #elif defined(NETBSD) || defined(OPENBSD) int mib[2]; struct uvmexp uvm; size_t size = sizeof(uvm); #elif defined(AIX) perfstat_memory_total_t mem; #elif defined(HPUX) struct pst_vminfo vminfo; #endif page_stats_buf->systime = time(NULL); page_stats_buf->pages_pagein=0; page_stats_buf->pages_pageout=0; #ifdef SOLARIS if ((kc = kstat_open()) == NULL) { RETURN_WITH_SET_ERROR("page", SG_ERROR_KSTAT_OPEN, NULL); } for (ksp = kc->kc_chain; ksp!=NULL; ksp = ksp->ks_next) { if ((strcmp(ksp->ks_module, "cpu_stat")) != 0) continue; if (kstat_read(kc, ksp, &cs) == -1) continue; page_stats_buf->pages_pagein += (long long)cs.cpu_vminfo.pgpgin; page_stats_buf->pages_pageout += (long long)cs.cpu_vminfo.pgpgout; } kstat_close(kc); #elif defined(LINUX) || defined(CYGWIN) if ((f = fopen("/proc/vmstat", "r")) != NULL) { unsigned matches = 0; while( (matches < 2) && (fgets(line_buf, sizeof(line_buf), f) != NULL) ) { unsigned long long value; if (sscanf(line_buf, "%*s %llu", &value) != 1) continue; if (strncmp(line_buf, "pgpgin ", 7) == 0) { page_stats_buf->pages_pagein = value; ++matches; } else if (strncmp(line_buf, "pgpgout ", 8) == 0) { page_stats_buf->pages_pageout = value; ++matches; } } fclose(f); if( matches < 2 ) { RETURN_WITH_SET_ERROR( "page", SG_ERROR_PARSE, "/proc/vmstat" ); } } else if ((f = fopen("/proc/stat", "r")) != NULL) { if (sg_f_read_line(f, line_buf, sizeof(line_buf), "page") == NULL) { fclose(f); RETURN_FROM_PREVIOUS_ERROR( "page", sg_get_error() ); } fclose(f); if( sscanf( line_buf, "page %llu %llu", &page_stats_buf->pages_pagein, &page_stats_buf->pages_pageout ) != 2 ) { RETURN_WITH_SET_ERROR("page", SG_ERROR_PARSE, "page"); } } else { RETURN_WITH_SET_ERROR_WITH_ERRNO("page", SG_ERROR_OPEN, "/proc/stat"); } #elif defined(HAVE_HOST_STATISTICS) || defined(HAVE_HOST_STATISTICS64) self_host_port = mach_host_self(); # if defined(HAVE_HOST_STATISTICS64) count = HOST_VM_INFO64_COUNT; rc = host_statistics64(self_host_port, HOST_VM_INFO64, (host_info64_t)(&vm_stats), &count); # else count = HOST_VM_INFO_COUNT; rc = host_statistics(self_host_port, HOST_VM_INFO, (host_info_t)(&vm_stats), &count); # endif if( rc != KERN_SUCCESS ) { RETURN_WITH_SET_ERROR_WITH_ERRNO_CODE( "mem", SG_ERROR_MACHCALL, rc, "host_statistics" ); } page_stats_buf->pages_pagein = vm_stats.pageins; page_stats_buf->pages_pageout = vm_stats.pageouts; #elif defined(HAVE_STRUCT_UVMEXP_SYSCTL) && defined(VM_UVMEXP2) mib[0] = CTL_VM; mib[1] = VM_UVMEXP2; if (sysctl(mib, 2, &uvm, &size, NULL, 0) < 0) { RETURN_WITH_SET_ERROR_WITH_ERRNO("mem", SG_ERROR_SYSCTL, "CTL_VM.VM_UVMEXP2"); } page_stats_buf->pages_pagein = uvm.pgswapin; page_stats_buf->pages_pageout = uvm.pgswapout; #elif defined(HAVE_STRUCT_UVMEXP) && defined(VM_UVMEXP) mib[0] = CTL_VM; mib[1] = VM_UVMEXP; if (sysctl(mib, 2, &uvm, &size, NULL, 0) < 0) { RETURN_WITH_SET_ERROR_WITH_ERRNO("mem", SG_ERROR_SYSCTL, "CTL_VM.VM_UVMEXP"); } page_stats_buf->pages_pagein = uvm.pgswapin; page_stats_buf->pages_pageout = uvm.pgswapout; #elif defined(FREEBSD) || defined(DFBSD) size = sizeof(page_stats_buf->pages_pagein); if (sysctlbyname("vm.stats.vm.v_swappgsin", &page_stats_buf->pages_pagein, &size, NULL, 0) < 0) { RETURN_WITH_SET_ERROR_WITH_ERRNO("page", SG_ERROR_SYSCTLBYNAME, "vm.stats.vm.v_swappgsin"); } size = sizeof(page_stats_buf->pages_pageout); if (sysctlbyname("vm.stats.vm.v_swappgsout", &page_stats_buf->pages_pageout, &size, NULL, 0) < 0) { RETURN_WITH_SET_ERROR_WITH_ERRNO("page", SG_ERROR_SYSCTLBYNAME, "vm.stats.vm.v_swappgsout"); } #elif defined(AIX) /* return code is number of structures returned */ if(perfstat_memory_total(NULL, &mem, sizeof(perfstat_memory_total_t), 1) != 1) { RETURN_WITH_SET_ERROR_WITH_ERRNO("page", SG_ERROR_SYSCTLBYNAME, "perfstat_memory_total"); } page_stats_buf->pages_pagein = mem.pgins; page_stats_buf->pages_pageout = mem.pgouts; #elif defined(HPUX) if( pstat_getvminfo( &vminfo, sizeof(vminfo), 1, 0 ) == -1 ) { RETURN_WITH_SET_ERROR_WITH_ERRNO("page", SG_ERROR_SYSCTLBYNAME, "pstat_getswap"); } page_stats_buf->pages_pagein = vminfo.psv_spgin; page_stats_buf->pages_pageout = vminfo.psv_spgout; #else RETURN_WITH_SET_ERROR("page", SG_ERROR_UNSUPPORTED, OS_TYPE); #endif return SG_ERROR_NONE; }
sg_page_stats *sg_get_page_stats(){ #ifdef SOLARIS kstat_ctl_t *kc; kstat_t *ksp; cpu_stat_t cs; #endif #if defined(LINUX) || defined(CYGWIN) FILE *f; char *line_ptr; #endif #if defined(FREEBSD) || defined(DFBSD) size_t size; #endif #if defined(NETBSD) || defined(OPENBSD) struct uvmexp *uvm; #endif #ifdef AIX perfstat_memory_total_t mem; #endif #ifdef HPUX struct pst_vminfo vminfo; #endif page_stats.systime = time(NULL); page_stats.pages_pagein=0; page_stats.pages_pageout=0; #ifdef SOLARIS if ((kc = kstat_open()) == NULL) { sg_set_error(SG_ERROR_KSTAT_OPEN, NULL); return NULL; } for (ksp = kc->kc_chain; ksp!=NULL; ksp = ksp->ks_next) { if ((strcmp(ksp->ks_module, "cpu_stat")) != 0) continue; if (kstat_read(kc, ksp, &cs) == -1) { continue; } page_stats.pages_pagein+=(long long)cs.cpu_vminfo.pgpgin; page_stats.pages_pageout+=(long long)cs.cpu_vminfo.pgpgout; } kstat_close(kc); #endif #if defined(LINUX) || defined(CYGWIN) if ((f = fopen("/proc/vmstat", "r")) != NULL) { while ((line_ptr = sg_f_read_line(f, "")) != NULL) { long long value; if (sscanf(line_ptr, "%*s %lld", &value) != 1) { continue; } if (strncmp(line_ptr, "pgpgin ", 7) == 0) { page_stats.pages_pagein = value; } else if (strncmp(line_ptr, "pgpgout ", 8) == 0) { page_stats.pages_pageout = value; } } fclose(f); } else if ((f = fopen("/proc/stat", "r")) != NULL) { if ((line_ptr = sg_f_read_line(f, "page")) == NULL) { sg_set_error(SG_ERROR_PARSE, "page"); fclose(f); return NULL; } if (sscanf(line_ptr, "page %lld %lld", &page_stats.pages_pagein, &page_stats.pages_pageout) != 2) { sg_set_error(SG_ERROR_PARSE, "page"); fclose(f); return NULL; } fclose(f); } else { sg_set_error_with_errno(SG_ERROR_OPEN, "/proc/stat"); return NULL; } #endif #if defined(FREEBSD) || defined(DFBSD) size = sizeof page_stats.pages_pagein; if (sysctlbyname("vm.stats.vm.v_swappgsin", &page_stats.pages_pagein, &size, NULL, 0) < 0){ sg_set_error_with_errno(SG_ERROR_SYSCTLBYNAME, "vm.stats.vm.v_swappgsin"); return NULL; } size = sizeof page_stats.pages_pageout; if (sysctlbyname("vm.stats.vm.v_swappgsout", &page_stats.pages_pageout, &size, NULL, 0) < 0){ sg_set_error_with_errno(SG_ERROR_SYSCTLBYNAME, "vm.stats.vm.v_swappgsout"); return NULL; } #endif #if defined(NETBSD) || defined(OPENBSD) if ((uvm = sg_get_uvmexp()) == NULL) { return NULL; } page_stats.pages_pagein = uvm->pgswapin; page_stats.pages_pageout = uvm->pgswapout; #endif #ifdef AIX /* return code is number of structures returned */ if(perfstat_memory_total(NULL, &mem, sizeof(perfstat_memory_total_t), 1) != 1) { sg_set_error_with_errno(SG_ERROR_SYSCTLBYNAME, "perfstat_memory_total"); return NULL; } page_stats.pages_pagein = mem.pgins; page_stats.pages_pageout = mem.pgouts; #endif #ifdef HPUX if( pstat_getvminfo( &vminfo, sizeof(vminfo), 1, 0 ) == -1 ) { sg_set_error_with_errno(SG_ERROR_SYSCTLBYNAME, "pstat_getswap"); return NULL; }; page_stats.pages_pagein = vminfo.psv_spgin; page_stats.pages_pageout = vminfo.psv_spgout; #endif #ifdef WIN32 sg_set_error(SG_ERROR_UNSUPPORTED, "Win32"); return NULL; #endif return &page_stats; }
static int swap_read (void) { #if KERNEL_LINUX FILE *fh; char buffer[1024]; char *fields[8]; int numfields; _Bool old_kernel=0; derive_t swap_used = 0; derive_t swap_cached = 0; derive_t swap_free = 0; derive_t swap_total = 0; derive_t swap_in = 0; derive_t swap_out = 0; if ((fh = fopen ("/proc/meminfo", "r")) == NULL) { char errbuf[1024]; WARNING ("memory: fopen: %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } while (fgets (buffer, sizeof (buffer), fh) != NULL) { numfields = strsplit (buffer, fields, STATIC_ARRAY_SIZE (fields)); if (numfields < 2) continue; if (strcasecmp (fields[0], "SwapTotal:") == 0) strtoderive (fields[1], &swap_total); else if (strcasecmp (fields[0], "SwapFree:") == 0) strtoderive (fields[1], &swap_free); else if (strcasecmp (fields[0], "SwapCached:") == 0) strtoderive (fields[1], &swap_cached); } if (fclose (fh)) { char errbuf[1024]; WARNING ("memory: fclose: %s", sstrerror (errno, errbuf, sizeof (errbuf))); } if ((swap_total == 0LL) || ((swap_free + swap_cached) > swap_total)) return (-1); swap_used = swap_total - (swap_free + swap_cached); if ((fh = fopen ("/proc/vmstat", "r")) == NULL) { // /proc/vmstat does not exist in kernels <2.6 if ((fh = fopen ("/proc/stat", "r")) == NULL ) { char errbuf[1024]; WARNING ("swap: fopen: %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } else old_kernel = 1; } while (fgets (buffer, sizeof (buffer), fh) != NULL) { numfields = strsplit (buffer, fields, STATIC_ARRAY_SIZE (fields)); if (!old_kernel) { if (numfields != 2) continue; if (strcasecmp ("pswpin", fields[0]) != 0) strtoderive (fields[1], &swap_in); else if (strcasecmp ("pswpout", fields[0]) == 0) strtoderive (fields[1], &swap_out); } else /* if (old_kernel) */ { if (numfields != 3) continue; if (strcasecmp ("page", fields[0]) == 0) { strtoderive (fields[1], &swap_in); strtoderive (fields[2], &swap_out); } } } /* while (fgets) */ if (fclose (fh)) { char errbuf[1024]; WARNING ("swap: fclose: %s", sstrerror (errno, errbuf, sizeof (errbuf))); } swap_submit ("used", 1024 * swap_used, DS_TYPE_GAUGE); swap_submit ("free", 1024 * swap_free, DS_TYPE_GAUGE); swap_submit ("cached", 1024 * swap_cached, DS_TYPE_GAUGE); swap_submit ("in", swap_in, DS_TYPE_DERIVE); swap_submit ("out", swap_out, DS_TYPE_DERIVE); /* #endif KERNEL_LINUX */ #elif HAVE_LIBKSTAT derive_t swap_alloc; derive_t swap_resv; derive_t swap_avail; struct anoninfo ai; if (swapctl (SC_AINFO, &ai) == -1) { char errbuf[1024]; ERROR ("swap plugin: swapctl failed: %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } /* * Calculations from: * http://cvs.opensolaris.org/source/xref/on/usr/src/cmd/swap/swap.c * Also see: * http://www.itworld.com/Comp/2377/UIR980701perf/ (outdated?) * /usr/include/vm/anon.h * * In short, swap -s shows: allocated + reserved = used, available * * However, Solaris does not allow to allocated/reserved more than the * available swap (physical memory + disk swap), so the pedant may * prefer: allocated + unallocated = reserved, available * * We map the above to: used + resv = n/a, free * * Does your brain hurt yet? - Christophe Kalt * * Oh, and in case you wonder, * swap_alloc = pagesize * ( ai.ani_max - ai.ani_free ); * can suffer from a 32bit overflow. */ swap_alloc = (derive_t) ((ai.ani_max - ai.ani_free) * pagesize); swap_resv = (derive_t) ((ai.ani_resv + ai.ani_free - ai.ani_max) * pagesize); swap_avail = (derive_t) ((ai.ani_max - ai.ani_resv) * pagesize); swap_submit ("used", swap_alloc, DS_TYPE_GAUGE); swap_submit ("free", swap_avail, DS_TYPE_GAUGE); swap_submit ("reserved", swap_resv, DS_TYPE_GAUGE); /* #endif HAVE_LIBKSTAT */ #elif HAVE_SWAPCTL struct swapent *swap_entries; int swap_num; int status; int i; derive_t used = 0; derive_t total = 0; /* * XXX: This is the syntax for the *BSD `swapctl', which has the * following prototype: * swapctl (int cmd, void *arg, int misc); * * HP-UX and Solaris (and possibly other UNIXes) provide `swapctl', * too, but with the following prototype: * swapctl (int cmd, void *arg); * * Solaris is usually handled in the KSTAT case above. For other UNIXes * a separate case for the other version of `swapctl' may be necessary. */ swap_num = swapctl (SWAP_NSWAP, NULL, 0); if (swap_num < 0) { ERROR ("swap plugin: swapctl (SWAP_NSWAP) failed with status %i.", swap_num); return (-1); } else if (swap_num == 0) return (0); swap_entries = calloc (swap_num, sizeof (*swap_entries)); if (swap_entries == NULL) { ERROR ("swap plugin: calloc failed."); return (-1); } status = swapctl (SWAP_STATS, swap_entries, swap_num); if (status != swap_num) { ERROR ("swap plugin: swapctl (SWAP_STATS) failed with status %i.", status); sfree (swap_entries); return (-1); } #if defined(DEV_BSIZE) && (DEV_BSIZE > 0) # define C_SWAP_BLOCK_SIZE ((derive_t) DEV_BSIZE) #else # define C_SWAP_BLOCK_SIZE ((derive_t) 512) #endif for (i = 0; i < swap_num; i++) { if ((swap_entries[i].se_flags & SWF_ENABLE) == 0) continue; used += ((derive_t) swap_entries[i].se_inuse) * C_SWAP_BLOCK_SIZE; total += ((derive_t) swap_entries[i].se_nblks) * C_SWAP_BLOCK_SIZE; } if (total < used) { ERROR ("swap plugin: Total swap space (%"PRIu64") " "is less than used swap space (%"PRIu64").", total, used); return (-1); } swap_submit ("used", used, DS_TYPE_GAUGE); swap_submit ("free", total - used, DS_TYPE_GAUGE); sfree (swap_entries); /* #endif HAVE_SWAPCTL */ #elif defined(VM_SWAPUSAGE) int mib[3]; size_t mib_len; struct xsw_usage sw_usage; size_t sw_usage_len; mib_len = 2; mib[0] = CTL_VM; mib[1] = VM_SWAPUSAGE; sw_usage_len = sizeof (struct xsw_usage); if (sysctl (mib, mib_len, &sw_usage, &sw_usage_len, NULL, 0) != 0) return (-1); /* The returned values are bytes. */ swap_submit ("used", (derive_t) sw_usage.xsu_used, DS_TYPE_GAUGE); swap_submit ("free", (derive_t) sw_usage.xsu_avail, DS_TYPE_GAUGE); /* #endif VM_SWAPUSAGE */ #elif HAVE_LIBKVM_GETSWAPINFO struct kvm_swap data_s; int status; derive_t used; derive_t free; derive_t total; if (kvm_obj == NULL) return (-1); /* only one structure => only get the grand total, no details */ status = kvm_getswapinfo (kvm_obj, &data_s, 1, 0); if (status == -1) return (-1); total = (derive_t) data_s.ksw_total; used = (derive_t) data_s.ksw_used; total *= (derive_t) kvm_pagesize; used *= (derive_t) kvm_pagesize; free = total - used; swap_submit ("used", used, DS_TYPE_GAUGE); swap_submit ("free", free, DS_TYPE_GAUGE); /* #endif HAVE_LIBKVM_GETSWAPINFO */ #elif HAVE_LIBSTATGRAB sg_swap_stats *swap; swap = sg_get_swap_stats (); if (swap == NULL) return (-1); swap_submit ("used", (derive_t) swap->used, DS_TYPE_GAUGE); swap_submit ("free", (derive_t) swap->free, DS_TYPE_GAUGE); /* #endif HAVE_LIBSTATGRAB */ #elif HAVE_PERFSTAT if(perfstat_memory_total(NULL, &pmemory, sizeof(perfstat_memory_total_t), 1) < 0) { char errbuf[1024]; WARNING ("memory plugin: perfstat_memory_total failed: %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } swap_submit ("used", (derive_t) (pmemory.pgsp_total - pmemory.pgsp_free) * pagesize, DS_TYPE_GAUGE); swap_submit ("free", (derive_t) pmemory.pgsp_free * pagesize , DS_TYPE_GAUGE); #endif /* HAVE_PERFSTAT */ return (0); } /* int swap_read */
/* * Data collection function take_snapshot starts here * Get data from kernel and save into the snapshot strutcs * Argument is the snapshot struct to save to. Global anyway, but looks nicer */ static int take_snapshot(struct cpu_stat_snapshot *css) { /* * Variables start here */ /* * High resolution time counter */ struct timeval tp; unsigned long long current_time; /* * see libperfstat.h, holds CPU/memory data */ perfstat_cpu_total_t cs; perfstat_memory_total_t ms; /* * The usual stuff to count on, err, by */ int i; /* * Variables end here */ /* * Function starts here */ /* * Get time */ gettimeofday(&tp, (struct timezone *)NULL); current_time = tp.tv_sec * (unsigned long long)1000000 + tp.tv_usec; /* * If we have just gotten the data, return the values from last run (skip if-clause) * This happens on a snmpwalk request. No need to read the perfstat again * if we just did it less than 2 seconds ago * Jumps into if-clause either when snapshot is empty or when too old */ if ((css->css_time == 0) || (current_time > css->css_time + 2000000)) { /* * Make sure we clean up before we put new data into snapshot */ memset(css, 0, sizeof *css); /* * Update timer */ css->css_time = current_time; if((perfstat_cpu_total((perfstat_id_t *)NULL, &cs, sizeof(perfstat_cpu_total_t), 1) > 0) && (perfstat_memory_total((perfstat_id_t *)NULL, &ms, sizeof(perfstat_memory_total_t), 1) > 0)) { css->css_cpus = cs.ncpus; css->css_swapin = ms.pgspins; css->css_swapout = ms.pgspouts; css->css_blocks_read = cs.sysread; css->css_blocks_write = cs.syswrite; css->css_interrupts = cs.devintrs + cs.softintrs; css->css_context_sw = cs.pswitch; css->css_cpu[CPU_USER] = cs.user; css->css_cpu[CPU_SYSTEM] = cs.sys; css->css_cpu[CPU_IDLE] = cs.idle; css->css_cpu[CPU_WAIT] = cs.wait; } } /* * All engines running at warp speed, no problems (if there are any engines, that is) */ return (cs.ncpus > 0 ? 0 : -1); } /* take_snapshot ends here */
/* * Load the latest memory usage statistics */ int netsnmp_mem_arch_load( netsnmp_cache *cache, void *magic ) { netsnmp_memory_info *mem; perfstat_memory_total_t pstat_mem; long pagesize; /* * Retrieve the memory information from the underlying O/S... */ if (perfstat_memory_total((perfstat_id_t *)NULL, &pstat_mem, sizeof(perfstat_memory_total_t), 1) < 1) { snmp_log(LOG_ERR, "memory_aix: perfstat_memory_total failed!\n"); return -1; } pagesize = getpagesize(); /* * ... and save this in a standard form. */ mem = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_PHYSMEM, 1 ); if (!mem) { snmp_log_perror("No Physical Memory info entry"); } else { if (!mem->descr) mem->descr = strdup("Physical memory"); mem->units = pagesize; /* or 4096 */ mem->size = pstat_mem.real_total; mem->free = pstat_mem.real_free; } /* ??? Duplicates Physical Memory statistics? */ mem = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_USERMEM, 1 ); if (!mem) { snmp_log_perror("No (user) Memory info entry"); } else { if (!mem->descr) mem->descr = strdup("Real memory"); mem->units = pagesize; /* or 4096 */ mem->size = pstat_mem.real_total; /* ? less system memory ? */ mem->free = pstat_mem.real_free; } 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 4096 */ mem->size = pstat_mem.virt_total; mem->free = pstat_mem.real_free + pstat_mem.pgsp_free; } 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; /* or 4096 */ mem->size = pstat_mem.pgsp_total; mem->free = pstat_mem.pgsp_free; mem->other = pstat_mem.pgsp_rsvd; } return 0; }
static int VM_MEMORY_FREE(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result) { #if defined(HAVE_LIBPERFSTAT) /* AIX 6.1 */ perfstat_memory_total_t m; zbx_uint64_t value; if (-1 == perfstat_memory_total(NULL, &m, sizeof(m), 1)) return SYSINFO_RET_FAIL; value = (zbx_uint64_t)m.real_free; /* free real memory (in 4KB pages) */ value <<= 12; SET_UI64_RESULT(result, value); return SYSINFO_RET_OK; #elif defined(HAVE_SYS_PSTAT_H) struct pst_static pst; struct pst_dynamic dyn; long page; if(pstat_getstatic(&pst, sizeof(pst), (size_t)1, 0) == -1) { return SYSINFO_RET_FAIL; } else { /* Get page size */ page = pst.page_size; /* return pst.physical_memory;*/ if (pstat_getdynamic(&dyn, sizeof(dyn), 1, 0) == -1) { return SYSINFO_RET_FAIL; } else { /* cout<<"total virtual memory allocated is " << dyn.psd_vm << " pages, " << dyn.psd_vm * page << " bytes" << endl; cout<<"active virtual memory is " << dyn.psd_avm <<" pages, " << dyn.psd_avm * page << " bytes" << endl; cout<<"total real memory is " << dyn.psd_rm << " pages, " << dyn.psd_rm * page << " bytes" << endl; cout<<"active real memory is " << dyn.psd_arm << " pages, " << dyn.psd_arm * page << " bytes" << endl; cout<<"free memory is " << dyn.psd_free << " pages, " << */ /* Free memory in bytes */ SET_UI64_RESULT(result, (zbx_uint64_t)dyn.psd_free * (zbx_uint64_t)page); return SYSINFO_RET_OK; } } #elif defined(HAVE_SYSINFO_FREERAM) struct sysinfo info; if( 0 == sysinfo(&info)) { #ifdef HAVE_SYSINFO_MEM_UNIT SET_UI64_RESULT(result, (zbx_uint64_t)info.freeram * (zbx_uint64_t)info.mem_unit); #else SET_UI64_RESULT(result, info.freeram); #endif return SYSINFO_RET_OK; } else { return SYSINFO_RET_FAIL; } #elif defined(HAVE_SYS_VMMETER_VMTOTAL) int mib[2],len; struct vmtotal v; len=sizeof(struct vmtotal); mib[0]=CTL_VM; mib[1]=VM_METER; sysctl(mib,2,&v,&len,NULL,0); SET_UI64_RESULT(result, v.t_free<<2); return SYSINFO_RET_OK; /* OS/X */ #elif defined(HAVE_MACH_HOST_INFO_H) vm_statistics_data_t page_info; vm_size_t pagesize; mach_msg_type_number_t count; kern_return_t kret; int ret; pagesize = 0; kret = host_page_size (mach_host_self(), &pagesize); count = HOST_VM_INFO_COUNT; kret = host_statistics (mach_host_self(), HOST_VM_INFO, (host_info_t)&page_info, &count); if (kret == KERN_SUCCESS) { double pw, pa, pi, pf, pu; pw = (double)page_info.wire_count*pagesize; pa = (double)page_info.active_count*pagesize; pi = (double)page_info.inactive_count*pagesize; pf = (double)page_info.free_count*pagesize; pu = pw+pa+pi; SET_UI64_RESULT(result, pf); ret = SYSINFO_RET_OK; } else { ret = SYSINFO_RET_FAIL; } return ret; #else return SYSINFO_RET_FAIL; #endif }
static int VM_MEMORY_TOTAL(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result) { #if defined(HAVE_LIBPERFSTAT) /* AIX 6.1 */ perfstat_memory_total_t m; zbx_uint64_t value; if (-1 == perfstat_memory_total(NULL, &m, sizeof(m), 1)) return SYSINFO_RET_FAIL; value = (zbx_uint64_t)m.real_total; /* total real memory (in 4KB pages) */ value <<= 12; SET_UI64_RESULT(result, value); return SYSINFO_RET_OK; #elif defined(HAVE_SYS_PSTAT_H) struct pst_static pst; long page; if(pstat_getstatic(&pst, sizeof(pst), (size_t)1, 0) == -1) { return SYSINFO_RET_FAIL; } else { /* Get page size */ page = pst.page_size; /* Total physical memory in bytes */ SET_UI64_RESULT(result, (zbx_uint64_t)page*(zbx_uint64_t)pst.physical_memory); return SYSINFO_RET_OK; } #elif defined(HAVE_SYSINFO_TOTALRAM) struct sysinfo info; if( 0 == sysinfo(&info)) { #ifdef HAVE_SYSINFO_MEM_UNIT SET_UI64_RESULT(result, (zbx_uint64_t)info.totalram * (zbx_uint64_t)info.mem_unit); #else SET_UI64_RESULT(result, info.totalram); #endif return SYSINFO_RET_OK; } else { return SYSINFO_RET_FAIL; } #elif defined(HAVE_SYS_VMMETER_VMTOTAL) int mib[2],len; struct vmtotal v; len=sizeof(struct vmtotal); mib[0]=CTL_VM; mib[1]=VM_METER; sysctl(mib,2,&v,&len,NULL,0); SET_UI64_RESULT(result, v.t_rm<<2); return SYSINFO_RET_OK; #elif defined(HAVE_SYS_SYSCTL_H) static int mib[] = { CTL_HW, HW_PHYSMEM }; size_t len; unsigned int memory; int ret; len=sizeof(memory); if(0==sysctl(mib,2,&memory,&len,NULL,0)) { SET_UI64_RESULT(result, memory); ret=SYSINFO_RET_OK; } else { ret=SYSINFO_RET_FAIL; } return ret; #else return SYSINFO_RET_FAIL; #endif }
static int memory_read_internal(value_list_t *vl) { #if HAVE_HOST_STATISTICS kern_return_t status; vm_statistics_data_t vm_data; mach_msg_type_number_t vm_data_len; gauge_t wired; gauge_t active; gauge_t inactive; gauge_t free; if (!port_host || !pagesize) return -1; vm_data_len = sizeof(vm_data) / sizeof(natural_t); if ((status = host_statistics(port_host, HOST_VM_INFO, (host_info_t)&vm_data, &vm_data_len)) != KERN_SUCCESS) { ERROR("memory-plugin: host_statistics failed and returned the value %i", (int)status); return -1; } /* * From <http://docs.info.apple.com/article.html?artnum=107918>: * * Wired memory * This information can't be cached to disk, so it must stay in RAM. * The amount depends on what applications you are using. * * Active memory * This information is currently in RAM and actively being used. * * Inactive memory * This information is no longer being used and has been cached to * disk, but it will remain in RAM until another application needs * the space. Leaving this information in RAM is to your advantage if * you (or a client of your computer) come back to it later. * * Free memory * This memory is not being used. */ wired = (gauge_t)(((uint64_t)vm_data.wire_count) * ((uint64_t)pagesize)); active = (gauge_t)(((uint64_t)vm_data.active_count) * ((uint64_t)pagesize)); inactive = (gauge_t)(((uint64_t)vm_data.inactive_count) * ((uint64_t)pagesize)); free = (gauge_t)(((uint64_t)vm_data.free_count) * ((uint64_t)pagesize)); MEMORY_SUBMIT("wired", wired, "active", active, "inactive", inactive, "free", free); /* #endif HAVE_HOST_STATISTICS */ #elif HAVE_SYSCTLBYNAME /* * vm.stats.vm.v_page_size: 4096 * vm.stats.vm.v_page_count: 246178 * vm.stats.vm.v_free_count: 28760 * vm.stats.vm.v_wire_count: 37526 * vm.stats.vm.v_active_count: 55239 * vm.stats.vm.v_inactive_count: 113730 * vm.stats.vm.v_cache_count: 10809 */ const char *sysctl_keys[8] = { "vm.stats.vm.v_page_size", "vm.stats.vm.v_page_count", "vm.stats.vm.v_free_count", "vm.stats.vm.v_wire_count", "vm.stats.vm.v_active_count", "vm.stats.vm.v_inactive_count", "vm.stats.vm.v_cache_count", NULL}; double sysctl_vals[8]; for (int i = 0; sysctl_keys[i] != NULL; i++) { int value; size_t value_len = sizeof(value); if (sysctlbyname(sysctl_keys[i], (void *)&value, &value_len, NULL, 0) == 0) { sysctl_vals[i] = value; DEBUG("memory plugin: %26s: %g", sysctl_keys[i], sysctl_vals[i]); } else { sysctl_vals[i] = NAN; } } /* for (sysctl_keys) */ /* multiply all all page counts with the pagesize */ for (int i = 1; sysctl_keys[i] != NULL; i++) if (!isnan(sysctl_vals[i])) sysctl_vals[i] *= sysctl_vals[0]; MEMORY_SUBMIT("free", (gauge_t)sysctl_vals[2], "wired", (gauge_t)sysctl_vals[3], "active", (gauge_t)sysctl_vals[4], "inactive", (gauge_t)sysctl_vals[5], "cache", (gauge_t)sysctl_vals[6]); /* #endif HAVE_SYSCTLBYNAME */ #elif KERNEL_LINUX FILE *fh; char buffer[1024]; char *fields[8]; int numfields; bool detailed_slab_info = false; gauge_t mem_total = 0; gauge_t mem_used = 0; gauge_t mem_buffered = 0; gauge_t mem_cached = 0; gauge_t mem_free = 0; gauge_t mem_slab_total = 0; gauge_t mem_slab_reclaimable = 0; gauge_t mem_slab_unreclaimable = 0; if ((fh = fopen("/proc/meminfo", "r")) == NULL) { WARNING("memory: fopen: %s", STRERRNO); return -1; } while (fgets(buffer, sizeof(buffer), fh) != NULL) { gauge_t *val = NULL; if (strncasecmp(buffer, "MemTotal:", 9) == 0) val = &mem_total; else if (strncasecmp(buffer, "MemFree:", 8) == 0) val = &mem_free; else if (strncasecmp(buffer, "Buffers:", 8) == 0) val = &mem_buffered; else if (strncasecmp(buffer, "Cached:", 7) == 0) val = &mem_cached; else if (strncasecmp(buffer, "Slab:", 5) == 0) val = &mem_slab_total; else if (strncasecmp(buffer, "SReclaimable:", 13) == 0) { val = &mem_slab_reclaimable; detailed_slab_info = true; } else if (strncasecmp(buffer, "SUnreclaim:", 11) == 0) { val = &mem_slab_unreclaimable; detailed_slab_info = true; } else continue; numfields = strsplit(buffer, fields, STATIC_ARRAY_SIZE(fields)); if (numfields < 2) continue; *val = 1024.0 * atof(fields[1]); } if (fclose(fh)) { WARNING("memory: fclose: %s", STRERRNO); } if (mem_total < (mem_free + mem_buffered + mem_cached + mem_slab_total)) return -1; mem_used = mem_total - (mem_free + mem_buffered + mem_cached + mem_slab_total); /* SReclaimable and SUnreclaim were introduced in kernel 2.6.19 * They sum up to the value of Slab, which is available on older & newer * kernels. So SReclaimable/SUnreclaim are submitted if available, and Slab * if not. */ if (detailed_slab_info) MEMORY_SUBMIT("used", mem_used, "buffered", mem_buffered, "cached", mem_cached, "free", mem_free, "slab_unrecl", mem_slab_unreclaimable, "slab_recl", mem_slab_reclaimable); else MEMORY_SUBMIT("used", mem_used, "buffered", mem_buffered, "cached", mem_cached, "free", mem_free, "slab", mem_slab_total); /* #endif KERNEL_LINUX */ #elif HAVE_LIBKSTAT /* Most of the additions here were taken as-is from the k9toolkit from * Brendan Gregg and are subject to change I guess */ long long mem_used; long long mem_free; long long mem_lock; long long mem_kern; long long mem_unus; long long arcsize; long long pp_kernel; long long physmem; long long availrmem; if (ksp == NULL) return -1; if (ksz == NULL) return -1; mem_used = get_kstat_value(ksp, "pagestotal"); mem_free = get_kstat_value(ksp, "pagesfree"); mem_lock = get_kstat_value(ksp, "pageslocked"); arcsize = get_kstat_value(ksz, "size"); pp_kernel = get_kstat_value(ksp, "pp_kernel"); physmem = get_kstat_value(ksp, "physmem"); availrmem = get_kstat_value(ksp, "availrmem"); mem_kern = 0; mem_unus = 0; if ((mem_used < 0LL) || (mem_free < 0LL) || (mem_lock < 0LL)) { WARNING("memory plugin: one of used, free or locked is negative."); return -1; } mem_unus = physmem - mem_used; if (mem_used < (mem_free + mem_lock)) { /* source: http://wesunsolve.net/bugid/id/4909199 * this seems to happen when swap space is small, e.g. 2G on a 32G system * we will make some assumptions here * educated solaris internals help welcome here */ DEBUG("memory plugin: pages total is smaller than \"free\" " "+ \"locked\". This is probably due to small " "swap space"); mem_free = availrmem; mem_used = 0; } else { mem_used -= mem_free + mem_lock; } /* mem_kern is accounted for in mem_lock */ if (pp_kernel < mem_lock) { mem_kern = pp_kernel; mem_lock -= pp_kernel; } else { mem_kern = mem_lock; mem_lock = 0; } mem_used *= pagesize; /* If this overflows you have some serious */ mem_free *= pagesize; /* memory.. Why not call me up and give me */ mem_lock *= pagesize; /* some? ;) */ mem_kern *= pagesize; /* it's 2011 RAM is cheap */ mem_unus *= pagesize; mem_kern -= arcsize; MEMORY_SUBMIT("used", (gauge_t)mem_used, "free", (gauge_t)mem_free, "locked", (gauge_t)mem_lock, "kernel", (gauge_t)mem_kern, "arc", (gauge_t)arcsize, "unusable", (gauge_t)mem_unus); /* #endif HAVE_LIBKSTAT */ #elif HAVE_SYSCTL int mib[] = {CTL_VM, VM_METER}; struct vmtotal vmtotal = {0}; gauge_t mem_active; gauge_t mem_inactive; gauge_t mem_free; size_t size; size = sizeof(vmtotal); if (sysctl(mib, 2, &vmtotal, &size, NULL, 0) < 0) { WARNING("memory plugin: sysctl failed: %s", STRERRNO); return -1; } assert(pagesize > 0); mem_active = (gauge_t)(vmtotal.t_arm * pagesize); mem_inactive = (gauge_t)((vmtotal.t_rm - vmtotal.t_arm) * pagesize); mem_free = (gauge_t)(vmtotal.t_free * pagesize); MEMORY_SUBMIT("active", mem_active, "inactive", mem_inactive, "free", mem_free); /* #endif HAVE_SYSCTL */ #elif HAVE_LIBSTATGRAB sg_mem_stats *ios; ios = sg_get_mem_stats(); if (ios == NULL) return -1; MEMORY_SUBMIT("used", (gauge_t)ios->used, "cached", (gauge_t)ios->cache, "free", (gauge_t)ios->free); /* #endif HAVE_LIBSTATGRAB */ #elif HAVE_PERFSTAT perfstat_memory_total_t pmemory = {0}; if (perfstat_memory_total(NULL, &pmemory, sizeof(pmemory), 1) < 0) { WARNING("memory plugin: perfstat_memory_total failed: %s", STRERRNO); return -1; } /* Unfortunately, the AIX documentation is not very clear on how these * numbers relate to one another. The only thing is states explcitly * is: * real_total = real_process + real_free + numperm + real_system * * Another segmentation, which would be closer to the numbers reported * by the "svmon" utility, would be: * real_total = real_free + real_inuse * real_inuse = "active" + real_pinned + numperm */ MEMORY_SUBMIT("free", (gauge_t)(pmemory.real_free * pagesize), "cached", (gauge_t)(pmemory.numperm * pagesize), "system", (gauge_t)(pmemory.real_system * pagesize), "user", (gauge_t)(pmemory.real_process * pagesize)); #endif /* HAVE_PERFSTAT */ return 0; } /* }}} int memory_read_internal */
/* * Load the latest CPU usage statistics */ int netsnmp_cpu_arch_load( netsnmp_cache *cache, void *magic ) { int i,n; perfstat_id_t name; perfstat_cpu_total_t cs; perfstat_cpu_t *cs2; perfstat_memory_total_t ms; netsnmp_cpu_info *cpu = netsnmp_cpu_get_byIdx( -1, 0 ); if (perfstat_cpu_total((perfstat_id_t *)NULL, &cs, sizeof(perfstat_cpu_total_t), 1) > 0) { /* Returns 'u_longlong_t' statistics */ cpu->user_ticks = (unsigned long long)cs.user / cs.ncpus; cpu->sys_ticks = ((unsigned long long)cs.sys + (unsigned long long)cs.wait) / cs.ncpus; cpu->kern_ticks = (unsigned long long)cs.sys / cs.ncpus; cpu->wait_ticks = (unsigned long long)cs.wait / cs.ncpus; cpu->idle_ticks = (unsigned long long)cs.idle / cs.ncpus; /* intrpt_ticks, sirq_ticks, nice_ticks unused */ /* * Interrupt/Context Switch statistics * XXX - Do these really belong here ? */ cpu->pageIn = (unsigned long long)cs.sysread; cpu->pageOut = (unsigned long long)cs.syswrite; cpu->nInterrupts = (unsigned long long)cs.devintrs + cs.softintrs; cpu->nCtxSwitches = (unsigned long long)cs.pswitch; } if (perfstat_memory_total((perfstat_id_t *)NULL, &ms, sizeof(perfstat_memory_total_t), 1) > 0) { cpu->swapIn = (unsigned long long)ms.pgspins; cpu->swapOut = (unsigned long long)ms.pgspouts; } /* * Per-CPU statistics */ n = cs.ncpus; /* XXX - Compare against cpu_num */ cs2 = (perfstat_cpu_t*)malloc( n*sizeof(perfstat_cpu_t)); strcpy( name.name, ""); if (perfstat_cpu(&name, cs2, sizeof(perfstat_cpu_t), n) > 0) { for ( i = 0; i < n; i++ ) { cpu = netsnmp_cpu_get_byIdx( i, 1 ); cpu->user_ticks = (unsigned long long)cs2[i].user; cpu->sys_ticks = (unsigned long long)cs2[i].sys + (unsigned long long)cs2[i].wait; cpu->kern_ticks = (unsigned long long)cs2[i].sys; cpu->wait_ticks = (unsigned long long)cs2[i].wait; cpu->idle_ticks = (unsigned long long)cs2[i].idle; cpu->pageIn = (unsigned long long)cs2[i].sysread; cpu->pageOut = (unsigned long long)cs2[i].syswrite; cpu->nCtxSwitches = (unsigned long long)cs2[i].pswitch; /* Interrupt stats only apply overall, not per-CPU */ } } else { _cpu_copy_stats( cpu ); } free(cs2); return 0; }
static int memory_read (void) { #if HAVE_HOST_STATISTICS kern_return_t status; vm_statistics_data_t vm_data; mach_msg_type_number_t vm_data_len; gauge_t wired; gauge_t active; gauge_t inactive; gauge_t free; if (!port_host || !pagesize) return (-1); vm_data_len = sizeof (vm_data) / sizeof (natural_t); if ((status = host_statistics (port_host, HOST_VM_INFO, (host_info_t) &vm_data, &vm_data_len)) != KERN_SUCCESS) { ERROR ("memory-plugin: host_statistics failed and returned the value %i", (int) status); return (-1); } /* * From <http://docs.info.apple.com/article.html?artnum=107918>: * * Wired memory * This information can't be cached to disk, so it must stay in RAM. * The amount depends on what applications you are using. * * Active memory * This information is currently in RAM and actively being used. * * Inactive memory * This information is no longer being used and has been cached to * disk, but it will remain in RAM until another application needs * the space. Leaving this information in RAM is to your advantage if * you (or a client of your computer) come back to it later. * * Free memory * This memory is not being used. */ wired = (gauge_t) (((uint64_t) vm_data.wire_count) * ((uint64_t) pagesize)); active = (gauge_t) (((uint64_t) vm_data.active_count) * ((uint64_t) pagesize)); inactive = (gauge_t) (((uint64_t) vm_data.inactive_count) * ((uint64_t) pagesize)); free = (gauge_t) (((uint64_t) vm_data.free_count) * ((uint64_t) pagesize)); memory_submit ("wired", wired); memory_submit ("active", active); memory_submit ("inactive", inactive); memory_submit ("free", free); /* #endif HAVE_HOST_STATISTICS */ #elif HAVE_SYSCTLBYNAME /* * vm.stats.vm.v_page_size: 4096 * vm.stats.vm.v_page_count: 246178 * vm.stats.vm.v_free_count: 28760 * vm.stats.vm.v_wire_count: 37526 * vm.stats.vm.v_active_count: 55239 * vm.stats.vm.v_inactive_count: 113730 * vm.stats.vm.v_cache_count: 10809 */ char *sysctl_keys[8] = { "vm.stats.vm.v_page_size", "vm.stats.vm.v_page_count", "vm.stats.vm.v_free_count", "vm.stats.vm.v_wire_count", "vm.stats.vm.v_active_count", "vm.stats.vm.v_inactive_count", "vm.stats.vm.v_cache_count", NULL }; double sysctl_vals[8]; int i; for (i = 0; sysctl_keys[i] != NULL; i++) { int value; size_t value_len = sizeof (value); if (sysctlbyname (sysctl_keys[i], (void *) &value, &value_len, NULL, 0) == 0) { sysctl_vals[i] = value; DEBUG ("memory plugin: %26s: %g", sysctl_keys[i], sysctl_vals[i]); } else { sysctl_vals[i] = NAN; } } /* for (sysctl_keys) */ /* multiply all all page counts with the pagesize */ for (i = 1; sysctl_keys[i] != NULL; i++) if (!isnan (sysctl_vals[i])) sysctl_vals[i] *= sysctl_vals[0]; memory_submit ("free", sysctl_vals[2]); memory_submit ("wired", sysctl_vals[3]); memory_submit ("active", sysctl_vals[4]); memory_submit ("inactive", sysctl_vals[5]); memory_submit ("cache", sysctl_vals[6]); /* #endif HAVE_SYSCTLBYNAME */ #elif KERNEL_LINUX FILE *fh; char buffer[1024]; char *fields[8]; int numfields; long long mem_used = 0; long long mem_buffered = 0; long long mem_cached = 0; long long mem_free = 0; if ((fh = fopen ("/proc/meminfo", "r")) == NULL) { char errbuf[1024]; WARNING ("memory: fopen: %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } while (fgets (buffer, 1024, fh) != NULL) { long long *val = NULL; if (strncasecmp (buffer, "MemTotal:", 9) == 0) val = &mem_used; else if (strncasecmp (buffer, "MemFree:", 8) == 0) val = &mem_free; else if (strncasecmp (buffer, "Buffers:", 8) == 0) val = &mem_buffered; else if (strncasecmp (buffer, "Cached:", 7) == 0) val = &mem_cached; else continue; numfields = strsplit (buffer, fields, 8); if (numfields < 2) continue; *val = atoll (fields[1]) * 1024LL; } if (fclose (fh)) { char errbuf[1024]; WARNING ("memory: fclose: %s", sstrerror (errno, errbuf, sizeof (errbuf))); } if (mem_used >= (mem_free + mem_buffered + mem_cached)) { mem_used -= mem_free + mem_buffered + mem_cached; memory_submit ("used", mem_used); memory_submit ("buffered", mem_buffered); memory_submit ("cached", mem_cached); memory_submit ("free", mem_free); } /* #endif KERNEL_LINUX */ #elif HAVE_LIBKSTAT /* Most of the additions here were taken as-is from the k9toolkit from * Brendan Gregg and are subject to change I guess */ long long mem_used; long long mem_free; long long mem_lock; long long mem_kern; long long mem_unus; long long pp_kernel; long long physmem; long long availrmem; if (ksp == NULL) return (-1); mem_used = get_kstat_value (ksp, "pagestotal"); mem_free = get_kstat_value (ksp, "pagesfree"); mem_lock = get_kstat_value (ksp, "pageslocked"); mem_kern = 0; mem_unus = 0; pp_kernel = get_kstat_value (ksp, "pp_kernel"); physmem = get_kstat_value (ksp, "physmem"); availrmem = get_kstat_value (ksp, "availrmem"); if ((mem_used < 0LL) || (mem_free < 0LL) || (mem_lock < 0LL)) { WARNING ("memory plugin: one of used, free or locked is negative."); return (-1); } mem_unus = physmem - mem_used; if (mem_used < (mem_free + mem_lock)) { /* source: http://wesunsolve.net/bugid/id/4909199 * this seems to happen when swap space is small, e.g. 2G on a 32G system * we will make some assumptions here * educated solaris internals help welcome here */ DEBUG ("memory plugin: pages total is smaller than \"free\" " "+ \"locked\". This is probably due to small " "swap space"); mem_free = availrmem; mem_used = 0; } else { mem_used -= mem_free + mem_lock; } /* mem_kern is accounted for in mem_lock */ if ( pp_kernel < mem_lock ) { mem_kern = pp_kernel; mem_lock -= pp_kernel; } else { mem_kern = mem_lock; mem_lock = 0; } mem_used *= pagesize; /* If this overflows you have some serious */ mem_free *= pagesize; /* memory.. Why not call me up and give me */ mem_lock *= pagesize; /* some? ;) */ mem_kern *= pagesize; /* it's 2011 RAM is cheap */ mem_unus *= pagesize; memory_submit ("used", mem_used); memory_submit ("free", mem_free); memory_submit ("locked", mem_lock); memory_submit ("kernel", mem_kern); memory_submit ("unusable", mem_unus); /* #endif HAVE_LIBKSTAT */ #elif HAVE_SYSCTL int mib[] = {CTL_VM, VM_METER}; struct vmtotal vmtotal; size_t size; memset (&vmtotal, 0, sizeof (vmtotal)); size = sizeof (vmtotal); if (sysctl (mib, 2, &vmtotal, &size, NULL, 0) < 0) { char errbuf[1024]; WARNING ("memory plugin: sysctl failed: %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } assert (pagesize > 0); memory_submit ("active", vmtotal.t_arm * pagesize); memory_submit ("inactive", (vmtotal.t_rm - vmtotal.t_arm) * pagesize); memory_submit ("free", vmtotal.t_free * pagesize); /* #endif HAVE_SYSCTL */ #elif HAVE_LIBSTATGRAB sg_mem_stats *ios; if ((ios = sg_get_mem_stats ()) != NULL) { memory_submit ("used", ios->used); memory_submit ("cached", ios->cache); memory_submit ("free", ios->free); } /* #endif HAVE_LIBSTATGRAB */ #elif HAVE_PERFSTAT if (perfstat_memory_total(NULL, &pmemory, sizeof(perfstat_memory_total_t), 1) < 0) { char errbuf[1024]; WARNING ("memory plugin: perfstat_memory_total failed: %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } memory_submit ("used", pmemory.real_inuse * pagesize); memory_submit ("free", pmemory.real_free * pagesize); memory_submit ("cached", pmemory.numperm * pagesize); memory_submit ("system", pmemory.real_system * pagesize); memory_submit ("user", pmemory.real_process * pagesize); #endif /* HAVE_PERFSTAT */ return (0); }