write_queue_t *next;
};
+struct flush_callback_s {
+ char *name;
+ cdtime_t timeout;
+};
+typedef struct flush_callback_s flush_callback_t;
+
/*
* Private variables
*/
{
ERROR ("plugin: register_callback: "
"llentry_create failed.");
- free (key);
+ sfree (key);
destroy_callback (cf);
return (-1);
}
*str = '\0';
strjoin(str, len, keys, n, "', '");
INFO("%s ['%s']", comment, str);
- free(str);
+ sfree (str);
}
- free(keys);
+ sfree (keys);
} /* }}} void log_list_callbacks */
static int create_register_callback (llist_t **list, /* {{{ */
{
callback_func_t *cf;
- cf = (callback_func_t *) malloc (sizeof (*cf));
+ cf = calloc (1, sizeof (*cf));
if (cf == NULL)
{
- ERROR ("plugin: create_register_callback: malloc failed.");
+ ERROR ("plugin: create_register_callback: calloc failed.");
return (-1);
}
- memset (cf, 0, sizeof (*cf));
cf->cf_callback = callback;
if (ud == NULL)
{
read_func_t *rf;
plugin_ctx_t old_ctx;
+ cdtime_t start;
cdtime_t now;
+ cdtime_t elapsed;
int status;
int rf_type;
int rc;
DEBUG ("plugin_read_thread: Handling `%s'.", rf->rf_name);
+ start = cdtime ();
+
old_ctx = plugin_set_ctx (rf->rf_ctx);
if (rf_type == RF_SIMPLE)
/* update the ``next read due'' field */
now = cdtime ();
+ /* calculate the time spent in the read function */
+ elapsed = (now - start);
+
+ if (elapsed > rf->rf_effective_interval)
+ WARNING ("plugin_read_thread: read-function of the `%s' plugin took %.3f "
+ "seconds, which is above its read interval (%.3f seconds). You might "
+ "want to adjust the `Interval' or `ReadThreads' settings.",
+ rf->rf_name, CDTIME_T_TO_DOUBLE(elapsed),
+ CDTIME_T_TO_DOUBLE(rf->rf_effective_interval));
+
+ DEBUG ("plugin_read_thread: read-function of the `%s' plugin took "
+ "%.6f seconds.",
+ rf->rf_name, CDTIME_T_TO_DOUBLE(elapsed));
+
DEBUG ("plugin_read_thread: Effective interval of the "
- "%s plugin is %.3f seconds.",
+ "`%s' plugin is %.3f seconds.",
rf->rf_name,
CDTIME_T_TO_DOUBLE (rf->rf_effective_interval));
rf->rf_next_read = now;
}
- DEBUG ("plugin_read_thread: Next read of the %s plugin at %.3f.",
+ DEBUG ("plugin_read_thread: Next read of the `%s' plugin at %.3f.",
rf->rf_name,
CDTIME_T_TO_DOUBLE (rf->rf_next_read));
static void stop_write_threads (void) /* {{{ */
{
write_queue_t *q;
- int i;
+ size_t i;
if (write_threads == NULL)
return;
if (i > 0)
{
- WARNING ("plugin: %i value list%s left after shutting down "
+ WARNING ("plugin: %zu value list%s left after shutting down "
"the write threads.",
i, (i == 1) ? " was" : "s were");
}
*/
void plugin_set_dir (const char *dir)
{
- if (plugindir != NULL)
- free (plugindir);
+ sfree (plugindir);
if (dir == NULL)
- plugindir = NULL;
- else if ((plugindir = strdup (dir)) == NULL)
{
- char errbuf[1024];
- ERROR ("strdup failed: %s",
- sstrerror (errno, errbuf, sizeof (errbuf)));
+ plugindir = NULL;
+ return;
}
+
+ plugindir = strdup (dir);
+ if (plugindir == NULL)
+ ERROR ("plugin_set_dir: strdup(\"%s\") failed", dir);
}
static _Bool plugin_is_loaded (char const *name)
return (status);
}
-static void plugin_free_loaded ()
+static void plugin_free_loaded (void)
{
void *key;
void *value;
/* success */
plugin_mark_loaded (plugin_name);
ret = 0;
+ INFO ("plugin_load: plugin \"%s\" successfully loaded.", plugin_name);
break;
}
else
read_func_t *rf;
int status;
- rf = malloc (sizeof (*rf));
+ rf = calloc (1, sizeof (*rf));
if (rf == NULL)
{
- ERROR ("plugin_register_read: malloc failed.");
+ ERROR ("plugin_register_read: calloc failed.");
return (ENOMEM);
}
- memset (rf, 0, sizeof (read_func_t));
rf->rf_callback = (void *) callback;
rf->rf_udata.data = NULL;
rf->rf_udata.free_func = NULL;
int plugin_register_complex_read (const char *group, const char *name,
plugin_read_cb callback,
- const struct timespec *interval,
+ cdtime_t interval,
user_data_t *user_data)
{
read_func_t *rf;
int status;
- rf = malloc (sizeof (*rf));
+ rf = calloc (1,sizeof (*rf));
if (rf == NULL)
{
- ERROR ("plugin_register_complex_read: malloc failed.");
+ ERROR ("plugin_register_complex_read: calloc failed.");
return (ENOMEM);
}
- memset (rf, 0, sizeof (read_func_t));
rf->rf_callback = (void *) callback;
if (group != NULL)
sstrncpy (rf->rf_group, group, sizeof (rf->rf_group));
rf->rf_group[0] = '\0';
rf->rf_name = strdup (name);
rf->rf_type = RF_COMPLEX;
- if (interval != NULL)
- rf->rf_interval = TIMESPEC_TO_CDTIME_T (interval);
- else
- rf->rf_interval = plugin_get_interval ();
+ rf->rf_interval = (interval != 0) ? interval : plugin_get_interval ();
/* Set user data */
if (user_data == NULL)
(void *) callback, ud));
} /* int plugin_register_write */
+static int plugin_flush_timeout_callback (user_data_t *ud)
+{
+ flush_callback_t *cb = ud->data;
+
+ return plugin_flush (cb->name, cb->timeout, /* identifier = */ NULL);
+} /* static int plugin_flush_callback */
+
+static void plugin_flush_timeout_callback_free (void *data)
+{
+ flush_callback_t *cb = data;
+
+ if (cb == NULL) return;
+
+ sfree (cb->name);
+ sfree (cb);
+} /* static void plugin_flush_callback_free */
+
+static char *plugin_flush_callback_name (const char *name)
+{
+ const char *flush_prefix = "flush/";
+ size_t prefix_size;
+ char *flush_name;
+ size_t name_size;
+
+ prefix_size = strlen(flush_prefix);
+ name_size = strlen(name);
+
+ flush_name = malloc (name_size + prefix_size + 1);
+ if (flush_name == NULL)
+ {
+ ERROR ("plugin_flush_callback_name: malloc failed.");
+ return (NULL);
+ }
+
+ sstrncpy (flush_name, flush_prefix, prefix_size + 1);
+ sstrncpy (flush_name + prefix_size, name, name_size + 1);
+
+ return flush_name;
+} /* static char *plugin_flush_callback_name */
+
int plugin_register_flush (const char *name,
plugin_flush_cb callback, user_data_t *ud)
{
- return (create_register_callback (&list_flush, name,
- (void *) callback, ud));
+ int status;
+ plugin_ctx_t ctx = plugin_get_ctx ();
+
+ status = create_register_callback (&list_flush, name,
+ (void *) callback, ud);
+ if (status != 0)
+ return status;
+
+ if (ctx.flush_interval != 0)
+ {
+ char *flush_name;
+ flush_callback_t *cb;
+
+ flush_name = plugin_flush_callback_name (name);
+ if (flush_name == NULL)
+ return (-1);
+
+ cb = malloc(sizeof (*cb));
+ if (cb == NULL)
+ {
+ ERROR ("plugin_register_flush: malloc failed.");
+ sfree (flush_name);
+ return (-1);
+ }
+
+ cb->name = strdup (name);
+ if (cb->name == NULL)
+ {
+ ERROR ("plugin_register_flush: strdup failed.");
+ sfree (cb);
+ sfree (flush_name);
+ return (-1);
+ }
+ cb->timeout = ctx.flush_timeout;
+
+ ud->data = cb;
+ ud->free_func = plugin_flush_timeout_callback_free;
+
+ status = plugin_register_complex_read (
+ /* group = */ "flush",
+ /* name = */ flush_name,
+ /* callback = */ plugin_flush_timeout_callback,
+ /* interval = */ ctx.flush_interval,
+ /* user data = */ ud);
+
+ sfree (flush_name);
+ if (status != 0)
+ {
+ sfree (cb->name);
+ sfree (cb);
+ return status;
+ }
+ }
+
+ return 0;
} /* int plugin_register_flush */
int plugin_register_missing (const char *name,
int plugin_register_data_set (const data_set_t *ds)
{
data_set_t *ds_copy;
- int i;
+ size_t i;
if ((data_sets != NULL)
&& (c_avl_get (data_sets, ds->type, NULL) == 0))
return (-1);
}
- ds_copy = (data_set_t *) malloc (sizeof (data_set_t));
+ ds_copy = malloc (sizeof (*ds_copy));
if (ds_copy == NULL)
return (-1);
memcpy(ds_copy, ds, sizeof (data_set_t));
- ds_copy->ds = (data_source_t *) malloc (sizeof (data_source_t)
+ ds_copy->ds = malloc (sizeof (*ds_copy->ds)
* ds->ds_num);
if (ds_copy->ds == NULL)
{
- free (ds_copy);
+ sfree (ds_copy);
return (-1);
}
int plugin_unregister_flush (const char *name)
{
- return (plugin_unregister (list_flush, name));
+ plugin_ctx_t ctx = plugin_get_ctx ();
+
+ if (ctx.flush_interval != 0)
+ {
+ char *flush_name;
+
+ flush_name = plugin_flush_callback_name (name);
+ if (flush_name != NULL)
+ {
+ plugin_unregister_read(flush_name);
+ sfree (flush_name);
+ }
+ }
+
+ return plugin_unregister (list_flush, name);
}
int plugin_unregister_missing (const char *name)
return (plugin_unregister (list_notification, name));
}
-void plugin_init_all (void)
+int plugin_init_all (void)
{
char const *chain_name;
- long write_threads_num;
llentry_t *le;
int status;
+ int ret = 0;
/* Init the value cache */
uc_init ();
}
if ((list_init == NULL) && (read_heap == NULL))
- return;
+ return ret;
/* Calling all init callbacks before checking if read callbacks
* are available allows the init callbacks to register the read
* handling themselves. */
/* FIXME: Unload _all_ functions */
plugin_unregister_read (le->key);
+ ret = -1;
}
le = le->next;
if (num != -1)
start_read_threads ((num > 0) ? num : 5);
}
+ return ret;
} /* void plugin_init_all */
/* TODO: Rename this function. */
return (0);
} /* int plugin_flush */
-void plugin_shutdown_all (void)
+int plugin_shutdown_all (void)
{
llentry_t *le;
+ int ret = 0; // Assume success.
stop_read_threads ();
* after callback returns. */
le = le->next;
- (*callback) ();
+ if ((*callback) () != 0)
+ ret = -1;
plugin_set_ctx (old_ctx);
}
plugin_free_loaded ();
plugin_free_data_sets ();
+ return (ret);
} /* void plugin_shutdown_all */
int plugin_dispatch_missing (const value_list_t *vl) /* {{{ */
int free_meta_data = 0;
- if ((vl == NULL) || (vl->type[0] == 0)
- || (vl->values == NULL) || (vl->values_len < 1))
+ assert(vl);
+ assert(vl->plugin);
+
+ if (vl->type[0] == 0 || vl->values == NULL || vl->values_len < 1)
{
ERROR ("plugin_dispatch_values: Invalid value list "
"from plugin %s.", vl->plugin);
if (ds->ds_num != vl->values_len)
{
ERROR ("plugin_dispatch_values: ds->type = %s: "
- "(ds->ds_num = %i) != "
- "(vl->values_len = %i)",
+ "(ds->ds_num = %zu) != "
+ "(vl->values_len = %zu)",
ds->type, ds->ds_num, vl->values_len);
return (-1);
}
* don't get confused.. */
if (saved_values != NULL)
{
- free (vl->values);
+ sfree (vl->values);
vl->values = saved_values;
vl->values_len = saved_values_len;
}
* confused.. */
if (saved_values != NULL)
{
- free (vl->values);
+ sfree (vl->values);
vl->values = saved_values;
vl->values_len = saved_values_len;
}
assert (template->values_len == 1);
- /* Calculate sum for Gauge to calculate percent if needed */
+ /* Calculate sum for Gauge to calculate percent if needed */
if (DS_TYPE_GAUGE == store_type) {
va_start (ap, store_type);
while (42)
case DS_TYPE_GAUGE:
vl->values[0].gauge = va_arg (ap, gauge_t);
if (store_percentage)
- vl->values[0].gauge *= 100.0 / sum;
+ vl->values[0].gauge *= sum ? (100.0 / sum) : 0;
break;
case DS_TYPE_ABSOLUTE:
vl->values[0].absolute = va_arg (ap, absolute_t);
return (-1);
}
- meta = (notification_meta_t *) malloc (sizeof (notification_meta_t));
+ meta = calloc (1, sizeof (*meta));
if (meta == NULL)
{
- ERROR ("plugin_notification_meta_add: malloc failed.");
+ ERROR ("plugin_notification_meta_add: calloc failed.");
return (-1);
}
- memset (meta, 0, sizeof (notification_meta_t));
sstrncpy (meta->name, name, sizeof (meta->name));
meta->type = type;
if (this->type == NM_TYPE_STRING)
{
- free ((char *)this->nm_value.nm_string);
+ /* Assign to a temporary variable to work around nm_string's const
+ * modifier. */
+ void *tmp = (void *) this->nm_value.nm_string;
+
+ sfree (tmp);
this->nm_value.nm_string = NULL;
}
sfree (this);
plugin_set_ctx (plugin_thread->ctx);
- free (plugin_thread);
+ sfree (plugin_thread);
return start_routine (plugin_arg);
} /* void *plugin_thread_start */