src/utils_rrdcreate.c: Convert vl->interval to seconds when creating RRD files.
[collectd.git] / src / utils_rrdcreate.c
index 99feda2..5b13238 100644 (file)
@@ -23,6 +23,7 @@
 #include "common.h"
 #include "utils_rrdcreate.h"
 
+#include <pthread.h>
 #include <rrd.h>
 
 /*
@@ -46,6 +47,10 @@ static char *rra_types[] =
 };
 static int rra_types_num = STATIC_ARRAY_SIZE (rra_types);
 
+#if !defined(HAVE_THREADSAFE_LIBRRD) || !HAVE_THREADSAFE_LIBRRD
+static pthread_mutex_t librrd_lock = PTHREAD_MUTEX_INITIALIZER;
+#endif
+
 /*
  * Private functions
  */
@@ -98,7 +103,10 @@ static int rra_get (char ***ret, const value_list_t *vl, /* {{{ */
     return (-1);
   }
 
-  ss = (cfg->stepsize > 0) ? cfg->stepsize : vl->interval;
+  if (cfg->stepsize > 0)
+    ss = cfg->stepsize;
+  else
+    ss = (int) CDTIME_T_TO_TIME_T (vl->interval);
   if (ss <= 0)
   {
     *ret = NULL;
@@ -143,12 +151,15 @@ static int rra_get (char ***ret, const value_list_t *vl, /* {{{ */
 
     for (j = 0; j < rra_types_num; j++)
     {
+      int status;
+
       if (rra_num >= rra_max)
         break;
 
-      if (ssnprintf (buffer, sizeof (buffer), "RRA:%s:%3.1f:%u:%u",
-            rra_types[j], cfg->xff,
-            cdp_len, cdp_num) >= sizeof (buffer))
+      status = ssnprintf (buffer, sizeof (buffer), "RRA:%s:%3.1f:%u:%u",
+          rra_types[j], cfg->xff, cdp_len, cdp_num);
+
+      if ((status < 0) || ((size_t) status >= sizeof (buffer)))
       {
         ERROR ("rra_get: Buffer would have been truncated.");
         continue;
@@ -205,6 +216,10 @@ static int ds_get (char ***ret, /* {{{ */
       type = "COUNTER";
     else if (d->type == DS_TYPE_GAUGE)
       type = "GAUGE";
+    else if (d->type == DS_TYPE_DERIVE)
+      type = "DERIVE";
+    else if (d->type == DS_TYPE_ABSOLUTE)
+      type = "ABSOLUTE";
     else
     {
       ERROR ("rrdtool plugin: Unknown DS type: %i",
@@ -217,21 +232,23 @@ static int ds_get (char ***ret, /* {{{ */
       sstrncpy (min, "U", sizeof (min));
     }
     else
-      ssnprintf (min, sizeof (min), "%lf", d->min);
+      ssnprintf (min, sizeof (min), "%f", d->min);
 
     if (isnan (d->max))
     {
       sstrncpy (max, "U", sizeof (max));
     }
     else
-      ssnprintf (max, sizeof (max), "%lf", d->max);
+      ssnprintf (max, sizeof (max), "%f", d->max);
 
     status = ssnprintf (buffer, sizeof (buffer),
         "DS:%s:%s:%i:%s:%s",
         d->name, type,
-        (cfg->heartbeat > 0) ? cfg->heartbeat : (2 * vl->interval),
+        (cfg->heartbeat > 0)
+        ? cfg->heartbeat
+        : (int) CDTIME_T_TO_TIME_T (2 * vl->interval),
         min, max);
-    if ((status < 1) || (status >= sizeof (buffer)))
+    if ((status < 1) || ((size_t) status >= sizeof (buffer)))
       break;
 
     ds_def[ds_num] = sstrdup (buffer);
@@ -253,11 +270,26 @@ static int srrd_create (const char *filename, /* {{{ */
     int argc, const char **argv)
 {
   int status;
+  char *filename_copy;
+
+  if ((filename == NULL) || (argv == NULL))
+    return (-EINVAL);
+
+  /* Some versions of librrd don't have the `const' qualifier for the first
+   * argument, so we have to copy the pointer here to avoid warnings. It sucks,
+   * but what else can we do? :(  -octo */
+  filename_copy = strdup (filename);
+  if (filename_copy == NULL)
+  {
+    ERROR ("srrd_create: strdup failed.");
+    return (-ENOMEM);
+  }
 
   optind = 0; /* bug in librrd? */
   rrd_clear_error ();
 
-  status = rrd_create_r (filename, pdp_step, last_up, argc, (void *) argv);
+  status = rrd_create_r (filename_copy, pdp_step, last_up,
+      argc, (void *) argv);
 
   if (status != 0)
   {
@@ -265,6 +297,8 @@ static int srrd_create (const char *filename, /* {{{ */
         filename, rrd_get_error ());
   }
 
+  sfree (filename_copy);
+
   return (status);
 } /* }}} int srrd_create */
 /* #endif HAVE_THREADSAFE_LIBRRD */
@@ -294,10 +328,10 @@ static int srrd_create (const char *filename, /* {{{ */
     last_up = time (NULL) - 10;
 
   ssnprintf (pdp_step_str, sizeof (pdp_step_str), "%lu", pdp_step);
-  ssnprintf (last_up_str, sizeof (last_up_str), "%u", (unsigned int) last_up);
+  ssnprintf (last_up_str, sizeof (last_up_str), "%lu", (unsigned long) last_up);
 
   new_argv[0] = "create";
-  new_argv[1] = filename;
+  new_argv[1] = (void *) filename;
   new_argv[2] = "-s";
   new_argv[3] = pdp_step_str;
   new_argv[4] = "-b";
@@ -339,6 +373,8 @@ int cu_rrd_create_file (const char *filename, /* {{{ */
   char **ds_def;
   int ds_num;
   int status = 0;
+  time_t last_up;
+  int stepsize;
 
   if (check_create_dir (filename))
     return (-1);
@@ -369,10 +405,19 @@ int cu_rrd_create_file (const char *filename, /* {{{ */
   memcpy (argv + ds_num, rra_def, rra_num * sizeof (char *));
   argv[ds_num + rra_num] = NULL;
 
-  assert (vl->time > 10);
+  last_up = CDTIME_T_TO_TIME_T (vl->time);
+  if (last_up <= 10)
+    last_up = time (NULL);
+  last_up -= 10;
+
+  if (cfg->stepsize > 0)
+    stepsize = cfg->stepsize;
+  else
+    stepsize = (int) CDTIME_T_TO_TIME_T (vl->interval);
+
   status = srrd_create (filename,
-      (cfg->stepsize > 0) ? cfg->stepsize : vl->interval,
-      vl->time - 10,
+      (cfg->stepsize > 0) ? cfg->stepsize : CDTIME_T_TO_TIME_T (vl->interval),
+      last_up,
       argc, (const char **) argv);
 
   free (argv);