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