diff --git a/CRT.c b/CRT.c index 5f6c2af9..35b285f7 100644 --- a/CRT.c +++ b/CRT.c @@ -131,6 +131,13 @@ typedef enum ColorElements_ { PRESSURE_STALL_TEN, PRESSURE_STALL_SIXTY, PRESSURE_STALL_THREEHUNDRED, + ZFS_MFU, + ZFS_MRU, + ZFS_ANON, + ZFS_HEADER, + ZFS_OTHER, + ZFS_COMPRESSED, + ZFS_RATIO, LAST_COLORELEMENT } ColorElements; @@ -238,6 +245,13 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = { [PRESSURE_STALL_THREEHUNDRED] = ColorPair(Cyan,Black), [PRESSURE_STALL_SIXTY] = A_BOLD | ColorPair(Cyan,Black), [PRESSURE_STALL_TEN] = A_BOLD | ColorPair(White,Black), + [ZFS_MFU] = ColorPair(Blue,Black), + [ZFS_MRU] = ColorPair(Yellow,Black), + [ZFS_ANON] = ColorPair(Magenta,Black), + [ZFS_HEADER] = ColorPair(Cyan,Black), + [ZFS_OTHER] = ColorPair(Magenta,Black), + [ZFS_COMPRESSED] = ColorPair(Blue,Black), + [ZFS_RATIO] = ColorPair(Magenta,Black), }, [COLORSCHEME_MONOCHROME] = { [RESET_COLOR] = A_NORMAL, @@ -300,6 +314,13 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = { [PRESSURE_STALL_THREEHUNDRED] = A_DIM, [PRESSURE_STALL_SIXTY] = A_NORMAL, [PRESSURE_STALL_TEN] = A_BOLD, + [ZFS_MFU] = A_NORMAL, + [ZFS_MRU] = A_NORMAL, + [ZFS_ANON] = A_DIM, + [ZFS_HEADER] = A_BOLD, + [ZFS_OTHER] = A_DIM, + [ZFS_COMPRESSED] = A_BOLD, + [ZFS_RATIO] = A_BOLD, }, [COLORSCHEME_BLACKONWHITE] = { [RESET_COLOR] = ColorPair(Black,White), @@ -362,6 +383,13 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = { [PRESSURE_STALL_THREEHUNDRED] = ColorPair(Black,White), [PRESSURE_STALL_SIXTY] = ColorPair(Black,White), [PRESSURE_STALL_TEN] = ColorPair(Black,White), + [ZFS_MFU] = ColorPair(Cyan,White), + [ZFS_MRU] = ColorPair(Yellow,White), + [ZFS_ANON] = ColorPair(Magenta,White), + [ZFS_HEADER] = ColorPair(Yellow,White), + [ZFS_OTHER] = ColorPair(Magenta,White), + [ZFS_COMPRESSED] = ColorPair(Cyan,White), + [ZFS_RATIO] = ColorPair(Magenta,White), }, [COLORSCHEME_LIGHTTERMINAL] = { [RESET_COLOR] = ColorPair(Black,Black), @@ -424,6 +452,13 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = { [PRESSURE_STALL_THREEHUNDRED] = ColorPair(Black,Black), [PRESSURE_STALL_SIXTY] = ColorPair(Black,Black), [PRESSURE_STALL_TEN] = ColorPair(Black,Black), + [ZFS_MFU] = ColorPair(Cyan,Black), + [ZFS_MRU] = ColorPair(Yellow,Black), + [ZFS_ANON] = A_BOLD | ColorPair(Magenta,Black), + [ZFS_HEADER] = ColorPair(Black,Black), + [ZFS_OTHER] = A_BOLD | ColorPair(Magenta,Black), + [ZFS_COMPRESSED] = ColorPair(Cyan,Black), + [ZFS_RATIO] = A_BOLD | ColorPair(Magenta,Black), }, [COLORSCHEME_MIDNIGHT] = { [RESET_COLOR] = ColorPair(White,Blue), @@ -486,6 +521,13 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = { [PRESSURE_STALL_THREEHUNDRED] = A_BOLD | ColorPair(Black,Blue), [PRESSURE_STALL_SIXTY] = A_NORMAL | ColorPair(White,Blue), [PRESSURE_STALL_TEN] = A_BOLD | ColorPair(White,Blue), + [ZFS_MFU] = A_BOLD | ColorPair(White,Blue), + [ZFS_MRU] = A_BOLD | ColorPair(Yellow,Blue), + [ZFS_ANON] = A_BOLD | ColorPair(Magenta,Blue), + [ZFS_HEADER] = A_BOLD | ColorPair(Yellow,Blue), + [ZFS_OTHER] = A_BOLD | ColorPair(Magenta,Blue), + [ZFS_COMPRESSED] = A_BOLD | ColorPair(White,Blue), + [ZFS_RATIO] = A_BOLD | ColorPair(Magenta,Blue), }, [COLORSCHEME_BLACKNIGHT] = { [RESET_COLOR] = ColorPair(Cyan,Black), @@ -548,6 +590,13 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = { [PRESSURE_STALL_THREEHUNDRED] = ColorPair(Green,Black), [PRESSURE_STALL_SIXTY] = ColorPair(Green,Black), [PRESSURE_STALL_TEN] = A_BOLD | ColorPair(Green,Black), + [ZFS_MFU] = ColorPair(Blue,Black), + [ZFS_MRU] = ColorPair(Yellow,Black), + [ZFS_ANON] = ColorPair(Magenta,Black), + [ZFS_HEADER] = ColorPair(Yellow,Black), + [ZFS_OTHER] = ColorPair(Magenta,Black), + [ZFS_COMPRESSED] = ColorPair(Blue,Black), + [ZFS_RATIO] = ColorPair(Magenta,Black), }, [COLORSCHEME_BROKENGRAY] = { 0 } // dynamically generated. }; diff --git a/CRT.h b/CRT.h index 8869da9d..80022f70 100644 --- a/CRT.h +++ b/CRT.h @@ -119,6 +119,13 @@ typedef enum ColorElements_ { PRESSURE_STALL_TEN, PRESSURE_STALL_SIXTY, PRESSURE_STALL_THREEHUNDRED, + ZFS_MFU, + ZFS_MRU, + ZFS_ANON, + ZFS_HEADER, + ZFS_OTHER, + ZFS_COMPRESSED, + ZFS_RATIO, LAST_COLORELEMENT } ColorElements; diff --git a/Makefile.am b/Makefile.am index 05492179..159e22a7 100644 --- a/Makefile.am +++ b/Makefile.am @@ -49,7 +49,10 @@ linux_platform_headers = \ linux/LinuxProcessList.h \ linux/LinuxCRT.h \ linux/Battery.h \ - linux/PressureStallMeter.h + linux/PressureStallMeter.h \ + zfs/ZfsArcMeter.h \ + zfs/ZfsCompressedArcMeter.h \ + zfs/ZfsArcStats.h all_platform_headers += $(linux_platform_headers) @@ -57,7 +60,8 @@ if HTOP_LINUX AM_LDFLAGS += -rdynamic myhtopplatsources = linux/Platform.c linux/IOPriorityPanel.c linux/IOPriority.c \ linux/LinuxProcess.c linux/LinuxProcessList.c linux/LinuxCRT.c linux/Battery.c \ -linux/PressureStallMeter.c +linux/PressureStallMeter.c \ +zfs/ZfsArcMeter.c zfs/ZfsCompressedArcMeter.c zfs/ZfsArcStats.c myhtopplatheaders = $(linux_platform_headers) endif @@ -70,13 +74,18 @@ freebsd_platform_headers = \ freebsd/FreeBSDProcessList.h \ freebsd/FreeBSDProcess.h \ freebsd/FreeBSDCRT.h \ - freebsd/Battery.h + freebsd/Battery.h \ + zfs/ZfsArcMeter.h \ + zfs/ZfsCompressedArcMeter.h \ + zfs/ZfsArcStats.h \ + zfs/openzfs_sysctl.h all_platform_headers += $(freebsd_platform_headers) if HTOP_FREEBSD myhtopplatsources = freebsd/Platform.c freebsd/FreeBSDProcessList.c \ -freebsd/FreeBSDProcess.c freebsd/FreeBSDCRT.c freebsd/Battery.c +freebsd/FreeBSDProcess.c freebsd/FreeBSDCRT.c freebsd/Battery.c \ +zfs/ZfsArcMeter.c zfs/ZfsCompressedArcMeter.c zfs/ZfsArcStats.c zfs/openzfs_sysctl.c myhtopplatheaders = $(freebsd_platform_headers) endif @@ -128,14 +137,19 @@ darwin_platform_headers = \ darwin/DarwinProcess.h \ darwin/DarwinProcessList.h \ darwin/DarwinCRT.h \ - darwin/Battery.h + darwin/Battery.h \ + zfs/ZfsArcMeter.h \ + zfs/ZfsCompressedArcMeter.h \ + zfs/ZfsArcStats.h \ + zfs/openzfs_sysctl.h all_platform_headers += $(darwin_platform_headers) if HTOP_DARWIN AM_LDFLAGS += -framework IOKit -framework CoreFoundation myhtopplatsources = darwin/Platform.c darwin/DarwinProcess.c \ -darwin/DarwinProcessList.c darwin/DarwinCRT.c darwin/Battery.c +darwin/DarwinProcessList.c darwin/DarwinCRT.c darwin/Battery.c \ +zfs/ZfsArcMeter.c zfs/ZfsCompressedArcMeter.c zfs/ZfsArcStats.c zfs/openzfs_sysctl.c myhtopplatheaders = $(darwin_platform_headers) endif @@ -148,14 +162,18 @@ solaris_platform_headers = \ solaris/SolarisProcess.h \ solaris/SolarisProcessList.h \ solaris/SolarisCRT.h \ - solaris/Battery.h + solaris/Battery.h \ + zfs/ZfsArcMeter.h \ + zfs/ZfsCompressedArcMeter.h \ + zfs/ZfsArcStats.h all_platform_headers += $(solaris_platform_headers) if HTOP_SOLARIS myhtopplatsources = solaris/Platform.c \ solaris/SolarisProcess.c solaris/SolarisProcessList.c \ -solaris/SolarisCRT.c solaris/Battery.c +solaris/SolarisCRT.c solaris/Battery.c \ +zfs/ZfsArcMeter.c zfs/ZfsCompressedArcMeter.c zfs/ZfsArcStats.c myhtopplatheaders = $(solaris_platform_headers) endif diff --git a/darwin/DarwinProcessList.c b/darwin/DarwinProcessList.c index 09884480..9b4ba119 100644 --- a/darwin/DarwinProcessList.c +++ b/darwin/DarwinProcessList.c @@ -9,6 +9,8 @@ in the source distribution for its full text. #include "DarwinProcess.h" #include "DarwinProcessList.h" #include "CRT.h" +#include "zfs/ZfsArcStats.h" +#include "zfs/openzfs_sysctl.h" #include #include @@ -54,6 +56,7 @@ int CompareKernelVersion(short int major, short int minor, short int component) /*{ #include "ProcessList.h" +#include "zfs/ZfsArcStats.h" #include #include @@ -67,6 +70,8 @@ typedef struct DarwinProcessList_ { uint64_t kernel_threads; uint64_t user_threads; uint64_t global_diff; + + ZfsArcStats zfs; } DarwinProcessList; }*/ @@ -131,8 +136,8 @@ struct kinfo_proc *ProcessList_getKInfoProcs(size_t *count) { return processes; } - ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidWhiteList, uid_t userId) { + size_t len; DarwinProcessList* this = xCalloc(1, sizeof(DarwinProcessList)); ProcessList_init(&this->super, Class(Process), usersTable, pidWhiteList, userId); @@ -145,6 +150,10 @@ ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidWhiteList, ui /* Initialize the VM statistics */ ProcessList_getVMStats(&this->vm_stats); + /* Initialize the ZFS kstats, if zfs.kext loaded */ + openzfs_sysctl_init(&this->zfs); + openzfs_sysctl_updateArcStats(&this->zfs); + this->super.kernelThreads = 0; this->super.userlandThreads = 0; this->super.totalTasks = 0; @@ -173,6 +182,7 @@ void ProcessList_goThroughEntries(ProcessList* super) { dpl->prev_load = dpl->curr_load; ProcessList_allocateCPULoadInfo(&dpl->curr_load); ProcessList_getVMStats(&dpl->vm_stats); + openzfs_sysctl_updateArcStats(&dpl->zfs); /* Get the time difference */ dpl->global_diff = 0; diff --git a/darwin/DarwinProcessList.h b/darwin/DarwinProcessList.h index c216a804..73fbd34f 100644 --- a/darwin/DarwinProcessList.h +++ b/darwin/DarwinProcessList.h @@ -9,7 +9,19 @@ Released under the GNU GPL, see the COPYING file in the source distribution for its full text. */ +struct kern; + +void GetKernelVersion(struct kern *k); + +/* compare the given os version with the one installed returns: +0 if equals the installed version +positive value if less than the installed version +negative value if more than the installed version +*/ +int CompareKernelVersion(short int major, short int minor, short int component); + #include "ProcessList.h" +#include "zfs/ZfsArcStats.h" #include #include @@ -23,6 +35,8 @@ typedef struct DarwinProcessList_ { uint64_t kernel_threads; uint64_t user_threads; uint64_t global_diff; + + ZfsArcStats zfs; } DarwinProcessList; diff --git a/darwin/Platform.c b/darwin/Platform.c index a052ea8a..26e84112 100644 --- a/darwin/Platform.c +++ b/darwin/Platform.c @@ -15,6 +15,8 @@ in the source distribution for its full text. #include "ClockMeter.h" #include "HostnameMeter.h" #include "UptimeMeter.h" +#include "zfs/ZfsArcMeter.h" +#include "zfs/ZfsCompressedArcMeter.h" #include "DarwinProcessList.h" #include @@ -117,6 +119,8 @@ MeterClass* Platform_meterTypes[] = { &RightCPUsMeter_class, &LeftCPUs2Meter_class, &RightCPUs2Meter_class, + &ZfsArcMeter_class, + &ZfsCompressedArcMeter_class, &BlankMeter_class, NULL }; @@ -243,6 +247,18 @@ void Platform_setSwapValues(Meter* mtr) { mtr->values[0] = swapused.xsu_used / 1024; } +void Platform_setZfsArcValues(Meter* this) { + DarwinProcessList* dpl = (DarwinProcessList*) this->pl; + + ZfsArcMeter_readStats(this, &(dpl->zfs)); +} + +void Platform_setZfsCompressedArcValues(Meter* this) { + DarwinProcessList* dpl = (DarwinProcessList*) this->pl; + + ZfsCompressedArcMeter_readStats(this, &(dpl->zfs)); +} + char* Platform_getProcessEnv(pid_t pid) { char* env = NULL; diff --git a/darwin/Platform.h b/darwin/Platform.h index 1231217b..e17661d6 100644 --- a/darwin/Platform.h +++ b/darwin/Platform.h @@ -48,6 +48,10 @@ void Platform_setMemoryValues(Meter* mtr); void Platform_setSwapValues(Meter* mtr); +void Platform_setZfsArcValues(Meter* this); + +void Platform_setZfsCompressedArcValues(Meter* this); + char* Platform_getProcessEnv(pid_t pid); #endif diff --git a/freebsd/FreeBSDProcessList.c b/freebsd/FreeBSDProcessList.c index ac5603fb..7bc42db6 100644 --- a/freebsd/FreeBSDProcessList.c +++ b/freebsd/FreeBSDProcessList.c @@ -8,6 +8,8 @@ in the source distribution for its full text. #include "ProcessList.h" #include "FreeBSDProcessList.h" #include "FreeBSDProcess.h" +#include "zfs/ZfsArcStats.h" +#include "zfs/openzfs_sysctl.h" #include #include @@ -22,6 +24,8 @@ in the source distribution for its full text. /*{ +#include "zfs/ZfsArcStats.h" + #include #include #include @@ -46,14 +50,12 @@ typedef struct FreeBSDProcessList_ { ProcessList super; kvm_t* kd; - int zfsArcEnabled; - unsigned long long int memWire; unsigned long long int memActive; unsigned long long int memInactive; unsigned long long int memFree; - unsigned long long int memZfsArc; + ZfsArcStats zfs; CPUData* cpus; @@ -81,8 +83,6 @@ static int MIB_vm_stats_vm_v_free_count[4]; static int MIB_vfs_bufspace[2]; -static int MIB_kstat_zfs_misc_arcstats_size[5]; - static int MIB_kern_cp_time[2]; static int MIB_kern_cp_times[2]; static int kernelFScale; @@ -119,15 +119,8 @@ ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidWhiteList, ui len = 2; sysctlnametomib("vfs.bufspace", MIB_vfs_bufspace, &len); - len = sizeof(fpl->memZfsArc); - if (sysctlbyname("kstat.zfs.misc.arcstats.size", &fpl->memZfsArc, &len, - NULL, 0) == 0 && fpl->memZfsArc != 0) { - sysctlnametomib("kstat.zfs.misc.arcstats.size", MIB_kstat_zfs_misc_arcstats_size, &len); - fpl->zfsArcEnabled = 1; - } else { - fpl->zfsArcEnabled = 0; - } - + openzfs_sysctl_init(&fpl->zfs); + openzfs_sysctl_updateArcStats(&fpl->zfs); int smp = 0; len = sizeof(smp); @@ -341,6 +334,11 @@ static inline void FreeBSDProcessList_scanMemoryInfo(ProcessList* pl) { pl->cachedMem += fpl->memZfsArc; // maybe when we learn how to make custom memory meter // we could do custom arc breakdown? + } + + if (fpl->zfs.enabled) { + fpl->memWire -= fpl->zfs.size; + pl->cachedMem += fpl->zfs.size; } pl->usedMem = fpl->memActive + fpl->memWire; @@ -438,6 +436,7 @@ void ProcessList_goThroughEntries(ProcessList* this) { bool hideKernelThreads = settings->hideKernelThreads; bool hideUserlandThreads = settings->hideUserlandThreads; + openzfs_sysctl_updateArcStats(&fpl->zfs); FreeBSDProcessList_scanMemoryInfo(this); FreeBSDProcessList_scanCPUTime(this); diff --git a/freebsd/FreeBSDProcessList.h b/freebsd/FreeBSDProcessList.h index af343fb0..7c1b7ad4 100644 --- a/freebsd/FreeBSDProcessList.h +++ b/freebsd/FreeBSDProcessList.h @@ -10,6 +10,8 @@ in the source distribution for its full text. */ +#include "zfs/ZfsArcStats.h" + #include #include #include @@ -34,14 +36,12 @@ typedef struct FreeBSDProcessList_ { ProcessList super; kvm_t* kd; - int zfsArcEnabled; - unsigned long long int memWire; unsigned long long int memActive; unsigned long long int memInactive; unsigned long long int memFree; - unsigned long long int memZfsArc; + ZfsArcStats zfs; CPUData* cpus; diff --git a/freebsd/Platform.c b/freebsd/Platform.c index 16d02329..e6acebdb 100644 --- a/freebsd/Platform.c +++ b/freebsd/Platform.c @@ -15,6 +15,8 @@ in the source distribution for its full text. #include "UptimeMeter.h" #include "ClockMeter.h" #include "HostnameMeter.h" +#include "zfs/ZfsArcMeter.h" +#include "zfs/ZfsCompressedArcMeter.h" #include "FreeBSDProcess.h" #include "FreeBSDProcessList.h" @@ -104,6 +106,8 @@ MeterClass* Platform_meterTypes[] = { &LeftCPUs2Meter_class, &RightCPUs2Meter_class, &BlankMeter_class, + &ZfsArcMeter_class, + &ZfsCompressedArcMeter_class, NULL }; @@ -200,6 +204,18 @@ void Platform_setSwapValues(Meter* this) { this->values[0] = pl->usedSwap; } +void Platform_setZfsArcValues(Meter* this) { + FreeBSDProcessList* fpl = (FreeBSDProcessList*) this->pl; + + ZfsArcMeter_readStats(this, &(fpl->zfs)); +} + +void Platform_setZfsCompressedArcValues(Meter* this) { + FreeBSDProcessList* fpl = (FreeBSDProcessList*) this->pl; + + ZfsCompressedArcMeter_readStats(this, &(fpl->zfs)); +} + void Platform_setTasksValues(Meter* this) { // TODO } diff --git a/freebsd/Platform.h b/freebsd/Platform.h index 1735e7e3..0268f2c6 100644 --- a/freebsd/Platform.h +++ b/freebsd/Platform.h @@ -44,6 +44,10 @@ void Platform_setMemoryValues(Meter* this); void Platform_setSwapValues(Meter* this); +void Platform_setZfsArcValues(Meter* this); + +void Platform_setZfsCompressedArcValues(Meter* this); + void Platform_setTasksValues(Meter* this); char* Platform_getProcessEnv(pid_t pid); diff --git a/linux/LinuxProcessList.c b/linux/LinuxProcessList.c index 64a4ffeb..bcdd5515 100644 --- a/linux/LinuxProcessList.c +++ b/linux/LinuxProcessList.c @@ -45,6 +45,7 @@ in the source distribution for its full text. /*{ #include "ProcessList.h" +#include "zfs/ZfsArcStats.h" extern long long btime; @@ -96,6 +97,8 @@ typedef struct LinuxProcessList_ { struct nl_sock *netlink_socket; int netlink_family; #endif + + ZfsArcStats zfs; } LinuxProcessList; #ifndef PROCDIR @@ -114,6 +117,10 @@ typedef struct LinuxProcessList_ { #define PROCMEMINFOFILE PROCDIR "/meminfo" #endif +#ifndef PROCARCSTATSFILE +#define PROCARCSTATSFILE PROCDIR "/spl/kstat/zfs/arcstats" +#endif + #ifndef PROCTTYDRIVERSFILE #define PROCTTYDRIVERSFILE PROCDIR "/tty/drivers" #endif @@ -1054,6 +1061,68 @@ static inline void LinuxProcessList_scanMemoryInfo(ProcessList* this) { fclose(file); } +static inline void LinuxProcessList_scanZfsArcstats(LinuxProcessList* lpl) { + unsigned long long int dbufSize; + unsigned long long int dnodeSize; + unsigned long long int bonusSize; + + FILE* file = fopen(PROCARCSTATSFILE, "r"); + if (file == NULL) { + lpl->zfs.enabled = 0; + return; + } + char buffer[128]; + while (fgets(buffer, 128, file)) { + #define tryRead(label, variable) do { if (String_startsWith(buffer, label) && sscanf(buffer + strlen(label), " %*2u %32llu", variable)) { break; } } while(0) + #define tryReadFlag(label, variable, flag) do { if (String_startsWith(buffer, label) && sscanf(buffer + strlen(label), " %*2u %32llu", variable)) { flag = 1; break; } else { flag = 0; } } while(0) + switch (buffer[0]) { + case 'c': + tryRead("c_max", &lpl->zfs.max); + tryReadFlag("compressed_size", &lpl->zfs.compressed, lpl->zfs.isCompressed); + break; + case 'u': + tryRead("uncompressed_size", &lpl->zfs.uncompressed); + break; + case 's': + tryRead("size", &lpl->zfs.size); + break; + case 'h': + tryRead("hdr_size", &lpl->zfs.header); + break; + case 'd': + tryRead("dbuf_size", &dbufSize); + tryRead("dnode_size", &dnodeSize); + break; + case 'b': + tryRead("bonus_size", &bonusSize); + break; + case 'a': + tryRead("anon_size", &lpl->zfs.anon); + break; + case 'm': + tryRead("mfu_size", &lpl->zfs.MFU); + tryRead("mru_size", &lpl->zfs.MRU); + break; + } + #undef tryRead + #undef tryReadFlag + } + fclose(file); + + lpl->zfs.enabled = (lpl->zfs.size > 0 ? 1 : 0); + lpl->zfs.size /= 1024; + lpl->zfs.max /= 1024; + lpl->zfs.MFU /= 1024; + lpl->zfs.MRU /= 1024; + lpl->zfs.anon /= 1024; + lpl->zfs.header /= 1024; + lpl->zfs.other = (dbufSize + dnodeSize + bonusSize) / 1024; + if ( lpl->zfs.isCompressed ) { + lpl->zfs.compressed /= 1024; + lpl->zfs.uncompressed /= 1024; + } +} + static inline double LinuxProcessList_scanCPUTime(LinuxProcessList* this) { FILE* file = fopen(PROCSTATFILE, "r"); @@ -1194,6 +1263,7 @@ void ProcessList_goThroughEntries(ProcessList* super) { LinuxProcessList* this = (LinuxProcessList*) super; LinuxProcessList_scanMemoryInfo(super); + LinuxProcessList_scanZfsArcstats(this); double period = LinuxProcessList_scanCPUTime(this); LinuxProcessList_scanCPUFrequency(this); diff --git a/linux/LinuxProcessList.h b/linux/LinuxProcessList.h index 24b94d87..86e9d3fd 100644 --- a/linux/LinuxProcessList.h +++ b/linux/LinuxProcessList.h @@ -18,6 +18,7 @@ in the source distribution for its full text. #include "ProcessList.h" +#include "zfs/ZfsArcStats.h" extern long long btime; @@ -69,6 +70,8 @@ typedef struct LinuxProcessList_ { struct nl_sock *netlink_socket; int netlink_family; #endif + + ZfsArcStats zfs; } LinuxProcessList; #ifndef PROCDIR @@ -87,6 +90,10 @@ typedef struct LinuxProcessList_ { #define PROCMEMINFOFILE PROCDIR "/meminfo" #endif +#ifndef PROCARCSTATSFILE +#define PROCARCSTATSFILE PROCDIR "/spl/kstat/zfs/arcstats" +#endif + #ifndef PROCTTYDRIVERSFILE #define PROCTTYDRIVERSFILE PROCDIR "/tty/drivers" #endif diff --git a/linux/Platform.c b/linux/Platform.c index 00a91a5e..1725eea9 100644 --- a/linux/Platform.c +++ b/linux/Platform.c @@ -22,6 +22,8 @@ in the source distribution for its full text. #include "PressureStallMeter.h" #include "ClockMeter.h" #include "HostnameMeter.h" +#include "zfs/ZfsArcMeter.h" +#include "zfs/ZfsCompressedArcMeter.h" #include "LinuxProcess.h" #include @@ -135,6 +137,8 @@ MeterClass* Platform_meterTypes[] = { &PressureStallIOFullMeter_class, &PressureStallMemorySomeMeter_class, &PressureStallMemoryFullMeter_class, + &ZfsArcMeter_class, + &ZfsCompressedArcMeter_class, NULL }; @@ -225,6 +229,17 @@ void Platform_setSwapValues(Meter* this) { this->values[0] = pl->usedSwap; } +void Platform_setZfsArcValues(Meter* this) { + LinuxProcessList* lpl = (LinuxProcessList*) this->pl; + + ZfsArcMeter_readStats(this, &(lpl->zfs)); +} + +void Platform_setZfsCompressedArcValues(Meter* this) { + LinuxProcessList* lpl = (LinuxProcessList*) this->pl; + + ZfsCompressedArcMeter_readStats(this, &(lpl->zfs)); +} char* Platform_getProcessEnv(pid_t pid) { char procname[32+1]; xSnprintf(procname, 32, "/proc/%d/environ", pid); diff --git a/linux/Platform.h b/linux/Platform.h index bb2c4b09..bf163a54 100644 --- a/linux/Platform.h +++ b/linux/Platform.h @@ -43,6 +43,9 @@ extern void Platform_setMemoryValues(Meter* this); extern void Platform_setSwapValues(Meter* this); +extern void Platform_setZfsArcValues(Meter* this); + +extern void Platform_setZfsCompressedArcValues(Meter* this); extern char* Platform_getProcessEnv(pid_t pid); extern void Platform_getPressureStall(const char *file, bool some, double* ten, double* sixty, double* threehundred); diff --git a/solaris/Platform.c b/solaris/Platform.c index 1322598e..092f4507 100644 --- a/solaris/Platform.c +++ b/solaris/Platform.c @@ -17,6 +17,8 @@ in the source distribution for its full text. #include "ClockMeter.h" #include "HostnameMeter.h" #include "UptimeMeter.h" +#include "zfs/ZfsArcMeter.h" +#include "zfs/ZfsCompressedArcMeter.h" #include "SolarisProcess.h" #include "SolarisProcessList.h" @@ -122,6 +124,8 @@ MeterClass* Platform_meterTypes[] = { &RightCPUsMeter_class, &LeftCPUs2Meter_class, &RightCPUs2Meter_class, + &ZfsArcMeter_class, + &ZfsCompressedArcMeter_class, &BlankMeter_class, NULL }; @@ -223,6 +227,18 @@ void Platform_setSwapValues(Meter* this) { this->values[0] = pl->usedSwap; } +void Platform_setZfsArcValues(Meter* this) { + SolarisProcessList* spl = (SolarisProcessList*) this->pl; + + ZfsArcMeter_readStats(this, &(spl->zfs)); +} + +void Platform_setZfsCompressedArcValues(Meter* this) { + SolarisProcessList* spl = (SolarisProcessList*) this->pl; + + ZfsCompressedArcMeter_readStats(this, &(spl->zfs)); +} + static int Platform_buildenv(void *accum, struct ps_prochandle *Phandle, uintptr_t addr, const char *str) { envAccum *accump = accum; (void) Phandle; diff --git a/solaris/Platform.h b/solaris/Platform.h index ffec60c9..dd1962dd 100644 --- a/solaris/Platform.h +++ b/solaris/Platform.h @@ -60,6 +60,10 @@ void Platform_setMemoryValues(Meter* this); void Platform_setSwapValues(Meter* this); +void Platform_setZfsArcValues(Meter* this); + +void Platform_setZfsCompressedArcValues(Meter* this); + char* Platform_getProcessEnv(pid_t pid); #endif diff --git a/solaris/SolarisProcessList.c b/solaris/SolarisProcessList.c index 15ae44bc..8faa49f3 100644 --- a/solaris/SolarisProcessList.c +++ b/solaris/SolarisProcessList.c @@ -29,6 +29,8 @@ in the source distribution for its full text. #define UZONE "unknown " /*{ +#include "zfs/ZfsArcStats.h" + #include #include #include @@ -57,6 +59,7 @@ typedef struct SolarisProcessList_ { ProcessList super; kstat_ctl_t* kd; CPUData* cpus; + ZfsArcStats zfs; } SolarisProcessList; }*/ @@ -232,6 +235,49 @@ static inline void SolarisProcessList_scanMemoryInfo(ProcessList* pl) { pl->usedSwap = pl->totalSwap - (totalfree * PAGE_SIZE_KB); } +static inline void SolarisProcessList_scanZfsArcstats(ProcessList* pl) { + SolarisProcessList* spl = (SolarisProcessList*) pl; + kstat_t *arcstats = NULL; + int ksrphyserr = -1; + kstat_named_t *cur_kstat = NULL; + + if (spl->kd != NULL) { arcstats = kstat_lookup(spl->kd,"zfs",0,"arcstats"); } + if (arcstats != NULL) { ksrphyserr = kstat_read(spl->kd,arcstats,NULL); } + if (ksrphyserr != -1) { + cur_kstat = kstat_data_lookup( arcstats, "size" ); + spl->zfs.size = cur_kstat->value.ui64 / 1024; + spl->zfs.enabled = spl->zfs.size > 0 ? 1 : 0; + + cur_kstat = kstat_data_lookup( arcstats, "c_max" ); + spl->zfs.max = cur_kstat->value.ui64 / 1024; + + cur_kstat = kstat_data_lookup( arcstats, "mfu_size" ); + spl->zfs.MFU = cur_kstat->value.ui64 / 1024; + + cur_kstat = kstat_data_lookup( arcstats, "mru_size" ); + spl->zfs.MRU = cur_kstat->value.ui64 / 1024; + + cur_kstat = kstat_data_lookup( arcstats, "anon_size" ); + spl->zfs.anon = cur_kstat->value.ui64 / 1024; + + cur_kstat = kstat_data_lookup( arcstats, "hdr_size" ); + spl->zfs.header = cur_kstat->value.ui64 / 1024; + + cur_kstat = kstat_data_lookup( arcstats, "other_size" ); + spl->zfs.other = cur_kstat->value.ui64 / 1024; + + if ((cur_kstat = kstat_data_lookup( arcstats, "compressed_size" )) != NULL) { + spl->zfs.compressed = cur_kstat->value.ui64 / 1024; + spl->zfs.isCompressed = 1; + + cur_kstat = kstat_data_lookup( arcstats, "uncompressed_size" ); + spl->zfs.uncompressed = cur_kstat->value.ui64 / 1024; + } else { + spl->zfs.isCompressed = 0; + } + } +} + void ProcessList_delete(ProcessList* pl) { SolarisProcessList* spl = (SolarisProcessList*) pl; ProcessList_done(pl); @@ -369,6 +415,7 @@ int SolarisProcessList_walkproc(psinfo_t *_psinfo, lwpsinfo_t *_lwpsinfo, void * void ProcessList_goThroughEntries(ProcessList* this) { SolarisProcessList_scanCPUTime(this); SolarisProcessList_scanMemoryInfo(this); + SolarisProcessList_scanZfsArcstats(this); this->kernelThreads = 1; proc_walk(&SolarisProcessList_walkproc, this, PR_WALK_LWP); } diff --git a/solaris/SolarisProcessList.h b/solaris/SolarisProcessList.h index 8388fabe..06c1330e 100644 --- a/solaris/SolarisProcessList.h +++ b/solaris/SolarisProcessList.h @@ -15,6 +15,8 @@ in the source distribution for its full text. #define GZONE "global " #define UZONE "unknown " +#include "zfs/ZfsArcStats.h" + #include #include #include @@ -43,6 +45,7 @@ typedef struct SolarisProcessList_ { ProcessList super; kstat_ctl_t* kd; CPUData* cpus; + ZfsArcStats zfs; } SolarisProcessList; diff --git a/zfs/ZfsArcMeter.c b/zfs/ZfsArcMeter.c new file mode 100644 index 00000000..9f7028bc --- /dev/null +++ b/zfs/ZfsArcMeter.c @@ -0,0 +1,104 @@ +/* +htop - ZfsArcMeter.c +(C) 2004-2011 Hisham H. Muhammad +Released under the GNU GPL, see the COPYING file +in the source distribution for its full text. +*/ + +#include "ZfsArcMeter.h" +#include "ZfsArcStats.h" + +#include "CRT.h" +#include "Platform.h" + +#include +#include +#include +#include +#include + +/*{ +#include "ZfsArcStats.h" + +#include "Meter.h" +}*/ + +int ZfsArcMeter_attributes[] = { + ZFS_MFU, ZFS_MRU, ZFS_ANON, ZFS_HEADER, ZFS_OTHER +}; + +void ZfsArcMeter_readStats(Meter* this, ZfsArcStats* stats) { + this->total = stats->max; + this->values[0] = stats->MFU; + this->values[1] = stats->MRU; + this->values[2] = stats->anon; + this->values[3] = stats->header; + this->values[4] = stats->other; + + // "Hide" the last value so it can + // only be accessed by index and is not + // displayed by the Bar or Graph style + Meter_setItems(this, 5); + this->values[5] = stats->size; +} + +static void ZfsArcMeter_updateValues(Meter* this, char* buffer, int size) { + int written; + Platform_setZfsArcValues(this); + + written = Meter_humanUnit(buffer, this->values[5], size); + buffer += written; + if ((size -= written) > 0) { + *buffer++ = '/'; + size--; + Meter_humanUnit(buffer, this->total, size); + } +} + +static void ZfsArcMeter_display(Object* cast, RichString* out) { + char buffer[50]; + Meter* this = (Meter*)cast; + + if (this->values[5] > 0) { + RichString_write(out, CRT_colors[METER_TEXT], ":"); + Meter_humanUnit(buffer, this->total, 50); + RichString_append(out, CRT_colors[METER_VALUE], buffer); + Meter_humanUnit(buffer, this->values[5], 50); + RichString_append(out, CRT_colors[METER_TEXT], " Used:"); + RichString_append(out, CRT_colors[METER_VALUE], buffer); + Meter_humanUnit(buffer, this->values[0], 50); + RichString_append(out, CRT_colors[METER_TEXT], " MFU:"); + RichString_append(out, CRT_colors[ZFS_MFU], buffer); + Meter_humanUnit(buffer, this->values[1], 50); + RichString_append(out, CRT_colors[METER_TEXT], " MRU:"); + RichString_append(out, CRT_colors[ZFS_MRU], buffer); + Meter_humanUnit(buffer, this->values[2], 50); + RichString_append(out, CRT_colors[METER_TEXT], " Anon:"); + RichString_append(out, CRT_colors[ZFS_ANON], buffer); + Meter_humanUnit(buffer, this->values[3], 50); + RichString_append(out, CRT_colors[METER_TEXT], " Hdr:"); + RichString_append(out, CRT_colors[ZFS_HEADER], buffer); + Meter_humanUnit(buffer, this->values[4], 50); + RichString_append(out, CRT_colors[METER_TEXT], " Oth:"); + RichString_append(out, CRT_colors[ZFS_OTHER], buffer); + } else { + RichString_write(out, CRT_colors[METER_TEXT], " "); + RichString_append(out, CRT_colors[FAILED_SEARCH], "Unavailable"); + } +} + +MeterClass ZfsArcMeter_class = { + .super = { + .extends = Class(Meter), + .delete = Meter_delete, + .display = ZfsArcMeter_display, + }, + .updateValues = ZfsArcMeter_updateValues, + .defaultMode = TEXT_METERMODE, + .maxItems = 6, + .total = 100.0, + .attributes = ZfsArcMeter_attributes, + .name = "ZFSARC", + .uiName = "ZFS ARC", + .caption = "ARC" +}; diff --git a/zfs/ZfsArcMeter.h b/zfs/ZfsArcMeter.h new file mode 100644 index 00000000..c52083df --- /dev/null +++ b/zfs/ZfsArcMeter.h @@ -0,0 +1,22 @@ +/* Do not edit this file. It was automatically generated. */ + +#ifndef HEADER_ZfsArcMeter +#define HEADER_ZfsArcMeter +/* +htop - ZfsArcMeter.h +(C) 2004-2011 Hisham H. Muhammad +Released under the GNU GPL, see the COPYING file +in the source distribution for its full text. +*/ + +#include "ZfsArcStats.h" + +#include "Meter.h" + +extern int ZfsArcMeter_attributes[]; + +void ZfsArcMeter_readStats(Meter* this, ZfsArcStats* stats); + +extern MeterClass ZfsArcMeter_class; + +#endif diff --git a/zfs/ZfsArcStats.c b/zfs/ZfsArcStats.c new file mode 100644 index 00000000..1bfaf47d --- /dev/null +++ b/zfs/ZfsArcStats.c @@ -0,0 +1,22 @@ +/* +htop - ZfsArcStats.c +(C) 2014 Hisham H. Muhammad +Released under the GNU GPL, see the COPYING file +in the source distribution for its full text. +*/ + +/*{ +typedef struct ZfsArcStats_ { + int enabled; + int isCompressed; + unsigned long long int max; + unsigned long long int size; + unsigned long long int MFU; + unsigned long long int MRU; + unsigned long long int anon; + unsigned long long int header; + unsigned long long int other; + unsigned long long int compressed; + unsigned long long int uncompressed; +} ZfsArcStats; +}*/ diff --git a/zfs/ZfsArcStats.h b/zfs/ZfsArcStats.h new file mode 100644 index 00000000..ee5d0edd --- /dev/null +++ b/zfs/ZfsArcStats.h @@ -0,0 +1,26 @@ +/* Do not edit this file. It was automatically generated. */ + +#ifndef HEADER_ZfsArcStats +#define HEADER_ZfsArcStats +/* +htop - ZfsArcStats.h +(C) 2014 Hisham H. Muhammad +Released under the GNU GPL, see the COPYING file +in the source distribution for its full text. +*/ + +typedef struct ZfsArcStats_ { + int enabled; + int isCompressed; + unsigned long long int max; + unsigned long long int size; + unsigned long long int MFU; + unsigned long long int MRU; + unsigned long long int anon; + unsigned long long int header; + unsigned long long int other; + unsigned long long int compressed; + unsigned long long int uncompressed; +} ZfsArcStats; + +#endif diff --git a/zfs/ZfsCompressedArcMeter.c b/zfs/ZfsCompressedArcMeter.c new file mode 100644 index 00000000..ac3944d3 --- /dev/null +++ b/zfs/ZfsCompressedArcMeter.c @@ -0,0 +1,86 @@ +/* +htop - ZfsCompressedArcMeter.c +(C) 2004-2011 Hisham H. Muhammad +Released under the GNU GPL, see the COPYING file +in the source distribution for its full text. +*/ + +#include "ZfsCompressedArcMeter.h" +#include "ZfsArcStats.h" + +#include "CRT.h" +#include "Platform.h" + +#include +#include +#include +#include +#include + +/*{ +#include "ZfsArcStats.h" + +#include "Meter.h" +}*/ + +int ZfsCompressedArcMeter_attributes[] = { + ZFS_COMPRESSED +}; + +void ZfsCompressedArcMeter_readStats(Meter* this, ZfsArcStats* stats) { + if ( stats->isCompressed ) { + this->total = stats->uncompressed; + this->values[0] = stats->compressed; + } else { + // For uncompressed ARC, report 1:1 ratio + this->total = stats->size; + this->values[0] = stats->size; + } +} + +static void ZfsCompressedArcMeter_printRatioString(Meter* this, char* buffer, int size) { + xSnprintf(buffer, size, "%.2f:1", this->total/this->values[0]); +} + +static void ZfsCompressedArcMeter_updateValues(Meter* this, char* buffer, int size) { + Platform_setZfsCompressedArcValues(this); + + ZfsCompressedArcMeter_printRatioString(this, buffer, size); +} + +static void ZfsCompressedArcMeter_display(Object* cast, RichString* out) { + char buffer[50]; + Meter* this = (Meter*)cast; + + if (this->values[0] > 0) { + Meter_humanUnit(buffer, this->total, 50); + RichString_append(out, CRT_colors[METER_VALUE], buffer); + RichString_append(out, CRT_colors[METER_TEXT], " Uncompressed, "); + Meter_humanUnit(buffer, this->values[0], 50); + RichString_append(out, CRT_colors[METER_VALUE], buffer); + RichString_append(out, CRT_colors[METER_TEXT], " Compressed, "); + ZfsCompressedArcMeter_printRatioString(this, buffer, 50); + RichString_append(out, CRT_colors[METER_VALUE], buffer); + RichString_append(out, CRT_colors[METER_TEXT], " Ratio"); + } else { + RichString_write(out, CRT_colors[METER_TEXT], " "); + RichString_append(out, CRT_colors[FAILED_SEARCH], "Compression Unavailable"); + } +} + +MeterClass ZfsCompressedArcMeter_class = { + .super = { + .extends = Class(Meter), + .delete = Meter_delete, + .display = ZfsCompressedArcMeter_display, + }, + .updateValues = ZfsCompressedArcMeter_updateValues, + .defaultMode = TEXT_METERMODE, + .maxItems = 1, + .total = 100.0, + .attributes = ZfsCompressedArcMeter_attributes, + .name = "ZFSCARC", + .uiName = "ZFS CARC", + .description = "ZFS CARC: Compressed ARC statistics", + .caption = "ARC: " +}; diff --git a/zfs/ZfsCompressedArcMeter.h b/zfs/ZfsCompressedArcMeter.h new file mode 100644 index 00000000..5afcc99e --- /dev/null +++ b/zfs/ZfsCompressedArcMeter.h @@ -0,0 +1,22 @@ +/* Do not edit this file. It was automatically generated. */ + +#ifndef HEADER_ZfsCompressedArcMeter +#define HEADER_ZfsCompressedArcMeter +/* +htop - ZfsCompressedArcMeter.h +(C) 2004-2011 Hisham H. Muhammad +Released under the GNU GPL, see the COPYING file +in the source distribution for its full text. +*/ + +#include "ZfsArcStats.h" + +#include "Meter.h" + +extern int ZfsCompressedArcMeter_attributes[]; + +void ZfsCompressedArcMeter_readStats(Meter* this, ZfsArcStats* stats); + +extern MeterClass ZfsCompressedArcMeter_class; + +#endif diff --git a/zfs/openzfs_sysctl.c b/zfs/openzfs_sysctl.c new file mode 100644 index 00000000..c1ab2239 --- /dev/null +++ b/zfs/openzfs_sysctl.c @@ -0,0 +1,99 @@ +/* +htop - zfs/openzfs_sysctl.c +(C) 2014 Hisham H. Muhammad +Released under the GNU GPL, see the COPYING file +in the source distribution for its full text. +*/ + +#include "zfs/openzfs_sysctl.h" +#include "zfs/ZfsArcStats.h" + +#include +#include +#include +#include + +static int MIB_kstat_zfs_misc_arcstats_size[5]; +static int MIB_kstat_zfs_misc_arcstats_c_max[5]; +static int MIB_kstat_zfs_misc_arcstats_mfu_size[5]; +static int MIB_kstat_zfs_misc_arcstats_mru_size[5]; +static int MIB_kstat_zfs_misc_arcstats_anon_size[5]; +static int MIB_kstat_zfs_misc_arcstats_hdr_size[5]; +static int MIB_kstat_zfs_misc_arcstats_other_size[5]; +static int MIB_kstat_zfs_misc_arcstats_compressed_size[5]; +static int MIB_kstat_zfs_misc_arcstats_uncompressed_size[5]; + +/*{ +#include "zfs/ZfsArcStats.h" +}*/ + +void openzfs_sysctl_init(ZfsArcStats *stats) { + size_t len; + unsigned long long int arcSize; + + len = sizeof(arcSize); + if (sysctlbyname("kstat.zfs.misc.arcstats.size", &arcSize, &len, + NULL, 0) == 0 && arcSize != 0) { + stats->enabled = 1; + len = 5; sysctlnametomib("kstat.zfs.misc.arcstats.size", MIB_kstat_zfs_misc_arcstats_size, &len); + + sysctlnametomib("kstat.zfs.misc.arcstats.c_max", MIB_kstat_zfs_misc_arcstats_c_max, &len); + sysctlnametomib("kstat.zfs.misc.arcstats.mfu_size", MIB_kstat_zfs_misc_arcstats_mfu_size, &len); + sysctlnametomib("kstat.zfs.misc.arcstats.mru_size", MIB_kstat_zfs_misc_arcstats_mru_size, &len); + sysctlnametomib("kstat.zfs.misc.arcstats.anon_size", MIB_kstat_zfs_misc_arcstats_anon_size, &len); + sysctlnametomib("kstat.zfs.misc.arcstats.hdr_size", MIB_kstat_zfs_misc_arcstats_hdr_size, &len); + sysctlnametomib("kstat.zfs.misc.arcstats.other_size", MIB_kstat_zfs_misc_arcstats_other_size, &len); + if (sysctlnametomib("kstat.zfs.misc.arcstats.compressed_size", MIB_kstat_zfs_misc_arcstats_compressed_size, &len) == 0) { + stats->isCompressed = 1; + sysctlnametomib("kstat.zfs.misc.arcstats.uncompressed_size", MIB_kstat_zfs_misc_arcstats_uncompressed_size, &len); + } else { + stats->isCompressed = 0; + } + } else { + stats->enabled = 0; + } +} + +void openzfs_sysctl_updateArcStats(ZfsArcStats *stats) { + size_t len; + + if (stats->enabled) { + len = sizeof(stats->size); + sysctl(MIB_kstat_zfs_misc_arcstats_size, 5, &(stats->size), &len , NULL, 0); + stats->size /= 1024; + + len = sizeof(stats->max); + sysctl(MIB_kstat_zfs_misc_arcstats_c_max, 5, &(stats->max), &len , NULL, 0); + stats->max /= 1024; + + len = sizeof(stats->MFU); + sysctl(MIB_kstat_zfs_misc_arcstats_mfu_size, 5, &(stats->MFU), &len , NULL, 0); + stats->MFU /= 1024; + + len = sizeof(stats->MRU); + sysctl(MIB_kstat_zfs_misc_arcstats_mru_size, 5, &(stats->MRU), &len , NULL, 0); + stats->MRU /= 1024; + + len = sizeof(stats->anon); + sysctl(MIB_kstat_zfs_misc_arcstats_anon_size, 5, &(stats->anon), &len , NULL, 0); + stats->anon /= 1024; + + len = sizeof(stats->header); + sysctl(MIB_kstat_zfs_misc_arcstats_hdr_size, 5, &(stats->header), &len , NULL, 0); + stats->header /= 1024; + + len = sizeof(stats->other); + sysctl(MIB_kstat_zfs_misc_arcstats_other_size, 5, &(stats->other), &len , NULL, 0); + stats->other /= 1024; + + if (stats->isCompressed) { + len = sizeof(stats->compressed); + sysctl(MIB_kstat_zfs_misc_arcstats_compressed_size, 5, &(stats->compressed), &len , NULL, 0); + stats->compressed /= 1024; + + len = sizeof(stats->uncompressed); + sysctl(MIB_kstat_zfs_misc_arcstats_uncompressed_size, 5, &(stats->uncompressed), &len , NULL, 0); + stats->uncompressed /= 1024; + } + } +} diff --git a/zfs/openzfs_sysctl.h b/zfs/openzfs_sysctl.h new file mode 100644 index 00000000..6e44ac3b --- /dev/null +++ b/zfs/openzfs_sysctl.h @@ -0,0 +1,18 @@ +/* Do not edit this file. It was automatically generated. */ + +#ifndef HEADER_openzfs_sysctl +#define HEADER_openzfs_sysctl +/* +htop - zfs/openzfs_sysctl.h +(C) 2014 Hisham H. Muhammad +Released under the GNU GPL, see the COPYING file +in the source distribution for its full text. +*/ + +#include "zfs/ZfsArcStats.h" + +void openzfs_sysctl_init(ZfsArcStats *stats); + +void openzfs_sysctl_updateArcStats(ZfsArcStats *stats); + +#endif