X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fplugin.c;h=24b269865da47cd74a1ea631b3ecd1c8c5eabb5f;hb=f9d51dc8fabe44f3cd17499713d63b518f0e1853;hp=70e0c0ffcf367e5f030e86a394fddf7e2d7c315c;hpb=03aa21f08fede809f37a7443d3124fb9314f4dc8;p=collectd.git diff --git a/src/plugin.c b/src/plugin.c index 70e0c0ff..24b26986 100644 --- a/src/plugin.c +++ b/src/plugin.c @@ -270,7 +270,7 @@ static int plugin_unregister (llist_t *list, const char *name) /* {{{ */ * object, but it will bitch about a shared object not having a * ``module_register'' symbol.. */ -static int plugin_load_file (char *file) +static int plugin_load_file (char *file, uint32_t flags) { lt_dlhandle dlh; void (*reg_handle) (void); @@ -280,7 +280,24 @@ static int plugin_load_file (char *file) lt_dlinit (); lt_dlerror (); /* clear errors */ - if ((dlh = lt_dlopen (file)) == NULL) +#if LIBTOOL_VERSION == 2 + if (flags & PLUGIN_FLAGS_GLOBAL) { + lt_dladvise advise; + lt_dladvise_init(&advise); + lt_dladvise_global(&advise); + dlh = lt_dlopenadvise(file, advise); + lt_dladvise_destroy(&advise); + } else { + dlh = lt_dlopen (file); + } +#else /* if LIBTOOL_VERSION == 1 */ + if (flags & PLUGIN_FLAGS_GLOBAL) + ERROR ("plugin_load_file: The global flag is not supported, " + "libtool 2 is required for this."); + dlh = lt_dlopen (file); +#endif + + if (dlh == NULL) { const char *error = lt_dlerror (); @@ -535,7 +552,7 @@ void plugin_set_dir (const char *dir) } #define BUFSIZE 512 -int plugin_load (const char *type) +int plugin_load (const char *type, uint32_t flags) { DIR *dh; const char *dir; @@ -597,7 +614,7 @@ int plugin_load (const char *type) continue; } - if (plugin_load_file (filename) == 0) + if (plugin_load_file (filename, flags) == 0) { /* success */ ret = 0; @@ -888,6 +905,14 @@ int plugin_unregister_read (const char *name) /* {{{ */ } le = llist_search (read_list, name); + if (le == NULL) + { + pthread_mutex_unlock (&read_lock); + WARNING ("plugin_unregister_read: No such read function: %s", + name); + return (-ENOENT); + } + llist_remove (read_list, le); rf = le->value; @@ -1205,8 +1230,14 @@ void plugin_shutdown_all (void) (*callback) (); } - destroy_all_callbacks (&list_write); + /* 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 + * the real free function when registering the write callback. This way + * the data isn't freed twice. */ destroy_all_callbacks (&list_flush); + destroy_all_callbacks (&list_write); + destroy_all_callbacks (&list_notification); destroy_all_callbacks (&list_shutdown); destroy_all_callbacks (&list_log); @@ -1222,6 +1253,8 @@ int plugin_dispatch_values (value_list_t *vl) data_set_t *ds; + int free_meta_data = 0; + if ((vl == NULL) || (vl->type[0] == 0) || (vl->values == NULL) || (vl->values_len < 1)) { @@ -1229,6 +1262,12 @@ int plugin_dispatch_values (value_list_t *vl) return (-1); } + /* Free meta data only if the calling function didn't specify any. In + * this case matches and targets may add some and the calling function + * may not expect (and therefore free) that data. */ + if (vl->meta == NULL) + free_meta_data = 1; + if (list_write == NULL) c_complain_once (LOG_WARNING, &no_write_complaint, "plugin_dispatch_values: No write callback has been " @@ -1369,6 +1408,12 @@ int plugin_dispatch_values (value_list_t *vl) vl->values_len = saved_values_len; } + if ((free_meta_data != 0) && (vl->meta != NULL)) + { + meta_data_destroy (vl->meta); + vl->meta = NULL; + } + return (0); } /* int plugin_dispatch_values */ @@ -1416,7 +1461,12 @@ void plugin_log (int level, const char *format, ...) llentry_t *le; if (list_log == NULL) + { + va_start (ap, format); + vfprintf (stderr, format, ap); + va_end (ap); return; + } #if !COLLECT_DEBUG if (level >= LOG_DEBUG)