]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
DROP: batch zone insert
authorAlessio Podda <alessio@isc.org>
Tue, 7 Apr 2026 17:52:22 +0000 (19:52 +0200)
committerAlessio Podda <alessio@isc.org>
Tue, 7 Apr 2026 17:52:22 +0000 (19:52 +0200)
bin/named/server.c
lib/dns/include/dns/view.h
lib/dns/include/dns/zt.h
lib/dns/view.c
lib/dns/zone.c
lib/dns/zt.c

index 39a3df97569902477d9a84dce4405f252f34e2fd..38aae1805ae47e54419830b6bf378427ee88909a 100644 (file)
@@ -457,7 +457,7 @@ configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig,
               const cfg_obj_t *vconfig, dns_view_t *view,
               dns_viewlist_t *viewlist, dns_kasplist_t *kasplist,
               cfg_aclconfctx_t *aclconf, bool added, bool old_rpz_ok,
-              bool is_catz_member, bool modify);
+              bool is_catz_member, bool modify, dns_zone_t **zonep);
 
 static void
 configure_zone_setviewcommit(isc_result_t result, const cfg_obj_t *zconfig,
@@ -2328,7 +2328,7 @@ catz_addmodzone_cb(void *arg) {
                cz->cbd->server->effectiveconfig, zoneobj,
                view->newzone.vconfig, view, &cz->cbd->server->viewlist,
                &cz->cbd->server->kasplist, cz->cbd->server->aclctx, true,
-               false, true, cz->mod);
+               false, true, cz->mod, NULL);
        dns_view_freeze(view);
        isc_loopmgr_resume();
 
@@ -2594,7 +2594,7 @@ catz_reconfigure(dns_catz_entry_t *entry, void *arg1, void *arg2) {
        result = configure_zone(
                data->config, zoneobj, view->newzone.vconfig, view,
                &data->cbd->server->viewlist, &data->cbd->server->kasplist,
-               data->cbd->server->aclctx, true, false, true, true);
+               data->cbd->server->aclctx, true, false, true, true, NULL);
        if (result != ISC_R_SUCCESS) {
                isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER,
                              ISC_LOG_ERROR,
@@ -3638,6 +3638,8 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config,
        const char *str = NULL;
        const char *cachename = NULL;
        dns_order_t *order = NULL;
+       dns_zone_t **pending = NULL;
+       unsigned int npending = 0, pending_cap = 0;
        unsigned int resopts = 0;
        dns_zone_t *zone = NULL;
        uint32_t clients_per_query, max_clients_per_query;
@@ -3723,10 +3725,33 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config,
         */
        CFG_LIST_FOREACH(zonelist, element) {
                const cfg_obj_t *zconfig = cfg_listelt_value(element);
+               dns_zone_t *newzone = NULL;
                CHECK(configure_zone(config, zconfig, vconfig, view, viewlist,
                                     kasplist, aclctx, false, old_rpz_ok, false,
-                                    false));
+                                    false, &newzone));
                zone_element_latest = element;
+               if (newzone != NULL) {
+                       if (npending == pending_cap) {
+                               pending_cap = (pending_cap == 0) ? 256
+                                                                : pending_cap * 2;
+                               pending = isc_mem_creget(mctx, pending,
+                                                       npending, pending_cap,
+                                                       sizeof(*pending));
+                       }
+                       pending[npending++] = newzone;
+               }
+       }
+
+       if (npending > 0) {
+               dns_view_addzone_batch(view, pending, npending);
+               for (unsigned int zi = 0; zi < npending; zi++) {
+                       dns_zone_detach(&pending[zi]);
+               }
+               npending = 0;
+       }
+       if (pending != NULL) {
+               isc_mem_cput(mctx, pending, pending_cap, sizeof(*pending));
+               pending = NULL;
        }
 
        /*
@@ -5360,6 +5385,14 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config,
        result = ISC_R_SUCCESS;
 
 cleanup:
+       if (pending != NULL) {
+               for (unsigned int zi = 0; zi < npending; zi++) {
+                       dns_zone_detach(&pending[zi]);
+               }
+               isc_mem_cput(mctx, pending, pending_cap, sizeof(*pending));
+               pending = NULL;
+       }
+
        /*
         * Revert to the old view if there was an error.
         */
