From 070fe90461182743fabb029415fc1bc59be14f3f Mon Sep 17 00:00:00 2001 From: Ross Williams Date: Sun, 7 Jul 2019 02:37:02 +0000 Subject: 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". --- linux/LinuxProcessList.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) (limited to 'linux/LinuxProcessList.c') diff --git a/linux/LinuxProcessList.c b/linux/LinuxProcessList.c index 5f38540c..4d19185c 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; -- cgit v1.2.3 From a88d2e313df7f5f2b781d5b14ffe0e7710018c10 Mon Sep 17 00:00:00 2001 From: Ross Williams Date: Sun, 7 Jul 2019 23:27:00 +0000 Subject: Refactor common OpenZFS sysctl access Darwin and FreeBSD export zfs kstats through the same APIs, so moving functions into a common file. --- linux/LinuxProcessList.c | 40 +++++++++++++++++----------------------- 1 file changed, 17 insertions(+), 23 deletions(-) (limited to 'linux/LinuxProcessList.c') diff --git a/linux/LinuxProcessList.c b/linux/LinuxProcessList.c index 4d19185c..3e889104 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) { -- cgit v1.2.3 From 613556faebd16325da8c9057c81f39a2410d803f Mon Sep 17 00:00:00 2001 From: Ross Williams Date: Tue, 3 Sep 2019 18:26:02 +0000 Subject: Support for ZFS Compressed ARC statistics --- linux/LinuxProcessList.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'linux/LinuxProcessList.c') diff --git a/linux/LinuxProcessList.c b/linux/LinuxProcessList.c index 3e889104..4596c3bc 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) { -- cgit v1.2.3 From a267003f2f38df5d52ae3f07658c1bbd20b5fb5e Mon Sep 17 00:00:00 2001 From: Ross Williams Date: Tue, 3 Sep 2019 19:56:38 +0000 Subject: Linux fixes --- linux/LinuxProcessList.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'linux/LinuxProcessList.c') diff --git a/linux/LinuxProcessList.c b/linux/LinuxProcessList.c index 4596c3bc..1d5700e5 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); -- cgit v1.2.3