From 7a8c01f304b673dd89923e05d242aebb9cd0a500 Mon Sep 17 00:00:00 2001 From: Benny Baumann Date: Sun, 5 Feb 2023 02:40:42 +0100 Subject: Implement File Descriptor Meter support for DragonflyBSD/FreeBSD/NetBSD --- Makefile.am | 6 ++++ dragonflybsd/Platform.c | 8 +++++ dragonflybsd/Platform.h | 2 ++ freebsd/Platform.c | 7 +++++ freebsd/Platform.h | 2 ++ generic/fdstat_sysctl.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++++ generic/fdstat_sysctl.h | 13 ++++++++ netbsd/Platform.c | 7 +++++ netbsd/Platform.h | 2 ++ 9 files changed, 130 insertions(+) create mode 100644 generic/fdstat_sysctl.c create mode 100644 generic/fdstat_sysctl.h diff --git a/Makefile.am b/Makefile.am index 749b0c24..86b747a0 100644 --- a/Makefile.am +++ b/Makefile.am @@ -209,6 +209,7 @@ freebsd_platform_headers = \ freebsd/FreeBSDProcess.h \ freebsd/Platform.h \ freebsd/ProcessField.h \ + generic/fdstat_sysctl.h \ generic/gettime.h \ generic/hostname.h \ generic/openzfs_sysctl.h \ @@ -221,6 +222,7 @@ freebsd_platform_sources = \ freebsd/Platform.c \ freebsd/FreeBSDProcessList.c \ freebsd/FreeBSDProcess.c \ + generic/fdstat_sysctl.c \ generic/gettime.c \ generic/hostname.c \ generic/openzfs_sysctl.c \ @@ -241,6 +243,7 @@ dragonflybsd_platform_headers = \ dragonflybsd/DragonFlyBSDProcess.h \ dragonflybsd/Platform.h \ dragonflybsd/ProcessField.h \ + generic/fdstat_sysctl.h \ generic/gettime.h \ generic/hostname.h \ generic/uname.h @@ -249,6 +252,7 @@ dragonflybsd_platform_sources = \ dragonflybsd/DragonFlyBSDProcessList.c \ dragonflybsd/DragonFlyBSDProcess.c \ dragonflybsd/Platform.c \ + generic/fdstat_sysctl.c \ generic/gettime.c \ generic/hostname.c \ generic/uname.c @@ -262,6 +266,7 @@ endif # ------- netbsd_platform_headers = \ + generic/fdstat_sysctl.h \ generic/gettime.h \ generic/hostname.h \ generic/uname.h \ @@ -271,6 +276,7 @@ netbsd_platform_headers = \ netbsd/NetBSDProcessList.h netbsd_platform_sources = \ + generic/fdstat_sysctl.c \ generic/gettime.c \ generic/hostname.c \ generic/uname.c \ diff --git a/dragonflybsd/Platform.c b/dragonflybsd/Platform.c index 8a684d86..277f1876 100644 --- a/dragonflybsd/Platform.c +++ b/dragonflybsd/Platform.c @@ -20,6 +20,7 @@ in the source distribution for its full text. #include "CPUMeter.h" #include "DateMeter.h" #include "DateTimeMeter.h" +#include "FileDescriptorMeter.h" #include "HostnameMeter.h" #include "LoadAverageMeter.h" #include "MemoryMeter.h" @@ -31,6 +32,8 @@ in the source distribution for its full text. #include "UptimeMeter.h" #include "dragonflybsd/DragonFlyBSDProcess.h" #include "dragonflybsd/DragonFlyBSDProcessList.h" +#include "generic/fdstat_sysctl.h" + const ScreenDefaults Platform_defaultScreens[] = { { @@ -108,6 +111,7 @@ const MeterClass* const Platform_meterTypes[] = { &RightCPUs4Meter_class, &LeftCPUs8Meter_class, &RightCPUs8Meter_class, + &FileDescriptorMeter_class, &BlankMeter_class, NULL }; @@ -233,6 +237,10 @@ FileLocks_ProcessData* Platform_getProcessLocks(pid_t pid) { return NULL; } +void Platform_getFileDescriptors(double* used, double* max) { + Generic_getFileDescriptors_sysctl(used, max); +} + bool Platform_getDiskIO(DiskIOData* data) { // TODO (void)data; diff --git a/dragonflybsd/Platform.h b/dragonflybsd/Platform.h index cf693562..b37cea2a 100644 --- a/dragonflybsd/Platform.h +++ b/dragonflybsd/Platform.h @@ -61,6 +61,8 @@ char* Platform_getProcessEnv(pid_t pid); FileLocks_ProcessData* Platform_getProcessLocks(pid_t pid); +void Platform_getFileDescriptors(double* used, double* max); + bool Platform_getDiskIO(DiskIOData* data); bool Platform_getNetworkIO(NetworkIOData* data); diff --git a/freebsd/Platform.c b/freebsd/Platform.c index 646163af..061de70b 100644 --- a/freebsd/Platform.c +++ b/freebsd/Platform.c @@ -31,6 +31,7 @@ in the source distribution for its full text. #include "DateMeter.h" #include "DateTimeMeter.h" #include "DiskIOMeter.h" +#include "FileDescriptorMeter.h" #include "HostnameMeter.h" #include "LoadAverageMeter.h" #include "Macros.h" @@ -47,6 +48,7 @@ in the source distribution for its full text. #include "XUtils.h" #include "freebsd/FreeBSDProcess.h" #include "freebsd/FreeBSDProcessList.h" +#include "generic/fdstat_sysctl.h" #include "zfs/ZfsArcMeter.h" #include "zfs/ZfsCompressedArcMeter.h" @@ -130,6 +132,7 @@ const MeterClass* const Platform_meterTypes[] = { &ZfsArcMeter_class, &ZfsCompressedArcMeter_class, &DiskIOMeter_class, + &FileDescriptorMeter_class, &NetworkIOMeter_class, NULL }; @@ -292,6 +295,10 @@ FileLocks_ProcessData* Platform_getProcessLocks(pid_t pid) { return NULL; } +void Platform_getFileDescriptors(double* used, double* max) { + Generic_getFileDescriptors_sysctl(used, max); +} + bool Platform_getDiskIO(DiskIOData* data) { if (devstat_checkversion(NULL) < 0) diff --git a/freebsd/Platform.h b/freebsd/Platform.h index 51269c09..849f7ddf 100644 --- a/freebsd/Platform.h +++ b/freebsd/Platform.h @@ -61,6 +61,8 @@ char* Platform_getProcessEnv(pid_t pid); FileLocks_ProcessData* Platform_getProcessLocks(pid_t pid); +void Platform_getFileDescriptors(double* used, double* max); + bool Platform_getDiskIO(DiskIOData* data); bool Platform_getNetworkIO(NetworkIOData* data); diff --git a/generic/fdstat_sysctl.c b/generic/fdstat_sysctl.c new file mode 100644 index 00000000..9e89a0da --- /dev/null +++ b/generic/fdstat_sysctl.c @@ -0,0 +1,83 @@ +/* +htop - generic/fdstat_sysctl.c +(C) 2022-2023 htop dev team +Released under the GNU GPLv2+, see the COPYING file +in the source distribution for its full text. +*/ + +#include "generic/fdstat_sysctl.h" + +#include +#include +#include + +#include +#include + +#include "config.h" + + +static void Generic_getFileDescriptors_sysctl_internal( + const char* sysctlname_maxfiles, + const char* sysctlname_numfiles, + size_t size_header, + size_t size_entry, + double* used, + double* max +) { + *used = NAN; + *max = 65536; + + int max_fd, open_fd; + size_t len; + + len = sizeof(max_fd); + if (sysctlname_maxfiles && sysctlbyname(sysctlname_maxfiles, &max_fd, &len, NULL, 0) == 0) { + if (max_fd) { + *max = max_fd; + } else { + *max = NAN; + } + } + + len = sizeof(open_fd); + if (sysctlname_numfiles && sysctlbyname(sysctlname_numfiles, &open_fd, &len, NULL, 0) == 0) { + *used = open_fd; + } + + if (!isnan(*used)) { + return; + } + + // If no sysctl arc available, try to guess from the file table size at kern.file + // The size per entry differs per OS, thus skip if we don't know: + if (!size_entry) + return; + + len = 0; + if (sysctlbyname("kern.file", NULL, &len, NULL, 0) < 0) + return; + + if (len < size_header) + return; + + *used = (len - size_header) / size_entry; +} + +void Generic_getFileDescriptors_sysctl(double* used, double* max) { +#if defined(HTOP_DARWIN) + Generic_getFileDescriptors_sysctl_internal( + "kern.maxfiles", "kern.num_files", 0, 0, used, max); +#elif defined(HTOP_DRAGONFLY) + Generic_getFileDescriptors_sysctl_internal( + "kern.maxfiles", NULL, 0, sizeof(struct kinfo_file), used, max); +#elif defined(HTOP_FREEBSD) + Generic_getFileDescriptors_sysctl_internal( + "kern.maxfiles", "kern.openfiles", 0, 0, used, max); +#elif defined(HTOP_NETBSD) + Generic_getFileDescriptors_sysctl_internal( + "kern.maxfiles", NULL, 0, sizeof(struct kinfo_file), used, max); +#else +#error Unknown platform: Please implement proper way to query open/max file information +#endif +} diff --git a/generic/fdstat_sysctl.h b/generic/fdstat_sysctl.h new file mode 100644 index 00000000..107fcabe --- /dev/null +++ b/generic/fdstat_sysctl.h @@ -0,0 +1,13 @@ +#ifndef HEADER_fdstat_sysctl +#define HEADER_fdstat_sysctl +/* +htop - generic/fdstat_sysctl.h +(C) 2022-2023 htop dev team +Released under the GNU GPLv2+, see the COPYING file +in the source distribution for its full text. +*/ + + +void Generic_getFileDescriptors_sysctl(double* used, double* max); + +#endif diff --git a/netbsd/Platform.c b/netbsd/Platform.c index ad6050c0..c5c42d0a 100644 --- a/netbsd/Platform.c +++ b/netbsd/Platform.c @@ -38,6 +38,7 @@ in the source distribution for its full text. #include "ClockMeter.h" #include "DateMeter.h" #include "DateTimeMeter.h" +#include "FileDescriptorMeter.h" #include "HostnameMeter.h" #include "LoadAverageMeter.h" #include "Macros.h" @@ -52,6 +53,7 @@ in the source distribution for its full text. #include "TasksMeter.h" #include "UptimeMeter.h" #include "XUtils.h" +#include "generic/fdstat_sysctl.h" #include "netbsd/NetBSDProcess.h" #include "netbsd/NetBSDProcessList.h" @@ -179,6 +181,7 @@ const MeterClass* const Platform_meterTypes[] = { &BlankMeter_class, &DiskIOMeter_class, &NetworkIOMeter_class, + &FileDescriptorMeter_class, NULL }; @@ -343,6 +346,10 @@ FileLocks_ProcessData* Platform_getProcessLocks(pid_t pid) { return NULL; } +void Platform_getFileDescriptors(double* used, double* max) { + Generic_getFileDescriptors_sysctl(used, max); +} + bool Platform_getDiskIO(DiskIOData* data) { const int mib[] = { CTL_HW, HW_IOSTATS, sizeof(struct io_sysctl) }; struct io_sysctl* iostats = NULL; diff --git a/netbsd/Platform.h b/netbsd/Platform.h index 0e53b457..a75c766c 100644 --- a/netbsd/Platform.h +++ b/netbsd/Platform.h @@ -67,6 +67,8 @@ char* Platform_getProcessEnv(pid_t pid); FileLocks_ProcessData* Platform_getProcessLocks(pid_t pid); +void Platform_getFileDescriptors(double* used, double* max); + bool Platform_getDiskIO(DiskIOData* data); bool Platform_getNetworkIO(NetworkIOData* data); -- cgit v1.2.3