]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Add shutdown signaling for catalog zones
authorAram Sargsyan <aram@isc.org>
Mon, 27 Feb 2023 21:29:24 +0000 (21:29 +0000)
committerArаm Sаrgsyаn <aram@isc.org>
Tue, 28 Feb 2023 09:50:42 +0000 (09:50 +0000)
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
lib/dns/catz.c
lib/dns/include/dns/catz.h
lib/dns/view.c

index 73d8fd1fdead5c1a05978d9c9bc02c6f479f1c1a..6b6f020017cb83fecf7f9cab3d88b01e44cea1ed 100644 (file)
@@ -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);
index 4edc8c80ecb2cc14613b021e83315e375780620d..9b48acdde8de0ecc74ab646ba8cb432538f00f8e 100644 (file)
@@ -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,28 +973,45 @@ 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_task_destroy(&catzs->updater);
+       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_task_destroy(&catzs->updater);
-       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
@@ -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);
 
        /*
index 049d76e622c2ff8a07c513331eb16541e15403ee..5c6282b66965850754a1c94ca9ff661dd432aac5 100644 (file)
@@ -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) \
index 755f69c8e7ff0a018fae2eb47ce4b69fad939edf..7f4280c5632d51969440532e07694e0feb77d2f9 100644 (file)
@@ -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) {