xref: /illumos-gate/usr/src/cmd/sendmail/libsm/memstat.c (revision 2a8bcb4efb45d99ac41c94a75c396b362c414f7f)
1058561cbSjbeck /*
2*4aac33d3Sjbeck  * Copyright (c) 2005-2007 Sendmail, Inc. and its suppliers.
3058561cbSjbeck  *      All rights reserved.
4058561cbSjbeck  *
5058561cbSjbeck  * By using this file, you agree to the terms and conditions set
6058561cbSjbeck  * forth in the LICENSE file which can be found at the top level of
7058561cbSjbeck  * the sendmail distribution.
8058561cbSjbeck  */
9058561cbSjbeck 
10058561cbSjbeck #include <sm/gen.h>
11*4aac33d3Sjbeck SM_RCSID("@(#)$Id: memstat.c,v 1.6 2007/03/20 23:26:12 ca Exp $")
12058561cbSjbeck 
13058561cbSjbeck #include <errno.h>
14058561cbSjbeck #include <sm/misc.h>
15058561cbSjbeck 
16058561cbSjbeck #if USESWAPCTL
17058561cbSjbeck #include <sys/stat.h>
18058561cbSjbeck #include <sys/swap.h>
19058561cbSjbeck 
20058561cbSjbeck static long sc_page_size;
21058561cbSjbeck 
22058561cbSjbeck /*
23058561cbSjbeck **  SM_MEMSTAT_OPEN -- open memory statistics
24058561cbSjbeck **
25058561cbSjbeck **	Parameters:
26058561cbSjbeck **		none
27058561cbSjbeck **
28058561cbSjbeck **	Results:
29058561cbSjbeck **		errno as error code, 0: ok
30058561cbSjbeck */
31058561cbSjbeck 
32058561cbSjbeck int
sm_memstat_open()33058561cbSjbeck sm_memstat_open()
34058561cbSjbeck {
35058561cbSjbeck 	sc_page_size = sysconf(_SC_PAGE_SIZE);
36058561cbSjbeck 	if (sc_page_size == -1)
37058561cbSjbeck 		return (errno != 0) ? errno : -1;
38058561cbSjbeck 	return 0;
39058561cbSjbeck }
40058561cbSjbeck 
41058561cbSjbeck /*
42058561cbSjbeck **  SM_MEMSTAT_CLOSE -- close memory statistics
43058561cbSjbeck **
44058561cbSjbeck **	Parameters:
45058561cbSjbeck **		none
46058561cbSjbeck **
47058561cbSjbeck **	Results:
48058561cbSjbeck **		errno as error code, 0: ok
49058561cbSjbeck */
50058561cbSjbeck 
51058561cbSjbeck int
sm_memstat_close()52058561cbSjbeck sm_memstat_close()
53058561cbSjbeck {
54058561cbSjbeck 	return 0;
55058561cbSjbeck }
56058561cbSjbeck 
57058561cbSjbeck /*
58058561cbSjbeck **  SM_MEMSTAT_GET -- get memory statistics
59058561cbSjbeck **
60058561cbSjbeck **	Parameters:
61058561cbSjbeck **		resource -- resource to look up
62058561cbSjbeck **		pvalue -- (pointer to) memory statistics value (output)
63058561cbSjbeck **
64058561cbSjbeck **	Results:
65058561cbSjbeck **		0: success
66058561cbSjbeck **		!=0: error
67058561cbSjbeck */
68058561cbSjbeck 
69058561cbSjbeck int
sm_memstat_get(resource,pvalue)70058561cbSjbeck sm_memstat_get(resource, pvalue)
71058561cbSjbeck 	char *resource;
72058561cbSjbeck 	long *pvalue;
73058561cbSjbeck {
74058561cbSjbeck 	int r;
75058561cbSjbeck 	struct anoninfo ai;
76058561cbSjbeck 
77058561cbSjbeck 	r = swapctl(SC_AINFO, &ai);
78058561cbSjbeck 	if (r == -1)
79058561cbSjbeck 		return (errno != 0) ? errno : -1;
80058561cbSjbeck 	r = ai.ani_max - ai.ani_resv;
81058561cbSjbeck 	r *= sc_page_size >> 10;
82058561cbSjbeck    	*pvalue = r;
83058561cbSjbeck 	return 0;
84058561cbSjbeck }
85058561cbSjbeck 
86058561cbSjbeck #elif USEKSTAT
87058561cbSjbeck 
88058561cbSjbeck #include <kstat.h>
89058561cbSjbeck #include <sys/sysinfo.h>
90058561cbSjbeck 
91058561cbSjbeck static kstat_ctl_t *kc;
92058561cbSjbeck static kstat_t *kst;
93058561cbSjbeck 
94058561cbSjbeck /*
95058561cbSjbeck **  SM_MEMSTAT_OPEN -- open memory statistics
96058561cbSjbeck **
97058561cbSjbeck **	Parameters:
98058561cbSjbeck **		none
99058561cbSjbeck **
100058561cbSjbeck **	Results:
101058561cbSjbeck **		errno as error code, 0: ok
102058561cbSjbeck */
103058561cbSjbeck 
104058561cbSjbeck int
105058561cbSjbeck sm_memstat_open()
106058561cbSjbeck {
107058561cbSjbeck 	kstat_named_t *kn;
108058561cbSjbeck 
109058561cbSjbeck 	kc = kstat_open();
110058561cbSjbeck 	if (kc == NULL)
111058561cbSjbeck 		return (errno != 0) ? errno : -1;
112058561cbSjbeck 	kst = kstat_lookup(kc, "unix", 0,
113058561cbSjbeck 		(name != NULL) ? name : "system_pages");
114058561cbSjbeck 	if (kst == 0)
115058561cbSjbeck 		return (errno != 0) ? errno : -2;
116058561cbSjbeck 	return 0;
117058561cbSjbeck }
118058561cbSjbeck 
119058561cbSjbeck /*
120058561cbSjbeck **  SM_MEMSTAT_CLOSE -- close memory statistics
121058561cbSjbeck **
122058561cbSjbeck **	Parameters:
123058561cbSjbeck **		none
124058561cbSjbeck **
125058561cbSjbeck **	Results:
126058561cbSjbeck **		errno as error code, 0: ok
127058561cbSjbeck */
128058561cbSjbeck 
129058561cbSjbeck int
130058561cbSjbeck sm_memstat_close()
131058561cbSjbeck {
132058561cbSjbeck 	int r;
133058561cbSjbeck 
134058561cbSjbeck 	if (kc == NULL)
135058561cbSjbeck 		return 0;
136058561cbSjbeck 	r = kstat_close(kc);
137058561cbSjbeck 	if (r != 0)
138058561cbSjbeck 		return (errno != 0) ? errno : -1;
139058561cbSjbeck 	return 0;
140058561cbSjbeck }
141058561cbSjbeck 
142058561cbSjbeck /*
143058561cbSjbeck **  SM_MEMSTAT_GET -- get memory statistics
144058561cbSjbeck **
145058561cbSjbeck **	Parameters:
146058561cbSjbeck **		resource -- resource to look up
147058561cbSjbeck **		pvalue -- (pointer to) memory statistics value (output)
148058561cbSjbeck **
149058561cbSjbeck **	Results:
150058561cbSjbeck **		0: success
151058561cbSjbeck **		!=0: error
152058561cbSjbeck */
153058561cbSjbeck 
154058561cbSjbeck int
155058561cbSjbeck sm_memstat_get(resource, pvalue)
156058561cbSjbeck 	char *resource;
157058561cbSjbeck 	long *pvalue;
158058561cbSjbeck {
159058561cbSjbeck 	int r;
160058561cbSjbeck 	kstat_named_t *kn;
161058561cbSjbeck 
162058561cbSjbeck 	if (kc == NULL || kst == NULL)
163058561cbSjbeck 		return -1;
164058561cbSjbeck 	if (kstat_read(kc, kst, NULL) == -1)
165058561cbSjbeck 		return (errno != 0) ? errno : -2;
166058561cbSjbeck 	kn = kstat_data_lookup(kst,
167058561cbSjbeck 			(resource != NULL) ? resource: "freemem");
168058561cbSjbeck 	if (kn == NULL)
169058561cbSjbeck 		return (errno != 0) ? errno : -3;
170058561cbSjbeck    	*pvalue = kn->value.ul;
171058561cbSjbeck 	return 0;
172058561cbSjbeck }
173058561cbSjbeck 
174058561cbSjbeck #elif USEPROCMEMINFO
175058561cbSjbeck 
176058561cbSjbeck /*
177058561cbSjbeck /proc/meminfo?
178058561cbSjbeck         total:    used:    free:  shared: buffers:  cached:
179058561cbSjbeck Mem:  261468160 252149760  9318400        0  3854336 109813760
180058561cbSjbeck Swap: 1052794880 62185472 990609408
181058561cbSjbeck MemTotal:       255340 kB
182058561cbSjbeck MemFree:          9100 kB
183058561cbSjbeck MemShared:           0 kB
184058561cbSjbeck Buffers:          3764 kB
185058561cbSjbeck Cached:         107240 kB
186058561cbSjbeck Active:         104340 kB
187058561cbSjbeck Inact_dirty:      4220 kB
188058561cbSjbeck Inact_clean:      2444 kB
189058561cbSjbeck Inact_target:     4092 kB
190058561cbSjbeck HighTotal:           0 kB
191058561cbSjbeck HighFree:            0 kB
192058561cbSjbeck LowTotal:       255340 kB
193058561cbSjbeck LowFree:          9100 kB
194058561cbSjbeck SwapTotal:     1028120 kB
195058561cbSjbeck SwapFree:       967392 kB
196058561cbSjbeck */
197058561cbSjbeck 
198058561cbSjbeck #include <stdio.h>
199058561cbSjbeck #include <string.h>
200058561cbSjbeck static FILE *fp;
201058561cbSjbeck 
202058561cbSjbeck /*
203058561cbSjbeck **  SM_MEMSTAT_OPEN -- open memory statistics
204058561cbSjbeck **
205058561cbSjbeck **	Parameters:
206058561cbSjbeck **		none
207058561cbSjbeck **
208058561cbSjbeck **	Results:
209058561cbSjbeck **		errno as error code, 0: ok
210058561cbSjbeck */
211058561cbSjbeck 
212058561cbSjbeck int
213058561cbSjbeck sm_memstat_open()
214058561cbSjbeck {
215058561cbSjbeck 	fp = fopen("/proc/meminfo", "r");
216058561cbSjbeck 	return (fp != NULL) ? 0 : errno;
217058561cbSjbeck }
218058561cbSjbeck 
219058561cbSjbeck /*
220058561cbSjbeck **  SM_MEMSTAT_CLOSE -- close memory statistics
221058561cbSjbeck **
222058561cbSjbeck **	Parameters:
223058561cbSjbeck **		none
224058561cbSjbeck **
225058561cbSjbeck **	Results:
226058561cbSjbeck **		errno as error code, 0: ok
227058561cbSjbeck */
228058561cbSjbeck 
229058561cbSjbeck int
230058561cbSjbeck sm_memstat_close()
231058561cbSjbeck {
232058561cbSjbeck 	if (fp != NULL)
233058561cbSjbeck 	{
234058561cbSjbeck 		fclose(fp);
235058561cbSjbeck 		fp = NULL;
236058561cbSjbeck 	}
237058561cbSjbeck 	return 0;
238058561cbSjbeck }
239058561cbSjbeck 
240058561cbSjbeck /*
241058561cbSjbeck **  SM_MEMSTAT_GET -- get memory statistics
242058561cbSjbeck **
243058561cbSjbeck **	Parameters:
244058561cbSjbeck **		resource -- resource to look up
245058561cbSjbeck **		pvalue -- (pointer to) memory statistics value (output)
246058561cbSjbeck **
247058561cbSjbeck **	Results:
248058561cbSjbeck **		0: success
249058561cbSjbeck **		!=0: error
250058561cbSjbeck */
251058561cbSjbeck 
252058561cbSjbeck int
253058561cbSjbeck sm_memstat_get(resource, pvalue)
254058561cbSjbeck 	char *resource;
255058561cbSjbeck 	long *pvalue;
256058561cbSjbeck {
257058561cbSjbeck 	int r;
258058561cbSjbeck 	size_t l;
259058561cbSjbeck 	char buf[80];
260058561cbSjbeck 
261058561cbSjbeck 	if (resource == NULL)
262058561cbSjbeck 		return EINVAL;
263058561cbSjbeck 	if (pvalue == NULL)
264058561cbSjbeck 		return EINVAL;
265058561cbSjbeck 	if (fp == NULL)
266058561cbSjbeck 		return -1;	/* try to reopen? */
267058561cbSjbeck 	rewind(fp);
268058561cbSjbeck 	l = strlen(resource);
269*4aac33d3Sjbeck 	if (l >= sizeof(buf))
270*4aac33d3Sjbeck 		return EINVAL;
271058561cbSjbeck 	while (fgets(buf, sizeof(buf), fp) != NULL)
272058561cbSjbeck 	{
273058561cbSjbeck 		if (strncmp(buf, resource, l) == 0 && buf[l] == ':')
274058561cbSjbeck 		{
275058561cbSjbeck 			r = sscanf(buf + l + 1, "%ld", pvalue);
276058561cbSjbeck 			return (r > 0) ? 0 : -1;
277058561cbSjbeck 		}
278058561cbSjbeck 	}
279058561cbSjbeck 	return 0;
280058561cbSjbeck }
281058561cbSjbeck 
282058561cbSjbeck #else /* USEPROCMEMINFO */
283058561cbSjbeck 
284058561cbSjbeck /*
285058561cbSjbeck **  SM_MEMSTAT_OPEN -- open memory statistics
286058561cbSjbeck **
287058561cbSjbeck **	Parameters:
288058561cbSjbeck **		none
289058561cbSjbeck **
290058561cbSjbeck **	Results:
291058561cbSjbeck **		errno as error code, 0: ok
292058561cbSjbeck */
293058561cbSjbeck 
294058561cbSjbeck int
295058561cbSjbeck sm_memstat_open()
296058561cbSjbeck {
297058561cbSjbeck 	return -1;
298058561cbSjbeck }
299058561cbSjbeck 
300058561cbSjbeck /*
301058561cbSjbeck **  SM_MEMSTAT_CLOSE -- close memory statistics
302058561cbSjbeck **
303058561cbSjbeck **	Parameters:
304058561cbSjbeck **		none
305058561cbSjbeck **
306058561cbSjbeck **	Results:
307058561cbSjbeck **		errno as error code, 0: ok
308058561cbSjbeck */
309058561cbSjbeck 
310058561cbSjbeck int
311058561cbSjbeck sm_memstat_close()
312058561cbSjbeck {
313058561cbSjbeck 	return 0;
314058561cbSjbeck }
315058561cbSjbeck 
316058561cbSjbeck /*
317058561cbSjbeck **  SM_MEMSTAT_GET -- get memory statistics
318058561cbSjbeck **
319058561cbSjbeck **	Parameters:
320058561cbSjbeck **		resource -- resource to look up
321058561cbSjbeck **		pvalue -- (pointer to) memory statistics value (output)
322058561cbSjbeck **
323058561cbSjbeck **	Results:
324058561cbSjbeck **		0: success
325058561cbSjbeck **		!=0: error
326058561cbSjbeck */
327058561cbSjbeck 
328058561cbSjbeck int
329058561cbSjbeck sm_memstat_get(resource, pvalue)
330058561cbSjbeck 	char *resource;
331058561cbSjbeck 	long *pvalue;
332058561cbSjbeck {
333058561cbSjbeck 	return -1;
334058561cbSjbeck }
335058561cbSjbeck 
336058561cbSjbeck #endif /* USEKSTAT */
337