1058561cbSjbeck /* 2*4aac33d3Sjbeck * Copyright (c) 2005-2007 Sendmail, Inc. and its suppliers. 3058561cbSjbeck * All rights reserved. 4058561cbSjbeck * 5058561cbSjbeck * By using this file, you agree to the terms and conditions set 6058561cbSjbeck * forth in the LICENSE file which can be found at the top level of 7058561cbSjbeck * the sendmail distribution. 8058561cbSjbeck */ 9058561cbSjbeck 10058561cbSjbeck #pragma ident "%Z%%M% %I% %E% SMI" 11058561cbSjbeck 12058561cbSjbeck #include <sm/gen.h> 13*4aac33d3Sjbeck SM_RCSID("@(#)$Id: memstat.c,v 1.6 2007/03/20 23:26:12 ca Exp $") 14058561cbSjbeck 15058561cbSjbeck #include <errno.h> 16058561cbSjbeck #include <sm/misc.h> 17058561cbSjbeck 18058561cbSjbeck #if USESWAPCTL 19058561cbSjbeck #include <sys/stat.h> 20058561cbSjbeck #include <sys/swap.h> 21058561cbSjbeck 22058561cbSjbeck static long sc_page_size; 23058561cbSjbeck 24058561cbSjbeck /* 25058561cbSjbeck ** SM_MEMSTAT_OPEN -- open memory statistics 26058561cbSjbeck ** 27058561cbSjbeck ** Parameters: 28058561cbSjbeck ** none 29058561cbSjbeck ** 30058561cbSjbeck ** Results: 31058561cbSjbeck ** errno as error code, 0: ok 32058561cbSjbeck */ 33058561cbSjbeck 34058561cbSjbeck int 35058561cbSjbeck sm_memstat_open() 36058561cbSjbeck { 37058561cbSjbeck sc_page_size = sysconf(_SC_PAGE_SIZE); 38058561cbSjbeck if (sc_page_size == -1) 39058561cbSjbeck return (errno != 0) ? errno : -1; 40058561cbSjbeck return 0; 41058561cbSjbeck } 42058561cbSjbeck 43058561cbSjbeck /* 44058561cbSjbeck ** SM_MEMSTAT_CLOSE -- close memory statistics 45058561cbSjbeck ** 46058561cbSjbeck ** Parameters: 47058561cbSjbeck ** none 48058561cbSjbeck ** 49058561cbSjbeck ** Results: 50058561cbSjbeck ** errno as error code, 0: ok 51058561cbSjbeck */ 52058561cbSjbeck 53058561cbSjbeck int 54058561cbSjbeck sm_memstat_close() 55058561cbSjbeck { 56058561cbSjbeck return 0; 57058561cbSjbeck } 58058561cbSjbeck 59058561cbSjbeck /* 60058561cbSjbeck ** SM_MEMSTAT_GET -- get memory statistics 61058561cbSjbeck ** 62058561cbSjbeck ** Parameters: 63058561cbSjbeck ** resource -- resource to look up 64058561cbSjbeck ** pvalue -- (pointer to) memory statistics value (output) 65058561cbSjbeck ** 66058561cbSjbeck ** Results: 67058561cbSjbeck ** 0: success 68058561cbSjbeck ** !=0: error 69058561cbSjbeck */ 70058561cbSjbeck 71058561cbSjbeck int 72058561cbSjbeck sm_memstat_get(resource, pvalue) 73058561cbSjbeck char *resource; 74058561cbSjbeck long *pvalue; 75058561cbSjbeck { 76058561cbSjbeck int r; 77058561cbSjbeck struct anoninfo ai; 78058561cbSjbeck 79058561cbSjbeck r = swapctl(SC_AINFO, &ai); 80058561cbSjbeck if (r == -1) 81058561cbSjbeck return (errno != 0) ? errno : -1; 82058561cbSjbeck r = ai.ani_max - ai.ani_resv; 83058561cbSjbeck r *= sc_page_size >> 10; 84058561cbSjbeck *pvalue = r; 85058561cbSjbeck return 0; 86058561cbSjbeck } 87058561cbSjbeck 88058561cbSjbeck #elif USEKSTAT 89058561cbSjbeck 90058561cbSjbeck #include <kstat.h> 91058561cbSjbeck #include <sys/sysinfo.h> 92058561cbSjbeck 93058561cbSjbeck static kstat_ctl_t *kc; 94058561cbSjbeck static kstat_t *kst; 95058561cbSjbeck 96058561cbSjbeck /* 97058561cbSjbeck ** SM_MEMSTAT_OPEN -- open memory statistics 98058561cbSjbeck ** 99058561cbSjbeck ** Parameters: 100058561cbSjbeck ** none 101058561cbSjbeck ** 102058561cbSjbeck ** Results: 103058561cbSjbeck ** errno as error code, 0: ok 104058561cbSjbeck */ 105058561cbSjbeck 106058561cbSjbeck int 107058561cbSjbeck sm_memstat_open() 108058561cbSjbeck { 109058561cbSjbeck kstat_named_t *kn; 110058561cbSjbeck 111058561cbSjbeck kc = kstat_open(); 112058561cbSjbeck if (kc == NULL) 113058561cbSjbeck return (errno != 0) ? errno : -1; 114058561cbSjbeck kst = kstat_lookup(kc, "unix", 0, 115058561cbSjbeck (name != NULL) ? name : "system_pages"); 116058561cbSjbeck if (kst == 0) 117058561cbSjbeck return (errno != 0) ? errno : -2; 118058561cbSjbeck return 0; 119058561cbSjbeck } 120058561cbSjbeck 121058561cbSjbeck /* 122058561cbSjbeck ** SM_MEMSTAT_CLOSE -- close memory statistics 123058561cbSjbeck ** 124058561cbSjbeck ** Parameters: 125058561cbSjbeck ** none 126058561cbSjbeck ** 127058561cbSjbeck ** Results: 128058561cbSjbeck ** errno as error code, 0: ok 129058561cbSjbeck */ 130058561cbSjbeck 131058561cbSjbeck int 132058561cbSjbeck sm_memstat_close() 133058561cbSjbeck { 134058561cbSjbeck int r; 135058561cbSjbeck 136058561cbSjbeck if (kc == NULL) 137058561cbSjbeck return 0; 138058561cbSjbeck r = kstat_close(kc); 139058561cbSjbeck if (r != 0) 140058561cbSjbeck return (errno != 0) ? errno : -1; 141058561cbSjbeck return 0; 142058561cbSjbeck } 143058561cbSjbeck 144058561cbSjbeck /* 145058561cbSjbeck ** SM_MEMSTAT_GET -- get memory statistics 146058561cbSjbeck ** 147058561cbSjbeck ** Parameters: 148058561cbSjbeck ** resource -- resource to look up 149058561cbSjbeck ** pvalue -- (pointer to) memory statistics value (output) 150058561cbSjbeck ** 151058561cbSjbeck ** Results: 152058561cbSjbeck ** 0: success 153058561cbSjbeck ** !=0: error 154058561cbSjbeck */ 155058561cbSjbeck 156058561cbSjbeck int 157058561cbSjbeck sm_memstat_get(resource, pvalue) 158058561cbSjbeck char *resource; 159058561cbSjbeck long *pvalue; 160058561cbSjbeck { 161058561cbSjbeck int r; 162058561cbSjbeck kstat_named_t *kn; 163058561cbSjbeck 164058561cbSjbeck if (kc == NULL || kst == NULL) 165058561cbSjbeck return -1; 166058561cbSjbeck if (kstat_read(kc, kst, NULL) == -1) 167058561cbSjbeck return (errno != 0) ? errno : -2; 168058561cbSjbeck kn = kstat_data_lookup(kst, 169058561cbSjbeck (resource != NULL) ? resource: "freemem"); 170058561cbSjbeck if (kn == NULL) 171058561cbSjbeck return (errno != 0) ? errno : -3; 172058561cbSjbeck *pvalue = kn->value.ul; 173058561cbSjbeck return 0; 174058561cbSjbeck } 175058561cbSjbeck 176058561cbSjbeck #elif USEPROCMEMINFO 177058561cbSjbeck 178058561cbSjbeck /* 179058561cbSjbeck /proc/meminfo? 180058561cbSjbeck total: used: free: shared: buffers: cached: 181058561cbSjbeck Mem: 261468160 252149760 9318400 0 3854336 109813760 182058561cbSjbeck Swap: 1052794880 62185472 990609408 183058561cbSjbeck MemTotal: 255340 kB 184058561cbSjbeck MemFree: 9100 kB 185058561cbSjbeck MemShared: 0 kB 186058561cbSjbeck Buffers: 3764 kB 187058561cbSjbeck Cached: 107240 kB 188058561cbSjbeck Active: 104340 kB 189058561cbSjbeck Inact_dirty: 4220 kB 190058561cbSjbeck Inact_clean: 2444 kB 191058561cbSjbeck Inact_target: 4092 kB 192058561cbSjbeck HighTotal: 0 kB 193058561cbSjbeck HighFree: 0 kB 194058561cbSjbeck LowTotal: 255340 kB 195058561cbSjbeck LowFree: 9100 kB 196058561cbSjbeck SwapTotal: 1028120 kB 197058561cbSjbeck SwapFree: 967392 kB 198058561cbSjbeck */ 199058561cbSjbeck 200058561cbSjbeck #include <stdio.h> 201058561cbSjbeck #include <string.h> 202058561cbSjbeck static FILE *fp; 203058561cbSjbeck 204058561cbSjbeck /* 205058561cbSjbeck ** SM_MEMSTAT_OPEN -- open memory statistics 206058561cbSjbeck ** 207058561cbSjbeck ** Parameters: 208058561cbSjbeck ** none 209058561cbSjbeck ** 210058561cbSjbeck ** Results: 211058561cbSjbeck ** errno as error code, 0: ok 212058561cbSjbeck */ 213058561cbSjbeck 214058561cbSjbeck int 215058561cbSjbeck sm_memstat_open() 216058561cbSjbeck { 217058561cbSjbeck fp = fopen("/proc/meminfo", "r"); 218058561cbSjbeck return (fp != NULL) ? 0 : errno; 219058561cbSjbeck } 220058561cbSjbeck 221058561cbSjbeck /* 222058561cbSjbeck ** SM_MEMSTAT_CLOSE -- close memory statistics 223058561cbSjbeck ** 224058561cbSjbeck ** Parameters: 225058561cbSjbeck ** none 226058561cbSjbeck ** 227058561cbSjbeck ** Results: 228058561cbSjbeck ** errno as error code, 0: ok 229058561cbSjbeck */ 230058561cbSjbeck 231058561cbSjbeck int 232058561cbSjbeck sm_memstat_close() 233058561cbSjbeck { 234058561cbSjbeck if (fp != NULL) 235058561cbSjbeck { 236058561cbSjbeck fclose(fp); 237058561cbSjbeck fp = NULL; 238058561cbSjbeck } 239058561cbSjbeck return 0; 240058561cbSjbeck } 241058561cbSjbeck 242058561cbSjbeck /* 243058561cbSjbeck ** SM_MEMSTAT_GET -- get memory statistics 244058561cbSjbeck ** 245058561cbSjbeck ** Parameters: 246058561cbSjbeck ** resource -- resource to look up 247058561cbSjbeck ** pvalue -- (pointer to) memory statistics value (output) 248058561cbSjbeck ** 249058561cbSjbeck ** Results: 250058561cbSjbeck ** 0: success 251058561cbSjbeck ** !=0: error 252058561cbSjbeck */ 253058561cbSjbeck 254058561cbSjbeck int 255058561cbSjbeck sm_memstat_get(resource, pvalue) 256058561cbSjbeck char *resource; 257058561cbSjbeck long *pvalue; 258058561cbSjbeck { 259058561cbSjbeck int r; 260058561cbSjbeck size_t l; 261058561cbSjbeck char buf[80]; 262058561cbSjbeck 263058561cbSjbeck if (resource == NULL) 264058561cbSjbeck return EINVAL; 265058561cbSjbeck if (pvalue == NULL) 266058561cbSjbeck return EINVAL; 267058561cbSjbeck if (fp == NULL) 268058561cbSjbeck return -1; /* try to reopen? */ 269058561cbSjbeck rewind(fp); 270058561cbSjbeck l = strlen(resource); 271*4aac33d3Sjbeck if (l >= sizeof(buf)) 272*4aac33d3Sjbeck return EINVAL; 273058561cbSjbeck while (fgets(buf, sizeof(buf), fp) != NULL) 274058561cbSjbeck { 275058561cbSjbeck if (strncmp(buf, resource, l) == 0 && buf[l] == ':') 276058561cbSjbeck { 277058561cbSjbeck r = sscanf(buf + l + 1, "%ld", pvalue); 278058561cbSjbeck return (r > 0) ? 0 : -1; 279058561cbSjbeck } 280058561cbSjbeck } 281058561cbSjbeck return 0; 282058561cbSjbeck } 283058561cbSjbeck 284058561cbSjbeck #else /* USEPROCMEMINFO */ 285058561cbSjbeck 286058561cbSjbeck /* 287058561cbSjbeck ** SM_MEMSTAT_OPEN -- open memory statistics 288058561cbSjbeck ** 289058561cbSjbeck ** Parameters: 290058561cbSjbeck ** none 291058561cbSjbeck ** 292058561cbSjbeck ** Results: 293058561cbSjbeck ** errno as error code, 0: ok 294058561cbSjbeck */ 295058561cbSjbeck 296058561cbSjbeck int 297058561cbSjbeck sm_memstat_open() 298058561cbSjbeck { 299058561cbSjbeck return -1; 300058561cbSjbeck } 301058561cbSjbeck 302058561cbSjbeck /* 303058561cbSjbeck ** SM_MEMSTAT_CLOSE -- close memory statistics 304058561cbSjbeck ** 305058561cbSjbeck ** Parameters: 306058561cbSjbeck ** none 307058561cbSjbeck ** 308058561cbSjbeck ** Results: 309058561cbSjbeck ** errno as error code, 0: ok 310058561cbSjbeck */ 311058561cbSjbeck 312058561cbSjbeck int 313058561cbSjbeck sm_memstat_close() 314058561cbSjbeck { 315058561cbSjbeck return 0; 316058561cbSjbeck } 317058561cbSjbeck 318058561cbSjbeck /* 319058561cbSjbeck ** SM_MEMSTAT_GET -- get memory statistics 320058561cbSjbeck ** 321058561cbSjbeck ** Parameters: 322058561cbSjbeck ** resource -- resource to look up 323058561cbSjbeck ** pvalue -- (pointer to) memory statistics value (output) 324058561cbSjbeck ** 325058561cbSjbeck ** Results: 326058561cbSjbeck ** 0: success 327058561cbSjbeck ** !=0: error 328058561cbSjbeck */ 329058561cbSjbeck 330058561cbSjbeck int 331058561cbSjbeck sm_memstat_get(resource, pvalue) 332058561cbSjbeck char *resource; 333058561cbSjbeck long *pvalue; 334058561cbSjbeck { 335058561cbSjbeck return -1; 336058561cbSjbeck } 337058561cbSjbeck 338058561cbSjbeck #endif /* USEKSTAT */ 339