@@ -5865,7 +5898,7 @@ configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig,
               const cfg_obj_t *vconfig, dns_view_t *view,
               dns_viewlist_t *viewlist, dns_kasplist_t *kasplist,
               cfg_aclconfctx_t *aclctx, bool added, bool old_rpz_ok,
-              bool is_catz_member, bool modify) {
+              bool is_catz_member, bool modify, dns_zone_t **zonep) {
        dns_view_t *pview = NULL; /* Production view */
        dns_zone_t *zone = NULL;  /* New or reused zone */
        dns_zone_t *raw = NULL;   /* New or reused raw zone */
@@ -5957,7 +5990,11 @@ configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig,
                        CLEANUP(ISC_R_FAILURE);
                }
 
-               CHECK(dns_view_addzone(view, zone));
+               if (zonep != NULL) {
+                       dns_zone_attach(zone, zonep);
+               } else {
+                       CHECK(dns_view_addzone(view, zone));
+               }
                dns_zone_detach(&zone);
 
                /*
@@ -6063,7 +6100,7 @@ configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig,
                goto cleanup;
        }
 
-       if (!modify) {
+       if (!modify && zonep == NULL) {
                /*
                 * Check for duplicates in the new zone table.
                 */
@@ -6241,7 +6278,11 @@ configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig,
         * Add the zone to its view in the new view list.
         */
        if (!modify) {
-               CHECK(dns_view_addzone(view, zone));
+               if (zonep != NULL) {
+                       dns_zone_attach(zone, zonep);
+               } else {
+                       CHECK(dns_view_addzone(view, zone));
+               }
        }
 
        if (zone_is_catz) {
@@ -7327,7 +7368,7 @@ configure_newzone(const cfg_obj_t *zconfig, cfg_obj_t *config,
                  cfg_aclconfctx_t *aclctx, dns_kasplist_t *kasplist) {
        return configure_zone(config, zconfig, vconfig, view,
                              &named_g_server->viewlist, kasplist, aclctx, true,
-                             false, false, false);
+                             false, false, false, NULL);
 }
 
 /*%
@@ -12098,7 +12139,7 @@ do_addzone(named_server_t *server, dns_view_t *view, dns_name_t *name,
        result = configure_zone(server->effectiveconfig, zoneobj,
                                view->newzone.vconfig, view, &server->viewlist,
                                &server->kasplist, server->aclctx, true, false,
-                               false, false);
+                               false, false, NULL);
        dns_view_freeze(view);
 
        isc_loopmgr_resume();
@@ -12241,7 +12282,7 @@ do_modzone(named_server_t *server, dns_view_t *view, dns_name_t *name,
        result = configure_zone(server->effectiveconfig, zoneobj,
                                view->newzone.vconfig, view, &server->viewlist,
                                &server->kasplist, server->aclctx, false, false,
-                               false, true);
+                               false, true, NULL);
        dns_view_freeze(view);
 
        isc_loopmgr_resume();
index 296a3ce273dcf5f9874aac9af3232a0664117001..8ef568499b17613ee9e032d7464e26b7f5476d4d 100644 (file)
@@ -496,6 +496,20 @@ dns_view_addzone(dns_view_t *view, dns_zone_t *zone);
  *\li  'zone' is a valid zone.
  */
 
+void
+dns_view_addzone_batch(dns_view_t *view, dns_zone_t **zones,
+                      unsigned int count);
+/*%<
+ * Add multiple zones to 'view' in a single QP transaction.
+ * Duplicate zones are silently ignored.
+ *
+ * Requires:
+ *
+ *\li  'view' is a valid, unfrozen view.
+ *
+ *\li  'zones' is non-NULL.
+ */
+
 isc_result_t
 dns_view_delzone(dns_view_t *view, dns_zone_t *zone);
 /*%<
index 1284143ec2cb7b50c2ce68c2c5819be575c9dc49..315650a6db2842a1ed4d5957e2a93a9440494bf1 100644 (file)
@@ -65,6 +65,17 @@ dns_zt_mount(dns_zt_t *zt, dns_zone_t *zone);
  * \li #ISC_R_EXISTS
  */
 
