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 vm_size_t pagesize = 0;
25
26 static struct vm_statistics vm;
27 static mach_msg_type_number_t count;
28
29 #define ZBX_HOST_STATISTICS(value) \
30 \
31 count = HOST_VM_INFO_COUNT; \
32 if (KERN_SUCCESS != host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&value, &count)) \
33 { \
34 SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot obtain host statistics.")); \
35 return SYSINFO_RET_FAIL; \
36 }
37
38 static int mib[] = {CTL_HW, HW_MEMSIZE};
39 static size_t len;
40 static zbx_uint64_t memsize;
41
42 #define ZBX_SYSCTL(value) \
43 \
44 len = sizeof(value); \
45 if (0 != sysctl(mib, 2, &value, &len, NULL, 0)) \
46 { \
47 SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain system information: %s", \
48 zbx_strerror(errno))); \
49 return SYSINFO_RET_FAIL; \
50 }
51
VM_MEMORY_TOTAL(AGENT_RESULT * result)52 static int VM_MEMORY_TOTAL(AGENT_RESULT *result)
53 {
54 ZBX_SYSCTL(memsize);
55
56 SET_UI64_RESULT(result, memsize);
57
58 return SYSINFO_RET_OK;
59 }
60
VM_MEMORY_ACTIVE(AGENT_RESULT * result)61 static int VM_MEMORY_ACTIVE(AGENT_RESULT *result)
62 {
63 ZBX_HOST_STATISTICS(vm);
64
65 SET_UI64_RESULT(result, (zbx_uint64_t)vm.active_count * pagesize);
66
67 return SYSINFO_RET_OK;
68 }
69
VM_MEMORY_INACTIVE(AGENT_RESULT * result)70 static int VM_MEMORY_INACTIVE(AGENT_RESULT *result)
71 {
72 ZBX_HOST_STATISTICS(vm);
73
74 SET_UI64_RESULT(result, (zbx_uint64_t)vm.inactive_count * pagesize);
75
76 return SYSINFO_RET_OK;
77 }
78
VM_MEMORY_WIRED(AGENT_RESULT * result)79 static int VM_MEMORY_WIRED(AGENT_RESULT *result)
80 {
81 ZBX_HOST_STATISTICS(vm);
82
83 SET_UI64_RESULT(result, (zbx_uint64_t)vm.wire_count * pagesize);
84
85 return SYSINFO_RET_OK;
86 }
87
VM_MEMORY_FREE(AGENT_RESULT * result)88 static int VM_MEMORY_FREE(AGENT_RESULT *result)
89 {
90 ZBX_HOST_STATISTICS(vm);
91
92 SET_UI64_RESULT(result, (zbx_uint64_t)vm.free_count * pagesize);
93
94 return SYSINFO_RET_OK;
95 }
96
VM_MEMORY_USED(AGENT_RESULT * result)97 static int VM_MEMORY_USED(AGENT_RESULT *result)
98 {
99 ZBX_HOST_STATISTICS(vm);
100
101 SET_UI64_RESULT(result, (zbx_uint64_t)(vm.active_count + vm.wire_count) * pagesize);
102
103 return SYSINFO_RET_OK;
104 }
105
VM_MEMORY_PUSED(AGENT_RESULT * result)106 static int VM_MEMORY_PUSED(AGENT_RESULT *result)
107 {
108 zbx_uint64_t used;
109
110 ZBX_SYSCTL(memsize);
111
112 if (0 == memsize)
113 {
114 SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot calculate percentage because total is zero."));
115 return SYSINFO_RET_FAIL;
116 }
117
118 ZBX_HOST_STATISTICS(vm);
119
120 used = (zbx_uint64_t)(vm.active_count + vm.wire_count) * pagesize;
121
122 SET_DBL_RESULT(result, used / (double)memsize * 100);
123
124 return SYSINFO_RET_OK;
125 }
126
VM_MEMORY_AVAILABLE(AGENT_RESULT * result)127 static int VM_MEMORY_AVAILABLE(AGENT_RESULT *result)
128 {
129 ZBX_HOST_STATISTICS(vm);
130
131 SET_UI64_RESULT(result, (zbx_uint64_t)(vm.inactive_count + vm.free_count) * pagesize);
132
133 return SYSINFO_RET_OK;
134 }
135
VM_MEMORY_PAVAILABLE(AGENT_RESULT * result)136 static int VM_MEMORY_PAVAILABLE(AGENT_RESULT *result)
137 {
138 zbx_uint64_t available;
139
140 ZBX_SYSCTL(memsize);
141
142 if (0 == memsize)
143 {
144 SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot calculate percentage because total is zero."));
145 return SYSINFO_RET_FAIL;
146 }
147
148 ZBX_HOST_STATISTICS(vm);
149
150 available = (zbx_uint64_t)(vm.inactive_count + vm.free_count) * pagesize;
151
152 SET_DBL_RESULT(result, available / (double)memsize * 100);
153
154 return SYSINFO_RET_OK;
155 }
156
VM_MEMORY_SIZE(AGENT_REQUEST * request,AGENT_RESULT * result)157 int VM_MEMORY_SIZE(AGENT_REQUEST *request, AGENT_RESULT *result)
158 {
159 char *mode;
160 int ret = SYSINFO_RET_FAIL;
161
162 if (1 < request->nparam)
163 {
164 SET_MSG_RESULT(result, zbx_strdup(NULL, "Too many parameters."));
165 return SYSINFO_RET_FAIL;
166 }
167
168 if (0 == pagesize)
169 {
170 if (KERN_SUCCESS != host_page_size(mach_host_self(), &pagesize))
171 {
172 SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot obtain host page size."));
173 return SYSINFO_RET_FAIL;
174 }
175 }
176
177 mode = get_rparam(request, 0);
178
179 if (NULL == mode || '\0' == *mode || 0 == strcmp(mode, "total"))
180 ret = VM_MEMORY_TOTAL(result);
181 else if (0 == strcmp(mode, "active"))
182 ret = VM_MEMORY_ACTIVE(result);
183 else if (0 == strcmp(mode, "inactive"))
184 ret = VM_MEMORY_INACTIVE(result);
185 else if (0 == strcmp(mode, "wired"))
186 ret = VM_MEMORY_WIRED(result);
187 else if (0 == strcmp(mode, "free"))
188 ret = VM_MEMORY_FREE(result);
189 else if (0 == strcmp(mode, "used"))
190 ret = VM_MEMORY_USED(result);
191 else if (0 == strcmp(mode, "pused"))
192 ret = VM_MEMORY_PUSED(result);
193 else if (0 == strcmp(mode, "available"))
194 ret = VM_MEMORY_AVAILABLE(result);
195 else if (0 == strcmp(mode, "pavailable"))
196 ret = VM_MEMORY_PAVAILABLE(result);
197 else
198 {
199 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid first parameter."));
200 return SYSINFO_RET_FAIL;
201 }
202
203 return ret;
204 }
205