diff options
Diffstat (limited to 'users/multi/pkgs/htop/zfs-arc-stats/0003-ZFS-arcstats-for-Linux.patch')
-rw-r--r-- | users/multi/pkgs/htop/zfs-arc-stats/0003-ZFS-arcstats-for-Linux.patch | 287 |
1 files changed, 287 insertions, 0 deletions
diff --git a/users/multi/pkgs/htop/zfs-arc-stats/0003-ZFS-arcstats-for-Linux.patch b/users/multi/pkgs/htop/zfs-arc-stats/0003-ZFS-arcstats-for-Linux.patch new file mode 100644 index 000000000000..f232f5e87db2 --- /dev/null +++ b/users/multi/pkgs/htop/zfs-arc-stats/0003-ZFS-arcstats-for-Linux.patch @@ -0,0 +1,287 @@ +From 070fe90461182743fabb029415fc1bc59be14f3f Mon Sep 17 00:00:00 2001 +From: Ross Williams <ross@ross-williams.net> +Date: Sun, 7 Jul 2019 02:37:02 +0000 +Subject: [PATCH 3/9] ZFS arcstats for Linux + +If no pools are imported (ARC size == 0) or the +ZFS module is not in the kernel (/proc/spl/kstat/zfs/arcstats +does not exist), then the Meter reports "Unavailable". +--- + Makefile.am | 6 ++-- + linux/LinuxProcessList.c | 66 ++++++++++++++++++++++++++++++++++++++++ + linux/LinuxProcessList.h | 13 ++++++++ + linux/Platform.c | 19 ++++++++++++ + linux/Platform.h | 2 ++ + zfs/ZfsArcMeter.c | 47 +++++++++++++++------------- + 6 files changed, 130 insertions(+), 23 deletions(-) + +diff --git a/Makefile.am b/Makefile.am +index ad23d19..b850815 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -52,14 +52,16 @@ linux_platform_headers = \ + linux/LinuxProcess.h \ + linux/LinuxProcessList.h \ + linux/LinuxCRT.h \ +- linux/Battery.h ++ linux/Battery.h \ ++ $(zfs_platform_headers) + + all_platform_headers += $(linux_platform_headers) + + if HTOP_LINUX + AM_CFLAGS += -rdynamic + myhtopplatsources = linux/Platform.c linux/IOPriorityPanel.c linux/IOPriority.c \ +-linux/LinuxProcess.c linux/LinuxProcessList.c linux/LinuxCRT.c linux/Battery.c ++linux/LinuxProcess.c linux/LinuxProcessList.c linux/LinuxCRT.c linux/Battery.c \ ++$(zfs_platform_sources) + + myhtopplatheaders = $(linux_platform_headers) + endif +diff --git a/linux/LinuxProcessList.c b/linux/LinuxProcessList.c +index 5f38540..4d19185 100644 +--- a/linux/LinuxProcessList.c ++++ b/linux/LinuxProcessList.c +@@ -94,6 +94,15 @@ typedef struct LinuxProcessList_ { + struct nl_sock *netlink_socket; + int netlink_family; + #endif ++ ++ int zfsArcEnabled; ++ unsigned long long int memZfsArc; ++ unsigned long long int zfsArcMax; ++ unsigned long long int zfsArcMFU; ++ unsigned long long int zfsArcMRU; ++ unsigned long long int zfsArcAnon; ++ unsigned long long int zfsArcHeader; ++ unsigned long long int zfsArcOther; + } LinuxProcessList; + + #ifndef PROCDIR +@@ -108,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 +@@ -964,6 +977,58 @@ 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->zfsArcEnabled = 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) ++ switch (buffer[0]) { ++ case 'c': ++ tryRead("c_max", &lpl->zfsArcMax); ++ break; ++ case 's': ++ tryRead("size", &lpl->memZfsArc); ++ break; ++ case 'h': ++ tryRead("hdr_size", &lpl->zfsArcHeader); ++ 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->zfsArcAnon); ++ break; ++ case 'm': ++ tryRead("mfu_size", &lpl->zfsArcMFU); ++ tryRead("mru_size", &lpl->zfsArcMRU); ++ break; ++ } ++ #undef tryRead ++ } ++ fclose(file); ++ ++ lpl->zfsArcEnabled = (lpl->memZfsArc > 0 ? 1 : 0); ++ lpl->memZfsArc /= 1024; ++ lpl->zfsArcMax /= 1024; ++ lpl->zfsArcMFU /= 1024; ++ lpl->zfsArcMRU /= 1024; ++ lpl->zfsArcAnon /= 1024; ++ lpl->zfsArcHeader /= 1024; ++ lpl->zfsArcOther = (dbufSize + dnodeSize + bonusSize) / 1024; ++} ++ + static inline double LinuxProcessList_scanCPUTime(LinuxProcessList* this) { + + FILE* file = fopen(PROCSTATFILE, "r"); +@@ -1038,6 +1103,7 @@ void ProcessList_goThroughEntries(ProcessList* super) { + LinuxProcessList* this = (LinuxProcessList*) super; + + LinuxProcessList_scanMemoryInfo(super); ++ LinuxProcessList_scanZfsArcstats(this); + double period = LinuxProcessList_scanCPUTime(this); + + struct timeval tv; +diff --git a/linux/LinuxProcessList.h b/linux/LinuxProcessList.h +index f30b487..749231e 100644 +--- a/linux/LinuxProcessList.h ++++ b/linux/LinuxProcessList.h +@@ -67,6 +67,15 @@ typedef struct LinuxProcessList_ { + struct nl_sock *netlink_socket; + int netlink_family; + #endif ++ ++ int zfsArcEnabled; ++ unsigned long long int memZfsArc; ++ unsigned long long int zfsArcMax; ++ unsigned long long int zfsArcMFU; ++ unsigned long long int zfsArcMRU; ++ unsigned long long int zfsArcAnon; ++ unsigned long long int zfsArcHeader; ++ unsigned long long int zfsArcOther; + } LinuxProcessList; + + #ifndef PROCDIR +@@ -81,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 ab90ca7..4e73c61 100644 +--- a/linux/Platform.c ++++ b/linux/Platform.c +@@ -21,6 +21,7 @@ in the source distribution for its full text. + #include "UptimeMeter.h" + #include "ClockMeter.h" + #include "HostnameMeter.h" ++#include "zfs/ZfsArcMeter.h" + #include "LinuxProcess.h" + + #include <math.h> +@@ -126,6 +127,7 @@ MeterClass* Platform_meterTypes[] = { + &LeftCPUs2Meter_class, + &RightCPUs2Meter_class, + &BlankMeter_class, ++ &ZfsArcMeter_class, + NULL + }; + +@@ -213,6 +215,23 @@ void Platform_setSwapValues(Meter* this) { + this->values[0] = pl->usedSwap; + } + ++void Platform_setZfsArcValues(Meter* this) { ++ LinuxProcessList* lpl = (LinuxProcessList*) this->pl; ++ ++ this->total = lpl->zfsArcMax; ++ this->values[0] = lpl->zfsArcMFU; ++ this->values[1] = lpl->zfsArcMRU; ++ this->values[2] = lpl->zfsArcAnon; ++ this->values[3] = lpl->zfsArcHeader; ++ this->values[4] = lpl->zfsArcOther; ++ ++ // "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] = lpl->memZfsArc; ++} ++ + 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 b0456e5..e775181 100644 +--- a/linux/Platform.h ++++ b/linux/Platform.h +@@ -43,6 +43,8 @@ void Platform_setMemoryValues(Meter* this); + + void Platform_setSwapValues(Meter* this); + ++void Platform_setZfsArcValues(Meter* this); ++ + char* Platform_getProcessEnv(pid_t pid); + + #endif +diff --git a/zfs/ZfsArcMeter.c b/zfs/ZfsArcMeter.c +index e12c46e..ebd8099 100644 +--- a/zfs/ZfsArcMeter.c ++++ b/zfs/ZfsArcMeter.c +@@ -41,27 +41,32 @@ static void ZfsArcMeter_display(Object* cast, RichString* out) { + char buffer[50]; + Meter* this = (Meter*)cast; + +- 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); ++ 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 = { +-- +2.20.1 + |