]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
lib/cache: kr_cache_clear() fixed
authorGrigorii Demidov <grigorii.demidov@nic.cz>
Mon, 22 Feb 2016 12:17:56 +0000 (13:17 +0100)
committerGrigorii Demidov <grigorii.demidov@nic.cz>
Mon, 22 Feb 2016 12:17:56 +0000 (13:17 +0100)
lib/cache.c
tests/test_cache.c

index f9c9b62d35a0ff7331b2f8e7f6031ccd4db5f066..6d0d25aaa48cfb6847574e51ccb66d65fe5c51d0 100644 (file)
 #define txn_api(txn) ((txn)->owner->api)
 #define txn_is_valid(txn) ((txn) && (txn)->owner && txn_api(txn))
 
-/** @internal Check cache internal data version. Clear if it doesn't match. */
+
+/** @internal Removes all records from cache. */
+static int cache_purge(struct kr_cache_txn *txn)
+{
+       int ret;
+       if (!txn_is_valid(txn)) {
+               return kr_error(EINVAL);
+       }
+
+       txn->owner->stats.delete += 1;
+       ret = txn_api(txn)->clear(&txn->t);
+       return ret;
+}
+
+/** @internal  Check cache internal data version. Clear if it doesn't match.
+ * returns :   EEXIST - cache data version matched.
+ *              0 - cache recreated, txn has to be committed.
+ *             otherwise - cache recreation fails.
+ */
+static int assert_right_version_txn(struct kr_cache_txn *txn)
+{
+       /* Check cache ABI version */
+       knot_db_val_t key = { KEY_VERSION, 2 };
+       knot_db_val_t val = { NULL, 0 };
+       int ret = txn_api(txn)->find(&txn->t, &key, &val, 0);
+       if (ret == 0) {
+               ret = kr_error(EEXIST);
+       } else {
+               /*
+                * Version doesn't not match.
+                * Recreate cache and write version key.
+                */
+               ret = txn_api(txn)->count(&txn->t);
+               if (ret != 0) { /* Non-empty cache, purge it. */
+                       kr_log_info("[cache] purging cache\n");
+                       ret = cache_purge(txn);
+               }
+               /* Either purged or empty. */
+               if (ret == 0) {
+                       ret = txn_api(txn)->insert(&txn->t, &key, &val, 0);
+               }
+       }
+       return ret;
+}
+
+/** @internal Open cache db transaction and check internal data version. */
 static void assert_right_version(struct kr_cache *cache)
 {
        /* Check cache ABI version */
@@ -47,25 +92,11 @@ static void assert_right_version(struct kr_cache *cache)
        if (ret != 0) {
                return; /* N/A, doesn't work. */
        }
-       knot_db_val_t key = { KEY_VERSION, 2 };
-       knot_db_val_t val = { NULL, 0 };
-       ret = txn_api(&txn)->find(&txn.t, &key, &val, 0);
-       if (ret == 0) { /* Version is OK */
-               kr_cache_txn_abort(&txn);
-               return;
-       }
-       /* Recreate cache and write version key */
-       ret = txn_api(&txn)->count(&txn.t);
-       if (ret > 0) { /* Non-empty cache, purge it. */
-               kr_log_info("[cache] purging cache\n");
-               kr_cache_clear(&txn);
-               kr_cache_txn_commit(&txn);
-               ret = kr_cache_txn_begin(cache, &txn, 0);
-       }
-       /* Either purged or empty. */
-       if (ret == 0) {
-               txn_api(&txn)->insert(&txn.t, &key, &val, 0);
+       ret = assert_right_version_txn(&txn);
+       if (ret == 0) { /* Cache recreated, commit. */
                kr_cache_txn_commit(&txn);
+       } else {
+               kr_cache_txn_abort(&txn);
        }
 }
 
@@ -290,9 +321,15 @@ int kr_cache_clear(struct kr_cache_txn *txn)
        if (!txn_is_valid(txn)) {
                return kr_error(EINVAL);
        }
-
-       txn->owner->stats.delete += 1;
-       return txn_api(txn)->clear(&txn->t);
+       int ret = cache_purge(txn);
+       if (ret == 0) {
+               /*
+                * normally must return 0, never EEXIST
+                * (due to cache_purge())
+                */
+               ret = assert_right_version_txn(txn);
+       }
+       return ret;
 }
 
 int kr_cache_peek_rr(struct kr_cache_txn *txn, knot_rrset_t *rr, uint16_t *rank, uint32_t *timestamp)
index 19c621bf733d15b784a0019c73c1eee2aa301232..e5a64eb9281c2878049b11cd3aa9103326ea4a56 100644 (file)
@@ -394,8 +394,11 @@ static void test_clear(void **state)
        struct kr_cache_txn *txn = test_txn_write(state);
        int preempt_ret = kr_cache_clear(txn);
        int commit_ret = kr_cache_txn_commit(txn);
+       int count_ret = txn->owner->api->count(&txn->t);
+
        assert_int_equal(preempt_ret, KNOT_EOK);
        assert_int_equal(commit_ret, KNOT_EOK);
+       assert_int_equal(count_ret, 1); /* Version record */
 }
 
 int main(void)