memstat.c revision 302408
1/*
2 * Copyright (c) 2005-2007 Proofpoint, Inc. and its suppliers.
3 *      All rights reserved.
4 *
5 * By using this file, you agree to the terms and conditions set
6 * forth in the LICENSE file which can be found at the top level of
7 * the sendmail distribution.
8 */
9
10#include <sm/gen.h>
11SM_RCSID("@(#)$Id: memstat.c,v 1.7 2013-11-22 20:51:43 ca Exp $")
12
13#include <errno.h>
14#include <sm/misc.h>
15
16#if USESWAPCTL
17#include <sys/stat.h>
18#include <sys/swap.h>
19
20static long sc_page_size;
21
22/*
23**  SM_MEMSTAT_OPEN -- open memory statistics
24**
25**	Parameters:
26**		none
27**
28**	Results:
29**		errno as error code, 0: ok
30*/
31
32int
33sm_memstat_open()
34{
35	sc_page_size = sysconf(_SC_PAGE_SIZE);
36	if (sc_page_size == -1)
37		return (errno != 0) ? errno : -1;
38	return 0;
39}
40
41/*
42**  SM_MEMSTAT_CLOSE -- close memory statistics
43**
44**	Parameters:
45**		none
46**
47**	Results:
48**		errno as error code, 0: ok
49*/
50
51int
52sm_memstat_close()
53{
54	return 0;
55}
56
57/*
58**  SM_MEMSTAT_GET -- get memory statistics
59**
60**	Parameters:
61**		resource -- resource to look up
62**		pvalue -- (pointer to) memory statistics value (output)
63**
64**	Results:
65**		0: success
66**		!=0: error
67*/
68
69int
70sm_memstat_get(resource, pvalue)
71	char *resource;
72	long *pvalue;
73{
74	int r;
75	struct anoninfo ai;
76
77	r = swapctl(SC_AINFO, &ai);
78	if (r == -1)
79		return (errno != 0) ? errno : -1;
80	r = ai.ani_max - ai.ani_resv;
81	r *= sc_page_size >> 10;
82   	*pvalue = r;
83	return 0;
84}
85
86#elif USEKSTAT
87
88#include <kstat.h>
89#include <sys/sysinfo.h>
90
91static kstat_ctl_t *kc;
92static kstat_t *kst;
93
94/*
95**  SM_MEMSTAT_OPEN -- open memory statistics
96**
97**	Parameters:
98**		none
99**
100**	Results:
101**		errno as error code, 0: ok
102*/
103
104int
105sm_memstat_open()
106{
107	kstat_named_t *kn;
108
109	kc = kstat_open();
110	if (kc == NULL)
111		return (errno != 0) ? errno : -1;
112	kst = kstat_lookup(kc, "unix", 0,
113		(name != NULL) ? name : "system_pages");
114	if (kst == 0)
115		return (errno != 0) ? errno : -2;
116	return 0;
117}
118
119/*
120**  SM_MEMSTAT_CLOSE -- close memory statistics
121**
122**	Parameters:
123**		none
124**
125**	Results:
126**		errno as error code, 0: ok
127*/
128
129int
130sm_memstat_close()
131{
132	int r;
133
134	if (kc == NULL)
135		return 0;
136	r = kstat_close(kc);
137	if (r != 0)
138		return (errno != 0) ? errno : -1;
139	return 0;
140}
141
142/*
143**  SM_MEMSTAT_GET -- get memory statistics
144**
145**	Parameters:
146**		resource -- resource to look up
147**		pvalue -- (pointer to) memory statistics value (output)
148**
149**	Results:
150**		0: success
151**		!=0: error
152*/
153
154int
155sm_memstat_get(resource, pvalue)
156	char *resource;
157	long *pvalue;
158{
159	int r;
160	kstat_named_t *kn;
161
162	if (kc == NULL || kst == NULL)
163		return -1;
164	if (kstat_read(kc, kst, NULL) == -1)
165		return (errno != 0) ? errno : -2;
166	kn = kstat_data_lookup(kst,
167			(resource != NULL) ? resource: "freemem");
168	if (kn == NULL)
169		return (errno != 0) ? errno : -3;
170   	*pvalue = kn->value.ul;
171	return 0;
172}
173
174#elif USEPROCMEMINFO
175
176/*
177/proc/meminfo?
178        total:    used:    free:  shared: buffers:  cached:
179Mem:  261468160 252149760  9318400        0  3854336 109813760
180Swap: 1052794880 62185472 990609408
181MemTotal:       255340 kB
182MemFree:          9100 kB
183MemShared:           0 kB
184Buffers:          3764 kB
185Cached:         107240 kB
186Active:         104340 kB
187Inact_dirty:      4220 kB
188Inact_clean:      2444 kB
189Inact_target:     4092 kB
190HighTotal:           0 kB
191HighFree:            0 kB
192LowTotal:       255340 kB
193LowFree:          9100 kB
194SwapTotal:     1028120 kB
195SwapFree:       967392 kB
196*/
197
198#include <stdio.h>
199#include <string.h>
200static FILE *fp;
201
202/*
203**  SM_MEMSTAT_OPEN -- open memory statistics
204**
205**	Parameters:
206**		none
207**
208**	Results:
209**		errno as error code, 0: ok
210*/
211
212int
213sm_memstat_open()
214{
215	fp = fopen("/proc/meminfo", "r");
216	return (fp != NULL) ? 0 : errno;
217}
218
219/*
220**  SM_MEMSTAT_CLOSE -- close memory statistics
221**
222**	Parameters:
223**		none
224**
225**	Results:
226**		errno as error code, 0: ok
227*/
228
229int
230sm_memstat_close()
231{
232	if (fp != NULL)
233	{
234		fclose(fp);
235		fp = NULL;
236	}
237	return 0;
238}
239
240/*
241**  SM_MEMSTAT_GET -- get memory statistics
242**
243**	Parameters:
244**		resource -- resource to look up
245**		pvalue -- (pointer to) memory statistics value (output)
246**
247**	Results:
248**		0: success
249**		!=0: error
250*/
251
252int
253sm_memstat_get(resource, pvalue)
254	char *resource;
255	long *pvalue;
256{
257	int r;
258	size_t l;
259	char buf[80];
260
261	if (resource == NULL)
262		return EINVAL;
263	if (pvalue == NULL)
264		return EINVAL;
265	if (fp == NULL)
266		return -1;	/* try to reopen? */
267	rewind(fp);
268	l = strlen(resource);
269	if (l >= sizeof(buf))
270		return EINVAL;
271	while (fgets(buf, sizeof(buf), fp) != NULL)
272	{
273		if (strncmp(buf, resource, l) == 0 && buf[l] == ':')
274		{
275			r = sscanf(buf + l + 1, "%ld", pvalue);
276			return (r > 0) ? 0 : -1;
277		}
278	}
279	return 0;
280}
281
282#else /* USEPROCMEMINFO */
283
284/*
285**  SM_MEMSTAT_OPEN -- open memory statistics
286**
287**	Parameters:
288**		none
289**
290**	Results:
291**		errno as error code, 0: ok
292*/
293
294int
295sm_memstat_open()
296{
297	return -1;
298}
299
300/*
301**  SM_MEMSTAT_CLOSE -- close memory statistics
302**
303**	Parameters:
304**		none
305**
306**	Results:
307**		errno as error code, 0: ok
308*/
309
310int
311sm_memstat_close()
312{
313	return 0;
314}
315
316/*
317**  SM_MEMSTAT_GET -- get memory statistics
318**
319**	Parameters:
320**		resource -- resource to look up
321**		pvalue -- (pointer to) memory statistics value (output)
322**
323**	Results:
324**		0: success
325**		!=0: error
326*/
327
328int
329sm_memstat_get(resource, pvalue)
330	char *resource;
331	long *pvalue;
332{
333	return -1;
334}
335
336#endif /* USEKSTAT */
337