From 22912eb530d3352544a450c149ae59d7f6ae0266 Mon Sep 17 00:00:00 2001 From: Florian Forster Date: Thu, 7 Dec 2017 21:20:40 +0100 Subject: [PATCH] processes plugin: Check for the CAP_NET_ADMIN capability. This allows us to print helpful error messages to the user if something goes wrong. --- src/collectd.conf.pod | 2 +- src/processes.c | 41 ++++++++++++++++++++++++++++++++++++----- 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/src/collectd.conf.pod b/src/collectd.conf.pod index 2b2c1e9b..dab723a0 100644 --- a/src/collectd.conf.pod +++ b/src/collectd.conf.pod @@ -6895,7 +6895,7 @@ freed pages to be reclaimed. The metrics are reported as a percentage, e.g. C. Disabled by default. This option is only available on Linux, requires the C library and -requires root privileges at runtime. +requires the C capability at runtime. =item B I diff --git a/src/processes.c b/src/processes.c index 30f4e32f..2e9715dd 100644 --- a/src/processes.c +++ b/src/processes.c @@ -158,6 +158,10 @@ #include #endif +#ifdef HAVE_SYS_CAPABILITY_H +#include +#endif + #ifndef CMDLINE_BUFFER_SIZE #if defined(ARG_MAX) && (ARG_MAX < 4096) #define CMDLINE_BUFFER_SIZE ARG_MAX @@ -1215,10 +1219,38 @@ static int ps_delay(process_entry_t *ps) { int status = ts_delay_by_tgid(taskstats_handle, (uint32_t)ps->id, &ps->delay); if (status == EPERM) { static c_complain_t c; - c_complain(LOG_ERR, &c, "processes plugin: reading delay information " - "failed: \"%s\". This is probably because the " - "taskstats interface requires root privileges.", +#if defined(HAVE_SYS_CAPABILITY_H) && defined(CAP_NET_ADMIN) + if (check_capability(CAP_NET_ADMIN) != 0) { + if (getuid() == 0) { + c_complain( + LOG_ERR, &c, + "processes plugin: Reading Delay Accounting metric failed: %s. " + "collectd is running as root, but missing the CAP_NET_ADMIN " + "capability. The most common cause for this is that the init " + "system is dropping capabilities.", + STRERROR(status)); + } else { + c_complain( + LOG_ERR, &c, + "processes plugin: Reading Delay Accounting metric failed: %s. " + "collectd is not running as root and missing the CAP_NET_ADMIN " + "capability. Either run collectd as root or grant it the " + "CAP_NET_ADMIN capability using \"setcap cap_net_admin=ep " PREFIX + "/sbin/collectd\".", + STRERROR(status)); + } + } else { + ERROR("processes plugin: ts_delay_by_tgid failed: %s. The CAP_NET_ADMIN " + "capability is available (I checked), so this error is utterly " + "unexpected.", + STRERROR(status)); + } +#else + c_complain(LOG_ERR, &c, + "processes plugin: Reading Delay Accounting metric failed: %s. " + "Reading Delay Accounting metrics requires root privileges.", STRERROR(status)); +#endif return status; } else if (status != 0) { ERROR("processes plugin: ts_delay_by_tgid failed: %s", STRERROR(status)); @@ -1757,8 +1789,7 @@ static int mach_get_task_name(task_t t, int *pid, char *name, return 0; } #endif /* HAVE_THREAD_INFO */ -/* ------- end of additional functions for KERNEL_LINUX/HAVE_THREAD_INFO ------- - */ +/* end of additional functions for KERNEL_LINUX/HAVE_THREAD_INFO */ /* do actual readings from kernel */ static int ps_read(void) { -- 2.11.0