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 "log.h"
23
24 static u_int pagesize = 0;
25
26 #define ZBX_SYSCTLBYNAME(name, value) \
27 \
28 len = sizeof(value); \
29 if (0 != sysctlbyname(name, &value, &len, NULL, 0)) \
30 { \
31 SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain \"%s\" system parameter: %s", \
32 name, zbx_strerror(errno))); \
33 return SYSINFO_RET_FAIL; \
34 }
35
VM_MEMORY_TOTAL(AGENT_RESULT * result)36 static int VM_MEMORY_TOTAL(AGENT_RESULT *result)
37 {
38 unsigned long totalbytes;
39 size_t len;
40
41 ZBX_SYSCTLBYNAME("hw.physmem", totalbytes);
42
43 SET_UI64_RESULT(result, (zbx_uint64_t)totalbytes);
44
45 return SYSINFO_RET_OK;
46 }
47
VM_MEMORY_ACTIVE(AGENT_RESULT * result)48 static int VM_MEMORY_ACTIVE(AGENT_RESULT *result)
49 {
50 u_int activepages;
51 size_t len;
52
53 ZBX_SYSCTLBYNAME("vm.stats.vm.v_active_count", activepages);
54
55 SET_UI64_RESULT(result, (zbx_uint64_t)activepages * pagesize);
56
57 return SYSINFO_RET_OK;
58 }
59
VM_MEMORY_INACTIVE(AGENT_RESULT * result)60 static int VM_MEMORY_INACTIVE(AGENT_RESULT *result)
61 {
62 u_int inactivepages;
63 size_t len;
64
65 ZBX_SYSCTLBYNAME("vm.stats.vm.v_inactive_count", inactivepages);
66
67 SET_UI64_RESULT(result, (zbx_uint64_t)inactivepages * pagesize);
68
69 return SYSINFO_RET_OK;
70 }
71
VM_MEMORY_WIRED(AGENT_RESULT * result)72 static int VM_MEMORY_WIRED(AGENT_RESULT *result)
73 {
74 u_int wiredpages;
75 size_t len;
76
77 ZBX_SYSCTLBYNAME("vm.stats.vm.v_wire_count", wiredpages);
78
79 SET_UI64_RESULT(result, (zbx_uint64_t)wiredpages * pagesize);
80
81 return SYSINFO_RET_OK;
82 }
83
VM_MEMORY_CACHED(AGENT_RESULT * result)84 static int VM_MEMORY_CACHED(AGENT_RESULT *result)
85 {
86 u_int cachedpages;
87 size_t len;
88
89 ZBX_SYSCTLBYNAME("vm.stats.vm.v_cache_count", cachedpages);
90
91 SET_UI64_RESULT(result, (zbx_uint64_t)cachedpages * pagesize);
92
93 return SYSINFO_RET_OK;
94 }
95
VM_MEMORY_FREE(AGENT_RESULT * result)96 static int VM_MEMORY_FREE(AGENT_RESULT *result)
97 {
98 u_int freepages;
99 size_t len;
100
101 ZBX_SYSCTLBYNAME("vm.stats.vm.v_free_count", freepages);
102
103 SET_UI64_RESULT(result, (zbx_uint64_t)freepages * pagesize);
104
105 return SYSINFO_RET_OK;
106 }
107
VM_MEMORY_USED(AGENT_RESULT * result)108 static int VM_MEMORY_USED(AGENT_RESULT *result)
109 {
110 u_int activepages, wiredpages, cachedpages;
111 size_t len;
112
113 ZBX_SYSCTLBYNAME("vm.stats.vm.v_active_count", activepages);
114 ZBX_SYSCTLBYNAME("vm.stats.vm.v_wire_count", wiredpages);
115 ZBX_SYSCTLBYNAME("vm.stats.vm.v_cache_count", cachedpages);
116
117 SET_UI64_RESULT(result, (zbx_uint64_t)(activepages + wiredpages + cachedpages) * pagesize);
118
119 return SYSINFO_RET_OK;
120 }
121
VM_MEMORY_PUSED(AGENT_RESULT * result)122 static int VM_MEMORY_PUSED(AGENT_RESULT *result)
123 {
124 u_int activepages, wiredpages, cachedpages, totalpages;
125 size_t len;
126
127 ZBX_SYSCTLBYNAME("vm.stats.vm.v_active_count", activepages);
128 ZBX_SYSCTLBYNAME("vm.stats.vm.v_wire_count", wiredpages);
129 ZBX_SYSCTLBYNAME("vm.stats.vm.v_cache_count", cachedpages);
130
131 ZBX_SYSCTLBYNAME("vm.stats.vm.v_page_count", totalpages);
132
133 if (0 == totalpages)
134 {
135 SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot calculate percentage because total is zero."));
136 return SYSINFO_RET_FAIL;
137 }
138
139 SET_DBL_RESULT(result, (activepages + wiredpages + cachedpages) / (double)totalpages * 100);
140
141 return SYSINFO_RET_OK;
142 }
143
VM_MEMORY_AVAILABLE(AGENT_RESULT * result)144 static int VM_MEMORY_AVAILABLE(AGENT_RESULT *result)
145 {
146 u_int inactivepages, cachedpages, freepages;
147 size_t len;
148
149 ZBX_SYSCTLBYNAME("vm.stats.vm.v_inactive_count", inactivepages);
150 ZBX_SYSCTLBYNAME("vm.stats.vm.v_cache_count", cachedpages);
151 ZBX_SYSCTLBYNAME("vm.stats.vm.v_free_count", freepages);
152
153 SET_UI64_RESULT(result, (zbx_uint64_t)(inactivepages + cachedpages + freepages) * pagesize);
154
155 return SYSINFO_RET_OK;
156 }
157
VM_MEMORY_PAVAILABLE(AGENT_RESULT * result)158 static int VM_MEMORY_PAVAILABLE(AGENT_RESULT *result)
159 {
160 u_int inactivepages, cachedpages, freepages, totalpages;
161 size_t len;
162
163 ZBX_SYSCTLBYNAME("vm.stats.vm.v_inactive_count", inactivepages);
164 ZBX_SYSCTLBYNAME("vm.stats.vm.v_cache_count", cachedpages);
165 ZBX_SYSCTLBYNAME("vm.stats.vm.v_free_count", freepages);
166
167 ZBX_SYSCTLBYNAME("vm.stats.vm.v_page_count", totalpages);
168
169 if (0 == totalpages)
170 {
171 SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot calculate percentage because total is zero."));
172 return SYSINFO_RET_FAIL;
173 }
174
175 SET_DBL_RESULT(result, (inactivepages + cachedpages + freepages) / (double)totalpages * 100);
176
177 return SYSINFO_RET_OK;
178 }
179
VM_MEMORY_BUFFERS(AGENT_RESULT * result)180 static int VM_MEMORY_BUFFERS(AGENT_RESULT *result)
181 {
182 u_int bufspace;
183 size_t len;
184
185 ZBX_SYSCTLBYNAME("vfs.bufspace", bufspace);
186
187 SET_UI64_RESULT(result, bufspace);
188
189 return SYSINFO_RET_OK;
190 }
191
VM_MEMORY_SHARED(AGENT_RESULT * result)192 static int VM_MEMORY_SHARED(AGENT_RESULT *result)
193 {
194 struct vmtotal vm;
195 size_t len = sizeof(vm);
196 int mib[] = {CTL_VM, VM_METER};
197
198 if (0 != sysctl(mib, 2, &vm, &len, NULL, 0))
199 {
200 SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain system information: %s", zbx_strerror(errno)));
201 return SYSINFO_RET_FAIL;
202 }
203
204 SET_UI64_RESULT(result, (zbx_uint64_t)(vm.t_vmshr + vm.t_rmshr) * pagesize);
205
206 return SYSINFO_RET_OK;
207 }
208
VM_MEMORY_SIZE(AGENT_REQUEST * request,AGENT_RESULT * result)209 int VM_MEMORY_SIZE(AGENT_REQUEST *request, AGENT_RESULT *result)
210 {
211 char *mode;
212 int ret;
213
214 if (1 < request->nparam)
215 {
216 SET_MSG_RESULT(result, zbx_strdup(NULL, "Too many parameters."));
217 return SYSINFO_RET_FAIL;
218 }
219
220 if (0 == pagesize)
221 {
222 size_t len;
223
224 ZBX_SYSCTLBYNAME("vm.stats.vm.v_page_size", pagesize);
225 }
226
227 mode = get_rparam(request, 0);
228
229 if (NULL == mode || '\0' == *mode || 0 == strcmp(mode, "total"))
230 ret = VM_MEMORY_TOTAL(result);
231 else if (0 == strcmp(mode, "active"))
232 ret = VM_MEMORY_ACTIVE(result);
233 else if (0 == strcmp(mode, "inactive"))
234 ret = VM_MEMORY_INACTIVE(result);
235 else if (0 == strcmp(mode, "wired"))
236 ret = VM_MEMORY_WIRED(result);
237 else if (0 == strcmp(mode, "cached"))
238 ret = VM_MEMORY_CACHED(result);
239 else if (0 == strcmp(mode, "free"))
240 ret = VM_MEMORY_FREE(result);
241 else if (0 == strcmp(mode, "used"))
242 ret = VM_MEMORY_USED(result);
243 else if (0 == strcmp(mode, "pused"))
244 ret = VM_MEMORY_PUSED(result);
245 else if (0 == strcmp(mode, "available"))
246 ret = VM_MEMORY_AVAILABLE(result);
247 else if (0 == strcmp(mode, "pavailable"))
248 ret = VM_MEMORY_PAVAILABLE(result);
249 else if (0 == strcmp(mode, "buffers"))
250 ret = VM_MEMORY_BUFFERS(result);
251 else if (0 == strcmp(mode, "shared"))
252 ret = VM_MEMORY_SHARED(result);
253 else
254 {
255 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid first parameter."));
256 ret = SYSINFO_RET_FAIL;
257 }
258
259 return ret;
260 }
261