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