]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
daemon/engine: extensible registry of cache backends
authorMarek Vavruša <marek.vavrusa@nic.cz>
Fri, 1 May 2015 15:51:09 +0000 (17:51 +0200)
committerMarek Vavruša <marek.vavrusa@nic.cz>
Sat, 2 May 2015 18:00:49 +0000 (20:00 +0200)
the engine keeps an array of storage backends available
for caching, it is possible to switch the backend on
runtime with standard ‘proto://config' string

the default backend is ‘lmdb://<path>’

daemon/bindings.c
daemon/engine.c
daemon/engine.h

index 6b6c7ccfcc8d5a9fd282983ddeb955be288eac32..cff98a205ab664190c4d85798c80ebca99e738c3 100644 (file)
@@ -304,6 +304,26 @@ static int cache_count(lua_State *L)
        return 1;
 }
 
+static struct storage_api *cache_select_storage(struct engine *engine, const char **conf)
+{
+       /* Return default backend */
+       storage_registry_t *registry = &engine->storage_registry;
+       if (!*conf || !strstr(*conf, "://")) {
+               return &registry->at[0];
+       }
+
+       /* Find storage backend from config prefix */
+       for (unsigned i = 0; i < registry->len; ++i) {
+               struct storage_api *storage = &registry->at[i];
+               if (strncmp(*conf, storage->prefix, strlen(storage->prefix)) == 0) {
+                       *conf += strlen(storage->prefix);
+                       return storage;
+               }
+       }
+
+       return NULL;
+}
+
 /** Open cache */
 static int cache_open(lua_State *L)
 {
@@ -314,16 +334,26 @@ static int cache_open(lua_State *L)
                lua_error(L);
        }
 
-       /* Close if already open */
+       /* Select cache storage backend */
        struct engine *engine = engine_luaget(L);
+       const char *conf = n > 1 ? lua_tostring(L, 2) : NULL;
+       struct storage_api *storage = cache_select_storage(engine, &conf);
+       if (!storage) {
+               format_error(L, "unsupported cache backend");
+               lua_error(L);
+       }
+       kr_cache_storage_set(storage->api);
+
+       /* Close if already open */
        if (engine->resolver.cache != NULL) {
                kr_cache_close(engine->resolver.cache);
        }
-
-       /* Open resolution context cache */
-       engine->resolver.cache = kr_cache_open(".", engine->pool, lua_tointeger(L, 1));
+       /* Reopen cache */
+       void *storage_opts = storage->opts_create(conf, lua_tointeger(L, 1));
+       engine->resolver.cache = kr_cache_open(storage_opts, engine->pool);
+       free(storage_opts);
        if (engine->resolver.cache == NULL) {
-               format_error(L, "can't open cache in rundir");
+               format_error(L, "can't open cache");
                lua_error(L);
        }
 
index f902354005efd891329335cd9de03a48f3fd2425..d6b562780fe45a8c5de51b5ab8bb587b06cce6cd 100644 (file)
@@ -17,6 +17,8 @@
 #include <uv.h>
 #include <unistd.h>
 #include <libknot/internal/mempattern.h>
+/* #include <libknot/internal/namedb/namedb_trie.h> @todo Not supported (doesn't keep value copy) */
+#include <libknot/internal/namedb/namedb_lmdb.h>
 
 #include "daemon/engine.h"
 #include "daemon/bindings.h"
@@ -97,6 +99,18 @@ static int l_trampoline(lua_State *L)
  * Engine API.
  */
 
+/** @internal Make lmdb options. */
+void *namedb_lmdb_mkopts(const char *conf, size_t maxsize)
+{
+       struct namedb_lmdb_opts *opts = malloc(sizeof(*opts));
+       if (opts) {
+               memset(opts, 0, sizeof(*opts));
+               opts->path = conf ? conf : ".";
+               opts->mapsize = maxsize;
+       }
+       return opts;
+}
+
 static int init_resolver(struct engine *engine)
 {
        /* Open resolution context */
@@ -106,7 +120,12 @@ static int init_resolver(struct engine *engine)
        engine_register(engine, "iterate");
        engine_register(engine, "itercache");
 
-       return kr_ok();
+       /* Initialize storage backends */
+       struct storage_api lmdb = {
+               "lmdb://", namedb_lmdb_api, namedb_lmdb_mkopts
+       };
+
+       return array_push(engine->storage_registry, lmdb);
 }
 
 static int init_state(struct engine *engine)
@@ -168,6 +187,7 @@ void engine_deinit(struct engine *engine)
                kr_module_unload(&engine->modules.at[i]);
        }
        array_clear(engine->modules);
+       array_clear(engine->storage_registry);
 
        if (engine->L) {
                lua_close(engine->L);
index 3918ee4b3ee127b4c46d9159ee4db1c7b2902c19..063bdff9ebbb7a2215ba5123e0a4e2528d53cf33 100644 (file)
@@ -24,10 +24,21 @@ struct lua_State;
 #include "lib/resolve.h"
 #include "daemon/network.h"
 
+/** Cache storage backend. */
+struct storage_api {
+       const char *prefix; /**< Storage prefix, e.g. 'lmdb://' */
+       const namedb_api_t *(*api)(void); /**< Storage API implementation */
+       void *(*opts_create)(const char *, size_t); /**< Storage options factory */
+};
+
+/** @internal Array of cache backend options. */
+typedef array_t(struct storage_api) storage_registry_t;
+
 struct engine {
     struct kr_context resolver;
     struct network net;
     module_array_t modules;
+    storage_registry_t storage_registry;
     mm_ctx_t *pool;
     struct lua_State *L;
 };