X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fdaemon%2Fplugin.c;h=be3f03fc57d5a7d1a68a4fd0b831543f44b6f03f;hb=e44ff919a7b02f1f5f94ab83a18209173e47e835;hp=0ef6273bf6c2d0d91034a1b20c0bdb17da50d306;hpb=e94f5c95909f895a80457baf543e03b6d6aff5ee;p=collectd.git diff --git a/src/daemon/plugin.c b/src/daemon/plugin.c index 0ef6273b..788b4549 100644 --- a/src/daemon/plugin.c +++ b/src/daemon/plugin.c @@ -241,13 +241,13 @@ static void destroy_read_heap (void) /* {{{ */ while (42) { - callback_func_t *cf; + read_func_t *rf; - cf = c_heap_get_root (read_heap); - if (cf == NULL) + rf = c_heap_get_root (read_heap); + if (rf == NULL) break; - - destroy_callback (cf); + sfree (rf->rf_name); + destroy_callback ((callback_func_t *) rf); } c_heap_destroy (read_heap); @@ -288,7 +288,7 @@ static int register_callback (llist_t **list, /* {{{ */ { ERROR ("plugin: register_callback: " "llentry_create failed."); - free (key); + sfree (key); destroy_callback (cf); return (-1); } @@ -358,9 +358,9 @@ static void log_list_callbacks (llist_t **list, /* {{{ */ *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, /* {{{ */ @@ -483,7 +483,9 @@ static void *plugin_read_thread (void __attribute__((unused)) *args) { 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; @@ -562,6 +564,8 @@ static void *plugin_read_thread (void __attribute__((unused)) *args) DEBUG ("plugin_read_thread: Handling `%s'.", rf->rf_name); + start = cdtime (); + old_ctx = plugin_set_ctx (rf->rf_ctx); if (rf_type == RF_SIMPLE) @@ -605,8 +609,22 @@ static void *plugin_read_thread (void __attribute__((unused)) *args) /* 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)); @@ -623,7 +641,7 @@ static void *plugin_read_thread (void __attribute__((unused)) *args) 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)); @@ -889,7 +907,7 @@ static void start_write_threads (size_t num) /* {{{ */ static void stop_write_threads (void) /* {{{ */ { write_queue_t *q; - int i; + size_t i; if (write_threads == NULL) return; @@ -930,7 +948,7 @@ static void stop_write_threads (void) /* {{{ */ 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"); } @@ -941,17 +959,17 @@ static void stop_write_threads (void) /* {{{ */ */ 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) @@ -980,7 +998,7 @@ static int plugin_mark_loaded (char const *name) return (status); } -static void plugin_free_loaded () +static void plugin_free_loaded (void) { void *key; void *value; @@ -1089,6 +1107,7 @@ int plugin_load (char const *plugin_name, uint32_t flags) /* success */ plugin_mark_loaded (plugin_name); ret = 0; + INFO ("plugin_load: plugin \"%s\" successfully loaded.", plugin_name); break; } else @@ -1243,8 +1262,10 @@ int plugin_register_read (const char *name, rf->rf_interval = plugin_get_interval (); status = plugin_insert_read (rf); - if (status != 0) + if (status != 0) { + sfree (rf->rf_name); sfree (rf); + } return (status); } /* int plugin_register_read */ @@ -1288,8 +1309,10 @@ int plugin_register_complex_read (const char *group, const char *name, rf->rf_ctx = plugin_get_ctx (); status = plugin_insert_read (rf); - if (status != 0) + if (status != 0) { + sfree (rf->rf_name); sfree (rf); + } return (status); } /* int plugin_register_complex_read */ @@ -1314,10 +1337,33 @@ static void plugin_flush_timeout_callback_free (void *data) if (cb == NULL) return; - sfree(cb->name); - sfree(cb); + sfree (cb->name); + sfree (cb); } /* static void plugin_flush_callback_free */ +static char *plugin_flush_callback_name (const char *name) +{ + 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 (sizeof(char) * (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) { @@ -1331,34 +1377,18 @@ int plugin_register_flush (const char *name, if (ctx.flush_interval != 0) { - char *flush_prefix = "flush/"; - size_t prefix_size; char *flush_name; - size_t name_size; - user_data_t ud; flush_callback_t *cb; - prefix_size = strlen(flush_prefix); - name_size = strlen(name); - - flush_name = (char *) malloc (sizeof (char) * - (name_size + prefix_size + 1)); + flush_name = plugin_flush_callback_name (name); if (flush_name == NULL) - { - ERROR ("plugin_register_flush: malloc failed."); - plugin_unregister (list_flush, name); return (-1); - } - - sstrncpy (flush_name, flush_prefix, prefix_size + 1); - sstrncpy (flush_name + prefix_size, name, name_size + 1); - cb = (flush_callback_t *)malloc(sizeof(flush_callback_t)); + cb = malloc(sizeof(flush_callback_t)); if (cb == NULL) { ERROR ("plugin_register_flush: malloc failed."); - sfree(flush_name); - plugin_unregister (list_flush, name); + sfree (flush_name); return (-1); } @@ -1366,29 +1396,27 @@ int plugin_register_flush (const char *name, if (cb->name == NULL) { ERROR ("plugin_register_flush: strdup failed."); - sfree(cb); - sfree(flush_name); - plugin_unregister (list_flush, name); + sfree (cb); + sfree (flush_name); return (-1); } cb->timeout = ctx.flush_timeout; - ud.data = cb; - ud.free_func = plugin_flush_timeout_callback_free; + 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); + /* user data = */ ud); - sfree(flush_name); + sfree (flush_name); if (status != 0) { - sfree(cb->name); - sfree(cb); - plugin_unregister (list_flush, name); + sfree (cb->name); + sfree (cb); return status; } } @@ -1434,7 +1462,7 @@ static void plugin_free_data_sets (void) 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)) @@ -1458,7 +1486,7 @@ int plugin_register_data_set (const data_set_t *ds) * ds->ds_num); if (ds_copy->ds == NULL) { - free (ds_copy); + sfree (ds_copy); return (-1); } @@ -1615,28 +1643,15 @@ int plugin_unregister_flush (const char *name) plugin_ctx_t ctx = plugin_get_ctx (); if (ctx.flush_interval != 0) - { - 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 = (char *) malloc (sizeof (char) * - (name_size + prefix_size + 1)); - if (flush_name == NULL) + flush_name = plugin_flush_callback_name (name); + if (flush_name != NULL) { - ERROR ("plugin_unregister_flush: malloc failed."); - return (-1); + plugin_unregister_read(flush_name); + sfree (flush_name); } - - sstrncpy (flush_name, flush_prefix, prefix_size + 1); - sstrncpy (flush_name + prefix_size, name, name_size + 1); - - plugin_unregister_read(flush_name); - sfree(flush_name); } return plugin_unregister (list_flush, name); @@ -1681,7 +1696,6 @@ int plugin_unregister_notification (const char *name) void plugin_init_all (void) { char const *chain_name; - long write_threads_num; llentry_t *le; int status; @@ -1727,8 +1741,6 @@ void plugin_init_all (void) write_threads_num = 5; } - start_write_threads ((size_t) write_threads_num); - if ((list_init == NULL) && (read_heap == NULL)) return; @@ -1764,6 +1776,8 @@ void plugin_init_all (void) le = le->next; } + start_write_threads ((size_t) write_threads_num); + max_read_interval = global_option_get_time ("MaxReadInterval", DEFAULT_MAX_READ_INTERVAL); @@ -1838,6 +1852,7 @@ int plugin_read_all_once (void) return_status = -1; } + sfree (rf->rf_name); destroy_callback ((void *) rf); } @@ -2144,8 +2159,8 @@ static int plugin_dispatch_values_internal (value_list_t *vl) 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); } @@ -2198,7 +2213,7 @@ static int plugin_dispatch_values_internal (value_list_t *vl) * don't get confused.. */ if (saved_values != NULL) { - free (vl->values); + sfree (vl->values); vl->values = saved_values; vl->values_len = saved_values_len; } @@ -2227,7 +2242,7 @@ static int plugin_dispatch_values_internal (value_list_t *vl) * confused.. */ if (saved_values != NULL) { - free (vl->values); + sfree (vl->values); vl->values = saved_values; vl->values_len = saved_values_len; } @@ -2385,7 +2400,7 @@ int plugin_dispatch_multivalue (value_list_t const *template, /* {{{ */ 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); @@ -2713,7 +2728,11 @@ int plugin_notification_meta_free (notification_meta_t *n) 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); @@ -2820,7 +2839,7 @@ static void *plugin_thread_start (void *arg) plugin_set_ctx (plugin_thread->ctx); - free (plugin_thread); + sfree (plugin_thread); return start_routine (plugin_arg); } /* void *plugin_thread_start */