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/
This commit is contained in:
Doug Torrance 2015-04-07 01:23:26 -05:00 committed by Carlos R. Mafra
parent 38c74350b0
commit f094d448e2
2 changed files with 22 additions and 31 deletions

View file

@ -101,8 +101,6 @@ linux*)
OS=freebsd OS=freebsd
ignore_wired=yes ignore_wired=yes
ignore_cached=yes ignore_cached=yes
LIBS="$LIBS -lkvm"
SETGID_FLAGS="-g kmem -m 2755 -o root"
;; ;;
openbsd*) openbsd*)
OS=openbsd OS=openbsd

View file

@ -11,38 +11,18 @@
#endif #endif
#include <stdio.h> #include <stdio.h>
#include <unistd.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "mem.h" #include "mem.h"
#include <kvm.h> #include <vm/vm_param.h>
#include <fcntl.h>
#include <sys/errno.h> #include <sys/errno.h>
#include <sys/sysctl.h> #include <sys/sysctl.h>
#include <time.h> #include <time.h>
static kvm_t *kvm_data;
/* initialize function */ /* initialize function */
void mem_init(void) 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; return;
} }
@ -53,12 +33,12 @@ static void getsysctl(const char *name, void *ptr, size_t len)
size_t nlen = len; size_t nlen = len;
if (sysctlbyname(name, ptr, &nlen, NULL, 0) == -1) { 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)); strerror(errno));
exit(1); exit(1);
} }
if (nlen != len) { 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); name, (unsigned long)len, (unsigned long)nlen);
exit(1); exit(1);
} }
@ -101,17 +81,30 @@ void mem_getusage(int *per_mem, int *per_swap, const struct mem_options *opts)
if (swap_firsttime || if (swap_firsttime ||
(((new_swappgsin > swappgsin) || (new_swappgsout > swappgsout)) (((new_swappgsin > swappgsin) || (new_swappgsout > swappgsout))
&& cur_time > last_time_swap + 1)) { && cur_time > last_time_swap + 1)) {
int mib[2], n;
size_t mibsize, size;
struct xswdev xsw;
struct kvm_swap swap; mibsize = sizeof(mib) / sizeof(mib[0]);
int n; if (sysctlnametomib("vm.swap_info", mib, &mibsize) == -1) {
fprintf(stderr, "sysctlnametomib() failed: %s\n", strerror(errno));
exit(1);
}
swapmax = 0; swapmax = 0;
swapused = 0; swapused = 0;
n = kvm_getswapinfo(kvm_data, &swap, 1, 0); for (n = 0; ; n++) {
if (n >= 0 && swap.ksw_total != 0) { mib[mibsize] = n;
swapmax = swap.ksw_total; size = sizeof(xsw);
swapused = swap.ksw_used; 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; swap_firsttime = 0;