X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fcore%2Fplugin.c;h=a521b89d1f00778233e7465cb3eb25e7692cd74c;hb=5ff9dd43c67b93bd8835c85ba09b4d5f74c386bf;hp=8200338a9d8fbb0804869b96f9267ed7b776e683;hpb=ddb7ffc175e49abfa69c82777b88d73e1f1103fb;p=sysdb.git diff --git a/src/core/plugin.c b/src/core/plugin.c index 8200338..a521b89 100644 --- a/src/core/plugin.c +++ b/src/core/plugin.c @@ -25,6 +25,10 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#if HAVE_CONFIG_H +# include "config.h" +#endif /* HAVE_CONFIG_H */ + #include "sysdb.h" #include "core/plugin.h" #include "core/time.h" @@ -77,9 +81,14 @@ typedef struct { sdb_plugin_ctx_t public; sdb_plugin_info_t info; + + /* The usage count differs from the object's ref count + * in that it provides higher level information about how + * the plugin is in use. */ + size_t use_cnt; } ctx_t; #define CTX_INIT { SDB_OBJECT_INIT, \ - SDB_PLUGIN_CTX_INIT, SDB_PLUGIN_INFO_INIT } + SDB_PLUGIN_CTX_INIT, SDB_PLUGIN_INFO_INIT, 0 } #define CTX(obj) ((ctx_t *)(obj)) @@ -117,6 +126,9 @@ static sdb_plugin_info_t plugin_default_info = SDB_PLUGIN_INFO_INIT; static pthread_key_t plugin_ctx_key; static _Bool plugin_ctx_key_initialized = 0; +/* a list of the plugin contexts of all registered plugins */ +static sdb_llist_t *all_plugins = NULL; + static sdb_llist_t *config_list = NULL; static sdb_llist_t *init_list = NULL; static sdb_llist_t *collector_list = NULL; @@ -239,6 +251,7 @@ ctx_init(sdb_object_t *obj, va_list __attribute__((unused)) ap) ctx->public = plugin_default_ctx; ctx->info = plugin_default_info; + ctx->use_cnt = 1; return 0; } /* ctx_init */ @@ -257,11 +270,11 @@ static sdb_type_t ctx_type = { }; static ctx_t * -ctx_create(void) +ctx_create(const char *name) { ctx_t *ctx; - ctx = CTX(sdb_object_create("plugin-context", ctx_type)); + ctx = CTX(sdb_object_create(name, ctx_type)); if (! ctx) return NULL; @@ -383,7 +396,7 @@ plugin_add_callback(sdb_llist_t **list, const char *type, int sdb_plugin_load(const char *name, const sdb_plugin_ctx_t *plugin_ctx) { - char real_name[strlen(name) > 0 ? strlen(name) : 1]; + char real_name[name ? strlen(name) + 1 : 1]; const char *name_ptr; char *tmp; @@ -408,6 +421,13 @@ sdb_plugin_load(const char *name, const sdb_plugin_ctx_t *plugin_ctx) } strcat(real_name, name_ptr); + ctx = CTX(sdb_llist_search_by_name(all_plugins, real_name)); + if (ctx) { + /* plugin already loaded */ + ++ctx->use_cnt; + return 0; + } + snprintf(filename, sizeof(filename), "%s/%s.so", PKGLIBDIR, real_name); filename[sizeof(filename) - 1] = '\0'; @@ -433,7 +453,7 @@ sdb_plugin_load(const char *name, const sdb_plugin_ctx_t *plugin_ctx) if (ctx_get()) sdb_log(SDB_LOG_WARNING, "core: Discarding old plugin context"); - ctx = ctx_create(); + ctx = ctx_create(real_name); if (! ctx) { sdb_log(SDB_LOG_ERR, "core: Failed to initialize plugin context"); return -1; @@ -471,6 +491,18 @@ sdb_plugin_load(const char *name, const sdb_plugin_ctx_t *plugin_ctx) name, SDB_VERSION_DECODE(ctx->info.version), SDB_VERSION_DECODE(SDB_VERSION)); + if (! all_plugins) { + if (! (all_plugins = sdb_llist_create())) { + sdb_log(SDB_LOG_ERR, "core: Failed to load plugin '%s': " + "internal error while creating linked list", name); + plugin_unregister_by_name(ctx->info.plugin_name); + sdb_object_deref(SDB_OBJ(ctx)); + return -1; + } + } + + sdb_llist_append(all_plugins, SDB_OBJ(ctx)); + sdb_log(SDB_LOG_INFO, "core: Successfully loaded " "plugin '%s' v%i (%s)\n\t%s\n\tLicense: %s", INFO_GET(&ctx->info, name), ctx->info.plugin_version, @@ -559,7 +591,7 @@ int sdb_plugin_register_config(const char *name, sdb_plugin_config_cb callback) { return plugin_add_callback(&config_list, "init", name, - callback, NULL); + (void *)callback, NULL); } /* sdb_plugin_register_config */ int @@ -567,7 +599,7 @@ sdb_plugin_register_init(const char *name, sdb_plugin_init_cb callback, sdb_object_t *user_data) { return plugin_add_callback(&init_list, "init", name, - callback, user_data); + (void *)callback, user_data); } /* sdb_plugin_register_init */ int @@ -575,14 +607,14 @@ sdb_plugin_register_shutdown(const char *name, sdb_plugin_shutdown_cb callback, sdb_object_t *user_data) { return plugin_add_callback(&shutdown_list, "shutdown", name, - callback, user_data); + (void *)callback, user_data); } /* sdb_plugin_register_shutdown */ int sdb_plugin_register_log(const char *name, sdb_plugin_log_cb callback, sdb_object_t *user_data) { - return plugin_add_callback(&log_list, "log", name, callback, + return plugin_add_callback(&log_list, "log", name, (void *)callback, user_data); } /* sdb_plugin_register_log */ @@ -590,7 +622,7 @@ int sdb_plugin_register_cname(const char *name, sdb_plugin_cname_cb callback, sdb_object_t *user_data) { - return plugin_add_callback(&cname_list, "cname", name, callback, + return plugin_add_callback(&cname_list, "cname", name, (void *)callback, user_data); } /* sdb_plugin_register_cname */ @@ -694,15 +726,18 @@ sdb_plugin_configure(const char *name, oconfig_item_t *ci) plugin = SDB_PLUGIN_CB(sdb_llist_search_by_name(config_list, name)); if (! plugin) { - /* XXX: check if any such plugin has been loaded */ - sdb_log(SDB_LOG_ERR, "core: Plugin '%s' did not register " - "a config callback.", name); + ctx_t *ctx = CTX(sdb_llist_search_by_name(all_plugins, name)); + if (! ctx) + sdb_log(SDB_LOG_ERR, "core: Plugin '%s' not loaded.", name); + else + sdb_log(SDB_LOG_ERR, "core: Plugin '%s' did not register " + "a config callback.", name); errno = ENOENT; return -1; } old_ctx = ctx_set(plugin->cb_ctx); - callback = plugin->cb_callback; + callback = (sdb_plugin_config_cb)plugin->cb_callback; status = callback(ci); ctx_set(old_ctx); return status; @@ -724,7 +759,7 @@ sdb_plugin_init_all(void) assert(obj); cb = SDB_PLUGIN_CB(obj); - callback = cb->cb_callback; + callback = (sdb_plugin_init_cb)cb->cb_callback; old_ctx = ctx_set(cb->cb_ctx); if (callback(cb->cb_user_data)) { @@ -761,7 +796,7 @@ sdb_plugin_collector_loop(sdb_plugin_loop_t *loop) if (! obj) return -1; - callback = SDB_PLUGIN_CCB(obj)->ccb_callback; + callback = (sdb_plugin_collector_cb)SDB_PLUGIN_CCB(obj)->ccb_callback; if (! (now = sdb_gettime())) { char errbuf[1024]; @@ -859,7 +894,7 @@ sdb_plugin_cname(char *hostname) sdb_object_t *obj = sdb_llist_iter_get_next(iter); assert(obj); - callback = SDB_PLUGIN_CB(obj)->cb_callback; + callback = (sdb_plugin_cname_cb)SDB_PLUGIN_CB(obj)->cb_callback; cname = callback(hostname, SDB_PLUGIN_CB(obj)->cb_user_data); if (cname) { free(hostname); @@ -891,7 +926,7 @@ sdb_plugin_log(int prio, const char *msg) sdb_object_t *obj = sdb_llist_iter_get_next(iter); assert(obj); - callback = SDB_PLUGIN_CB(obj)->cb_callback; + callback = (sdb_plugin_log_cb)SDB_PLUGIN_CB(obj)->cb_callback; tmp = callback(prio, msg, SDB_PLUGIN_CB(obj)->cb_user_data); if (tmp > ret) ret = tmp;