]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
WIP; main FIXME: the GC would need rewriting
authorVladimír Čunát <vladimir.cunat@nic.cz>
Tue, 4 May 2021 10:44:12 +0000 (12:44 +0200)
committerVladimír Čunát <vladimir.cunat@nic.cz>
Tue, 4 May 2021 15:51:54 +0000 (17:51 +0200)
contrib/meson.build
lib/cache/cdb_lmdb.c
lib/meson.build
meson.build
meson_options.txt
tests/unit/meson.build

index 622bfce315f9d9dde55fc4fef63099467c3b3e52..e4075b70a3192a7c63a9d8e863f435df473f6fd5 100644 (file)
@@ -27,8 +27,3 @@ contrib_dep = declare_dependency(
   link_with: contrib_lib,
 )
 
-
-cmake = import('cmake')
-libmdbx_proj = cmake.subproject('libmdbx')
-libmdbx = libmdbx_proj.dependency('mdbx-static')
-
index d2885a7c0b7bf0595269fb6b82ef265ec2408fbd..b8b105a07866a7d182fe5dd6346061acd128cd0f 100644 (file)
@@ -10,8 +10,6 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <unistd.h>
-//#include <lmdb.h>
-#include <mdbx.h>
 
 #include "contrib/cleanup.h"
 #include "contrib/ucw/lib.h"
 #define LMDB_DIR_MODE   0770
 #define LMDB_FILE_MODE  0660
 
+#if KR_USE_MDBX
+       #include <mdbx.h>
+       // FIXME: investigate mysterious constant-sized memleaks
+#else
+       #include <lmdb.h>
+#endif
 
