From f094d448e29373dd307913c28bd269646bd63966 Mon Sep 17 00:00:00 2001 From: Doug Torrance Date: Tue, 7 Apr 2015 01:23:26 -0500 Subject: [PATCH] wmmemload: Use sysctl for swap usage information in FreeBSD. Use sysctl instead of kvm_getswapinfo() to read the swap usage information in FreeBSD. This removes the need for a dependency on libkvm and for a setgid binary. Based on the Debian patch [1]. [1] https://sources.debian.net/src/wmmemload/0.1.7-2/debian/patches/sysctl_swap.patch/ --- wmmemload/configure.ac | 2 -- wmmemload/src/mem_freebsd.c | 51 ++++++++++++++++--------------------- 2 files changed, 22 insertions(+), 31 deletions(-) diff --git a/wmmemload/configure.ac b/wmmemload/configure.ac index dc70267..3978edd 100644 --- a/wmmemload/configure.ac +++ b/wmmemload/configure.ac @@ -101,8 +101,6 @@ linux*) OS=freebsd ignore_wired=yes ignore_cached=yes - LIBS="$LIBS -lkvm" - SETGID_FLAGS="-g kmem -m 2755 -o root" ;; openbsd*) OS=openbsd diff --git a/wmmemload/src/mem_freebsd.c b/wmmemload/src/mem_freebsd.c index 3b12346..bf325e9 100644 --- a/wmmemload/src/mem_freebsd.c +++ b/wmmemload/src/mem_freebsd.c @@ -11,38 +11,18 @@ #endif #include -#include #include #include #include "mem.h" -#include -#include +#include #include #include #include -static kvm_t *kvm_data; - /* initialize function */ void mem_init(void) { - kvm_data = kvm_open(NULL, NULL, NULL, O_RDONLY, "kvm_open"); - - if (kvm_data == NULL) { - fprintf(stderr, "can't open kernel virtual memory"); - exit(1); - } - - /* drop setgid & setuid (the latter should not be there really) */ - seteuid(getuid()); - setegid(getgid()); - - if (geteuid() != getuid() || getegid() != getgid()) { - fprintf(stderr, "unable to drop privileges"); - exit(1); - } - return; } @@ -53,12 +33,12 @@ static void getsysctl(const char *name, void *ptr, size_t len) size_t nlen = len; if (sysctlbyname(name, ptr, &nlen, NULL, 0) == -1) { - fprintf(stderr, "top: sysctl(%s...) failed: %s\n", name, + fprintf(stderr, "sysctl(%s...) failed: %s\n", name, strerror(errno)); exit(1); } if (nlen != len) { - fprintf(stderr, "top: sysctl(%s...) expected %lu, got %lu\n", + fprintf(stderr, "sysctl(%s...) expected %lu, got %lu\n", name, (unsigned long)len, (unsigned long)nlen); exit(1); } @@ -101,17 +81,30 @@ void mem_getusage(int *per_mem, int *per_swap, const struct mem_options *opts) if (swap_firsttime || (((new_swappgsin > swappgsin) || (new_swappgsout > swappgsout)) && cur_time > last_time_swap + 1)) { + int mib[2], n; + size_t mibsize, size; + struct xswdev xsw; - struct kvm_swap swap; - int n; + mibsize = sizeof(mib) / sizeof(mib[0]); + if (sysctlnametomib("vm.swap_info", mib, &mibsize) == -1) { + fprintf(stderr, "sysctlnametomib() failed: %s\n", strerror(errno)); + exit(1); + } swapmax = 0; swapused = 0; - n = kvm_getswapinfo(kvm_data, &swap, 1, 0); - if (n >= 0 && swap.ksw_total != 0) { - swapmax = swap.ksw_total; - swapused = swap.ksw_used; + for (n = 0; ; n++) { + mib[mibsize] = n; + size = sizeof(xsw); + if (sysctl(mib, mibsize + 1, &xsw, &size, NULL, 0) == -1) { + if (errno == ENOENT) + break; + fprintf(stderr, "sysctl() failed: %s\n", strerror(errno)); + exit(1); + } + swapmax += xsw.xsw_nblks; + swapused += xsw.xsw_used; } swap_firsttime = 0;