2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-09-04 16:45:24 +00:00

[master] "rndc flushtree -all <name>"

3606.	[func]		"rndc flushtree -all" flushes matching
			records in the ADB and bad cache as well as
			the DNS cache.  (Without the "-all" option,
			flushtree will still only flush records from
			the DNS cache.) [RT #33970]
This commit is contained in:
Evan Hunt
2013-06-26 14:59:32 -07:00
parent c5a53e9ab5
commit 9fa5a723e1
11 changed files with 143 additions and 21 deletions

View File

@@ -1,3 +1,9 @@
3606. [func] "rndc flushtree -all" flushes matching
records in the ADB and bad cache as well as
the DNS cache. (Without the "-all" option,
flushtree will still only flush records from
the DNS cache.) [RT #33970]
3605. [port] win32: Addressed several compatibility issues 3605. [port] win32: Addressed several compatibility issues
with newer versions of Visual Studio. [RT #33916] with newer versions of Visual Studio. [RT #33916]

View File

@@ -7614,22 +7614,27 @@ ns_server_flushcache(ns_server_t *server, char *args) {
isc_result_t isc_result_t
ns_server_flushnode(ns_server_t *server, char *args, isc_boolean_t tree) { ns_server_flushnode(ns_server_t *server, char *args, isc_boolean_t tree) {
char *ptr, *target, *viewname; char *target, *viewname;
dns_view_t *view; dns_view_t *view;
isc_boolean_t flushed; isc_boolean_t flushed;
isc_boolean_t found; isc_boolean_t found, all = ISC_FALSE;
isc_result_t result; isc_result_t result;
isc_buffer_t b; isc_buffer_t b;
dns_fixedname_t fixed; dns_fixedname_t fixed;
dns_name_t *name; dns_name_t *name;
/* Skip the command name. */ /* Skip the command name. */
ptr = next_token(&args, " \t"); target = next_token(&args, " \t");
if (ptr == NULL) if (target == NULL)
return (ISC_R_UNEXPECTEDEND); return (ISC_R_UNEXPECTEDEND);
/* Find the domain name to flush. */
target = next_token(&args, " \t"); target = next_token(&args, " \t");
if (strcmp(target, "-all") == 0) {
all = ISC_TRUE;
target = next_token(&args, " \t");
}
/* Find the domain name to flush. */
if (target == NULL) if (target == NULL)
return (ISC_R_UNEXPECTEDEND); return (ISC_R_UNEXPECTEDEND);
@@ -7660,7 +7665,7 @@ ns_server_flushnode(ns_server_t *server, char *args, isc_boolean_t tree) {
* if some of the views share a single cache. But since the * if some of the views share a single cache. But since the
* operation is lightweight we prefer simplicity here. * operation is lightweight we prefer simplicity here.
*/ */
result = dns_view_flushnode(view, name, tree); result = dns_view_flushnode(view, name, tree, all);
if (result != ISC_R_SUCCESS) { if (result != ISC_R_SUCCESS) {
flushed = ISC_FALSE; flushed = ISC_FALSE;
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,

View File

@@ -518,13 +518,15 @@
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><userinput>flushtree</userinput> <replaceable>name</replaceable> <optional><replaceable>view</replaceable></optional> </term> <term><userinput>flushtree</userinput> <optional>-all</optional> <replaceable>name</replaceable> <optional><replaceable>view</replaceable></optional> </term>
<listitem> <listitem>
<para> <para>
Flushes the given name, and all of its subdomains, Flushes the given name, and all of its subdomains,
from the server's DNS cache. Note that this does from the server's DNS cache. By default, this does
<emphasis>not</emphasis> affect he server's address <emphasis>not</emphasis> affect the server's address
database or bad-server cache. database or bad-server cache. To eliminate matching
names from those databases as well, use
the <option>-all</option> option.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>

View File

@@ -65,7 +65,7 @@ EOF
dump_cache () { dump_cache () {
rm -f ns2/named_dump.db rm -f ns2/named_dump.db
$RNDC $RNDCOPTS dumpdb -cache $RNDC $RNDCOPTS dumpdb -cache _default
sleep 1 sleep 1
} }
@@ -185,5 +185,16 @@ nrecords=`grep flushtest.example ns2/named_dump.db | grep -v '^;' | grep -Ew '(T
if [ $ret != 0 ]; then echo "I:failed"; fi if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret` status=`expr $status + $ret`
echo "I:check flushtree -all clears adb correctly"
ret=0
load_cache
dump_cache
awk '/Address database/ {getline; getline; if ($2 == "ns.flushtest.example") exit(0); exit(1); }' ns2/named_dump.db || ret=1
$RNDC $RNDCOPTS flushtree -all flushtest.example || ret=1
dump_cache
awk '/Address database/ {getline; getline; if ($2 == "ns.flushtest.example") exit(1); exit(0); }' ns2/named_dump.db || ret=1
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
echo "I:exit status: $status" echo "I:exit status: $status"
exit $status exit $status

View File

@@ -4362,7 +4362,8 @@ dns_adb_flushname(dns_adb_t *adb, dns_name_t *name) {
dns_adbname_t *nextname; dns_adbname_t *nextname;
int bucket; int bucket;
INSIST(DNS_ADB_VALID(adb)); REQUIRE(DNS_ADB_VALID(adb));
REQUIRE(name != NULL);
LOCK(&adb->lock); LOCK(&adb->lock);
bucket = dns_name_hash(name, ISC_FALSE) % adb->nnames; bucket = dns_name_hash(name, ISC_FALSE) % adb->nnames;
@@ -4382,6 +4383,35 @@ dns_adb_flushname(dns_adb_t *adb, dns_name_t *name) {
UNLOCK(&adb->lock); UNLOCK(&adb->lock);
} }
void
dns_adb_flushnames(dns_adb_t *adb, dns_name_t *name) {
dns_adbname_t *adbname, *nextname;
unsigned int i;
REQUIRE(DNS_ADB_VALID(adb));
REQUIRE(name != NULL);
LOCK(&adb->lock);
for (i = 0; i < adb->nnames; i++) {
LOCK(&adb->namelocks[i]);
adbname = ISC_LIST_HEAD(adb->names[i]);
while (adbname != NULL) {
isc_boolean_t ret;
nextname = ISC_LIST_NEXT(adbname, plink);
if (!NAME_DEAD(adbname) &&
dns_name_issubdomain(&adbname->name, name))
{
ret = kill_name(&adbname,
DNS_EVENT_ADBCANCELED);
RUNTIME_CHECK(ret == ISC_FALSE);
}
adbname = nextname;
}
UNLOCK(&adb->namelocks[i]);
}
UNLOCK(&adb->lock);
}
static void static void
water(void *arg, int mark) { water(void *arg, int mark) {
/* /*

View File

@@ -718,6 +718,17 @@ dns_adb_flushname(dns_adb_t *adb, dns_name_t *name);
*\li 'name' is valid. *\li 'name' is valid.
*/ */
void
dns_adb_flushnames(dns_adb_t *adb, dns_name_t *name);
/*%<
* Flush 'name' and all subdomains from the adb cache.
*
* Requires:
*\li 'adb' is valid.
*\li 'name' is valid.
*/
ISC_LANG_ENDDECLS ISC_LANG_ENDDECLS
#endif /* DNS_ADB_H */ #endif /* DNS_ADB_H */

View File

@@ -589,6 +589,16 @@ dns_resolver_flushbadcache(dns_resolver_t *resolver, dns_name_t *name);
* \li resolver to be valid. * \li resolver to be valid.
*/ */
void
dns_resolver_flushbadnames(dns_resolver_t *resolver, dns_name_t *name);
/*%<
* Flush the bad cache of all entries at or below 'name'.
*
* Requires:
* \li resolver to be valid.
* \li name != NULL
*/
void void
dns_resolver_printbadcache(dns_resolver_t *resolver, FILE *fp); dns_resolver_printbadcache(dns_resolver_t *resolver, FILE *fp);
/*% /*%

View File

@@ -875,15 +875,18 @@ dns_view_flushcache2(dns_view_t *view, isc_boolean_t fixuponly);
*/ */
isc_result_t isc_result_t
dns_view_flushnode(dns_view_t *view, dns_name_t *name, isc_boolean_t tree); dns_view_flushnode(dns_view_t *view, dns_name_t *name,
isc_boolean_t cachetree, isc_boolean_t all);
/*%< /*%<
* Flush the given name from the view's cache (and optionally ADB/badcache). * Flush the given name from the view's cache (and optionally ADB/badcache).
* *
* If 'tree' is true, flush 'name' and all names below it * If 'cachetree' or 'all' is true, flush 'name' and all names below it
* from the cache, but do not flush ADB. * from the cache.
* If 'all' is true, flush 'name' and all names below it from the ADB
* and badcache.
* *
* If 'tree' is false, flush 'name' frmo both the cache and ADB, * If 'cachetree' and 'all' are false, flush 'name' from both the
* but do not touch any other nodes. * cache and ADB, but do not touch any other nodes.
* *
* Requires: * Requires:
*\li 'view' is valid. *\li 'view' is valid.

View File

@@ -8747,6 +8747,40 @@ dns_resolver_flushbadcache(dns_resolver_t *resolver, dns_name_t *name) {
} }
void
dns_resolver_flushbadnames(dns_resolver_t *resolver, dns_name_t *name) {
dns_badcache_t *bad, *prev, *next;
unsigned int i;
REQUIRE(VALID_RESOLVER(resolver));
REQUIRE(name != NULL);
LOCK(&resolver->lock);
if (resolver->badcache == NULL)
goto unlock;
for (i = 0; i < resolver->badhash; i++) {
prev = NULL;
for (bad = resolver->badcache[i]; bad != NULL; bad = next) {
next = bad->next;
if (dns_name_issubdomain(&bad->name, name)) {
if (prev == NULL)
resolver->badcache[i] = bad->next;
else
prev->next = bad->next;
isc_mem_put(resolver->mctx, bad, sizeof(*bad) +
bad->name.length);
resolver->badcount--;
} else
prev = bad;
}
}
unlock:
UNLOCK(&resolver->lock);
}
static void static void
resizehash(dns_resolver_t *resolver, isc_time_t *now, isc_boolean_t grow) { resizehash(dns_resolver_t *resolver, isc_time_t *now, isc_boolean_t grow) {
unsigned int newsize; unsigned int newsize;

View File

@@ -1556,15 +1556,22 @@ dns_view_flushcache2(dns_view_t *view, isc_boolean_t fixuponly) {
isc_result_t isc_result_t
dns_view_flushname(dns_view_t *view, dns_name_t *name) { dns_view_flushname(dns_view_t *view, dns_name_t *name) {
return (dns_view_flushnode(view, name, ISC_FALSE)); return (dns_view_flushnode(view, name, ISC_FALSE, ISC_FALSE));
} }
isc_result_t isc_result_t
dns_view_flushnode(dns_view_t *view, dns_name_t *name, isc_boolean_t tree) { dns_view_flushnode(dns_view_t *view, dns_name_t *name,
isc_boolean_t cachetree, isc_boolean_t all)
{
REQUIRE(DNS_VIEW_VALID(view)); REQUIRE(DNS_VIEW_VALID(view));
if (!tree) { if (all) {
if (view->adb != NULL)
dns_adb_flushnames(view->adb, name);
if (view->resolver != NULL)
dns_resolver_flushbadnames(view->resolver, name);
} else if (!cachetree) {
if (view->adb != NULL) if (view->adb != NULL)
dns_adb_flushname(view->adb, name); dns_adb_flushname(view->adb, name);
if (view->cache == NULL) if (view->cache == NULL)
@@ -1572,7 +1579,8 @@ dns_view_flushnode(dns_view_t *view, dns_name_t *name, isc_boolean_t tree) {
if (view->resolver != NULL) if (view->resolver != NULL)
dns_resolver_flushbadcache(view->resolver, name); dns_resolver_flushbadcache(view->resolver, name);
} }
return (dns_cache_flushnode(view->cache, name, tree));
return (dns_cache_flushnode(view->cache, name, cachetree || all));
} }
isc_result_t isc_result_t

View File

@@ -43,6 +43,8 @@ dns_adb_dump
dns_adb_dumpfind dns_adb_dumpfind
dns_adb_findaddrinfo dns_adb_findaddrinfo
dns_adb_flush dns_adb_flush
dns_adb_flushmatch
dns_adb_flushname
dns_adb_freeaddrinfo dns_adb_freeaddrinfo
dns_adb_marklame dns_adb_marklame
dns_adb_setadbsize dns_adb_setadbsize