-#define MDB_env MDBX_env
-#define mdb_env_create mdbx_env_create
-#define MDB_SUCCESS 0
-#define MDB_WRITEMAP MDBX_WRITEMAP
-#define MDB_MAPASYNC MDBX_UTTERLY_NOSYNC
-#define MDB_NOTLS MDBX_NOTLS
-#define mdb_env_open mdbx_env_open
-#define mdb_filehandle_t mdbx_filehandle_t
-#define mdb_env_get_fd mdbx_env_get_fd
-#define MDB_txn MDBX_txn
-#define MDB_RDWR MDBX_TXN_READWRITE
-#define mdb_txn_begin mdbx_txn_begin
-#define mdb_dbi_open mdbx_dbi_open
-#define MDB_dbi MDBX_dbi
-#define mdb_txn_commit mdbx_txn_commit
-#define mdb_env_close mdbx_env_close
-// Avoid mdbx_env_sync() as it uses some macro magic.
-#define mdb_env_sync(env, force) mdbx_env_sync_ex((env), (force), false)
-#define mdb_dbi_close mdbx_dbi_close
-#define MDB_cursor MDBX_cursor
-#define MDB_NOTFOUND MDBX_NOTFOUND
-#define MDB_MAP_FULL MDBX_MAP_FULL
-#define MDB_TXN_FULL MDBX_TXN_FULL
-#define mdb_strerror mdbx_strerror
-// Different field names as well; see val_mdb2knot().
-#define MDB_val MDBX_val
-// TODO: can be improved
-#define mdb_env_set_mapsize mdbx_env_set_mapsize
-#define MDB_RDONLY MDBX_TXN_RDONLY
-#define mdb_txn_renew mdbx_txn_renew
-#define MDB_READERS_FULL MDBX_READERS_FULL
-#define mdb_reader_check mdbx_reader_check
-#define mdb_txn_reset mdbx_txn_reset
-#define mdb_cursor_renew mdbx_cursor_renew
-#define mdb_cursor_open mdbx_cursor_open
-#define mdb_cursor_close mdbx_cursor_close
-#define mdb_cursor_get mdbx_cursor_get
-#define MDB_SET_RANGE MDBX_SET_RANGE
-#define mdb_txn_abort mdbx_txn_abort
-#define MDB_PREV MDBX_PREV
-#define MDB_NEXT MDBX_NEXT
-#define mdb_env_get_path mdbx_env_get_path
-#define mdb_del mdbx_del
-#define MDB_RESERVE MDBX_RESERVE
-#define mdb_put mdbx_put
-#define mdb_get mdbx_get
-#define mdb_drop mdbx_drop
+#if KR_USE_MDBX
+       #define MDB_env MDBX_env
+       #define mdb_env_create mdbx_env_create
+       #define MDB_SUCCESS 0
+       #define MDB_WRITEMAP MDBX_WRITEMAP
+       #define MDB_MAPASYNC MDBX_UTTERLY_NOSYNC
+       #define MDB_NOTLS MDBX_NOTLS
+       #define mdb_env_open mdbx_env_open
+       #define mdb_filehandle_t mdbx_filehandle_t
+       #define mdb_env_get_fd mdbx_env_get_fd
+       #define MDB_txn MDBX_txn
+       #define mdb_txn_begin mdbx_txn_begin
+       #define mdb_dbi_open mdbx_dbi_open
+       #define MDB_dbi MDBX_dbi
+       #define mdb_txn_commit mdbx_txn_commit
+       #define mdb_env_close mdbx_env_close
+       // Avoid mdbx_env_sync() as it uses some macro magic.
+       #define mdb_env_sync(env, force) mdbx_env_sync_ex((env), (force), false)
+       #define mdb_dbi_close mdbx_dbi_close
+       #define MDB_cursor MDBX_cursor
+       #define MDB_NOTFOUND MDBX_NOTFOUND
+       #define MDB_MAP_FULL MDBX_MAP_FULL
+       #define MDB_TXN_FULL MDBX_TXN_FULL
+       #define mdb_strerror mdbx_strerror
+       // Different field names as well; see val_mdb2knot().
+       #define MDB_val MDBX_val
+       // TODO: can be improved
+       #define mdb_env_set_mapsize mdbx_env_set_mapsize
+       #define MDB_RDONLY MDBX_TXN_RDONLY
+       #define mdb_txn_renew mdbx_txn_renew
+       #define MDB_READERS_FULL MDBX_READERS_FULL
+       #define mdb_reader_check mdbx_reader_check
+       #define mdb_txn_reset mdbx_txn_reset
+       #define mdb_cursor_renew mdbx_cursor_renew
+       #define mdb_cursor_open mdbx_cursor_open
+       #define mdb_cursor_close mdbx_cursor_close
+       #define mdb_cursor_get mdbx_cursor_get
+       #define MDB_SET_RANGE MDBX_SET_RANGE
+       #define mdb_txn_abort mdbx_txn_abort
+       #define MDB_PREV MDBX_PREV
+       #define MDB_NEXT MDBX_NEXT
+       #define mdb_env_get_path mdbx_env_get_path
+       #define mdb_del mdbx_del
+       #define MDB_RESERVE MDBX_RESERVE
+       #define mdb_put mdbx_put
+       #define mdb_get mdbx_get
+       #define mdb_drop mdbx_drop
+       // just an extra field at the end
+       #define MDB_stat MDBX_stat
+       #define MDB_RDWR MDBX_TXN_READWRITE
+       #define MDB_DATANAME MDBX_DATANAME
+#else
+       #define MDB_RDWR 0
+       #define MDB_DATANAME "/data.mdb"
+#endif
 
 /* TODO: we rely on mirrors of these two structs not changing layout
  * in libknot and knot resolver! */
@@ -146,16 +158,26 @@ static int lmdb_error(int error)
 /** Conversion between knot and lmdb structs for values. */
 static inline knot_db_val_t val_mdb2knot(MDB_val v)
 {
-       //return (knot_db_val_t){ .len = v.mv_size, .data = v.mv_data };
-       return (knot_db_val_t){ .len = v.iov_len, .data = v.iov_base };
+       return (knot_db_val_t){
+       #if KR_USE_MDBX
+               .len = v.iov_len, .data = v.iov_base
+       #else
+               .len = v.mv_size, .data = v.mv_data
+       #endif
+       };
 }
 static inline MDB_val val_knot2mdb(knot_db_val_t v)
 {
-       //return (MDB_val){ .mv_size = v.len, .mv_data = v.data };
-       return (MDB_val){ .iov_len = v.len, .iov_base = v.data };
+       return (MDB_val){
+       #if KR_USE_MDBX
+               .iov_len = v.len, .iov_base = v.data
+       #else
+               .mv_size = v.len, .mv_data = v.data
+       #endif
+       };
 }
 
