1 /* 2 * Copyright (c) 2005 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.4 2005/12/10 00:38:48 ca Exp $") 12 13 #include <errno.h> 14 15 #if USESWAPCTL 16 #include <sys/stat.h> 17 #include <sys/swap.h> 18 19 static long sc_page_size; 20 21 /* 22 ** SM_MEMSTAT_OPEN -- open memory statistics 23 ** 24 ** Parameters: 25 ** none 26 ** 27 ** Results: 28 ** errno as error code, 0: ok 29 */ 30 31 int 32 sm_memstat_open() 33 { 34 sc_page_size = sysconf(_SC_PAGE_SIZE); 35 if (sc_page_size == -1) 36 return (errno != 0) ? errno : -1; 37 return 0; 38 } 39 40 /* 41 ** SM_MEMSTAT_CLOSE -- close memory statistics 42 ** 43 ** Parameters: 44 ** none 45 ** 46 ** Results: 47 ** errno as error code, 0: ok 48 */ 49 50 int 51 sm_memstat_close() 52 { 53 return 0; 54 } 55 56 /* 57 ** SM_MEMSTAT_GET -- get memory statistics 58 ** 59 ** Parameters: 60 ** resource -- resource to look up 61 ** pvalue -- (pointer to) memory statistics value (output) 62 ** 63 ** Results: 64 ** 0: success 65 ** !=0: error 66 */ 67 68 int 69 sm_memstat_get(resource, pvalue) 70 char *resource; 71 long *pvalue; 72 { 73 int r; 74 struct anoninfo ai; 75 76 r = swapctl(SC_AINFO, &ai); 77 if (r == -1) 78 return (errno != 0) ? errno : -1; 79 r = ai.ani_max - ai.ani_resv; 80 r *= sc_page_size >> 10; 81 *pvalue = r; 82 return 0; 83 } 84 85 #elif USEKSTAT 86 87 #include <kstat.h> 88 #include <sys/sysinfo.h> 89 90 static kstat_ctl_t *kc; 91 static kstat_t *kst; 92 93 /* 94 ** SM_MEMSTAT_OPEN -- open memory statistics 95 ** 96 ** Parameters: 97 ** none 98 ** 99 ** Results: 100 ** errno as error code, 0: ok 101 */ 102 103 int 104 sm_memstat_open() 105 { 106 kstat_named_t *kn; 107 108 kc = kstat_open(); 109 if (kc == NULL) 110 return (errno != 0) ? errno : -1; 111 kst = kstat_lookup(kc, "unix", 0, 112 (name != NULL) ? name : "system_pages"); 113 if (kst == 0) 114 return (errno != 0) ? errno : -2; 115 return 0; 116 } 117 118 /* 119 ** SM_MEMSTAT_CLOSE -- close memory statistics 120 ** 121 ** Parameters: 122 ** none 123 ** 124 ** Results: 125 ** errno as error code, 0: ok 126 */ 127 128 int 129 sm_memstat_close() 130 { 131 int r; 132 133 if (kc == NULL) 134 return 0; 135 r = kstat_close(kc); 136 if (r != 0) 137 return (errno != 0) ? errno : -1; 138 return 0; 139 } 140 141 /* 142 ** SM_MEMSTAT_GET -- get memory statistics 143 ** 144 ** Parameters: 145 ** resource -- resource to look up 146 ** pvalue -- (pointer to) memory statistics value (output) 147 ** 148 ** Results: 149 ** 0: success 150 ** !=0: error 151 */ 152 153 int 154 sm_memstat_get(resource, pvalue) 155 char *resource; 156 long *pvalue; 157 { 158 int r; 159 kstat_named_t *kn; 160 161 if (kc == NULL || kst == NULL) 162 return -1; 163 if (kstat_read(kc, kst, NULL) == -1) 164 return (errno != 0) ? errno : -2; 165 kn = kstat_data_lookup(kst, 166 (resource != NULL) ? resource: "freemem"); 167 if (kn == NULL) 168 return (errno != 0) ? errno : -3; 169 *pvalue = kn->value.ul; 170 return 0; 171 } 172 173 #elif USEPROCMEMINFO 174 175 /* 176 /proc/meminfo? 177 total: used: free: shared: buffers: cached: 178 Mem: 261468160 252149760 9318400 0 3854336 109813760 179 Swap: 1052794880 62185472 990609408 180 MemTotal: 255340 kB 181 MemFree: 9100 kB 182 MemShared: 0 kB 183 Buffers: 3764 kB 184 Cached: 107240 kB 185 Active: 104340 kB 186 Inact_dirty: 4220 kB 187 Inact_clean: 2444 kB 188 Inact_target: 4092 kB 189 HighTotal: 0 kB 190 HighFree: 0 kB 191 LowTotal: 255340 kB 192 LowFree: 9100 kB 193 SwapTotal: 1028120 kB 194 SwapFree: 967392 kB 195 */ 196 197 #include <stdio.h> 198 #include <string.h> 199 static FILE *fp; 200 201 /* 202 ** SM_MEMSTAT_OPEN -- open memory statistics 203 ** 204 ** Parameters: 205 ** none 206 ** 207 ** Results: 208 ** errno as error code, 0: ok 209 */ 210 211 int 212 sm_memstat_open() 213 { 214 fp = fopen("/proc/meminfo", "r"); 215 return (fp != NULL) ? 0 : errno; 216 } 217 218 /* 219 ** SM_MEMSTAT_CLOSE -- close memory statistics 220 ** 221 ** Parameters: 222 ** none 223 ** 224 ** Results: 225 ** errno as error code, 0: ok 226 */ 227 228 int 229 sm_memstat_close() 230 { 231 if (fp != NULL) 232 { 233 fclose(fp); 234 fp = NULL; 235 } 236 return 0; 237 } 238 239 /* 240 ** SM_MEMSTAT_GET -- get memory statistics 241 ** 242 ** Parameters: 243 ** resource -- resource to look up 244 ** pvalue -- (pointer to) memory statistics value (output) 245 ** 246 ** Results: 247 ** 0: success 248 ** !=0: error 249 */ 250 251 int 252 sm_memstat_get(resource, pvalue) 253 char *resource; 254 long *pvalue; 255 { 256 int r; 257 size_t l; 258 char buf[80]; 259 260 if (resource == NULL) 261 return EINVAL; 262 if (pvalue == NULL) 263 return EINVAL; 264 if (fp == NULL) 265 return -1; /* try to reopen? */ 266 rewind(fp); 267 l = strlen(resource); 268 while (fgets(buf, sizeof(buf), fp) != NULL) 269 { 270 if (strncmp(buf, resource, l) == 0 && buf[l] == ':') 271 { 272 r = sscanf(buf + l + 1, "%ld", pvalue); 273 return (r > 0) ? 0 : -1; 274 } 275 } 276 return 0; 277 } 278 279 #else /* USEPROCMEMINFO */ 280 281 /* 282 ** SM_MEMSTAT_OPEN -- open memory statistics 283 ** 284 ** Parameters: 285 ** none 286 ** 287 ** Results: 288 ** errno as error code, 0: ok 289 */ 290 291 int 292 sm_memstat_open() 293 { 294 return -1; 295 } 296 297 /* 298 ** SM_MEMSTAT_CLOSE -- close memory statistics 299 ** 300 ** Parameters: 301 ** none 302 ** 303 ** Results: 304 ** errno as error code, 0: ok 305 */ 306 307 int 308 sm_memstat_close() 309 { 310 return 0; 311 } 312 313 /* 314 ** SM_MEMSTAT_GET -- get memory statistics 315 ** 316 ** Parameters: 317 ** resource -- resource to look up 318 ** pvalue -- (pointer to) memory statistics value (output) 319 ** 320 ** Results: 321 ** 0: success 322 ** !=0: error 323 */ 324 325 int 326 sm_memstat_get(resource, pvalue) 327 char *resource; 328 long *pvalue; 329 { 330 return -1; 331 } 332 333 #endif /* USEKSTAT */ 334