X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fplugin.c;h=a3a716115a2b80c9e1464c81a777cca09e42dc00;hb=0171b227b670c7ca338b26bfaff303fd7cf2d023;hp=bf707eca82d6e20d2261b46fd6055016b77f4686;hpb=6667ac0ae4b48596df71998d38ef945b984102d3;p=collectd.git diff --git a/src/plugin.c b/src/plugin.c index bf707eca..a3a71611 100644 --- a/src/plugin.c +++ b/src/plugin.c @@ -1,6 +1,6 @@ /** * collectd - src/plugin.c - * Copyright (C) 2005-2008 Florian octo Forster + * Copyright (C) 2005-2009 Florian octo Forster * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -56,12 +56,14 @@ typedef struct read_func_s read_func_t; static llist_t *list_init; static llist_t *list_read; static llist_t *list_write; -static llist_t *list_filter; static llist_t *list_flush; static llist_t *list_shutdown; static llist_t *list_log; static llist_t *list_notification; +static fc_chain_t *pre_cache_chain = NULL; +static fc_chain_t *post_cache_chain = NULL; + static c_avl_tree_t *data_sets; static char *plugindir = NULL; @@ -169,7 +171,7 @@ static int plugin_load_file (char *file) return (0); } -static void *plugin_read_thread (void *args) +static void *plugin_read_thread (void __attribute__((unused)) *args) { llentry_t *le; read_func_t *rf; @@ -326,6 +328,7 @@ int plugin_load (const char *type) int ret; struct stat statbuf; struct dirent *de; + int status; DEBUG ("type = %s", type); @@ -334,8 +337,8 @@ int plugin_load (const char *type) /* `cpu' should not match `cpufreq'. To solve this we add `.so' to the * type when matching the filename */ - if (ssnprintf (typename, sizeof (typename), - "%s.so", type) >= sizeof (typename)) + status = ssnprintf (typename, sizeof (typename), "%s.so", type); + if ((status < 0) || ((size_t) status >= sizeof (typename))) { WARNING ("snprintf: truncated: `%s.so'", type); return (-1); @@ -355,8 +358,9 @@ int plugin_load (const char *type) if (strncasecmp (de->d_name, typename, typename_len)) continue; - if (ssnprintf (filename, sizeof (filename), - "%s/%s", dir, de->d_name) >= sizeof (filename)) + status = ssnprintf (filename, sizeof (filename), + "%s/%s", dir, de->d_name); + if ((status < 0) || ((size_t) status >= sizeof (filename))) { WARNING ("snprintf: truncated: `%s/%s'", dir, de->d_name); continue; @@ -372,6 +376,7 @@ int plugin_load (const char *type) else if (!S_ISREG (statbuf.st_mode)) { /* don't follow symlinks */ + WARNING ("stat %s: not a regular file", filename); continue; } @@ -447,12 +452,6 @@ int plugin_register_write (const char *name, return (register_callback (&list_write, name, (void *) callback)); } /* int plugin_register_write */ -int plugin_register_filter (const char *name, - int (*callback) (const data_set_t *ds, value_list_t *vl)) -{ - return (register_callback (&list_filter, name, (void *) callback)); -} /* int plugin_register_filter */ - int plugin_register_flush (const char *name, int (*callback) (const int timeout, const char *identifier)) { @@ -553,11 +552,6 @@ int plugin_unregister_write (const char *name) return (plugin_unregister (list_write, name)); } -int plugin_unregister_filter (const char *name) -{ - return (plugin_unregister (list_filter, name)); -} - int plugin_unregister_flush (const char *name) { return (plugin_unregister (list_flush, name)); @@ -596,6 +590,7 @@ int plugin_unregister_notification (const char *name) void plugin_init_all (void) { + const char *chain_name; int (*callback) (void); llentry_t *le; int status; @@ -603,6 +598,13 @@ void plugin_init_all (void) /* Init the value cache */ uc_init (); + chain_name = global_option_get ("PreCacheChain"); + pre_cache_chain = fc_chain_get_by_name (chain_name); + + chain_name = global_option_get ("PostCacheChain"); + post_cache_chain = fc_chain_get_by_name (chain_name); + + if ((list_init == NULL) && (list_read == NULL)) return; @@ -833,11 +835,17 @@ void plugin_shutdown_all (void) int plugin_dispatch_values (value_list_t *vl) { + int status; static c_complain_t no_write_complaint = C_COMPLAIN_INIT_STATIC; + value_t *saved_values; + int saved_values_len; + data_set_t *ds; - if ((vl == NULL) || (*vl->type == '\0')) { + if ((vl == NULL) || (vl->type[0] == 0) + || (vl->values == NULL) || (vl->values_len < 1)) + { ERROR ("plugin_dispatch_values: Invalid value list."); return (-1); } @@ -862,6 +870,9 @@ int plugin_dispatch_values (value_list_t *vl) return (-1); } + if (vl->time == 0) + vl->time = time (NULL); + DEBUG ("plugin_dispatch_values: time = %u; interval = %i; " "host = %s; " "plugin = %s; plugin_instance = %s; " @@ -898,10 +909,83 @@ int plugin_dispatch_values (value_list_t *vl) escape_slashes (vl->type, sizeof (vl->type)); escape_slashes (vl->type_instance, sizeof (vl->type_instance)); + /* Copy the values. This way, we can assure `targets' that they get + * dynamically allocated values, which they can free and replace if + * they like. */ + if ((pre_cache_chain != NULL) || (post_cache_chain != NULL)) + { + saved_values = vl->values; + saved_values_len = vl->values_len; + + vl->values = (value_t *) calloc (vl->values_len, + sizeof (*vl->values)); + if (vl->values == NULL) + { + ERROR ("plugin_dispatch_values: calloc failed."); + vl->values = saved_values; + return (-1); + } + memcpy (vl->values, saved_values, + vl->values_len * sizeof (*vl->values)); + } + else /* if ((pre == NULL) && (post == NULL)) */ + { + saved_values = NULL; + saved_values_len = 0; + } + + if (pre_cache_chain != NULL) + { + status = fc_process_chain (ds, vl, pre_cache_chain); + if (status < 0) + { + WARNING ("plugin_dispatch_values: Running the " + "pre-cache chain failed with " + "status %i (%#x).", + status, status); + } + else if (status == FC_TARGET_STOP) + { + /* Restore the state of the value_list so that plugins + * don't get confused.. */ + if (saved_values != NULL) + { + free (vl->values); + vl->values = saved_values; + vl->values_len = saved_values_len; + } + return (0); + } + } + /* Update the value cache */ uc_update (ds, vl); - fc_process (ds, vl); + /* Initiate threshold checking */ + ut_check_threshold (ds, vl); + + if (post_cache_chain != NULL) + { + status = fc_process_chain (ds, vl, post_cache_chain); + if (status < 0) + { + WARNING ("plugin_dispatch_values: Running the " + "post-cache chain failed with " + "status %i (%#x).", + status, status); + } + } + else + fc_default_action (ds, vl); + + /* Restore the state of the value_list so that plugins don't get + * confused.. */ + if (saved_values != NULL) + { + free (vl->values); + vl->values = saved_values; + vl->values_len = saved_values_len; + } return (0); } /* int plugin_dispatch_values */ @@ -1123,7 +1207,7 @@ int plugin_notification_meta_copy (notification_t *dst, return (0); } /* int plugin_notification_meta_copy */ -int plugin_notification_meta_free (notification_t *n) +int plugin_notification_meta_free (notification_meta_t *n) { notification_meta_t *this; notification_meta_t *next; @@ -1134,8 +1218,7 @@ int plugin_notification_meta_free (notification_t *n) return (-1); } - this = n->meta; - n->meta = NULL; + this = n; while (this != NULL) { next = this->next;