1 /* 2 * Copyright (c) 2005, 2006 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.5 2006/06/28 23:57:59 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 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 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 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 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