htop icon indicating copy to clipboard operation
htop copied to clipboard

Create new File Descriptors meter

Open BenBE opened this issue 2 years ago • 4 comments

The meter shows the number of globally open (used) and maximally available file descriptors for the system.

BenBE avatar May 01 '22 20:05 BenBE

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 …

BenBE avatar May 02 '22 14:05 BenBE

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.

BenBE avatar May 05 '22 09:05 BenBE

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'

alarixnia avatar May 07 '22 07:05 alarixnia

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.

BenBE avatar May 07 '22 13:05 BenBE

Tests for OpenBSD are still open …

BenBE avatar Feb 18 '23 15:02 BenBE

Tested on OpenBSD 7.2

cgzones avatar Feb 18 '23 17:02 cgzones