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