]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
save effective configuration as text
authorEvan Hunt <each@isc.org>
Wed, 12 Nov 2025 02:50:23 +0000 (18:50 -0800)
committerColin Vidal <colin@isc.org>
Wed, 12 Nov 2025 10:36:07 +0000 (11:36 +0100)
the effective configuration tree is now detached if allow-new-zones
or catalog-zones aren't enabled in any views. this reduces memory
consumption while still allowing "rndc showconf -effective" to work.

bin/named/include/named/server.h
bin/named/server.c

index 8e866f1bc8e20617f90fa4191aa69d41a008814d..a716110e8344a43e2ae530e84d77bd5c9f95b46e 100644 (file)
@@ -110,7 +110,8 @@ struct named_server {
        isc_signal_t *sigusr1;
 
        cfg_aclconfctx_t *aclctx;
-       isc_buffer_t     *userconf;
+       isc_buffer_t     *userconftext;
+       isc_buffer_t     *effectivetext;
        cfg_obj_t        *effectiveconfig;
 };
 
index 6176f2334aef4a06b95f6545aa9fb95c586ad1cd..5b1bba785d9be6e76f115839fa8f019cfb363da8 100644 (file)
@@ -7690,7 +7690,7 @@ configure_newzones(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
                      ISC_LOG_DEBUG(1), "apply_configuration: %s", __func__);
 
 static isc_result_t
