X-Git-Url: https://git.octo.it/?p=collectd.git;a=blobdiff_plain;f=src%2Fdaemon%2Fplugin.c;h=4b7a58ec76e48a6033a096001c592e36d04ef26f;hp=3bf183d9c066934ecbfd664ef1c25e75d1c1920c;hb=f9d2c85e5459dfedbb1e3c09307556a74d5dc3bd;hpb=b165cd13cd30a30ac830df1f6f6fbd52474a6f64 diff --git a/src/daemon/plugin.c b/src/daemon/plugin.c index 3bf183d9..4b7a58ec 100644 --- a/src/daemon/plugin.c +++ b/src/daemon/plugin.c @@ -191,16 +191,21 @@ static int plugin_update_internal_statistics(void) { /* {{{ */ return 0; } /* }}} int plugin_update_internal_statistics */ -static void destroy_callback(callback_func_t *cf) /* {{{ */ +static void free_userdata(user_data_t const *ud) /* {{{ */ { - if (cf == NULL) + if (ud == NULL) return; - if ((cf->cf_udata.data != NULL) && (cf->cf_udata.free_func != NULL)) { - cf->cf_udata.free_func(cf->cf_udata.data); - cf->cf_udata.data = NULL; - cf->cf_udata.free_func = NULL; + if ((ud->data != NULL) && (ud->free_func != NULL)) { + ud->free_func(ud->data); } +} /* }}} void free_userdata */ + +static void destroy_callback(callback_func_t *cf) /* {{{ */ +{ + if (cf == NULL) + return; + free_userdata(&cf->cf_udata); sfree(cf); } /* }}} void destroy_callback */ @@ -345,6 +350,7 @@ static int create_register_callback(llist_t **list, /* {{{ */ cf = calloc(1, sizeof(*cf)); if (cf == NULL) { + free_userdata(ud); ERROR("plugin: create_register_callback: calloc failed."); return -1; } @@ -383,50 +389,44 @@ static int plugin_unregister(llist_t *list, const char *name) /* {{{ */ return 0; } /* }}} int plugin_unregister */ -/* - * (Try to) load the shared object `file'. Won't complain if it isn't a shared - * object, but it will bitch about a shared object not having a - * ``module_register'' symbol.. - */ -static int plugin_load_file(const char *file, _Bool global) { - void (*reg_handle)(void); - +/* plugin_load_file loads the shared object "file" and calls its + * "module_register" function. Returns zero on success, non-zero otherwise. */ +static int plugin_load_file(char const *file, _Bool global) { int flags = RTLD_NOW; if (global) flags |= RTLD_GLOBAL; void *dlh = dlopen(file, flags); - if (dlh == NULL) { char errbuf[1024] = ""; - ssnprintf(errbuf, sizeof(errbuf), - "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, 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); + snprintf(errbuf, sizeof(errbuf), + "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, dlerror()); + + /* This error is printed to STDERR unconditionally. If list_log is NULL, + * plugin_log() will also print to STDERR. We avoid duplicate output by + * checking that the list of log handlers, list_log, is not NULL. */ + fprintf(stderr, "ERROR: %s\n", errbuf); + if (list_log != NULL) { + ERROR("%s", errbuf); + } - return 1; + return ENOENT; } - reg_handle = (void (*)(void))dlsym(dlh, "module_register"); + void (*reg_handle)(void) = dlsym(dlh, "module_register"); if (reg_handle == NULL) { - WARNING("Couldn't find symbol \"module_register\" in \"%s\": %s\n", file, - dlerror()); + ERROR("Couldn't find symbol \"module_register\" in \"%s\": %s\n", file, + dlerror()); dlclose(dlh); - return -1; + return ENOENT; } (*reg_handle)(); - return 0; } @@ -604,9 +604,7 @@ static void set_thread_name(pthread_t tid, char const *name) { #if defined(HAVE_PTHREAD_SETNAME_NP) int status = pthread_setname_np(tid, n); if (status != 0) { - char errbuf[1024]; - ERROR("set_thread_name(\"%s\"): %s", n, - sstrerror(status, errbuf, sizeof(errbuf))); + ERROR("set_thread_name(\"%s\"): %s", n, STRERROR(status)); } #else /* if defined(HAVE_PTHREAD_SET_NAME_NP) */ pthread_set_name_np(tid, n); @@ -632,15 +630,14 @@ static void start_read_threads(size_t num) /* {{{ */ /* attr = */ NULL, plugin_read_thread, /* arg = */ NULL); if (status != 0) { - char errbuf[1024]; - ERROR("plugin: start_read_threads: pthread_create failed " - "with status %i (%s).", - status, sstrerror(status, errbuf, sizeof(errbuf))); + ERROR("plugin: start_read_threads: pthread_create failed with status %i " + "(%s).", + status, STRERROR(status)); return; } char name[THREAD_NAME_MAX]; - ssnprintf(name, sizeof(name), "reader#%zu", read_threads_num); + snprintf(name, sizeof(name), "reader#%zu", read_threads_num); set_thread_name(read_threads[read_threads_num], name); read_threads_num++; @@ -839,15 +836,14 @@ static void start_write_threads(size_t num) /* {{{ */ /* attr = */ NULL, plugin_write_thread, /* arg = */ NULL); if (status != 0) { - char errbuf[1024]; - ERROR("plugin: start_write_threads: pthread_create failed " - "with status %i (%s).", - status, sstrerror(status, errbuf, sizeof(errbuf))); + ERROR("plugin: start_write_threads: pthread_create failed with status %i " + "(%s).", + status, STRERROR(status)); return; } char name[THREAD_NAME_MAX]; - ssnprintf(name, sizeof(name), "writer#%zu", write_threads_num); + snprintf(name, sizeof(name), "writer#%zu", write_threads_num); set_thread_name(write_threads[write_threads_num], name); write_threads_num++; @@ -996,16 +992,14 @@ int plugin_load(char const *plugin_name, _Bool global) { /* `cpu' should not match `cpufreq'. To solve this we add `.so' to the * type when matching the filename */ - status = ssnprintf(typename, sizeof(typename), "%s.so", plugin_name); + status = snprintf(typename, sizeof(typename), "%s.so", plugin_name); if ((status < 0) || ((size_t)status >= sizeof(typename))) { WARNING("plugin_load: Filename too long: \"%s.so\"", plugin_name); return -1; } if ((dh = opendir(dir)) == NULL) { - char errbuf[1024]; - ERROR("plugin_load: opendir (%s) failed: %s", dir, - sstrerror(errno, errbuf, sizeof(errbuf))); + ERROR("plugin_load: opendir (%s) failed: %s", dir, STRERRNO); return -1; } @@ -1013,16 +1007,14 @@ int plugin_load(char const *plugin_name, _Bool global) { if (strcasecmp(de->d_name, typename)) continue; - status = ssnprintf(filename, sizeof(filename), "%s/%s", dir, de->d_name); + status = snprintf(filename, sizeof(filename), "%s/%s", dir, de->d_name); if ((status < 0) || ((size_t)status >= sizeof(filename))) { WARNING("plugin_load: Filename too long: \"%s/%s\"", dir, de->d_name); continue; } if (lstat(filename, &statbuf) == -1) { - char errbuf[1024]; - WARNING("plugin_load: stat (\"%s\") failed: %s", filename, - sstrerror(errno, errbuf, sizeof(errbuf))); + WARNING("plugin_load: stat (\"%s\") failed: %s", filename, STRERRNO); continue; } else if (!S_ISREG(statbuf.st_mode)) { /* don't follow symlinks */ @@ -1120,8 +1112,7 @@ static int plugin_insert_read(read_func_t *rf) { if (le != NULL) { pthread_mutex_unlock(&read_lock); WARNING("The read function \"%s\" is already registered. " - "Check for duplicate \"LoadPlugin\" lines " - "in your configuration!", + "Check for duplicates in your configuration!", rf->rf_name); return EINVAL; } @@ -1186,6 +1177,7 @@ int plugin_register_complex_read(const char *group, const char *name, rf = calloc(1, sizeof(*rf)); if (rf == NULL) { + free_userdata(user_data); ERROR("plugin_register_complex_read: calloc failed."); return ENOMEM; } @@ -1211,6 +1203,7 @@ int plugin_register_complex_read(const char *group, const char *name, status = plugin_insert_read(rf); if (status != 0) { + free_userdata(&rf->rf_udata); sfree(rf->rf_name); sfree(rf); } @@ -1303,11 +1296,7 @@ int plugin_register_flush(const char *name, plugin_flush_cb callback, }); sfree(flush_name); - if (status != 0) { - sfree(cb->name); - sfree(cb); - return status; - } + return status; } return 0; @@ -1319,8 +1308,7 @@ int plugin_register_missing(const char *name, plugin_missing_cb callback, } /* int plugin_register_missing */ int plugin_register_shutdown(const char *name, int (*callback)(void)) { - return create_register_callback(&list_shutdown, name, (void *)callback, - NULL); + return create_register_callback(&list_shutdown, name, (void *)callback, NULL); } /* int plugin_register_shutdown */ static void plugin_free_data_sets(void) { @@ -1871,23 +1859,16 @@ int plugin_shutdown_all(void) { int plugin_dispatch_missing(const value_list_t *vl) /* {{{ */ { - llentry_t *le; - if (list_missing == NULL) return 0; - le = llist_head(list_missing); + llentry_t *le = llist_head(list_missing); while (le != NULL) { - callback_func_t *cf; - plugin_missing_cb callback; - plugin_ctx_t old_ctx; - int status; - - cf = le->value; - old_ctx = plugin_set_ctx(cf->cf_ctx); - callback = cf->cf_callback; + callback_func_t *cf = le->value; + plugin_ctx_t old_ctx = plugin_set_ctx(cf->cf_ctx); + plugin_missing_cb callback = cf->cf_callback; - status = (*callback)(vl, &cf->cf_udata); + int status = (*callback)(vl, &cf->cf_udata); plugin_set_ctx(old_ctx); if (status != 0) { if (status < 0) { @@ -1909,8 +1890,6 @@ static int plugin_dispatch_values_internal(value_list_t *vl) { int status; static c_complain_t no_write_complaint = C_COMPLAIN_INIT_STATIC; - data_set_t *ds; - _Bool free_meta_data = 0; assert(vl != NULL); @@ -1946,6 +1925,7 @@ static int plugin_dispatch_values_internal(value_list_t *vl) { return -1; } + data_set_t *ds = NULL; if (c_avl_get(data_sets, vl->type, (void *)&ds) != 0) { char ident[6 * DATA_MAX_NAME_LEN]; @@ -2098,10 +2078,9 @@ int plugin_dispatch_values(value_list_t const *vl) { status = plugin_write_enqueue(vl); if (status != 0) { - char errbuf[1024]; - ERROR("plugin_dispatch_values: plugin_write_enqueue failed " - "with status %i (%s).", - status, sstrerror(status, errbuf, sizeof(errbuf))); + ERROR("plugin_dispatch_values: plugin_write_enqueue failed with status %i " + "(%s).", + status, STRERROR(status)); return status; } @@ -2468,9 +2447,7 @@ static plugin_ctx_t *plugin_ctx_create(void) { ctx = malloc(sizeof(*ctx)); if (ctx == NULL) { - char errbuf[1024]; - ERROR("Failed to allocate plugin context: %s", - sstrerror(errno, errbuf, sizeof(errbuf))); + ERROR("Failed to allocate plugin context: %s", STRERRNO); return NULL; }