Improvements
------------
- capabilities are no longer constrained when running as root (!1012)
+- cache: add percentage usage to cache.stats() (!1025)
Bugfixes
--------
*/
#include "daemon/bindings/impl.h"
+#include "lib/cache/cdb_lmdb.h"
#include "daemon/worker.h"
#include "daemon/zimport.h"
add_stat(match_miss);
add_stat(read_leq);
add_stat(read_leq_miss);
+ /* usage_percent statistics special case - double */
+ struct libknot_lmdb_env *libknot_db = knot_db_t_kres2libknot(cache->db);
+ cache->stats.usage_percent = cache->api->usage_percent(libknot_db);
+ lua_pushnumber(L, cache->stats.usage_percent);
+ lua_setfield(L, -2, "usage_percent");
+ free(libknot_db);
#undef add_stat
return 1;
is(cache.count(), 0, 'cache is empty after full clear')
end
+local function test_cache_used(lower, upper)
+ return function()
+ local usage = cache.stats().usage_percent
+ ok(usage >= lower and usage <= upper, string.format('cache percentage usage is between <%d, %d>', lower, upper))
+ end
+end
+
return {
+ test_cache_used(0, 1),
import_zone,
+ test_cache_used(11, 12),
test_exact_match_qtype,
test_exact_match_qname,
test_callback,
import_zone,
test_subtree,
+ test_cache_used(10, 11),
test_subtree_limit,
+ test_cache_used(5, 6),
test_apex,
import_zone,
test_root,
import_zone,
test_complete_flush,
+ test_cache_used(0, 1),
}
uint64_t match_miss;
uint64_t read_leq;
uint64_t read_leq_miss;
+ double usage_percent;
};
struct kr_cache {
knot_db_t *db;
uint64_t match_miss;
uint64_t read_leq;
uint64_t read_leq_miss;
+ double usage_percent;
};
* return: 0 for equality, > 0 for less, < 0 kr_error */
int (*read_leq)(knot_db_t *db, struct kr_cdb_stats *stat,
knot_db_val_t *key, knot_db_val_t *val);
+
+ double (*usage_percent)(knot_db_t *db);
};
#include "lib/cache/cdb_lmdb.h"
#include "lib/cache/cdb_api.h"
#include "lib/cache/api.h"
+#include <lib/cache/impl.h>
#include "lib/utils.h"
#define LMDB_DIR_MODE 0770
#define LMDB_FILE_MODE 0660
+/* TODO: we rely on mirrors of these two structs not changing layout
+ * in libknot and knot resolver! */
struct lmdb_env
{
size_t mapsize;
} txn;
};
+struct libknot_lmdb_env {
+ bool shared;
+ unsigned dbi;
+ void *env;
+ knot_mm_t *pool;
+};
+
+
/** @brief Convert LMDB error code. */
static int lmdb_error(int error)
{
return (MDB_val){ .mv_size = v.len, .mv_data = v.data };
}
-
/*! \brief Set the environment map size.
* \note This also sets the maximum database size, see \fn mdb_env_set_mapsize
*/
return ret;
}
+static double cdb_usage(knot_db_t *db)
+{
+ const size_t db_size = knot_db_lmdb_get_mapsize(db);
+ const size_t db_usage_abs = knot_db_lmdb_get_usage(db);
+ const double db_usage = (double)db_usage_abs / db_size * 100.0;
+
+ return db_usage;
+}
+
+
+/** Conversion between knot and lmdb structs. */
+knot_db_t *knot_db_t_kres2libknot(const knot_db_t * db)
+{
+ /* this is struct lmdb_env as in resolver/cdb_lmdb.c */
+ const struct lmdb_env *kres_db = db;
+ struct libknot_lmdb_env *libknot_db = malloc(sizeof(*libknot_db));
+ if (libknot_db != NULL) {
+ libknot_db->shared = false;
+ libknot_db->pool = NULL;
+ libknot_db->env = kres_db->env;
+ libknot_db->dbi = kres_db->dbi;
+ }
+ return libknot_db;
+}
const struct kr_cdb_api *kr_cdb_lmdb(void)
{
cdb_init, cdb_deinit, cdb_count, cdb_clear, cdb_commit,
cdb_readv, cdb_writev, cdb_remove,
cdb_match,
- cdb_read_leq
+ cdb_read_leq,
+ cdb_usage,
};
return &api;
KR_EXPORT KR_CONST
const struct kr_cdb_api *kr_cdb_lmdb(void);
+
+KR_EXPORT
+knot_db_t *knot_db_t_kres2libknot(const knot_db_t * db);
#include "db.h"
+#include "lib/cache/cdb_lmdb.h"
#include <lib/cache/impl.h>
//#include <lib/defines.h>
#include <time.h>
#include <sys/stat.h>
-//TODO: we rely on mirrors of these two structs not changing layout in knot-dns and knot-resolver!
-struct libknot_lmdb_env {
- bool shared;
- unsigned dbi;
- void *env;
- knot_mm_t *pool;
-};
-
-struct kres_lmdb_env {
- size_t mapsize;
- unsigned dbi;
- void *env;
- // sub-struct txn ommited
-};
-
-static knot_db_t *knot_db_t_kres2libknot(const knot_db_t * db)
-{
- const struct kres_lmdb_env *kres_db = db; // this is struct lmdb_env as in resolver/cdb_lmdb.c
- struct libknot_lmdb_env *libknot_db = malloc(sizeof(*libknot_db));
- if (libknot_db != NULL) {
- libknot_db->shared = false;
- libknot_db->pool = NULL;
- libknot_db->env = kres_db->env;
- libknot_db->dbi = kres_db->dbi;
- }
- return libknot_db;
-}
-
int kr_gc_cache_open(const char *cache_path, struct kr_cache *kres_db,
knot_db_t ** libknot_db)
{
#include <lib/cache/api.h>
#include <lib/cache/impl.h>
#include <lib/defines.h>
+#include "lib/cache/cdb_lmdb.h"
#include "kr_cache_gc.h"
}
knot_db_t *const db = (*state)->db; // frequently used shortcut
- const size_t db_size = knot_db_lmdb_get_mapsize(db);
- const size_t db_usage_abs = knot_db_lmdb_get_usage(db);
- const double db_usage = (double)db_usage_abs / db_size * 100.0;
+ const struct kr_cdb_api *cache_api = kr_cdb_lmdb();
+ const double db_usage = cache_api->usage_percent(db);
#if 0 // Probably not worth it, better reduce the risk by checking more often.
if (db_usage > 90.0) {
free(*libknot_db);
#endif
const bool large_usage = db_usage >= cfg->cache_max_usage;
if (cfg->dry_run || large_usage) { // don't print this on every size check
- const size_t MiB = 1024 * 1024;
- #define MiB_round(n) (((n) + MiB/2) / MiB)
- printf("Usage: %.2lf%% (%zu / %zu MiB)\n",
- db_usage, MiB_round(db_usage_abs), MiB_round(db_size));
- #undef MiB_round
+ printf("Usage: %.2lf%%\n", db_usage);
}
if (cfg->dry_run || !large_usage) {
return KNOT_EOK;