-#if 0
+#if !KR_USE_MDBX
 /** Refresh mapsize value from file, including env->mapsize.
  * It's much lighter than reopen_env(). */
 static int refresh_mapsize(struct lmdb_env *env)
@@ -202,7 +224,7 @@ retry:
                ret = mdb_txn_begin(env->env, NULL, flag, txn);
        }
 
-#if 0
+#if !KR_USE_MDBX
        if (unlikely(ret == MDB_MAP_RESIZED)) {
                kr_log_info("[cache] detected size increased by another process\n");
                ret = refresh_mapsize(env);
@@ -367,7 +389,7 @@ static int cdb_open_env(struct lmdb_env *env, const char *path, const size_t map
        ret = mdb_env_create(&env->env);
        if (ret != MDB_SUCCESS) return lmdb_error(ret);
 
-       env->mdb_data_path = kr_absolutize_path(path, "data.mdb");
+       env->mdb_data_path = kr_absolutize_path(path, MDB_DATANAME);
        if (!env->mdb_data_path) {
                ret = ENOMEM;
                goto error_sys;
@@ -407,7 +429,7 @@ static int cdb_open_env(struct lmdb_env *env, const char *path, const size_t map
        env->st_ino = st.st_ino;
        env->st_size = st.st_size;
 
-#if 0
+#if !KR_USE_MDBX
        /* Get the real mapsize.  Shrinking can be restricted, etc.
         * Unfortunately this is only reliable when not setting the size explicitly. */
        if (!size_requested) {
@@ -499,7 +521,11 @@ static int cdb_count(kr_cdb_pt db, struct kr_cdb_stats *stats)
 
        MDB_stat stat;
        stats->count++;
+#if KR_USE_MDBX
+       ret = mdbx_env_stat_ex(env->env, txn, &stat, sizeof(stat));
+#else
        ret = mdb_stat(txn, env->dbi, &stat);
+#endif
 
        if (ret == MDB_SUCCESS) {
                return stat.ms_entries;
@@ -546,7 +572,12 @@ static int cdb_check_health(kr_cdb_pt db, struct kr_cdb_stats *stats)
                        ": file size %zu -> file size %zu\n",
                        env->mdb_data_path, (size_t)env->st_size, (size_t)st.st_size);
        env->st_size = st.st_size; // avoid retrying in cycle even if we fail
+       // FIXME?
+#if KR_USE_MDBX
+       return kr_ok();
+#else
        return refresh_mapsize(env);
+#endif
 }
 
 /** Obtain exclusive (advisory) lock by creating a file, returning FD or negative kr_error().
@@ -796,13 +827,15 @@ static int cdb_match(kr_cdb_pt db, struct kr_cdb_stats *stats,
 
        int results = 0;
        while (ret == MDB_SUCCESS) {
+               const knot_db_val_t cur_key_k = val_mdb2knot(cur_key);
                /* Retrieve current key and compare with prefix */
-               if (cur_key.mv_size < key->len || memcmp(cur_key.mv_data, key->data, key->len) != 0) {
+               if (cur_key_k.len < key->len
+                   || memcmp(cur_key_k.data, key->data, key->len) != 0) {
                        break;
                }
                /* Add to result set */
                if (results < maxcount) {
-                       keyval[results][0] = val_mdb2knot(cur_key);
+                       keyval[results][0] = cur_key_k;
                        keyval[results][1] = val_mdb2knot(cur_val);
                        ++results;
                } else {
@@ -882,7 +915,10 @@ static size_t cdb_get_maxsize(kr_cdb_pt db)
 /** Conversion between knot and lmdb structs. */
 knot_db_t *kr_cdb_pt2knot_db_t(kr_cdb_pt db)
 {
-       /* this is struct lmdb_env as in resolver/cdb_lmdb.c */
+#if KR_USE_MDBX
+       #pragma GCC warning "FIXME: we can't convert mdbx to libknot_lmdb_env; GC needs rewriting"
+       abort();
+#endif
        const struct lmdb_env *kres_db = db2env(db);
        struct libknot_lmdb_env *libknot_db = malloc(sizeof(*libknot_db));
        if (libknot_db != NULL) {
index 30f6511409cb37372bad5d8b5ade2682df1bf1e4..9cb3f6c699ba1ca218fcac2be0589521884c4d7f 100644 (file)
@@ -94,8 +94,7 @@ libkres_lib = library('kres',
     contrib_dep,
     kresconfig_dep,
     libuv,
-       #lmdb,
-       libmdbx,
+    cache_backend_dep,
     libknot,
     libdnssec,
     gnutls,
index 46b83e2280d78d1e069c136f75ca2ba4ac3afdd6..b2b85529740a7c29f0daf9401e8cb5f7f4a38144 100644 (file)
@@ -23,16 +23,31 @@ libknot = dependency('libknot', version: knot_version)
 libdnssec = dependency('libdnssec', version: knot_version)
 libzscanner = dependency('libzscanner', version: knot_version)
 libuv = dependency('libuv', version: '>=1.7')
-#FIXME
-lmdb = dependency('lmdb', required: false)
-if not lmdb.found()  # darwin workaround: missing pkgconfig
-  lmdb = meson.get_compiler('c').find_library('lmdb')
-endif
 gnutls = dependency('gnutls')
 luajit = dependency('luajit')
 # NOTE avoid using link_args for luajit due to a macOS issue
 # https://github.com/Homebrew/homebrew-core/issues/37169
 luajit_inc = luajit.partial_dependency(compile_args: true, includes: true)
+
+if get_option('cache_backend') == 'lmdb'
+  lmdb = dependency('lmdb', required: false)
+  if not lmdb.found()  # darwin workaround: missing pkgconfig
+       lmdb = meson.get_compiler('c').find_library('lmdb')
+  endif
+  cache_backend_dep = lmdb
+  add_project_arguments('-DKR_USE_MDBX=0', language : 'c')
+elif get_option('cache_backend') == 'mdbx'
+  cmake = import('cmake')
+  mdbx_opt = cmake.subproject_options()
+  mdbx_opt.add_cmake_defines({
+    'MDBX_BUILD_SHARED_LIBRARY': false,
+    'MDBX_BUILD_CXX': false,
+  })
+  libmdbx_proj = cmake.subproject('libmdbx', options: mdbx_opt)
+  cache_backend_dep = libmdbx_proj.dependency('mdbx-static')
+  add_project_arguments('-DKR_USE_MDBX=1', language : 'c')
+endif
+
 message('------------------------------')
 
 
index f7ca06aabdca3fda2aff1ed43a52859137b3c96f..de2cf92713a995cfebdde9ad7a3467e675ea060e 100644 (file)
@@ -210,3 +210,14 @@ option(
   value: 'auto',
   description: 'cmocka unit tests',
 )
+
+option(
+  'cache_backend',
+  type: 'combo',
+  choices: [
+    'lmdb',
+    'mdbx',
+  ],
+  value: 'lmdb',
+  description: 'cache backend to use; mdbx is experimental',
+)
index 53cf3d1d1d6398df7dffa3b3edb683aa8934df21..ab9480511c634ec144d69edfb9c9ec1f40705fd1 100644 (file)
@@ -22,7 +22,6 @@ foreach unit_test : unit_tests
       contrib_dep,
       libkres_dep,
       cmocka,
-      lmdb, #FIXME
     ],
   )
   test(