X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fdaemon%2Fplugin.c;h=1deabba3dde599a3c203258e1b26200519d6951c;hb=7bfda8d327240ac73297e4449663814dd0594be5;hp=97b794f75d35cbd66d1449981b12567899a9089c;hpb=f2389f97fbec15f49dcd1d9b06b3b6bbd0837e8a;p=collectd.git diff --git a/src/daemon/plugin.c b/src/daemon/plugin.c index 97b794f7..1deabba3 100644 --- a/src/daemon/plugin.c +++ b/src/daemon/plugin.c @@ -235,13 +235,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); @@ -307,6 +307,56 @@ static int register_callback (llist_t **list, /* {{{ */ return (0); } /* }}} int register_callback */ +static void log_list_callbacks (llist_t **list, /* {{{ */ + const char *comment) +{ + char *str; + int len; + llentry_t *le; + int i; + int n; + char **keys; + + n = llist_size(*list); + if (n == 0) + { + INFO("%s [none]", comment); + return; + } + + keys = calloc(n, sizeof(char*)); + + if (keys == NULL) + { + ERROR("%s: failed to allocate memory for list of callbacks", + comment); + + return; + } + + for (le = llist_head (*list), i = 0, len = 0; + le != NULL; + le = le->next, i++) + { + keys[i] = le->key; + len += strlen(le->key) + 6; + } + str = malloc(len + 10); + if (str == NULL) + { + ERROR("%s: failed to allocate memory for list of callbacks", + comment); + } + else + { + *str = '\0'; + strjoin(str, len, keys, n, "', '"); + INFO("%s ['%s']", comment, str); + free(str); + } + free(keys); +} /* }}} void log_list_callbacks */ + static int create_register_callback (llist_t **list, /* {{{ */ const char *name, void *callback, user_data_t *ud) { @@ -393,7 +443,7 @@ static int plugin_load_file (char *file, uint32_t flags) ssnprintf (errbuf, sizeof (errbuf), "lt_dlopen (\"%s\") failed: %s. " - "The most common cause for this problem are " + "The most common cause for this problem is " "missing dependencies. Use ldd(1) to check " "the dependencies of the plugin " "/ shared object.", @@ -924,7 +974,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; @@ -949,7 +999,6 @@ int plugin_load (char const *plugin_name, uint32_t flags) const char *dir; char filename[BUFSIZE] = ""; char typename[BUFSIZE]; - int typename_len; int ret; struct stat statbuf; struct dirent *de; @@ -989,7 +1038,6 @@ int plugin_load (char const *plugin_name, uint32_t flags) WARNING ("plugin_load: Filename too long: \"%s.so\"", plugin_name); return (-1); } - typename_len = strlen (typename); if ((dh = opendir (dir)) == NULL) { @@ -1001,7 +1049,7 @@ int plugin_load (char const *plugin_name, uint32_t flags) while ((de = readdir (dh)) != NULL) { - if (strncasecmp (de->d_name, typename, typename_len)) + if (strcasecmp (de->d_name, typename)) continue; status = ssnprintf (filename, sizeof (filename), @@ -1189,8 +1237,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 */ @@ -1237,8 +1287,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 */ @@ -1400,6 +1452,11 @@ int plugin_unregister_read (const char *name) /* {{{ */ return (0); } /* }}} int plugin_unregister_read */ +void plugin_log_available_writers (void) +{ + log_list_callbacks (&list_write, "Available write targets:"); +} + static int compare_read_func_group (llentry_t *e, void *ud) /* {{{ */ { read_func_t *rf = e->value; @@ -1510,7 +1567,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; @@ -1556,8 +1612,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; @@ -1593,6 +1647,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); @@ -1667,6 +1723,7 @@ int plugin_read_all_once (void) return_status = -1; } + sfree (rf->rf_name); destroy_callback ((void *) rf); } @@ -1793,10 +1850,10 @@ void plugin_shutdown_all (void) { llentry_t *le; - stop_read_threads (); - destroy_all_callbacks (&list_init); + stop_read_threads (); + pthread_mutex_lock (&read_lock); llist_destroy (read_list); read_list = NULL; @@ -1804,6 +1861,10 @@ void plugin_shutdown_all (void) destroy_read_heap (); + /* blocks until all write threads have shut down. */ + stop_write_threads (); + + /* ask all plugins to write out the state they kept. */ plugin_flush (/* plugin = */ NULL, /* timeout = */ 0, /* identifier = */ NULL); @@ -1833,8 +1894,6 @@ void plugin_shutdown_all (void) plugin_set_ctx (old_ctx); } - stop_write_threads (); - /* Write plugins which use the `user_data' pointer usually need the * same data available to the flush callback. If this is the case, set * the free_function to NULL when registering the flush callback and to @@ -2162,7 +2221,7 @@ int plugin_dispatch_values (value_list_t const *vl) __attribute__((sentinel)) int plugin_dispatch_multivalue (value_list_t const *template, /* {{{ */ - _Bool store_percentage, ...) + _Bool store_percentage, int store_type, ...) { value_list_t *vl; int failed = 0; @@ -2171,28 +2230,32 @@ int plugin_dispatch_multivalue (value_list_t const *template, /* {{{ */ assert (template->values_len == 1); - va_start (ap, store_percentage); - while (42) - { - char const *name; - gauge_t value; + /* Calculate sum for Gauge to calculate percent if needed */ + if (DS_TYPE_GAUGE == store_type) { + va_start (ap, store_type); + while (42) + { + char const *name; + gauge_t value; - name = va_arg (ap, char const *); - if (name == NULL) - break; + name = va_arg (ap, char const *); + if (name == NULL) + break; - value = va_arg (ap, gauge_t); - if (!isnan (value)) - sum += value; + value = va_arg (ap, gauge_t); + if (!isnan (value)) + sum += value; + } + va_end (ap); } - va_end (ap); + vl = plugin_value_list_clone (template); /* plugin_value_list_clone makes sure vl->time is set to non-zero. */ if (store_percentage) sstrncpy (vl->type, "percent", sizeof (vl->type)); - va_start (ap, store_percentage); + va_start (ap, store_type); while (42) { char const *name; @@ -2205,9 +2268,27 @@ int plugin_dispatch_multivalue (value_list_t const *template, /* {{{ */ sstrncpy (vl->type_instance, name, sizeof (vl->type_instance)); /* Set the value. */ - vl->values[0].gauge = va_arg (ap, gauge_t); - if (store_percentage) - vl->values[0].gauge *= 100.0 / sum; + switch (store_type) + { + case DS_TYPE_GAUGE: + vl->values[0].gauge = va_arg (ap, gauge_t); + if (store_percentage) + vl->values[0].gauge *= sum ? (100.0 / sum) : 0; + break; + case DS_TYPE_ABSOLUTE: + vl->values[0].absolute = va_arg (ap, absolute_t); + break; + case DS_TYPE_COUNTER: + vl->values[0].counter = va_arg (ap, counter_t); + break; + case DS_TYPE_DERIVE: + vl->values[0].derive = va_arg (ap, derive_t); + break; + default: + ERROR ("plugin_dispatch_multivalue: given store_type is incorrect."); + failed++; + } + status = plugin_write_enqueue (vl); if (status != 0)