mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-29 05:28:00 +00:00
Fixed multiple shutdown cleanup bugs in the zone object. This
involved extensive restructuring of the reference counting of zones and related objects. Zones now attach to their views. To avoid a circular dependency that would keep views from ever shutting down, this is done using the new functions dns_view_weakattach() / dns_view_weakdetach() which guarantee that the view will not be freed but still allow it to be shut down. The zones themselves now only have a single reference count, with similar "weak" semantics. Managed zones must now be shut down explicitly by calling dns_zone_shutdown(). To shut down all zones in a zone table, call dns_zt_shutdown(). The zone manager is now reference counted, weakly. To shut down the zone manager, you must explicitly call dns_zonemgr_shutdown().
This commit is contained in:
parent
bc436be071
commit
22608315e8
@ -524,7 +524,8 @@ configure_view(dns_view_t *view, dns_c_ctx_t *cctx, dns_c_view_t *cview,
|
||||
* there is no "version" configuration option.
|
||||
*/
|
||||
static isc_result_t
|
||||
create_version_view(dns_c_ctx_t *cctx, dns_view_t **viewp) {
|
||||
create_version_view(dns_c_ctx_t *cctx, dns_zonemgr_t *zmgr, dns_view_t **viewp)
|
||||
{
|
||||
isc_result_t result;
|
||||
dns_db_t *db = NULL;
|
||||
dns_zone_t *zone = NULL;
|
||||
@ -564,6 +565,7 @@ create_version_view(dns_c_ctx_t *cctx, dns_view_t **viewp) {
|
||||
|
||||
CHECK(dns_zone_create(&zone, ns_g_mctx));
|
||||
CHECK(dns_zone_setorigin(zone, &origin));
|
||||
CHECK(dns_zonemgr_managezone(zmgr, zone));
|
||||
|
||||
CHECK(dns_db_create(ns_g_mctx, "rbt", &origin, ISC_FALSE,
|
||||
dns_rdataclass_ch, 0, NULL, &db));
|
||||
@ -1253,7 +1255,7 @@ load_configuration(const char *filename, ns_server_t *server,
|
||||
* Create (or recreate) the version view.
|
||||
*/
|
||||
view = NULL;
|
||||
CHECK(create_version_view(cctx, &view));
|
||||
CHECK(create_version_view(cctx, server->zonemgr, &view));
|
||||
ISC_LIST_APPEND(lctx.viewlist, view, link);
|
||||
view = NULL;
|
||||
|
||||
@ -1447,9 +1449,12 @@ shutdown_server(isc_task_t *task, isc_event_t *event) {
|
||||
dns_dispatch_detach(&server->querysrc_dispatchv6);
|
||||
ns_clientmgr_destroy(&server->clientmgr);
|
||||
isc_timer_detach(&server->interface_timer);
|
||||
|
||||
ns_interfacemgr_shutdown(server->interfacemgr);
|
||||
ns_interfacemgr_detach(&server->interfacemgr);
|
||||
|
||||
dns_zonemgr_shutdown(server->zonemgr);
|
||||
dns_zonemgr_detach(&server->zonemgr);
|
||||
|
||||
isc_task_detach(&server->task);
|
||||
|
||||
@ -1551,9 +1556,6 @@ ns_server_destroy(ns_server_t **serverp) {
|
||||
|
||||
INSIST(ISC_LIST_EMPTY(server->viewlist));
|
||||
|
||||
dns_zonemgr_destroy(&server->zonemgr);
|
||||
server->zonemgr = NULL;
|
||||
|
||||
dns_db_detach(&server->in_roothints);
|
||||
|
||||
dns_aclenv_destroy(&server->aclenv);
|
||||
|
@ -110,6 +110,7 @@ struct dns_view {
|
||||
dns_acl_t * matchclients;
|
||||
/* Locked by lock. */
|
||||
unsigned int references;
|
||||
unsigned int weakrefs;
|
||||
unsigned int attributes;
|
||||
/* Under owner's locking control. */
|
||||
ISC_LINK(struct dns_view) link;
|
||||
@ -165,10 +166,44 @@ dns_view_attach(dns_view_t *source, dns_view_t **targetp);
|
||||
* Ensures:
|
||||
*
|
||||
* *targetp is attached to source.
|
||||
*
|
||||
* While *targetp is attached, the view will not shut down.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_view_detach(dns_view_t **viewp);
|
||||
/*
|
||||
* Detach '*viewp' from its view.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
* 'viewp' points to a valid dns_view_t *
|
||||
*
|
||||
* Ensures:
|
||||
*
|
||||
* *viewp is NULL.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_view_weakattach(dns_view_t *source, dns_view_t **targetp);
|
||||
/*
|
||||
* Weakly attach '*targetp' to 'source'.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
* 'source' is a valid, frozen view.
|
||||
*
|
||||
* 'targetp' points to a NULL dns_view_t *.
|
||||
*
|
||||
* Ensures:
|
||||
*
|
||||
* *targetp is attached to source.
|
||||
*
|
||||
* While *targetp is attached, the view will not be freed.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_view_weakdetach(dns_view_t **targetp);
|
||||
/*
|
||||
* Detach '*viewp' from its view.
|
||||
*
|
||||
@ -179,10 +214,6 @@ dns_view_detach(dns_view_t **viewp);
|
||||
* Ensures:
|
||||
*
|
||||
* *viewp is NULL.
|
||||
*
|
||||
* If '*viewp' is the last reference to the view,
|
||||
*
|
||||
* All resources used by the view will be freed.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
|
@ -200,30 +200,6 @@ dns_zone_detach(dns_zone_t **zonep);
|
||||
* 'zonep' to point to a valid initalised zone.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_zone_iattach(dns_zone_t *source, dns_zone_t **target);
|
||||
/*
|
||||
* Attach 'zone' to 'target' incrementing its internal
|
||||
* reference count. This is intended for use by operations
|
||||
* such as zone transfers that need to prevent the zone
|
||||
* object from being freed but not from shutting down.
|
||||
*
|
||||
* Require:
|
||||
* 'zone' to be a valid initalised zone.
|
||||
* 'target' to be non NULL and '*target' to be NULL.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_zone_idetach(dns_zone_t **zonep);
|
||||
/*
|
||||
* Detach from a zone decrementing its internal reference count.
|
||||
* If there are no more internal or external references to the
|
||||
* zone, it will be freed.
|
||||
*
|
||||
* Require:
|
||||
* 'zonep' to point to a valid initalised zone.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_zone_setflag(dns_zone_t *zone, unsigned int flags, isc_boolean_t value);
|
||||
/*
|
||||
@ -811,6 +787,12 @@ dns_zone_getmctx(dns_zone_t *zone);
|
||||
dns_zonemgr_t *
|
||||
dns_zone_getmgr(dns_zone_t *zone);
|
||||
|
||||
void
|
||||
dns_zone_shutdown(dns_zone_t *zone);
|
||||
/*
|
||||
* Initiate shutdown for a zone.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
|
||||
isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr,
|
||||
@ -845,15 +827,16 @@ dns_zonemgr_forcemaint(dns_zonemgr_t *zmgr);
|
||||
void
|
||||
dns_zonemgr_shutdown(dns_zonemgr_t *zmgr);
|
||||
/*
|
||||
* Shut down and detach the task of the zone manager.
|
||||
* Shut down the zone manager.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_zonemgr_destroy(dns_zonemgr_t **zmgrp);
|
||||
dns_zonemgr_detach(dns_zonemgr_t **zmgrp);
|
||||
/*
|
||||
* Destroy a zone manager.
|
||||
* Detach from a zone manager.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
* '*zmgrp' is a valid, non-NULL zone manager pointer.
|
||||
* Ensures:
|
||||
* '*zmgrp' is NULL.
|
||||
|
@ -134,6 +134,15 @@ dns_zt_print(dns_zt_t *zt);
|
||||
* 'zt' to be valid.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_zt_shutdown(dns_zt_t *zt);
|
||||
/*
|
||||
* Shut down all zones in the table.
|
||||
*
|
||||
* Requires
|
||||
* 'zt' to be valid.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
dns_zt_apply(dns_zt_t *zt, isc_boolean_t stop,
|
||||
isc_result_t (*action)(dns_zone_t *, void *), void *uap);
|
||||
|
@ -121,6 +121,7 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
|
||||
view->frozen = ISC_FALSE;
|
||||
view->task = NULL;
|
||||
view->references = 1;
|
||||
view->weakrefs = 0;
|
||||
view->attributes = (DNS_VIEWATTR_RESSHUTDOWN|DNS_VIEWATTR_ADBSHUTDOWN|
|
||||
DNS_VIEWATTR_REQSHUTDOWN);
|
||||
view->statickeys = NULL;
|
||||
@ -188,31 +189,11 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
|
||||
return (result);
|
||||
}
|
||||
|
||||
void
|
||||
dns_view_attach(dns_view_t *source, dns_view_t **targetp) {
|
||||
|
||||
/*
|
||||
* Attach '*targetp' to 'source'.
|
||||
*/
|
||||
|
||||
REQUIRE(DNS_VIEW_VALID(source));
|
||||
REQUIRE(targetp != NULL && *targetp == NULL);
|
||||
|
||||
LOCK(&source->lock);
|
||||
|
||||
INSIST(source->references > 0);
|
||||
source->references++;
|
||||
INSIST(source->references != 0);
|
||||
|
||||
UNLOCK(&source->lock);
|
||||
|
||||
*targetp = source;
|
||||
}
|
||||
|
||||
static inline void
|
||||
destroy(dns_view_t *view) {
|
||||
REQUIRE(!ISC_LINK_LINKED(view, link));
|
||||
REQUIRE(view->references == 0);
|
||||
REQUIRE(view->weakrefs == 0);
|
||||
REQUIRE(RESSHUTDOWN(view));
|
||||
REQUIRE(ADBSHUTDOWN(view));
|
||||
REQUIRE(REQSHUTDOWN(view));
|
||||
@ -257,22 +238,35 @@ all_done(dns_view_t *view) {
|
||||
* Caller must be holding the view lock.
|
||||
*/
|
||||
|
||||
if (view->references == 0 && RESSHUTDOWN(view) &&
|
||||
ADBSHUTDOWN(view) && REQSHUTDOWN(view))
|
||||
if (view->references == 0 && view->weakrefs == 0 &&
|
||||
RESSHUTDOWN(view) && ADBSHUTDOWN(view) && REQSHUTDOWN(view))
|
||||
return (ISC_TRUE);
|
||||
|
||||
return (ISC_FALSE);
|
||||
}
|
||||
|
||||
void
|
||||
dns_view_attach(dns_view_t *source, dns_view_t **targetp) {
|
||||
|
||||
REQUIRE(DNS_VIEW_VALID(source));
|
||||
REQUIRE(targetp != NULL && *targetp == NULL);
|
||||
|
||||
LOCK(&source->lock);
|
||||
|
||||
INSIST(source->references > 0);
|
||||
source->references++;
|
||||
INSIST(source->references != 0);
|
||||
|
||||
UNLOCK(&source->lock);
|
||||
|
||||
*targetp = source;
|
||||
}
|
||||
|
||||
void
|
||||
dns_view_detach(dns_view_t **viewp) {
|
||||
dns_view_t *view;
|
||||
isc_boolean_t done = ISC_FALSE;
|
||||
|
||||
/*
|
||||
* Detach '*viewp' from its view.
|
||||
*/
|
||||
|
||||
REQUIRE(viewp != NULL);
|
||||
view = *viewp;
|
||||
REQUIRE(DNS_VIEW_VALID(view));
|
||||
@ -288,6 +282,7 @@ dns_view_detach(dns_view_t **viewp) {
|
||||
dns_adb_shutdown(view->adb);
|
||||
if (!REQSHUTDOWN(view))
|
||||
dns_requestmgr_shutdown(view->requestmgr);
|
||||
dns_zt_shutdown(view->zonetable);
|
||||
done = all_done(view);
|
||||
}
|
||||
UNLOCK(&view->lock);
|
||||
@ -298,6 +293,42 @@ dns_view_detach(dns_view_t **viewp) {
|
||||
destroy(view);
|
||||
}
|
||||
|
||||
void
|
||||
dns_view_weakattach(dns_view_t *source, dns_view_t **targetp) {
|
||||
|
||||
REQUIRE(DNS_VIEW_VALID(source));
|
||||
REQUIRE(targetp != NULL && *targetp == NULL);
|
||||
|
||||
LOCK(&source->lock);
|
||||
source->weakrefs++;
|
||||
UNLOCK(&source->lock);
|
||||
|
||||
*targetp = source;
|
||||
}
|
||||
|
||||
void
|
||||
dns_view_weakdetach(dns_view_t **viewp) {
|
||||
dns_view_t *view;
|
||||
isc_boolean_t done = ISC_FALSE;
|
||||
|
||||
REQUIRE(viewp != NULL);
|
||||
view = *viewp;
|
||||
REQUIRE(DNS_VIEW_VALID(view));
|
||||
|
||||
LOCK(&view->lock);
|
||||
|
||||
INSIST(view->weakrefs > 0);
|
||||
view->weakrefs--;
|
||||
done = all_done(view);
|
||||
|
||||
UNLOCK(&view->lock);
|
||||
|
||||
*viewp = NULL;
|
||||
|
||||
if (done)
|
||||
destroy(view);
|
||||
}
|
||||
|
||||
static void
|
||||
resolver_shutdown(isc_task_t *task, isc_event_t *event) {
|
||||
dns_view_t *view = event->ev_arg;
|
||||
|
@ -15,7 +15,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: xfrin.c,v 1.69 2000/05/14 20:01:27 gson Exp $ */
|
||||
/* $Id: xfrin.c,v 1.70 2000/05/17 19:45:29 gson Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
@ -605,7 +605,7 @@ xfrin_create(isc_mem_t *mctx,
|
||||
xfr->mctx = mctx;
|
||||
xfr->refcount = 0;
|
||||
xfr->zone = NULL;
|
||||
dns_zone_iattach(zone, &xfr->zone);
|
||||
dns_zone_attach(zone, &xfr->zone);
|
||||
xfr->task = NULL;
|
||||
isc_task_attach(task, &xfr->task);
|
||||
xfr->timer = NULL;
|
||||
@ -1180,7 +1180,7 @@ maybe_free(dns_xfrin_ctx_t *xfr) {
|
||||
dns_db_detach(&xfr->db);
|
||||
|
||||
if (xfr->zone != NULL)
|
||||
dns_zone_idetach(&xfr->zone);
|
||||
dns_zone_detach(&xfr->zone);
|
||||
|
||||
isc_mem_put(xfr->mctx, xfr, sizeof(*xfr));
|
||||
}
|
||||
|
294
lib/dns/zone.c
294
lib/dns/zone.c
@ -15,7 +15,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: zone.c,v 1.115 2000/05/14 23:23:37 gson Exp $ */
|
||||
/* $Id: zone.c,v 1.116 2000/05/17 19:45:31 gson Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
@ -93,8 +93,7 @@ struct dns_zone {
|
||||
dns_zonemgr_t *zmgr;
|
||||
ISC_LINK(dns_zone_t) link; /* Used by zmgr. */
|
||||
isc_timer_t *timer;
|
||||
unsigned int erefs;
|
||||
unsigned int irefs;
|
||||
unsigned int refs;
|
||||
dns_name_t origin;
|
||||
char *dbname;
|
||||
char *journal;
|
||||
@ -178,6 +177,7 @@ struct dns_zone {
|
||||
|
||||
struct dns_zonemgr {
|
||||
isc_mem_t * mctx;
|
||||
int refs;
|
||||
isc_taskmgr_t * taskmgr;
|
||||
isc_timermgr_t * timermgr;
|
||||
isc_socketmgr_t * socketmgr;
|
||||
@ -223,7 +223,6 @@ static void zone_expire(dns_zone_t *zone);
|
||||
static isc_result_t zone_replacedb(dns_zone_t *zone, dns_db_t *db,
|
||||
isc_boolean_t dump);
|
||||
static isc_result_t default_journal(dns_zone_t *zone);
|
||||
static void releasezone(dns_zonemgr_t *zmgr, dns_zone_t *zone);
|
||||
static void xfrdone(dns_zone_t *zone, isc_result_t result);
|
||||
static void zone_shutdown(isc_task_t *, isc_event_t *);
|
||||
|
||||
@ -247,15 +246,18 @@ static isc_result_t zone_dump(dns_zone_t *);
|
||||
static void got_transfer_quota(isc_task_t *task, isc_event_t *event);
|
||||
static isc_result_t zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr, dns_zone_t *zone);
|
||||
static void zmgr_resume_xfrs(dns_zonemgr_t *zmgr);
|
||||
|
||||
static void zonemgr_free(dns_zonemgr_t *zmgr);
|
||||
|
||||
|
||||
|
||||
#define PRINT_ZONE_REF(zone) \
|
||||
do { \
|
||||
char *s = NULL; \
|
||||
isc_result_t r; \
|
||||
r = dns_zone_tostr(zone, zone->mctx, &s); \
|
||||
if (r == ISC_R_SUCCESS) { \
|
||||
printf("%p: %s: erefs = %d\n", zone, s, \
|
||||
zone->erefs); \
|
||||
printf("%p: %s: refs = %d\n", zone, s, \
|
||||
zone->refs); \
|
||||
isc_mem_free(zone->mctx, s); \
|
||||
} \
|
||||
} while (0)
|
||||
@ -302,8 +304,7 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
|
||||
zone->db = NULL;
|
||||
zone->zmgr = NULL;
|
||||
ISC_LINK_INIT(zone, link);
|
||||
zone->erefs = 1; /* Implicit attach. */
|
||||
zone->irefs = 0;
|
||||
zone->refs = 1; /* Implicit attach. */
|
||||
dns_name_init(&zone->origin, NULL);
|
||||
zone->dbname = NULL;
|
||||
zone->journalsize = -1;
|
||||
@ -364,7 +365,7 @@ zone_free(dns_zone_t *zone) {
|
||||
|
||||
REQUIRE(DNS_ZONE_VALID(zone));
|
||||
LOCK(&zone->lock);
|
||||
REQUIRE(zone->erefs == 0);
|
||||
REQUIRE(zone->refs == 0);
|
||||
zone->flags |= DNS_ZONE_F_EXITING;
|
||||
UNLOCK(&zone->lock);
|
||||
|
||||
@ -379,13 +380,14 @@ zone_free(dns_zone_t *zone) {
|
||||
dns_request_cancel(zone->request); /* XXXMPA */
|
||||
dns_request_destroy(&zone->request); /* XXXMPA */
|
||||
}
|
||||
|
||||
INSIST(zone->statelist == NULL);
|
||||
|
||||
if (zone->task != NULL)
|
||||
isc_task_detach(&zone->task);
|
||||
if (zone->zmgr)
|
||||
dns_zonemgr_releasezone(zone->zmgr, zone);
|
||||
|
||||
INSIST(zone->statelist == NULL);
|
||||
|
||||
/* Unmanaged objects */
|
||||
if (zone->dbname != NULL)
|
||||
isc_mem_free(zone->mctx, zone->dbname);
|
||||
@ -484,7 +486,7 @@ dns_zone_setdbtype(dns_zone_t *zone, char *db_type) {
|
||||
|
||||
void
|
||||
dns_zone_setview(dns_zone_t *zone, dns_view_t *view) {
|
||||
zone->view = view;
|
||||
dns_view_weakattach(view, &zone->view);
|
||||
}
|
||||
|
||||
|
||||
@ -856,93 +858,74 @@ dns_zone_load(dns_zone_t *zone) {
|
||||
|
||||
static void
|
||||
exit_check(dns_zone_t *zone) {
|
||||
if (zone->irefs == 0 && DNS_ZONE_FLAG(zone, DNS_ZONE_F_EXITING))
|
||||
if (zone->refs == 0)
|
||||
zone_free(zone);
|
||||
}
|
||||
|
||||
void
|
||||
dns_zone_shutdown(dns_zone_t *zone) {
|
||||
REQUIRE(DNS_ZONE_VALID(zone));
|
||||
LOCK(&zone->lock);
|
||||
REQUIRE(zone->refs > 0);
|
||||
|
||||
if (zone->task != NULL) {
|
||||
/*
|
||||
* This zone is being managed. Post
|
||||
* its control event and let it clean
|
||||
* up synchronously in the context of
|
||||
* its task.
|
||||
*/
|
||||
isc_event_t *ev = &zone->ctlevent;
|
||||
isc_task_send(zone->task, &ev);
|
||||
} else {
|
||||
/*
|
||||
* Unmanaged zones should not have non-null views;
|
||||
* we have no way of detaching from the view here
|
||||
* without causing deadlock because this code is called
|
||||
* with the view already locked.
|
||||
*/
|
||||
INSIST(zone->view != NULL);
|
||||
}
|
||||
UNLOCK(&zone->lock);
|
||||
}
|
||||
|
||||
static void
|
||||
zone_attach(dns_zone_t *source, dns_zone_t **target) {
|
||||
REQUIRE(DNS_ZONE_VALID(source));
|
||||
REQUIRE(target != NULL && *target == NULL);
|
||||
source->refs++;
|
||||
INSIST(source->refs != 0xffffffffU);
|
||||
*target = source;
|
||||
}
|
||||
|
||||
void
|
||||
dns_zone_attach(dns_zone_t *source, dns_zone_t **target) {
|
||||
REQUIRE(DNS_ZONE_VALID(source));
|
||||
REQUIRE(target != NULL && *target == NULL);
|
||||
|
||||
LOCK(&source->lock);
|
||||
REQUIRE(source->erefs > 0);
|
||||
source->erefs++;
|
||||
INSIST(source->erefs != 0xffffffffU);
|
||||
zone_attach(source, target);
|
||||
UNLOCK(&source->lock);
|
||||
*target = source;
|
||||
}
|
||||
|
||||
static void
|
||||
zone_detach(dns_zone_t **zonep) {
|
||||
dns_zone_t *zone;
|
||||
|
||||
REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
|
||||
zone = *zonep;
|
||||
REQUIRE(zone->refs > 0);
|
||||
zone->refs--;
|
||||
*zonep = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
dns_zone_detach(dns_zone_t **zonep) {
|
||||
dns_zone_t *zone;
|
||||
isc_boolean_t free_now = ISC_FALSE;
|
||||
REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
|
||||
zone = *zonep;
|
||||
LOCK(&zone->lock);
|
||||
REQUIRE(zone->erefs > 0);
|
||||
zone->erefs--;
|
||||
if (zone->erefs == 0) {
|
||||
if (zone->task != NULL) {
|
||||
/*
|
||||
* This zone is being managed. Post
|
||||
* its control event and let it clean
|
||||
* up synchronously in the context of
|
||||
* its task.
|
||||
*/
|
||||
isc_event_t *ev = &zone->ctlevent;
|
||||
isc_task_send(zone->task, &ev);
|
||||
} else {
|
||||
/*
|
||||
* This zone is not being managed; it has
|
||||
* no task and can have no outstanding
|
||||
* events. Free it immediately.
|
||||
*/
|
||||
free_now = ISC_TRUE;
|
||||
}
|
||||
}
|
||||
UNLOCK(&zone->lock);
|
||||
if (free_now)
|
||||
zone_free(zone);
|
||||
*zonep = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
zone_iattach(dns_zone_t *source, dns_zone_t **target) {
|
||||
REQUIRE(DNS_ZONE_VALID(source));
|
||||
REQUIRE(target != NULL && *target == NULL);
|
||||
source->irefs++;
|
||||
INSIST(source->irefs != 0xffffffffU);
|
||||
*target = source;
|
||||
}
|
||||
|
||||
void
|
||||
dns_zone_iattach(dns_zone_t *source, dns_zone_t **target) {
|
||||
REQUIRE(DNS_ZONE_VALID(source));
|
||||
|
||||
LOCK(&source->lock);
|
||||
zone_iattach(source, target);
|
||||
UNLOCK(&source->lock);
|
||||
}
|
||||
|
||||
static void
|
||||
zone_idetach(dns_zone_t **zonep) {
|
||||
dns_zone_t *zone;
|
||||
|
||||
REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
|
||||
zone = *zonep;
|
||||
REQUIRE(zone->irefs > 0);
|
||||
zone->irefs--;
|
||||
*zonep = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
dns_zone_idetach(dns_zone_t **zonep) {
|
||||
dns_zone_t *zone;
|
||||
|
||||
REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
|
||||
zone = *zonep;
|
||||
LOCK(&zone->lock);
|
||||
zone_idetach(zonep);
|
||||
zone_detach(zonep);
|
||||
UNLOCK(&zone->lock);
|
||||
exit_check(zone);
|
||||
}
|
||||
@ -1483,7 +1466,8 @@ notify_destroy(notify_t *notify) {
|
||||
if (notify->zone != NULL) {
|
||||
if (ISC_LINK_LINKED(notify, link))
|
||||
ISC_LIST_UNLINK(notify->zone->notifies, notify, link);
|
||||
zone_idetach(¬ify->zone);
|
||||
zone_detach(¬ify->zone);
|
||||
/* XXXAG exit_check */
|
||||
}
|
||||
if (notify->find != NULL)
|
||||
dns_adb_destroyfind(¬ify->find);
|
||||
@ -1530,7 +1514,7 @@ process_adb_event(isc_task_t *task, isc_event_t *ev) {
|
||||
REQUIRE(DNS_NOTIFY_VALID(notify));
|
||||
result = ev->ev_type;
|
||||
isc_event_free(&ev);
|
||||
dns_zone_iattach(notify->zone, &zone);
|
||||
dns_zone_attach(notify->zone, &zone);
|
||||
if (result == DNS_EVENT_ADBNOMOREADDRESSES) {
|
||||
LOCK(¬ify->zone->lock);
|
||||
notify_send(notify);
|
||||
@ -1546,7 +1530,7 @@ process_adb_event(isc_task_t *task, isc_event_t *ev) {
|
||||
notify_destroy(notify);
|
||||
UNLOCK(&zone->lock);
|
||||
detach:
|
||||
dns_zone_idetach(&zone);
|
||||
dns_zone_detach(&zone);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1559,7 +1543,7 @@ notify_find_address(notify_t *notify) {
|
||||
options = DNS_ADBFIND_WANTEVENT | DNS_ADBFIND_INET |
|
||||
DNS_ADBFIND_INET6 | DNS_ADBFIND_RETURNLAME;
|
||||
|
||||
dns_zone_iattach(notify->zone, &zone);
|
||||
dns_zone_attach(notify->zone, &zone);
|
||||
result = dns_adb_createfind(zone->view->adb,
|
||||
zone->task,
|
||||
process_adb_event, notify,
|
||||
@ -1571,13 +1555,13 @@ notify_find_address(notify_t *notify) {
|
||||
LOCK(&zone->lock);
|
||||
notify_destroy(notify);
|
||||
UNLOCK(&zone->lock);
|
||||
dns_zone_idetach(&zone);
|
||||
dns_zone_detach(&zone);
|
||||
return;
|
||||
}
|
||||
|
||||
/* More addresses pending? */
|
||||
if ((notify->find->options & DNS_ADBFIND_WANTEVENT) != 0) {
|
||||
dns_zone_idetach(&zone);
|
||||
dns_zone_detach(&zone);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1585,7 +1569,7 @@ notify_find_address(notify_t *notify) {
|
||||
LOCK(&zone->lock);
|
||||
notify_send(notify);
|
||||
UNLOCK(&zone->lock);
|
||||
dns_zone_idetach(&zone);
|
||||
dns_zone_detach(&zone);
|
||||
}
|
||||
|
||||
|
||||
@ -1621,7 +1605,7 @@ notify_send_toaddr(isc_task_t *task, isc_event_t *event) {
|
||||
UNUSED(task);
|
||||
|
||||
LOCK(¬ify->zone->lock);
|
||||
zone_iattach(notify->zone, &zone);
|
||||
zone_attach(notify->zone, &zone);
|
||||
if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0 ||
|
||||
DNS_ZONE_FLAG(notify->zone, DNS_ZONE_F_EXITING)) {
|
||||
result = ISC_R_CANCELED;
|
||||
@ -1640,7 +1624,7 @@ notify_send_toaddr(isc_task_t *task, isc_event_t *event) {
|
||||
if (result != ISC_R_SUCCESS)
|
||||
notify_destroy(notify);
|
||||
UNLOCK(&zone->lock);
|
||||
dns_zone_idetach(&zone);
|
||||
dns_zone_detach(&zone);
|
||||
isc_event_free(&event);
|
||||
}
|
||||
|
||||
@ -1670,7 +1654,7 @@ notify_send(notify_t *notify) {
|
||||
result = notify_create(notify->mctx, &new);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
zone_iattach(notify->zone, &new->zone);
|
||||
zone_attach(notify->zone, &new->zone);
|
||||
ISC_LIST_APPEND(new->zone->notifies, new, link);
|
||||
new->dst = dst;
|
||||
result = notify_send_queue(new);
|
||||
@ -1729,7 +1713,7 @@ dns_zone_notify(dns_zone_t *zone) {
|
||||
result = notify_create(zone->mctx, ¬ify);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup0;
|
||||
dns_zone_iattach(zone, ¬ify->zone);
|
||||
dns_zone_attach(zone, ¬ify->zone);
|
||||
notify->dst = zone->notify[i];
|
||||
if (isc_sockaddr_getport(¬ify->dst) == 0)
|
||||
isc_sockaddr_setport(¬ify->dst, 53); /* XXX */
|
||||
@ -1810,7 +1794,7 @@ dns_zone_notify(dns_zone_t *zone) {
|
||||
dns_rdata_freestruct(&ns);
|
||||
continue;
|
||||
}
|
||||
dns_zone_iattach(zone, ¬ify->zone);
|
||||
dns_zone_attach(zone, ¬ify->zone);
|
||||
result = dns_name_dup(&ns.name, zone->mctx, ¬ify->ns);
|
||||
dns_rdata_freestruct(&ns);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
@ -2050,7 +2034,7 @@ queue_soa_query(dns_zone_t *zone) {
|
||||
cancel_refresh(zone);
|
||||
return;
|
||||
}
|
||||
dns_zone_iattach(zone, &dummy); /*
|
||||
dns_zone_attach(zone, &dummy); /*
|
||||
* Attach so that we won't clean up
|
||||
* until the event is delivered.
|
||||
*/
|
||||
@ -2058,7 +2042,7 @@ queue_soa_query(dns_zone_t *zone) {
|
||||
e->ev_sender = zone;
|
||||
result = isc_ratelimiter_enqueue(zone->zmgr->rl, &e);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
dns_zone_idetach(&dummy);
|
||||
dns_zone_detach(&dummy);
|
||||
isc_event_free(&e);
|
||||
cancel_refresh(zone);
|
||||
}
|
||||
@ -2084,7 +2068,7 @@ soa_query(isc_task_t *task, isc_event_t *event) {
|
||||
if (!DNS_ZONE_FLAG(zone, DNS_ZONE_F_EXITING))
|
||||
cancel_refresh(zone);
|
||||
isc_event_free(&event);
|
||||
dns_zone_idetach(&zone);
|
||||
dns_zone_detach(&zone);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2139,7 +2123,7 @@ soa_query(isc_task_t *task, isc_event_t *event) {
|
||||
}
|
||||
dns_message_destroy(&message);
|
||||
isc_event_free(&event);
|
||||
dns_zone_idetach(&zone);
|
||||
dns_zone_detach(&zone);
|
||||
return;
|
||||
|
||||
cleanup:
|
||||
@ -2151,7 +2135,7 @@ soa_query(isc_task_t *task, isc_event_t *event) {
|
||||
dns_message_destroy(&message);
|
||||
cancel_refresh(zone);
|
||||
isc_event_free(&event);
|
||||
dns_zone_idetach(&zone);
|
||||
dns_zone_detach(&zone);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2167,7 +2151,6 @@ zone_shutdown(isc_task_t *task, isc_event_t *event) {
|
||||
UNUSED(task);
|
||||
REQUIRE(DNS_ZONE_VALID(zone));
|
||||
INSIST(event->ev_type == DNS_EVENT_ZONECONTROL);
|
||||
INSIST(zone->erefs == 0);
|
||||
zone_log(zone, "zone_shutdown", ISC_LOG_DEBUG(3), "shutting down");
|
||||
LOCK(&zone->lock);
|
||||
zone->flags |= DNS_ZONE_F_EXITING;
|
||||
@ -2199,6 +2182,10 @@ zone_shutdown(isc_task_t *task, isc_event_t *event) {
|
||||
if (notify->request != NULL)
|
||||
dns_request_cancel(notify->request);
|
||||
}
|
||||
|
||||
if (zone->view != NULL)
|
||||
dns_view_weakdetach(&zone->view);
|
||||
|
||||
exit_check(zone);
|
||||
}
|
||||
|
||||
@ -2862,13 +2849,13 @@ notify_done(isc_task_t *task, isc_event_t *event) {
|
||||
notify = event->ev_arg;
|
||||
REQUIRE(DNS_NOTIFY_VALID(notify));
|
||||
|
||||
dns_zone_iattach(notify->zone, &zone);
|
||||
dns_zone_attach(notify->zone, &zone);
|
||||
DNS_ENTER;
|
||||
isc_event_free(&event);
|
||||
LOCK(&zone->lock);
|
||||
notify_destroy(notify);
|
||||
UNLOCK(&zone->lock);
|
||||
dns_zone_idetach(&zone);
|
||||
dns_zone_detach(&zone);
|
||||
}
|
||||
|
||||
|
||||
@ -3091,13 +3078,14 @@ xfrdone(dns_zone_t *zone, isc_result_t result) {
|
||||
RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
|
||||
ISC_LIST_UNLINK(zone->zmgr->xfrin_in_progress, zone, statelink);
|
||||
zone->statelist = NULL;
|
||||
zmgr_resume_xfrs(zone->zmgr);
|
||||
if (!DNS_ZONE_FLAG(zone, DNS_ZONE_F_EXITING))
|
||||
zmgr_resume_xfrs(zone->zmgr);
|
||||
RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
|
||||
|
||||
/*
|
||||
* Retry with a different server if necessary.
|
||||
*/
|
||||
if (again)
|
||||
if (again && !DNS_ZONE_FLAG(zone, DNS_ZONE_F_EXITING))
|
||||
queue_soa_query(zone);
|
||||
}
|
||||
|
||||
@ -3226,10 +3214,15 @@ got_transfer_quota(isc_task_t *task, isc_event_t *event) {
|
||||
tsigkey, zone->mctx,
|
||||
zone->zmgr->timermgr, zone->zmgr->socketmgr,
|
||||
zone->task, xfrdone, &zone->xfr);
|
||||
cleanup:
|
||||
/*
|
||||
* Any failure in this function is handled like a failed
|
||||
* zone transfer. This ensures that we get removed from
|
||||
* zmgr->xfrin_in_progress.
|
||||
*/
|
||||
if (result != ISC_R_SUCCESS)
|
||||
xfrdone(zone, result);
|
||||
|
||||
cleanup:
|
||||
|
||||
isc_event_free(&event);
|
||||
|
||||
dns_zone_detach(&zone);
|
||||
@ -3254,6 +3247,7 @@ dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
|
||||
if (zmgr == NULL)
|
||||
return (ISC_R_NOMEMORY);
|
||||
zmgr->mctx = NULL;
|
||||
zmgr->refs = 1;
|
||||
isc_mem_attach(mctx, &zmgr->mctx);
|
||||
zmgr->taskmgr = taskmgr;
|
||||
zmgr->timermgr = timermgr;
|
||||
@ -3339,6 +3333,13 @@ dns_zonemgr_managezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
|
||||
ISC_FALSE),
|
||||
&zone->task);
|
||||
|
||||
/*
|
||||
* Set the task name. The tag will arbitrarily point to one
|
||||
* of the zones sharing the task (in practice, the one
|
||||
* to be managed last).
|
||||
*/
|
||||
isc_task_setname(zone->task, "zone", zone);
|
||||
|
||||
result = isc_timer_create(zmgr->timermgr, isc_timertype_inactive,
|
||||
NULL, NULL,
|
||||
zmgr->task, zone_timer, zone,
|
||||
@ -3346,8 +3347,9 @@ dns_zonemgr_managezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup_task;
|
||||
|
||||
zone->zmgr = zmgr;
|
||||
ISC_LIST_APPEND(zmgr->zones, zone, link);
|
||||
zone->zmgr = zmgr;
|
||||
zmgr->refs++;
|
||||
|
||||
goto unlock;
|
||||
|
||||
@ -3360,24 +3362,41 @@ dns_zonemgr_managezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
|
||||
return (result);
|
||||
}
|
||||
|
||||
static void
|
||||
releasezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
|
||||
/*
|
||||
* Caller to lock zone and zmgr
|
||||
*/
|
||||
ISC_LIST_UNLINK(zmgr->zones, zone, link);
|
||||
zone->zmgr = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
dns_zonemgr_releasezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
|
||||
isc_boolean_t free_now = ISC_FALSE;
|
||||
|
||||
REQUIRE(DNS_ZONE_VALID(zone));
|
||||
|
||||
RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
|
||||
LOCK(&zone->lock);
|
||||
releasezone(zmgr, zone);
|
||||
|
||||
ISC_LIST_UNLINK(zmgr->zones, zone, link);
|
||||
zone->zmgr = NULL;
|
||||
zmgr->refs--;
|
||||
if (zmgr->refs == 0)
|
||||
free_now = ISC_TRUE;
|
||||
|
||||
UNLOCK(&zone->lock);
|
||||
RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
|
||||
|
||||
if (free_now)
|
||||
zonemgr_free(zmgr);
|
||||
}
|
||||
|
||||
void
|
||||
dns_zonemgr_detach(dns_zonemgr_t **zmgrp) {
|
||||
dns_zonemgr_t *zmgr = *zmgrp;
|
||||
isc_boolean_t free_now = ISC_FALSE;
|
||||
|
||||
RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
|
||||
zmgr->refs--;
|
||||
if (zmgr->refs == 0)
|
||||
free_now = ISC_TRUE;
|
||||
RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
|
||||
|
||||
if (free_now)
|
||||
zonemgr_free(zmgr);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
@ -3397,39 +3416,28 @@ dns_zonemgr_forcemaint(dns_zonemgr_t *zmgr) {
|
||||
|
||||
void
|
||||
dns_zonemgr_shutdown(dns_zonemgr_t *zmgr) {
|
||||
if (zmgr->rl)
|
||||
isc_ratelimiter_destroy(&zmgr->rl);
|
||||
isc_ratelimiter_shutdown(zmgr->rl);
|
||||
}
|
||||
|
||||
static void
|
||||
zonemgr_free(dns_zonemgr_t *zmgr) {
|
||||
isc_mem_t *mctx;
|
||||
|
||||
INSIST(zmgr->refs == 0);
|
||||
INSIST(ISC_LIST_EMPTY(zmgr->zones));
|
||||
|
||||
if (zmgr->task != NULL)
|
||||
isc_task_destroy(&zmgr->task);
|
||||
if (zmgr->zonetasks != NULL)
|
||||
isc_taskpool_destroy(&zmgr->zonetasks);
|
||||
}
|
||||
|
||||
void
|
||||
dns_zonemgr_destroy(dns_zonemgr_t **zmgrp) {
|
||||
isc_mem_t *mctx;
|
||||
dns_zonemgr_t *zmgr = *zmgrp;
|
||||
dns_zone_t *zone;
|
||||
|
||||
RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
|
||||
zone = ISC_LIST_HEAD(zmgr->zones);
|
||||
while (zone != NULL) {
|
||||
LOCK(&zone->lock);
|
||||
releasezone(zmgr, zone);
|
||||
UNLOCK(&zone->lock);
|
||||
zone = ISC_LIST_HEAD(zmgr->zones);
|
||||
}
|
||||
RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
|
||||
|
||||
/* Probably done already, but does not hurt to repeat. */
|
||||
dns_zonemgr_shutdown(zmgr);
|
||||
isc_ratelimiter_destroy(&zmgr->rl);
|
||||
|
||||
isc_rwlock_destroy(&zmgr->conflock);
|
||||
isc_rwlock_destroy(&zmgr->rwlock);
|
||||
mctx = zmgr->mctx;
|
||||
isc_mem_put(zmgr->mctx, zmgr, sizeof *zmgr);
|
||||
isc_mem_detach(&mctx);
|
||||
*zmgrp = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
@ -3584,14 +3592,12 @@ zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
|
||||
ISC_LIST_UNLINK(zmgr->waiting_for_xfrin, zone, statelink);
|
||||
ISC_LIST_APPEND(zmgr->xfrin_in_progress, zone, statelink);
|
||||
zone->statelist = &zmgr->xfrin_in_progress;
|
||||
isc_task_send(zone->task, &e);
|
||||
/*
|
||||
* Make sure the zone does not go away before it has processed
|
||||
* the event; in effect, the event is attached to the zone.
|
||||
* We must use erefs rather than irefs because accesses
|
||||
* to irefs are not locked.
|
||||
*/
|
||||
zone->erefs++;
|
||||
zone->refs++;
|
||||
isc_task_send(zone->task, &e);
|
||||
UNLOCK(&zone->lock);
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
|
41
lib/dns/zt.c
41
lib/dns/zt.c
@ -34,7 +34,8 @@ struct dns_zt {
|
||||
isc_rwlock_t rwlock;
|
||||
/* Locked by lock. */
|
||||
isc_uint32_t references;
|
||||
dns_rbt_t *table;
|
||||
dns_rbt_t *table;
|
||||
isc_boolean_t shutdown; /* Has been shut down. */
|
||||
};
|
||||
|
||||
#define ZTMAGIC 0x5a54626cU /* ZTbl */
|
||||
@ -46,6 +47,9 @@ auto_detach(void *, void *);
|
||||
static isc_result_t
|
||||
load(dns_zone_t *zone, void *uap);
|
||||
|
||||
static isc_result_t
|
||||
shutdown(dns_zone_t *zone, void *uap);
|
||||
|
||||
isc_result_t
|
||||
dns_zt_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, dns_zt_t **ztp) {
|
||||
dns_zt_t *zt;
|
||||
@ -58,7 +62,7 @@ dns_zt_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, dns_zt_t **ztp) {
|
||||
return (ISC_R_NOMEMORY);
|
||||
|
||||
zt->table = NULL;
|
||||
result = dns_rbt_create(mctx, auto_detach, NULL, &zt->table);
|
||||
result = dns_rbt_create(mctx, auto_detach, zt, &zt->table);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup_zt;
|
||||
|
||||
@ -74,6 +78,7 @@ dns_zt_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, dns_zt_t **ztp) {
|
||||
zt->mctx = mctx;
|
||||
zt->references = 1;
|
||||
zt->rdclass = rdclass;
|
||||
zt->shutdown = ISC_FALSE;
|
||||
zt->magic = ZTMAGIC;
|
||||
*ztp = zt;
|
||||
|
||||
@ -227,15 +232,37 @@ dns_zt_print(dns_zt_t *zt) {
|
||||
|
||||
isc_result_t
|
||||
dns_zt_load(dns_zt_t *zt, isc_boolean_t stop) {
|
||||
return (dns_zt_apply(zt, stop, load, NULL));
|
||||
isc_result_t result;
|
||||
RWLOCK(&zt->rwlock, isc_rwlocktype_read);
|
||||
result = dns_zt_apply(zt, stop, load, NULL);
|
||||
RWUNLOCK(&zt->rwlock, isc_rwlocktype_read);
|
||||
return (result);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
load(dns_zone_t *zone, void *uap) {
|
||||
uap = uap;
|
||||
UNUSED(uap);
|
||||
return (dns_zone_load(zone));
|
||||
}
|
||||
|
||||
void
|
||||
dns_zt_shutdown(dns_zt_t *zt) {
|
||||
RWLOCK(&zt->rwlock, isc_rwlocktype_write);
|
||||
if (! zt->shutdown) {
|
||||
(void)dns_zt_apply(zt, ISC_FALSE, shutdown, NULL);
|
||||
zt->shutdown = ISC_TRUE;
|
||||
}
|
||||
RWUNLOCK(&zt->rwlock, isc_rwlocktype_write);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
shutdown(dns_zone_t *zone, void *uap) {
|
||||
|
||||
UNUSED(uap);
|
||||
dns_zone_shutdown(zone);
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_zt_apply(dns_zt_t *zt, isc_boolean_t stop,
|
||||
isc_result_t (*action)(dns_zone_t *, void *), void *uap)
|
||||
@ -248,8 +275,6 @@ dns_zt_apply(dns_zt_t *zt, isc_boolean_t stop,
|
||||
REQUIRE(VALID_ZT(zt));
|
||||
REQUIRE(action != NULL);
|
||||
|
||||
RWLOCK(&zt->rwlock, isc_rwlocktype_read);
|
||||
|
||||
dns_rbtnodechain_init(&chain, zt->mctx);
|
||||
result = dns_rbtnodechain_first(&chain, zt->table, NULL, NULL);
|
||||
if (result == ISC_R_NOTFOUND) {
|
||||
@ -276,8 +301,6 @@ dns_zt_apply(dns_zt_t *zt, isc_boolean_t stop,
|
||||
cleanup:
|
||||
dns_rbtnodechain_invalidate(&chain);
|
||||
|
||||
RWUNLOCK(&zt->rwlock, isc_rwlocktype_read);
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
@ -290,6 +313,6 @@ auto_detach(void *data, void *arg) {
|
||||
dns_zone_t *zone = data;
|
||||
|
||||
UNUSED(arg);
|
||||
|
||||
|
||||
dns_zone_detach(&zone);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user