Merge branch 'collectd-5.8' into master
authorPavel Rochnyack <pavel2000@ngs.ru>
Fri, 26 Oct 2018 17:29:52 +0000 (00:29 +0700)
committerPavel Rochnyack <pavel2000@ngs.ru>
Fri, 26 Oct 2018 17:29:52 +0000 (00:29 +0700)
Conflicts:
src/disk.c
src/virt.c

ChangeLog
configure.ac
src/disk.c
src/exec.c
src/ntpd.c
src/powerdns.c
src/utils_mount.c
src/virt.c
src/zfs_arc.c
version-gen.sh

index 5c7c42f..e9a8415 100644 (file)
--- 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.
index 4627965..86296d9 100644 (file)
@@ -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
index c0408ce..c78df4e 100644 (file)
@@ -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;
     }
 
     {
index 77b1375..26b8fa7 100644 (file)
@@ -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);
index ef63498..0b824ba 100644 (file)
@@ -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;
   }
 
index 7a2fbfd..644d0ae 100644 (file)
@@ -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"},
index e430cc9..279f8e2 100644 (file)
@@ -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
index c52a8a7..a828c45 100644 (file)
@@ -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;
 }
index c9abdd5..d1ee111 100644 (file)
@@ -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;
index f16e661..048b5a2 100755 (executable)
@@ -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'`"