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> 13SM_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 22static 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 34int 35sm_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 53int 54sm_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 71int 72sm_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 93static kstat_ctl_t *kc; 94static 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 106int 107sm_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 131int 132sm_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 156int 157sm_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: 181Mem: 261468160 252149760 9318400 0 3854336 109813760 182Swap: 1052794880 62185472 990609408 183MemTotal: 255340 kB 184MemFree: 9100 kB 185MemShared: 0 kB 186Buffers: 3764 kB 187Cached: 107240 kB 188Active: 104340 kB 189Inact_dirty: 4220 kB 190Inact_clean: 2444 kB 191Inact_target: 4092 kB 192HighTotal: 0 kB 193HighFree: 0 kB 194LowTotal: 255340 kB 195LowFree: 9100 kB 196SwapTotal: 1028120 kB 197SwapFree: 967392 kB 198*/ 199 200#include <stdio.h> 201#include <string.h> 202static 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 214int 215sm_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 231int 232sm_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 254int 255sm_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 296int 297sm_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 312int 313sm_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 330int 331sm_memstat_get(resource, pvalue) 332 char *resource; 333 long *pvalue; 334{ 335 return -1; 336} 337 338#endif /* USEKSTAT */ 339