From: Evan Hunt Date: Fri, 14 Aug 2026 00:17:44 +0000 (-0700) Subject: "rndc flushtree ." failed to flush the cache X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=231db283546fa6b4d82f0fcb13e0696988520e64;p=thirdparty%2Fbind9.git "rndc flushtree ." failed to flush the cache `rndc flushtree` flushes cache data below a specified name. If the name specified is the DNS root, that should fully empty the cache, the same as `rndc flush`. However, there was a bug causing that command to have no effect on the cache at all; this has been fixed. --- diff --git a/bin/named/server.c b/bin/named/server.c index 89a30b07fd2..e9e018a97ee 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -11476,7 +11476,11 @@ flushnode_cache(dns_view_t *view, const dns_name_t *name, const char *target, * if some of the views share a single cache. But since the * operation is lightweight we prefer simplicity here. */ - result = dns_view_flushnode(view, name, tree); + if (dns_name_equal(name, dns_rootname)) { + result = dns_view_flushcache(view, false); + } else { + result = dns_view_flushnode(view, name, tree); + } if (result != ISC_R_SUCCESS) { isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER, ISC_LOG_ERROR, diff --git a/bin/tests/system/cacheclean/tests.sh b/bin/tests/system/cacheclean/tests.sh index fe71c2f8627..cb0e0e822e3 100755 --- a/bin/tests/system/cacheclean/tests.sh +++ b/bin/tests/system/cacheclean/tests.sh @@ -278,5 +278,21 @@ grep EXPIRE: dig.out.expire >/dev/null || ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi status=$((status + ret)) +n=$((n + 1)) +echo_i "check 'flushtree .' is equivalent to 'flush' ($n)" +ret=0 +clear_cache +dump_cache +grep -v DATE ns2/named_dump.db.test$n >ns2/named_dump.db.test$n.a +load_cache +dump_cache +grep -v DATE ns2/named_dump.db.test$n >ns2/named_dump.db.test$n.b +$RNDC $RNDCOPTS flushtree . || ret=1 +dump_cache +grep -v DATE ns2/named_dump.db.test$n >ns2/named_dump.db.test$n.c +cmp -s ns2/named_dump.db.test$n.a ns2/named_dump.db.test$n.b && ret=1 +cmp -s ns2/named_dump.db.test$n.a ns2/named_dump.db.test$n.c || ret=1 +status=$((status + ret)) + echo_i "exit status: $status" [ $status -eq 0 ] || exit 1 diff --git a/lib/dns/cache.c b/lib/dns/cache.c index f0bc00ab85a..6c070dd9c27 100644 --- a/lib/dns/cache.c +++ b/lib/dns/cache.c @@ -418,9 +418,7 @@ dns_cache_flushnode(dns_cache_t *cache, const dns_name_t *name, bool tree) { dns_dbnode_t *node = NULL; dns_db_t *db = NULL; - if (tree && dns_name_equal(name, dns_rootname)) { - return dns_cache_flush(cache); - } + REQUIRE(!(tree && dns_name_equal(name, dns_rootname))); LOCK(&cache->lock); if (cache->db != NULL) { diff --git a/lib/dns/include/dns/cache.h b/lib/dns/include/dns/cache.h index 1ac822ad717..9913a5cb6a2 100644 --- a/lib/dns/include/dns/cache.h +++ b/lib/dns/include/dns/cache.h @@ -200,12 +200,16 @@ dns_cache_flush(dns_cache_t *cache); isc_result_t dns_cache_flushnode(dns_cache_t *cache, const dns_name_t *name, bool tree); /* - * Flush a given name from the cache. If 'tree' is true, then - * also flush all names under 'name'. + * Flush the data for node 'name' from the cache. + * + * If 'tree' is true, then also flush all nodes under 'name'. (Note that + * flushing of a tree only works for names below the root. To flush the + * entire tree, use dns_cache_flush().) * * Requires: *\li 'cache' to be valid. *\li 'name' to be valid. + *\li if 'tree' is true, then 'name' is not root. * * Returns: *\li #ISC_R_SUCCESS diff --git a/lib/dns/include/dns/view.h b/lib/dns/include/dns/view.h index 453ac9d1b06..5ef6377fd5c 100644 --- a/lib/dns/include/dns/view.h +++ b/lib/dns/include/dns/view.h @@ -853,10 +853,9 @@ isc_result_t dns_view_flushcache(dns_view_t *view, bool fixuponly); /*%< * Flush the view's cache (and ADB). If 'fixuponly' is true, it only updates - * the internal reference to the cache DB with omitting actual flush operation. + * the internal reference to the cache DB, omitting actual flush operation. * 'fixuponly' is intended to be used for a view that shares a cache with - * a different view. dns_view_flushcache() is a backward compatible version - * that always sets fixuponly to false. + * a different view. * * Requires: * 'view' is valid.