X-Git-Url: https://git.tokkee.org/?p=sysdb.git;a=blobdiff_plain;f=src%2Fcore%2Fplugin.c;h=ca04ae21efc8745efc62553cda354060ca54390d;hp=92fa8866981f6e5b4623100498c04d7e5567f0d8;hb=b2d31bc42a7694c671186081ee0cac077a188b99;hpb=1bde17786b9a0b342daae5faa46a54b3eeab6558 diff --git a/src/core/plugin.c b/src/core/plugin.c index 92fa886..ca04ae2 100644 --- a/src/core/plugin.c +++ b/src/core/plugin.c @@ -114,6 +114,14 @@ typedef struct { } reader_t; #define READER(obj) ((reader_t *)(obj)) +typedef struct { + callback_t super; /* cb_callback will always be NULL */ +#define ts_user_data super.cb_user_data +#define ts_ctx super.cb_ctx + sdb_timeseries_fetcher_t impl; +} ts_fetcher_t; +#define TS_FETCHER(obj) ((ts_fetcher_t *)(obj)) + /* * private variables */ @@ -133,7 +141,7 @@ static sdb_llist_t *collector_list = NULL; static sdb_llist_t *cname_list = NULL; static sdb_llist_t *shutdown_list = NULL; static sdb_llist_t *log_list = NULL; -static sdb_llist_t *ts_fetcher_list = NULL; +static sdb_llist_t *timeseries_fetcher_list = NULL; static sdb_llist_t *writer_list = NULL; static sdb_llist_t *reader_list = NULL; @@ -147,7 +155,7 @@ static struct { { "cname", &cname_list }, { "shutdown", &shutdown_list }, { "log", &log_list }, - { "timeseries fetcher", &ts_fetcher_list }, + { "timeseries fetcher", ×eries_fetcher_list }, { "store writer", &writer_list }, { "store reader", &reader_list }, }; @@ -345,24 +353,39 @@ ctx_create(const char *name) return ctx; } /* ctx_create */ -static int -plugin_cb_init(sdb_object_t *obj, va_list ap) +/* + * plugin_init_ok: + * Checks whether the registration of a new plugin identified by 'obj' is + * okay. It consumes the first two arguments of 'ap'. + */ +static bool +plugin_init_ok(sdb_object_t *obj, va_list ap) { sdb_llist_t **list = va_arg(ap, sdb_llist_t **); - const char *type = va_arg(ap, const char *); - void *callback = va_arg(ap, void *); - sdb_object_t *ud = va_arg(ap, sdb_object_t *); + const char *type = va_arg(ap, const char *); - assert(list); - assert(type); - assert(obj); + assert(list); assert(type); if (sdb_llist_search_by_name(*list, obj->name)) { sdb_log(SDB_LOG_WARNING, "core: %s callback '%s' " "has already been registered. Ignoring newly " "registered version.", type, obj->name); - return -1; + return 0; } + return 1; +} /* plugin_init_ok */ + +static int +plugin_cb_init(sdb_object_t *obj, va_list ap) +{ + void *callback; + sdb_object_t *ud; + + if (! plugin_init_ok(obj, ap)) + return -1; + + callback = va_arg(ap, void *); + ud = va_arg(ap, sdb_object_t *); /* cb_ctx may be NULL if the plugin was not registered by a plugin */ @@ -400,9 +423,14 @@ static sdb_type_t collector_type = { static int plugin_writer_init(sdb_object_t *obj, va_list ap) { - sdb_store_writer_t *impl = va_arg(ap, sdb_store_writer_t *); - sdb_object_t *ud = va_arg(ap, sdb_object_t *); + sdb_store_writer_t *impl; + sdb_object_t *ud; + + if (! plugin_init_ok(obj, ap)) + return -1; + impl = va_arg(ap, sdb_store_writer_t *); + ud = va_arg(ap, sdb_object_t *); assert(impl); if ((! impl->store_host) || (! impl->store_service) @@ -412,12 +440,6 @@ plugin_writer_init(sdb_object_t *obj, va_list ap) obj->name); return -1; } - if (sdb_llist_search_by_name(writer_list, obj->name)) { - sdb_log(SDB_LOG_WARNING, "core: store writer callback '%s' " - "has already been registered. Ignoring newly " - "registered version.", obj->name); - return -1; - } /* ctx may be NULL if the callback was not registered by a plugin */ @@ -448,9 +470,14 @@ static sdb_type_t writer_type = { static int plugin_reader_init(sdb_object_t *obj, va_list ap) { - sdb_store_reader_t *impl = va_arg(ap, sdb_store_reader_t *); - sdb_object_t *ud = va_arg(ap, sdb_object_t *); + sdb_store_reader_t *impl; + sdb_object_t *ud; + if (! plugin_init_ok(obj, ap)) + return -1; + + impl = va_arg(ap, sdb_store_reader_t *); + ud = va_arg(ap, sdb_object_t *); assert(impl); if ((! impl->prepare_query) || (! impl->execute_query)) { @@ -459,12 +486,6 @@ plugin_reader_init(sdb_object_t *obj, va_list ap) obj->name); return -1; } - if (sdb_llist_search_by_name(reader_list, obj->name)) { - sdb_log(SDB_LOG_WARNING, "core: store reader callback '%s' " - "has already been registered. Ignoring newly " - "registered version.", obj->name); - return -1; - } /* ctx may be NULL if the callback was not registered by a plugin */ @@ -492,6 +513,52 @@ static sdb_type_t reader_type = { plugin_reader_destroy }; +static int +plugin_ts_fetcher_init(sdb_object_t *obj, va_list ap) +{ + sdb_timeseries_fetcher_t *impl; + sdb_object_t *ud; + + if (! plugin_init_ok(obj, ap)) + return -1; + + impl = va_arg(ap, sdb_timeseries_fetcher_t *); + ud = va_arg(ap, sdb_object_t *); + assert(impl); + + if ((! impl->describe) || (! impl->fetch)) { + sdb_log(SDB_LOG_ERR, "core: timeseries fetcher callback '%s' " + "does not fully implement the interface.", + obj->name); + return -1; + } + + /* ctx may be NULL if the callback was not registered by a plugin */ + + TS_FETCHER(obj)->impl = *impl; + TS_FETCHER(obj)->ts_ctx = ctx_get(); + sdb_object_ref(SDB_OBJ(TS_FETCHER(obj)->ts_ctx)); + + sdb_object_ref(ud); + TS_FETCHER(obj)->ts_user_data = ud; + return 0; +} /* plugin_ts_fetcher_init */ + +static void +plugin_ts_fetcher_destroy(sdb_object_t *obj) +{ + assert(obj); + sdb_object_deref(TS_FETCHER(obj)->ts_user_data); + sdb_object_deref(SDB_OBJ(TS_FETCHER(obj)->ts_ctx)); +} /* plugin_ts_fetcher_destroy */ + +static sdb_type_t ts_fetcher_type = { + sizeof(ts_fetcher_t), + + plugin_ts_fetcher_init, + plugin_ts_fetcher_destroy +}; + static int module_init(const char *name, lt_dlhandle lh, sdb_plugin_info_t *info) { @@ -628,12 +695,12 @@ plugin_get_name(const char *name, char *buf, size_t bufsize) } /* plugin_get_name */ static int -plugin_add_callback(sdb_llist_t **list, const char *type, - const char *name, void *callback, sdb_object_t *user_data) +plugin_add_impl(sdb_llist_t **list, sdb_type_t T, const char *type, + const char *name, void *impl, sdb_object_t *user_data) { sdb_object_t *obj; - if ((! name) || (! callback)) + if ((! name) || (! impl)) return -1; assert(list); @@ -643,8 +710,7 @@ plugin_add_callback(sdb_llist_t **list, const char *type, if (! *list) return -1; - obj = sdb_object_create(name, callback_type, - list, type, callback, user_data); + obj = sdb_object_create(name, T, list, type, impl, user_data); if (! obj) return -1; @@ -659,7 +725,7 @@ plugin_add_callback(sdb_llist_t **list, const char *type, sdb_log(SDB_LOG_INFO, "core: Registered %s callback '%s'.", type, name); return 0; -} /* plugin_add_callback */ +} /* plugin_add_impl */ /* * object meta-data @@ -896,8 +962,8 @@ sdb_plugin_register_config(sdb_plugin_config_cb callback) "config callback from outside a plugin"); return -1; } - return plugin_add_callback(&config_list, "config", ctx->info.plugin_name, - (void *)callback, NULL); + return plugin_add_impl(&config_list, callback_type, "config", + ctx->info.plugin_name, (void *)callback, NULL); } /* sdb_plugin_register_config */ int @@ -905,7 +971,7 @@ sdb_plugin_register_init(const char *name, sdb_plugin_init_cb callback, sdb_object_t *user_data) { char cb_name[1024]; - return plugin_add_callback(&init_list, "init", + return plugin_add_impl(&init_list, callback_type, "init", plugin_get_name(name, cb_name, sizeof(cb_name)), (void *)callback, user_data); } /* sdb_plugin_register_init */ @@ -915,7 +981,7 @@ sdb_plugin_register_shutdown(const char *name, sdb_plugin_shutdown_cb callback, sdb_object_t *user_data) { char cb_name[1024]; - return plugin_add_callback(&shutdown_list, "shutdown", + return plugin_add_impl(&shutdown_list, callback_type, "shutdown", plugin_get_name(name, cb_name, sizeof(cb_name)), (void *)callback, user_data); } /* sdb_plugin_register_shutdown */ @@ -925,7 +991,7 @@ sdb_plugin_register_log(const char *name, sdb_plugin_log_cb callback, sdb_object_t *user_data) { char cb_name[1024]; - return plugin_add_callback(&log_list, "log", + return plugin_add_impl(&log_list, callback_type, "log", plugin_get_name(name, cb_name, sizeof(cb_name)), callback, user_data); } /* sdb_plugin_register_log */ @@ -935,7 +1001,7 @@ sdb_plugin_register_cname(const char *name, sdb_plugin_cname_cb callback, sdb_object_t *user_data) { char cb_name[1024]; - return plugin_add_callback(&cname_list, "cname", + return plugin_add_impl(&cname_list, callback_type, "cname", plugin_get_name(name, cb_name, sizeof(cb_name)), callback, user_data); } /* sdb_plugin_register_cname */ @@ -1001,46 +1067,21 @@ sdb_plugin_register_collector(const char *name, sdb_plugin_collector_cb callback } /* sdb_plugin_register_collector */ int -sdb_plugin_register_ts_fetcher(const char *name, - sdb_plugin_fetch_ts_cb callback, sdb_object_t *user_data) +sdb_plugin_register_timeseries_fetcher(const char *name, + sdb_timeseries_fetcher_t *fetcher, sdb_object_t *user_data) { - return plugin_add_callback(&ts_fetcher_list, "time-series fetcher", - name, callback, user_data); -} /* sdb_plugin_register_ts_fetcher */ + return plugin_add_impl(×eries_fetcher_list, ts_fetcher_type, "time-series fetcher", + name, fetcher, user_data); +} /* sdb_plugin_register_timeseries_fetcher */ int sdb_plugin_register_writer(const char *name, sdb_store_writer_t *writer, sdb_object_t *user_data) { char cb_name[1024]; - sdb_object_t *obj; - - if ((! name) || (! writer)) - return -1; - - if (! writer_list) - writer_list = sdb_llist_create(); - if (! writer_list) - return -1; - - plugin_get_name(name, cb_name, sizeof(cb_name)); - - obj = sdb_object_create(cb_name, writer_type, + return plugin_add_impl(&writer_list, writer_type, "store writer", + plugin_get_name(name, cb_name, sizeof(cb_name)), writer, user_data); - if (! obj) - return -1; - - if (sdb_llist_append(writer_list, obj)) { - sdb_object_deref(obj); - return -1; - } - - /* pass control to the list */ - sdb_object_deref(obj); - - sdb_log(SDB_LOG_INFO, "core: Registered store writer callback '%s'.", - cb_name); - return 0; } /* sdb_store_register_writer */ int @@ -1048,34 +1089,9 @@ sdb_plugin_register_reader(const char *name, sdb_store_reader_t *reader, sdb_object_t *user_data) { char cb_name[1024]; - sdb_object_t *obj; - - if ((! name) || (! reader)) - return -1; - - if (! reader_list) - reader_list = sdb_llist_create(); - if (! reader_list) - return -1; - - plugin_get_name(name, cb_name, sizeof(cb_name)); - - obj = sdb_object_create(cb_name, reader_type, + return plugin_add_impl(&reader_list, reader_type, "store reader", + plugin_get_name(name, cb_name, sizeof(cb_name)), reader, user_data); - if (! obj) - return -1; - - if (sdb_llist_append(reader_list, obj)) { - sdb_object_deref(obj); - return -1; - } - - /* pass control to the list */ - sdb_object_deref(obj); - - sdb_log(SDB_LOG_INFO, "core: Registered store reader callback '%s'.", - cb_name); - return 0; } /* sdb_plugin_register_reader */ void @@ -1517,8 +1533,7 @@ sdb_timeseries_t * sdb_plugin_fetch_timeseries(const char *type, const char *id, sdb_timeseries_opts_t *opts) { - callback_t *plugin; - sdb_plugin_fetch_ts_cb callback; + ts_fetcher_t *fetcher; sdb_timeseries_t *ts; ctx_t *old_ctx; @@ -1526,21 +1541,45 @@ sdb_plugin_fetch_timeseries(const char *type, const char *id, if ((! type) || (! id) || (! opts)) return NULL; - plugin = CB(sdb_llist_search_by_name(ts_fetcher_list, type)); - if (! plugin) { + fetcher = TS_FETCHER(sdb_llist_search_by_name(timeseries_fetcher_list, type)); + if (! fetcher) { sdb_log(SDB_LOG_ERR, "core: Cannot fetch time-series of type %s: " "no such plugin loaded", type); errno = ENOENT; return NULL; } - old_ctx = ctx_set(plugin->cb_ctx); - callback = (sdb_plugin_fetch_ts_cb)plugin->cb_callback; - ts = callback(id, opts, plugin->cb_user_data); + old_ctx = ctx_set(fetcher->ts_ctx); + ts = fetcher->impl.fetch(id, opts, fetcher->ts_user_data); ctx_set(old_ctx); return ts; } /* sdb_plugin_fetch_timeseries */ +sdb_timeseries_info_t * +sdb_plugin_describe_timeseries(const char *type, const char *id) +{ + ts_fetcher_t *fetcher; + sdb_timeseries_info_t *ts_info; + + ctx_t *old_ctx; + + if ((! type) || (! id)) + return NULL; + + fetcher = TS_FETCHER(sdb_llist_search_by_name(timeseries_fetcher_list, type)); + if (! fetcher) { + sdb_log(SDB_LOG_ERR, "core: Cannot describe time-series of type %s: " + "no such plugin loaded", type); + errno = ENOENT; + return NULL; + } + + old_ctx = ctx_set(fetcher->ts_ctx); + ts_info = fetcher->impl.describe(id, fetcher->ts_user_data); + ctx_set(old_ctx); + return ts_info; +} /* sdb_plugin_describe_timeseries */ + int sdb_plugin_query(sdb_ast_node_t *ast, sdb_store_writer_t *w, sdb_object_t *wd, sdb_strbuf_t *errbuf) @@ -1735,9 +1774,8 @@ sdb_plugin_store_metric(const char *hostname, const char *name, if (store) { if (store->last_update < last_update) store->last_update = last_update; - metric.store.type = store->type; - metric.store.id = store->id; - metric.store.last_update = store->last_update; + metric.stores = store; + metric.stores_num = 1; } metric.last_update = last_update ? last_update : sdb_gettime(); if (get_interval(SDB_METRIC, cname, -1, NULL, name,