1157001Sgshapiro/*
2261363Sgshapiro * Copyright (c) 2005-2007 Proofpoint, Inc. and its suppliers.
3157001Sgshapiro *      All rights reserved.
4157001Sgshapiro *
5157001Sgshapiro * By using this file, you agree to the terms and conditions set
6157001Sgshapiro * forth in the LICENSE file which can be found at the top level of
7157001Sgshapiro * the sendmail distribution.
8157001Sgshapiro */
9157001Sgshapiro
10157001Sgshapiro#include <sm/gen.h>
11266692SgshapiroSM_RCSID("@(#)$Id: memstat.c,v 1.7 2013-11-22 20:51:43 ca Exp $")
12157001Sgshapiro
13157001Sgshapiro#include <errno.h>
14168515Sgshapiro#include <sm/misc.h>
15157001Sgshapiro
16157001Sgshapiro#if USESWAPCTL
17157001Sgshapiro#include <sys/stat.h>
18157001Sgshapiro#include <sys/swap.h>
19157001Sgshapiro
20157001Sgshapirostatic long sc_page_size;
21157001Sgshapiro
22157001Sgshapiro/*
23157001Sgshapiro**  SM_MEMSTAT_OPEN -- open memory statistics
24157001Sgshapiro**
25157001Sgshapiro**	Parameters:
26157001Sgshapiro**		none
27157001Sgshapiro**
28157001Sgshapiro**	Results:
29157001Sgshapiro**		errno as error code, 0: ok
30157001Sgshapiro*/
31157001Sgshapiro
32157001Sgshapiroint
33157001Sgshapirosm_memstat_open()
34157001Sgshapiro{
35157001Sgshapiro	sc_page_size = sysconf(_SC_PAGE_SIZE);
36157001Sgshapiro	if (sc_page_size == -1)
37157001Sgshapiro		return (errno != 0) ? errno : -1;
38157001Sgshapiro	return 0;
39157001Sgshapiro}
40157001Sgshapiro
41157001Sgshapiro/*
42157001Sgshapiro**  SM_MEMSTAT_CLOSE -- close memory statistics
43157001Sgshapiro**
44157001Sgshapiro**	Parameters:
45157001Sgshapiro**		none
46157001Sgshapiro**
47157001Sgshapiro**	Results:
48157001Sgshapiro**		errno as error code, 0: ok
49157001Sgshapiro*/
50157001Sgshapiro
51157001Sgshapiroint
52157001Sgshapirosm_memstat_close()
53157001Sgshapiro{
54157001Sgshapiro	return 0;
55157001Sgshapiro}
56157001Sgshapiro
57157001Sgshapiro/*
58157001Sgshapiro**  SM_MEMSTAT_GET -- get memory statistics
59157001Sgshapiro**
60157001Sgshapiro**	Parameters:
61157001Sgshapiro**		resource -- resource to look up
62157001Sgshapiro**		pvalue -- (pointer to) memory statistics value (output)
63157001Sgshapiro**
64157001Sgshapiro**	Results:
65157001Sgshapiro**		0: success
66157001Sgshapiro**		!=0: error
67157001Sgshapiro*/
68157001Sgshapiro
69157001Sgshapiroint
70157001Sgshapirosm_memstat_get(resource, pvalue)
71157001Sgshapiro	char *resource;
72157001Sgshapiro	long *pvalue;
73157001Sgshapiro{
74157001Sgshapiro	int r;
75157001Sgshapiro	struct anoninfo ai;
76157001Sgshapiro
77157001Sgshapiro	r = swapctl(SC_AINFO, &ai);
78157001Sgshapiro	if (r == -1)
79157001Sgshapiro		return (errno != 0) ? errno : -1;
80157001Sgshapiro	r = ai.ani_max - ai.ani_resv;
81157001Sgshapiro	r *= sc_page_size >> 10;
82157001Sgshapiro   	*pvalue = r;
83157001Sgshapiro	return 0;
84157001Sgshapiro}
85157001Sgshapiro
86157001Sgshapiro#elif USEKSTAT
87157001Sgshapiro
88157001Sgshapiro#include <kstat.h>
89157001Sgshapiro#include <sys/sysinfo.h>
90157001Sgshapiro
91157001Sgshapirostatic kstat_ctl_t *kc;
92157001Sgshapirostatic kstat_t *kst;
93157001Sgshapiro
94157001Sgshapiro/*
95157001Sgshapiro**  SM_MEMSTAT_OPEN -- open memory statistics
96157001Sgshapiro**
97157001Sgshapiro**	Parameters:
98157001Sgshapiro**		none
99157001Sgshapiro**
100157001Sgshapiro**	Results:
101157001Sgshapiro**		errno as error code, 0: ok
102157001Sgshapiro*/
103157001Sgshapiro
104157001Sgshapiroint
105157001Sgshapirosm_memstat_open()
106157001Sgshapiro{
107157001Sgshapiro	kstat_named_t *kn;
108157001Sgshapiro
109157001Sgshapiro	kc = kstat_open();
110157001Sgshapiro	if (kc == NULL)
111157001Sgshapiro		return (errno != 0) ? errno : -1;
112157001Sgshapiro	kst = kstat_lookup(kc, "unix", 0,
113157001Sgshapiro		(name != NULL) ? name : "system_pages");
114157001Sgshapiro	if (kst == 0)
115157001Sgshapiro		return (errno != 0) ? errno : -2;
116157001Sgshapiro	return 0;
117157001Sgshapiro}
118157001Sgshapiro
119157001Sgshapiro/*
120157001Sgshapiro**  SM_MEMSTAT_CLOSE -- close memory statistics
121157001Sgshapiro**
122157001Sgshapiro**	Parameters:
123157001Sgshapiro**		none
124157001Sgshapiro**
125157001Sgshapiro**	Results:
126157001Sgshapiro**		errno as error code, 0: ok
127157001Sgshapiro*/
128157001Sgshapiro
129157001Sgshapiroint
130157001Sgshapirosm_memstat_close()
131157001Sgshapiro{
132157001Sgshapiro	int r;
133157001Sgshapiro
134157001Sgshapiro	if (kc == NULL)
135157001Sgshapiro		return 0;
136157001Sgshapiro	r = kstat_close(kc);
137157001Sgshapiro	if (r != 0)
138157001Sgshapiro		return (errno != 0) ? errno : -1;
139157001Sgshapiro	return 0;
140157001Sgshapiro}
141157001Sgshapiro
142157001Sgshapiro/*
143157001Sgshapiro**  SM_MEMSTAT_GET -- get memory statistics
144157001Sgshapiro**
145157001Sgshapiro**	Parameters:
146157001Sgshapiro**		resource -- resource to look up
147157001Sgshapiro**		pvalue -- (pointer to) memory statistics value (output)
148157001Sgshapiro**
149157001Sgshapiro**	Results:
150157001Sgshapiro**		0: success
151157001Sgshapiro**		!=0: error
152157001Sgshapiro*/
153157001Sgshapiro
154157001Sgshapiroint
155157001Sgshapirosm_memstat_get(resource, pvalue)
156157001Sgshapiro	char *resource;
157157001Sgshapiro	long *pvalue;
158157001Sgshapiro{
159157001Sgshapiro	int r;
160157001Sgshapiro	kstat_named_t *kn;
161157001Sgshapiro
162157001Sgshapiro	if (kc == NULL || kst == NULL)
163157001Sgshapiro		return -1;
164157001Sgshapiro	if (kstat_read(kc, kst, NULL) == -1)
165157001Sgshapiro		return (errno != 0) ? errno : -2;
166157001Sgshapiro	kn = kstat_data_lookup(kst,
167157001Sgshapiro			(resource != NULL) ? resource: "freemem");
168157001Sgshapiro	if (kn == NULL)
169157001Sgshapiro		return (errno != 0) ? errno : -3;
170157001Sgshapiro   	*pvalue = kn->value.ul;
171157001Sgshapiro	return 0;
172157001Sgshapiro}
173157001Sgshapiro
174157001Sgshapiro#elif USEPROCMEMINFO
175157001Sgshapiro
176157001Sgshapiro/*
177157001Sgshapiro/proc/meminfo?
178157001Sgshapiro        total:    used:    free:  shared: buffers:  cached:
179157001SgshapiroMem:  261468160 252149760  9318400        0  3854336 109813760
180157001SgshapiroSwap: 1052794880 62185472 990609408
181157001SgshapiroMemTotal:       255340 kB
182157001SgshapiroMemFree:          9100 kB
183157001SgshapiroMemShared:           0 kB
184157001SgshapiroBuffers:          3764 kB
185157001SgshapiroCached:         107240 kB
186157001SgshapiroActive:         104340 kB
187157001SgshapiroInact_dirty:      4220 kB
188157001SgshapiroInact_clean:      2444 kB
189157001SgshapiroInact_target:     4092 kB
190157001SgshapiroHighTotal:           0 kB
191157001SgshapiroHighFree:            0 kB
192157001SgshapiroLowTotal:       255340 kB
193157001SgshapiroLowFree:          9100 kB
194157001SgshapiroSwapTotal:     1028120 kB
195157001SgshapiroSwapFree:       967392 kB
196157001Sgshapiro*/
197157001Sgshapiro
198157001Sgshapiro#include <stdio.h>
199157001Sgshapiro#include <string.h>
200157001Sgshapirostatic FILE *fp;
201157001Sgshapiro
202157001Sgshapiro/*
203157001Sgshapiro**  SM_MEMSTAT_OPEN -- open memory statistics
204157001Sgshapiro**
205157001Sgshapiro**	Parameters:
206157001Sgshapiro**		none
207157001Sgshapiro**
208157001Sgshapiro**	Results:
209157001Sgshapiro**		errno as error code, 0: ok
210157001Sgshapiro*/
211157001Sgshapiro
212157001Sgshapiroint
213157001Sgshapirosm_memstat_open()
214157001Sgshapiro{
215157001Sgshapiro	fp = fopen("/proc/meminfo", "r");
216157001Sgshapiro	return (fp != NULL) ? 0 : errno;
217157001Sgshapiro}
218157001Sgshapiro
219157001Sgshapiro/*
220157001Sgshapiro**  SM_MEMSTAT_CLOSE -- close memory statistics
221157001Sgshapiro**
222157001Sgshapiro**	Parameters:
223157001Sgshapiro**		none
224157001Sgshapiro**
225157001Sgshapiro**	Results:
226157001Sgshapiro**		errno as error code, 0: ok
227157001Sgshapiro*/
228157001Sgshapiro
229157001Sgshapiroint
230157001Sgshapirosm_memstat_close()
231157001Sgshapiro{
232157001Sgshapiro	if (fp != NULL)
233157001Sgshapiro	{
234157001Sgshapiro		fclose(fp);
235157001Sgshapiro		fp = NULL;
236157001Sgshapiro	}
237157001Sgshapiro	return 0;
238157001Sgshapiro}
239157001Sgshapiro
240157001Sgshapiro/*
241157001Sgshapiro**  SM_MEMSTAT_GET -- get memory statistics
242157001Sgshapiro**
243157001Sgshapiro**	Parameters:
244157001Sgshapiro**		resource -- resource to look up
245157001Sgshapiro**		pvalue -- (pointer to) memory statistics value (output)
246157001Sgshapiro**
247157001Sgshapiro**	Results:
248157001Sgshapiro**		0: success
249157001Sgshapiro**		!=0: error
250157001Sgshapiro*/
251157001Sgshapiro
252157001Sgshapiroint
253157001Sgshapirosm_memstat_get(resource, pvalue)
254157001Sgshapiro	char *resource;
255157001Sgshapiro	long *pvalue;
256157001Sgshapiro{
257157001Sgshapiro	int r;
258157001Sgshapiro	size_t l;
259157001Sgshapiro	char buf[80];
260157001Sgshapiro
261157001Sgshapiro	if (resource == NULL)
262157001Sgshapiro		return EINVAL;
263157001Sgshapiro	if (pvalue == NULL)
264157001Sgshapiro		return EINVAL;
265157001Sgshapiro	if (fp == NULL)
266157001Sgshapiro		return -1;	/* try to reopen? */
267157001Sgshapiro	rewind(fp);
268157001Sgshapiro	l = strlen(resource);
269168515Sgshapiro	if (l >= sizeof(buf))
270168515Sgshapiro		return EINVAL;
271157001Sgshapiro	while (fgets(buf, sizeof(buf), fp) != NULL)
272157001Sgshapiro	{
273157001Sgshapiro		if (strncmp(buf, resource, l) == 0 && buf[l] == ':')
274157001Sgshapiro		{
275157001Sgshapiro			r = sscanf(buf + l + 1, "%ld", pvalue);
276157001Sgshapiro			return (r > 0) ? 0 : -1;
277157001Sgshapiro		}
278157001Sgshapiro	}
279157001Sgshapiro	return 0;
280157001Sgshapiro}
281157001Sgshapiro
282157001Sgshapiro#else /* USEPROCMEMINFO */
283157001Sgshapiro
284157001Sgshapiro/*
285157001Sgshapiro**  SM_MEMSTAT_OPEN -- open memory statistics
286157001Sgshapiro**
287157001Sgshapiro**	Parameters:
288157001Sgshapiro**		none
289157001Sgshapiro**
290157001Sgshapiro**	Results:
291157001Sgshapiro**		errno as error code, 0: ok
292157001Sgshapiro*/
293157001Sgshapiro
294157001Sgshapiroint
295157001Sgshapirosm_memstat_open()
296157001Sgshapiro{
297157001Sgshapiro	return -1;
298157001Sgshapiro}
299157001Sgshapiro
300157001Sgshapiro/*
301157001Sgshapiro**  SM_MEMSTAT_CLOSE -- close memory statistics
302157001Sgshapiro**
303157001Sgshapiro**	Parameters:
304157001Sgshapiro**		none
305157001Sgshapiro**
306157001Sgshapiro**	Results:
307157001Sgshapiro**		errno as error code, 0: ok
308157001Sgshapiro*/
309157001Sgshapiro
310157001Sgshapiroint
311157001Sgshapirosm_memstat_close()
312157001Sgshapiro{
313157001Sgshapiro	return 0;
314157001Sgshapiro}
315157001Sgshapiro
316157001Sgshapiro/*
317157001Sgshapiro**  SM_MEMSTAT_GET -- get memory statistics
318157001Sgshapiro**
319157001Sgshapiro**	Parameters:
320157001Sgshapiro**		resource -- resource to look up
321157001Sgshapiro**		pvalue -- (pointer to) memory statistics value (output)
322157001Sgshapiro**
323157001Sgshapiro**	Results:
324157001Sgshapiro**		0: success
325157001Sgshapiro**		!=0: error
326157001Sgshapiro*/
327157001Sgshapiro
328157001Sgshapiroint
329157001Sgshapirosm_memstat_get(resource, pvalue)
330157001Sgshapiro	char *resource;
331157001Sgshapiro	long *pvalue;
332157001Sgshapiro{
333157001Sgshapiro	return -1;
334157001Sgshapiro}
335157001Sgshapiro
336157001Sgshapiro#endif /* USEKSTAT */
337