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