Unbreak the kvm(3) calls used by the processes and tcpconns plugins.

- patch the correct kvm_open call to use KVM_NO_FILES.  Also, use
  kvm_openfiles instead, as was probably intended
- add a new implementation for tcpconns, based on kvm_getfiles instead
  of peeking at kernel memory

ok landry@
This commit is contained in:
jca 2016-12-04 16:56:53 +00:00
parent 6eedafef6f
commit 8cce6470d9
3 changed files with 122 additions and 10 deletions

View File

@ -1,4 +1,4 @@
# $OpenBSD: Makefile,v 1.42 2016/12/03 11:44:41 landry Exp $
# $OpenBSD: Makefile,v 1.43 2016/12/04 16:56:53 jca Exp $
COMMENT-main = system metrics collection engine
COMMENT-mysql = collectd mysql plugin
@ -11,6 +11,7 @@ COMMENT-memcachec = collectd memcachec plugin
COMMENT-nut = collectd nut plugin
COMMENT-riemann = collectd riemann plugin
REVISION-main = 0
V = 5.6.2
DISTNAME = collectd-$V
PKGNAME-main = collectd-$V

View File

@ -1,15 +1,15 @@
$OpenBSD: patch-src_processes_c,v 1.6 2016/12/03 11:44:41 landry Exp $
$OpenBSD: patch-src_processes_c,v 1.7 2016/12/04 16:56:53 jca Exp $
https://github.com/collectd/collectd/issues/2061
--- src/processes.c.orig Wed Nov 30 09:52:01 2016
+++ src/processes.c Sat Dec 3 12:30:07 2016
@@ -1786,7 +1786,7 @@ static int ps_read(void) {
+++ src/processes.c Sun Dec 4 16:22:15 2016
@@ -1937,7 +1937,7 @@ static int ps_read(void) {
ps_list_reset();
/* Open the kvm interface, get a descriptor */
- kd = kvm_openfiles(NULL, "/dev/null", NULL, 0, errbuf);
+ kd = kvm_openfiles(NULL, "/dev/null", NULL, O_RDONLY|KVM_NO_FILES, errbuf);
- kd = kvm_open(NULL, NULL, NULL, 0, errbuf);
+ kd = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, errbuf);
if (kd == NULL) {
ERROR("processes plugin: Cannot open kvm interface: %s", errbuf);
return (0);

View File

@ -1,7 +1,48 @@
$OpenBSD: patch-src_tcpconns_c,v 1.10 2016/12/03 11:44:41 landry Exp $
--- src/tcpconns.c.orig Sat Dec 3 11:49:16 2016
+++ src/tcpconns.c Sat Dec 3 11:52:02 2016
@@ -111,9 +111,9 @@
$OpenBSD: patch-src_tcpconns_c,v 1.11 2016/12/04 16:56:53 jca Exp $
https://github.com/collectd/collectd/issues/2061
--- src/tcpconns.c.orig Wed Nov 30 09:52:01 2016
+++ src/tcpconns.c Sun Dec 4 16:22:52 2016
@@ -62,11 +62,16 @@
#include "common.h"
#include "plugin.h"
-#if defined(__OpenBSD__) || defined(__NetBSD__)
+/* Maybe usable on NetBSD? */
+#if defined(__OpenBSD__)
+#define HAVE_KVM_GETFILES 1
+#endif
+
+#if defined(__NetBSD__)
#undef HAVE_SYSCTLBYNAME /* force HAVE_LIBKVM_NLIST path */
#endif
-#if !KERNEL_LINUX && !HAVE_SYSCTLBYNAME && !HAVE_LIBKVM_NLIST && !KERNEL_AIX
+#if !KERNEL_LINUX && !HAVE_SYSCTLBYNAME && !HAVE_KVM_GETFILES && !HAVE_LIBKVM_NLIST && !KERNEL_AIX
#error "No applicable input method."
#endif
@@ -105,15 +110,27 @@
#include <netinet/tcpip.h>
/* #endif HAVE_SYSCTLBYNAME */
-/* This is for OpenBSD and NetBSD. */
+#elif HAVE_KVM_GETFILES
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#define _KERNEL /* for DTYPE_SOCKET */
+#include <sys/file.h>
+#undef _KERNEL
+
+#include <netinet/in.h>
+
+#include <kvm.h>
+/* #endif HAVE_KVM_GETFILES */
+
+/* This is for NetBSD. */
#elif HAVE_LIBKVM_NLIST
#include <arpa/inet.h>
#include <net/route.h>
#include <netdb.h>
#include <netinet/in.h>
@ -12,3 +53,73 @@ $OpenBSD: patch-src_tcpconns_c,v 1.10 2016/12/03 11:44:41 landry Exp $
#include <netinet/ip_var.h>
#include <netinet/tcp.h>
#include <netinet/tcp_timer.h>
@@ -169,6 +186,19 @@ static const char *tcp_state[] = {"CLOSED", "LISTEN
#define TCP_STATE_MAX 10
/* #endif HAVE_SYSCTLBYNAME */
+#elif HAVE_KVM_GETFILES
+static const char *tcp_state[] = {"CLOSED", "LISTEN", "SYN_SENT",
+ "SYN_RECV", "ESTABLISHED", "CLOSE_WAIT",
+ "FIN_WAIT1", "CLOSING", "LAST_ACK",
+ "FIN_WAIT2", "TIME_WAIT"};
+
+#define TCP_STATE_LISTEN 1
+#define TCP_STATE_MIN 0
+#define TCP_STATE_MAX 10
+
+static kvm_t *kvmd;
+/* #endif HAVE_KVM_GETFILES */
+
#elif HAVE_LIBKVM_NLIST
static const char *tcp_state[] = {"CLOSED", "LISTEN", "SYN_SENT",
"SYN_RECV", "ESTABLISHED", "CLOSE_WAIT",
@@ -775,6 +805,49 @@ static int conn_read(void) {
return (0);
} /* int conn_read */
/* #endif HAVE_SYSCTLBYNAME */
+
+#elif HAVE_KVM_GETFILES
+
+static int conn_init(void) {
+ char buf[_POSIX2_LINE_MAX];
+
+ kvmd = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, buf);
+ if (kvmd == NULL) {
+ ERROR("tcpconns plugin: kvm_openfiles failed: %s", buf);
+ return (-1);
+ }
+
+ return (0);
+} /* int conn_init */
+
+static int conn_read(void) {
+ struct kinfo_file *kf;
+ int i, fcnt;
+
+ conn_reset_port_entry();
+
+ kf = kvm_getfiles(kvmd, KERN_FILE_BYFILE, DTYPE_SOCKET,
+ sizeof(*kf), &fcnt);
+ if (kf == NULL) {
+ ERROR("tcpconns plugin: kvm_getfiles failed.");
+ return (-1);
+ }
+
+ for (i = 0; i < fcnt; i++) {
+ if (kf[i].so_protocol != IPPROTO_TCP)
+ continue;
+ if (kf[i].inp_fport == 0)
+ continue;
+ conn_handle_ports(ntohs(kf[i].inp_lport), ntohs(kf[i].inp_fport),
+ kf[i].t_state);
+ }
+
+ conn_submit_all();
+
+ return (0);
+}
+/* int conn_read */
+/* #endif HAVE_KVM_GETFILES */
#elif HAVE_LIBKVM_NLIST
static int kread(u_long addr, void *buf, int size) {