#include "plugin.h"
#include "common.h"
#include "utils_avltree.h"
+#include "utils_random.h"
#include "utils_rrdcreate.h"
#include <rrd.h>
{
"CacheTimeout",
"CacheFlush",
+ "CreateFilesAsync",
"DataDir",
"StepSize",
"HeartBeat",
/* timespans_num = */ 0,
/* consolidation_functions = */ NULL,
- /* consolidation_functions_num = */ 0
+ /* consolidation_functions_num = */ 0,
+
+ /* async = */ 0
};
/* XXX: If you need to lock both, cache_lock and queue_lock, at the same time,
} /* int srrd_update */
#endif /* !HAVE_THREADSAFE_LIBRRD */
-static int value_list_to_string (char *buffer, int buffer_len,
+static int value_list_to_string_multiple (char *buffer, int buffer_len,
const data_set_t *ds, const value_list_t *vl)
{
int offset;
":%llu", vl->values[i].counter);
else if (ds->ds[i].type == DS_TYPE_GAUGE)
status = ssnprintf (buffer + offset, buffer_len - offset,
- ":%lf", vl->values[i].gauge);
+ ":"GAUGE_FORMAT, vl->values[i].gauge);
else if (ds->ds[i].type == DS_TYPE_DERIVE)
status = ssnprintf (buffer + offset, buffer_len - offset,
":%"PRIi64, vl->values[i].derive);
} /* for ds->ds_num */
return (0);
+} /* int value_list_to_string_multiple */
+
+static int value_list_to_string (char *buffer, int buffer_len,
+ const data_set_t *ds, const value_list_t *vl)
+{
+ int status;
+ time_t tt;
+
+ if (ds->ds_num != 1)
+ return (value_list_to_string_multiple (buffer, buffer_len,
+ ds, vl));
+
+ tt = CDTIME_T_TO_TIME_T (vl->time);
+ switch (ds->ds[0].type)
+ {
+ case DS_TYPE_DERIVE:
+ status = ssnprintf (buffer, buffer_len, "%u:%"PRIi64,
+ (unsigned) tt, vl->values[0].derive);
+ break;
+ case DS_TYPE_GAUGE:
+ status = ssnprintf (buffer, buffer_len, "%u:"GAUGE_FORMAT,
+ (unsigned) tt, vl->values[0].gauge);
+ break;
+ case DS_TYPE_COUNTER:
+ status = ssnprintf (buffer, buffer_len, "%u:%llu",
+ (unsigned) tt, vl->values[0].counter);
+ break;
+ case DS_TYPE_ABSOLUTE:
+ status = ssnprintf (buffer, buffer_len, "%u:%"PRIu64,
+ (unsigned) tt, vl->values[0].absolute);
+ break;
+ default:
+ return (EINVAL);
+ }
+
+ if ((status < 1) || (status >= buffer_len))
+ return (ENOMEM);
+
+ return (0);
} /* int value_list_to_string */
static int value_list_to_filename (char *buffer, size_t buffer_size,
if (datadir != NULL)
{
- size_t datadir_len = strlen (datadir);
+ size_t datadir_len = strlen (datadir) + 1;
if (datadir_len >= buffer_size)
return (ENOMEM);
sstrncpy (buffer, datadir, buffer_size);
+ buffer[datadir_len - 1] = '/';
+ buffer[datadir_len] = 0;
+
buffer += datadir_len;
buffer_size -= datadir_len;
}
static int64_t rrd_get_random_variation (void)
{
- double dbl_timeout;
- cdtime_t ctm_timeout;
- double rand_fact;
- _Bool negative;
- int64_t ret;
+ long min;
+ long max;
if (random_timeout <= 0)
return (0);
random_timeout = cache_timeout;
}
- /* This seems a bit complicated, but "random_timeout" is likely larger than
- * RAND_MAX, so we can't simply use modulo here. */
- dbl_timeout = CDTIME_T_TO_DOUBLE (random_timeout);
- rand_fact = ((double) random ())
- / ((double) RAND_MAX);
- negative = (_Bool) (random () % 2);
-
- ctm_timeout = DOUBLE_TO_CDTIME_T (dbl_timeout * rand_fact);
-
- ret = (int64_t) ctm_timeout;
- if (negative)
- ret *= -1;
+ max = (long) (random_timeout / 2);
+ min = max - ((long) random_timeout);
- return (ret);
+ return ((int64_t) cdrand_range (min, max));
} /* int64_t rrd_get_random_variation */
static int rrd_cache_insert (const char *filename,
{
rc = malloc (sizeof (*rc));
if (rc == NULL)
+ {
+ pthread_mutex_unlock (&cache_lock);
return (-1);
+ }
rc->values_num = 0;
rc->values = NULL;
rc->first_value = 0;
new_rc = 1;
}
+ assert (value_time > 0); /* plugin_dispatch() ensures this. */
if (rc->last_value >= value_time)
{
pthread_mutex_unlock (&cache_lock);
ds, vl, &rrdcreate_config);
if (status != 0)
return (-1);
+ else if (rrdcreate_config.async)
+ return (0);
}
else
{
}
else if (strcasecmp ("DataDir", key) == 0)
{
- if (datadir != NULL)
- free (datadir);
- datadir = strdup (value);
+ char *tmp;
+ size_t len;
+
+ tmp = strdup (value);
+ if (tmp == NULL)
+ {
+ ERROR ("rrdtool plugin: strdup failed.");
+ return (1);
+ }
+
+ len = strlen (tmp);
+ while ((len > 0) && (tmp[len - 1] == '/'))
+ {
+ len--;
+ tmp[len] = 0;
+ }
+
+ if (len == 0)
+ {
+ ERROR ("rrdtool plugin: Invalid \"DataDir\" option.");
+ sfree (tmp);
+ return (1);
+ }
+
if (datadir != NULL)
{
- int len = strlen (datadir);
- while ((len > 0) && (datadir[len - 1] == '/'))
- {
- len--;
- datadir[len] = '\0';
- }
- if (len <= 0)
- {
- free (datadir);
- datadir = NULL;
- }
+ sfree (datadir);
}
+
+ datadir = tmp;
}
else if (strcasecmp ("StepSize", key) == 0)
{
if (temp > 0)
rrdcreate_config.heartbeat = temp;
}
+ else if (strcasecmp ("CreateFilesAsync", key) == 0)
+ {
+ if (IS_TRUE (value))
+ rrdcreate_config.async = 1;
+ else
+ rrdcreate_config.async = 0;
+ }
else if (strcasecmp ("RRARows", key) == 0)
{
int tmp = atoi (value);
cache = c_avl_create ((int (*) (const void *, const void *)) strcmp);
if (cache == NULL)
{
+ pthread_mutex_unlock (&cache_lock);
ERROR ("rrdtool plugin: c_avl_create failed.");
return (-1);
}