+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.
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
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]);
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]);
io_time = atof(fields[12]);
weighted_time = atof(fields[13]);
}
- } else {
- DEBUG("numfields = %i; => unknown file format.", numfields);
- continue;
}
{
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);
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) /* {{{ */
{
goto failed;
}
+ set_environment();
+
pid = fork();
if (pid < 0) {
ERROR("exec plugin: fork failed: %s", STRERRNO);
close(fd_pipe_err[1]);
}
- set_environment();
-
/* Unblock all signals */
reset_signal_mask();
/* does not return */
}
+ unset_environment();
+
close(fd_pipe_in[0]);
close(fd_pipe_out[1]);
close(fd_pipe_err[1]);
return pid;
failed:
+ unset_environment();
+
close_pipe(fd_pipe_in);
close_pipe(fd_pipe_out);
close_pipe(fd_pipe_err);
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;
}
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;
}
{"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"},
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
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;
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];
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) {
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;
}
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) {
#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);
}
/* 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
#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;
}
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;
#!/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'`"