+void
+dns_zt_mount_batch(dns_zt_t *zt, dns_zone_t **zones, unsigned int count);
+/*%<
+ * Mounts multiple zones on the zone table in a single QP transaction.
+ * Duplicate zones are silently ignored.
+ *
+ * Requires:
+ * \li 'zt' to be valid
+ * \li 'zones' to be non-NULL
+ */
+
 isc_result_t
 dns_zt_unmount(dns_zt_t *zt, dns_zone_t *zone);
 /*%<
index d31d17161ad0b57d00d92e364d814660a4cc6200..8f25efb4309944ca880fd70701c8206fe8226548 100644 (file)
@@ -695,9 +695,33 @@ dns_view_addzone(dns_view_t *view, dns_zone_t *zone) {
        }
        rcu_read_unlock();
 
+       if (result == ISC_R_SUCCESS) {
+               dns_view_sfd_add(view, dns_zone_getorigin(zone));
+       }
+
        return result;
 }
 
+void
+dns_view_addzone_batch(dns_view_t *view, dns_zone_t **zones,
+                      unsigned int count) {
+       dns_zt_t *zonetable = NULL;
+
+       REQUIRE(DNS_VIEW_VALID(view));
+       REQUIRE(!view->frozen);
+
+       rcu_read_lock();
+       zonetable = rcu_dereference(view->zonetable);
+       if (zonetable != NULL) {
+               dns_zt_mount_batch(zonetable, zones, count);
+       }
+       rcu_read_unlock();
+
+       for (unsigned int i = 0; i < count; i++) {
+               dns_view_sfd_add(view, dns_zone_getorigin(zones[i]));
+       }
+}
+
 isc_result_t
 dns_view_delzone(dns_view_t *view, dns_zone_t *zone) {
        isc_result_t result;
@@ -716,6 +740,10 @@ dns_view_delzone(dns_view_t *view, dns_zone_t *zone) {
        }
        rcu_read_unlock();
 
+       if (result == ISC_R_SUCCESS) {
+               dns_view_sfd_del(view, dns_zone_getorigin(zone));
+       }
+
        return result;
 }
 
index 41bc99a0f58484d173647445f62ab90b9758cba9..4db671527e365813f3f7a23600cf70d3241b2278 100644 (file)
@@ -1569,11 +1569,9 @@ dns_zone_setview_helper(dns_zone_t *zone, dns_view_t *view) {
 
        INSIST(zone != zone->raw);
        if (zone->view != NULL) {
-               dns_view_sfd_del(zone->view, &zone->origin);
                dns_view_weakdetach(&zone->view);
        }
        dns_view_weakattach(view, &zone->view);
-       dns_view_sfd_add(view, &zone->origin);
 
        if (zone->strviewname != NULL) {
                isc_mem_free(zone->mctx, zone->strviewname);
index 7342fa2f79e9b10c4d08a89577a047075197a881..98520ef4b2145f692bec9cebc704ea7bbc16330f 100644 (file)
@@ -148,6 +148,21 @@ dns_zt_mount(dns_zt_t *zt, dns_zone_t *zone) {
        return result;
 }
 
+void
+dns_zt_mount_batch(dns_zt_t *zt, dns_zone_t **zones, unsigned int count) {
+       dns_qp_t *qp = NULL;
+
+       REQUIRE(VALID_ZT(zt));
+       REQUIRE(zones != NULL);
+
+       dns_qpmulti_write(zt->multi, &qp);
+       for (unsigned int i = 0; i < count; i++) {
+               (void)dns_qp_insert(qp, zones[i], 0);
+       }
+       dns_qp_compact(qp, DNS_QPGC_ALL);
+       dns_qpmulti_commit(zt->multi, &qp);
+}
+
 isc_result_t
 dns_zt_unmount(dns_zt_t *zt, dns_zone_t *zone) {
        isc_result_t result;