From ed942f55366526134ff56f98cd9311dbcc49ccd7 Mon Sep 17 00:00:00 2001 From: Aram Sargsyan Date: Mon, 27 Feb 2023 21:29:24 +0000 Subject: [PATCH] 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. (cherry picked from commit 246b7084d6ecb692643da464e734d719495ae63f) --- bin/named/server.c | 1 + lib/dns/catz.c | 70 +++++++++++++++++++++++++++++--------- lib/dns/include/dns/catz.h | 10 ++++++ lib/dns/view.c | 2 ++ 4 files changed, 67 insertions(+), 16 deletions(-) diff --git a/bin/named/server.c b/bin/named/server.c index 73d8fd1fde..6b6f020017 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -3189,6 +3189,7 @@ configure_catz(dns_view_t *view, dns_view_t *pview, const cfg_obj_t *config, } if (old != NULL) { + dns_catz_shutdown_catzs(view->catzs); dns_catz_detach_catzs(&view->catzs); dns_catz_attach_catzs(pview->catzs, &view->catzs); dns_catz_detach_catzs(&pview->catzs); diff --git a/lib/dns/catz.c b/lib/dns/catz.c index 4edc8c80ec..9b48acdde8 100644 --- a/lib/dns/catz.c +++ b/lib/dns/catz.c @@ -127,6 +127,7 @@ struct dns_catz_zones { isc_timermgr_t *timermgr; dns_view_t *view; isc_task_t *updater; + atomic_bool shuttingdown; }; void @@ -889,6 +890,22 @@ 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) { + isc_result_t result; + + /* Don't wait for timer to trigger for shutdown */ + result = isc_timer_reset(catz->updatetimer, + isc_timertype_inactive, NULL, NULL, + true); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + } + + dns_catz_detach_catz(&catz); +} + static void dns__catz_zone_destroy(dns_catz_zone_t *catz) { isc_mem_t *mctx = catz->catzs->mctx; @@ -956,22 +973,9 @@ dns__catz_zone_destroy(dns_catz_zone_t *catz) { static void dns__catz_zones_destroy(dns_catz_zones_t *catzs) { - 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); - result = isc_ht_iter_delcurrent_next(iter); - dns_catz_detach_catz(&zone); - } - INSIST(result == ISC_R_NOMORE); - isc_ht_iter_destroy(&iter); - INSIST(isc_ht_count(catzs->zones) == 0); - isc_ht_destroy(&catzs->zones); - } + REQUIRE(atomic_load(&catzs->shuttingdown)); + REQUIRE(catzs->zones == NULL); + catzs->magic = 0; isc_task_destroy(&catzs->updater); isc_mutex_destroy(&catzs->lock); @@ -980,6 +984,36 @@ dns__catz_zones_destroy(dns_catz_zones_t *catzs) { 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 *catz = NULL; + isc_ht_iter_current(iter, (void **)&catz); + result = isc_ht_iter_delcurrent_next(iter); + 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); + } + UNLOCK(&catzs->lock); +} + #ifdef DNS_CATZ_TRACE ISC_REFCOUNT_TRACE_IMPL(dns_catz_zone, dns__catz_zone_destroy); ISC_REFCOUNT_TRACE_IMPL(dns_catz_zones, dns__catz_zones_destroy); @@ -2120,6 +2154,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); /* diff --git a/lib/dns/include/dns/catz.h b/lib/dns/include/dns/catz.h index 049d76e622..5c6282b669 100644 --- a/lib/dns/include/dns/catz.h +++ b/lib/dns/include/dns/catz.h @@ -437,6 +437,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) \ diff --git a/lib/dns/view.c b/lib/dns/view.c index 755f69c8e7..7f4280c563 100644 --- a/lib/dns/view.c +++ b/lib/dns/view.c @@ -423,6 +423,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; @@ -680,6 +681,7 @@ view_flushanddetach(dns_view_t **viewp, bool flush) { } } if (view->catzs != NULL) { + dns_catz_shutdown_catzs(view->catzs); dns_catz_detach_catzs(&view->catzs); } if (view->ntatable_priv != NULL) {