feat(users/multi): bootstrap home-manager configuration for whitby

Change-Id: Iad3024a5a640d33377cfae436134fda9f358397b
Reviewed-on: https://cl.tvl.fyi/c/depot/+/1703
Tested-by: BuildkiteCI
Reviewed-by: multi <depot@in-addr.xyz>
This commit is contained in:
multi 2020-08-09 23:24:43 +00:00
parent 5e58c8bc28
commit 5851f672ac
15 changed files with 3677 additions and 0 deletions

View file

@ -0,0 +1,6 @@
{ pkgs, ... }:
let
htop = import ./htop { inherit pkgs; };
in
[ htop ]

View file

@ -0,0 +1,33 @@
{ pkgs, ... }:
let
arcStats = [
./zfs-arc-stats/0001-Specify-correct-MIB-length.patch
./zfs-arc-stats/0002-Support-ZFS-ARC-stats-on-FreeBSD.patch
./zfs-arc-stats/0003-ZFS-arcstats-for-Linux.patch
./zfs-arc-stats/0004-ZFS-arcstats-for-Darwin-macOS-OS-X.patch
./zfs-arc-stats/0005-Refactor-common-OpenZFS-sysctl-access.patch
./zfs-arc-stats/0006-ZFS-arcstats-for-Solaris.patch
./zfs-arc-stats/0007-Refactor-openzfs_sysctl_init-and-ZfsArcMeter.patch
./zfs-arc-stats/0008-Support-for-ZFS-Compressed-ARC-statistics.patch
./zfs-arc-stats/0009-Linux-fixes.patch
];
arcCache = [
./zfs-arc-cache/0001-Linux-consider-ZFS-ARC-to-be-cache.patch
];
removeMousing = [
./remove-mousing/0001-Tear-out-ncurses-mouse-mode.patch
];
octoMeter = [
./octo-meter/0001-Add-quad-and-octo-meter-display-meters.patch
];
in
with pkgs; htop.overrideAttrs
({ patches ? [], nativeBuildInputs ? [], ... }:
{
patches = patches ++ arcStats ++ arcCache ++ removeMousing ++ octoMeter;
nativeBuildInputs = nativeBuildInputs ++ [ autoreconfHook ];
})

View file

