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 #ifdef HAVE_VMINFO_T_UPDATES
23 #include "stats.h"
24 #endif
25 
VM_MEMORY_TOTAL(AGENT_RESULT * result)26 static int	VM_MEMORY_TOTAL(AGENT_RESULT *result)
27 {
28 	SET_UI64_RESULT(result, (zbx_uint64_t)sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE));
29 
30 	return SYSINFO_RET_OK;
31 }
32 
33 #ifndef HAVE_VMINFO_T_UPDATES
VM_MEMORY_USED(AGENT_RESULT * result)34 static int	VM_MEMORY_USED(AGENT_RESULT *result)
35 {
36 	zbx_uint64_t	used;
37 
38 	used = sysconf(_SC_PHYS_PAGES) - sysconf(_SC_AVPHYS_PAGES);
39 
40 	SET_UI64_RESULT(result, used * sysconf(_SC_PAGESIZE));
41 
42 	return SYSINFO_RET_OK;
43 }
44 
VM_MEMORY_PUSED(AGENT_RESULT * result)45 static int	VM_MEMORY_PUSED(AGENT_RESULT *result)
46 {
47 	zbx_uint64_t	used, total;
48 
49 	if (0 == (total = sysconf(_SC_PHYS_PAGES)))
50 	{
51 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot calculate percentage because total is zero."));
52 		return SYSINFO_RET_FAIL;
53 	}
54 
55 	used = total - sysconf(_SC_AVPHYS_PAGES);
56 
57 	SET_DBL_RESULT(result, used / (double)total * 100);
58 
59 	return SYSINFO_RET_OK;
60 }
61 
VM_MEMORY_AVAILABLE(AGENT_RESULT * result)62 static int	VM_MEMORY_AVAILABLE(AGENT_RESULT *result)
63 {
64 	SET_UI64_RESULT(result, (zbx_uint64_t)sysconf(_SC_AVPHYS_PAGES) * sysconf(_SC_PAGESIZE));
65 
66 	return SYSINFO_RET_OK;
67 }
68 
VM_MEMORY_PAVAILABLE(AGENT_RESULT * result)69 static int	VM_MEMORY_PAVAILABLE(AGENT_RESULT *result)
70 {
71 	zbx_uint64_t	total;
72 
73 	if (0 == (total = sysconf(_SC_PHYS_PAGES)))
74 	{
75 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot calculate percentage because total is zero."));
76 		return SYSINFO_RET_FAIL;
77 	}
78 
79 	SET_DBL_RESULT(result, sysconf(_SC_AVPHYS_PAGES) / (double)total * 100);
80 
81 	return SYSINFO_RET_OK;
82 }
83 
84 #else /*HAVE_VMINFO_T_UPDATES*/
85 
VM_MEMORY_USED(AGENT_RESULT * result)86 static int	VM_MEMORY_USED(AGENT_RESULT *result)
87 {
88 	zbx_uint64_t	freemem;
89 	char		*error = NULL;
90 
91 	if (SUCCEED == zbx_kstat_get_freemem(&freemem, &error))
92 	{
93 		SET_UI64_RESULT(result, sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE) - freemem);
94 	}
95 	else if (NULL != error)
96 	{
97 		SET_MSG_RESULT(result, error);
98 		return SYSINFO_RET_FAIL;
99 	}
100 
101 	return SYSINFO_RET_OK;
102 }
103 
VM_MEMORY_PUSED(AGENT_RESULT * result)104 static int	VM_MEMORY_PUSED(AGENT_RESULT *result)
105 {
106 	zbx_uint64_t	freemem, total;
107 	char		*error = NULL;
108 
109 	if (0 == (total = sysconf(_SC_PHYS_PAGES)))
110 	{
111 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot calculate percentage because total is zero."));
112 		return SYSINFO_RET_FAIL;
113 	}
114 
115 	if (SUCCEED == zbx_kstat_get_freemem(&freemem, &error))
116 	{
117 		total *= sysconf(_SC_PAGESIZE);
118 		SET_DBL_RESULT(result, (total - freemem) / (double)total * 100);
119 	}
120 	else if (NULL != error)
121 	{
122 		SET_MSG_RESULT(result, error);
123 		return SYSINFO_RET_FAIL;
124 	}
125 
126 	return SYSINFO_RET_OK;
127 }
128 
VM_MEMORY_AVAILABLE(AGENT_RESULT * result)129 static int	VM_MEMORY_AVAILABLE(AGENT_RESULT *result)
130 {
131 	zbx_uint64_t	freemem;
132 	char		*error = NULL;
133 
134 	if (SUCCEED == zbx_kstat_get_freemem(&freemem, &error))
135 	{
136 		SET_UI64_RESULT(result, freemem);
137 	}
138 	else if (NULL != error)
139 	{
140 		SET_MSG_RESULT(result, error);
141 		return SYSINFO_RET_FAIL;
142 	}
143 
144 	return SYSINFO_RET_OK;
145 }
146 
VM_MEMORY_PAVAILABLE(AGENT_RESULT * result)147 static int	VM_MEMORY_PAVAILABLE(AGENT_RESULT *result)
148 {
149 	zbx_uint64_t	total, freemem;
150 	char		*error = NULL;
151 
152 	if (0 == (total = sysconf(_SC_PHYS_PAGES)))
153 	{
154 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot calculate percentage because total is zero."));
155 		return SYSINFO_RET_FAIL;
156 	}
157 
158 	if (SUCCEED == zbx_kstat_get_freemem(&freemem, &error))
159 	{
160 		total *= sysconf(_SC_PAGESIZE);
161 		SET_DBL_RESULT(result, freemem / (double)total * 100);
162 	}
163 	else if (NULL != error)
164 	{
165 		SET_MSG_RESULT(result, error);
166 		return SYSINFO_RET_FAIL;
167 	}
168 
169 	return SYSINFO_RET_OK;
170 }
171 #endif /*HAVE_VMINFO_T_UPDATES*/
172 
VM_MEMORY_SIZE(AGENT_REQUEST * request,AGENT_RESULT * result)173 int     VM_MEMORY_SIZE(AGENT_REQUEST *request, AGENT_RESULT *result)
174 {
175 	char	*mode;
176 	int	ret;
177 
178 	if (1 < request->nparam)
179 	{
180 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Too many parameters."));
181 		return SYSINFO_RET_FAIL;
182 	}
183 
184 	mode = get_rparam(request, 0);
185 
186 	if (NULL == mode || '\0' == *mode || 0 == strcmp(mode, "total"))
187 		ret = VM_MEMORY_TOTAL(result);
188 	else if (0 == strcmp(mode, "used"))
189 		ret = VM_MEMORY_USED(result);
190 	else if (0 == strcmp(mode, "pused"))
191 		ret = VM_MEMORY_PUSED(result);
192 	else if (0 == strcmp(mode, "available") || 0 == strcmp(mode, "free"))
193 		ret = VM_MEMORY_AVAILABLE(result);
194 	else if (0 == strcmp(mode, "pavailable"))
195 		ret = VM_MEMORY_PAVAILABLE(result);
196 	else
197 	{
198 		SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid first parameter."));
199 		return SYSINFO_RET_FAIL;
200 	}
201 
202 	return ret;
203 }
204