htop
htop copied to clipboard
Create new File Descriptors meter
The meter shows the number of globally open (used) and maximally available file descriptors for the system.
Maybe a process column would also be useful? On Linux counting the number of entries in
/proc/<pid>/fd/
.
Not part of this PR. Also if we go that route I'd like to add some different columns based on the same information too. Also such columns would arguably be best implemented cross-platform. So jumping ahead for Linux for FDs per process just leads to a situation like with the command line highlighting later …
Quick survey for NetBSD seems to indicate requirement to use libkvm to parse kernel memory, as seen in the fstat source.
On various other *BSDs I noticed the availability of the kern.file
information:
/*
htop - fdstat_sysctl.c
(C) 2022 htop dev team
Released under the GNU GPLv2+, see the COPYING file
in the source distribution for its full text.
*/
#include <math.h>
#include <stddef.h>
#include <stdint.h>
#include <sys/sysctl.h>
#include <sys/types.h>
#include "config.h"
void Generic_getFileDescriptors_sysctl(double* used, double* max) {
*used = NAN;
*max = 65536;
int max_fd, open_fd;
size_t len;
len = sizeof(max_fd);
if (sysctlbyname("kern.maxfiles", &max_fd, &len, NULL, 0) == 0) {
if (!max_fd) {
max_fd = 1;
}
*max = max_fd;
}
len = sizeof(open_fd);
if (sysctlbyname("kern.nfiles", &open_fd, &len, NULL, 0) == 0) { // OpenBSD
*used = open_fd;
} else if (sysctlbyname("kern.num_files", &open_fd, &len, NULL, 0) == 0) { // Darwin
*used = open_fd;
} else if (sysctlbyname("kern.openfiles", &open_fd, &len, NULL, 0) == 0) { // FreeBSD
*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 defined(HTOP_DARWIN)
#define HTOP_OS_KERNFILE_SIZE(x) (((x) - sizeof(struct filehead)) / sizeof(struct file))
#define HTOP_OS_KERNFILE_MIN sizeof(struct filehead)
#elif defined(HTOP_DRAGONFLY)
#define HTOP_OS_KERNFILE_SIZE(x) ((x) / sizeof(struct kinfo_file))
#elif defined(HTOP_FREEBSD)
#define HTOP_OS_KERNFILE_SIZE(x) ((x) / sizeof(struct xfile))
#elif defined(HTOP_NETBSD)
#define HTOP_OS_KERNFILE_SIZE(x) (((x) - sizeof(struct filelist)) / sizeof(struct file))
#define HTOP_OS_KERNFILE_MIN sizeof(struct filelist)
#elif defined(HTOP_OPENBSD)
#define HTOP_OS_KERNFILE_SIZE(x) ((x) / sizeof(struct kinfo_file))
#endif
#if defined(HTOP_OS_KERNFILE_SIZE)
len = 0;
if(sysctlnyname("kern.file", NULL, &len, NULL, NULL) < 0) {
return;
}
#if defined(HTOP_OS_KERNFILE_MIN)
if(len < HTOP_OS_KERNFILE_MIN) {
return;
}
#endif
*used = HTOP_OS_KERNFILE_SIZE(len);
#endif
}
For DragonFlyBSD there's libkinfo
providing kinfo_get_maxfiles
and kinfo_get_openfiles
, which we just would need to check for in Configure.ac
.
@fraggerfox @alarixnia : Please have a look if I missed something for NetBSD.
Errors building the branch on NetBSD:
--- htop ---
ld: CategoriesPanel.o: in function `CategoriesPanel_makeScreensPage':
/home/nia/git/htop/CategoriesPanel.c:73: undefined reference to `ScreensPanel_new'
ld: CategoriesPanel.o: in function `CategoriesPanel_makeHeaderOptionsPage':
/home/nia/git/htop/CategoriesPanel.c:82: undefined reference to `HeaderOptionsPanel_new'
--- Makefile ---
config.status: config.h is unchanged
config.status: executing depfiles commands
--- htop ---
ld: netbsd/Platform.o:(.rodata+0x40): undefined reference to `MemorySwapMeter_class'
Errors building the branch on NetBSD:
These errors look like some files have not been compiled or are outdated.
Please re-run ./autogen.sh && ./configure
in a clean checkout to update the Makefile
.
Please also check if the issue is reproducible on the main branch.
If it is I'd suggest to continue as part of a separate issue to keep discussions here focused.
Tests for OpenBSD are still open …
Tested on OpenBSD 7.2