1 /*
2 ** Zabbix
3 ** Copyright (C) 2001-2021 Zabbix SIA
4 **
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU General Public License as published by
7 ** the Free Software Foundation; either version 2 of the License, or
8 ** (at your option) any later version.
9 **
10 ** This program is distributed in the hope that it will be useful,
11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ** GNU General Public License for more details.
14 **
15 ** You should have received a copy of the GNU General Public License
16 ** along with this program; if not, write to the Free Software
17 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18 **/
19 
20 #include <sys/dr.h>
21 #include "common.h"
22 #include "sysinfo.h"
23 #include "stats.h"
24 #include "log.h"
25 
SYSTEM_CPU_NUM(AGENT_REQUEST * request,AGENT_RESULT * result)26 int	SYSTEM_CPU_NUM(AGENT_REQUEST *request, AGENT_RESULT *result)
27 {
28 #ifdef HAVE_LIBPERFSTAT
29 	char			*tmp;
30 	lpar_info_format2_t	buf;
31 
32 	if (1 < request->nparam)
33 	{
34 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Too many parameters."));
35 		return SYSINFO_RET_FAIL;
36 	}
37 
38 	tmp = get_rparam(request, 0);
39 
40 	/* only "online" (default) for parameter "type" is supported */
41 	if (NULL != tmp && '\0' != *tmp && 0 != strcmp(tmp, "online"))
42 	{
43 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid first parameter."));
44 		return SYSINFO_RET_FAIL;
45 	}
46 
47 	if (0 != lpar_get_info(LPAR_INFO_FORMAT2, &buf, sizeof(buf)))
48 	{
49 		SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain system information: %s", zbx_strerror(errno)));
50 		return SYSINFO_RET_FAIL;
51 	}
52 
53 	SET_UI64_RESULT(result, buf.online_lcpus);
54 
55 	return SYSINFO_RET_OK;
56 #else
57 	SET_MSG_RESULT(result, zbx_strdup(NULL, "Agent was compiled without support for Perfstat API."));
58 	return SYSINFO_RET_FAIL;
59 #endif
60 }
61 
SYSTEM_CPU_UTIL(AGENT_REQUEST * request,AGENT_RESULT * result)62 int	SYSTEM_CPU_UTIL(AGENT_REQUEST *request, AGENT_RESULT *result)
63 {
64 	char	*tmp;
65 	int	cpu_num, state, mode;
66 
67 	if (3 < request->nparam)
68 	{
69 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Too many parameters."));
70 		return SYSINFO_RET_FAIL;
71 	}
72 
73 	tmp = get_rparam(request, 0);
74 
75 	if (NULL == tmp || '\0' == *tmp || 0 == strcmp(tmp, "all"))
76 		cpu_num = ZBX_CPUNUM_ALL;
77 	else if (SUCCEED != is_uint31_1(tmp, &cpu_num))
78 	{
79 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid first parameter."));
80 		return SYSINFO_RET_FAIL;
81 	}
82 
83 	tmp = get_rparam(request, 1);
84 
85 	if (NULL == tmp || '\0' == *tmp || 0 == strcmp(tmp, "user"))
86 		state = ZBX_CPU_STATE_USER;
87 	else if (0 == strcmp(tmp, "system"))
88 		state = ZBX_CPU_STATE_SYSTEM;
89 	else if (0 == strcmp(tmp, "idle"))
90 		state = ZBX_CPU_STATE_IDLE;
91 	else if (0 == strcmp(tmp, "iowait"))
92 		state = ZBX_CPU_STATE_IOWAIT;
93 	else
94 	{
95 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter."));
96 		return SYSINFO_RET_FAIL;
97 	}
98 
99 	tmp = get_rparam(request, 2);
100 
101 	if (NULL == tmp || '\0' == *tmp || 0 == strcmp(tmp, "avg1"))
102 		mode = ZBX_AVG1;
103 	else if (0 == strcmp(tmp, "avg5"))
104 		mode = ZBX_AVG5;
105 	else if (0 == strcmp(tmp, "avg15"))
106 		mode = ZBX_AVG15;
107 	else
108 	{
109 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter."));
110 		return SYSINFO_RET_FAIL;
111 	}
112 
113 	if (SYSINFO_RET_FAIL == get_cpustat(result, cpu_num, state, mode))
114 	{
115 		if (!ISSET_MSG(result))
116 			SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot obtain CPU information."));
117 
118 		return SYSINFO_RET_FAIL;
119 	}
120 
121 	return SYSINFO_RET_OK;
122 }
123 
SYSTEM_CPU_LOAD(AGENT_REQUEST * request,AGENT_RESULT * result)124 int	SYSTEM_CPU_LOAD(AGENT_REQUEST *request, AGENT_RESULT *result)
125 {
126 #ifdef HAVE_LIBPERFSTAT
127 #if !defined(SBITS)
128 #	define SBITS 16
129 #endif
130 	char			*tmp;
131 	int			mode, per_cpu = 1;
132 	perfstat_cpu_total_t	ps_cpu_total;
133 	double			value;
134 
135 	if (2 < request->nparam)
136 	{
137 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Too many parameters."));
138 		return SYSINFO_RET_FAIL;
139 	}
140 
141 	tmp = get_rparam(request, 0);
142 
143 	if (NULL == tmp || '\0' == *tmp || 0 == strcmp(tmp, "all"))
144 		per_cpu = 0;
145 	else if (0 != strcmp(tmp, "percpu"))
146 	{
147 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid first parameter."));
148 		return SYSINFO_RET_FAIL;
149 	}
150 
151 	tmp = get_rparam(request, 1);
152 
153 	if (NULL == tmp || '\0' == *tmp || 0 == strcmp(tmp, "avg1"))
154 		mode = ZBX_AVG1;
155 	else if (0 == strcmp(tmp, "avg5"))
156 		mode = ZBX_AVG5;
157 	else if (0 == strcmp(tmp, "avg15"))
158 		mode = ZBX_AVG15;
159 	else
160 	{
161 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter."));
162 		return SYSINFO_RET_FAIL;
163 	}
164 
165 	if (-1 == perfstat_cpu_total(NULL, &ps_cpu_total, sizeof(ps_cpu_total), 1))
166 	{
167 		SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain system information: %s", zbx_strerror(errno)));
168 		return SYSINFO_RET_FAIL;
169 	}
170 
171 	value = (double)ps_cpu_total.loadavg[mode] / (1 << SBITS);
172 
173 	if (1 == per_cpu)
174 	{
175 		if (0 >= ps_cpu_total.ncpus)
176 		{
177 			SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot obtain number of CPUs."));
178 			return SYSINFO_RET_FAIL;
179 		}
180 		value /= ps_cpu_total.ncpus;
181 	}
182 
183 	SET_DBL_RESULT(result, value);
184 
185 	return SYSINFO_RET_OK;
186 #else
187 	SET_MSG_RESULT(result, zbx_strdup(NULL, "Agent was compiled without support for Perfstat API."));
188 	return SYSINFO_RET_FAIL;
189 #endif
190 }
191 
SYSTEM_CPU_SWITCHES(AGENT_REQUEST * request,AGENT_RESULT * result)192 int     SYSTEM_CPU_SWITCHES(AGENT_REQUEST *request, AGENT_RESULT *result)
193 {
194 #ifdef HAVE_LIBPERFSTAT
195 	perfstat_cpu_total_t	ps_cpu_total;
196 
197 	if (-1 == perfstat_cpu_total(NULL, &ps_cpu_total, sizeof(ps_cpu_total), 1))
198 	{
199 		SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain system information: %s", zbx_strerror(errno)));
200 		return SYSINFO_RET_FAIL;
201 	}
202 
203 	SET_UI64_RESULT(result, (zbx_uint64_t)ps_cpu_total.pswitch);
204 
205 	return SYSINFO_RET_OK;
206 #else
207 	SET_MSG_RESULT(result, zbx_strdup(NULL, "Agent was compiled without support for Perfstat API."));
208 	return SYSINFO_RET_FAIL;
209 #endif
210 }
211 
SYSTEM_CPU_INTR(AGENT_REQUEST * request,AGENT_RESULT * result)212 int     SYSTEM_CPU_INTR(AGENT_REQUEST *request, AGENT_RESULT *result)
213 {
214 #ifdef HAVE_LIBPERFSTAT
215 	perfstat_cpu_total_t	ps_cpu_total;
216 
217 	if (-1 == perfstat_cpu_total(NULL, &ps_cpu_total, sizeof(ps_cpu_total), 1))
218 	{
219 		SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain system information: %s", zbx_strerror(errno)));
220 		return SYSINFO_RET_FAIL;
221 	}
222 
223 	SET_UI64_RESULT(result, (zbx_uint64_t)ps_cpu_total.devintrs);
224 
225 	return SYSINFO_RET_OK;
226 #else
227 	SET_MSG_RESULT(result, zbx_strdup(NULL, "Agent was compiled without support for Perfstat API."));
228 	return SYSINFO_RET_FAIL;
229 #endif
230 }
231