-create_views(cfg_obj_t *config, dns_viewlist_t *viewlist) {
+create_views(cfg_obj_t *config, dns_viewlist_t *viewlist, bool *nzp) {
        isc_result_t result = ISC_R_SUCCESS;
        const cfg_obj_t *bindview = NULL;
        const cfg_obj_t *views = NULL;
@@ -7724,6 +7724,9 @@ create_views(cfg_obj_t *config, dns_viewlist_t *viewlist) {
 
                CHECK(setup_newzones(view, config, vconfig));
                explicitviews = true;
+               if (view->newzone.allowed) {
+                       *nzp = true;
+               }
                dns_view_detach(&view);
        }
 
@@ -7736,6 +7739,9 @@ create_views(cfg_obj_t *config, dns_viewlist_t *viewlist) {
                INSIST(view != NULL);
 
                CHECK(setup_newzones(view, config, NULL));
+               if (view->newzone.allowed) {
+                       *nzp = true;
+               }
                dns_view_detach(&view);
        }
 
@@ -7925,7 +7931,8 @@ configure_kasplist(const cfg_obj_t *config, dns_kasplist_t *kasplist,
 
 static isc_result_t
 apply_configuration(cfg_obj_t *effectiveconfig, cfg_obj_t *bindkeys,
-                   named_server_t *server, bool first_time) {
+                   named_server_t *server, bool first_time,
+                   bool *newzones_allowed) {
        const cfg_obj_t *maps[3];
        const cfg_obj_t *obj = NULL;
        const cfg_obj_t *options = NULL;
@@ -8000,7 +8007,7 @@ apply_configuration(cfg_obj_t *effectiveconfig, cfg_obj_t *bindkeys,
                goto cleanup_kasplist;
        }
 
-       result = create_views(effectiveconfig, &viewlist);
+       result = create_views(effectiveconfig, &viewlist, newzones_allowed);
        if (result != ISC_R_SUCCESS) {
                goto cleanup_viewlist;
        }
@@ -8986,14 +8993,6 @@ apply_configuration(cfg_obj_t *effectiveconfig, cfg_obj_t *bindkeys,
         */
        named_g_defaultconfigtime = isc_time_now();
 
-       /*
-        * Save the current effective configuration
-        */
-       if (server->effectiveconfig != NULL) {
-               cfg_obj_detach(&server->effectiveconfig);
-       }
-       cfg_obj_attach(effectiveconfig, &server->effectiveconfig);
-
        isc_loopmgr_resume();
        exclusive = false;
 
@@ -9003,8 +9002,8 @@ apply_configuration(cfg_obj_t *effectiveconfig, cfg_obj_t *bindkeys,
        }
 
        /* Configure the statistics channel(s) */
-       result = named_statschannels_configure(
-               named_g_server, server->effectiveconfig, server->aclctx);
+       result = named_statschannels_configure(named_g_server, effectiveconfig,
+                                              server->aclctx);
        if (result != ISC_R_SUCCESS) {
                isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER,
                              ISC_LOG_ERROR,
@@ -9017,8 +9016,7 @@ apply_configuration(cfg_obj_t *effectiveconfig, cfg_obj_t *bindkeys,
         * Bind the control port(s).
         */
        result = named_controls_configure(named_g_server->controls,
-                                         server->effectiveconfig,
-                                         server->aclctx);
+                                         effectiveconfig, server->aclctx);
        if (result != ISC_R_SUCCESS) {
                isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER,
                              ISC_LOG_ERROR, "binding control channel(s): %s",
@@ -9108,7 +9106,6 @@ cleanup_aclctx:
                      ISC_LOG_DEBUG(1), "apply_configuration: %s",
                      isc_result_totext(result));
 
-       cfg_obj_detach(&effectiveconfig);
        return result;
 }
 
@@ -9117,11 +9114,8 @@ load_configuration(named_server_t *server, bool first_time) {
        isc_result_t result;
        cfg_obj_t *config = NULL, *effective = NULL;
        cfg_obj_t *bindkeys = NULL, *builtin = NULL;
-       ns_dzarg_t dzarg = {
-               .magic = DZARG_MAGIC,
-               .result = ISC_R_SUCCESS,
-               .text = &server->userconf,
-       };
+       ns_dzarg_t dzarg;
+       bool newzones_allowed = false;
 
        isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER,
                      ISC_LOG_DEBUG(1), "load_configuration");
@@ -9163,17 +9157,51 @@ load_configuration(named_server_t *server, bool first_time) {
        effective = cfg_effective_config(config, builtin);
 
        /*
-        * Save the user configuration for later reference.
-        * We keep it in text format to save space; we won't need
-        * to access it as a tree again after this.
+        * Save the user and effective configurations in text format,
+        * to display with "rndc showconf". (Text takes up less memory
+        * than an object tree.)
+        *
+        * Also save the effective configuration as an object tree, if
+        * "allow-new-zones" or catalog zones are in use. That takes
+        * more memory but avoids the need to re-parse the configuration
+        * when zone changes are made.
         */
-       if (server->userconf != NULL) {
-               isc_buffer_free(&server->userconf);
+
+       if (server->effectiveconfig != NULL) {
+               cfg_obj_detach(&server->effectiveconfig);
+       }
+
+       if (server->effectivetext != NULL) {
+               isc_buffer_free(&server->effectivetext);
        }
-       isc_buffer_allocate(isc_g_mctx, &server->userconf, BUFSIZ);
+       isc_buffer_allocate(isc_g_mctx, &server->effectivetext, BUFSIZ);
+
+       if (server->userconftext != NULL) {
+               isc_buffer_free(&server->userconftext);
+       }
+       isc_buffer_allocate(isc_g_mctx, &server->userconftext, BUFSIZ);
+
+       dzarg = (ns_dzarg_t){
+               .magic = DZARG_MAGIC,
+               .text = &server->userconftext,
+       };
        cfg_printx(config, 0, emit_text, &dzarg);
 
-       result = apply_configuration(effective, bindkeys, server, first_time);
+       dzarg = (ns_dzarg_t){
+               .magic = DZARG_MAGIC,
+               .text = &server->effectivetext,
+       };
+       cfg_printx(effective, 0, emit_text, &dzarg);
+
+       /*
+        * And finally we apply the effective configuration.
+        */
+       result = apply_configuration(effective, bindkeys, server, first_time,
+                                    &newzones_allowed);
+       if (newzones_allowed) {
+               server->effectiveconfig = effective;
+               effective = NULL;
+       }
 
 cleanup:
        if (bindkeys != NULL) {
@@ -9185,6 +9213,9 @@ cleanup:
        if (builtin != NULL) {
                cfg_obj_detach(&builtin);
        }
+       if (effective != NULL) {
+               cfg_obj_detach(&effective);
+       }
 
        return result;
 }
@@ -9807,8 +9838,12 @@ named_server_destroy(named_server_t **serverp) {
                isc_tlsctx_cache_detach(&server->tlsctx_client_cache);
        }
 
-       if (server->userconf != NULL) {
-               isc_buffer_free(&server->userconf);
+       if (server->userconftext != NULL) {
+               isc_buffer_free(&server->userconftext);
+       }
+
+       if (server->effectivetext != NULL) {
+               isc_buffer_free(&server->effectivetext);
        }
 
        if (server->effectiveconfig != NULL) {
@@ -13902,14 +13937,8 @@ cleanup:
 isc_result_t
 named_server_showconf(named_server_t *server, isc_lex_t *lex,
                      isc_buffer_t **text) {
-       isc_result_t result, tresult;
+       isc_result_t result = ISC_R_SUCCESS;
        const char *arg = NULL;
-       cfg_obj_t *config = NULL;
-       ns_dzarg_t dzarg = {
-               .magic = DZARG_MAGIC,
-               .result = ISC_R_SUCCESS,
-               .text = text,
-       };
 
        REQUIRE(text != NULL && *text != NULL);
 
@@ -13920,37 +13949,32 @@ named_server_showconf(named_server_t *server, isc_lex_t *lex,
        if (arg == NULL) {
                return ISC_R_UNEXPECTEDEND;
        }
+
        if (strcasecmp(arg, "-user") == 0) {
-               putmem(text, isc_buffer_base(server->userconf),
-                      isc_buffer_usedlength(server->userconf));
-               result = ISC_R_SUCCESS;
-               goto cleanup;
-       } else if (strcasecmp(arg, "-builtin") == 0) {
-               named_config_parsedefaults(&config);
+               result = putmem(text, isc_buffer_base(server->userconftext),
+                               isc_buffer_usedlength(server->userconftext));
        } else if (strcasecmp(arg, "-effective") == 0) {
-               cfg_obj_attach(server->effectiveconfig, &config);
+               result = putmem(text, isc_buffer_base(server->effectivetext),
+                               isc_buffer_usedlength(server->effectivetext));
+       } else if (strcasecmp(arg, "-builtin") == 0) {
+               cfg_obj_t *config = NULL;
+               ns_dzarg_t dzarg = {
+                       .magic = DZARG_MAGIC,
+                       .text = text,
+               };
+               CHECK(named_config_parsedefaults(&config));
+               cfg_printx(config, 0, emit_text, &dzarg);
+               cfg_obj_detach(&config);
+               result = dzarg.result;
        } else {
-               CHECK(DNS_R_SYNTAX);
-       }
-
-       if (config == NULL) {
-               result = ISC_R_NOTFOUND;
-               TCHECK(putstr(text, "configuration data not found.\n"));
-               goto cleanup;
+               result = DNS_R_SYNTAX;
        }
 
-       cfg_printx(config, 0, emit_text, &dzarg);
-       result = dzarg.result;
-
 cleanup:
        if (isc_buffer_usedlength(*text) > 0) {
                (void)putnull(text);
        }
 
-       if (config != NULL) {
-               cfg_obj_detach(&config);
-       }
-
        return result;
 }