2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-31 06:25:31 +00:00

Add shutdown signaling for catalog zones

This change should make sure that catalog zone update processing
doesn't happen when the catalog zone is being shut down. This
should help avoid races when offloading the catalog zone updates
in the follow-up commit.
This commit is contained in:
Aram Sargsyan
2023-02-21 21:14:44 +00:00
committed by Ondřej Surý
parent 94ee6f6672
commit 246b7084d6
3 changed files with 77 additions and 10 deletions

View File

@@ -69,6 +69,7 @@ struct dns_catz_entry {
*/
struct dns_catz_zone {
unsigned int magic;
isc_loop_t *loop;
dns_name_t name;
dns_catz_zones_t *catzs;
dns_rdata_t soa;
@@ -101,6 +102,8 @@ struct dns_catz_zone {
static void
dns__catz_timer_start(dns_catz_zone_t *catz);
static void
dns__catz_timer_stop(void *arg);
static isc_result_t
catz_process_zones_entry(dns_catz_zone_t *catz, dns_rdataset_t *value,
@@ -126,6 +129,7 @@ struct dns_catz_zones {
dns_catz_zonemodmethods_t *zmm;
isc_loopmgr_t *loopmgr;
dns_view_t *view;
atomic_bool shuttingdown;
};
void
@@ -820,11 +824,26 @@ dns__catz_timer_start(dns_catz_zone_t *catz) {
isc_interval_set(&interval, 0, 0);
}
isc_timer_create(isc_loop_current(catz->catzs->loopmgr),
dns_catz_update_action, catz, &catz->updatetimer);
catz->loop = isc_loop_current(catz->catzs->loopmgr);
isc_timer_create(catz->loop, dns_catz_update_action, catz,
&catz->updatetimer);
isc_timer_start(catz->updatetimer, isc_timertype_once, &interval);
}
static void
dns__catz_timer_stop(void *arg) {
dns_catz_zone_t *catz = arg;
REQUIRE(DNS_CATZ_ZONE_VALID(catz));
isc_timer_stop(catz->updatetimer);
isc_timer_destroy(&catz->updatetimer);
catz->loop = NULL;
dns_catz_unref_catzs(catz->catzs);
dns_catz_detach_catz(&catz);
}
isc_result_t
dns_catz_add_zone(dns_catz_zones_t *catzs, const dns_name_t *name,
dns_catz_zone_t **catzp) {
@@ -888,6 +907,20 @@ dns_catz_get_zone(dns_catz_zones_t *catzs, const dns_name_t *name) {
return (found);
}
static void
dns__catz_shutdown(dns_catz_zone_t *catz) {
/* lock must be locked */
if (catz->updatetimer != NULL) {
/* Don't wait for timer to trigger for shutdown */
INSIST(catz->loop != NULL);
dns_catz_ref_catzs(catz->catzs);
isc_async_run(catz->loop, dns__catz_timer_stop, catz);
} else {
dns_catz_detach_catz(&catz);
}
}
static void
dns__catz_zone_destroy(dns_catz_zone_t *catz) {
isc_mem_t *mctx = catz->catzs->mctx;
@@ -959,27 +992,44 @@ dns__catz_zone_destroy(dns_catz_zone_t *catz) {
static void
dns__catz_zones_destroy(dns_catz_zones_t *catzs) {
REQUIRE(atomic_load(&catzs->shuttingdown));
REQUIRE(catzs->zones == NULL);
catzs->magic = 0;
isc_mutex_destroy(&catzs->lock);
isc_refcount_destroy(&catzs->references);
isc_mem_putanddetach(&catzs->mctx, catzs, sizeof(*catzs));
}
void
dns_catz_shutdown_catzs(dns_catz_zones_t *catzs) {
REQUIRE(DNS_CATZ_ZONES_VALID(catzs));
if (!atomic_compare_exchange_strong(&catzs->shuttingdown,
&(bool){ false }, true))
{
return;
}
LOCK(&catzs->lock);
if (catzs->zones != NULL) {
isc_ht_iter_t *iter = NULL;
isc_result_t result;
isc_ht_iter_create(catzs->zones, &iter);
for (result = isc_ht_iter_first(iter); result == ISC_R_SUCCESS;)
{
dns_catz_zone_t *zone = NULL;
isc_ht_iter_current(iter, (void **)&zone);
dns_catz_zone_t *catz = NULL;
isc_ht_iter_current(iter, (void **)&catz);
result = isc_ht_iter_delcurrent_next(iter);
dns_catz_detach_catz(&zone);
dns__catz_shutdown(catz);
}
INSIST(result == ISC_R_NOMORE);
isc_ht_iter_destroy(&iter);
INSIST(isc_ht_count(catzs->zones) == 0);
isc_ht_destroy(&catzs->zones);
}
catzs->magic = 0;
isc_mutex_destroy(&catzs->lock);
isc_refcount_destroy(&catzs->references);
isc_mem_putanddetach(&catzs->mctx, catzs, sizeof(*catzs));
UNLOCK(&catzs->lock);
}
#ifdef DNS_CATZ_TRACE
@@ -1991,6 +2041,7 @@ dns_catz_update_action(void *arg) {
dns_catz_update_from_db(catz->db, catz->catzs);
isc_timer_stop(catz->updatetimer);
isc_timer_destroy(&catz->updatetimer);
catz->loop = NULL;
result = isc_time_now(&catz->lastupdated);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
UNLOCK(&catz->catzs->lock);
@@ -2083,6 +2134,10 @@ dns_catz_update_from_db(dns_db_t *db, dns_catz_zones_t *catzs) {
REQUIRE(DNS_DB_VALID(db));
REQUIRE(DNS_CATZ_ZONES_VALID(catzs));
if (atomic_load(&catzs->shuttingdown)) {
return;
}
dns_name_format(&db->origin, bname, DNS_NAME_FORMATSIZE);
/*

View File

@@ -438,6 +438,16 @@ dns_catz_get_iterator(dns_catz_zone_t *catz, isc_ht_iter_t **itp);
*
*/
void
dns_catz_shutdown_catzs(dns_catz_zones_t *catzs);
/*%<
* Shut down the catalog zones.
*
* Requires:
* \li 'catzs' is a valid dns_catz_zones_t.
*
*/
#ifdef DNS_CATZ_TRACE
/* Compatibility macros */
#define dns_catz_attach_catz(catz, catzp) \

View File

@@ -300,6 +300,7 @@ destroy(dns_view_t *view) {
dns_rpz_detach_rpzs(&view->rpzs);
}
if (view->catzs != NULL) {
dns_catz_shutdown_catzs(view->catzs);
dns_catz_detach_catzs(&view->catzs);
}
for (dlzdb = ISC_LIST_HEAD(view->dlz_searched); dlzdb != NULL;
@@ -548,6 +549,7 @@ dns_view_detach(dns_view_t **viewp) {
}
}
if (view->catzs != NULL) {
dns_catz_shutdown_catzs(view->catzs);
dns_catz_detach_catzs(&view->catzs);
}
if (view->ntatable_priv != NULL) {