From: Colin Vidal Date: Wed, 27 May 2026 08:50:42 +0000 (+0200) Subject: Add system test for delegdb size preservation across `rndc flush` X-Git-Tag: v9.21.23~24^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ad92081c5b53f3fec5f539ea37b5f64498efa6c2;p=thirdparty%2Fbind9.git Add system test for delegdb size preservation across `rndc flush` Test that flushing the delegdb via `rndc flush` preserves its configured size limit. The test checks delegdb watermarks after `named` startup, flushes caches, and verifies that the delegdb watermarks are correctly restored afterwards. To distinguish between the previous `delegdb` memory contexts and the new ones, we need to know exactly when the previous `delegdb` memory contexts are removed (this is not immediate, since those are removed during RCU reclamation phase). A trace is therefore added when a memory context is destroyed, if `ISC_MEM_DEBUGTRACE` is set. --- diff --git a/bin/tests/system/delegdb_flush/ns1/named.args b/bin/tests/system/delegdb_flush/ns1/named.args new file mode 100644 index 00000000000..6a68cc8857c --- /dev/null +++ b/bin/tests/system/delegdb_flush/ns1/named.args @@ -0,0 +1 @@ +-m trace -c named.conf -d 99 -D delegdb_flush-ns1 -g diff --git a/bin/tests/system/delegdb_flush/ns1/named.conf.j2 b/bin/tests/system/delegdb_flush/ns1/named.conf.j2 new file mode 100644 index 00000000000..e9204885fcc --- /dev/null +++ b/bin/tests/system/delegdb_flush/ns1/named.conf.j2 @@ -0,0 +1,19 @@ +options { + port @PORT@; + pid-file "named.pid"; + listen-on { 10.53.0.1; }; + max-cache-size 8000; +}; + +statistics-channels { + inet 10.53.0.1 port @EXTRAPORT1@; +}; + +key rndc_key { + secret "1234abcd8765"; + algorithm @DEFAULT_HMAC@; +}; + +controls { + inet 10.53.0.1 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; +}; diff --git a/bin/tests/system/delegdb_flush/tests_delegdb_flush.py b/bin/tests/system/delegdb_flush/tests_delegdb_flush.py new file mode 100644 index 00000000000..dd72971fc29 --- /dev/null +++ b/bin/tests/system/delegdb_flush/tests_delegdb_flush.py @@ -0,0 +1,65 @@ +# Copyright (C) Internet Systems Consortium, Inc. ("ISC") +# +# SPDX-License-Identifier: MPL-2.0 +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, you can obtain one at https://mozilla.org/MPL/2.0/. +# +# See the COPYRIGHT file distributed with this work for additional +# information regarding copyright ownership. + +import os + +import requests + +import isctest.mark + +pytestmark = [isctest.mark.with_json_c, isctest.mark.with_developer] + + +def get_delegdb_watermarks(ip, port): + watermarks = [] + r = requests.get(f"http://{ip}:{port}/json/v1/mem", timeout=600) + assert r.status_code == 200 + mem = r.json()["memory"] + for c in mem["contexts"]: + if c["name"] == "dns_delegdb": + watermarks.append((c["id"], c["lowater"], c["hiwater"])) + return watermarks + + +def check_watermarks(watermarks1, watermarks2): + if watermarks2 is not None: + assert len(watermarks1) == len(watermarks2) + for i, (id1, lowater1, hiwater1) in enumerate(watermarks1): + assert lowater1 > 0 + assert hiwater1 > 0 + if watermarks2 is not None: + id2, lowater2, hiwater2 = watermarks2[i] + assert id1 != id2 + assert lowater1 == lowater2 + assert hiwater1 == hiwater2 + + +def test_delegdb_flush(ns1): + statsport = os.getenv("EXTRAPORT1") + + watermarks1 = get_delegdb_watermarks(ns1.ip, statsport) + check_watermarks(watermarks1, None) + + with ns1.watch_log_from_here() as watcher: + ns1.rndc("flush") + watcher.wait_for_sequence( + ["flushing caches in all views succeeded", "loop exclusive mode: ended"] + ) + + # The previous delegdb contexts can still be hanging around for a little + # bit, until RCU reclamation run and it actually gets detached/freed. + for watermarks in watermarks1: + id1, _, _ = watermarks + with ns1.watch_log_from_start() as watcher: + watcher.wait_for_line(f"destroyed mctx {id1}") + + watermarks2 = get_delegdb_watermarks(ns1.ip, statsport) + check_watermarks(watermarks1, watermarks2) diff --git a/lib/isc/mem.c b/lib/isc/mem.c index 70c8b6b86e2..fd594d8ebe4 100644 --- a/lib/isc/mem.c +++ b/lib/isc/mem.c @@ -700,6 +700,12 @@ mem_destroy(isc_mem_t *ctx) { isc_mutex_destroy(&ctx->lock); +#if ISC_MEM_TRACKLINES + if ((mem_debugging & ISC_MEM_DEBUGTRACE) != 0) { + fprintf(stderr, "destroyed mctx %p\n", ctx); + } +#endif /* ISC_MEM_TRACKLINES */ + sdallocx(ctx, sizeof(*ctx), ctx->jemalloc_flags); }