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 "common.h"
21 #include "sysinfo.h"
22 #include "stats.h"
23 #include "log.h"
24
25 #include <uvm/uvm_extern.h>
26
get_cpu_num()27 static int get_cpu_num()
28 {
29 #ifdef HAVE_FUNCTION_SYSCTL_HW_NCPU /* NetBSD 3.1 i386; NetBSD 4.0 i386 */
30 size_t len;
31 int mib[] = {CTL_HW, HW_NCPU}, ncpu;
32
33 len = sizeof(ncpu);
34
35 if (-1 == sysctl(mib, 2, &ncpu, &len, NULL, 0))
36 return -1;
37
38 return ncpu;
39 #else
40 return -1;
41 #endif
42 }
43
SYSTEM_CPU_NUM(AGENT_REQUEST * request,AGENT_RESULT * result)44 int SYSTEM_CPU_NUM(AGENT_REQUEST *request, AGENT_RESULT *result)
45 {
46 char *tmp;
47 int cpu_num;
48
49 if (1 < request->nparam)
50 {
51 SET_MSG_RESULT(result, zbx_strdup(NULL, "Too many parameters."));
52 return SYSINFO_RET_FAIL;
53 }
54
55 tmp = get_rparam(request, 0);
56
57 /* only "online" (default) for parameter "type" is supported */
58 if (NULL != tmp && '\0' != *tmp && 0 != strcmp(tmp, "online"))
59 {
60 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid first parameter."));
61 return SYSINFO_RET_FAIL;
62 }
63
64 if (-1 == (cpu_num = get_cpu_num()))
65 {
66 SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot obtain number of CPUs."));
67 return SYSINFO_RET_FAIL;
68 }
69
70 SET_UI64_RESULT(result, cpu_num);
71
72 return SYSINFO_RET_OK;
73 }
74
SYSTEM_CPU_UTIL(AGENT_REQUEST * request,AGENT_RESULT * result)75 int SYSTEM_CPU_UTIL(AGENT_REQUEST *request, AGENT_RESULT *result)
76 {
77 char *tmp;
78 int cpu_num, state, mode;
79
80 if (3 < request->nparam)
81 {
82 SET_MSG_RESULT(result, zbx_strdup(NULL, "Too many parameters."));
83 return SYSINFO_RET_FAIL;
84 }
85
86 tmp = get_rparam(request, 0);
87
88 if (NULL == tmp || '\0' == *tmp || 0 == strcmp(tmp, "all"))
89 cpu_num = ZBX_CPUNUM_ALL;
90 else if (SUCCEED != is_uint31_1(tmp, &cpu_num))
91 {
92 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid first parameter."));
93 return SYSINFO_RET_FAIL;
94 }
95
96 tmp = get_rparam(request, 1);
97
98 if (NULL == tmp || '\0' == *tmp || 0 == strcmp(tmp, "user"))
99 state = ZBX_CPU_STATE_USER;
100 else if (0 == strcmp(tmp, "nice"))
101 state = ZBX_CPU_STATE_NICE;
102 else if (0 == strcmp(tmp, "system"))
103 state = ZBX_CPU_STATE_SYSTEM;
104 else if (0 == strcmp(tmp, "idle"))
105 state = ZBX_CPU_STATE_IDLE;
106 else
107 {
108 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter."));
109 return SYSINFO_RET_FAIL;
110 }
111
112 tmp = get_rparam(request, 2);
113
114 if (NULL == tmp || '\0' == *tmp || 0 == strcmp(tmp, "avg1"))
115 mode = ZBX_AVG1;
116 else if (0 == strcmp(tmp, "avg5"))
117 mode = ZBX_AVG5;
118 else if (0 == strcmp(tmp, "avg15"))
119 mode = ZBX_AVG15;
120 else
121 {
122 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter."));
123 return SYSINFO_RET_FAIL;
124 }
125
126 return get_cpustat(result, cpu_num, state, mode);
127 }
128
SYSTEM_CPU_LOAD(AGENT_REQUEST * request,AGENT_RESULT * result)129 int SYSTEM_CPU_LOAD(AGENT_REQUEST *request, AGENT_RESULT *result)
130 {
131 char *tmp;
132 int mode, per_cpu = 1, cpu_num;
133 double load[ZBX_AVG_COUNT], 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 (mode >= getloadavg(load, 3))
166 {
167 SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain load average: %s", zbx_strerror(errno)));
168 return SYSINFO_RET_FAIL;
169 }
170
171 value = load[mode];
172
173 if (1 == per_cpu)
174 {
175 if (0 >= (cpu_num = get_cpu_num()))
176 {
177 SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot obtain number of CPUs."));
178 return SYSINFO_RET_FAIL;
179 }
180 value /= cpu_num;
181 }
182
183 SET_DBL_RESULT(result, value);
184
185 return SYSINFO_RET_OK;
186 }
187
SYSTEM_CPU_SWITCHES(AGENT_REQUEST * request,AGENT_RESULT * result)188 int SYSTEM_CPU_SWITCHES(AGENT_REQUEST *request, AGENT_RESULT *result)
189 {
190 int mib[] = {CTL_VM, VM_UVMEXP2};
191 size_t len;
192 struct uvmexp_sysctl v;
193
194 len = sizeof(struct uvmexp_sysctl);
195
196 if (0 != sysctl(mib, 2, &v, &len, NULL, 0))
197 {
198 SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain system information: %s", zbx_strerror(errno)));
199 return SYSINFO_RET_FAIL;
200 }
201
202 SET_UI64_RESULT(result, v.swtch);
203
204 return SYSINFO_RET_OK;
205 }
206
SYSTEM_CPU_INTR(AGENT_REQUEST * request,AGENT_RESULT * result)207 int SYSTEM_CPU_INTR(AGENT_REQUEST *request, AGENT_RESULT *result)
208 {
209 int mib[] = {CTL_VM, VM_UVMEXP2};
210 size_t len;
211 struct uvmexp_sysctl v;
212
213 len = sizeof(struct uvmexp_sysctl);
214
215 if (0 != sysctl(mib, 2, &v, &len, NULL, 0))
216 {
217 SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain system information: %s", zbx_strerror(errno)));
218 return SYSINFO_RET_FAIL;
219 }
220
221 SET_UI64_RESULT(result, v.intrs);
222
223 return SYSINFO_RET_OK;
224 }
225