Add delegdb configuration struct

Instead of having independent APIs to configure various aspects of the
delegdb (i.e. cache size, other settings that may come up later), a
single configuration struct is passed to `dns_delegdb_setconfig()`, which
internally does all the plumbing. To avoid relying on
atomics/synchronization, `dns_delegdb_setconfig()` must be called from
exclusive mode (for now).

The configuration can be retrieved at any time (not necessarily from
exclusive mode) using `dns_delegdb_getconfig()`. This is useful, for
instance, to flush the delegdb without losing its parameters.
This commit is contained in:
Colin Vidal 2026-05-26 18:11:12 +02:00
parent ac342bf652
commit 3610fd2df9
4 changed files with 61 additions and 17 deletions

View file

@ -4334,7 +4334,9 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config,
} else {
dns_delegdb_create(&view->deleg);
}
dns_delegdb_setsize(view->deleg, cache_size_slice);
dns_delegdb_setconfig(
view->deleg,
&(dns_delegdb_config_t){ .dbsize = cache_size_slice });
/*
* The previous view isn't needed anymore.

View file

@ -70,6 +70,8 @@ struct dns_delegdb {
* (After decrementing `owners`.)
*/
isc_refcount_t owners;
dns_delegdb_config_t config;
};
static void
@ -217,7 +219,8 @@ dns_delegdb_create(dns_delegdb_t **delegdbp) {
.mctx = mctx,
.references = ISC_REFCOUNT_INITIALIZER(1),
.nloops = isc_loopmgr_nloops(),
.owners = ISC_REFCOUNT_INITIALIZER(1) };
.owners = ISC_REFCOUNT_INITIALIZER(1),
.config = {} };
dns_qpmulti_create(mctx, &qpmethods, &delegdb->nodes, &delegdb->nodes);
@ -1033,8 +1036,8 @@ dns_delegdb_shutdown(dns_delegdb_t *delegdb) {
}
}
void
dns_delegdb_setsize(dns_delegdb_t *delegdb, size_t size) {
static void
delegdb_setsize(dns_delegdb_t *delegdb, size_t size) {
size_t lowater;
size_t hiwater;
@ -1058,3 +1061,20 @@ dns_delegdb_setsize(dns_delegdb_t *delegdb, size_t size) {
isc_mem_setwater(delegdb->mctx, hiwater, lowater);
}
}
dns_delegdb_config_t
dns_delegdb_getconfig(dns_delegdb_t *delegdb) {
REQUIRE(VALID_DELEGDB(delegdb));
return delegdb->config;
}
void
dns_delegdb_setconfig(dns_delegdb_t *delegdb,
const dns_delegdb_config_t *config) {
REQUIRE(isc_loop_get(isc_tid()) == isc_loop_main());
REQUIRE(VALID_DELEGDB(delegdb));
delegdb->config = *config;
delegdb_setsize(delegdb, delegdb->config.dbsize);
}

View file

@ -18,6 +18,19 @@
#include <dns/types.h>
/*
* `dns_delegdb_config_t` centralizes all configurable parameters
* for the delegation database.
*/
typedef struct {
/*
* Defines the size of the delegation cache. Whenever the effective
* cache size comes close to this size, least recently used cache
* entries are discarded. Value `0` means there is no limitation.
*/
size_t dbsize;
} dns_delegdb_config_t;
/*
* A `dns_deleg_t` object represents either:
*
@ -94,6 +107,21 @@ typedef struct dns_delegdb dns_delegdb_t;
void
dns_delegdb_create(dns_delegdb_t **delegdbp);
/*
* Configure the delegation database. Must be called from the exclusive mode
* only.
*/
void
dns_delegdb_setconfig(dns_delegdb_t *delegdb,
const dns_delegdb_config_t *config);
/*
* Returns a copy of the current configuration of the delegation database. Can
* be called anytime.
*/
dns_delegdb_config_t
dns_delegdb_getconfig(dns_delegdb_t *delegdb);
/*
* Attach a delegation DB from an existing view to another view. Used when
* reloading the server and the delegation DB is reused.
@ -222,12 +250,4 @@ dns_delegset_fromnsrdataset(isc_mem_t *mctx, dns_rdataset_t *rdataset,
isc_result_t
dns_delegdb_delete(dns_delegdb_t *db, const dns_name_t *name, bool tree);
/*
* Defines the size of the delegation cache. Whenever the effective cache
* size comes close to this size, least recently used cache entries are
* discarded. Value `0` means there is no limitation.
*/
void
dns_delegdb_setsize(dns_delegdb_t *db, size_t size);
ISC_REFCOUNT_DECL(dns_delegdb);

View file

@ -659,16 +659,18 @@ cleanuptests(ISC_ATTR_UNUSED void *arg) {
dns_deleg_t *deleg = NULL;
dns_delegset_t *delegset = NULL;
/*
* hiwater is 4375000 = 5000000 - (5000000 >> 3)
* lowater is 3750000 = 5000000 - (5000000 >> 2)
*/
dns_delegdb_config_t config = { .dbsize = 5000000 };
dns_delegdb_create(&db);
assert_non_null(db);
ctx = (cleanup_ctx_t){ .db = db, .now = isc_stdtime_now() };
/*
* hiwater is 4375000 = 5000000 - (5000000 >> 3)
* lowater is 3750000 = 5000000 - (5000000 >> 2)
*/
dns_delegdb_setsize(db, 5000000);
dns_delegdb_setconfig(db, &config);
/*
* A valid record