summaryrefslogtreecommitdiffstats
path: root/utils/cache_gc
diff options
context:
space:
mode:
Diffstat (limited to 'utils/cache_gc')
-rw-r--r--utils/cache_gc/categories.c2
-rw-r--r--utils/cache_gc/db.c6
-rw-r--r--utils/cache_gc/kr_cache_gc.c77
-rw-r--r--utils/cache_gc/main.c26
-rw-r--r--utils/cache_gc/meson.build3
5 files changed, 58 insertions, 56 deletions
diff --git a/utils/cache_gc/categories.c b/utils/cache_gc/categories.c
index 19dec45..aaa1ae5 100644
--- a/utils/cache_gc/categories.c
+++ b/utils/cache_gc/categories.c
@@ -18,7 +18,7 @@ static bool rrtype_is_infrastructure(uint16_t r)
}
}
-static int get_random(int to)
+static unsigned int get_random(int to)
{
// We don't need these to be really unpredictable,
// but this should be cheap enough not to be noticeable.
diff --git a/utils/cache_gc/db.c b/utils/cache_gc/db.c
index fc4a2fd..c31ff22 100644
--- a/utils/cache_gc/db.c
+++ b/utils/cache_gc/db.c
@@ -9,11 +9,13 @@
#include <time.h>
#include <sys/stat.h>
+#define MDB_FILE "/data.mdb"
+
int kr_gc_cache_open(const char *cache_path, struct kr_cache *kres_db,
knot_db_t ** libknot_db)
{
- char cache_data[strlen(cache_path) + 10];
- snprintf(cache_data, sizeof(cache_data), "%s/data.mdb", cache_path);
+ char cache_data[strlen(cache_path) + sizeof(MDB_FILE)];
+ (void)snprintf(cache_data, sizeof(cache_data), "%s" MDB_FILE, cache_path);
struct stat st = { 0 };
if (stat(cache_path, &st) || !(st.st_mode & S_IFDIR)
diff --git a/utils/cache_gc/kr_cache_gc.c b/utils/cache_gc/kr_cache_gc.c
index 5978345..4097c80 100644
--- a/utils/cache_gc/kr_cache_gc.c
+++ b/utils/cache_gc/kr_cache_gc.c
@@ -8,20 +8,12 @@
// libknot includes
#include <libknot/libknot.h>
-// dynarray is inside libknot since 3.1, but it's differently named
-#ifdef knot_dynarray_declare
- #define dynarray_declare knot_dynarray_declare
- #define dynarray_define knot_dynarray_define
- #define dynarray_foreach knot_dynarray_foreach
-#else
- #include <contrib/dynarray.h>
-#endif
-
// resolver includes
#include <lib/cache/api.h>
#include <lib/cache/impl.h>
#include <lib/defines.h>
#include "lib/cache/cdb_lmdb.h"
+#include "lib/generic/array.h"
#include "lib/utils.h"
#include "kr_cache_gc.h"
@@ -43,41 +35,40 @@ static knot_db_val_t *dbval_copy(const knot_db_val_t * from)
}
// section: rrtype list
+typedef array_t(uint16_t) rrtype_array_t;
-dynarray_declare(rrtype, uint16_t, DYNARRAY_VISIBILITY_STATIC, 64)
- dynarray_define(rrtype, uint16_t, DYNARRAY_VISIBILITY_STATIC)
-static void rrtypelist_add(rrtype_dynarray_t * arr, uint16_t add_type)
+static void rrtypelist_add(rrtype_array_t *arr, uint16_t add_type)
{
bool already_present = false;
- dynarray_foreach(rrtype, uint16_t, i, *arr) {
- if (*i == add_type) {
+ for (size_t i = 0; i < arr->len; i++) {
+ if (arr->at[i] == add_type) {
already_present = true;
break;
}
}
if (!already_present) {
- rrtype_dynarray_add(arr, &add_type);
+ kr_require(array_push(*arr, add_type) >= 0);
}
}
-static void rrtypelist_print(rrtype_dynarray_t * arr)
+static void rrtypelist_print(rrtype_array_t *arr)
{
char type_s[32] = { 0 };
- dynarray_foreach(rrtype, uint16_t, i, *arr) {
- knot_rrtype_to_string(*i, type_s, sizeof(type_s));
+ for (size_t i = 0; i < arr->len; i++) {
+ knot_rrtype_to_string(arr->at[i], type_s, sizeof(type_s));
printf(" %s", type_s);
}
printf("\n");
}
-dynarray_declare(entry, knot_db_val_t *, DYNARRAY_VISIBILITY_STATIC, 256)
- dynarray_define(entry, knot_db_val_t *, DYNARRAY_VISIBILITY_STATIC)
-static void entry_dynarray_deep_free(entry_dynarray_t * d)
+typedef array_t(knot_db_val_t *) entry_array_t;
+
+static void entry_array_deep_free(entry_array_t *d)
{
- dynarray_foreach(entry, knot_db_val_t *, i, *d) {
- free(*i);
+ for (size_t i = 0; i < d->len; i++) {
+ free(d->at[i]);
}
- entry_dynarray_free(d);
+ array_clear(*d);
}
typedef struct {
@@ -98,7 +89,7 @@ int cb_compute_categories(const knot_db_val_t * key, gc_record_info_t * info,
typedef struct {
category_t limit_category;
- entry_dynarray_t to_delete;
+ entry_array_t to_delete;
size_t cfg_temp_keys_space;
size_t used_space;
size_t oversize_records;
@@ -117,7 +108,7 @@ int cb_delete_categories(const knot_db_val_t * key, gc_record_info_t * info,
ctx->oversize_records++;
free(todelete);
} else {
- entry_dynarray_add(&ctx->to_delete, &todelete);
+ kr_require(array_push(ctx->to_delete, todelete) >= 0);
ctx->used_space = used;
}
}
@@ -194,12 +185,12 @@ int kr_cache_gc(kr_cache_gc_cfg_t *cfg, kr_cache_gc_state_t **state)
// Mixing ^^ page usage and entry sizes (key+value lengths) didn't work
// too well, probably due to internal fragmentation after some GC cycles.
// Therefore let's scale this by the ratio of these two sums.
- ssize_t cats_sumsize = 0;
+ size_t cats_sumsize = 0;
for (int i = 0; i < CATEGORIES; ++i) {
cats_sumsize += cats.categories_sizes[i];
}
/* use less precise variant to avoid 32-bit overflow */
- ssize_t amount_tofree = cats_sumsize / 100 * cfg->cache_to_be_freed;
+ size_t amount_tofree = cats_sumsize / 100 * cfg->cache_to_be_freed;
kr_log_debug(CACHE, "tofree: %zd / %zd\n", amount_tofree, cats_sumsize);
if (VERBOSE_STATUS) {
@@ -212,8 +203,11 @@ int kr_cache_gc(kr_cache_gc_cfg_t *cfg, kr_cache_gc_state_t **state)
}
category_t limit_category = CATEGORIES;
- while (limit_category > 0 && amount_tofree > 0) {
- amount_tofree -= cats.categories_sizes[--limit_category];
+ while (limit_category > 0) {
+ size_t cat_size = cats.categories_sizes[--limit_category];
+ if (cat_size > amount_tofree)
+ break;
+ amount_tofree -= cat_size;
}
printf("Cache analyzed in %.0lf msecs, %zu records, limit category is %d.\n",
@@ -226,13 +220,13 @@ int kr_cache_gc(kr_cache_gc_cfg_t *cfg, kr_cache_gc_state_t **state)
to_del.limit_category = limit_category;
ret = kr_gc_cache_iter(db, cfg, cb_delete_categories, &to_del);
if (ret != KNOT_EOK) {
- entry_dynarray_deep_free(&to_del.to_delete);
+ entry_array_deep_free(&to_del.to_delete);
kr_cache_gc_free_state(state);
return ret;
}
printf
("%zu records to be deleted using %.2lf MBytes of temporary memory, %zu records skipped due to memory limit.\n",
- to_del.to_delete.size, ((double)to_del.used_space / 1048576.0),
+ to_del.to_delete.len, ((double)to_del.used_space / 1048576.0),
to_del.oversize_records);
//// 4. execute the planned deletions.
@@ -242,23 +236,24 @@ int kr_cache_gc(kr_cache_gc_cfg_t *cfg, kr_cache_gc_state_t **state)
kr_timer_start(&timer_delete);
kr_timer_start(&timer_rw_txn);
- rrtype_dynarray_t deleted_rrtypes = { 0 };
+ rrtype_array_t deleted_rrtypes = { 0 };
ret = api->txn_begin(db, &txn, 0);
if (ret != KNOT_EOK) {
printf("Error starting R/W DB transaction (%s).\n",
knot_strerror(ret));
- entry_dynarray_deep_free(&to_del.to_delete);
+ entry_array_deep_free(&to_del.to_delete);
kr_cache_gc_free_state(state);
return ret;
}
- dynarray_foreach(entry, knot_db_val_t *, i, to_del.to_delete) {
- ret = api->del(&txn, *i);
+ for (size_t i = 0; i < to_del.to_delete.len; i++) {
+ knot_db_val_t *val = to_del.to_delete.at[i];
+ ret = api->del(&txn, val);
switch (ret) {
case KNOT_EOK:
deleted_records++;
- const int entry_type = kr_gc_key_consistent(**i);
+ const int entry_type = kr_gc_key_consistent(*val);
if (entry_type >= 0) // some "inconsistent" entries are OK
rrtypelist_add(&deleted_rrtypes, entry_type);
break;
@@ -267,8 +262,8 @@ int kr_cache_gc(kr_cache_gc_cfg_t *cfg, kr_cache_gc_state_t **state)
if (VERBOSE_STATUS) {
// kresd normally only inserts (or overwrites),
// so it's generally suspicious when a key goes missing.
- printf("Record already gone (key len %zu): ", (*i)->len);
- debug_printbin((*i)->data, (*i)->len);
+ printf("Record already gone (key len %zu): ", val->len);
+ debug_printbin(val->data, val->len);
printf("\n");
}
break;
@@ -316,8 +311,8 @@ finish:
printf("It took %.0lf msecs, %zu transactions (%s)\n\n",
kr_timer_elapsed(&timer_delete) * 1000, rw_txn_count, knot_strerror(ret));
- rrtype_dynarray_free(&deleted_rrtypes);
- entry_dynarray_deep_free(&to_del.to_delete);
+ array_clear(deleted_rrtypes);
+ entry_array_deep_free(&to_del.to_delete);
// OK, let's close it in this case.
kr_cache_gc_free_state(state);
diff --git a/utils/cache_gc/main.c b/utils/cache_gc/main.c
index 5adf19f..fe131cd 100644
--- a/utils/cache_gc/main.c
+++ b/utils/cache_gc/main.c
@@ -13,6 +13,7 @@
#include "kr_cache_gc.h"
static volatile int killed = 0;
+static volatile int exit_code = 0;
static void got_killed(int signum)
{
@@ -21,12 +22,10 @@ static void got_killed(int signum)
case 1:
break;
case 2:
- exit(5);
+ exit_code = 5;
break;
- case 3:
- abort();
default:
- kr_assert(false);
+ abort();
}
}
@@ -60,16 +59,20 @@ int main(int argc, char *argv[])
{
printf("Knot Resolver Cache Garbage Collector, version %s\n", PACKAGE_VERSION);
if (setvbuf(stdout, NULL, _IONBF, 0) || setvbuf(stderr, NULL, _IONBF, 0)) {
- fprintf(stderr, "Failed to to set output buffering (ignored): %s\n",
+ (void)fprintf(stderr, "Failed to to set output buffering (ignored): %s\n",
strerror(errno));
- fflush(stderr);
+ (void)fflush(stderr);
}
- signal(SIGTERM, got_killed);
- signal(SIGKILL, got_killed);
- signal(SIGPIPE, got_killed);
- signal(SIGCHLD, got_killed);
- signal(SIGINT, got_killed);
+ struct sigaction act = {
+ .sa_handler = got_killed,
+ .sa_flags = SA_RESETHAND,
+ };
+ sigemptyset(&act.sa_mask);
+ kr_assert(!sigaction(SIGTERM, &act, NULL));
+ kr_assert(!sigaction(SIGPIPE, &act, NULL));
+ kr_assert(!sigaction(SIGCHLD, &act, NULL));
+ kr_assert(!sigaction(SIGINT, &act, NULL));
kr_cache_gc_cfg_t cfg = {
.ro_txn_items = 200,
@@ -131,7 +134,6 @@ int main(int argc, char *argv[])
return 1;
}
- int exit_code = 0;
kr_cache_gc_state_t *gc_state = NULL;
bool last_espace = false;
do {
diff --git a/utils/cache_gc/meson.build b/utils/cache_gc/meson.build
index 40e127d..6ed86af 100644
--- a/utils/cache_gc/meson.build
+++ b/utils/cache_gc/meson.build
@@ -18,9 +18,12 @@ if build_utils
contrib_dep,
libkres_dep,
libknot,
+ libuv,
+ lmdb,
],
install: true,
install_dir: get_option('sbindir'),
+ install_rpath: rpath,
)
integr_tests += [