From: Pavel Rochnyack Date: Fri, 26 Oct 2018 17:29:52 +0000 (+0700) Subject: Merge branch 'collectd-5.8' into master X-Git-Url: https://git.octo.it/?p=collectd.git;a=commitdiff_plain;h=c00630eab6161514c1044e8adb2895f179a535da;hp=db13c6de0558fac44baed03c24af111c50dad7ec Merge branch 'collectd-5.8' into master Conflicts: src/disk.c src/virt.c --- diff --git a/ChangeLog b/ChangeLog index 5c7c42f8..e9a8415b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,78 @@ +2018-10-23, Version 5.8.1 + * collectd: Fix "BaseDir" option. Thanks to Mariusz Białończyk and + Pavel Rochnyak. #2857 + * collectd: improve error handling, check return values. Thanks to + Florian Forster. + * Build System: use "kstat.h", when available. Thanks to Dagobert + Michelsen and Pavel Rochnyak. #2784 + * Build System: Fix distcheck on MacOS. Thanks to Ruben Kerkhof. + * Build System: add missing include of ""collectd.h"" to fix builds on + Solaris. Thanks to Pavel Rochnyak. + * Build System: add endianess checks for AIX, fix GCC issue on Mac + byteorder, fix byteorder on Solaris, add fallback for endianess + conversion. Thanks to Dagobert Michelsen (multiple cherry picks from + master). + * Build System: Out-of-tree builds have been fixed. Thanks to Florian + Forster. #2602 + * Configuration: Error handling in the config parsing code has been + improved. Thanks to Florian Forster. + * Documentation: Fix typo in collectd.conf(5). Thanks to Pavel Rochnyak. + #2760 + * Documentation: update note on dpdkstat. Thanks to Maryam Tahhan. #2613 + * Various plugins: Errors found by the static code analysis tool + Coverity were fixed. Thanks to Florian Forster. #2559, #2560, #2561, + #2562, #2563, #2565, #2568, #2575, #2579, #2580, #2588, #2589 + * Ceph plugin: A segfault has been fixed. Thanks to Aleksei Zakharov and + Matthias Runge. #2572 + * DF plugin: fix memory leak in error case. Thanks to Takahashi tsc. + * Exec plugin: check return value of "plugin_thread_create()". Thanks to + Florian Forster. + * Exec plugin: Handling of large groups has been fixed. Thanks to + Sridhar Mallem. #2696 + * Exec plugin: Incorrect use of *putenv(3)* has been fixed. Thanks to + Daniel Vrátil. + * Exec plugin: A deadlock related to setting environment variables after + *fork()* has been fixed. Thanks to Daniel Vrátil. + * Intel PMU plugin: add core groups feature. Thanks to Kamil Wiatrowski. + #2681 + * Intel PMU plugin: fix compatibility issue with collectd 5.8. Thanks to + Kamil Wiatrowski. + * Intel PMU plugin: fix possible "NULL" pointer dereference. Thanks to + Kamil Wiatrowski. #2676 + * IPMI plugin: A segfault caused by a wrong data type has been fixed. + Thanks to Mariusz Szafrański. #2742 + * IPMI plugin: The sensor configuration option has been fixed. Thanks to + Pavel Rochnyak. #2629 + * memcached plugin: A deadlock situation has been fixed. Thanks to Pavel + Rochnyak. #2612 + * NFS plugin: Support for NFSv4 has been fixed. Thanks to Jan-Philipp + Litza. #2076 + * NTPd plugin: A memory leak in the error handling path has been fixed. + Thanks to Ruben Kerkhof. #2942 + * OVS Stats plugin: A deadlock situation has been fixed. Thanks to + Volodymyr Mytnyk. #2590 + * OVS Stats plugin: Fix reconnect after thread terminated. Thanks to + Volodymyr Mytnyk and Maram Tahhan. #2574 + * Perl plugin: A compilation failure has been fixed. Thanks to Pavel + Rochnyak. #2732 + * Perl plugin: Fix exporting notification meta data. Thanks to Florian + Forster. + * RRDtool plugin: Handling of very large "GAUGE" metrics has been fixed. + Thanks to Miroslav Lichvar. #2566 + * Tail plugin: Several regressions have been fixed. Thanks to Pavel + Rochnyak. #2535, #2587, #2611 + * turbostat plugin: A potential segfault due to an incorrect *free()* + has been fixed. Thanks to Ruben Kerkhof. #2948 + * UUID plugin: Fix hostname setting. Thanks to Pavel Rochnyak. #2723 + * virt plugin: A segfault during error handling has been fixed. Thanks + to Ruben Kerkhof. {{Issue|2919]} + * Write Kafka plugin: A build failure due to a deprecated API call has + been fixed. Thanks to Pavel Rochnyak. #2607, #2628, #2640 + * Write Prometheus plugin: Fix "MHD_USE_INTERNAL_POLLING_THREAD" flag in + newer libmicrohttpd. Thanks to Pavel Rochnyak. #2849 + * Write Prometheus plugin: set "SO_REUSEADDRESS" on listening socket. + Thanks to Pavel Rochnyak. #2570, #2673 + 2017-11-17, Version 5.8.0 * collectd: The core daemon is now completely licensed under the MIT license. diff --git a/configure.ac b/configure.ac index 46279652..86296d9f 100644 --- a/configure.ac +++ b/configure.ac @@ -5745,15 +5745,15 @@ if test "x$with_libxmms" = "xyes"; then fi if test "x$with_libxmms" = "xyes"; then - SAVE_CFLAGS="$CFLAGS" - CFLAGS="$with_xmms_cflags" + SAVE_CPPFLAGS="$CFLAGS" + CPPFLAGS="$with_xmms_cflags" AC_CHECK_HEADER([xmmsctrl.h], [with_libxmms="yes"], [with_libxmms="no"], ) - CFLAGS="$SAVE_CFLAGS" + CPPFLAGS="$SAVE_CPPFLAGS" fi if test "x$with_libxmms" = "xyes"; then diff --git a/src/disk.c b/src/disk.c index c0408cec..c78df4ec 100644 --- a/src/disk.c +++ b/src/disk.c @@ -692,7 +692,9 @@ static int disk_read(void) { char *output_name; numfields = strsplit(buffer, fields, 32); - if ((numfields != 14) && (numfields != 7)) + + /* need either 7 fields (partition) or at least 14 fields */ + if ((numfields != 7) && (numfields < 14)) continue; minor = atoll(fields[1]); @@ -726,7 +728,8 @@ static int disk_read(void) { read_sectors = atoll(fields[4]); write_ops = atoll(fields[5]); write_sectors = atoll(fields[6]); - } else if (numfields == 14) { + } else { + assert(numfields >= 14); read_ops = atoll(fields[3]); write_ops = atoll(fields[7]); @@ -745,9 +748,6 @@ static int disk_read(void) { io_time = atof(fields[12]); weighted_time = atof(fields[13]); } - } else { - DEBUG("numfields = %i; => unknown file format.", numfields); - continue; } { diff --git a/src/exec.c b/src/exec.c index 77b13755..26b8fa7e 100644 --- a/src/exec.c +++ b/src/exec.c @@ -245,11 +245,17 @@ static int exec_config(oconfig_item_t *ci) /* {{{ */ return 0; } /* int exec_config }}} */ +#if !defined(HAVE_SETENV) +static char env_interval[64]; +// max hostname len is 255, so this should be enough +static char env_hostname[300]; +#endif + static void set_environment(void) /* {{{ */ { +#ifdef HAVE_SETENV char buffer[1024]; -#ifdef HAVE_SETENV snprintf(buffer, sizeof(buffer), "%.3f", CDTIME_T_TO_DOUBLE(plugin_get_interval())); setenv("COLLECTD_INTERVAL", buffer, /* overwrite = */ 1); @@ -257,15 +263,29 @@ static void set_environment(void) /* {{{ */ sstrncpy(buffer, hostname_g, sizeof(buffer)); setenv("COLLECTD_HOSTNAME", buffer, /* overwrite = */ 1); #else - snprintf(buffer, sizeof(buffer), "COLLECTD_INTERVAL=%.3f", + snprintf(env_interval, sizeof(env_interval), "COLLECTD_INTERVAL=%.3f", CDTIME_T_TO_DOUBLE(plugin_get_interval())); - putenv(buffer); + putenv(env_interval); - snprintf(buffer, sizeof(buffer), "COLLECTD_HOSTNAME=%s", hostname_g); - putenv(buffer); + snprintf(env_hostname, sizeof(env_hostname), "COLLECTD_HOSTNAME=%s", + hostname_g); + putenv(env_hostname); #endif } /* }}} void set_environment */ +static void unset_environment(void) /* {{{ */ +{ +#ifdef HAVE_SETENV + unsetenv("COLLECTD_INTERVAL"); + unsetenv("COLLECTD_HOSTNAME"); +#else + snprintf(env_interval, sizeof(env_interval), "COLLECTD_INTERVAL"); + putenv(env_interval); + snprintf(env_hostname, sizeof(env_hostname), "COLLECTD_HOSTNAME"); + putenv(env_hostname); +#endif +} /* }}} void unset_environment */ + __attribute__((noreturn)) static void exec_child(program_list_t *pl, int uid, int gid, int egid) /* {{{ */ { @@ -466,6 +486,8 @@ static int fork_child(program_list_t *pl, int *fd_in, int *fd_out, goto failed; } + set_environment(); + pid = fork(); if (pid < 0) { ERROR("exec plugin: fork failed: %s", STRERRNO); @@ -500,8 +522,6 @@ static int fork_child(program_list_t *pl, int *fd_in, int *fd_out, close(fd_pipe_err[1]); } - set_environment(); - /* Unblock all signals */ reset_signal_mask(); @@ -509,6 +529,8 @@ static int fork_child(program_list_t *pl, int *fd_in, int *fd_out, /* does not return */ } + unset_environment(); + close(fd_pipe_in[0]); close(fd_pipe_out[1]); close(fd_pipe_err[1]); @@ -531,6 +553,8 @@ static int fork_child(program_list_t *pl, int *fd_in, int *fd_out, return pid; failed: + unset_environment(); + close_pipe(fd_pipe_in); close_pipe(fd_pipe_out); close_pipe(fd_pipe_err); diff --git a/src/ntpd.c b/src/ntpd.c index ef634988..0b824ba2 100644 --- a/src/ntpd.c +++ b/src/ntpd.c @@ -810,11 +810,13 @@ static int ntpd_read(void) { if (status != 0) { ERROR("ntpd plugin: ntpd_do_query (REQ_GET_KERNEL) failed with status %i", status); + free(ik); return status; } else if ((ik == NULL) || (ik_num == 0) || (ik_size == 0)) { ERROR("ntpd plugin: ntpd_do_query returned unexpected data. " "(ik = %p; ik_num = %i; ik_size = %i)", (void *)ik, ik_num, ik_size); + free(ik); return -1; } @@ -849,11 +851,13 @@ static int ntpd_read(void) { ERROR( "ntpd plugin: ntpd_do_query (REQ_PEER_LIST_SUM) failed with status %i", status); + free(ps); return status; } else if ((ps == NULL) || (ps_num == 0) || (ps_size == 0)) { ERROR("ntpd plugin: ntpd_do_query returned unexpected data. " "(ps = %p; ps_num = %i; ps_size = %i)", (void *)ps, ps_num, ps_size); + free(ps); return -1; } diff --git a/src/powerdns.c b/src/powerdns.c index 7a2fbfd6..644d0ae7 100644 --- a/src/powerdns.c +++ b/src/powerdns.c @@ -279,7 +279,7 @@ static statname_lookup_t lookup_table[] = /* {{{ */ {"ipv6-questions", "dns_question", "incoming-ipv6"}, {"malloc-bytes", "gauge", "malloc_bytes"}, {"max-mthread-stack", "gauge", "max_mthread_stack"}, - {"no-packet-error", "gauge", "no_packet_error"}, + {"no-packet-error", "errors", "no_packet_error"}, {"noedns-outqueries", "dns_question", "outgoing-noedns"}, {"noping-outqueries", "dns_question", "outgoing-noping"}, {"over-capacity-drops", "dns_question", "incoming-over_capacity"}, diff --git a/src/utils_mount.c b/src/utils_mount.c index e430cc9c..279f8e2f 100644 --- a/src/utils_mount.c +++ b/src/utils_mount.c @@ -651,6 +651,8 @@ cu_mount_t *cu_mount_getlist(cu_mount_t **list) { new = cu_mount_gen_getmntent(); #elif HAVE_SEQ_GETMNTENT #error "This version of `getmntent' hat not yet been implemented!" +#elif HAVE_GETMNTENT_R + new = cu_mount_getmntent(); #elif HAVE_ONE_GETMNTENT new = cu_mount_getmntent(); #else diff --git a/src/virt.c b/src/virt.c index c52a8a7e..a828c456 100644 --- a/src/virt.c +++ b/src/virt.c @@ -639,12 +639,6 @@ static time_t last_refresh = (time_t)0; static int refresh_lists(struct lv_read_instance *inst); -struct lv_info { - virDomainInfo di; - unsigned long long total_user_cpu_time; - unsigned long long total_syst_cpu_time; -}; - struct lv_block_info { virDomainBlockStatsStruct bi; @@ -708,59 +702,9 @@ static int get_block_info(struct lv_block_info *binfo, virErrorPtr err; \ err = (conn) ? virConnGetLastError((conn)) : virGetLastError(); \ if (err) \ - ERROR("%s: %s", (s), err->message); \ + ERROR(PLUGIN_NAME " plugin: %s failed: %s", (s), err->message); \ } while (0) -static void init_lv_info(struct lv_info *info) { - if (info != NULL) - memset(info, 0, sizeof(*info)); -} - -static int lv_domain_info(virDomainPtr dom, struct lv_info *info) { -#ifdef HAVE_CPU_STATS - virTypedParameterPtr param = NULL; - int nparams = 0; -#endif /* HAVE_CPU_STATS */ - int ret = virDomainGetInfo(dom, &(info->di)); - if (ret != 0) { - return ret; - } - -#ifdef HAVE_CPU_STATS - nparams = virDomainGetCPUStats(dom, NULL, 0, -1, 1, 0); - if (nparams < 0) { - VIRT_ERROR(conn, "getting the CPU params count"); - return -1; - } - - param = calloc(nparams, sizeof(virTypedParameter)); - if (param == NULL) { - ERROR("virt plugin: alloc(%i) for cpu parameters failed.", nparams); - return -1; - } - - ret = virDomainGetCPUStats(dom, param, nparams, -1, 1, 0); // total stats. - if (ret < 0) { - virTypedParamsClear(param, nparams); - sfree(param); - VIRT_ERROR(conn, "getting the disk params values"); - return -1; - } - - for (int i = 0; i < nparams; ++i) { - if (!strcmp(param[i].field, "user_time")) - info->total_user_cpu_time = param[i].value.ul; - else if (!strcmp(param[i].field, "system_time")) - info->total_syst_cpu_time = param[i].value.ul; - } - - virTypedParamsClear(param, nparams); - sfree(param); -#endif /* HAVE_CPU_STATS */ - - return 0; -} - static void init_value_list(value_list_t *vl, virDomainPtr dom) { const char *name; char uuid[VIR_UUID_STRING_BUFLEN]; @@ -892,14 +836,6 @@ static void submit_derive2(const char *type, derive_t v0, derive_t v1, submit(dom, type, devname, values, STATIC_ARRAY_SIZE(values)); } /* void submit_derive2 */ -static void pcpu_submit(virDomainPtr dom, struct lv_info *info) { -#ifdef HAVE_CPU_STATS - if (extra_stats & ex_stats_pcpu) - submit_derive2("ps_cputime", info->total_user_cpu_time, - info->total_syst_cpu_time, dom, NULL); -#endif /* HAVE_CPU_STATS */ -} - static double cpu_ns_to_percent(unsigned int node_cpus, unsigned long long cpu_time_old, unsigned long long cpu_time_new) { @@ -1411,13 +1347,13 @@ static int get_vcpu_stats(virDomainPtr domain, unsigned short nr_virt_cpu) { virVcpuInfoPtr vinfo = calloc(nr_virt_cpu, sizeof(vinfo[0])); if (vinfo == NULL) { - ERROR(PLUGIN_NAME " plugin: malloc failed."); + ERROR(PLUGIN_NAME " plugin: calloc failed."); return -1; } unsigned char *cpumaps = calloc(nr_virt_cpu, cpu_map_len); if (cpumaps == NULL) { - ERROR(PLUGIN_NAME " plugin: malloc failed."); + ERROR(PLUGIN_NAME " plugin: calloc failed."); sfree(vinfo); return -1; } @@ -1443,6 +1379,49 @@ static int get_vcpu_stats(virDomainPtr domain, unsigned short nr_virt_cpu) { return 0; } +#ifdef HAVE_CPU_STATS +static int get_pcpu_stats(virDomainPtr dom) { + int nparams = virDomainGetCPUStats(dom, NULL, 0, -1, 1, 0); + if (nparams < 0) { + VIRT_ERROR(conn, "getting the CPU params count"); + return -1; + } + + virTypedParameterPtr param = calloc(nparams, sizeof(virTypedParameter)); + if (param == NULL) { + ERROR(PLUGIN_NAME " plugin: alloc(%i) for cpu parameters failed.", nparams); + return -1; + } + + int ret = virDomainGetCPUStats(dom, param, nparams, -1, 1, 0); // total stats. + if (ret < 0) { + virTypedParamsClear(param, nparams); + sfree(param); + VIRT_ERROR(conn, "getting the CPU params values"); + return -1; + } + + unsigned long long total_user_cpu_time = 0; + unsigned long long total_syst_cpu_time = 0; + + for (int i = 0; i < nparams; ++i) { + if (!strcmp(param[i].field, "user_time")) + total_user_cpu_time = param[i].value.ul; + else if (!strcmp(param[i].field, "system_time")) + total_syst_cpu_time = param[i].value.ul; + } + + if (total_user_cpu_time > 0 || total_syst_cpu_time > 0) + submit_derive2("ps_cputime", total_user_cpu_time, total_syst_cpu_time, dom, + NULL); + + virTypedParamsClear(param, nparams); + sfree(param); + + return 0; +} +#endif /* HAVE_CPU_STATS */ + #ifdef HAVE_DOM_REASON static void domain_state_submit(virDomainPtr dom, int state, int reason) { @@ -1716,15 +1695,13 @@ static int get_job_stats(virDomainPtr domain) { #endif /* HAVE_JOB_STATS */ static int get_domain_metrics(domain_t *domain) { - struct lv_info info; - if (!domain || !domain->ptr) { - ERROR(PLUGIN_NAME ": get_domain_metrics: NULL pointer"); + ERROR(PLUGIN_NAME "plugin: get_domain_metrics: NULL pointer"); return -1; } - init_lv_info(&info); - int status = lv_domain_info(domain->ptr, &info); + virDomainInfo info; + int status = virDomainGetInfo(domain->ptr, &info); if (status != 0) { ERROR(PLUGIN_NAME " plugin: virDomainGetInfo failed with status %i.", status); @@ -1742,15 +1719,19 @@ static int get_domain_metrics(domain_t *domain) { } /* Gather remaining stats only for running domains */ - if (info.di.state != VIR_DOMAIN_RUNNING) + if (info.state != VIR_DOMAIN_RUNNING) return 0; - pcpu_submit(domain->ptr, &info); - cpu_submit(domain, info.di.cpuTime); +#ifdef HAVE_CPU_STATS + if (extra_stats & ex_stats_pcpu) + get_pcpu_stats(domain->ptr); +#endif + + cpu_submit(domain, info.cpuTime); - memory_submit(domain->ptr, (gauge_t)info.di.memory * 1024); + memory_submit(domain->ptr, (gauge_t)info.memory * 1024); - GET_STATS(get_vcpu_stats, "vcpu stats", domain->ptr, info.di.nrVirtCpu); + GET_STATS(get_vcpu_stats, "vcpu stats", domain->ptr, info.nrVirtCpu); GET_STATS(get_memory_stats, "memory stats", domain->ptr); #ifdef HAVE_PERF_STATS @@ -1775,7 +1756,7 @@ static int get_domain_metrics(domain_t *domain) { #endif /* Update cached virDomainInfo. It has to be done after cpu_submit */ - memcpy(&domain->info, &info.di, sizeof(domain->info)); + memcpy(&domain->info, &info, sizeof(domain->info)); return 0; } diff --git a/src/zfs_arc.c b/src/zfs_arc.c index c9abdd5f..d1ee111b 100644 --- a/src/zfs_arc.c +++ b/src/zfs_arc.c @@ -231,6 +231,23 @@ static int za_read(void) { return -1; } + // Ignore the first two lines because they contain information about + // the rest of the file. + // See kstat_seq_show_headers module/spl/spl-kstat.c of the spl kernel + // module. + if (fgets(buffer, sizeof(buffer), fh) == NULL) { + ERROR("zfs_arc plugin: \"%s\" does not contain a single line.", + ZOL_ARCSTATS_FILE); + fclose(fh); + return (-1); + } + if (fgets(buffer, sizeof(buffer), fh) == NULL) { + ERROR("zfs_arc plugin: \"%s\" does not contain at least two lines.", + ZOL_ARCSTATS_FILE); + fclose(fh); + return (-1); + } + while (fgets(buffer, sizeof(buffer), fh) != NULL) { char *fields[3]; value_t v; diff --git a/version-gen.sh b/version-gen.sh index f16e6616..048b5a21 100755 --- a/version-gen.sh +++ b/version-gen.sh @@ -1,6 +1,6 @@ #!/bin/sh -DEFAULT_VERSION="5.8.0.git" +DEFAULT_VERSION="5.8.1.git" if [ -d .git ]; then VERSION="`git describe --dirty=+ --abbrev=7 2> /dev/null | grep collectd | sed -e 's/^collectd-//' -e 's/-/./g'`"