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