/* KSysGuard, the KDE System Guard Copyright (c) 2010-2011 David Naylor Copyright (c) 1999-2000 Hans Petter Bieker Copyright (c) 1999 Chris Schlaeger This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include #include #include #include #include "Command.h" #include "Memory.h" #include "ksysguardd.h" #define MEM_ACTIVE 0 #define MEM_INACTIVE 1 #define MEM_WIRED 2 #define MEM_CACHED 3 #define MEM_BUFFERED 4 #define MEM_FREE 5 #define MEM_TOTAL 6 static size_t memory_stats[7]; #define SWAP_IN 0 #define SWAP_OUT 1 #define SWAP_USED 2 #define SWAP_FREE 3 #define SWAP_TOTAL 4 static size_t swap_stats[5]; static size_t swap_old[2]; static int pagesize; void kvm_getswapinfo_sysctl(size_t *ksw_used, size_t *ksw_total); void initMemory(struct SensorModul* sm) { char *nlistf = NULL; char *memf = NULL; char buf[_POSIX2_LINE_MAX]; pagesize = getpagesize(); registerMonitor("mem/physical/active", "integer", printMActive, printMActiveInfo, sm); registerMonitor("mem/physical/inactive", "integer", printMInactive, printMInactiveInfo, sm); registerMonitor("mem/physical/application", "integer", printMApplication, printMApplicationInfo, sm); registerMonitor("mem/physical/wired", "integer", printMWired, printMWiredInfo, sm); registerMonitor("mem/physical/cached", "integer", printMCached, printMCachedInfo, sm); registerMonitor("mem/physical/buf", "integer", printMBuffers, printMBuffersInfo, sm); registerMonitor("mem/physical/free", "integer", printMFree, printMFreeInfo, sm); registerMonitor("mem/physical/used", "integer", printMUsed, printMUsedInfo, sm); registerMonitor("mem/swap/free", "integer", printSwapFree, printSwapFreeInfo, sm); registerMonitor("mem/swap/used", "integer", printSwapUsed, printSwapUsedInfo, sm); registerMonitor("mem/swap/pageIn", "integer", printSwapIn, printSwapInInfo, sm); registerMonitor("mem/swap/pageOut", "integer", printSwapOut, printSwapOutInfo, sm); registerLegacyMonitor("cpu/pageIn", "float", printSwapIn, printSwapInInfo, sm); registerLegacyMonitor("cpu/pageOut", "float", printSwapOut, printSwapOutInfo, sm); swap_old[SWAP_IN] = -1; swap_old[SWAP_OUT] = -1; updateMemory(); } void exitMemory(void) { removeMonitor("mem/physical/active"); removeMonitor("mem/physical/inactive"); removeMonitor("mem/physical/application"); removeMonitor("mem/physical/wired"); removeMonitor("mem/physical/cached"); removeMonitor("mem/physical/buf"); removeMonitor("mem/physical/free"); removeMonitor("mem/physical/used"); removeMonitor("mem/swap/free"); removeMonitor("mem/swap/used"); removeMonitor("mem/swap/pageIn"); removeMonitor("mem/swap/pageOut"); removeMonitor("cpu/pageIn"); removeMonitor("cpu/pageOut"); } int updateMemory(void) { size_t len, ksw_used, ksw_total; int swapin, swapout; #define CONVERT(v) ((quad_t)(v) * pagesize / 1024) #define GETSYSCTL(mib, var) \ len = sizeof(var); \ sysctlbyname(mib, &var, &len, NULL, 0); #define GETPAGESYSCTL(mib, var) \ GETSYSCTL(mib, var) \ var = CONVERT(var); #define GETMEMSYSCTL(mib, var) \ GETSYSCTL(mib, var) \ var /= 1024; /* * Memory */ GETPAGESYSCTL("vm.stats.vm.v_active_count", memory_stats[MEM_ACTIVE]) GETPAGESYSCTL("vm.stats.vm.v_inactive_count", memory_stats[MEM_INACTIVE]) GETPAGESYSCTL("vm.stats.vm.v_wire_count", memory_stats[MEM_WIRED]) GETPAGESYSCTL("vm.stats.vm.v_cache_count", memory_stats[MEM_CACHED]) GETPAGESYSCTL("vm.stats.vm.v_free_count", memory_stats[MEM_FREE]) GETMEMSYSCTL("vfs.bufspace", memory_stats[MEM_BUFFERED]) GETMEMSYSCTL("hw.physmem", memory_stats[MEM_TOTAL]) /* * Swap */ GETSYSCTL("vm.stats.vm.v_swappgsin", swapin); GETSYSCTL("vm.stats.vm.v_swappgsout", swapout); if (swap_old[SWAP_IN] < 0) { swap_stats[SWAP_IN] = 0; swap_stats[SWAP_OUT] = 0; } else { swap_stats[SWAP_IN] = CONVERT(swapin - swap_old[SWAP_IN]); swap_stats[SWAP_OUT] = CONVERT(swapout - swap_old[SWAP_OUT]); } /* only for changes */ if (swap_stats[SWAP_IN] > 0 || swap_stats[SWAP_OUT] > 0 || swap_old[SWAP_IN] < 0) { kvm_getswapinfo_sysctl(&ksw_used, &ksw_total); swap_stats[SWAP_TOTAL] = CONVERT(ksw_total); swap_stats[SWAP_USED] = CONVERT(ksw_used); swap_stats[SWAP_FREE] = CONVERT(ksw_total - ksw_used); } swap_old[SWAP_IN] = swapin; swap_old[SWAP_OUT] = swapout; return 0; #undef CONVERT #undef GETSYSCTL #undef GETPAGESYSCTL #undef GETMEMSYSCTL } void printMActive(const char* cmd) { fprintf(CurrentClient, "%lu\n", memory_stats[MEM_ACTIVE]); } void printMActiveInfo(const char* cmd) { fprintf(CurrentClient, "Active Memory\t0\t%lu\tKB\n", memory_stats[MEM_TOTAL]); } void printMInactive(const char* cmd) { fprintf(CurrentClient, "%lu\n", memory_stats[MEM_INACTIVE]); } void printMInactiveInfo(const char* cmd) { fprintf(CurrentClient, "Inactive Memory\t0\t%lu\tKB\n", memory_stats[MEM_TOTAL]); } void printMApplication(const char* cmd) { fprintf(CurrentClient, "%lu\n", memory_stats[MEM_ACTIVE] + memory_stats[MEM_INACTIVE]); } void printMApplicationInfo(const char* cmd) { fprintf(CurrentClient, "Application (Active and Inactive) Memory\t0\t%ld\tKB\n", memory_stats[MEM_TOTAL]); } void printMWired(const char* cmd) { fprintf(CurrentClient, "%lu\n", memory_stats[MEM_WIRED]); } void printMWiredInfo(const char* cmd) { fprintf(CurrentClient, "Wired Memory\t0\t%lu\tKB\n", memory_stats[MEM_TOTAL]); } void printMCached(const char* cmd) { fprintf(CurrentClient, "%lu\n", memory_stats[MEM_CACHED]); } void printMCachedInfo(const char* cmd) { fprintf(CurrentClient, "Cached Memory\t0\t%lu\tKB\n", memory_stats[MEM_TOTAL]); } void printMBuffers(const char* cmd) { fprintf(CurrentClient, "%lu\n", memory_stats[MEM_BUFFERED]); } void printMBuffersInfo(const char* cmd) { fprintf(CurrentClient, "Buffer Memory\t0\t%lu\tKB\n", memory_stats[MEM_TOTAL]); } void printMFree(const char* cmd) { fprintf(CurrentClient, "%lu\n", memory_stats[MEM_FREE]); } void printMFreeInfo(const char* cmd) { fprintf(CurrentClient, "Free Memory\t0\t%lu\tKB\n", memory_stats[MEM_TOTAL]); } void printMUsed(const char* cmd) { fprintf(CurrentClient, "%lu\n", memory_stats[MEM_TOTAL] - memory_stats[MEM_FREE]); } void printMUsedInfo(const char* cmd) { fprintf(CurrentClient, "Used Memory\t0\t%lu\tKB\n", memory_stats[MEM_TOTAL]); } void printSwapUsed(const char* cmd) { fprintf(CurrentClient, "%lu\n", swap_stats[SWAP_USED]); } void printSwapUsedInfo(const char* cmd) { fprintf(CurrentClient, "Used Swap Memory\t0\t%lu\tKB\n", swap_stats[SWAP_TOTAL]); } void printSwapFree(const char* cmd) { fprintf(CurrentClient, "%lu\n", swap_stats[SWAP_FREE]); } void printSwapFreeInfo(const char* cmd) { fprintf(CurrentClient, "Free Swap Memory\t0\t%lu\tKB\n", swap_stats[SWAP_TOTAL]); } void printSwapIn(const char* cmd) { fprintf(CurrentClient, "%lu\n", swap_stats[SWAP_IN]); } void printSwapInInfo(const char* cmd) { fprintf(CurrentClient, "Swapped In Memory\t0\t0\tKB/s\n"); } void printSwapOut(const char* cmd) { fprintf(CurrentClient, "%lu\n", swap_stats[SWAP_OUT]); } void printSwapOutInfo(const char* cmd) { fprintf(CurrentClient, "Swapped Out Memory\t0\t0\tKB/s\n"); } /* Adapted from src/lib/libkvm/kvm_getswapinfo.c */ #define SWI_MAXMIB 3 void kvm_getswapinfo_sysctl(size_t *ksw_used, size_t *ksw_total) { int unswdev; size_t len; static int soid[SWI_MAXMIB], dmmax = -1; static size_t mibi = -1; struct xswdev xsd; *ksw_used = 0; *ksw_total = 0; if (dmmax == -1) { len = sizeof(dmmax); if (sysctlbyname("vm.dmmax", &dmmax, &len, NULL, 0) == -1 || len != sizeof(dmmax)) { dmmax = -1; return; } } if (mibi == -1) { mibi = SWI_MAXMIB - 1; if (sysctlnametomib("vm.swap_info", soid, &mibi) == -1) { mibi = -1; return; } } for (unswdev = 0;; unswdev++) { soid[mibi] = unswdev; len = sizeof(xsd); if (sysctl(soid, mibi + 1, &xsd, &len, NULL, 0) == -1 || len != sizeof(xsd)) { return; } *ksw_used += xsd.xsw_used; *ksw_total += xsd.xsw_nblks - dmmax; } }