memstat.c revision 157001
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> 11SM_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 19static 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 31int 32sm_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 50int 51sm_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 68int 69sm_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 90static kstat_ctl_t *kc; 91static 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 103int 104sm_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 128int 129sm_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 153int 154sm_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: 178Mem: 261468160 252149760 9318400 0 3854336 109813760 179Swap: 1052794880 62185472 990609408 180MemTotal: 255340 kB 181MemFree: 9100 kB 182MemShared: 0 kB 183Buffers: 3764 kB 184Cached: 107240 kB 185Active: 104340 kB 186Inact_dirty: 4220 kB 187Inact_clean: 2444 kB 188Inact_target: 4092 kB 189HighTotal: 0 kB 190HighFree: 0 kB 191LowTotal: 255340 kB 192LowFree: 9100 kB 193SwapTotal: 1028120 kB 194SwapFree: 967392 kB 195*/ 196 197#include <stdio.h> 198#include <string.h> 199static 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 211int 212sm_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 228int 229sm_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 251int 252sm_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 291int 292sm_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 307int 308sm_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 325int 326sm_memstat_get(resource, pvalue) 327 char *resource; 328 long *pvalue; 329{ 330 return -1; 331} 332 333#endif /* USEKSTAT */ 334