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