]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
clear cache if overfull
authorVladimír Čunát <vladimir.cunat@nic.cz>
Wed, 3 Jan 2018 08:57:27 +0000 (09:57 +0100)
committerVladimír Čunát <vladimir.cunat@nic.cz>
Wed, 3 Jan 2018 08:58:31 +0000 (09:58 +0100)
I somehow forgot to migrate that behavior when rewriting cache :-/

lib/cache/entry_list.c
lib/cdb_lmdb.c

index 70553e5df6b30070d30f607a56bfdefa0af51f18..f2c40b3ca5f6c8d81afa008cf4b52c094001aa7c 100644 (file)
@@ -184,6 +184,19 @@ int entry_h_splice(
        knot_db_val_t val = { .len = storage_size, .data = NULL };
        int ret = cache_op(cache, write, &key, &val, 1);
        if (ret || !val.data || !val.len) {
+               /* Clear cache if overfull.  It's nontrivial to do better with LMDB.
+                * LATER: some garbage-collection mechanism. */
+               if (ret == kr_error(ENOSPC)) {
+                       ret = kr_cache_clear(cache);
+                       const char *msg = "[cache] clearing because overfull, ret = %d\n";
+                       if (ret) {
+                               kr_log_error(msg, ret);
+                       } else {
+                               kr_log_info(msg, ret);
+                               ret = kr_error(ENOSPC);
+                       }
+                       return ret;
+               }
                assert(ret); /* otherwise "succeeding" but `val` is bad */
                VERBOSE_MSG(qry, "=> failed backend write, ret = %d\n", ret);
                return kr_error(ret ? ret : ENOSPC);
index af2495961febd11d285a2e4113b4d17a89623710..cfbfc38474e6665359e1a55a03fa70051151302b 100644 (file)
@@ -56,20 +56,21 @@ struct lmdb_env
 /** @brief Convert LMDB error code. */
 static int lmdb_error(int error)
 {
+       /* _BAD_TXN may happen with overfull DB,
+        * even during mdb_get with a single fork :-/ */
+       if (error == MDB_BAD_TXN) {
+               kr_log_info("[cache] MDB_BAD_TXN, probably overfull\n");
+               error = ENOSPC;
+       }
        switch (error) {
        case MDB_SUCCESS:
                return kr_ok();
        case MDB_NOTFOUND:
                return kr_error(ENOENT);
-
        case ENOSPC:
        case MDB_MAP_FULL:
        case MDB_TXN_FULL:
-       case MDB_BAD_TXN:
-               /* _BAD_TXN in practice happens with overfull DB,
-                * even during mdb_get with a single fork :-/ */
                return kr_error(ENOSPC);
-
        default:
                kr_log_error("[cache] LMDB error: %s\n", mdb_strerror(error));
                assert(false);