diff --git a/lib/layer/itercache.c b/lib/layer/itercache.c index 30ef1e06f585886474f04bd1f88e72d8a353c3ad..78365874cc96a548428e4b5994a0a2cdf3b5e140 100644 --- a/lib/layer/itercache.c +++ b/lib/layer/itercache.c @@ -82,7 +82,11 @@ static int read_cache(knot_layer_t *ctx, knot_pkt_t *pkt) return ctx->state; } - namedb_txn_t *txn = kr_rplan_txn_acquire(rplan, NAMEDB_RDONLY); + namedb_txn_t txn; + struct kr_cache *cache = req->ctx->cache; + if (kr_cache_txn_begin(cache, &txn, NAMEDB_RDONLY) != 0) { + return KNOT_STATE_CONSUME; + } uint32_t timestamp = cur->timestamp.tv_sec; knot_rrset_t cache_rr; knot_rrset_init(&cache_rr, cur->sname, cur->stype, cur->sclass); @@ -94,29 +98,33 @@ static int read_cache(knot_layer_t *ctx, knot_pkt_t *pkt) } /* Try to find expected record first. */ - int state = read_cache_rr(txn, &cache_rr, timestamp, callback, req); + int state = read_cache_rr(&txn, &cache_rr, timestamp, callback, req); if (state == KNOT_STATE_DONE) { DEBUG_MSG("=> satisfied from cache\n"); cur->flags |= QUERY_RESOLVED; + kr_cache_txn_abort(&txn); return state; } /* Check if CNAME chain exists. */ cache_rr.type = KNOT_RRTYPE_CNAME; - state = read_cache_rr(txn, &cache_rr, timestamp, callback, req); + state = read_cache_rr(&txn, &cache_rr, timestamp, callback, req); if (state != KNOT_STATE_NOOP) { if (cur->stype != KNOT_RRTYPE_CNAME) { const knot_dname_t *cname = knot_cname_name(&cache_rr.rrs); if (kr_rplan_push(rplan, cur->parent, cname, cur->sclass, cur->stype) == NULL) { + kr_cache_txn_abort(&txn); return KNOT_STATE_FAIL; } } cur->flags |= QUERY_RESOLVED; + kr_cache_txn_abort(&txn); return KNOT_STATE_DONE; } /* Not resolved. */ + kr_cache_txn_abort(&txn); return KNOT_STATE_CONSUME; } @@ -239,32 +247,35 @@ static int write_cache(knot_layer_t *ctx, knot_pkt_t *pkt) return ctx->state; } - /* Open write transaction */ - mm_ctx_t *pool = rplan->pool; - uint32_t timestamp = query->timestamp.tv_sec; - namedb_txn_t *txn = kr_rplan_txn_acquire(rplan, 0); - if (txn == NULL) { - return ctx->state; /* Couldn't acquire cache, ignore. */ - } - /* Cache only positive answers. */ /** \todo Negative answers cache support */ if (knot_wire_get_rcode(pkt->wire) != KNOT_RCODE_NOERROR) { return ctx->state; } + /* Open write transaction */ + mm_ctx_t *pool = rplan->pool; + uint32_t timestamp = query->timestamp.tv_sec; + struct kr_cache *cache = req->ctx->cache; + namedb_txn_t txn; + if (kr_cache_txn_begin(cache, &txn, 0) != 0) { + return ctx->state; /* Couldn't acquire cache, ignore. */ + } + /* If authoritative, cache answer for current query. */ int ret = KNOT_EOK; if (knot_wire_get_aa(pkt->wire)) { - ret = write_cache_answer(pkt, txn, pool, timestamp); + ret = write_cache_answer(pkt, &txn, pool, timestamp); } if (ret == KNOT_EOK) { - ret = write_cache_authority(pkt, txn, pool, timestamp); + ret = write_cache_authority(pkt, &txn, pool, timestamp); } /* Cache full, do what we must. */ if (ret == KNOT_ESPACE) { - kr_cache_clear(txn); + kr_cache_clear(&txn); + } else { + kr_cache_txn_commit(&txn); } return ctx->state; diff --git a/lib/resolve.c b/lib/resolve.c index 5c4c70e88b638a7690f7516362c13c3b2d770384..faefb2092fdc0523f39dd503278650c4d02d357c 100644 --- a/lib/resolve.c +++ b/lib/resolve.c @@ -335,14 +335,12 @@ int kr_resolve_produce(struct kr_request *request, struct sockaddr **dst, int *t int kr_resolve_finish(struct kr_request *request, int state) { +#ifndef NDEBUG struct kr_rplan *rplan = &request->rplan; DEBUG_MSG("finished: %d, mempool: %zu B\n", state, (size_t) mp_total_size(request->pool.ctx)); - - /* Resolution success, commit cache transaction. */ - if (state == KNOT_STATE_DONE) { - kr_rplan_txn_commit(rplan); - } else { - /* Error during procesing, internal failure */ +#endif + /* Error during procesing, internal failure */ + if (state != KNOT_STATE_DONE) { knot_pkt_t *answer = request->answer; if (knot_wire_get_rcode(answer->wire) == KNOT_RCODE_NOERROR) { knot_wire_set_rcode(answer->wire, KNOT_RCODE_SERVFAIL); diff --git a/lib/rplan.c b/lib/rplan.c index 7438b66f1ec1933281ef07b8b57daa06647affb8..c02e61a4f8ffb05ca21501cd9a105fd0d2ffcdc7 100644 --- a/lib/rplan.c +++ b/lib/rplan.c @@ -84,11 +84,6 @@ void kr_rplan_deinit(struct kr_rplan *rplan) WALK_LIST_DELSAFE(qry, next, rplan->resolved) { query_free(rplan->pool, qry); } - - /* Abort any pending transactions. */ - if (rplan->txn.db != NULL) { - kr_cache_txn_abort(&rplan->txn); - } } bool kr_rplan_empty(struct kr_rplan *rplan) @@ -119,9 +114,14 @@ struct kr_query *kr_rplan_push(struct kr_rplan *rplan, struct kr_query *parent, add_tail(&rplan->pending, &qry->node); /* Find closest zone cut for this query. */ - namedb_txn_t *txn = kr_rplan_txn_acquire(rplan, NAMEDB_RDONLY); + namedb_txn_t txn; kr_zonecut_init(&qry->zone_cut, name, rplan->pool); - kr_zonecut_find_cached(&qry->zone_cut, txn, qry->timestamp.tv_sec); + if (kr_cache_txn_begin(rplan->context->cache, &txn, NAMEDB_RDONLY) != 0) { + kr_zonecut_set_sbelt(&qry->zone_cut); + } else { + kr_zonecut_find_cached(&qry->zone_cut, &txn, qry->timestamp.tv_sec); + kr_cache_txn_abort(&txn); + } #ifndef NDEBUG char name_str[KNOT_DNAME_MAXLEN], type_str[16]; @@ -152,53 +152,6 @@ struct kr_query *kr_rplan_current(struct kr_rplan *rplan) return TAIL(rplan->pending); } -namedb_txn_t *kr_rplan_txn_acquire(struct kr_rplan *rplan, unsigned flags) -{ - if (rplan == NULL || rplan->context == NULL) { - return NULL; - } - - /* Discard current transaction if RDONLY, but WR is requested. */ - if ((rplan->txn_flags & NAMEDB_RDONLY) && !(flags & NAMEDB_RDONLY)) { - kr_cache_txn_abort(&rplan->txn); - rplan->txn.db = NULL; - } - - /* Reuse transaction if exists. */ - if (rplan->txn.db != NULL) { - return &rplan->txn; - } - - /* Transaction doesn't exist, start new one. */ - int ret = kr_cache_txn_begin(rplan->context->cache, &rplan->txn, flags); - if (ret != KNOT_EOK) { - rplan->txn.db = NULL; - return NULL; - } - - rplan->txn_flags = flags; - return &rplan->txn; -} - -int kr_rplan_txn_commit(struct kr_rplan *rplan) -{ - if (rplan == NULL || rplan->context == NULL) { - return KNOT_EINVAL; - } - - /* Just discard RDONLY transactions. */ - int ret = KNOT_EOK; - if (rplan->txn_flags & NAMEDB_RDONLY) { - kr_cache_txn_abort(&rplan->txn); - } else { - /* Commit write transactions. */ - ret = kr_cache_txn_commit(&rplan->txn); - } - - rplan->txn.db = NULL; - return ret; -} - bool kr_rplan_satisfies(struct kr_query *closure, const knot_dname_t *name, uint16_t cls, uint16_t type) { while (closure != NULL) { diff --git a/lib/rplan.h b/lib/rplan.h index 07aa951fa1d74eca53268afc2643898e984dbd49..ef5786c31c8a7b387f4458b909f704dfc70d06a2 100644 --- a/lib/rplan.h +++ b/lib/rplan.h @@ -58,8 +58,6 @@ struct kr_query { * It also keeps a notion of current zone cut. */ struct kr_rplan { - unsigned txn_flags; /**< Current transaction flags. */ - namedb_txn_t txn; /**< Current transaction (may be r/o). */ list_t pending; /**< List of pending queries. */ list_t resolved; /**< List of resolved queries. */ struct kr_context *context; /**< Parent resolution context. */ @@ -87,23 +85,6 @@ void kr_rplan_deinit(struct kr_rplan *rplan); */ bool kr_rplan_empty(struct kr_rplan *rplan); -/** - * Acquire rplan transaction (read or write only). - * @note The transaction is shared during the whole resolution, read only transactions - * may be promoted to write-enabled transactions if requested, but never demoted. - * @param rplan plan instance - * @param flags transaction flags - * @return transaction instance or NULL - */ -namedb_txn_t *kr_rplan_txn_acquire(struct kr_rplan *rplan, unsigned flags); - -/** - * Commit any existing transaction, read-only transactions may be just aborted. - * @param rplan plan instance - * @return KNOT_E* - */ -int kr_rplan_txn_commit(struct kr_rplan *rplan); - /** * Push a query to the top of the resolution plan. * @note This means that this query takes precedence before all pending queries. diff --git a/tests/test_rplan.c b/tests/test_rplan.c index f25bc9ba1c66912f50c2faeee53bfeb95e05925c..8a8d5d6496eea186f13bab234b7c28bb4e7791f2 100644 --- a/tests/test_rplan.c +++ b/tests/test_rplan.c @@ -27,8 +27,6 @@ static void test_rplan_params(void **state) assert_int_equal(kr_rplan_pop(NULL, NULL), KNOT_EINVAL); assert_true(kr_rplan_empty(NULL)); assert_null(kr_rplan_current(NULL)); - assert_null(kr_rplan_txn_acquire(NULL, 0)); - assert_int_equal(kr_rplan_txn_commit(NULL), KNOT_EINVAL); kr_rplan_deinit(NULL); /* NULL mandatory parameters */ @@ -39,8 +37,6 @@ static void test_rplan_params(void **state) assert_int_equal(kr_rplan_pop(&rplan, NULL), KNOT_EINVAL); assert_true(kr_rplan_empty(&rplan)); assert_null(kr_rplan_current(&rplan)); - assert_null(kr_rplan_txn_acquire(&rplan, 0)); - assert_int_equal(kr_rplan_txn_commit(&rplan), KNOT_EINVAL); kr_rplan_deinit(&rplan); } diff --git a/tests/testdata/iter_cname_qnamecopy.rpl b/tests/testdata/iter_cname_qnamecopy.rpl index 12019816ac16d2e2095b586cd9e3e40c2bf620bb..9539d34ced4b1ea6c7e3a368264cd57a77005e7e 100644 --- a/tests/testdata/iter_cname_qnamecopy.rpl +++ b/tests/testdata/iter_cname_qnamecopy.rpl @@ -171,7 +171,7 @@ www.example.com. IN A SECTION ANSWER www.example.com. IN CNAME www.next.com. SECTION AUTHORITY -next.com. IN SOA next.com. next.com. 2007090400 28800 7200 604800 18000 +;next.com. IN SOA next.com. next.com. 2007090400 28800 7200 604800 18000 SECTION ADDITIONAL ENTRY_END