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