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 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 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