/* * Copyright (c) 2005-2007 Sendmail, Inc. and its suppliers. * All rights reserved. * * By using this file, you agree to the terms and conditions set * forth in the LICENSE file which can be found at the top level of * the sendmail distribution. */ #include SM_RCSID("@(#)$Id: memstat.c,v 1.6 2007/03/20 23:26:12 ca Exp $") #include #include #if USESWAPCTL #include #include static long sc_page_size; /* ** SM_MEMSTAT_OPEN -- open memory statistics ** ** Parameters: ** none ** ** Results: ** errno as error code, 0: ok */ int sm_memstat_open() { sc_page_size = sysconf(_SC_PAGE_SIZE); if (sc_page_size == -1) return (errno != 0) ? errno : -1; return 0; } /* ** SM_MEMSTAT_CLOSE -- close memory statistics ** ** Parameters: ** none ** ** Results: ** errno as error code, 0: ok */ int sm_memstat_close() { return 0; } /* ** SM_MEMSTAT_GET -- get memory statistics ** ** Parameters: ** resource -- resource to look up ** pvalue -- (pointer to) memory statistics value (output) ** ** Results: ** 0: success ** !=0: error */ int sm_memstat_get(resource, pvalue) char *resource; long *pvalue; { int r; struct anoninfo ai; r = swapctl(SC_AINFO, &ai); if (r == -1) return (errno != 0) ? errno : -1; r = ai.ani_max - ai.ani_resv; r *= sc_page_size >> 10; *pvalue = r; return 0; } #elif USEKSTAT #include #include static kstat_ctl_t *kc; static kstat_t *kst; /* ** SM_MEMSTAT_OPEN -- open memory statistics ** ** Parameters: ** none ** ** Results: ** errno as error code, 0: ok */ int sm_memstat_open() { kstat_named_t *kn; kc = kstat_open(); if (kc == NULL) return (errno != 0) ? errno : -1; kst = kstat_lookup(kc, "unix", 0, (name != NULL) ? name : "system_pages"); if (kst == 0) return (errno != 0) ? errno : -2; return 0; } /* ** SM_MEMSTAT_CLOSE -- close memory statistics ** ** Parameters: ** none ** ** Results: ** errno as error code, 0: ok */ int sm_memstat_close() { int r; if (kc == NULL) return 0; r = kstat_close(kc); if (r != 0) return (errno != 0) ? errno : -1; return 0; } /* ** SM_MEMSTAT_GET -- get memory statistics ** ** Parameters: ** resource -- resource to look up ** pvalue -- (pointer to) memory statistics value (output) ** ** Results: ** 0: success ** !=0: error */ int sm_memstat_get(resource, pvalue) char *resource; long *pvalue; { int r; kstat_named_t *kn; if (kc == NULL || kst == NULL) return -1; if (kstat_read(kc, kst, NULL) == -1) return (errno != 0) ? errno : -2; kn = kstat_data_lookup(kst, (resource != NULL) ? resource: "freemem"); if (kn == NULL) return (errno != 0) ? errno : -3; *pvalue = kn->value.ul; return 0; } #elif USEPROCMEMINFO /* /proc/meminfo? total: used: free: shared: buffers: cached: Mem: 261468160 252149760 9318400 0 3854336 109813760 Swap: 1052794880 62185472 990609408 MemTotal: 255340 kB MemFree: 9100 kB MemShared: 0 kB Buffers: 3764 kB Cached: 107240 kB Active: 104340 kB Inact_dirty: 4220 kB Inact_clean: 2444 kB Inact_target: 4092 kB HighTotal: 0 kB HighFree: 0 kB LowTotal: 255340 kB LowFree: 9100 kB SwapTotal: 1028120 kB SwapFree: 967392 kB */ #include #include static FILE *fp; /* ** SM_MEMSTAT_OPEN -- open memory statistics ** ** Parameters: ** none ** ** Results: ** errno as error code, 0: ok */ int sm_memstat_open() { fp = fopen("/proc/meminfo", "r"); return (fp != NULL) ? 0 : errno; } /* ** SM_MEMSTAT_CLOSE -- close memory statistics ** ** Parameters: ** none ** ** Results: ** errno as error code, 0: ok */ int sm_memstat_close() { if (fp != NULL) { fclose(fp); fp = NULL; } return 0; } /* ** SM_MEMSTAT_GET -- get memory statistics ** ** Parameters: ** resource -- resource to look up ** pvalue -- (pointer to) memory statistics value (output) ** ** Results: ** 0: success ** !=0: error */ int sm_memstat_get(resource, pvalue) char *resource; long *pvalue; { int r; size_t l; char buf[80]; if (resource == NULL) return EINVAL; if (pvalue == NULL) return EINVAL; if (fp == NULL) return -1; /* try to reopen? */ rewind(fp); l = strlen(resource); if (l >= sizeof(buf)) return EINVAL; while (fgets(buf, sizeof(buf), fp) != NULL) { if (strncmp(buf, resource, l) == 0 && buf[l] == ':') { r = sscanf(buf + l + 1, "%ld", pvalue); return (r > 0) ? 0 : -1; } } return 0; } #else /* USEPROCMEMINFO */ /* ** SM_MEMSTAT_OPEN -- open memory statistics ** ** Parameters: ** none ** ** Results: ** errno as error code, 0: ok */ int sm_memstat_open() { return -1; } /* ** SM_MEMSTAT_CLOSE -- close memory statistics ** ** Parameters: ** none ** ** Results: ** errno as error code, 0: ok */ int sm_memstat_close() { return 0; } /* ** SM_MEMSTAT_GET -- get memory statistics ** ** Parameters: ** resource -- resource to look up ** pvalue -- (pointer to) memory statistics value (output) ** ** Results: ** 0: success ** !=0: error */ int sm_memstat_get(resource, pvalue) char *resource; long *pvalue; { return -1; } #endif /* USEKSTAT */