Esempio n. 1
0
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
}
Esempio n. 2
0
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
}
Esempio n. 3
0
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;
}
Esempio n. 4
0
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);
}
Esempio n. 5
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);
}
Esempio n. 6
0
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);
}
Esempio n. 7
0
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
}
Esempio n. 8
0
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;
}
Esempio n. 9
0
File: swap.c Progetto: zabbix/zabbix
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
}
Esempio n. 10
0
/**
 * 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;
}
Esempio n. 11
0
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 */
Esempio n. 12
0
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;
}
Esempio n. 13
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;
}
Esempio n. 14
0
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;
}
Esempio n. 15
0
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 */
}
Esempio n. 16
0
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;
}
Esempio n. 17
0
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;
}
Esempio n. 18
0
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 */
Esempio n. 20
0
    /*
     * 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;
}
Esempio n. 21
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
}
Esempio n. 22
0
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
}
Esempio n. 23
0
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 */
Esempio n. 24
0
    /*
     * 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;
}
Esempio n. 25
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);
}