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