@ -0,0 +1,497 @@
From c42ac9f33968c42c02b40a62b87b08b6f410f30b Mon Sep 17 00:00:00 2001
From: multiplexd <multi@in-addr.xyz>
Date: Mon, 10 Aug 2020 01:10:23 +0100
Subject: [PATCH] Add quad- and octo-meter display meters
---
CPUMeter.c | 230 ++++++++++++++++++++++++++++++++++++++--
CPUMeter.h | 12 +++
darwin/Platform.c | 6 ++
dragonflybsd/Platform.c | 6 ++
freebsd/Platform.c | 6 ++
linux/Platform.c | 6 ++
openbsd/Platform.c | 6 ++
solaris/Platform.c | 6 ++
unsupported/Platform.c | 6 ++
9 files changed, 277 insertions(+), 7 deletions(-)
diff --git a/CPUMeter.c b/CPUMeter.c
index de5490d..8d00b81 100644
--- a/CPUMeter.c
+++ b/CPUMeter.c
@@ -181,6 +181,107 @@ static void AllCPUsMeter_updateMode(Meter* this, int mode) {
this->h = h * count;
}
+static void OctoCPUsMeter_updateMode(Meter* this, int mode) {
+ Meter** meters = (Meter**) this->drawData;
+ this->mode = mode;
+ int h = Meter_modes[mode]->h;
+ int start, count;
+ AllCPUsMeter_getRange(this, &start, &count);
+ for (int i = 0; i < count; i++) {
+ Meter_setMode(meters[i], mode);
+ }
+ this->h = h * ((count+1) / 8);
+}
+
+static void OctoColCPUsMeter_draw(Meter* this, int x, int y, int w) {
+ Meter** meters = (Meter**) this->drawData;
+ int start, count;
+ int pad = this->pl->settings->headerMargin ? 2 : 0;
+ AllCPUsMeter_getRange(this, &start, &count);
+ int height = (count+1)/8;
+ int startY = y;
+ for (int i = 0; i < height; i++) {
+ meters[i]->draw(meters[i], x, y, (w-pad)/8);
+ y += meters[i]->h;
+ }
+ y = startY;
+ for (int i = height; i < (count+1)/4; i++) {
+ meters[i]->draw(meters[i], x+(w-1)/8+(pad/2), y, (w-pad)/8);
+ y += meters[i]->h;
+ }
+ y = startY;
+ for (int i = 2*height; i < (count+1)/4 + (count+1)/8; i++) {
+ meters[i]->draw(meters[i], x+(w-1)/4+(pad/2), y, (w-pad)/8);
+ y += meters[i]->h;
+ }
+ y = startY;
+ for (int i = 3*height; i < (count+1)/2; i++) {
+ meters[i]->draw(meters[i], x+3*(w-1)/8+(pad/2), y, (w-pad)/8);
+ y += meters[i]->h;
+ }
+ y = startY;
+
+ for (int i = 4*height; i < (count+1)/2 + (count+1)/8; i++) {
+ meters[i]->draw(meters[i], x+(w-1)/2+1+(pad/2), y, (w-pad)/8);
+ y += meters[i]->h;
+ }
+ y = startY;
+ for (int i = 5*height; i < (count+1)/2 + (count+1)/4; i++) {
+ meters[i]->draw(meters[i], x+5*(w-1)/8+1+(pad/2), y, (w-pad)/8);
+ y += meters[i]->h;
+ }
+ y = startY;
+ for (int i = 6*height; i < (count+1)/2 + (count+1)/4 + (count+1)/8; i++) {
+ meters[i]->draw(meters[i], x+3*(w-1)/4+1+(pad/2), y, (w-pad)/8);
+ y += meters[i]->h;
+ }
+ y = startY;
+ for (int i = 7*height; i < count; i++) {
+ meters[i]->draw(meters[i], x+7*(w-1)/8+1+(pad/2), y, (w-pad)/8);
+ y += meters[i]->h;
+ }
+}
+
+static void QuadCPUsMeter_updateMode(Meter* this, int mode) {
+ Meter** meters = (Meter**) this->drawData;
+ this->mode = mode;
+ int h = Meter_modes[mode]->h;
+ int start, count;
+ AllCPUsMeter_getRange(this, &start, &count);
+ for (int i = 0; i < count; i++) {
+ Meter_setMode(meters[i], mode);
+ }
+ this->h = h * ((count+1) / 4);
+}
+
+static void QuadColCPUsMeter_draw(Meter* this, int x, int y, int w) {
+ Meter** meters = (Meter**) this->drawData;
+ int start, count;
+ int pad = this->pl->settings->headerMargin ? 2 : 0;
+ AllCPUsMeter_getRange(this, &start, &count);
+ int height = (count+1)/4;
+ int startY = y;
+ for (int i = 0; i < height; i++) {
+ meters[i]->draw(meters[i], x, y, (w-pad)/4);
+ y += meters[i]->h;
+ }
+ y = startY;
+ for (int i = height; i < (count+1)/2; i++) {
+ meters[i]->draw(meters[i], x+(w-1)/4+(pad/2), y, (w-pad)/4);
+ y += meters[i]->h;
+ }
+ y = startY;
+ for (int i = 2*height; i < (count+1)/2 + (count+1)/4; i++) {
+ meters[i]->draw(meters[i], x+(w-1)/2+(pad/2), y, (w-pad)/4);
+ y += meters[i]->h;
+ }
+ y = startY;
+ for (int i = 3*height; i < count; i++) {
+ meters[i]->draw(meters[i], x+3*(w-1)/4+1+(pad/2), y, (w-pad)/4);
+ y += meters[i]->h;
+ }
+}
+
static void DualColCPUsMeter_draw(Meter* this, int x, int y, int w) {
Meter** meters = (Meter**) this->drawData;
int start, count;
@@ -219,7 +320,7 @@ MeterClass CPUMeter_class = {
.defaultMode = BAR_METERMODE,
.maxItems = CPU_METER_ITEMCOUNT,
.total = 100.0,
- .attributes = CPUMeter_attributes,
+ .attributes = CPUMeter_attributes,
.name = "CPU",
.uiName = "CPU",
.caption = "CPU",
@@ -234,7 +335,7 @@ MeterClass AllCPUsMeter_class = {
},
.defaultMode = CUSTOM_METERMODE,
.total = 100.0,
- .attributes = CPUMeter_attributes,
+ .attributes = CPUMeter_attributes,
.name = "AllCPUs",
.uiName = "CPUs (1/1)",
.description = "CPUs (1/1): all CPUs",
@@ -253,7 +354,7 @@ MeterClass AllCPUs2Meter_class = {
},
.defaultMode = CUSTOM_METERMODE,
.total = 100.0,
- .attributes = CPUMeter_attributes,
+ .attributes = CPUMeter_attributes,
.name = "AllCPUs2",
.uiName = "CPUs (1&2/2)",
.description = "CPUs (1&2/2): all CPUs in 2 shorter columns",
@@ -264,6 +365,44 @@ MeterClass AllCPUs2Meter_class = {
.done = AllCPUsMeter_done
};
+MeterClass AllCPUs4Meter_class = {
+ .super = {
+ .extends = Class(Meter),
+ .delete = Meter_delete,
+ .display = CPUMeter_display
+ },
+ .defaultMode = CUSTOM_METERMODE,
+ .total = 100.0,
+ .attributes = CPUMeter_attributes,
+ .name = "AllCPUs4",
+ .uiName = "CPUs (1-4/4)",
+ .description = "CPUs (1-4/4): all CPUs in 4 shorter columns",
+ .caption = "CPU",
+ .draw = QuadColCPUsMeter_draw,
+ .init = AllCPUsMeter_init,
+ .updateMode = QuadCPUsMeter_updateMode,
+ .done = AllCPUsMeter_done
+};
+
+MeterClass AllCPUs8Meter_class = {
+ .super = {
+ .extends = Class(Meter),
+ .delete = Meter_delete,
+ .display = CPUMeter_display
+ },
+ .defaultMode = CUSTOM_METERMODE,
+ .total = 100.0,
+ .attributes = CPUMeter_attributes,
+ .name = "AllCPUs8",
+ .uiName = "CPUs (1-8/8)",
+ .description = "CPUs (1-8/8): all CPUs in 8 shorter columns",
+ .caption = "CPU",
+ .draw = OctoColCPUsMeter_draw,
+ .init = AllCPUsMeter_init,
+ .updateMode = OctoCPUsMeter_updateMode,
+ .done = AllCPUsMeter_done
+};
+
MeterClass LeftCPUsMeter_class = {
.super = {
.extends = Class(Meter),
@@ -272,7 +411,7 @@ MeterClass LeftCPUsMeter_class = {
},
.defaultMode = CUSTOM_METERMODE,
.total = 100.0,
- .attributes = CPUMeter_attributes,
+ .attributes = CPUMeter_attributes,
.name = "LeftCPUs",
.uiName = "CPUs (1/2)",
.description = "CPUs (1/2): first half of list",
@@ -291,7 +430,7 @@ MeterClass RightCPUsMeter_class = {
},
.defaultMode = CUSTOM_METERMODE,
.total = 100.0,
- .attributes = CPUMeter_attributes,
+ .attributes = CPUMeter_attributes,
.name = "RightCPUs",
.uiName = "CPUs (2/2)",
.description = "CPUs (2/2): second half of list",
@@ -310,7 +449,7 @@ MeterClass LeftCPUs2Meter_class = {
},
.defaultMode = CUSTOM_METERMODE,
.total = 100.0,
- .attributes = CPUMeter_attributes,
+ .attributes = CPUMeter_attributes,
.name = "LeftCPUs2",
.uiName = "CPUs (1&2/4)",
.description = "CPUs (1&2/4): first half in 2 shorter columns",
@@ -329,7 +468,7 @@ MeterClass RightCPUs2Meter_class = {
},
.defaultMode = CUSTOM_METERMODE,
.total = 100.0,
- .attributes = CPUMeter_attributes,
+ .attributes = CPUMeter_attributes,
.name = "RightCPUs2",
.uiName = "CPUs (3&4/4)",
.description = "CPUs (3&4/4): second half in 2 shorter columns",
@@ -340,3 +479,80 @@ MeterClass RightCPUs2Meter_class = {
.done = AllCPUsMeter_done
};
+MeterClass LeftCPUs4Meter_class = {
+ .super = {
+ .extends = Class(Meter),
+ .delete = Meter_delete,
+ .display = CPUMeter_display
+ },
+ .defaultMode = CUSTOM_METERMODE,
+ .total = 100.0,
+ .attributes = CPUMeter_attributes,
+ .name = "LeftCPUs4",
+ .uiName = "CPUs (1-4/8)",
+ .description = "CPUs (1-4/8): first half in 4 shorter columns",
+ .caption = "CPU",
+ .draw = QuadColCPUsMeter_draw,
+ .init = AllCPUsMeter_init,
+ .updateMode = QuadCPUsMeter_updateMode,
+ .done = AllCPUsMeter_done
+};
+
+MeterClass RightCPUs4Meter_class = {
+ .super = {
+ .extends = Class(Meter),
+ .delete = Meter_delete,
+ .display = CPUMeter_display
+ },
+ .defaultMode = CUSTOM_METERMODE,
+ .total = 100.0,
+ .attributes = CPUMeter_attributes,
+ .name = "RightCPUs4",
+ .uiName = "CPUs (5-8/8)",
+ .description = "CPUs (5-8/8): second half in 4 shorter columns",
+ .caption = "CPU",
+ .draw = QuadColCPUsMeter_draw,
+ .init = AllCPUsMeter_init,
+ .updateMode = QuadCPUsMeter_updateMode,
+ .done = AllCPUsMeter_done
+};
+
+
+MeterClass LeftCPUs8Meter_class = {
+ .super = {
+ .extends = Class(Meter),
+ .delete = Meter_delete,
+ .display = CPUMeter_display
+ },
+ .defaultMode = CUSTOM_METERMODE,
+ .total = 100.0,
+ .attributes = CPUMeter_attributes,
+ .name = "LeftCPUs8",
+ .uiName = "CPUs (1-8/16)",
+ .description = "CPUs (1-8/16): first half in 8 shorter columns",
+ .caption = "CPU",
+ .draw = OctoColCPUsMeter_draw,
+ .init = AllCPUsMeter_init,
+ .updateMode = OctoCPUsMeter_updateMode,
+ .done = AllCPUsMeter_done
+};
+
+MeterClass RightCPUs8Meter_class = {
+ .super = {
+ .extends = Class(Meter),
+ .delete = Meter_delete,
+ .display = CPUMeter_display
+ },
+ .defaultMode = CUSTOM_METERMODE,
+ .total = 100.0,
+ .attributes = CPUMeter_attributes,
+ .name = "RightCPUs8",
+ .uiName = "CPUs (9-16/16)",
+ .description = "CPUs (9-16/16): second half in 8 shorter columns",
+ .caption = "CPU",
+ .draw = OctoColCPUsMeter_draw,
+ .init = AllCPUsMeter_init,
+ .updateMode = OctoCPUsMeter_updateMode,
+ .done = AllCPUsMeter_done
+};
+
diff --git a/CPUMeter.h b/CPUMeter.h
index 2f16396..e8aa176 100644
--- a/CPUMeter.h
+++ b/CPUMeter.h
@@ -39,6 +39,10 @@ extern MeterClass AllCPUsMeter_class;
extern MeterClass AllCPUs2Meter_class;
+extern MeterClass AllCPUs4Meter_class;
+
+extern MeterClass AllCPUs8Meter_class;
+
extern MeterClass LeftCPUsMeter_class;
extern MeterClass RightCPUsMeter_class;
@@ -47,5 +51,13 @@ extern MeterClass LeftCPUs2Meter_class;
extern MeterClass RightCPUs2Meter_class;
+extern MeterClass LeftCPUs4Meter_class;
+
+extern MeterClass RightCPUs4Meter_class;
+
+extern MeterClass LeftCPUs8Meter_class;
+
+extern MeterClass RightCPUs8Meter_class;
+
#endif
diff --git a/darwin/Platform.c b/darwin/Platform.c
index 286ff16..39929da 100644
--- a/darwin/Platform.c
+++ b/darwin/Platform.c
@@ -115,10 +115,16 @@ MeterClass* Platform_meterTypes[] = {
&UptimeMeter_class,
&AllCPUsMeter_class,
&AllCPUs2Meter_class,
+ &AllCPUs4Meter_class,
+ &AllCPUs8Meter_class,
&LeftCPUsMeter_class,
&RightCPUsMeter_class,
&LeftCPUs2Meter_class,
&RightCPUs2Meter_class,
+ &LeftCPUs4Meter_class,
+ &RightCPUs4Meter_class,
+ &LeftCPUs8Meter_class,
+ &RightCPUs8Meter_class,
&ZfsArcMeter_class,
&ZfsCompressedArcMeter_class,
&BlankMeter_class,
diff --git a/dragonflybsd/Platform.c b/dragonflybsd/Platform.c
index 370943d..7985949 100644
--- a/dragonflybsd/Platform.c
+++ b/dragonflybsd/Platform.c
@@ -100,10 +100,16 @@ MeterClass* Platform_meterTypes[] = {
&HostnameMeter_class,
&AllCPUsMeter_class,
&AllCPUs2Meter_class,
+ &AllCPUs4Meter_class,
+ &AllCPUs8Meter_class,
&LeftCPUsMeter_class,
&RightCPUsMeter_class,
&LeftCPUs2Meter_class,
&RightCPUs2Meter_class,
+ &LeftCPUs4Meter_class,
+ &RightCPUs4Meter_class,
+ &LeftCPUs8Meter_class,
+ &RightCPUs8Meter_class,
&BlankMeter_class,
NULL
};
diff --git a/freebsd/Platform.c b/freebsd/Platform.c
index 0986a3d..ed73673 100644
--- a/freebsd/Platform.c
+++ b/freebsd/Platform.c
@@ -101,10 +101,16 @@ MeterClass* Platform_meterTypes[] = {
&HostnameMeter_class,
&AllCPUsMeter_class,
&AllCPUs2Meter_class,
+ &AllCPUs4Meter_class,
+ &AllCPUs8Meter_class,
&LeftCPUsMeter_class,
&RightCPUsMeter_class,
&LeftCPUs2Meter_class,
&RightCPUs2Meter_class,
+ &LeftCPUs4Meter_class,
+ &RightCPUs4Meter_class,
+ &LeftCPUs8Meter_class,
+ &RightCPUs8Meter_class,
&BlankMeter_class,
&ZfsArcMeter_class,
&ZfsCompressedArcMeter_class,
diff --git a/linux/Platform.c b/linux/Platform.c
index f7088cf..1556b14 100644
--- a/linux/Platform.c
+++ b/linux/Platform.c
@@ -123,10 +123,16 @@ MeterClass* Platform_meterTypes[] = {
&HostnameMeter_class,
&AllCPUsMeter_class,
&AllCPUs2Meter_class,
+ &AllCPUs4Meter_class,
+ &AllCPUs8Meter_class,
&LeftCPUsMeter_class,
&RightCPUsMeter_class,
&LeftCPUs2Meter_class,
&RightCPUs2Meter_class,
+ &LeftCPUs4Meter_class,
+ &RightCPUs4Meter_class,
+ &LeftCPUs8Meter_class,
+ &RightCPUs8Meter_class,
&BlankMeter_class,
&ZfsArcMeter_class,
&ZfsCompressedArcMeter_class,
diff --git a/openbsd/Platform.c b/openbsd/Platform.c
index 4bb2e35..9604771 100644
--- a/openbsd/Platform.c
+++ b/openbsd/Platform.c
@@ -159,10 +159,16 @@ MeterClass* Platform_meterTypes[] = {
&HostnameMeter_class,
&AllCPUsMeter_class,
&AllCPUs2Meter_class,
+ &AllCPUs4Meter_class,
+ &AllCPUs8Meter_class,
&LeftCPUsMeter_class,
&RightCPUsMeter_class,
&LeftCPUs2Meter_class,
&RightCPUs2Meter_class,
+ &LeftCPUs4Meter_class,
+ &RightCPUs4Meter_class,
+ &LeftCPUs8Meter_class,
+ &RightCPUs8Meter_class,
&BlankMeter_class,
NULL
};
diff --git a/solaris/Platform.c b/solaris/Platform.c
index 7dcfe32..9d3b123 100644
--- a/solaris/Platform.c
+++ b/solaris/Platform.c
@@ -120,10 +120,16 @@ MeterClass* Platform_meterTypes[] = {
&UptimeMeter_class,
&AllCPUsMeter_class,
&AllCPUs2Meter_class,
+ &AllCPUs4Meter_class,
+ &AllCPUs8Meter_class,
&LeftCPUsMeter_class,
&RightCPUsMeter_class,
&LeftCPUs2Meter_class,
&RightCPUs2Meter_class,
+ &LeftCPUs4Meter_class,
+ &RightCPUs4Meter_class,
+ &LeftCPUs8Meter_class,
+ &RightCPUs8Meter_class,
&ZfsArcMeter_class,
&ZfsCompressedArcMeter_class,
&BlankMeter_class,
diff --git a/unsupported/Platform.c b/unsupported/Platform.c
index ba84419..8d60fed 100644
--- a/unsupported/Platform.c
+++ b/unsupported/Platform.c
@@ -73,10 +73,16 @@ MeterClass* Platform_meterTypes[] = {
&UptimeMeter_class,
&AllCPUsMeter_class,
&AllCPUs2Meter_class,
+ &AllCPUs4Meter_class,
+ &AllCPUs8Meter_class,
&LeftCPUsMeter_class,
&RightCPUsMeter_class,
&LeftCPUs2Meter_class,
&RightCPUs2Meter_class,
+ &LeftCPUs4Meter_class,
+ &RightCPUs4Meter_class,
+ &LeftCPUs8Meter_class,
+ &RightCPUs8Meter_class,
&BlankMeter_class,
NULL
};
--
2.20.1

View file

@ -0,0 +1,29 @@
From b9575370e6ab804bd9689b99b81b99e4e84116a3 Mon Sep 17 00:00:00 2001
From: multiplexd <multi@in-addr.xyz>
Date: Sun, 5 Jul 2020 14:12:03 +0100
Subject: [PATCH] Tear out ncurses mouse mode
---
CRT.c | 6 ------
1 file changed, 6 deletions(-)
diff --git a/CRT.c b/CRT.c
index ca9a10d..f6dd1e2 100644
--- a/CRT.c
+++ b/CRT.c
@@ -673,12 +673,6 @@ void CRT_init(int delay, int colorScheme) {
#endif
CRT_treeStrAscii;
-#if NCURSES_MOUSE_VERSION > 1
- mousemask(BUTTON1_RELEASED | BUTTON4_PRESSED | BUTTON5_PRESSED, NULL);
-#else
- mousemask(BUTTON1_RELEASED, NULL);
-#endif
-
}
void CRT_done() {
--
2.20.1

View file

@ -0,0 +1,119 @@
From d1dadae5674222a0134092b3313383e088deda89 Mon Sep 17 00:00:00 2001
From: multiplexd <multi@in-addr.xyz>
Date: Sat, 9 May 2020 20:13:09 +0100
Subject: [PATCH] Linux: consider ZFS ARC to be cache
---
ProcessList.c | 1 +
ProcessList.h | 1 +
linux/LinuxProcessList.c | 27 +++++++++++++++++++++++++++
linux/LinuxProcessList.h | 4 ++++
linux/Platform.c | 5 +++--
5 files changed, 36 insertions(+), 2 deletions(-)
diff --git a/ProcessList.c b/ProcessList.c
index 7482b03..7083957 100644
--- a/ProcessList.c
+++ b/ProcessList.c
@@ -67,6 +67,7 @@ typedef struct ProcessList_ {
unsigned long long int totalSwap;
unsigned long long int usedSwap;
unsigned long long int freeSwap;
+ unsigned long long int arcSize;
int cpuCount;
diff --git a/ProcessList.h b/ProcessList.h
index 572d484..65029f1 100644
--- a/ProcessList.h
+++ b/ProcessList.h
@@ -61,6 +61,7 @@ typedef struct ProcessList_ {
unsigned long long int totalSwap;
unsigned long long int usedSwap;
unsigned long long int freeSwap;
+ unsigned long long int arcSize;
int cpuCount;
diff --git a/linux/LinuxProcessList.c b/linux/LinuxProcessList.c
index 5f38540..507ebd2 100644
--- a/linux/LinuxProcessList.c
+++ b/linux/LinuxProcessList.c
@@ -104,6 +104,10 @@ typedef struct LinuxProcessList_ {
#define PROCSTATFILE PROCDIR "/stat"
#endif
+#ifndef ARCSTATFILE
+#define ARCSTATFILE PROCDIR "/spl/kstat/zfs/arcstats"
+#endif
+
#ifndef PROCMEMINFOFILE
#define PROCMEMINFOFILE PROCDIR "/meminfo"
#endif
@@ -962,6 +966,29 @@ static inline void LinuxProcessList_scanMemoryInfo(ProcessList* this) {
this->cachedMem = this->cachedMem + sreclaimable - shmem;
this->usedSwap = this->totalSwap - swapFree;
fclose(file);
+
+ file = fopen(ARCSTATFILE, "r");
+ if (file == NULL && errno != ENOENT) {
+ CRT_fatalError("Cannot open " ARCSTATFILE);
+ }
+
+ if (file != NULL) {
+ // skip the first two lines
+ fgets(buffer, sizeof buffer, file);
+ fgets(buffer, sizeof buffer, file);
+
+ unsigned long long int arcsize = 0;
+ while (fgets(buffer, sizeof buffer, file)) {
+ #define tryRead(label, variable) do { if (String_startsWith(buffer, label) && sscanf(buffer + strlen(label), " %*d %llu", variable)) { break; } } while(0)
+ if (buffer[0] == 's') tryRead("size", &arcsize);
+ }
+
+ this->arcSize = arcsize / 1024;
+
+ fclose(file);
+ } else {
+ this->arcSize = 0;
+ }
}
static inline double LinuxProcessList_scanCPUTime(LinuxProcessList* this) {
diff --git a/linux/LinuxProcessList.h b/linux/LinuxProcessList.h
index f30b487..8f2edbb 100644
--- a/linux/LinuxProcessList.h
+++ b/linux/LinuxProcessList.h
@@ -77,6 +77,10 @@ typedef struct LinuxProcessList_ {
#define PROCSTATFILE PROCDIR "/stat"
#endif
+#ifndef ARCSTATFILE
+#define ARCSTATFILE PROCDIR "/spl/kstat/zfs/arcstats"
+#endif
+
#ifndef PROCMEMINFOFILE
#define PROCMEMINFOFILE PROCDIR "/meminfo"
#endif
diff --git a/linux/Platform.c b/linux/Platform.c
index ab90ca7..fb78c4c 100644
--- a/linux/Platform.c
+++ b/linux/Platform.c
@@ -200,11 +200,12 @@ void Platform_setMemoryValues(Meter* this) {
long int usedMem = pl->usedMem;
long int buffersMem = pl->buffersMem;
long int cachedMem = pl->cachedMem;
- usedMem -= buffersMem + cachedMem;
+ long int arcSize = pl->arcSize;
+ usedMem -= buffersMem + cachedMem + arcSize;
this->total = pl->totalMem;
this->values[0] = usedMem;
this->values[1] = buffersMem;
- this->values[2] = cachedMem;
+ this->values[2] = cachedMem + arcSize;
}
void Platform_setSwapValues(Meter* this) {
--
2.20.1

View file

@ -0,0 +1,27 @@
From 92258e99e639795f4119a86a1c44d5015b29ffdc Mon Sep 17 00:00:00 2001
From: Ross Williams <ross@ross-williams.net>
Date: Sat, 6 Jul 2019 04:27:00 +0000
Subject: [PATCH 1/9] Specify correct MIB length
Could have resulted in a buffer overflow if the
FreeBSD kernel returned more bytes than expected.
---
freebsd/FreeBSDProcessList.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/freebsd/FreeBSDProcessList.c b/freebsd/FreeBSDProcessList.c
index 9fef324..26019b6 100644
--- a/freebsd/FreeBSDProcessList.c
+++ b/freebsd/FreeBSDProcessList.c
@@ -121,7 +121,7 @@ ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidWhiteList, ui
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);
+ len = 5; sysctlnametomib("kstat.zfs.misc.arcstats.size", MIB_kstat_zfs_misc_arcstats_size, &len);
fpl->zfsArcEnabled = 1;
} else {
fpl->zfsArcEnabled = 0;
--
2.20.1

View file

@ -0,0 +1,438 @@
From a93edde1a21e533472b5d443002032260b5bd066 Mon Sep 17 00:00:00 2001
From: Ross Williams <ross@ross-williams.net>
Date: Sat, 6 Jul 2019 04:27:49 +0000
Subject: [PATCH 2/9] Support ZFS ARC stats on FreeBSD
New meter displays same ARC stats as FreeBSD top(1).
Can be extended to other platforms that support ZFS.
Pulling kstat.zfs.misc.arcstats.c_max as the meter
total, so the meter has a meaningful value to work
up to.
The Text meter displays, first, the maximum
ARC size (Meter.total), then second, the total
ARC used, using the difference between Meter.maxItems
and Meter.curItems to "hide" the used value from the
Bar and Graph drawing functions by using an index
in Meter.values[] that is beyond curItems - 1, but
less than maxItems - 1.
---
CRT.c | 35 ++++++++++++++++
CRT.h | 5 +++
Makefile.am | 10 ++++-
freebsd/FreeBSDProcessList.c | 48 ++++++++++++++++++++-
freebsd/FreeBSDProcessList.h | 6 +++
freebsd/Platform.c | 19 +++++++++
freebsd/Platform.h | 2 +
zfs/ZfsArcMeter.c | 81 ++++++++++++++++++++++++++++++++++++
zfs/ZfsArcMeter.h | 18 ++++++++
9 files changed, 220 insertions(+), 4 deletions(-)
create mode 100644 zfs/ZfsArcMeter.c
create mode 100644 zfs/ZfsArcMeter.h
diff --git a/CRT.c b/CRT.c
index ca9a10d..b9017aa 100644
--- a/CRT.c
+++ b/CRT.c
@@ -128,6 +128,11 @@ typedef enum ColorElements_ {
CPU_SOFTIRQ,
CPU_STEAL,
CPU_GUEST,
+ ZFS_MFU,
+ ZFS_MRU,
+ ZFS_ANON,
+ ZFS_HEADER,
+ ZFS_OTHER,
LAST_COLORELEMENT
} ColorElements;
@@ -232,6 +237,11 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[CPU_SOFTIRQ] = ColorPair(Magenta,Black),
[CPU_STEAL] = ColorPair(Cyan,Black),
[CPU_GUEST] = ColorPair(Cyan,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),
},
[COLORSCHEME_MONOCHROME] = {
[RESET_COLOR] = A_NORMAL,
@@ -291,6 +301,11 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[CPU_SOFTIRQ] = A_BOLD,
[CPU_STEAL] = A_REVERSE,
[CPU_GUEST] = A_REVERSE,
+ [ZFS_MFU] = A_NORMAL,
+ [ZFS_MRU] = A_NORMAL,
+ [ZFS_ANON] = A_DIM,
+ [ZFS_HEADER] = A_BOLD,
+ [ZFS_OTHER] = A_DIM,
},
[COLORSCHEME_BLACKONWHITE] = {
[RESET_COLOR] = ColorPair(Black,White),
@@ -350,6 +365,11 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[CPU_SOFTIRQ] = ColorPair(Blue,White),
[CPU_STEAL] = ColorPair(Cyan,White),
[CPU_GUEST] = ColorPair(Cyan,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),
},
[COLORSCHEME_LIGHTTERMINAL] = {
[RESET_COLOR] = ColorPair(Black,Black),
@@ -409,6 +429,11 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[CPU_SOFTIRQ] = ColorPair(Blue,Black),
[CPU_STEAL] = ColorPair(Black,Black),
[CPU_GUEST] = 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),
},
[COLORSCHEME_MIDNIGHT] = {
[RESET_COLOR] = ColorPair(White,Blue),
@@ -468,6 +493,11 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[CPU_SOFTIRQ] = ColorPair(Black,Blue),
[CPU_STEAL] = ColorPair(White,Blue),
[CPU_GUEST] = 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),
},
[COLORSCHEME_BLACKNIGHT] = {
[RESET_COLOR] = ColorPair(Cyan,Black),
@@ -527,6 +557,11 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[CPU_SOFTIRQ] = ColorPair(Blue,Black),
[CPU_STEAL] = ColorPair(Cyan,Black),
[CPU_GUEST] = ColorPair(Cyan,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),
},
[COLORSCHEME_BROKENGRAY] = { 0 } // dynamically generated.
};
diff --git a/CRT.h b/CRT.h
index 933fe06..2275349 100644
--- a/CRT.h
+++ b/CRT.h
@@ -116,6 +116,11 @@ typedef enum ColorElements_ {
CPU_SOFTIRQ,
CPU_STEAL,
CPU_GUEST,
+ ZFS_MFU,
+ ZFS_MRU,
+ ZFS_ANON,
+ ZFS_HEADER,
+ ZFS_OTHER,
LAST_COLORELEMENT
} ColorElements;
diff --git a/Makefile.am b/Makefile.am
index 7d19600..ad23d19 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -36,6 +36,10 @@ TasksMeter.h UptimeMeter.h TraceScreen.h UsersTable.h Vector.h Process.h \
AffinityPanel.h HostnameMeter.h OpenFilesScreen.h Affinity.h IncSet.h Action.h \
EnvScreen.h InfoScreen.h XAlloc.h
+zfs_platform_sources = zfs/ZfsArcMeter.c
+
+zfs_platform_headers = zfs/ZfsArcMeter.h
+
all_platform_headers =
# Linux
@@ -68,13 +72,15 @@ freebsd_platform_headers = \
freebsd/FreeBSDProcessList.h \
freebsd/FreeBSDProcess.h \
freebsd/FreeBSDCRT.h \
- freebsd/Battery.h
+ freebsd/Battery.h \
+ $(zfs_platform_headers)
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_platform_sources)
myhtopplatheaders = $(freebsd_platform_headers)
endif
diff --git a/freebsd/FreeBSDProcessList.c b/freebsd/FreeBSDProcessList.c
index 26019b6..94cbaa1 100644
--- a/freebsd/FreeBSDProcessList.c
+++ b/freebsd/FreeBSDProcessList.c
@@ -53,6 +53,12 @@ typedef struct FreeBSDProcessList_ {
unsigned long long int memFree;
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;
CPUData* cpus;
@@ -81,6 +87,12 @@ 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_vfs_zfs_arc_max[3];
+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_kern_cp_time[2];
static int MIB_kern_cp_times[2];
@@ -123,6 +135,16 @@ ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidWhiteList, ui
NULL, 0) == 0 && fpl->memZfsArc != 0) {
len = 5; sysctlnametomib("kstat.zfs.misc.arcstats.size", MIB_kstat_zfs_misc_arcstats_size, &len);
fpl->zfsArcEnabled = 1;
+
+ len = 3;
+ sysctlnametomib("vfs.zfs.arc_max", MIB_vfs_zfs_arc_max, &len);
+
+ len = 5;
+ 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);
} else {
fpl->zfsArcEnabled = 0;
}
@@ -323,8 +345,30 @@ static inline void FreeBSDProcessList_scanMemoryInfo(ProcessList* pl) {
fpl->memZfsArc /= 1024;
fpl->memWire -= fpl->memZfsArc;
pl->cachedMem += fpl->memZfsArc;
- // maybe when we learn how to make custom memory meter
- // we could do custom arc breakdown?
+
+ len = sizeof(fpl->zfsArcMax);
+ sysctl(MIB_vfs_zfs_arc_max, 3, &(fpl->zfsArcMax), &len , NULL, 0);
+ fpl->zfsArcMax /= 1024;
+
+ len = sizeof(fpl->zfsArcMFU);
+ sysctl(MIB_kstat_zfs_misc_arcstats_mfu_size, 5, &(fpl->zfsArcMFU), &len , NULL, 0);
+ fpl->zfsArcMFU /= 1024;
+
+ len = sizeof(fpl->zfsArcMRU);
+ sysctl(MIB_kstat_zfs_misc_arcstats_mru_size, 5, &(fpl->zfsArcMRU), &len , NULL, 0);
+ fpl->zfsArcMRU /= 1024;
+
+ len = sizeof(fpl->zfsArcAnon);
+ sysctl(MIB_kstat_zfs_misc_arcstats_anon_size, 5, &(fpl->zfsArcAnon), &len , NULL, 0);
+ fpl->zfsArcAnon /= 1024;
+
+ len = sizeof(fpl->zfsArcHeader);
+ sysctl(MIB_kstat_zfs_misc_arcstats_hdr_size, 5, &(fpl->zfsArcHeader), &len , NULL, 0);
+ fpl->zfsArcHeader /= 1024;
+
+ len = sizeof(fpl->zfsArcOther);
+ sysctl(MIB_kstat_zfs_misc_arcstats_other_size, 5, &(fpl->zfsArcOther), &len , NULL, 0);
+ fpl->zfsArcOther /= 1024;
}
pl->usedMem = fpl->memActive + fpl->memWire;
diff --git a/freebsd/FreeBSDProcessList.h b/freebsd/FreeBSDProcessList.h
index af343fb..cf96a70 100644
--- a/freebsd/FreeBSDProcessList.h
+++ b/freebsd/FreeBSDProcessList.h
@@ -42,6 +42,12 @@ typedef struct FreeBSDProcessList_ {
unsigned long long int memFree;
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;
CPUData* cpus;
diff --git a/freebsd/Platform.c b/freebsd/Platform.c
index 5dd6ca4..d8d2ed0 100644
--- a/freebsd/Platform.c
+++ b/freebsd/Platform.c
@@ -15,6 +15,7 @@ in the source distribution for its full text.
#include "UptimeMeter.h"
#include "ClockMeter.h"
#include "HostnameMeter.h"
+#include "zfs/ZfsArcMeter.h"
#include "FreeBSDProcess.h"
#include "FreeBSDProcessList.h"
@@ -104,6 +105,7 @@ MeterClass* Platform_meterTypes[] = {
&LeftCPUs2Meter_class,
&RightCPUs2Meter_class,
&BlankMeter_class,
+ &ZfsArcMeter_class,
NULL
};
@@ -197,6 +199,23 @@ void Platform_setSwapValues(Meter* this) {
this->values[0] = pl->usedSwap;
}
+void Platform_setZfsArcValues(Meter* this) {
+ FreeBSDProcessList* fpl = (FreeBSDProcessList*) this->pl;
+
+ this->total = fpl->zfsArcMax;
+ this->values[0] = fpl->zfsArcMFU;
+ this->values[1] = fpl->zfsArcMRU;
+ this->values[2] = fpl->zfsArcAnon;
+ this->values[3] = fpl->zfsArcHeader;
+ this->values[4] = fpl->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] = fpl->memZfsArc;
+}
+
void Platform_setTasksValues(Meter* this) {
// TODO
}
diff --git a/freebsd/Platform.h b/freebsd/Platform.h
index 1735e7e..3dc7ebf 100644
--- a/freebsd/Platform.h
+++ b/freebsd/Platform.h
@@ -44,6 +44,8 @@ void Platform_setMemoryValues(Meter* this);
void Platform_setSwapValues(Meter* this);
+void Platform_setZfsArcValues(Meter* this);
+
void Platform_setTasksValues(Meter* this);
char* Platform_getProcessEnv(pid_t pid);
diff --git a/zfs/ZfsArcMeter.c b/zfs/ZfsArcMeter.c
new file mode 100644
index 0000000..e12c46e
--- /dev/null
+++ b/zfs/ZfsArcMeter.c
@@ -0,0 +1,81 @@
+/*
+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 "CRT.h"
+#include "Platform.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <sys/param.h>
+#include <assert.h>
+
+/*{
+#include "Meter.h"
+}*/
+
+int ZfsArcMeter_attributes[] = {
+ ZFS_MFU, ZFS_MRU, ZFS_ANON, ZFS_HEADER, ZFS_OTHER
+};
+
+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;
+
+ 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);
+}
+
+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 0000000..b89be22
--- /dev/null
+++ b/zfs/ZfsArcMeter.h
@@ -0,0 +1,18 @@
+/* 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 "Meter.h"
+
+extern int ZfsArcMeter_attributes[];
+
+extern MeterClass ZfsArcMeter_class;
+
+#endif
--
2.20.1

View file

@ -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

View file

@ -0,0 +1,260 @@
From fc8e9a2d3e25e35c0f9903baa345b1744b12b6cb Mon Sep 17 00:00:00 2001
From: Ross Williams <ross@ross-williams.net>
Date: Sun, 7 Jul 2019 17:30:37 -0400
Subject: [PATCH 4/9] ZFS arcstats for Darwin (macOS / OS X)
---
Makefile.am | 6 ++-
darwin/DarwinProcessList.c | 80 ++++++++++++++++++++++++++++++++++++++
darwin/DarwinProcessList.h | 21 ++++++++++
darwin/Platform.c | 19 +++++++++
darwin/Platform.h | 2 +
5 files changed, 126 insertions(+), 2 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index b850815..b6d2117 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -134,14 +134,16 @@ darwin_platform_headers = \
darwin/DarwinProcess.h \
darwin/DarwinProcessList.h \
darwin/DarwinCRT.h \
- darwin/Battery.h
+ darwin/Battery.h \
+ $(zfs_platform_headers)
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_platform_sources)
myhtopplatheaders = $(darwin_platform_headers)
endif
diff --git a/darwin/DarwinProcessList.c b/darwin/DarwinProcessList.c
index 0988448..267e8e9 100644
--- a/darwin/DarwinProcessList.c
+++ b/darwin/DarwinProcessList.c
@@ -54,6 +54,7 @@ int CompareKernelVersion(short int major, short int minor, short int component)
/*{
#include "ProcessList.h"
+#include "zfs/ZfsArcStats.h"
#include <mach/mach_host.h>
#include <sys/sysctl.h>
@@ -67,10 +68,28 @@ typedef struct DarwinProcessList_ {
uint64_t kernel_threads;
uint64_t user_threads;
uint64_t global_diff;
+
+ int zfsArcEnabled;
+ unsigned long long int zfsArcMax;
+ unsigned long long int zfsArcSize;
+ 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;
+
} DarwinProcessList;
}*/
+static int MIB_kstat_zfs_misc_arcstats_c_max[5];
+static int MIB_kstat_zfs_misc_arcstats_size[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];
+
void ProcessList_getHostInfo(host_basic_info_data_t *p) {
mach_msg_type_number_t info_size = HOST_BASIC_INFO_COUNT;
@@ -131,8 +150,50 @@ struct kinfo_proc *ProcessList_getKInfoProcs(size_t *count) {
return processes;
}
+static inline void DarwinProcessList_scanZfsArcstats(DarwinProcessList* dpl) {
+ size_t len;
+
+ if (dpl->zfsArcEnabled) {
+ len = sizeof(dpl->zfsArcSize);
+ sysctl(MIB_kstat_zfs_misc_arcstats_size, 5, &(dpl->zfsArcSize), &len , NULL, 0);
+ /* TODO: adjust reported memory in use to move ARC from wired to inactive
+ Like:
+ // In bytes
+ dpl->vm_stats.wire_count -= dpl->zfsArcSize / vm_page_size;
+ dpl->vm_stats.inactive_count += dpl->zfsArcSize / vm_page_size;
+ // Would purgable_count be more true?
+ // Then convert to KB:
+ */
+ dpl->zfsArcSize /= 1024;
+
+ len = sizeof(dpl->zfsArcMax);
+ sysctl(MIB_kstat_zfs_misc_arcstats_c_max, 5, &(dpl->zfsArcMax), &len , NULL, 0);
+ dpl->zfsArcMax /= 1024;
+
+ len = sizeof(dpl->zfsArcMFU);
+ sysctl(MIB_kstat_zfs_misc_arcstats_mfu_size, 5, &(dpl->zfsArcMFU), &len , NULL, 0);
+ dpl->zfsArcMFU /= 1024;
+
+ len = sizeof(dpl->zfsArcMRU);
+ sysctl(MIB_kstat_zfs_misc_arcstats_mru_size, 5, &(dpl->zfsArcMRU), &len , NULL, 0);
+ dpl->zfsArcMRU /= 1024;
+
+ len = sizeof(dpl->zfsArcAnon);
+ sysctl(MIB_kstat_zfs_misc_arcstats_anon_size, 5, &(dpl->zfsArcAnon), &len , NULL, 0);
+ dpl->zfsArcAnon /= 1024;
+
+ len = sizeof(dpl->zfsArcHeader);
+ sysctl(MIB_kstat_zfs_misc_arcstats_hdr_size, 5, &(dpl->zfsArcHeader), &len , NULL, 0);
+ dpl->zfsArcHeader /= 1024;
+
+ len = sizeof(dpl->zfsArcOther);
+ sysctl(MIB_kstat_zfs_misc_arcstats_other_size, 5, &(dpl->zfsArcOther), &len , NULL, 0);
+ dpl->zfsArcOther /= 1024;
+ }
+}
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 +206,24 @@ 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 */
+ len = sizeof(this->zfsArcSize);
+ if (sysctlbyname("kstat.zfs.misc.arcstats.size", &this->zfsArcSize, &len,
+ NULL, 0) == 0 && this->zfsArcSize != 0) {
+ this->zfsArcEnabled = 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);
+ } else {
+ this->zfsArcEnabled = 0;
+ }
+
this->super.kernelThreads = 0;
this->super.userlandThreads = 0;
this->super.totalTasks = 0;
@@ -173,6 +252,7 @@ void ProcessList_goThroughEntries(ProcessList* super) {
dpl->prev_load = dpl->curr_load;
ProcessList_allocateCPULoadInfo(&dpl->curr_load);
ProcessList_getVMStats(&dpl->vm_stats);
+ DarwinProcessList_scanZfsArcstats(dpl);
/* Get the time difference */
dpl->global_diff = 0;
diff --git a/darwin/DarwinProcessList.h b/darwin/DarwinProcessList.h
index c216a80..6686d05 100644
--- a/darwin/DarwinProcessList.h
+++ b/darwin/DarwinProcessList.h
@@ -9,6 +9,17 @@ 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 <mach/mach_host.h>
#include <sys/sysctl.h>
@@ -23,6 +34,16 @@ typedef struct DarwinProcessList_ {
uint64_t kernel_threads;
uint64_t user_threads;
uint64_t global_diff;
+
+ int zfsArcEnabled;
+ unsigned long long int zfsArcMax;
+ unsigned long long int zfsArcSize;
+ 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;
+
} DarwinProcessList;
diff --git a/darwin/Platform.c b/darwin/Platform.c
index 1dce8b6..52d60a9 100644
--- a/darwin/Platform.c
+++ b/darwin/Platform.c
@@ -15,6 +15,7 @@ in the source distribution for its full text.
#include "ClockMeter.h"
#include "HostnameMeter.h"
#include "UptimeMeter.h"
+#include "zfs/ZfsArcMeter.h"
#include "DarwinProcessList.h"
#include <stdlib.h>
@@ -117,6 +118,7 @@ MeterClass* Platform_meterTypes[] = {
&RightCPUsMeter_class,
&LeftCPUs2Meter_class,
&RightCPUs2Meter_class,
+ &ZfsArcMeter_class,
&BlankMeter_class,
NULL
};
@@ -241,6 +243,23 @@ void Platform_setSwapValues(Meter* mtr) {
mtr->values[0] = swapused.xsu_used / 1024;
}
+void Platform_setZfsArcValues(Meter* this) {
+ DarwinProcessList* dpl = (DarwinProcessList*) this->pl;
+
+ this->total = dpl->zfsArcMax;
+ this->values[0] = dpl->zfsArcMFU;
+ this->values[1] = dpl->zfsArcMRU;
+ this->values[2] = dpl->zfsArcAnon;
+ this->values[3] = dpl->zfsArcHeader;
+ this->values[4] = dpl->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] = dpl->zfsArcSize;
+}
+
char* Platform_getProcessEnv(pid_t pid) {
char* env = NULL;
diff --git a/darwin/Platform.h b/darwin/Platform.h
index 1231217..4acda2c 100644
--- a/darwin/Platform.h
+++ b/darwin/Platform.h
@@ -48,6 +48,8 @@ void Platform_setMemoryValues(Meter* mtr);
void Platform_setSwapValues(Meter* mtr);
+void Platform_setZfsArcValues(Meter* mtr);
+
char* Platform_getProcessEnv(pid_t pid);
#endif
--
2.20.1

View file

@ -0,0 +1,817 @@
From a88d2e313df7f5f2b781d5b14ffe0e7710018c10 Mon Sep 17 00:00:00 2001
From: Ross Williams <ross@ross-williams.net>
Date: Sun, 7 Jul 2019 23:27:00 +0000
Subject: [PATCH 5/9] Refactor common OpenZFS sysctl access
Darwin and FreeBSD export zfs kstats through the
same APIs, so moving functions into a common file.
---
Makefile.am | 21 ++++-----
darwin/DarwinProcessList.c | 82 +++---------------------------------
darwin/DarwinProcessList.h | 11 +----
darwin/Platform.c | 14 +++---
darwin/Platform.h | 2 +-
freebsd/FreeBSDProcessList.c | 77 +++++----------------------------
freebsd/FreeBSDProcessList.h | 14 ++----
freebsd/Platform.c | 14 +++---
linux/LinuxProcessList.c | 40 ++++++++----------
linux/LinuxProcessList.h | 10 +----
linux/Platform.c | 14 +++---
zfs/ZfsArcStats.c | 19 +++++++++
zfs/ZfsArcStats.h | 23 ++++++++++
zfs/openzfs_sysctl.c | 81 +++++++++++++++++++++++++++++++++++
zfs/openzfs_sysctl.h | 18 ++++++++
15 files changed, 216 insertions(+), 224 deletions(-)
create mode 100644 zfs/ZfsArcStats.c
create mode 100644 zfs/ZfsArcStats.h
create mode 100644 zfs/openzfs_sysctl.c
create mode 100644 zfs/openzfs_sysctl.h
diff --git a/Makefile.am b/Makefile.am
index b6d2117..5eee631 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -36,10 +36,6 @@ TasksMeter.h UptimeMeter.h TraceScreen.h UsersTable.h Vector.h Process.h \
AffinityPanel.h HostnameMeter.h OpenFilesScreen.h Affinity.h IncSet.h Action.h \
EnvScreen.h InfoScreen.h XAlloc.h
-zfs_platform_sources = zfs/ZfsArcMeter.c
-
-zfs_platform_headers = zfs/ZfsArcMeter.h
-
all_platform_headers =
# Linux
@@ -53,7 +49,8 @@ linux_platform_headers = \
linux/LinuxProcessList.h \
linux/LinuxCRT.h \
linux/Battery.h \
- $(zfs_platform_headers)
+ zfs/ZfsArcMeter.h \
+ zfs/ZfsArcStats.h
all_platform_headers += $(linux_platform_headers)
@@ -61,7 +58,7 @@ 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 \
-$(zfs_platform_sources)
+zfs/ZfsArcMeter.c zfs/ZfsArcStats.c
myhtopplatheaders = $(linux_platform_headers)
endif
@@ -75,14 +72,16 @@ freebsd_platform_headers = \
freebsd/FreeBSDProcess.h \
freebsd/FreeBSDCRT.h \
freebsd/Battery.h \
- $(zfs_platform_headers)
+ zfs/ZfsArcMeter.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 \
-$(zfs_platform_sources)
+zfs/ZfsArcMeter.c zfs/ZfsArcStats.c zfs/openzfs_sysctl.c
myhtopplatheaders = $(freebsd_platform_headers)
endif
@@ -135,7 +134,9 @@ darwin_platform_headers = \
darwin/DarwinProcessList.h \
darwin/DarwinCRT.h \
darwin/Battery.h \
- $(zfs_platform_headers)
+ zfs/ZfsArcMeter.h \
+ zfs/ZfsArcStats.h \
+ zfs/openzfs_sysctl.h
all_platform_headers += $(darwin_platform_headers)
@@ -143,7 +144,7 @@ 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 \
-$(zfs_platform_sources)
+zfs/ZfsArcMeter.c zfs/ZfsArcStats.c zfs/openzfs_sysctl.c
myhtopplatheaders = $(darwin_platform_headers)
endif
diff --git a/darwin/DarwinProcessList.c b/darwin/DarwinProcessList.c
index 267e8e9..122e018 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 <stdlib.h>
#include <string.h>
@@ -69,27 +71,11 @@ typedef struct DarwinProcessList_ {
uint64_t user_threads;
uint64_t global_diff;
- int zfsArcEnabled;
- unsigned long long int zfsArcMax;
- unsigned long long int zfsArcSize;
- 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;
-
+ ZfsArcStats zfs;
} DarwinProcessList;
}*/
-static int MIB_kstat_zfs_misc_arcstats_c_max[5];
-static int MIB_kstat_zfs_misc_arcstats_size[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];
-
void ProcessList_getHostInfo(host_basic_info_data_t *p) {
mach_msg_type_number_t info_size = HOST_BASIC_INFO_COUNT;
@@ -150,48 +136,6 @@ struct kinfo_proc *ProcessList_getKInfoProcs(size_t *count) {
return processes;
}
-static inline void DarwinProcessList_scanZfsArcstats(DarwinProcessList* dpl) {
- size_t len;
-
- if (dpl->zfsArcEnabled) {
- len = sizeof(dpl->zfsArcSize);
- sysctl(MIB_kstat_zfs_misc_arcstats_size, 5, &(dpl->zfsArcSize), &len , NULL, 0);
- /* TODO: adjust reported memory in use to move ARC from wired to inactive
- Like:
- // In bytes
- dpl->vm_stats.wire_count -= dpl->zfsArcSize / vm_page_size;
- dpl->vm_stats.inactive_count += dpl->zfsArcSize / vm_page_size;
- // Would purgable_count be more true?
- // Then convert to KB:
- */
- dpl->zfsArcSize /= 1024;
-
- len = sizeof(dpl->zfsArcMax);
- sysctl(MIB_kstat_zfs_misc_arcstats_c_max, 5, &(dpl->zfsArcMax), &len , NULL, 0);
- dpl->zfsArcMax /= 1024;
-
- len = sizeof(dpl->zfsArcMFU);
- sysctl(MIB_kstat_zfs_misc_arcstats_mfu_size, 5, &(dpl->zfsArcMFU), &len , NULL, 0);
- dpl->zfsArcMFU /= 1024;
-
- len = sizeof(dpl->zfsArcMRU);
- sysctl(MIB_kstat_zfs_misc_arcstats_mru_size, 5, &(dpl->zfsArcMRU), &len , NULL, 0);
- dpl->zfsArcMRU /= 1024;
-
- len = sizeof(dpl->zfsArcAnon);
- sysctl(MIB_kstat_zfs_misc_arcstats_anon_size, 5, &(dpl->zfsArcAnon), &len , NULL, 0);
- dpl->zfsArcAnon /= 1024;
-
- len = sizeof(dpl->zfsArcHeader);
- sysctl(MIB_kstat_zfs_misc_arcstats_hdr_size, 5, &(dpl->zfsArcHeader), &len , NULL, 0);
- dpl->zfsArcHeader /= 1024;
-
- len = sizeof(dpl->zfsArcOther);
- sysctl(MIB_kstat_zfs_misc_arcstats_other_size, 5, &(dpl->zfsArcOther), &len , NULL, 0);
- dpl->zfsArcOther /= 1024;
- }
-}
-
ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidWhiteList, uid_t userId) {
size_t len;
DarwinProcessList* this = xCalloc(1, sizeof(DarwinProcessList));
@@ -207,22 +151,8 @@ ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidWhiteList, ui
ProcessList_getVMStats(&this->vm_stats);
/* Initialize the ZFS kstats, if zfs.kext loaded */
- len = sizeof(this->zfsArcSize);
- if (sysctlbyname("kstat.zfs.misc.arcstats.size", &this->zfsArcSize, &len,
- NULL, 0) == 0 && this->zfsArcSize != 0) {
- this->zfsArcEnabled = 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);
- } else {
- this->zfsArcEnabled = 0;
- }
+ this->zfs.enabled = openzfs_sysctl_init();
+ openzfs_sysctl_updateArcStats(&this->zfs);
this->super.kernelThreads = 0;
this->super.userlandThreads = 0;
@@ -252,7 +182,7 @@ void ProcessList_goThroughEntries(ProcessList* super) {
dpl->prev_load = dpl->curr_load;
ProcessList_allocateCPULoadInfo(&dpl->curr_load);
ProcessList_getVMStats(&dpl->vm_stats);
- DarwinProcessList_scanZfsArcstats(dpl);
+ openzfs_sysctl_updateArcStats(&dpl->zfs);
/* Get the time difference */
dpl->global_diff = 0;
diff --git a/darwin/DarwinProcessList.h b/darwin/DarwinProcessList.h
index 6686d05..73fbd34 100644
--- a/darwin/DarwinProcessList.h
+++ b/darwin/DarwinProcessList.h
@@ -21,6 +21,7 @@ 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 <mach/mach_host.h>
#include <sys/sysctl.h>
@@ -35,15 +36,7 @@ typedef struct DarwinProcessList_ {
uint64_t user_threads;
uint64_t global_diff;
- int zfsArcEnabled;
- unsigned long long int zfsArcMax;
- unsigned long long int zfsArcSize;
- 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;
-
+ ZfsArcStats zfs;
} DarwinProcessList;
diff --git a/darwin/Platform.c b/darwin/Platform.c
index 52d60a9..8fbb9c9 100644
--- a/darwin/Platform.c
+++ b/darwin/Platform.c
@@ -246,18 +246,18 @@ void Platform_setSwapValues(Meter* mtr) {
void Platform_setZfsArcValues(Meter* this) {
DarwinProcessList* dpl = (DarwinProcessList*) this->pl;
- this->total = dpl->zfsArcMax;
- this->values[0] = dpl->zfsArcMFU;
- this->values[1] = dpl->zfsArcMRU;
- this->values[2] = dpl->zfsArcAnon;
- this->values[3] = dpl->zfsArcHeader;
- this->values[4] = dpl->zfsArcOther;
+ this->total = dpl->zfs.max;
+ this->values[0] = dpl->zfs.MFU;
+ this->values[1] = dpl->zfs.MRU;
+ this->values[2] = dpl->zfs.anon;
+ this->values[3] = dpl->zfs.header;
+ this->values[4] = dpl->zfs.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] = dpl->zfsArcSize;
+ this->values[5] = dpl->zfs.size;
}
char* Platform_getProcessEnv(pid_t pid) {
diff --git a/darwin/Platform.h b/darwin/Platform.h
index 4acda2c..f836077 100644
--- a/darwin/Platform.h
+++ b/darwin/Platform.h
@@ -48,7 +48,7 @@ void Platform_setMemoryValues(Meter* mtr);
void Platform_setSwapValues(Meter* mtr);
-void Platform_setZfsArcValues(Meter* mtr);
+void Platform_setZfsArcValues(Meter* this);
char* Platform_getProcessEnv(pid_t pid);
diff --git a/freebsd/FreeBSDProcessList.c b/freebsd/FreeBSDProcessList.c
index 94cbaa1..1cbfdaa 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 <unistd.h>
#include <stdlib.h>
@@ -21,6 +23,8 @@ in the source distribution for its full text.
/*{
+#include "zfs/ZfsArcStats.h"
+
#include <kvm.h>
#include <sys/param.h>
#include <sys/jail.h>
@@ -45,20 +49,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;
- 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;
+ ZfsArcStats zfs;
CPUData* cpus;
@@ -86,14 +82,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_vfs_zfs_arc_max[3];
-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_kern_cp_time[2];
static int MIB_kern_cp_times[2];
static int kernelFScale;
@@ -130,25 +118,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) {
- len = 5; sysctlnametomib("kstat.zfs.misc.arcstats.size", MIB_kstat_zfs_misc_arcstats_size, &len);
- fpl->zfsArcEnabled = 1;
-
- len = 3;
- sysctlnametomib("vfs.zfs.arc_max", MIB_vfs_zfs_arc_max, &len);
-
- len = 5;
- 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);
- } else {
- fpl->zfsArcEnabled = 0;
- }
-
+ fpl->zfs.enabled = openzfs_sysctl_init();
+ openzfs_sysctl_updateArcStats(&fpl->zfs);
int smp = 0;
len = sizeof(smp);
@@ -339,36 +310,9 @@ static inline void FreeBSDProcessList_scanMemoryInfo(ProcessList* pl) {
sysctl(MIB_vm_stats_vm_v_cache_count, 4, &(pl->cachedMem), &len, NULL, 0);
pl->cachedMem *= pageSizeKb;
- if (fpl->zfsArcEnabled) {
- len = sizeof(fpl->memZfsArc);
- sysctl(MIB_kstat_zfs_misc_arcstats_size, 5, &(fpl->memZfsArc), &len , NULL, 0);
- fpl->memZfsArc /= 1024;
- fpl->memWire -= fpl->memZfsArc;
- pl->cachedMem += fpl->memZfsArc;
-
- len = sizeof(fpl->zfsArcMax);
- sysctl(MIB_vfs_zfs_arc_max, 3, &(fpl->zfsArcMax), &len , NULL, 0);
- fpl->zfsArcMax /= 1024;
-
- len = sizeof(fpl->zfsArcMFU);
- sysctl(MIB_kstat_zfs_misc_arcstats_mfu_size, 5, &(fpl->zfsArcMFU), &len , NULL, 0);
- fpl->zfsArcMFU /= 1024;
-
- len = sizeof(fpl->zfsArcMRU);
- sysctl(MIB_kstat_zfs_misc_arcstats_mru_size, 5, &(fpl->zfsArcMRU), &len , NULL, 0);
- fpl->zfsArcMRU /= 1024;
-
- len = sizeof(fpl->zfsArcAnon);
- sysctl(MIB_kstat_zfs_misc_arcstats_anon_size, 5, &(fpl->zfsArcAnon), &len , NULL, 0);
- fpl->zfsArcAnon /= 1024;
-
- len = sizeof(fpl->zfsArcHeader);
- sysctl(MIB_kstat_zfs_misc_arcstats_hdr_size, 5, &(fpl->zfsArcHeader), &len , NULL, 0);
- fpl->zfsArcHeader /= 1024;
-
- len = sizeof(fpl->zfsArcOther);
- sysctl(MIB_kstat_zfs_misc_arcstats_other_size, 5, &(fpl->zfsArcOther), &len , NULL, 0);
- fpl->zfsArcOther /= 1024;
+ if (fpl->zfs.enabled) {
+ fpl->memWire -= fpl->zfs.size;
+ pl->cachedMem += fpl->zfs.size;
}
pl->usedMem = fpl->memActive + fpl->memWire;
@@ -466,6 +410,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 cf96a70..7c1b7ad 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 <kvm.h>
#include <sys/param.h>
#include <sys/jail.h>
@@ -34,20 +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;
-
- 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;
+
+ ZfsArcStats zfs;
CPUData* cpus;
diff --git a/freebsd/Platform.c b/freebsd/Platform.c
index d8d2ed0..05c0e92 100644
--- a/freebsd/Platform.c
+++ b/freebsd/Platform.c
@@ -202,18 +202,18 @@ void Platform_setSwapValues(Meter* this) {
void Platform_setZfsArcValues(Meter* this) {
FreeBSDProcessList* fpl = (FreeBSDProcessList*) this->pl;
- this->total = fpl->zfsArcMax;
- this->values[0] = fpl->zfsArcMFU;
- this->values[1] = fpl->zfsArcMRU;
- this->values[2] = fpl->zfsArcAnon;
- this->values[3] = fpl->zfsArcHeader;
- this->values[4] = fpl->zfsArcOther;
+ this->total = fpl->zfs.max;
+ this->values[0] = fpl->zfs.MFU;
+ this->values[1] = fpl->zfs.MRU;
+ this->values[2] = fpl->zfs.anon;
+ this->values[3] = fpl->zfs.header;
+ this->values[4] = fpl->zfs.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] = fpl->memZfsArc;
+ this->values[5] = fpl->zfs.size;
}
void Platform_setTasksValues(Meter* this) {
diff --git a/linux/LinuxProcessList.c b/linux/LinuxProcessList.c
index 4d19185..3e88910 100644
--- a/linux/LinuxProcessList.c
+++ b/linux/LinuxProcessList.c
@@ -46,6 +46,7 @@ in the source distribution for its full text.
/*{
#include "ProcessList.h"
+#include "zfs/ZfsArcStats.h"
extern long long btime;
@@ -95,14 +96,7 @@ typedef struct LinuxProcessList_ {
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;
+ ZfsArcStats zfs;
} LinuxProcessList;
#ifndef PROCDIR
@@ -984,7 +978,7 @@ static inline void LinuxProcessList_scanZfsArcstats(LinuxProcessList* lpl) {
FILE* file = fopen(PROCARCSTATSFILE, "r");
if (file == NULL) {
- lpl->zfsArcEnabled = 0;
+ lpl->zfs.enabled = 0;
return;
}
char buffer[128];
@@ -992,13 +986,13 @@ static inline void LinuxProcessList_scanZfsArcstats(LinuxProcessList* lpl) {
#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);
+ tryRead("c_max", &lpl->zfs.max);
break;
case 's':
- tryRead("size", &lpl->memZfsArc);
+ tryRead("size", &lpl->zfs.size);
break;
case 'h':
- tryRead("hdr_size", &lpl->zfsArcHeader);
+ tryRead("hdr_size", &lpl->zfs.header);
break;
case 'd':
tryRead("dbuf_size", &dbufSize);
@@ -1008,25 +1002,25 @@ static inline void LinuxProcessList_scanZfsArcstats(LinuxProcessList* lpl) {
tryRead("bonus_size", &bonusSize);
break;
case 'a':
- tryRead("anon_size", &lpl->zfsArcAnon);
+ tryRead("anon_size", &lpl->zfs.anon);
break;
case 'm':
- tryRead("mfu_size", &lpl->zfsArcMFU);
- tryRead("mru_size", &lpl->zfsArcMRU);
+ tryRead("mfu_size", &lpl->zfs.MFU);
+ tryRead("mru_size", &lpl->zfs.MRU);
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;
+ 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;
}
static inline double LinuxProcessList_scanCPUTime(LinuxProcessList* this) {
diff --git a/linux/LinuxProcessList.h b/linux/LinuxProcessList.h
index 749231e..353fe60 100644
--- a/linux/LinuxProcessList.h
+++ b/linux/LinuxProcessList.h
@@ -19,6 +19,7 @@ in the source distribution for its full text.
#include "ProcessList.h"
+#include "zfs/ZfsArcStats.h"
extern long long btime;
@@ -68,14 +69,7 @@ typedef struct LinuxProcessList_ {
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;
+ ZfsArcStats zfs;
} LinuxProcessList;
#ifndef PROCDIR
diff --git a/linux/Platform.c b/linux/Platform.c
index 4e73c61..e2a3c6d 100644
--- a/linux/Platform.c
+++ b/linux/Platform.c
@@ -218,18 +218,18 @@ void Platform_setSwapValues(Meter* this) {
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;
+ this->total = lpl->zfs.max;
+ this->values[0] = lpl->zfs.MFU;
+ this->values[1] = lpl->zfs.MRU;
+ this->values[2] = lpl->zfs.anon;
+ this->values[3] = lpl->zfs.header;
+ this->values[4] = lpl->zfs.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] = lpl->memZfsArc;
+ this->values[5] = lpl->zfs.size;
}
char* Platform_getProcessEnv(pid_t pid) {
diff --git a/zfs/ZfsArcStats.c b/zfs/ZfsArcStats.c
new file mode 100644
index 0000000..c33076a
--- /dev/null
+++ b/zfs/ZfsArcStats.c
@@ -0,0 +1,19 @@
+/*
+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;
+ 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;
+} ZfsArcStats;
+}*/
diff --git a/zfs/ZfsArcStats.h b/zfs/ZfsArcStats.h
new file mode 100644
index 0000000..3697af2
--- /dev/null
+++ b/zfs/ZfsArcStats.h
@@ -0,0 +1,23 @@
+/* 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;
+ 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;
+} ZfsArcStats;
+
+#endif
diff --git a/zfs/openzfs_sysctl.c b/zfs/openzfs_sysctl.c
new file mode 100644
index 0000000..ce48f23
--- /dev/null
+++ b/zfs/openzfs_sysctl.c
@@ -0,0 +1,81 @@
+/*
+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 <unistd.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/sysctl.h>
+
+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];
+
+/*{
+#include "zfs/ZfsArcStats.h"
+}*/
+
+int openzfs_sysctl_init() {
+ 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) {
+ 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);
+ return 1;
+ } else {
+ return 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;
+ }
+}
diff --git a/zfs/openzfs_sysctl.h b/zfs/openzfs_sysctl.h
new file mode 100644
index 0000000..7c04bd7
--- /dev/null
+++ b/zfs/openzfs_sysctl.h
@@ -0,0 +1,18 @@
+/* Do not edit this file. It was automatically generated. */
+
+#ifndef HEADER_openzfs
+#define HEADER_openzfs
+/*
+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"
+
+int openzfs_sysctl_init();
+
+void openzfs_sysctl_updateArcStats(ZfsArcStats *stats);
+
+#endif
--
2.20.1

View file

@ -0,0 +1,187 @@
From ff6914e4ad4b78749bcee5471a33ef206b0a7d03 Mon Sep 17 00:00:00 2001
From: Ross Williams <ross@ross-williams.net>
Date: Mon, 8 Jul 2019 02:43:39 +0000
Subject: [PATCH 6/9] ZFS arcstats for Solaris
---
Makefile.am | 7 +++++--
solaris/Platform.c | 19 ++++++++++++++++++
solaris/Platform.h | 2 ++
solaris/SolarisProcessList.c | 37 ++++++++++++++++++++++++++++++++++++
solaris/SolarisProcessList.h | 3 +++
5 files changed, 66 insertions(+), 2 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index 5eee631..204a8b7 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -157,14 +157,17 @@ solaris_platform_headers = \
solaris/SolarisProcess.h \
solaris/SolarisProcessList.h \
solaris/SolarisCRT.h \
- solaris/Battery.h
+ solaris/Battery.h \
+ zfs/ZfsArcMeter.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/ZfsArcStats.c
myhtopplatheaders = $(solaris_platform_headers)
endif
diff --git a/solaris/Platform.c b/solaris/Platform.c
index a29fcb4..8084d1f 100644
--- a/solaris/Platform.c
+++ b/solaris/Platform.c
@@ -17,6 +17,7 @@ in the source distribution for its full text.
#include "ClockMeter.h"
#include "HostnameMeter.h"
#include "UptimeMeter.h"
+#include "zfs/ZfsArcMeter.h"
#include "SolarisProcess.h"
#include "SolarisProcessList.h"
@@ -122,6 +123,7 @@ MeterClass* Platform_meterTypes[] = {
&RightCPUsMeter_class,
&LeftCPUs2Meter_class,
&RightCPUs2Meter_class,
+ &ZfsArcMeter_class,
&BlankMeter_class,
NULL
};
@@ -220,6 +222,23 @@ void Platform_setSwapValues(Meter* this) {
this->values[0] = pl->usedSwap;
}
+void Platform_setZfsArcValues(Meter* this) {
+ SolarisProcessList* spl = (SolarisProcessList*) this->pl;
+
+ this->total = spl->zfs.max;
+ this->values[0] = spl->zfs.MFU;
+ this->values[1] = spl->zfs.MRU;
+ this->values[2] = spl->zfs.anon;
+ this->values[3] = spl->zfs.header;
+ this->values[4] = spl->zfs.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] = spl->zfs.size;
+}
+
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 f961b91..62757ff 100644
--- a/solaris/Platform.h
+++ b/solaris/Platform.h
@@ -60,6 +60,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/solaris/SolarisProcessList.c b/solaris/SolarisProcessList.c
index 2c68185..b6bc6f5 100644
--- a/solaris/SolarisProcessList.c
+++ b/solaris/SolarisProcessList.c
@@ -27,6 +27,8 @@ in the source distribution for its full text.
/*{
+#include "zfs/ZfsArcStats.h"
+
#include <kstat.h>
#include <sys/param.h>
#include <sys/uio.h>
@@ -55,6 +57,7 @@ typedef struct SolarisProcessList_ {
ProcessList super;
kstat_ctl_t* kd;
CPUData* cpus;
+ ZfsArcStats zfs;
} SolarisProcessList;
}*/
@@ -230,6 +233,39 @@ 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;
+ }
+}
+
void ProcessList_delete(ProcessList* pl) {
SolarisProcessList* spl = (SolarisProcessList*) pl;
ProcessList_done(pl);
@@ -367,6 +403,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 a5f2fbc..26bf449 100644
--- a/solaris/SolarisProcessList.h
+++ b/solaris/SolarisProcessList.h
@@ -13,6 +13,8 @@ in the source distribution for its full text.
#define MAXCMDLINE 255
+#include "zfs/ZfsArcStats.h"
+
#include <kstat.h>
#include <sys/param.h>
#include <sys/uio.h>
@@ -41,6 +43,7 @@ typedef struct SolarisProcessList_ {
ProcessList super;
kstat_ctl_t* kd;
CPUData* cpus;
+ ZfsArcStats zfs;
} SolarisProcessList;
--
2.20.1

View file

@ -0,0 +1,267 @@
From e450b586368750e771746ef3e2f5a070962dfd28 Mon Sep 17 00:00:00 2001
From: Ross Williams <ross@ross-williams.net>
Date: Tue, 3 Sep 2019 18:21:33 +0000
Subject: [PATCH 7/9] Refactor openzfs_sysctl_init() and ZfsArcMeter...
openzfs_sysctl_init() now returns void instead of int.
The ZfsArcStats->enabled flag is set inside the init function
now, instead of having to be set from its return value.
Preparation for more flag setting in Compressed ARC commit.
ZfsArcMeter_readStats() added and all Meter->values[] setting
moved to it, eliminating duplicated code in
{darwin,freebsd,linux,solaris}/Platform.c.
---
darwin/DarwinProcessList.c | 2 +-
darwin/Platform.c | 13 +------------
freebsd/FreeBSDProcessList.c | 2 +-
freebsd/Platform.c | 13 +------------
linux/Platform.c | 13 +------------
solaris/Platform.c | 13 +------------
zfs/ZfsArcMeter.c | 18 ++++++++++++++++++
zfs/ZfsArcMeter.h | 4 ++++
zfs/openzfs_sysctl.c | 6 +++---
zfs/openzfs_sysctl.h | 6 +++---
10 files changed, 34 insertions(+), 56 deletions(-)
diff --git a/darwin/DarwinProcessList.c b/darwin/DarwinProcessList.c
index 122e018..9b4ba11 100644
--- a/darwin/DarwinProcessList.c
+++ b/darwin/DarwinProcessList.c
@@ -151,7 +151,7 @@ ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidWhiteList, ui
ProcessList_getVMStats(&this->vm_stats);
/* Initialize the ZFS kstats, if zfs.kext loaded */
- this->zfs.enabled = openzfs_sysctl_init();
+ openzfs_sysctl_init(&this->zfs);
openzfs_sysctl_updateArcStats(&this->zfs);
this->super.kernelThreads = 0;
diff --git a/darwin/Platform.c b/darwin/Platform.c
index 8fbb9c9..f9f09b5 100644
--- a/darwin/Platform.c
+++ b/darwin/Platform.c
@@ -246,18 +246,7 @@ void Platform_setSwapValues(Meter* mtr) {
void Platform_setZfsArcValues(Meter* this) {
DarwinProcessList* dpl = (DarwinProcessList*) this->pl;
- this->total = dpl->zfs.max;
- this->values[0] = dpl->zfs.MFU;
- this->values[1] = dpl->zfs.MRU;
- this->values[2] = dpl->zfs.anon;
- this->values[3] = dpl->zfs.header;
- this->values[4] = dpl->zfs.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] = dpl->zfs.size;
+ ZfsArcMeter_readStats(this, &(dpl->zfs));
}
char* Platform_getProcessEnv(pid_t pid) {
diff --git a/freebsd/FreeBSDProcessList.c b/freebsd/FreeBSDProcessList.c
index 1cbfdaa..fd69419 100644
--- a/freebsd/FreeBSDProcessList.c
+++ b/freebsd/FreeBSDProcessList.c
@@ -118,7 +118,7 @@ ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidWhiteList, ui
len = 2; sysctlnametomib("vfs.bufspace", MIB_vfs_bufspace, &len);
- fpl->zfs.enabled = openzfs_sysctl_init();
+ openzfs_sysctl_init(&fpl->zfs);
openzfs_sysctl_updateArcStats(&fpl->zfs);
int smp = 0;
diff --git a/freebsd/Platform.c b/freebsd/Platform.c
index 05c0e92..b08a508 100644
--- a/freebsd/Platform.c
+++ b/freebsd/Platform.c
@@ -202,18 +202,7 @@ void Platform_setSwapValues(Meter* this) {
void Platform_setZfsArcValues(Meter* this) {
FreeBSDProcessList* fpl = (FreeBSDProcessList*) this->pl;
- this->total = fpl->zfs.max;
- this->values[0] = fpl->zfs.MFU;
- this->values[1] = fpl->zfs.MRU;
- this->values[2] = fpl->zfs.anon;
- this->values[3] = fpl->zfs.header;
- this->values[4] = fpl->zfs.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] = fpl->zfs.size;
+ ZfsArcMeter_readStats(this, &(fpl->zfs));
}
void Platform_setTasksValues(Meter* this) {
diff --git a/linux/Platform.c b/linux/Platform.c
index e2a3c6d..69f6688 100644
--- a/linux/Platform.c
+++ b/linux/Platform.c
@@ -218,18 +218,7 @@ void Platform_setSwapValues(Meter* this) {
void Platform_setZfsArcValues(Meter* this) {
LinuxProcessList* lpl = (LinuxProcessList*) this->pl;
- this->total = lpl->zfs.max;
- this->values[0] = lpl->zfs.MFU;
- this->values[1] = lpl->zfs.MRU;
- this->values[2] = lpl->zfs.anon;
- this->values[3] = lpl->zfs.header;
- this->values[4] = lpl->zfs.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] = lpl->zfs.size;
+ ZfsArcMeter_readStats(this, &(lpl->zfs));
}
char* Platform_getProcessEnv(pid_t pid) {
diff --git a/solaris/Platform.c b/solaris/Platform.c
index 8084d1f..74ae14e 100644
--- a/solaris/Platform.c
+++ b/solaris/Platform.c
@@ -225,18 +225,7 @@ void Platform_setSwapValues(Meter* this) {
void Platform_setZfsArcValues(Meter* this) {
SolarisProcessList* spl = (SolarisProcessList*) this->pl;
- this->total = spl->zfs.max;
- this->values[0] = spl->zfs.MFU;
- this->values[1] = spl->zfs.MRU;
- this->values[2] = spl->zfs.anon;
- this->values[3] = spl->zfs.header;
- this->values[4] = spl->zfs.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] = spl->zfs.size;
+ ZfsArcMeter_readStats(this, &(spl->zfs));
}
static int Platform_buildenv(void *accum, struct ps_prochandle *Phandle, uintptr_t addr, const char *str) {
diff --git a/zfs/ZfsArcMeter.c b/zfs/ZfsArcMeter.c
index ebd8099..9f7028b 100644
--- a/zfs/ZfsArcMeter.c
+++ b/zfs/ZfsArcMeter.c
@@ -6,6 +6,7 @@ in the source distribution for its full text.
*/
#include "ZfsArcMeter.h"
+#include "ZfsArcStats.h"
#include "CRT.h"
#include "Platform.h"
@@ -17,6 +18,8 @@ in the source distribution for its full text.
#include <assert.h>
/*{
+#include "ZfsArcStats.h"
+
#include "Meter.h"
}*/
@@ -24,6 +27,21 @@ 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);
diff --git a/zfs/ZfsArcMeter.h b/zfs/ZfsArcMeter.h
index b89be22..c52083d 100644
--- a/zfs/ZfsArcMeter.h
+++ b/zfs/ZfsArcMeter.h
@@ -9,10 +9,14 @@ 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/openzfs_sysctl.c b/zfs/openzfs_sysctl.c
index ce48f23..ceee4d1 100644
--- a/zfs/openzfs_sysctl.c
+++ b/zfs/openzfs_sysctl.c
@@ -25,13 +25,14 @@ static int MIB_kstat_zfs_misc_arcstats_other_size[5];
#include "zfs/ZfsArcStats.h"
}*/
-int openzfs_sysctl_init() {
+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);
@@ -40,9 +41,8 @@ int openzfs_sysctl_init() {
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);
- return 1;
} else {
- return 0;
+ stats->enabled = 0;
}
}
diff --git a/zfs/openzfs_sysctl.h b/zfs/openzfs_sysctl.h
index 7c04bd7..6e44ac3 100644
--- a/zfs/openzfs_sysctl.h
+++ b/zfs/openzfs_sysctl.h
@@ -1,7 +1,7 @@
/* Do not edit this file. It was automatically generated. */
-#ifndef HEADER_openzfs
-#define HEADER_openzfs
+#ifndef HEADER_openzfs_sysctl
+#define HEADER_openzfs_sysctl
/*
htop - zfs/openzfs_sysctl.h
(C) 2014 Hisham H. Muhammad
@@ -11,7 +11,7 @@ in the source distribution for its full text.
#include "zfs/ZfsArcStats.h"
-int openzfs_sysctl_init();
+void openzfs_sysctl_init(ZfsArcStats *stats);
void openzfs_sysctl_updateArcStats(ZfsArcStats *stats);
--
2.20.1

View file

@ -0,0 +1,628 @@
From 613556faebd16325da8c9057c81f39a2410d803f Mon Sep 17 00:00:00 2001
From: Ross Williams <ross@ross-williams.net>
Date: Tue, 3 Sep 2019 18:26:02 +0000
Subject: [PATCH 8/9] Support for ZFS Compressed ARC statistics
---
CRT.c | 14 ++++++
CRT.h | 2 +
Makefile.am | 12 +++--
darwin/Platform.c | 8 ++++
darwin/Platform.h | 2 +
freebsd/Platform.c | 8 ++++
freebsd/Platform.h | 2 +
linux/LinuxProcessList.c | 10 +++++
linux/Platform.c | 7 +++
linux/Platform.h | 2 +
solaris/Platform.c | 8 ++++
solaris/Platform.h | 2 +
solaris/SolarisProcessList.c | 10 +++++
zfs/ZfsArcStats.c | 3 ++
zfs/ZfsArcStats.h | 3 ++
zfs/ZfsCompressedArcMeter.c | 86 ++++++++++++++++++++++++++++++++++++
zfs/ZfsCompressedArcMeter.h | 22 +++++++++
zfs/openzfs_sysctl.c | 18 ++++++++
18 files changed, 215 insertions(+), 4 deletions(-)
create mode 100644 zfs/ZfsCompressedArcMeter.c
create mode 100644 zfs/ZfsCompressedArcMeter.h
diff --git a/CRT.c b/CRT.c
index b9017aa..cb36b6c 100644
--- a/CRT.c
+++ b/CRT.c
@@ -133,6 +133,8 @@ typedef enum ColorElements_ {
ZFS_ANON,
ZFS_HEADER,
ZFS_OTHER,
+ ZFS_COMPRESSED,
+ ZFS_RATIO,
LAST_COLORELEMENT
} ColorElements;
@@ -242,6 +244,8 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[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,
@@ -306,6 +310,8 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[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),
@@ -370,6 +376,8 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[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),
@@ -434,6 +442,8 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[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),
@@ -498,6 +508,8 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[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),
@@ -562,6 +574,8 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[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 2275349..d9eba55 100644
--- a/CRT.h
+++ b/CRT.h
@@ -121,6 +121,8 @@ typedef enum ColorElements_ {
ZFS_ANON,
ZFS_HEADER,
ZFS_OTHER,
+ ZFS_COMPRESSED,
+ ZFS_RATIO,
LAST_COLORELEMENT
} ColorElements;
diff --git a/Makefile.am b/Makefile.am
index 204a8b7..2d159f0 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -50,6 +50,7 @@ linux_platform_headers = \
linux/LinuxCRT.h \
linux/Battery.h \
zfs/ZfsArcMeter.h \
+ zfs/ZfsCompressedArcMeter.h \
zfs/ZfsArcStats.h
all_platform_headers += $(linux_platform_headers)
@@ -58,7 +59,7 @@ 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 \
-zfs/ZfsArcMeter.c zfs/ZfsArcStats.c
+zfs/ZfsArcMeter.c zfs/ZfsCompressedArcMeter.c zfs/ZfsArcStats.c
myhtopplatheaders = $(linux_platform_headers)
endif
@@ -73,6 +74,7 @@ freebsd_platform_headers = \
freebsd/FreeBSDCRT.h \
freebsd/Battery.h \
zfs/ZfsArcMeter.h \
+ zfs/ZfsCompressedArcMeter.h \
zfs/ZfsArcStats.h \
zfs/openzfs_sysctl.h
@@ -81,7 +83,7 @@ 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 \
-zfs/ZfsArcMeter.c zfs/ZfsArcStats.c zfs/openzfs_sysctl.c
+zfs/ZfsArcMeter.c zfs/ZfsCompressedArcMeter.c zfs/ZfsArcStats.c zfs/openzfs_sysctl.c
myhtopplatheaders = $(freebsd_platform_headers)
endif
@@ -135,6 +137,7 @@ darwin_platform_headers = \
darwin/DarwinCRT.h \
darwin/Battery.h \
zfs/ZfsArcMeter.h \
+ zfs/ZfsCompressedArcMeter.h \
zfs/ZfsArcStats.h \
zfs/openzfs_sysctl.h
@@ -144,7 +147,7 @@ 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 \
-zfs/ZfsArcMeter.c zfs/ZfsArcStats.c zfs/openzfs_sysctl.c
+zfs/ZfsArcMeter.c zfs/ZfsCompressedArcMeter.c zfs/ZfsArcStats.c zfs/openzfs_sysctl.c
myhtopplatheaders = $(darwin_platform_headers)
endif
@@ -159,6 +162,7 @@ solaris_platform_headers = \
solaris/SolarisCRT.h \
solaris/Battery.h \
zfs/ZfsArcMeter.h \
+ zfs/ZfsCompressedArcMeter.h \
zfs/ZfsArcStats.h
all_platform_headers += $(solaris_platform_headers)
@@ -167,7 +171,7 @@ if HTOP_SOLARIS
myhtopplatsources = solaris/Platform.c \
solaris/SolarisProcess.c solaris/SolarisProcessList.c \
solaris/SolarisCRT.c solaris/Battery.c \
-zfs/ZfsArcMeter.c zfs/ZfsArcStats.c
+zfs/ZfsArcMeter.c zfs/ZfsCompressedArcMeter.c zfs/ZfsArcStats.c
myhtopplatheaders = $(solaris_platform_headers)
endif
diff --git a/darwin/Platform.c b/darwin/Platform.c
index f9f09b5..286ff16 100644
--- a/darwin/Platform.c
+++ b/darwin/Platform.c
@@ -16,6 +16,7 @@ in the source distribution for its full text.
#include "HostnameMeter.h"
#include "UptimeMeter.h"
#include "zfs/ZfsArcMeter.h"
+#include "zfs/ZfsCompressedArcMeter.h"
#include "DarwinProcessList.h"
#include <stdlib.h>
@@ -119,6 +120,7 @@ MeterClass* Platform_meterTypes[] = {
&LeftCPUs2Meter_class,
&RightCPUs2Meter_class,
&ZfsArcMeter_class,
+ &ZfsCompressedArcMeter_class,
&BlankMeter_class,
NULL
};
@@ -249,6 +251,12 @@ void Platform_setZfsArcValues(Meter* this) {
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 f836077..e17661d 100644
--- a/darwin/Platform.h
+++ b/darwin/Platform.h
@@ -50,6 +50,8 @@ 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/Platform.c b/freebsd/Platform.c
index b08a508..0986a3d 100644
--- a/freebsd/Platform.c
+++ b/freebsd/Platform.c
@@ -16,6 +16,7 @@ in the source distribution for its full text.
#include "ClockMeter.h"
#include "HostnameMeter.h"
#include "zfs/ZfsArcMeter.h"
+#include "zfs/ZfsCompressedArcMeter.h"
#include "FreeBSDProcess.h"
#include "FreeBSDProcessList.h"
@@ -106,6 +107,7 @@ MeterClass* Platform_meterTypes[] = {
&RightCPUs2Meter_class,
&BlankMeter_class,
&ZfsArcMeter_class,
+ &ZfsCompressedArcMeter_class,
NULL
};
@@ -205,6 +207,12 @@ void Platform_setZfsArcValues(Meter* this) {
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 3dc7ebf..0268f2c 100644
--- a/freebsd/Platform.h
+++ b/freebsd/Platform.h
@@ -46,6 +46,8 @@ 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 3e88910..4596c3b 100644
--- a/linux/LinuxProcessList.c
+++ b/linux/LinuxProcessList.c
@@ -984,9 +984,14 @@ static inline void LinuxProcessList_scanZfsArcstats(LinuxProcessList* lpl) {
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", &lpl->zfs.compressed, &lpl->zfs.isCompressed);
+ break;
+ case 'u':
+ tryRead("uncompressed", &lpl->zfs.uncompressed);
break;
case 's':
tryRead("size", &lpl->zfs.size);
@@ -1010,6 +1015,7 @@ static inline void LinuxProcessList_scanZfsArcstats(LinuxProcessList* lpl) {
break;
}
#undef tryRead
+ #undef tryReadFlag
}
fclose(file);
@@ -1021,6 +1027,10 @@ static inline void LinuxProcessList_scanZfsArcstats(LinuxProcessList* lpl) {
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) {
diff --git a/linux/Platform.c b/linux/Platform.c
index 69f6688..f7088cf 100644
--- a/linux/Platform.c
+++ b/linux/Platform.c
@@ -22,6 +22,7 @@ in the source distribution for its full text.
#include "ClockMeter.h"
#include "HostnameMeter.h"
#include "zfs/ZfsArcMeter.h"
+#include "zfs/ZfsCompressedArcMeter.h"
#include "LinuxProcess.h"
#include <math.h>
@@ -128,6 +129,7 @@ MeterClass* Platform_meterTypes[] = {
&RightCPUs2Meter_class,
&BlankMeter_class,
&ZfsArcMeter_class,
+ &ZfsCompressedArcMeter_class,
NULL
};
@@ -221,6 +223,11 @@ void Platform_setZfsArcValues(Meter* this) {
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 e775181..5d85eb3 100644
--- a/linux/Platform.h
+++ b/linux/Platform.h
@@ -45,6 +45,8 @@ 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/Platform.c b/solaris/Platform.c
index 74ae14e..7dcfe32 100644
--- a/solaris/Platform.c
+++ b/solaris/Platform.c
@@ -18,6 +18,7 @@ in the source distribution for its full text.
#include "HostnameMeter.h"
#include "UptimeMeter.h"
#include "zfs/ZfsArcMeter.h"
+#include "zfs/ZfsCompressedArcMeter.h"
#include "SolarisProcess.h"
#include "SolarisProcessList.h"
@@ -124,6 +125,7 @@ MeterClass* Platform_meterTypes[] = {
&LeftCPUs2Meter_class,
&RightCPUs2Meter_class,
&ZfsArcMeter_class,
+ &ZfsCompressedArcMeter_class,
&BlankMeter_class,
NULL
};
@@ -228,6 +230,12 @@ void Platform_setZfsArcValues(Meter* this) {
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 62757ff..3b5aef8 100644
--- a/solaris/Platform.h
+++ b/solaris/Platform.h
@@ -62,6 +62,8 @@ 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 b6bc6f5..d62ea1d 100644
--- a/solaris/SolarisProcessList.c
+++ b/solaris/SolarisProcessList.c
@@ -263,6 +263,16 @@ static inline void SolarisProcessList_scanZfsArcstats(ProcessList* pl) {
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;
+ }
}
}
diff --git a/zfs/ZfsArcStats.c b/zfs/ZfsArcStats.c
index c33076a..1bfaf47 100644
--- a/zfs/ZfsArcStats.c
+++ b/zfs/ZfsArcStats.c
@@ -8,6 +8,7 @@ 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;
@@ -15,5 +16,7 @@ typedef struct ZfsArcStats_ {
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
index 3697af2..ee5d0ed 100644
--- a/zfs/ZfsArcStats.h
+++ b/zfs/ZfsArcStats.h
@@ -11,6 +11,7 @@ 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;
@@ -18,6 +19,8 @@ typedef struct ZfsArcStats_ {
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 0000000..ac3944d
--- /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 <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <sys/param.h>
+#include <assert.h>
+
+/*{
+#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 0000000..5afcc99
--- /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
index ceee4d1..c1ab223 100644
--- a/zfs/openzfs_sysctl.c
+++ b/zfs/openzfs_sysctl.c
@@ -20,6 +20,8 @@ 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"
@@ -41,6 +43,12 @@ void openzfs_sysctl_init(ZfsArcStats *stats) {
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;
}
@@ -77,5 +85,15 @@ void openzfs_sysctl_updateArcStats(ZfsArcStats *stats) {
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;
+ }
}
}
--
2.20.1

View file

@ -0,0 +1,29 @@
From a267003f2f38df5d52ae3f07658c1bbd20b5fb5e Mon Sep 17 00:00:00 2001
From: Ross Williams <ross@ross-williams.net>
Date: Tue, 3 Sep 2019 19:56:38 +0000
Subject: [PATCH 9/9] Linux fixes
---
linux/LinuxProcessList.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/linux/LinuxProcessList.c b/linux/LinuxProcessList.c
index 4596c3b..1d5700e 100644
--- a/linux/LinuxProcessList.c
+++ b/linux/LinuxProcessList.c
@@ -988,10 +988,10 @@ static inline void LinuxProcessList_scanZfsArcstats(LinuxProcessList* lpl) {
switch (buffer[0]) {
case 'c':
tryRead("c_max", &lpl->zfs.max);
- tryReadFlag("compressed", &lpl->zfs.compressed, &lpl->zfs.isCompressed);
+ tryReadFlag("compressed_size", &lpl->zfs.compressed, lpl->zfs.isCompressed);
break;
case 'u':
- tryRead("uncompressed", &lpl->zfs.uncompressed);
+ tryRead("uncompressed_size", &lpl->zfs.uncompressed);
break;
case 's':
tryRead("size", &lpl->zfs.size);
--
2.20.1

View file

@ -0,0 +1,53 @@
{ config, pkgs, depot, ... }:
let
hmPath = "$HOME/nix/home-manager";
in
{
programs = {
home-manager = { enable = true; path = hmPath; };
bash = {
enable = true;
initExtra = ''
PS1="[\\u@\\h:\\w]\\\$ "
_Z_CMD=d
source ~/.z.sh
'';
};
tmux = {
enable = true;
terminal = "tmux-256color";
escapeTime = 50;
extraConfig = ''
bind-key -n C-S-Left swap-window -t -1
bind-key -n C-S-Right swap-window -t +1
'';
};
};
home.sessionVariables = {
NIX_PATH =
"nixpkgs=$HOME/nix/nixpkgs:" +
"home-manager=${hmPath}:" +
"depot=$HOME/nix/depot:" +
"/nix/var/nix/profiles/per-user/root/channels";
HOME_MANAGER_CONFIG = <depot/users/multi/whitby/home-manager.nix>;
};
home.packages = (import ../pkgs { inherit pkgs; });
home.file = {
z = {
source = builtins.fetchurl "https://raw.githubusercontent.com/rupa/z/master/z.sh";
target = ".z.sh";
};
};
home.stateVersion = "20.03";
}