/*
** Copyright (C) 2001-2025 Zabbix SIA
**
** This program is free software: you can redistribute it and/or modify it under the terms of
** the GNU Affero General Public License as published by the Free Software Foundation, version 3.
**
** This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
** without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
** See the GNU Affero General Public License for more details.
**
** You should have received a copy of the GNU Affero General Public License along with this program.
** If not, see .
**/
#include "zbxsysinfo.h"
#include "../sysinfo.h"
#include "zbxnum.h"
#include "../common/stats.h"
#include
static int get_cpu_num(void)
{
#ifdef HAVE_FUNCTION_SYSCTL_HW_NCPU /* NetBSD 3.1 i386; NetBSD 4.0 i386 */
size_t len;
int mib[] = {CTL_HW, HW_NCPU}, ncpu;
len = sizeof(ncpu);
if (-1 == sysctl(mib, 2, &ncpu, &len, NULL, 0))
return -1;
return ncpu;
#else
return -1;
#endif
}
int system_cpu_num(AGENT_REQUEST *request, AGENT_RESULT *result)
{
char *tmp;
int cpu_num;
if (1 < request->nparam)
{
SET_MSG_RESULT(result, zbx_strdup(NULL, "Too many parameters."));
return SYSINFO_RET_FAIL;
}
tmp = get_rparam(request, 0);
/* only "online" (default) for parameter "type" is supported */
if (NULL != tmp && '\0' != *tmp && 0 != strcmp(tmp, "online"))
{
SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid first parameter."));
return SYSINFO_RET_FAIL;
}
if (-1 == (cpu_num = get_cpu_num()))
{
SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot obtain number of CPUs."));
return SYSINFO_RET_FAIL;
}
SET_UI64_RESULT(result, cpu_num);
return SYSINFO_RET_OK;
}
int system_cpu_util(AGENT_REQUEST *request, AGENT_RESULT *result)
{
char *tmp;
int cpu_num, state, mode;
if (3 < request->nparam)
{
SET_MSG_RESULT(result, zbx_strdup(NULL, "Too many parameters."));
return SYSINFO_RET_FAIL;
}
tmp = get_rparam(request, 0);
if (NULL == tmp || '\0' == *tmp || 0 == strcmp(tmp, "all"))
cpu_num = ZBX_CPUNUM_ALL;
else if (SUCCEED != zbx_is_uint31_1(tmp, &cpu_num))
{
SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid first parameter."));
return SYSINFO_RET_FAIL;
}
tmp = get_rparam(request, 1);
if (NULL == tmp || '\0' == *tmp || 0 == strcmp(tmp, "user"))
state = ZBX_CPU_STATE_USER;
else if (0 == strcmp(tmp, "nice"))
state = ZBX_CPU_STATE_NICE;
else if (0 == strcmp(tmp, "system"))
state = ZBX_CPU_STATE_SYSTEM;
else if (0 == strcmp(tmp, "idle"))
state = ZBX_CPU_STATE_IDLE;
else
{
SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter."));
return SYSINFO_RET_FAIL;
}
tmp = get_rparam(request, 2);
if (NULL == tmp || '\0' == *tmp || 0 == strcmp(tmp, "avg1"))
mode = ZBX_AVG1;
else if (0 == strcmp(tmp, "avg5"))
mode = ZBX_AVG5;
else if (0 == strcmp(tmp, "avg15"))
mode = ZBX_AVG15;
else
{
SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter."));
return SYSINFO_RET_FAIL;
}
return get_cpustat(result, cpu_num, state, mode);
}
int system_cpu_load(AGENT_REQUEST *request, AGENT_RESULT *result)
{
char *tmp;
int mode, per_cpu = 1, cpu_num;
double load[ZBX_AVG_COUNT], value;
if (2 < request->nparam)
{
SET_MSG_RESULT(result, zbx_strdup(NULL, "Too many parameters."));
return SYSINFO_RET_FAIL;
}
tmp = get_rparam(request, 0);
if (NULL == tmp || '\0' == *tmp || 0 == strcmp(tmp, "all"))
per_cpu = 0;
else if (0 != strcmp(tmp, "percpu"))
{
SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid first parameter."));
return SYSINFO_RET_FAIL;
}
tmp = get_rparam(request, 1);
if (NULL == tmp || '\0' == *tmp || 0 == strcmp(tmp, "avg1"))
mode = ZBX_AVG1;
else if (0 == strcmp(tmp, "avg5"))
mode = ZBX_AVG5;
else if (0 == strcmp(tmp, "avg15"))
mode = ZBX_AVG15;
else
{
SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter."));
return SYSINFO_RET_FAIL;
}
if (mode >= getloadavg(load, 3))
{
SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain load average: %s", zbx_strerror(errno)));
return SYSINFO_RET_FAIL;
}
value = load[mode];
if (1 == per_cpu)
{
if (0 >= (cpu_num = get_cpu_num()))
{
SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot obtain number of CPUs."));
return SYSINFO_RET_FAIL;
}
value /= cpu_num;
}
SET_DBL_RESULT(result, value);
return SYSINFO_RET_OK;
}
int system_cpu_switches(AGENT_REQUEST *request, AGENT_RESULT *result)
{
int mib[] = {CTL_VM, VM_UVMEXP2};
size_t len;
struct uvmexp_sysctl v;
len = sizeof(struct uvmexp_sysctl);
if (0 != sysctl(mib, 2, &v, &len, NULL, 0))
{
SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain system information: %s", zbx_strerror(errno)));
return SYSINFO_RET_FAIL;
}
SET_UI64_RESULT(result, v.swtch);
return SYSINFO_RET_OK;
}
int system_cpu_intr(AGENT_REQUEST *request, AGENT_RESULT *result)
{
int mib[] = {CTL_VM, VM_UVMEXP2};
size_t len;
struct uvmexp_sysctl v;
len = sizeof(struct uvmexp_sysctl);
if (0 != sysctl(mib, 2, &v, &len, NULL, 0))
{
SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain system information: %s", zbx_strerror(errno)));
return SYSINFO_RET_FAIL;
}
SET_UI64_RESULT(result, v.intrs);
return SYSINFO_RET_OK;
}