mirror of
https://github.com/isc-projects/bind9.git
synced 2026-06-09 04:12:08 -04:00
Merge branch '4093-use-rcu-for-view-zonetable' into 'main'
Use RCU for view->zonetable Closes #4093 See merge request isc-projects/bind9!7990
This commit is contained in:
commit
c26d66604b
17 changed files with 281 additions and 84 deletions
3
CHANGES
3
CHANGES
|
|
@ -1,3 +1,6 @@
|
|||
6187. [bug] Address view shutdown INSIST when accessing the
|
||||
zonetable. [GL #4093]
|
||||
|
||||
6186. [bug] Fix a 'clients-per-query' miscalculation bug. When the
|
||||
'stale-answer-enable' options was enabled and the
|
||||
'stale-answer-client-timeout' option was enabled and
|
||||
|
|
|
|||
|
|
@ -2708,7 +2708,7 @@ catz_addmodzone_cb(void *arg) {
|
|||
goto cleanup;
|
||||
}
|
||||
|
||||
result = dns_view_findzone(cz->view, name, &zone);
|
||||
result = dns_view_findzone(cz->view, name, DNS_ZTFIND_EXACT, &zone);
|
||||
|
||||
if (cz->mod) {
|
||||
dns_catz_zone_t *parentcatz;
|
||||
|
|
@ -2834,7 +2834,7 @@ catz_addmodzone_cb(void *arg) {
|
|||
}
|
||||
|
||||
/* Is it there yet? */
|
||||
CHECK(dns_view_findzone(cz->view, name, &zone));
|
||||
CHECK(dns_view_findzone(cz->view, name, DNS_ZTFIND_EXACT, &zone));
|
||||
|
||||
/*
|
||||
* Load the zone from the master file. If this fails, we'll
|
||||
|
|
@ -2856,7 +2856,7 @@ catz_addmodzone_cb(void *arg) {
|
|||
}
|
||||
|
||||
/* Remove the zone from the zone table */
|
||||
dns_zt_unmount(cz->view->zonetable, zone);
|
||||
dns_view_delzone(cz->view, zone);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
|
|
@ -2891,7 +2891,7 @@ catz_delzone_cb(void *arg) {
|
|||
dns_name_format(dns_catz_entry_getname(cz->entry), cname,
|
||||
DNS_NAME_FORMATSIZE);
|
||||
result = dns_view_findzone(cz->view, dns_catz_entry_getname(cz->entry),
|
||||
&zone);
|
||||
DNS_ZTFIND_EXACT, &zone);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
|
||||
NAMED_LOGMODULE_SERVER, ISC_LOG_WARNING,
|
||||
|
|
@ -2925,7 +2925,7 @@ catz_delzone_cb(void *arg) {
|
|||
dns_zone_unload(zone);
|
||||
}
|
||||
|
||||
CHECK(dns_zt_unmount(cz->view->zonetable, zone));
|
||||
CHECK(dns_view_delzone(cz->view, zone));
|
||||
file = dns_zone_getfile(zone);
|
||||
if (file != NULL) {
|
||||
isc_file_remove(file);
|
||||
|
|
@ -3068,7 +3068,8 @@ configure_catz_zone(dns_view_t *view, dns_view_t *pview,
|
|||
isc_ht_iter_current(it, (void **)&entry);
|
||||
name = dns_catz_entry_getname(entry);
|
||||
|
||||
tresult = dns_view_findzone(pview, name, &dnszone);
|
||||
tresult = dns_view_findzone(pview, name,
|
||||
DNS_ZTFIND_EXACT, &dnszone);
|
||||
if (tresult != ISC_R_SUCCESS) {
|
||||
continue;
|
||||
}
|
||||
|
|
@ -5036,7 +5037,8 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config,
|
|||
*/
|
||||
if (view->hints == NULL) {
|
||||
dns_zone_t *rootzone = NULL;
|
||||
(void)dns_view_findzone(view, dns_rootname, &rootzone);
|
||||
(void)dns_view_findzone(view, dns_rootname, DNS_ZTFIND_EXACT,
|
||||
&rootzone);
|
||||
if (rootzone != NULL) {
|
||||
dns_zone_detach(&rootzone);
|
||||
need_hints = false;
|
||||
|
|
@ -5768,7 +5770,8 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config,
|
|||
/*
|
||||
* This zone already exists.
|
||||
*/
|
||||
(void)dns_view_findzone(view, name, &zone);
|
||||
(void)dns_view_findzone(view, name, DNS_ZTFIND_EXACT,
|
||||
&zone);
|
||||
if (zone != NULL) {
|
||||
dns_zone_detach(&zone);
|
||||
continue;
|
||||
|
|
@ -5799,7 +5802,8 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config,
|
|||
}
|
||||
|
||||
if (pview != NULL) {
|
||||
(void)dns_view_findzone(pview, name, &zone);
|
||||
(void)dns_view_findzone(
|
||||
pview, name, DNS_ZTFIND_EXACT, &zone);
|
||||
dns_view_detach(&pview);
|
||||
}
|
||||
|
||||
|
|
@ -5858,7 +5862,8 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config,
|
|||
CHECK(dns_name_fromstring(
|
||||
name, zones[ipv4only_zone].name, 0, NULL));
|
||||
|
||||
(void)dns_view_findzone(view, name, &zone);
|
||||
(void)dns_view_findzone(view, name, DNS_ZTFIND_EXACT,
|
||||
&zone);
|
||||
if (zone != NULL) {
|
||||
dns_zone_detach(&zone);
|
||||
continue;
|
||||
|
|
@ -5888,7 +5893,8 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config,
|
|||
}
|
||||
|
||||
if (pview != NULL) {
|
||||
(void)dns_view_findzone(pview, name, &zone);
|
||||
(void)dns_view_findzone(
|
||||
pview, name, DNS_ZTFIND_EXACT, &zone);
|
||||
dns_view_detach(&pview);
|
||||
}
|
||||
|
||||
|
|
@ -6574,7 +6580,8 @@ configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig,
|
|||
goto cleanup;
|
||||
}
|
||||
|
||||
result = dns_view_findzone(otherview, origin, &zone);
|
||||
result = dns_view_findzone(otherview, origin, DNS_ZTFIND_EXACT,
|
||||
&zone);
|
||||
dns_view_detach(&otherview);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
cfg_obj_log(zconfig, named_g_lctx, ISC_LOG_ERROR,
|
||||
|
|
@ -6693,7 +6700,8 @@ configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig,
|
|||
/*
|
||||
* Check for duplicates in the new zone table.
|
||||
*/
|
||||
result = dns_view_findzone(view, origin, &dupzone);
|
||||
result = dns_view_findzone(view, origin, DNS_ZTFIND_EXACT,
|
||||
&dupzone);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
/*
|
||||
* We already have this zone!
|
||||
|
|
@ -6749,7 +6757,8 @@ configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig,
|
|||
goto cleanup;
|
||||
}
|
||||
if (pview != NULL) {
|
||||
result = dns_view_findzone(pview, origin, &zone);
|
||||
result = dns_view_findzone(pview, origin, DNS_ZTFIND_EXACT,
|
||||
&zone);
|
||||
}
|
||||
if (result != ISC_R_NOTFOUND && result != ISC_R_SUCCESS) {
|
||||
goto cleanup;
|
||||
|
|
@ -7815,7 +7824,7 @@ configure_zone_setviewcommit(isc_result_t result, const cfg_obj_t *zconfig,
|
|||
return;
|
||||
}
|
||||
|
||||
result2 = dns_view_findzone(pview, origin, &zone);
|
||||
result2 = dns_view_findzone(pview, origin, DNS_ZTFIND_EXACT, &zone);
|
||||
if (result2 != ISC_R_SUCCESS) {
|
||||
dns_view_detach(&pview);
|
||||
return;
|
||||
|
|
@ -9740,8 +9749,7 @@ cleanup_viewlist:
|
|||
if (result == ISC_R_SUCCESS && strcmp(view->name, "_bind") != 0)
|
||||
{
|
||||
dns_view_setviewrevert(view);
|
||||
(void)dns_zt_apply(view->zonetable, false, NULL,
|
||||
removed, view);
|
||||
(void)dns_view_apply(view, false, NULL, removed, view);
|
||||
}
|
||||
dns_view_detach(&view);
|
||||
}
|
||||
|
|
@ -10572,7 +10580,8 @@ zone_from_args(named_server_t *server, isc_lex_t *lex, const char *zonetxt,
|
|||
result = ISC_R_NOTFOUND;
|
||||
}
|
||||
} else {
|
||||
result = dns_view_findzone(view, name, zonep);
|
||||
result = dns_view_findzone(view, name, DNS_ZTFIND_EXACT,
|
||||
zonep);
|
||||
}
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
snprintf(problem, sizeof(problem),
|
||||
|
|
@ -11311,8 +11320,8 @@ add_view_tolist(struct dumpcontext *dctx, dns_view_t *view) {
|
|||
ISC_LIST_INIT(vle->zonelist);
|
||||
ISC_LIST_APPEND(dctx->viewlist, vle, link);
|
||||
if (dctx->dumpzones) {
|
||||
result = dns_zt_apply(view->zonetable, true, NULL,
|
||||
add_zone_tolist, dctx);
|
||||
result = dns_view_apply(view, true, NULL, add_zone_tolist,
|
||||
dctx);
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
|
|
@ -12409,8 +12418,8 @@ named_server_sync(named_server_t *server, isc_lex_t *lex, isc_buffer_t **text) {
|
|||
for (view = ISC_LIST_HEAD(server->viewlist); view != NULL;
|
||||
view = ISC_LIST_NEXT(view, link))
|
||||
{
|
||||
result = dns_zt_apply(view->zonetable, false, NULL,
|
||||
synczone, &cleanup);
|
||||
result = dns_view_apply(view, false, NULL, synczone,
|
||||
&cleanup);
|
||||
if (result != ISC_R_SUCCESS && tresult == ISC_R_SUCCESS)
|
||||
{
|
||||
tresult = result;
|
||||
|
|
@ -13439,7 +13448,7 @@ do_addzone(named_server_t *server, ns_cfgctx_t *cfg, dns_view_t *view,
|
|||
result = (view->redirect == NULL) ? ISC_R_NOTFOUND
|
||||
: ISC_R_EXISTS;
|
||||
} else {
|
||||
result = dns_view_findzone(view, name, &zone);
|
||||
result = dns_view_findzone(view, name, DNS_ZTFIND_EXACT, &zone);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
result = ISC_R_EXISTS;
|
||||
}
|
||||
|
|
@ -13503,7 +13512,7 @@ do_addzone(named_server_t *server, ns_cfgctx_t *cfg, dns_view_t *view,
|
|||
}
|
||||
dns_zone_attach(view->redirect, &zone);
|
||||
} else {
|
||||
result = dns_view_findzone(view, name, &zone);
|
||||
result = dns_view_findzone(view, name, DNS_ZTFIND_EXACT, &zone);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
|
||||
NAMED_LOGMODULE_SERVER, ISC_LOG_ERROR,
|
||||
|
|
@ -13551,7 +13560,7 @@ do_addzone(named_server_t *server, ns_cfgctx_t *cfg, dns_view_t *view,
|
|||
}
|
||||
|
||||
/* Remove the zone from the zone table */
|
||||
dns_zt_unmount(view->zonetable, zone);
|
||||
dns_view_delzone(view, zone);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
|
|
@ -13619,7 +13628,7 @@ do_modzone(named_server_t *server, ns_cfgctx_t *cfg, dns_view_t *view,
|
|||
result = ISC_R_NOTFOUND;
|
||||
}
|
||||
} else {
|
||||
result = dns_view_findzone(view, name, &zone);
|
||||
result = dns_view_findzone(view, name, DNS_ZTFIND_EXACT, &zone);
|
||||
}
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup;
|
||||
|
|
@ -13688,7 +13697,7 @@ do_modzone(named_server_t *server, ns_cfgctx_t *cfg, dns_view_t *view,
|
|||
}
|
||||
dns_zone_attach(view->redirect, &zone);
|
||||
} else {
|
||||
CHECK(dns_view_findzone(view, name, &zone));
|
||||
CHECK(dns_view_findzone(view, name, DNS_ZTFIND_EXACT, &zone));
|
||||
}
|
||||
|
||||
#ifndef HAVE_LMDB
|
||||
|
|
@ -13759,7 +13768,7 @@ do_modzone(named_server_t *server, ns_cfgctx_t *cfg, dns_view_t *view,
|
|||
}
|
||||
|
||||
/* Remove the zone from the zone table */
|
||||
dns_zt_unmount(view->zonetable, zone);
|
||||
dns_view_delzone(view, zone);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
|
|
@ -14147,7 +14156,7 @@ named_server_delzone(named_server_t *server, isc_lex_t *lex,
|
|||
if (dns_zone_gettype(zone) == dns_zone_redirect) {
|
||||
dns_zone_detach(&view->redirect);
|
||||
} else {
|
||||
CHECK(dns_zt_unmount(view->zonetable, zone));
|
||||
CHECK(dns_view_delzone(view, zone));
|
||||
}
|
||||
|
||||
/* Send cleanup event */
|
||||
|
|
|
|||
|
|
@ -1780,8 +1780,8 @@ generatexml(named_server_t *server, uint32_t flags, int *buflen,
|
|||
if ((flags & STATS_XML_ZONES) != 0) {
|
||||
TRY0(xmlTextWriterStartElement(writer,
|
||||
ISC_XMLCHAR "zones"));
|
||||
CHECK(dns_zt_apply(view->zonetable, true, NULL,
|
||||
zone_xmlrender, writer));
|
||||
CHECK(dns_view_apply(view, true, NULL, zone_xmlrender,
|
||||
writer));
|
||||
TRY0(xmlTextWriterEndElement(writer)); /* /zones */
|
||||
}
|
||||
|
||||
|
|
@ -2494,8 +2494,8 @@ generatejson(named_server_t *server, size_t *msglen, const char **msg,
|
|||
CHECKMEM(za);
|
||||
|
||||
if ((flags & STATS_JSON_ZONES) != 0) {
|
||||
CHECK(dns_zt_apply(view->zonetable, true, NULL,
|
||||
zone_jsonrender, za));
|
||||
CHECK(dns_view_apply(view, true, NULL,
|
||||
zone_jsonrender, za));
|
||||
}
|
||||
|
||||
if (json_object_array_length(za) != 0) {
|
||||
|
|
|
|||
|
|
@ -166,7 +166,7 @@ syncptr_find_zone(sample_instance_t *inst, dns_rdata_t *rdata, dns_name_t *name,
|
|||
}
|
||||
|
||||
/* Find a zone containing owner name of the PTR record. */
|
||||
result = dns_zt_find(inst->view->zonetable, name, 0, zone);
|
||||
result = dns_view_findzone(inst->view, name, 0, zone);
|
||||
if (result == DNS_R_PARTIALMATCH) {
|
||||
result = ISC_R_SUCCESS;
|
||||
} else if (result != ISC_R_SUCCESS) {
|
||||
|
|
|
|||
|
|
@ -139,7 +139,7 @@ publish_zone(sample_instance_t *inst, dns_zone_t *zone) {
|
|||
|
||||
/* Return success if the zone is already in the view as expected. */
|
||||
result = dns_view_findzone(inst->view, dns_zone_getorigin(zone),
|
||||
&zone_in_view);
|
||||
DNS_ZTFIND_EXACT, &zone_in_view);
|
||||
if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
|
|
|||
13
configure.ac
13
configure.ac
|
|
@ -247,6 +247,19 @@ AC_DEFINE_UNQUOTED([RCU_VERSION], ["$RCU_VERSION"], [Compile-time Userspace-RCU
|
|||
CFLAGS="$CFLAGS $LIBURCU_CFLAGS"
|
||||
LIBS="$LIBS $LIBURCU_LIBS"
|
||||
|
||||
#
|
||||
# Userspace-RCU inlining doesn't work for rcu_deference() with some combination
|
||||
# of C compiler and library version.
|
||||
#
|
||||
AC_MSG_CHECKING([whether we can inline small liburcu functions])
|
||||
AC_COMPILE_IFELSE(
|
||||
[AC_LANG_PROGRAM([[#define URCU_INLINE_SMALL_FUNCTIONS 1
|
||||
#include <urcu.h>]],
|
||||
[[struct opaque *a; struct opaque *b = rcu_dereference(a);]])],
|
||||
[AC_MSG_RESULT([yes])
|
||||
AC_DEFINE([URCU_INLINE_SMALL_FUNCTIONS], [1], [Inline small (less than 10 lines) functions])],
|
||||
[AC_MSG_RESULT([no])])
|
||||
|
||||
# Fuzzing is not included in pairwise testing as fuzzing tools are
|
||||
# not present in the relevant Docker image.
|
||||
#
|
||||
|
|
|
|||
|
|
@ -561,7 +561,7 @@ dns__catz_zones_merge(dns_catz_zone_t *catz, dns_catz_zone_t *newcatz) {
|
|||
/* Try to find the zone in the view */
|
||||
find_result = dns_view_findzone(catz->catzs->view,
|
||||
dns_catz_entry_getname(nentry),
|
||||
&zone);
|
||||
DNS_ZTFIND_EXACT, &zone);
|
||||
if (find_result == ISC_R_SUCCESS) {
|
||||
dns_catz_coo_t *coo = NULL;
|
||||
char pczname[DNS_NAME_FORMATSIZE];
|
||||
|
|
|
|||
|
|
@ -441,7 +441,7 @@ dns_dlz_writeablezone(dns_view_t *view, dns_dlzdb_t *dlzdb,
|
|||
}
|
||||
|
||||
/* See if the zone already exists */
|
||||
result = dns_view_findzone(view, origin, &dupzone);
|
||||
result = dns_view_findzone(view, origin, DNS_ZTFIND_EXACT, &dupzone);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
dns_zone_detach(&dupzone);
|
||||
result = ISC_R_EXISTS;
|
||||
|
|
|
|||
|
|
@ -493,6 +493,16 @@ dns_view_addzone(dns_view_t *view, dns_zone_t *zone);
|
|||
*\li 'zone' is a valid zone.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
dns_view_delzone(dns_view_t *view, dns_zone_t *zone);
|
||||
/*%<
|
||||
* Removes zone 'zone' from 'view'.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li 'zone' is a valid zone.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_view_freeze(dns_view_t *view);
|
||||
/*%<
|
||||
|
|
@ -751,11 +761,11 @@ dns_viewlist_findzone(dns_viewlist_t *list, const dns_name_t *name,
|
|||
*/
|
||||
|
||||
isc_result_t
|
||||
dns_view_findzone(dns_view_t *view, const dns_name_t *name, dns_zone_t **zonep);
|
||||
dns_view_findzone(dns_view_t *view, const dns_name_t *name,
|
||||
unsigned int options, dns_zone_t **zonep);
|
||||
/*%<
|
||||
* Search for the zone 'name' in the zone table of 'view'.
|
||||
* If found, 'zonep' is (strongly) attached to it. There
|
||||
* are no partial matches.
|
||||
* If found, 'zonep' is (strongly) attached to it.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
|
|
@ -1281,4 +1291,20 @@ dns_view_addtrustedkey(dns_view_t *view, dns_rdatatype_t rdtype,
|
|||
*
|
||||
*\li Anything else Failure.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
dns_view_apply(dns_view_t *view, bool stop, isc_result_t *sub,
|
||||
isc_result_t (*action)(dns_zone_t *, void *), void *uap);
|
||||
/*%<
|
||||
* Call dns_zt_apply on the view's zonetable.
|
||||
*
|
||||
* Returns:
|
||||
* \li ISC_R_SUCCESS if action was applied to all nodes. If 'stop' is
|
||||
* false and 'sub' is non NULL then the first error (if any)
|
||||
* reported by 'action' is returned in '*sub'. If 'stop' is true,
|
||||
* the first error code from 'action' is returned.
|
||||
*
|
||||
* \li ISC_R_SHUTTINGDOWN if the view is in the process of shutting down.
|
||||
*/
|
||||
|
||||
ISC_LANG_ENDDECLS
|
||||
|
|
|
|||
|
|
@ -6593,7 +6593,7 @@ name_external(const dns_name_t *name, dns_rdatatype_t type, fetchctx_t *fctx) {
|
|||
* then don't cache.
|
||||
*/
|
||||
dns_ztfind_t options = DNS_ZTFIND_NOEXACT | DNS_ZTFIND_MIRROR;
|
||||
result = dns_zt_find(fctx->res->view->zonetable, name, options, &zone);
|
||||
result = dns_view_findzone(fctx->res->view, name, options, &zone);
|
||||
if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) {
|
||||
dns_name_t *zname = dns_zone_getorigin(zone);
|
||||
dns_namereln_t reln = dns_name_fullcompare(
|
||||
|
|
|
|||
194
lib/dns/view.c
194
lib/dns/view.c
|
|
@ -30,6 +30,7 @@
|
|||
#include <isc/result.h>
|
||||
#include <isc/stats.h>
|
||||
#include <isc/string.h>
|
||||
#include <isc/urcu.h>
|
||||
#include <isc/util.h>
|
||||
|
||||
#include <dns/acl.h>
|
||||
|
|
@ -133,7 +134,6 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, const char *name,
|
|||
|
||||
isc_rwlock_init(&view->sfd_lock);
|
||||
|
||||
view->zonetable = NULL;
|
||||
dns_zt_create(mctx, view, &view->zonetable);
|
||||
|
||||
result = dns_fwdtable_create(mctx, &view->fwdtable);
|
||||
|
|
@ -460,7 +460,7 @@ dns_view_detach(dns_view_t **viewp) {
|
|||
|
||||
if (isc_refcount_decrement(&view->references) == 1) {
|
||||
dns_zone_t *mkzone = NULL, *rdzone = NULL;
|
||||
dns_zt_t *zt = NULL;
|
||||
dns_zt_t *zonetable = NULL;
|
||||
dns_resolver_t *resolver = NULL;
|
||||
dns_adb_t *adb = NULL;
|
||||
dns_requestmgr_t *requestmgr = NULL;
|
||||
|
|
@ -481,6 +481,15 @@ dns_view_detach(dns_view_t **viewp) {
|
|||
/* Swap the pointers under the lock */
|
||||
LOCK(&view->lock);
|
||||
|
||||
rcu_read_lock();
|
||||
zonetable = rcu_xchg_pointer(&view->zonetable, NULL);
|
||||
if (zonetable != NULL) {
|
||||
if (view->flush) {
|
||||
dns_zt_flush(zonetable);
|
||||
}
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
if (view->resolver != NULL) {
|
||||
resolver = view->resolver;
|
||||
view->resolver = NULL;
|
||||
|
|
@ -495,14 +504,6 @@ dns_view_detach(dns_view_t **viewp) {
|
|||
requestmgr = view->requestmgr;
|
||||
view->requestmgr = NULL;
|
||||
}
|
||||
|
||||
if (view->zonetable != NULL) {
|
||||
zt = view->zonetable;
|
||||
view->zonetable = NULL;
|
||||
if (view->flush) {
|
||||
dns_zt_flush(zt);
|
||||
}
|
||||
}
|
||||
if (view->managed_keys != NULL) {
|
||||
mkzone = view->managed_keys;
|
||||
view->managed_keys = NULL;
|
||||
|
|
@ -537,8 +538,9 @@ dns_view_detach(dns_view_t **viewp) {
|
|||
dns_requestmgr_detach(&requestmgr);
|
||||
}
|
||||
|
||||
if (zt != NULL) {
|
||||
dns_zt_detach(&zt);
|
||||
if (zonetable != NULL) {
|
||||
synchronize_rcu();
|
||||
dns_zt_detach(&zonetable);
|
||||
}
|
||||
if (mkzone != NULL) {
|
||||
dns_zone_detach(&mkzone);
|
||||
|
|
@ -560,10 +562,16 @@ dialup(dns_zone_t *zone, void *dummy) {
|
|||
|
||||
void
|
||||
dns_view_dialup(dns_view_t *view) {
|
||||
REQUIRE(DNS_VIEW_VALID(view));
|
||||
REQUIRE(view->zonetable != NULL);
|
||||
dns_zt_t *zonetable = NULL;
|
||||
|
||||
(void)dns_zt_apply(view->zonetable, false, NULL, dialup, NULL);
|
||||
REQUIRE(DNS_VIEW_VALID(view));
|
||||
|
||||
rcu_read_lock();
|
||||
zonetable = rcu_dereference(view->zonetable);
|
||||
if (zonetable != NULL) {
|
||||
(void)dns_zt_apply(zonetable, false, NULL, dialup, NULL);
|
||||
}
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -762,21 +770,60 @@ dns_view_thaw(dns_view_t *view) {
|
|||
isc_result_t
|
||||
dns_view_addzone(dns_view_t *view, dns_zone_t *zone) {
|
||||
isc_result_t result;
|
||||
dns_zt_t *zonetable = NULL;
|
||||
|
||||
REQUIRE(DNS_VIEW_VALID(view));
|
||||
REQUIRE(!view->frozen);
|
||||
|
||||
result = dns_zt_mount(view->zonetable, zone);
|
||||
rcu_read_lock();
|
||||
zonetable = rcu_dereference(view->zonetable);
|
||||
if (zonetable != NULL) {
|
||||
result = dns_zt_mount(zonetable, zone);
|
||||
} else {
|
||||
result = ISC_R_SHUTTINGDOWN;
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_view_delzone(dns_view_t *view, dns_zone_t *zone) {
|
||||
isc_result_t result;
|
||||
dns_zt_t *zonetable = NULL;
|
||||
|
||||
REQUIRE(DNS_VIEW_VALID(view));
|
||||
|
||||
rcu_read_lock();
|
||||
zonetable = rcu_dereference(view->zonetable);
|
||||
if (zonetable != NULL) {
|
||||
result = dns_zt_unmount(zonetable, zone);
|
||||
} else {
|
||||
result = ISC_R_SUCCESS;
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_view_findzone(dns_view_t *view, const dns_name_t *name,
|
||||
dns_zone_t **zonep) {
|
||||
unsigned int options, dns_zone_t **zonep) {
|
||||
isc_result_t result;
|
||||
dns_zt_t *zonetable = NULL;
|
||||
|
||||
REQUIRE(DNS_VIEW_VALID(view));
|
||||
|
||||
return (dns_zt_find(view->zonetable, name, DNS_ZTFIND_EXACT, zonep));
|
||||
rcu_read_lock();
|
||||
zonetable = rcu_dereference(view->zonetable);
|
||||
if (zonetable != NULL) {
|
||||
result = dns_zt_find(zonetable, name, options, zonep);
|
||||
} else {
|
||||
result = ISC_R_NOTFOUND;
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
|
|
@ -791,6 +838,7 @@ dns_view_find(dns_view_t *view, const dns_name_t *name, dns_rdatatype_t type,
|
|||
bool is_cache, is_staticstub_zone;
|
||||
dns_rdataset_t zrdataset, zsigrdataset;
|
||||
dns_zone_t *zone = NULL;
|
||||
dns_zt_t *zonetable = NULL;
|
||||
|
||||
/*
|
||||
* Find an rdataset whose owner name is 'name', and whose type is
|
||||
|
|
@ -813,7 +861,14 @@ dns_view_find(dns_view_t *view, const dns_name_t *name, dns_rdatatype_t type,
|
|||
* Find a database to answer the query.
|
||||
*/
|
||||
is_staticstub_zone = false;
|
||||
result = dns_zt_find(view->zonetable, name, DNS_ZTFIND_MIRROR, &zone);
|
||||
rcu_read_lock();
|
||||
zonetable = rcu_dereference(view->zonetable);
|
||||
if (zonetable != NULL) {
|
||||
result = dns_zt_find(zonetable, name, DNS_ZTFIND_MIRROR, &zone);
|
||||
} else {
|
||||
result = ISC_R_SHUTTINGDOWN;
|
||||
}
|
||||
rcu_read_unlock();
|
||||
if (zone != NULL && dns_zone_gettype(zone) == dns_zone_staticstub &&
|
||||
!use_static_stub)
|
||||
{
|
||||
|
|
@ -1067,6 +1122,7 @@ dns_view_findzonecut(dns_view_t *view, const dns_name_t *name,
|
|||
bool is_cache, use_zone = false, try_hints = false;
|
||||
dns_zone_t *zone = NULL;
|
||||
dns_name_t *zfname = NULL;
|
||||
dns_zt_t *zonetable = NULL;
|
||||
dns_rdataset_t zrdataset, zsigrdataset;
|
||||
dns_fixedname_t zfixedname;
|
||||
unsigned int ztoptions = DNS_ZTFIND_MIRROR;
|
||||
|
|
@ -1087,7 +1143,14 @@ dns_view_findzonecut(dns_view_t *view, const dns_name_t *name,
|
|||
if ((options & DNS_DBFIND_NOEXACT) != 0) {
|
||||
ztoptions |= DNS_ZTFIND_NOEXACT;
|
||||
}
|
||||
result = dns_zt_find(view->zonetable, name, ztoptions, &zone);
|
||||
rcu_read_lock();
|
||||
zonetable = rcu_dereference(view->zonetable);
|
||||
if (zonetable != NULL) {
|
||||
result = dns_zt_find(zonetable, name, ztoptions, &zone);
|
||||
} else {
|
||||
result = ISC_R_SHUTTINGDOWN;
|
||||
}
|
||||
rcu_read_unlock();
|
||||
if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) {
|
||||
result = dns_zone_getdb(zone, &db);
|
||||
}
|
||||
|
|
@ -1287,11 +1350,19 @@ dns_viewlist_findzone(dns_viewlist_t *list, const dns_name_t *name,
|
|||
for (view = ISC_LIST_HEAD(*list); view != NULL;
|
||||
view = ISC_LIST_NEXT(view, link))
|
||||
{
|
||||
dns_zt_t *zonetable = NULL;
|
||||
if (!allclasses && view->rdclass != rdclass) {
|
||||
continue;
|
||||
}
|
||||
result = dns_zt_find(view->zonetable, name, DNS_ZTFIND_EXACT,
|
||||
(zone1 == NULL) ? &zone1 : &zone2);
|
||||
rcu_read_lock();
|
||||
zonetable = rcu_dereference(view->zonetable);
|
||||
if (zonetable != NULL) {
|
||||
result = dns_zt_find(zonetable, name, DNS_ZTFIND_EXACT,
|
||||
(zone1 == NULL) ? &zone1 : &zone2);
|
||||
} else {
|
||||
result = ISC_R_NOTFOUND;
|
||||
}
|
||||
rcu_read_unlock();
|
||||
INSIST(result == ISC_R_SUCCESS || result == ISC_R_NOTFOUND);
|
||||
if (zone2 != NULL) {
|
||||
dns_zone_detach(&zone1);
|
||||
|
|
@ -1311,15 +1382,39 @@ dns_viewlist_findzone(dns_viewlist_t *list, const dns_name_t *name,
|
|||
|
||||
isc_result_t
|
||||
dns_view_load(dns_view_t *view, bool stop, bool newonly) {
|
||||
isc_result_t result;
|
||||
dns_zt_t *zonetable = NULL;
|
||||
|
||||
REQUIRE(DNS_VIEW_VALID(view));
|
||||
return (dns_zt_load(view->zonetable, stop, newonly));
|
||||
|
||||
rcu_read_lock();
|
||||
zonetable = rcu_dereference(view->zonetable);
|
||||
if (zonetable != NULL) {
|
||||
result = dns_zt_load(zonetable, stop, newonly);
|
||||
} else {
|
||||
result = ISC_R_SUCCESS;
|
||||
}
|
||||
rcu_read_unlock();
|
||||
return (result);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_view_asyncload(dns_view_t *view, bool newonly, dns_zt_callback_t *callback,
|
||||
void *arg) {
|
||||
isc_result_t result;
|
||||
dns_zt_t *zonetable = NULL;
|
||||
|
||||
REQUIRE(DNS_VIEW_VALID(view));
|
||||
return (dns_zt_asyncload(view->zonetable, newonly, callback, arg));
|
||||
|
||||
rcu_read_lock();
|
||||
zonetable = rcu_dereference(view->zonetable);
|
||||
if (zonetable != NULL) {
|
||||
result = dns_zt_asyncload(zonetable, newonly, callback, arg);
|
||||
} else {
|
||||
result = ISC_R_SUCCESS;
|
||||
}
|
||||
rcu_read_unlock();
|
||||
return (result);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
|
|
@ -1455,10 +1550,21 @@ dns_view_flushnode(dns_view_t *view, const dns_name_t *name, bool tree) {
|
|||
|
||||
isc_result_t
|
||||
dns_view_freezezones(dns_view_t *view, bool value) {
|
||||
REQUIRE(DNS_VIEW_VALID(view));
|
||||
REQUIRE(view->zonetable != NULL);
|
||||
isc_result_t result;
|
||||
dns_zt_t *zonetable = NULL;
|
||||
|
||||
return (dns_zt_freezezones(view->zonetable, view, value));
|
||||
REQUIRE(DNS_VIEW_VALID(view));
|
||||
|
||||
rcu_read_lock();
|
||||
zonetable = rcu_dereference(view->zonetable);
|
||||
if (zonetable != NULL) {
|
||||
result = dns_zt_freezezones(zonetable, view, value);
|
||||
} else {
|
||||
result = ISC_R_SUCCESS;
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
|
|
@ -2119,6 +2225,7 @@ cleanup:
|
|||
void
|
||||
dns_view_setviewcommit(dns_view_t *view) {
|
||||
dns_zone_t *redirect = NULL, *managed_keys = NULL;
|
||||
dns_zt_t *zonetable = NULL;
|
||||
|
||||
REQUIRE(DNS_VIEW_VALID(view));
|
||||
|
||||
|
|
@ -2133,9 +2240,13 @@ dns_view_setviewcommit(dns_view_t *view) {
|
|||
|
||||
UNLOCK(&view->lock);
|
||||
|
||||
if (view->zonetable != NULL) {
|
||||
dns_zt_setviewcommit(view->zonetable);
|
||||
rcu_read_lock();
|
||||
zonetable = rcu_dereference(view->zonetable);
|
||||
if (zonetable != NULL) {
|
||||
dns_zt_setviewcommit(zonetable);
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
if (redirect != NULL) {
|
||||
dns_zone_setviewcommit(redirect);
|
||||
dns_zone_detach(&redirect);
|
||||
|
|
@ -2149,7 +2260,7 @@ dns_view_setviewcommit(dns_view_t *view) {
|
|||
void
|
||||
dns_view_setviewrevert(dns_view_t *view) {
|
||||
dns_zone_t *redirect = NULL, *managed_keys = NULL;
|
||||
dns_zt_t *zonetable;
|
||||
dns_zt_t *zonetable = NULL;
|
||||
|
||||
REQUIRE(DNS_VIEW_VALID(view));
|
||||
|
||||
|
|
@ -2164,7 +2275,6 @@ dns_view_setviewrevert(dns_view_t *view) {
|
|||
if (view->managed_keys != NULL) {
|
||||
dns_zone_attach(view->managed_keys, &managed_keys);
|
||||
}
|
||||
zonetable = view->zonetable;
|
||||
UNLOCK(&view->lock);
|
||||
|
||||
if (redirect != NULL) {
|
||||
|
|
@ -2175,9 +2285,12 @@ dns_view_setviewrevert(dns_view_t *view) {
|
|||
dns_zone_setviewrevert(managed_keys);
|
||||
dns_zone_detach(&managed_keys);
|
||||
}
|
||||
rcu_read_lock();
|
||||
zonetable = rcu_dereference(view->zonetable);
|
||||
if (zonetable != NULL) {
|
||||
dns_zt_setviewrevert(zonetable);
|
||||
}
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
@ -2361,3 +2474,22 @@ dns_view_addtrustedkey(dns_view_t *view, dns_rdatatype_t rdtype,
|
|||
cleanup:
|
||||
return (result);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_view_apply(dns_view_t *view, bool stop, isc_result_t *sub,
|
||||
isc_result_t (*action)(dns_zone_t *, void *), void *uap) {
|
||||
isc_result_t result;
|
||||
dns_zt_t *zonetable = NULL;
|
||||
|
||||
REQUIRE(DNS_VIEW_VALID(view));
|
||||
|
||||
rcu_read_lock();
|
||||
zonetable = rcu_dereference(view->zonetable);
|
||||
if (zonetable != NULL) {
|
||||
result = dns_zt_apply(zonetable, stop, sub, action, uap);
|
||||
} else {
|
||||
result = ISC_R_SHUTTINGDOWN;
|
||||
}
|
||||
rcu_read_unlock();
|
||||
return (result);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,9 +19,6 @@
|
|||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||
|
||||
/* Inline small (less than 10 lines) functions */
|
||||
#define URCU_INLINE_SMALL_FUNCTIONS
|
||||
|
||||
#if defined(RCU_MEMBARRIER) || defined(RCU_MB) || defined(RCU_SIGNAL)
|
||||
#include <urcu.h>
|
||||
#elif defined(RCU_QSBR)
|
||||
|
|
|
|||
|
|
@ -146,7 +146,8 @@ ns_notify_start(ns_client_t *client, isc_nmhandle_t *handle) {
|
|||
}
|
||||
|
||||
dns_name_format(zonename, namebuf, sizeof(namebuf));
|
||||
result = dns_view_findzone(client->view, zonename, &zone);
|
||||
result = dns_view_findzone(client->view, zonename, DNS_ZTFIND_EXACT,
|
||||
&zone);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
dns_zonetype_t zonetype = dns_zone_gettype(zone);
|
||||
|
||||
|
|
|
|||
|
|
@ -1116,7 +1116,7 @@ query_getzonedb(ns_client_t *client, const dns_name_t *name,
|
|||
ztoptions |= DNS_ZTFIND_NOEXACT;
|
||||
}
|
||||
|
||||
result = dns_zt_find(client->view->zonetable, name, ztoptions, &zone);
|
||||
result = dns_view_findzone(client->view, name, ztoptions, &zone);
|
||||
|
||||
if (result == DNS_R_PARTIALMATCH) {
|
||||
partial = true;
|
||||
|
|
|
|||
|
|
@ -1987,7 +1987,8 @@ ns_update_start(ns_client_t *client, isc_nmhandle_t *handle,
|
|||
"RRs");
|
||||
}
|
||||
|
||||
result = dns_view_findzone(client->view, zonename, &zone);
|
||||
result = dns_view_findzone(client->view, zonename, DNS_ZTFIND_EXACT,
|
||||
&zone);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
FAILN(DNS_R_NOTAUTH, zonename,
|
||||
"not authoritative for update zone");
|
||||
|
|
|
|||
|
|
@ -795,7 +795,8 @@ ns_xfr_start(ns_client_t *client, dns_rdatatype_t reqtype) {
|
|||
FAILC(DNS_R_FORMERR, "multiple questions");
|
||||
}
|
||||
|
||||
result = dns_view_findzone(client->view, question_name, &zone);
|
||||
result = dns_view_findzone(client->view, question_name,
|
||||
DNS_ZTFIND_EXACT, &zone);
|
||||
if (result != ISC_R_SUCCESS || dns_zone_gettype(zone) == dns_zone_dlz) {
|
||||
/*
|
||||
* The normal zone table does not have a match, or this is
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
#include <isc/buffer.h>
|
||||
#include <isc/loop.h>
|
||||
#include <isc/timer.h>
|
||||
#include <isc/urcu.h>
|
||||
#include <isc/util.h>
|
||||
|
||||
#include <dns/db.h>
|
||||
|
|
@ -56,17 +57,21 @@ count_zone(dns_zone_t *zone, void *uap) {
|
|||
ISC_LOOP_TEST_IMPL(apply) {
|
||||
isc_result_t result;
|
||||
dns_zone_t *zone = NULL;
|
||||
dns_zt_t *zt = NULL;
|
||||
int nzones = 0;
|
||||
|
||||
result = dns_test_makezone("foo", &zone, NULL, true);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
view = dns_zone_getview(zone);
|
||||
assert_non_null(view->zonetable);
|
||||
rcu_read_lock();
|
||||
zt = rcu_dereference(view->zonetable);
|
||||
rcu_read_unlock();
|
||||
|
||||
assert_non_null(zt);
|
||||
|
||||
assert_int_equal(nzones, 0);
|
||||
result = dns_zt_apply(view->zonetable, false, NULL, count_zone,
|
||||
&nzones);
|
||||
result = dns_view_apply(view, false, NULL, count_zone, &nzones);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
assert_int_equal(nzones, 1);
|
||||
|
||||
|
|
@ -151,6 +156,7 @@ ISC_LOOP_TEST_IMPL(asyncload_zone) {
|
|||
isc_result_t result;
|
||||
int n;
|
||||
dns_zone_t *zone = NULL;
|
||||
dns_zt_t *zt = NULL;
|
||||
char buf[4096];
|
||||
|
||||
result = dns_test_makezone("foo", &zone, NULL, true);
|
||||
|
|
@ -161,7 +167,10 @@ ISC_LOOP_TEST_IMPL(asyncload_zone) {
|
|||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
view = dns_zone_getview(zone);
|
||||
assert_non_null(view->zonetable);
|
||||
rcu_read_lock();
|
||||
zt = rcu_dereference(view->zonetable);
|
||||
rcu_read_unlock();
|
||||
assert_non_null(zt);
|
||||
|
||||
assert_false(dns__zone_loadpending(zone));
|
||||
zonefile = fopen("./zone.data", "wb");
|
||||
|
|
@ -239,7 +248,9 @@ ISC_LOOP_TEST_IMPL(asyncload_zt) {
|
|||
dns_zone_setfile(zone3, TESTS_DIR "/testdata/zt/nonexistent.db",
|
||||
dns_masterformat_text, &dns_master_style_default);
|
||||
|
||||
zt = view->zonetable;
|
||||
rcu_read_lock();
|
||||
zt = rcu_dereference(view->zonetable);
|
||||
rcu_read_unlock();
|
||||
assert_non_null(zt);
|
||||
|
||||
dns_test_setupzonemgr();
|
||||
|
|
@ -254,7 +265,10 @@ ISC_LOOP_TEST_IMPL(asyncload_zt) {
|
|||
assert_false(dns__zone_loadpending(zone2));
|
||||
assert_false(atomic_load(&done));
|
||||
|
||||
rcu_read_lock();
|
||||
zt = rcu_dereference(view->zonetable);
|
||||
dns_zt_asyncload(zt, false, all_done, NULL);
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
ISC_TEST_LIST_START
|
||||
|
|
|
|||
Loading…
Reference in a new issue