Merge branch '3239-fix-cleaning-of-adb-buckets' into 'main'

Refactor the dns_adb unit

Closes #3239, #3238, #2615, #2078, #2437, #3312, and #2441

See merge request isc-projects/bind9!7138
This commit is contained in:
Ondřej Surý 2022-11-30 09:35:18 +00:00
commit a9cbf84e0f
7 changed files with 940 additions and 1355 deletions

View file

@ -1,3 +1,10 @@
6030. [bug] Refactor the ADB to use a global LRU queue, store
the ADB names and ADB entries directly in the hash
tables instead of buckets, and properly clean the
ADB names and entries when not in use. [GL #3239]
[GL #3238] [GL #2615] [GL #2078] [GL #2437]
[GL #3312] [GL #2441]
6029. [cleanup] Remove the unused external cache cleaning mechanism
as RBTDB has its own internal cache cleaning
mechanism and we don't support any other database

View file

@ -234,7 +234,6 @@ mv ns2/named_dump.db.test$n ns2/named_dump.db.test$n.a
sed -n '/plain success\/timeout/,/Unassociated entries/p' \
ns2/named_dump.db.test$n.a > sed.out.$n.a
grep 'plain success/timeout' sed.out.$n.a > /dev/null 2>&1 || ret=1
grep 'Unassociated entries' sed.out.$n.a > /dev/null 2>&1 || ret=1
grep 'ns.flushtest.example' sed.out.$n.a > /dev/null 2>&1 || ret=1
$RNDC $RNDCOPTS flushtree flushtest.example || ret=1
dump_cache
@ -242,7 +241,6 @@ mv ns2/named_dump.db.test$n ns2/named_dump.db.test$n.b
sed -n '/plain success\/timeout/,/Unassociated entries/p' \
ns2/named_dump.db.test$n.b > sed.out.$n.b
grep 'plain success/timeout' sed.out.$n.b > /dev/null 2>&1 || ret=1
grep 'Unassociated entries' sed.out.$n.b > /dev/null 2>&1 || ret=1
grep 'ns.flushtest.example' sed.out.$n.b > /dev/null 2>&1 && ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=`expr $status + $ret`

File diff suppressed because it is too large Load diff

View file

@ -66,6 +66,9 @@
*** Imports
***/
/* Define to 1 for detailed reference tracing */
#undef DNS_ADB_TRACE
#include <inttypes.h>
#include <stdbool.h>
@ -92,9 +95,7 @@ ISC_LANG_BEGINDECLS
*** TYPES
***/
typedef struct dns_adbname dns_adbname_t;
typedef struct dns_adbnamebucket dns_adbnamebucket_t;
typedef struct dns_adbentrybucket dns_adbentrybucket_t;
typedef struct dns_adbname dns_adbname_t;
/*!
*\brief
@ -146,11 +147,6 @@ struct dns_adbfind {
* Fetches will start using the closest zone data or use the root servers.
* This is useful for reestablishing glue that has expired.
*
* _GLUEOK:
* _HINTOK:
* Glue or hints are ok. These are used when matching names already
* in the adb, and when dns databases are searched.
*
* _RETURNLAME:
* Return lame servers in a find, so that all addresses are returned.
*
@ -183,16 +179,6 @@ struct dns_adbfind {
* This is useful for reestablishing glue that has expired.
*/
#define DNS_ADBFIND_STARTATZONE 0x00000020
/*%
* Glue or hints are ok. These are used when matching names already
* in the adb, and when dns databases are searched.
*/
#define DNS_ADBFIND_GLUEOK 0x00000040
/*%
* Glue or hints are ok. These are used when matching names already
* in the adb, and when dns databases are searched.
*/
#define DNS_ADBFIND_HINTOK 0x00000080
/*%
* Return lame servers in a find, so that all addresses are returned.
*/
@ -255,8 +241,8 @@ struct dns_adbaddrinfo {
****/
isc_result_t
dns_adb_create(isc_mem_t *mem, dns_view_t *view, isc_taskmgr_t *taskmgr,
dns_adb_t **newadb);
dns_adb_create(isc_mem_t *mem, dns_view_t *view, isc_loopmgr_t *loopmgr,
isc_taskmgr_t *taskmgr, dns_adb_t **newadb);
/*%<
* Create a new ADB.
*
@ -281,32 +267,16 @@ dns_adb_create(isc_mem_t *mem, dns_view_t *view, isc_taskmgr_t *taskmgr,
*\li #ISC_R_NOMEMORY after resource allocation failure.
*/
#define dns_adb_attach(a, ap) \
dns__adb_attach(a, ap, __func__, __FILE__, __LINE__)
void
dns__adb_attach(dns_adb_t *adb, dns_adb_t **adbp, const char *func,
const char *file, unsigned int line);
/*%
* Attach to an 'adb' to 'adbp'.
*
* Requires:
*\li 'adb' to be a valid dns_adb_t, created via dns_adb_create().
*\li 'adbp' to be a valid pointer to a *dns_adb_t which is initialized
* to NULL.
*/
#define dns_adb_detach(ap) dns__adb_detach(ap, __func__, __FILE__, __LINE__)
void
dns__adb_detach(dns_adb_t **adb, const char *func, const char *file,
unsigned int line);
/*%
* Delete the ADB. Sets *ADB to NULL. Cancels any outstanding requests.
*
* Requires:
*
*\li 'adb' be non-NULL and '*adb' be a valid dns_adb_t, created via
* dns_adb_create().
*/
#if DNS_ADB_TRACE
#define dns_adb_ref(ptr) dns_adb__ref(ptr, __func__, __FILE__, __LINE__)
#define dns_adb_unref(ptr) dns_adb__unref(ptr, __func__, __FILE__, __LINE__)
#define dns_adb_attach(ptr, ptrp) \
dns_adb__attach(ptr, ptrp, __func__, __FILE__, __LINE__)
#define dns_adb_detach(ptrp) dns_adb__detach(ptrp, __func__, __FILE__, __LINE__)
ISC_REFCOUNT_TRACE_DECL(dns_adb);
#else
ISC_REFCOUNT_DECL(dns_adb);
#endif
void
dns_adb_shutdown(dns_adb_t *adb);

View file

@ -3444,8 +3444,6 @@ findname(fetchctx_t *fctx, const dns_name_t *name, in_port_t port,
if (dns_name_issubdomain(name, fctx->domain)) {
options |= DNS_ADBFIND_STARTATZONE;
}
options |= DNS_ADBFIND_GLUEOK;
options |= DNS_ADBFIND_HINTOK;
/*
* See what we know about this address.

View file

@ -681,7 +681,7 @@ dns_view_createresolver(dns_view_t *view, isc_loopmgr_t *loopmgr,
isc_mem_create(&mctx);
isc_mem_setname(mctx, "ADB");
result = dns_adb_create(mctx, view, taskmgr, &view->adb);
result = dns_adb_create(mctx, view, loopmgr, taskmgr, &view->adb);
isc_mem_detach(&mctx);
if (result != ISC_R_SUCCESS) {
goto cleanup_resolver;

View file

@ -150,8 +150,8 @@ isc_refcount_decrement(isc_refcount_t *target) {
} while (0)
#define ISC_REFCOUNT_TRACE_DECL(name) \
void name##__ref(name##_t *ptr, const char *func, const char *file, \
unsigned int line); \
name##_t *name##__ref(name##_t *ptr, const char *func, \
const char *file, unsigned int line); \
void name##__unref(name##_t *ptr, const char *func, const char *file, \
unsigned int line); \
void name##__attach(name##_t *ptr, name##_t **ptrp, const char *func, \
@ -160,31 +160,37 @@ isc_refcount_decrement(isc_refcount_t *target) {
const char *file, unsigned int line)
#define ISC_REFCOUNT_TRACE_IMPL(name, destroy) \
void name##__ref(name##_t *ptr, const char *func, const char *file, \
unsigned int line) { \
uint_fast32_t refs; \
name##_t *name##__ref(name##_t *ptr, const char *func, \
const char *file, unsigned int line) { \
REQUIRE(ptr != NULL); \
refs = isc_refcount_increment(&ptr->references); \
uint_fast32_t refs = \
isc_refcount_increment(&ptr->references) + 1; \
fprintf(stderr, \
"%s:%s:%s:%u:%p->references = %" PRIuFAST32 "\n", \
__func__, func, file, line, ptr, refs + 1); \
__func__, func, file, line, ptr, refs); \
return (ptr); \
} \
\
void name##__unref(name##_t *ptr, const char *func, const char *file, \
unsigned int line) { \
uint_fast32_t refs; \
REQUIRE(ptr != NULL); \
if ((refs = isc_refcount_decrement(&ptr->references)) == 1) { \
uint_fast32_t refs = \
isc_refcount_decrement(&ptr->references) - 1; \
if (refs == 0) { \
destroy(ptr); \
} \
fprintf(stderr, \
"%s:%s:%s:%u:%p->references = %" PRIuFAST32 "\n", \
__func__, func, file, line, ptr, refs - 1); \
__func__, func, file, line, ptr, refs); \
} \
void name##__attach(name##_t *ptr, name##_t **ptrp, const char *func, \
const char *file, unsigned int line) { \
REQUIRE(ptrp != NULL && *ptrp == NULL); \
name##__ref(ptr, func, file, line); \
uint_fast32_t refs = \
isc_refcount_increment(&ptr->references) + 1; \
fprintf(stderr, \
"%s:%s:%s:%u:%p->references = %" PRIuFAST32 "\n", \
__func__, func, file, line, ptr, refs); \
*ptrp = ptr; \
} \
\
@ -193,19 +199,27 @@ isc_refcount_decrement(isc_refcount_t *target) {
REQUIRE(ptrp != NULL && *ptrp != NULL); \
name##_t *ptr = *ptrp; \
*ptrp = NULL; \
name##__unref(ptr, func, file, line); \
uint_fast32_t refs = \
isc_refcount_decrement(&ptr->references) - 1; \
if (refs == 0) { \
destroy(ptr); \
} \
fprintf(stderr, \
"%s:%s:%s:%u:%p->references = %" PRIuFAST32 "\n", \
__func__, func, file, line, ptr, refs); \
}
#define ISC_REFCOUNT_DECL(name) \
void name##_ref(name##_t *ptr); \
void name##_unref(name##_t *ptr); \
void name##_attach(name##_t *ptr, name##_t **ptrp); \
void name##_detach(name##_t **ptrp)
#define ISC_REFCOUNT_DECL(name) \
name##_t *name##_ref(name##_t *ptr); \
void name##_unref(name##_t *ptr); \
void name##_attach(name##_t *ptr, name##_t **ptrp); \
void name##_detach(name##_t **ptrp)
#define ISC_REFCOUNT_IMPL(name, destroy) \
void name##_ref(name##_t *ptr) { \
name##_t *name##_ref(name##_t *ptr) { \
REQUIRE(ptr != NULL); \
isc_refcount_increment(&ptr->references); \
return (ptr); \
} \
\
void name##_unref(name##_t *ptr) { \