diff --git a/src/libs/zbxsysinfo/solaris/memory.c b/src/libs/zbxsysinfo/solaris/memory.c index e9ce429..11dc31b 100644 --- a/src/libs/zbxsysinfo/solaris/memory.c +++ b/src/libs/zbxsysinfo/solaris/memory.c @@ -153,19 +153,35 @@ out: static int VM_MEMORY_USED(AGENT_RESULT *result) { int ret; - zbx_uint64_t freemem; + zbx_uint64_t freemem, pagesize; char *error = NULL; zabbix_log(LOG_LEVEL_DEBUG, "In %s (with HAVE_VMINFO_T_UPDATES)", __func__); - if (SUCCEED == zbx_kstat_get_freemem(&freemem, &error)) + if (SUCCEED == zbx_kstat_get_freemem(&freemem, &pagesize, &error)) { - long res_SC_PHYS_PAGES, res_SC_PAGESIZE; + long res_SC_PHYS_PAGES; + zbx_uint64_t total; CHECKED_SYSCONF_SYSCALL(_SC_PHYS_PAGES); - CHECKED_SYSCONF_SYSCALL(_SC_PAGESIZE); - SET_UI64_RESULT(result, res_SC_PHYS_PAGES * res_SC_PAGESIZE - freemem); + if (0 == (total = res_SC_PHYS_PAGES)) + { + SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot calculate usage because total is zero.")); + ret = SYSINFO_RET_FAIL; + goto out; + } + + total *= pagesize; + + if (total < freemem) + { + zabbix_log(LOG_LEVEL_WARNING, "%s() total < freemem, where total:" ZBX_FS_UI64 " freemem:" + ZBX_FS_UI64 " pagesize:" ZBX_FS_UI64 " delta:" ZBX_FS_I64, __func__, total, freemem, + pagesize, total - freemem); + } + else + SET_UI64_RESULT(result, total - freemem); } else if (NULL != error) { @@ -186,7 +202,7 @@ out: static int VM_MEMORY_PUSED(AGENT_RESULT *result) { int ret; - zbx_uint64_t freemem, total; + zbx_uint64_t freemem, total, pagesize; char *error = NULL; long res_SC_PHYS_PAGES; @@ -201,14 +217,18 @@ static int VM_MEMORY_PUSED(AGENT_RESULT *result) goto out; } - if (SUCCEED == zbx_kstat_get_freemem(&freemem, &error)) + if (SUCCEED == zbx_kstat_get_freemem(&freemem, &pagesize, &error)) { - long res_SC_PAGESIZE; - - CHECKED_SYSCONF_SYSCALL(_SC_PAGESIZE); - - total *= res_SC_PAGESIZE; - SET_DBL_RESULT(result, (total - freemem) / (double)total * 100); + total *= pagesize; + + if (total < freemem) + { + zabbix_log(LOG_LEVEL_WARNING, "%s() total < freemem, where total:" ZBX_FS_UI64 " freemem:" + ZBX_FS_UI64 " pagesize:" ZBX_FS_UI64 " delta:" ZBX_FS_I64, __func__, total, freemem, + pagesize, total - freemem); + } + else + SET_DBL_RESULT(result, (total - freemem) / (double)total * 100); } else if (NULL != error) { @@ -234,7 +254,7 @@ static int VM_MEMORY_AVAILABLE(AGENT_RESULT *result) zabbix_log(LOG_LEVEL_DEBUG, "In %s, (with HAVE_VMINFO_T_UPDATES)", __func__); - if (SUCCEED == zbx_kstat_get_freemem(&freemem, &error)) + if (SUCCEED == zbx_kstat_get_freemem(&freemem, NULL, &error)) { SET_UI64_RESULT(result, freemem); } @@ -257,7 +277,7 @@ out: static int VM_MEMORY_PAVAILABLE(AGENT_RESULT *result) { int ret; - zbx_uint64_t total, freemem; + zbx_uint64_t total, freemem, pagesize; char *error = NULL; long res_SC_PHYS_PAGES; @@ -272,14 +292,18 @@ static int VM_MEMORY_PAVAILABLE(AGENT_RESULT *result) goto out; } - if (SUCCEED == zbx_kstat_get_freemem(&freemem, &error)) + if (SUCCEED == zbx_kstat_get_freemem(&freemem, &pagesize, &error)) { - long res_SC_PAGESIZE; - - CHECKED_SYSCONF_SYSCALL(_SC_PAGESIZE); - - total *= res_SC_PAGESIZE; - SET_DBL_RESULT(result, freemem / (double)total * 100); + total *= pagesize; + + if (total < freemem) + { + zabbix_log(LOG_LEVEL_WARNING, "%s() total < freemem, where total:" ZBX_FS_UI64 " freemem:" + ZBX_FS_UI64 " pagesize:" ZBX_FS_UI64 " delta:" ZBX_FS_I64, __func__, total, freemem, + pagesize, total - freemem); + } + else + SET_DBL_RESULT(result, freemem / (double)total * 100); } else if (NULL != error) { diff --git a/src/zabbix_agent/zbxkstat.c b/src/zabbix_agent/zbxkstat.c index 591ba2d..5a4dd77 100644 --- a/src/zabbix_agent/zbxkstat.c +++ b/src/zabbix_agent/zbxkstat.c @@ -30,6 +30,7 @@ extern ZBX_COLLECTOR_DATA *collector; static kstat_ctl_t *kc = NULL; static kid_t kc_id = 0; static kstat_t *kc_vminfo; +static kstat_t *kc_sysinfo; static zbx_mutex_t kstat_lock = ZBX_MUTEX_NULL; @@ -66,6 +67,14 @@ static int zbx_kstat_refresh(char **error) ret = FAIL; goto out; } + + if (NULL == (kc_sysinfo = kstat_lookup(kc, "unix", -1, "sysinfo"))) + { + *error = zbx_dsprintf(*error, "failed to find sysinfo data: %s", zbx_strerror(errno)); + ret = FAIL; + goto out; + } + ret = SUCCEED; out: zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__); @@ -151,10 +160,14 @@ void zbx_kstat_collect(zbx_kstat_t *kstat) kid_t kid; char *error = NULL; vminfo_t vminfo; + sysinfo_t sysinfo; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__); - while (-1 == (kid = kstat_read(kc, kc_vminfo, &vminfo)) || kc_id != kid) + while (-1 == (kid = kstat_read(kc, kc_vminfo, &vminfo)) || + kc_id != kid || + -1 == (kid = kstat_read(kc, kc_sysinfo, &sysinfo)) || + kc_id != kid) { if (-1 == kid) zabbix_log(LOG_LEVEL_DEBUG, "cannot collect kstat data, kstat_read: %s", ZBX_NULL2STR(error)); @@ -172,7 +185,7 @@ void zbx_kstat_collect(zbx_kstat_t *kstat) kstat->vminfo_index ^= 1; kstat->vminfo[kstat->vminfo_index].freemem = vminfo.freemem; - kstat->vminfo[kstat->vminfo_index].updates = time(NULL); + kstat->vminfo[kstat->vminfo_index].updates = sysinfo.updates; zbx_mutex_unlock(kstat_lock); @@ -187,8 +200,9 @@ out: * * * Purpose: get free memory size * * * - * Parameters: value - [OUT] the free memory size in bytes * - * error - [OUT] the error message * + * Parameters: value - [OUT] the free memory size in bytes * + * pagesize - [OUT] * + * error - [OUT] the error message * * * * Return value: SUCCEED - the free memory size was stored in value * * FAIL - either an error occurred (error parameter is set) or * @@ -196,8 +210,9 @@ out: * unchanged) * * * ******************************************************************************/ -int zbx_kstat_get_freemem(zbx_uint64_t *value, char **error) +int zbx_kstat_get_freemem(zbx_uint64_t *value, zbx_uint64_t *pagesize, char **error) { + static int last_pagesize = FAIL; int sysconf_pagesize, last, prev, ret = FAIL; zbx_kstat_vminfo_t *vminfo; @@ -223,6 +238,21 @@ int zbx_kstat_get_freemem(zbx_uint64_t *value, char **error) *value = (vminfo[last].freemem - vminfo[prev].freemem) / (vminfo[last].updates - vminfo[prev].updates) * sysconf_pagesize; ret = SUCCEED; + + if (NULL != pagesize) + *pagesize = sysconf_pagesize; + + if (sysconf_pagesize != last_pagesize) + { + if (FAIL != last_pagesize) + { + zabbix_log(LOG_LEVEL_WARNING, + "sysconf(_SC_PAGESIZE) value has changed from [%d] to [%d]", + last_pagesize, sysconf_pagesize); + } + + last_pagesize = sysconf_pagesize; + } } else zabbix_log(LOG_LEVEL_DEBUG, "no new vminfo update is available"); diff --git a/src/zabbix_agent/zbxkstat.h b/src/zabbix_agent/zbxkstat.h index 141ea78..f47d20e 100644 --- a/src/zabbix_agent/zbxkstat.h +++ b/src/zabbix_agent/zbxkstat.h @@ -41,7 +41,7 @@ zbx_kstat_t; int zbx_kstat_init(zbx_kstat_t *kstat, char **error); void zbx_kstat_destroy(void); void zbx_kstat_collect(zbx_kstat_t *kstat); -int zbx_kstat_get_freemem(zbx_uint64_t *value, char **error); +int zbx_kstat_get_freemem(zbx_uint64_t *value, zbx_uint64_t *pagesize, char **error); #endif