X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fplugin.c;h=f4461b5d174851df287e88fd659e7a53aab8845e;hb=c6da31fb30c2fb1d131f92efcde0b3ec9a010b2c;hp=84a5abf240bba3226c450afda0a23e38931711f1;hpb=dd28a7dbb9404672d850063f3e58ee8dc6debb20;p=collectd.git diff --git a/src/plugin.c b/src/plugin.c index 84a5abf2..f4461b5d 100644 --- a/src/plugin.c +++ b/src/plugin.c @@ -59,6 +59,7 @@ struct read_func_s #define rf_callback rf_super.cf_callback #define rf_udata rf_super.cf_udata callback_func_t rf_super; + char rf_group[DATA_MAX_NAME_LEN]; char rf_name[DATA_MAX_NAME_LEN]; int rf_type; struct timespec rf_interval; @@ -279,8 +280,6 @@ static int plugin_load_file (char *file, uint32_t flags) lt_dlhandle dlh; void (*reg_handle) (void); - DEBUG ("file = %s", file); - lt_dlinit (); lt_dlerror (); /* clear errors */ @@ -296,23 +295,35 @@ static int plugin_load_file (char *file, uint32_t flags) } #else /* if LIBTOOL_VERSION == 1 */ if (flags & PLUGIN_FLAGS_GLOBAL) - ERROR ("plugin_load_file: The global flag is not supported, " + WARNING ("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 (); + char errbuf[1024] = ""; + + ssnprintf (errbuf, sizeof (errbuf), + "lt_dlopen (\"%s\") failed: %s. " + "The most common cause for this problem is " + "missing dependencies. Use ldd(1) to check " + "the dependencies of the plugin " + "/ shared object.", + file, lt_dlerror ()); + + ERROR ("%s", errbuf); + /* Make sure this is printed to STDERR in any case, but also + * make sure it's printed only once. */ + if (list_log != NULL) + fprintf (stderr, "ERROR: %s\n", errbuf); - ERROR ("lt_dlopen (%s) failed: %s", file, error); - fprintf (stderr, "lt_dlopen (%s) failed: %s\n", file, error); return (1); } if ((reg_handle = (void (*) (void)) lt_dlsym (dlh, "module_register")) == NULL) { - WARNING ("Couldn't find symbol `module_register' in `%s': %s\n", + WARNING ("Couldn't find symbol \"module_register\" in \"%s\": %s\n", file, lt_dlerror ()); lt_dlclose (dlh); return (-1); @@ -775,6 +786,7 @@ int plugin_register_read (const char *name, rf->rf_callback = (void *) callback; rf->rf_udata.data = NULL; rf->rf_udata.free_func = NULL; + rf->rf_group[0] = '\0'; sstrncpy (rf->rf_name, name, sizeof (rf->rf_name)); rf->rf_type = RF_SIMPLE; rf->rf_interval.tv_sec = 0; @@ -784,7 +796,7 @@ int plugin_register_read (const char *name, return (plugin_insert_read (rf)); } /* int plugin_register_read */ -int plugin_register_complex_read (const char *name, +int plugin_register_complex_read (const char *group, const char *name, plugin_read_cb callback, const struct timespec *interval, user_data_t *user_data) @@ -800,6 +812,10 @@ int plugin_register_complex_read (const char *name, memset (rf, 0, sizeof (read_func_t)); rf->rf_callback = (void *) callback; + if (group != NULL) + sstrncpy (rf->rf_group, group, sizeof (rf->rf_group)); + else + rf->rf_group[0] = '\0'; sstrncpy (rf->rf_name, name, sizeof (rf->rf_name)); rf->rf_type = RF_COMPLEX; if (interval != NULL) @@ -836,7 +852,7 @@ int plugin_register_flush (const char *name, (void *) callback, ud)); } /* int plugin_register_flush */ -int plugin_register_shutdown (char *name, +int plugin_register_shutdown (const char *name, int (*callback) (void)) { return (create_register_callback (&list_shutdown, name, @@ -951,6 +967,67 @@ int plugin_unregister_read (const char *name) /* {{{ */ return (0); } /* }}} int plugin_unregister_read */ +static int compare_read_func_group (llentry_t *e, void *ud) /* {{{ */ +{ + read_func_t *rf = e->value; + char *group = ud; + + return strcmp (rf->rf_group, (const char *)group); +} /* }}} int compare_read_func_group */ + +int plugin_unregister_read_group (const char *group) /* {{{ */ +{ + llentry_t *le; + read_func_t *rf; + + int found = 0; + + if (group == NULL) + return (-ENOENT); + + pthread_mutex_lock (&read_lock); + + if (read_list == NULL) + { + pthread_mutex_unlock (&read_lock); + return (-ENOENT); + } + + while (42) + { + le = llist_search_custom (read_list, + compare_read_func_group, (void *)group); + + if (le == NULL) + break; + + ++found; + + llist_remove (read_list, le); + + rf = le->value; + assert (rf != NULL); + rf->rf_type = RF_REMOVE; + + llentry_destroy (le); + + DEBUG ("plugin_unregister_read_group: " + "Marked `%s' (group `%s') for removal.", + rf->rf_name, group); + } + + pthread_mutex_unlock (&read_lock); + + if (found == 0) + { + WARNING ("plugin_unregister_read_group: No such " + "group of read function: %s", group); + return (-ENOENT); + } + + return (0); +} /* }}} int plugin_unregister_read_group */ + int plugin_unregister_write (const char *name) { return (plugin_unregister (list_write, name)); @@ -1281,7 +1358,8 @@ int plugin_dispatch_values (value_list_t *vl) if ((vl == NULL) || (vl->type[0] == 0) || (vl->values == NULL) || (vl->values_len < 1)) { - ERROR ("plugin_dispatch_values: Invalid value list."); + ERROR ("plugin_dispatch_values: Invalid value list " + "from plugin %s.", vl->plugin); return (-1); } @@ -1307,7 +1385,12 @@ int plugin_dispatch_values (value_list_t *vl) if (c_avl_get (data_sets, vl->type, (void *) &ds) != 0) { - INFO ("plugin_dispatch_values: Dataset not found: %s", vl->type); + char ident[6 * DATA_MAX_NAME_LEN]; + + FORMAT_VL (ident, sizeof (ident), vl); + INFO ("plugin_dispatch_values: Dataset not found: %s " + "(from \"%s\"), check your types.db!", + vl->type, ident); return (-1); } @@ -1440,6 +1523,52 @@ int plugin_dispatch_values (value_list_t *vl) return (0); } /* int plugin_dispatch_values */ +int plugin_dispatch_values_secure (const value_list_t *vl) +{ + value_list_t vl_copy; + int status; + + if (vl == NULL) + return EINVAL; + + memcpy (&vl_copy, vl, sizeof (vl_copy)); + + /* Write callbacks must not change the values and meta pointers, so we can + * savely skip copying those and make this more efficient. */ + if ((pre_cache_chain == NULL) && (post_cache_chain == NULL)) + return (plugin_dispatch_values (&vl_copy)); + + /* Set pointers to NULL, just to be on the save side. */ + vl_copy.values = NULL; + vl_copy.meta = NULL; + + vl_copy.values = malloc (sizeof (*vl_copy.values) * vl->values_len); + if (vl_copy.values == NULL) + { + ERROR ("plugin_dispatch_values_secure: malloc failed."); + return (ENOMEM); + } + memcpy (vl_copy.values, vl->values, sizeof (*vl_copy.values) * vl->values_len); + + if (vl->meta != NULL) + { + vl_copy.meta = meta_data_clone (vl->meta); + if (vl_copy.meta == NULL) + { + ERROR ("plugin_dispatch_values_secure: meta_data_clone failed."); + free (vl_copy.values); + return (ENOMEM); + } + } /* if (vl->meta) */ + + status = plugin_dispatch_values (&vl_copy); + + meta_data_destroy (vl_copy.meta); + free (vl_copy.values); + + return (status); +} /* int plugin_dispatch_values_secure */ + int plugin_dispatch_notification (const notification_t *notif) { llentry_t *le;