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 #include <sm/gen.h>
11 SM_RCSID("@(#)$Id: memstat.c,v 1.6 2007/03/20 23:26:12 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 
20 static 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 
32 int
sm_memstat_open()33 sm_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 
51 int
sm_memstat_close()52 sm_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 
69 int
sm_memstat_get(resource,pvalue)70 sm_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 
91 static kstat_ctl_t *kc;
92 static 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 
104 int
105 sm_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 
129 int
130 sm_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 
154 int
155 sm_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:
179 Mem:  261468160 252149760  9318400        0  3854336 109813760
180 Swap: 1052794880 62185472 990609408
181 MemTotal:       255340 kB
182 MemFree:          9100 kB
183 MemShared:           0 kB
184 Buffers:          3764 kB
185 Cached:         107240 kB
186 Active:         104340 kB
187 Inact_dirty:      4220 kB
188 Inact_clean:      2444 kB
189 Inact_target:     4092 kB
190 HighTotal:           0 kB
191 HighFree:            0 kB
192 LowTotal:       255340 kB
193 LowFree:          9100 kB
194 SwapTotal:     1028120 kB
195 SwapFree:       967392 kB
196 */
197 
198 #include <stdio.h>
199 #include <string.h>
200 static 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 
212 int
213 sm_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 
229 int
230 sm_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 
252 int
253 sm_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 
294 int
295 sm_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 
310 int
311 sm_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 
328 int
329 sm_memstat_get(resource, pvalue)
330 	char *resource;
331 	long *pvalue;
332 {
333 	return -1;
334 }
335 
336 #endif /* USEKSTAT */
337