X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fprocesses.c;h=d73d24a2a064488c030b79040e98f26ad49239d5;hb=f42de42e5caa71fd8da9e79eb452ade6e9f20519;hp=30f4e32fb7f3bb36d5fd0a2bf216cb702caefb83;hpb=4ea7a57256f5e4d77f4fff052490b7f67a9a3829;p=collectd.git diff --git a/src/processes.c b/src/processes.c index 30f4e32f..d73d24a2 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 @@ -653,7 +657,7 @@ static void ps_tune_instance(oconfig_item_t *ci, procstat_t *ps) { "for the \"CollectDelayAccounting\" option."); #endif } else { - ERROR("processes plugin: Option `%s' not allowed heeere.", c->key); + ERROR("processes plugin: Option \"%s\" not allowed here.", c->key); } } /* for (ci->children) */ } /* void ps_tune_instance */ @@ -681,7 +685,8 @@ static int ps_config(oconfig_item_t *ci) { #if KERNEL_LINUX || KERNEL_SOLARIS || KERNEL_FREEBSD if (strlen(c->values[0].value.string) > max_procname_len) { - WARNING("processes plugin: this platform has a %zu character limit " + WARNING("processes plugin: this platform has a %" PRIsz + " character limit " "to process names. The `Process \"%s\"' option will " "not work as expected.", max_procname_len, c->values[0].value.string); @@ -899,38 +904,27 @@ static void ps_submit_proc_list(procstat_t *ps) { plugin_dispatch_values(&vl); } - /* The ps->delay_* metrics are in nanoseconds per second. This factor converts - * them to a percentage. */ - gauge_t const delay_factor = 100.0 / 1000000000.0; - - if (!isnan(ps->delay_cpu)) { - sstrncpy(vl.type, "percent", sizeof(vl.type)); - sstrncpy(vl.type_instance, "delay-cpu", sizeof(vl.type_instance)); - vl.values[0].gauge = ps->delay_cpu * delay_factor; - vl.values_len = 1; - plugin_dispatch_values(&vl); - } - - if (!isnan(ps->delay_blkio)) { - sstrncpy(vl.type, "percent", sizeof(vl.type)); - sstrncpy(vl.type_instance, "delay-blkio", sizeof(vl.type_instance)); - vl.values[0].gauge = ps->delay_blkio * delay_factor; - vl.values_len = 1; - plugin_dispatch_values(&vl); - } - - if (!isnan(ps->delay_swapin)) { - sstrncpy(vl.type, "percent", sizeof(vl.type)); - sstrncpy(vl.type_instance, "delay-swapin", sizeof(vl.type_instance)); - vl.values[0].gauge = ps->delay_swapin * delay_factor; - vl.values_len = 1; - plugin_dispatch_values(&vl); - } - - if (!isnan(ps->delay_freepages)) { - sstrncpy(vl.type, "percent", sizeof(vl.type)); - sstrncpy(vl.type_instance, "delay-freepages", sizeof(vl.type_instance)); - vl.values[0].gauge = ps->delay_freepages * delay_factor; + /* The ps->delay_* metrics are in nanoseconds per second. Convert to seconds + * per second. */ + gauge_t const delay_factor = 1000000000.0; + + struct { + char *type_instance; + gauge_t rate_ns; + } delay_metrics[] = { + {"delay-cpu", ps->delay_cpu}, + {"delay-blkio", ps->delay_blkio}, + {"delay-swapin", ps->delay_swapin}, + {"delay-freepages", ps->delay_freepages}, + }; + for (size_t i = 0; i < STATIC_ARRAY_SIZE(delay_metrics); i++) { + if (isnan(delay_metrics[i].rate_ns)) { + continue; + } + sstrncpy(vl.type, "delay_rate", sizeof(vl.type)); + sstrncpy(vl.type_instance, delay_metrics[i].type_instance, + sizeof(vl.type_instance)); + vl.values[0].gauge = delay_metrics[i].rate_ns * delay_factor; vl.values_len = 1; plugin_dispatch_values(&vl); } @@ -1215,10 +1209,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)); @@ -1227,10 +1249,6 @@ static int ps_delay(process_entry_t *ps) { return 0; } -#else -static int ps_delay(__attribute__((unused)) process_entry_t *unused) { - return -1; -} #endif static void ps_fill_details(const procstat_t *ps, process_entry_t *entry) { @@ -1318,7 +1336,8 @@ static int ps_read_process(long pid, process_entry_t *ps, char *state) { /* Either '(' or ')' is not found or they are in the wrong order. * Anyway, something weird that shouldn't happen ever. */ if (name_start_pos >= name_end_pos) { - ERROR("processes plugin: name_start_pos = %zu >= name_end_pos = %zu", + ERROR("processes plugin: name_start_pos = %" PRIsz + " >= name_end_pos = %" PRIsz, name_start_pos, name_end_pos); return -1; } @@ -1552,7 +1571,7 @@ static char *ps_get_cmdline(long pid, if ((status < 0) || (((size_t)status) != sizeof(info))) { ERROR("processes plugin: Unexpected return value " "while reading \"%s\": " - "Returned %zd but expected %zu.", + "Returned %zd but expected %" PRIsz ".", path, status, buffer_size); return NULL; } @@ -1757,8 +1776,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) {