#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;
lt_dlhandle dlh;
void (*reg_handle) (void);
- DEBUG ("file = %s", file);
-
lt_dlinit ();
lt_dlerror (); /* clear errors */
}
#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 are "
+ "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);
* we need to re-evaluate the condition every time
* pthread_cond_timedwait returns. */
rc = 0;
- while (!timeout_reached(rf->rf_next_read) && rc == 0) {
+ while ((read_loop != 0)
+ && !timeout_reached(rf->rf_next_read)
+ && rc == 0)
+ {
rc = pthread_cond_timedwait (&read_cond, &read_lock,
&rf->rf_next_read);
}
- /* Must hold `real_lock' when accessing `rf->rf_type'. */
+ /* Must hold `read_lock' when accessing `rf->rf_type'. */
rf_type = rf->rf_type;
pthread_mutex_unlock (&read_lock);
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;
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)
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)
(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,
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));
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);
}
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);
}
va_list ap;
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)
return;
msg[sizeof (msg) - 1] = '\0';
va_end (ap);
+ if (list_log == NULL)
+ {
+ fprintf (stderr, "%s\n", msg);
+ return;
+ }
+
le = llist_head (list_log);
while (le != NULL)
{