From ab17ef4dc0a306b7481cb47149b1c25f7f200932 Mon Sep 17 00:00:00 2001 From: Murloc Knight Date: Tue, 22 Sep 2020 18:54:15 +0700 Subject: [PATCH] Zram Meter feature --- CRT.c | 6 ++++ CRT.h | 1 + Makefile.am | 3 ++ linux/LinuxProcessList.c | 50 ++++++++++++++++++++++++++- linux/LinuxProcessList.h | 3 ++ linux/Platform.c | 9 +++++ linux/Platform.h | 2 ++ linux/ZramMeter.c | 75 ++++++++++++++++++++++++++++++++++++++++ linux/ZramMeter.h | 8 +++++ linux/ZramStats.h | 10 ++++++ 10 files changed, 166 insertions(+), 1 deletion(-) create mode 100644 linux/ZramMeter.c create mode 100644 linux/ZramMeter.h create mode 100644 linux/ZramStats.h diff --git a/CRT.c b/CRT.c index 888444cc..a13f531a 100644 --- a/CRT.c +++ b/CRT.c @@ -153,6 +153,7 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = { [ZFS_OTHER] = ColorPair(Magenta,Black), [ZFS_COMPRESSED] = ColorPair(Blue,Black), [ZFS_RATIO] = ColorPair(Magenta,Black), + [ZRAM] = ColorPair(Yellow,Black), }, [COLORSCHEME_MONOCHROME] = { [RESET_COLOR] = A_NORMAL, @@ -230,6 +231,7 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = { [ZFS_OTHER] = A_DIM, [ZFS_COMPRESSED] = A_BOLD, [ZFS_RATIO] = A_BOLD, + [ZRAM] = A_NORMAL, }, [COLORSCHEME_BLACKONWHITE] = { [RESET_COLOR] = ColorPair(Black,White), @@ -307,6 +309,7 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = { [ZFS_OTHER] = ColorPair(Magenta,White), [ZFS_COMPRESSED] = ColorPair(Cyan,White), [ZFS_RATIO] = ColorPair(Magenta,White), + [ZRAM] = ColorPair(Yellow,White) }, [COLORSCHEME_LIGHTTERMINAL] = { [RESET_COLOR] = ColorPair(Blue,Black), @@ -384,6 +387,7 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = { [ZFS_OTHER] = A_BOLD | ColorPair(Magenta,Black), [ZFS_COMPRESSED] = ColorPair(Cyan,Black), [ZFS_RATIO] = A_BOLD | ColorPair(Magenta,Black), + [ZRAM] = ColorPair(Yellow,Black), }, [COLORSCHEME_MIDNIGHT] = { [RESET_COLOR] = ColorPair(White,Blue), @@ -461,6 +465,7 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = { [ZFS_OTHER] = A_BOLD | ColorPair(Magenta,Blue), [ZFS_COMPRESSED] = A_BOLD | ColorPair(White,Blue), [ZFS_RATIO] = A_BOLD | ColorPair(Magenta,Blue), + [ZRAM] = A_BOLD | ColorPair(Yellow,Blue), }, [COLORSCHEME_BLACKNIGHT] = { [RESET_COLOR] = ColorPair(Cyan,Black), @@ -536,6 +541,7 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = { [ZFS_OTHER] = ColorPair(Magenta,Black), [ZFS_COMPRESSED] = ColorPair(Blue,Black), [ZFS_RATIO] = ColorPair(Magenta,Black), + [ZRAM] = ColorPair(Yellow,Black), }, [COLORSCHEME_BROKENGRAY] = { 0 } // dynamically generated. }; diff --git a/CRT.h b/CRT.h index 1cdc209c..49ed4ed0 100644 --- a/CRT.h +++ b/CRT.h @@ -113,6 +113,7 @@ typedef enum ColorElements_ { ZFS_OTHER, ZFS_COMPRESSED, ZFS_RATIO, + ZRAM, LAST_COLORELEMENT } ColorElements; diff --git a/Makefile.am b/Makefile.am index e7582e71..a6629f6d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -130,6 +130,8 @@ linux_platform_headers = \ linux/Platform.h \ linux/PressureStallMeter.h \ linux/SELinuxMeter.h \ + linux/ZramMeter.h \ + linux/ZramStats.h \ zfs/ZfsArcMeter.h \ zfs/ZfsArcStats.h \ zfs/ZfsCompressedArcMeter.h @@ -144,6 +146,7 @@ myhtopplatsources = \ linux/Platform.c \ linux/PressureStallMeter.c \ linux/SELinuxMeter.c \ + linux/ZramMeter.c \ zfs/ZfsArcMeter.c \ zfs/ZfsArcStats.c \ zfs/ZfsCompressedArcMeter.c diff --git a/linux/LinuxProcessList.c b/linux/LinuxProcessList.c index 2530b2bb..f32aba41 100644 --- a/linux/LinuxProcessList.c +++ b/linux/LinuxProcessList.c @@ -1148,6 +1148,54 @@ static inline void LinuxProcessList_scanMemoryInfo(ProcessList* this) { fclose(file); } +static inline void LinuxProcessList_scanZramInfo(LinuxProcessList* this) { + unsigned long long int totalZram = 0; + unsigned long long int usedZramComp = 0; + unsigned long long int usedZramOrig = 0; + + char mm_stat[34]; + char disksize[34]; + + unsigned int i = 0; + for(;;) { + xSnprintf(mm_stat, sizeof(mm_stat), "/sys/block/zram%u/mm_stat", i); + xSnprintf(disksize, sizeof(disksize), "/sys/block/zram%u/disksize", i); + i++; + FILE* disksize_file = fopen(disksize, "r"); + FILE* mm_stat_file = fopen(mm_stat, "r"); + if (disksize_file == NULL || mm_stat_file == NULL) { + if (disksize_file) { + fclose(disksize_file); + } + if (mm_stat_file) { + fclose(mm_stat_file); + } + break; + } + unsigned long long int size = 0; + unsigned long long int orig_data_size = 0; + unsigned long long int compr_data_size = 0; + + if (!fscanf(disksize_file, "%llu\n", &size) || + !fscanf(mm_stat_file, " %llu %llu", &orig_data_size, &compr_data_size)) { + fclose(disksize_file); + fclose(mm_stat_file); + break; + } + + totalZram += size; + usedZramComp += compr_data_size; + usedZramOrig += orig_data_size; + + fclose(disksize_file); + fclose(mm_stat_file); + } + + this->zram.totalZram = totalZram / 1024; + this->zram.usedZramComp = usedZramComp / 1024; + this->zram.usedZramOrig = usedZramOrig / 1024; +} + static inline void LinuxProcessList_scanZfsArcstats(LinuxProcessList* lpl) { unsigned long long int dbufSize = 0; unsigned long long int dnodeSize = 0; @@ -1376,8 +1424,8 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) { LinuxProcessList_scanMemoryInfo(super); LinuxProcessList_scanZfsArcstats(this); - LinuxProcessList_updateCPUcount(this); + LinuxProcessList_scanZramInfo(this); double period = LinuxProcessList_scanCPUTime(this); diff --git a/linux/LinuxProcessList.h b/linux/LinuxProcessList.h index 4427ccdf..1795543f 100644 --- a/linux/LinuxProcessList.h +++ b/linux/LinuxProcessList.h @@ -15,8 +15,10 @@ in the source distribution for its full text. #include "Hashtable.h" #include "ProcessList.h" #include "UsersTable.h" +#include "ZramStats.h" #include "zfs/ZfsArcStats.h" + typedef struct CPUData_ { unsigned long long int totalTime; unsigned long long int userTime; @@ -67,6 +69,7 @@ typedef struct LinuxProcessList_ { #endif ZfsArcStats zfs; + ZramStats zram; } LinuxProcessList; #ifndef PROCDIR diff --git a/linux/Platform.c b/linux/Platform.c index fe9764ba..f7a768c9 100644 --- a/linux/Platform.c +++ b/linux/Platform.c @@ -42,6 +42,7 @@ in the source distribution for its full text. #include "TasksMeter.h" #include "UptimeMeter.h" #include "XUtils.h" +#include "ZramMeter.h" #include "zfs/ZfsArcMeter.h" #include "zfs/ZfsArcStats.h" @@ -148,6 +149,7 @@ const MeterClass* const Platform_meterTypes[] = { &PressureStallMemoryFullMeter_class, &ZfsArcMeter_class, &ZfsCompressedArcMeter_class, + &ZramMeter_class, &DiskIOMeter_class, &NetworkIOMeter_class, &SELinuxMeter_class, @@ -248,6 +250,13 @@ void Platform_setSwapValues(Meter* this) { this->values[0] = pl->usedSwap; } +void Platform_setZramValues(Meter* this) { + const LinuxProcessList* lpl = (const LinuxProcessList*) this->pl; + this->total = lpl->zram.totalZram; + this->values[0] = lpl->zram.usedZramComp; + this->values[1] = lpl->zram.usedZramOrig; +} + void Platform_setZfsArcValues(Meter* this) { const LinuxProcessList* lpl = (const LinuxProcessList*) this->pl; diff --git a/linux/Platform.h b/linux/Platform.h index 62402432..b61a4db8 100644 --- a/linux/Platform.h +++ b/linux/Platform.h @@ -40,6 +40,8 @@ void Platform_setMemoryValues(Meter* this); void Platform_setSwapValues(Meter* this); +void Platform_setZramValues(Meter* this); + void Platform_setZfsArcValues(Meter* this); void Platform_setZfsCompressedArcValues(Meter* this); diff --git a/linux/ZramMeter.c b/linux/ZramMeter.c new file mode 100644 index 00000000..f855488e --- /dev/null +++ b/linux/ZramMeter.c @@ -0,0 +1,75 @@ +#include "ZramMeter.h" + +#include "CRT.h" +#include "Meter.h" +#include "Platform.h" + +static const int ZramMeter_attributes[] = { + ZRAM +}; + +static void ZramMeter_updateValues(Meter* this, char* buffer, int size) { + int written; + + Platform_setZramValues(this); + + /* on print bar for compressed data size, not uncompressed */ + this->curItems = 1; + + written = Meter_humanUnit(buffer, this->values[0], size); + buffer += written; + size -= written; + if(size <= 0) { + return; + } + *buffer++ = '('; + size--; + if(size <= 0) { + return; + } + written = Meter_humanUnit(buffer, this->values[1], size); + buffer += written; + size -= written; + if(size <= 0) { + return; + } + *buffer++ = ')'; + size--; + if ((size -= written) > 0) { + *buffer++ = '/'; + size--; + Meter_humanUnit(buffer, this->total, size); + } +} + +static void ZramMeter_display(const Object* cast, RichString* out) { + char buffer[50]; + const Meter* this = (const Meter*)cast; + RichString_write(out, CRT_colors[METER_TEXT], ":"); + Meter_humanUnit(buffer, this->total, sizeof(buffer)); + + RichString_append(out, CRT_colors[METER_VALUE], buffer); + Meter_humanUnit(buffer, this->values[0], sizeof(buffer)); + RichString_append(out, CRT_colors[METER_TEXT], " used:"); + RichString_append(out, CRT_colors[METER_VALUE], buffer); + + Meter_humanUnit(buffer, this->values[1], sizeof(buffer)); + RichString_append(out, CRT_colors[METER_TEXT], " uncompressed:"); + RichString_append(out, CRT_colors[METER_VALUE], buffer); +} + +const MeterClass ZramMeter_class = { + .super = { + .extends = Class(Meter), + .delete = Meter_delete, + .display = ZramMeter_display, + }, + .updateValues = ZramMeter_updateValues, + .defaultMode = BAR_METERMODE, + .maxItems = 2, + .total = 100.0, + .attributes = ZramMeter_attributes, + .name = "Zram", + .uiName = "Zram", + .caption = "zrm" +}; diff --git a/linux/ZramMeter.h b/linux/ZramMeter.h new file mode 100644 index 00000000..7cf7861e --- /dev/null +++ b/linux/ZramMeter.h @@ -0,0 +1,8 @@ +#ifndef HEADER_ZramMeter +#define HEADER_ZramMeter + +#include "Meter.h" + +extern const MeterClass ZramMeter_class; + +#endif diff --git a/linux/ZramStats.h b/linux/ZramStats.h new file mode 100644 index 00000000..2305cfd2 --- /dev/null +++ b/linux/ZramStats.h @@ -0,0 +1,10 @@ +#ifndef HEADER_ZramStats +#define HEADER_ZramStats + +typedef struct ZramStats_ { + unsigned long long int totalZram; + unsigned long long int usedZramComp; + unsigned long long int usedZramOrig; +} ZramStats; + +#endif