From 870b7329f838cd09a58d5434ae4dc655353c41ff Mon Sep 17 00:00:00 2001 From: Colin Vidal Date: Mon, 3 Nov 2025 17:24:22 +0100 Subject: [PATCH 1/6] parser: add cfg_string_create() API The parser has a static function `create_string()` used internally. But there was duplicate code to create a string node in `namedconf.c`. Instead of implementing the same logic twice, `create_string()` is now publicly exposed as `cfg_string_create()`. --- lib/isccfg/include/isccfg/grammar.h | 4 ++++ lib/isccfg/namedconf.c | 10 +--------- lib/isccfg/parser.c | 22 ++++++++++------------ 3 files changed, 15 insertions(+), 21 deletions(-) diff --git a/lib/isccfg/include/isccfg/grammar.h b/lib/isccfg/include/isccfg/grammar.h index 460afb1087..bee2a22469 100644 --- a/lib/isccfg/include/isccfg/grammar.h +++ b/lib/isccfg/include/isccfg/grammar.h @@ -382,6 +382,10 @@ void cfg_obj_create(isc_mem_t *mctx, cfg_obj_t *file, size_t line, const cfg_type_t *type, cfg_obj_t **ret); +void +cfg_string_create(cfg_parser_t *pctx, const char *contents, + const cfg_type_t *type, cfg_obj_t **ret); + void cfg_print_rawuint(cfg_printer_t *pctx, unsigned int u); diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c index 69cff0317f..455ef114ae 100644 --- a/lib/isccfg/namedconf.c +++ b/lib/isccfg/namedconf.c @@ -406,15 +406,7 @@ parse_updatepolicy(cfg_parser_t *pctx, const cfg_type_t *type, if (pctx->token.type == isc_tokentype_string && strcasecmp(TOKEN_STRING(pctx), "local") == 0) { - cfg_obj_t *obj = NULL; - cfg_obj_create(pctx->mctx, cfg_parser_currentfile(pctx), - pctx->line, &cfg_type_ustring, &obj); - obj->value.string.length = strlen("local"); - obj->value.string.base = - isc_mem_get(pctx->mctx, obj->value.string.length + 1); - memmove(obj->value.string.base, "local", 5); - obj->value.string.base[5] = '\0'; - *ret = obj; + cfg_string_create(pctx, "local", &cfg_type_ustring, ret); return ISC_R_SUCCESS; } diff --git a/lib/isccfg/parser.c b/lib/isccfg/parser.c index ac9a4a24af..35721eb2f1 100644 --- a/lib/isccfg/parser.c +++ b/lib/isccfg/parser.c @@ -114,9 +114,6 @@ create_list(isc_mem_t *mctx, cfg_obj_t *file, size_t line, static void create_listelt(cfg_obj_t *list, cfg_listelt_t **eltp); -static void -create_string(cfg_parser_t *pctx, const char *contents, const cfg_type_t *type, - cfg_obj_t **ret); static void free_string(cfg_obj_t *obj); @@ -766,8 +763,8 @@ parser_openfile(cfg_parser_t *pctx, const char *filename) { goto cleanup; } - create_string(pctx, filename, &cfg_type_qstring, &stringobj); create_listelt(pctx->open_files, &elt); + cfg_string_create(pctx, filename, &cfg_type_qstring, &stringobj); elt->obj = stringobj; ISC_LIST_APPEND(pctx->open_files->value.list, elt, link); @@ -1409,9 +1406,9 @@ cfg_type_t cfg_type_duration_or_unlimited = { "duration_or_unlimited", */ /* Create a string object from a null-terminated C string. */ -static void -create_string(cfg_parser_t *pctx, const char *contents, const cfg_type_t *type, - cfg_obj_t **ret) { +void +cfg_string_create(cfg_parser_t *pctx, const char *contents, + const cfg_type_t *type, cfg_obj_t **ret) { cfg_obj_t *obj = NULL; int len; @@ -1439,7 +1436,7 @@ cfg_parse_qstring(cfg_parser_t *pctx, const cfg_type_t *type ISC_ATTR_UNUSED, cfg_parser_error(pctx, CFG_LOG_NEAR, "expected quoted string"); return ISC_R_UNEXPECTEDTOKEN; } - create_string(pctx, TOKEN_STRING(pctx), &cfg_type_qstring, ret); + cfg_string_create(pctx, TOKEN_STRING(pctx), &cfg_type_qstring, ret); return ISC_R_SUCCESS; cleanup: @@ -1457,7 +1454,7 @@ parse_ustring(cfg_parser_t *pctx, const cfg_type_t *type ISC_ATTR_UNUSED, "expected unquoted string"); return ISC_R_UNEXPECTEDTOKEN; } - create_string(pctx, TOKEN_STRING(pctx), &cfg_type_ustring, ret); + cfg_string_create(pctx, TOKEN_STRING(pctx), &cfg_type_ustring, ret); return ISC_R_SUCCESS; cleanup: @@ -1473,7 +1470,7 @@ cfg_parse_astring(cfg_parser_t *pctx, const cfg_type_t *type ISC_ATTR_UNUSED, REQUIRE(ret != NULL && *ret == NULL); CHECK(cfg_getstringtoken(pctx)); - create_string(pctx, TOKEN_STRING(pctx), &cfg_type_qstring, ret); + cfg_string_create(pctx, TOKEN_STRING(pctx), &cfg_type_qstring, ret); return ISC_R_SUCCESS; cleanup: @@ -1489,7 +1486,7 @@ cfg_parse_sstring(cfg_parser_t *pctx, const cfg_type_t *type ISC_ATTR_UNUSED, REQUIRE(ret != NULL && *ret == NULL); CHECK(cfg_getstringtoken(pctx)); - create_string(pctx, TOKEN_STRING(pctx), &cfg_type_sstring, ret); + cfg_string_create(pctx, TOKEN_STRING(pctx), &cfg_type_sstring, ret); return ISC_R_SUCCESS; cleanup: @@ -1506,7 +1503,8 @@ parse_btext(cfg_parser_t *pctx, const cfg_type_t *type ISC_ATTR_UNUSED, cfg_parser_error(pctx, CFG_LOG_NEAR, "expected bracketed text"); return ISC_R_UNEXPECTEDTOKEN; } - create_string(pctx, TOKEN_STRING(pctx), &cfg_type_bracketed_text, ret); + cfg_string_create(pctx, TOKEN_STRING(pctx), &cfg_type_bracketed_text, + ret); return ISC_R_SUCCESS; cleanup: From bc82db7b82262148f02218fb9702bb5bf28b43b5 Mon Sep 17 00:00:00 2001 From: Colin Vidal Date: Wed, 26 Nov 2025 14:33:02 +0100 Subject: [PATCH 2/6] remove `references` from cfg_parser_t The parser used to be referenced by `cfg_obj_t`, but not anymore. Removing the reference counter from `cfg_parser_t`. --- lib/isccfg/include/isccfg/grammar.h | 3 --- lib/isccfg/parser.c | 22 +++++++++------------- 2 files changed, 9 insertions(+), 16 deletions(-) diff --git a/lib/isccfg/include/isccfg/grammar.h b/lib/isccfg/include/isccfg/grammar.h index bee2a22469..0018942fb5 100644 --- a/lib/isccfg/include/isccfg/grammar.h +++ b/lib/isccfg/include/isccfg/grammar.h @@ -288,9 +288,6 @@ struct cfg_parser { * from one token to the next. */ unsigned int flags; - - /*%< Reference counter */ - isc_refcount_t references; }; /* Parser context flags */ diff --git a/lib/isccfg/parser.c b/lib/isccfg/parser.c index 35721eb2f1..188d34226b 100644 --- a/lib/isccfg/parser.c +++ b/lib/isccfg/parser.c @@ -692,8 +692,6 @@ parser_create(isc_mem_t *mctx, cfg_parser_t **ret) { pctx->mctx = NULL; isc_mem_attach(mctx, &pctx->mctx); - isc_refcount_init(&pctx->references, 1); - pctx->lexer = NULL; pctx->seen_eof = false; pctx->ungotten = false; @@ -737,17 +735,15 @@ parser_destroy(cfg_parser_t **pctxp) { pctx = *pctxp; *pctxp = NULL; - if (isc_refcount_decrement(&pctx->references) == 1) { - isc_lex_destroy(&pctx->lexer); - /* - * Cleaning up open_files does not - * close the files; that was already done - * by closing the lexer. - */ - CLEANUP_OBJ(pctx->open_files); - CLEANUP_OBJ(pctx->closed_files); - isc_mem_putanddetach(&pctx->mctx, pctx, sizeof(*pctx)); - } + isc_lex_destroy(&pctx->lexer); + /* + * Cleaning up open_files does not + * close the files; that was already done + * by closing the lexer. + */ + CLEANUP_OBJ(pctx->open_files); + CLEANUP_OBJ(pctx->closed_files); + isc_mem_putanddetach(&pctx->mctx, pctx, sizeof(*pctx)); } static isc_result_t From f7b64e2e87a6c13b49c40f4b67e87f1c751b6880 Mon Sep 17 00:00:00 2001 From: Colin Vidal Date: Tue, 4 Nov 2025 10:46:05 +0100 Subject: [PATCH 3/6] cfg_parse_ API doesn't need memory context Because the parser now uses global memory context, the cfg_parse_* API doesn't take a memory context anymore. --- bin/check/named-checkconf.c | 14 +++++----- bin/delv/delv.c | 8 +++--- bin/dig/dighost.c | 3 +-- bin/dnssec/dnssec-keygen.c | 5 ++-- bin/dnssec/dnssec-ksr.c | 4 +-- bin/named/config.c | 13 +++++----- bin/named/controlconf.c | 3 +-- bin/named/server.c | 25 +++++++++--------- bin/nsupdate/nsupdate.c | 3 +-- bin/plugins/filter-a.c | 8 +++--- bin/plugins/filter-aaaa.c | 8 +++--- bin/plugins/synthrecord.c | 5 ++-- bin/rndc/rndc.c | 6 ++--- .../system/hooks/driver/test-syncplugin.c | 4 +-- doc/misc/cfg_test.c | 6 ++++- lib/isccfg/include/isccfg/cfg.h | 9 +++---- lib/isccfg/parser.c | 26 ++++++++----------- tests/isccfg/duration_test.c | 2 +- tests/isccfg/grammar_test.c | 4 +-- tests/isccfg/parser_test.c | 17 +++++------- 20 files changed, 81 insertions(+), 92 deletions(-) diff --git a/bin/check/named-checkconf.c b/bin/check/named-checkconf.c index 5b2c934e52..a40a4b703c 100644 --- a/bin/check/named-checkconf.c +++ b/bin/check/named-checkconf.c @@ -531,11 +531,11 @@ parse_builtin(cfg_obj_t **defaultconfig) { sizeof(common_named_defaultconf) - 1); isc_buffer_add(&b, sizeof(common_named_defaultconf) - 1); - return cfg_parse_buffer( - isc_g_mctx, &b, __FILE__, 0, &cfg_type_namedconf, - CFG_PCTX_NODEPRECATED | CFG_PCTX_NOOBSOLETE | - CFG_PCTX_NOEXPERIMENTAL | CFG_PCTX_BUILTIN, - defaultconfig); + return cfg_parse_buffer(&b, __FILE__, 0, &cfg_type_namedconf, + CFG_PCTX_NODEPRECATED | CFG_PCTX_NOOBSOLETE | + CFG_PCTX_NOEXPERIMENTAL | + CFG_PCTX_BUILTIN, + defaultconfig); } static void @@ -714,8 +714,8 @@ main(int argc, char **argv) { } CHECK(setup_logging(stdout)); - CHECK(cfg_parse_file(isc_g_mctx, conffile, &cfg_type_namedconf, - parserflags, &config)); + CHECK(cfg_parse_file(conffile, &cfg_type_namedconf, parserflags, + &config)); CHECK(isccfg_check_namedconf(config, checkflags, isc_g_mctx)); if (load_zones || list_zones) { CHECK(load_zones_fromconfig(config, list_zones)); diff --git a/bin/delv/delv.c b/bin/delv/delv.c index 262497da41..0d69fb79d3 100644 --- a/bin/delv/delv.c +++ b/bin/delv/delv.c @@ -829,8 +829,8 @@ setup_dnsseckeys(dns_client_t *client, dns_view_t *toview) { fatal("Unable to read key file '%s'", anchorfile); } - result = cfg_parse_file(isc_g_mctx, anchorfile, - &cfg_type_bindkeys, 0, &bindkeys); + result = cfg_parse_file(anchorfile, &cfg_type_bindkeys, 0, + &bindkeys); if (result != ISC_R_SUCCESS) { fatal("Unable to load keys from '%s'", anchorfile); } @@ -842,8 +842,8 @@ setup_dnsseckeys(dns_client_t *client, dns_view_t *toview) { isc_buffer_init(&b, anchortext, sizeof(anchortext) - 1); isc_buffer_add(&b, sizeof(anchortext) - 1); - result = cfg_parse_buffer(isc_g_mctx, &b, NULL, 0, &delv_type, - 0, &bindkeys); + result = cfg_parse_buffer(&b, NULL, 0, &delv_type, 0, + &bindkeys); if (result != ISC_R_SUCCESS) { fatal("Unable to parse built-in keys"); } diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c index 80253b18d6..4c0af64d64 100644 --- a/bin/dig/dighost.c +++ b/bin/dig/dighost.c @@ -1062,8 +1062,7 @@ read_confkey(void) { return ISC_R_FILENOTFOUND; } - CHECK(cfg_parse_file(isc_g_mctx, keyfile, &cfg_type_sessionkey, 0, - &file)); + CHECK(cfg_parse_file(keyfile, &cfg_type_sessionkey, 0, &file)); CHECK(cfg_map_get(file, "key", &keyobj)); diff --git a/bin/dnssec/dnssec-keygen.c b/bin/dnssec/dnssec-keygen.c index 17556b17b9..4b222de72e 100644 --- a/bin/dnssec/dnssec-keygen.c +++ b/bin/dnssec/dnssec-keygen.c @@ -1150,9 +1150,8 @@ main(int argc, char **argv) { cfg_obj_t *config = NULL; dns_kasp_t *kasp = NULL; - if (cfg_parse_file(isc_g_mctx, ctx.configfile, - &cfg_type_namedconf, 0, - &config) != ISC_R_SUCCESS) + if (cfg_parse_file(ctx.configfile, &cfg_type_namedconf, + 0, &config) != ISC_R_SUCCESS) { fatal("unable to load dnssec-policy '%s' from " "'%s'", diff --git a/bin/dnssec/dnssec-ksr.c b/bin/dnssec/dnssec-ksr.c index 8f0c61c7a1..9664653d0b 100644 --- a/bin/dnssec/dnssec-ksr.c +++ b/bin/dnssec/dnssec-ksr.c @@ -157,8 +157,8 @@ static void getkasp(ksr_ctx_t *ksr, dns_kasp_t **kasp) { cfg_obj_t *config = NULL; - if (cfg_parse_file(isc_g_mctx, ksr->configfile, &cfg_type_namedconf, 0, - &config) != ISC_R_SUCCESS) + if (cfg_parse_file(ksr->configfile, &cfg_type_namedconf, 0, &config) != + ISC_R_SUCCESS) { fatal("unable to load dnssec-policy '%s' from '%s'", ksr->policy, ksr->configfile); diff --git a/bin/named/config.c b/bin/named/config.c index c953f4c45a..7c74b52739 100644 --- a/bin/named/config.c +++ b/bin/named/config.c @@ -55,11 +55,11 @@ named_config_parsedefaults(cfg_obj_t **conf) { isc_buffer_constinit(&b, common_named_defaultconf, sizeof(common_named_defaultconf) - 1); isc_buffer_add(&b, sizeof(common_named_defaultconf) - 1); - return cfg_parse_buffer( - isc_g_mctx, &b, __FILE__, 0, &cfg_type_namedconf, - CFG_PCTX_NODEPRECATED | CFG_PCTX_NOOBSOLETE | - CFG_PCTX_NOEXPERIMENTAL | CFG_PCTX_BUILTIN, - conf); + return cfg_parse_buffer(&b, __FILE__, 0, &cfg_type_namedconf, + CFG_PCTX_NODEPRECATED | CFG_PCTX_NOOBSOLETE | + CFG_PCTX_NOEXPERIMENTAL | + CFG_PCTX_BUILTIN, + conf); } isc_result_t @@ -72,8 +72,7 @@ named_config_parsefile(cfg_obj_t **conf) { ISC_LOG_INFO, "parsing user configuration from '%s'", named_g_conffile); - CHECK(cfg_parse_file(isc_g_mctx, named_g_conffile, &cfg_type_namedconf, - 0, conf)); + CHECK(cfg_parse_file(named_g_conffile, &cfg_type_namedconf, 0, conf)); /* * Check the validity of the configuration. diff --git a/bin/named/controlconf.c b/bin/named/controlconf.c index 4653bcafa7..048b88f087 100644 --- a/bin/named/controlconf.c +++ b/bin/named/controlconf.c @@ -787,8 +787,7 @@ get_rndckey(isc_mem_t *mctx, controlkeylist_t *keyids) { return ISC_R_FILENOTFOUND; } - CHECK(cfg_parse_file(mctx, named_g_keyfile, &cfg_type_rndckey, 0, - &config)); + CHECK(cfg_parse_file(named_g_keyfile, &cfg_type_rndckey, 0, &config)); CHECK(cfg_map_get(config, "key", &key)); keyid = isc_mem_get(mctx, sizeof(*keyid)); diff --git a/bin/named/server.c b/bin/named/server.c index 4dc7b91afa..cb03db4d62 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -2350,7 +2350,7 @@ catz_addmodzone_cb(void *arg) { confbuf = NULL; result = dns_catz_generate_zonecfg(cz->origin, cz->entry, &confbuf); if (result == ISC_R_SUCCESS) { - result = cfg_parse_buffer(isc_g_mctx, confbuf, "catz", 0, + result = cfg_parse_buffer(confbuf, "catz", 0, &cfg_type_addzoneconf, 0, &zoneconf); isc_buffer_free(&confbuf); } @@ -2618,7 +2618,7 @@ catz_reconfigure(dns_catz_entry_t *entry, void *arg1, void *arg2) { result = dns_catz_generate_zonecfg(data->catz, entry, &confbuf); if (result == ISC_R_SUCCESS) { - result = cfg_parse_buffer(isc_g_mctx, confbuf, "catz", 0, + result = cfg_parse_buffer(confbuf, "catz", 0, &cfg_type_addzoneconf, 0, &zoneconf); isc_buffer_free(&confbuf); } @@ -7294,8 +7294,8 @@ data_to_cfg(dns_view_t *view, MDB_val *key, MDB_val *data, isc_buffer_t *text, snprintf(bufname, sizeof(bufname), "%.*s", (int)zone_name_len, zone_name); - result = cfg_parse_buffer(isc_g_mctx, text, bufname, 0, - &cfg_type_addzoneconf, 0, &zoneconf); + result = cfg_parse_buffer(text, bufname, 0, &cfg_type_addzoneconf, 0, + &zoneconf); if (result != ISC_R_SUCCESS) { isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER, ISC_LOG_ERROR, @@ -8920,9 +8920,9 @@ load_configuration(named_server_t *server, bool first_time) { "keys instead", named_g_bindkeysfile); } else { - result = cfg_parse_file( - isc_g_mctx, named_g_bindkeysfile, - &cfg_type_bindkeys, 0, &bindkeys); + result = cfg_parse_file(named_g_bindkeysfile, + &cfg_type_bindkeys, 0, + &bindkeys); if (result != ISC_R_SUCCESS) { isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER, @@ -12129,8 +12129,7 @@ load_nzf(dns_view_t *view) { /* * Parse the configuration in the NZF file. */ - result = cfg_parse_file(view->mctx, view->newzone.file, - &cfg_type_addzoneconf, 0, + result = cfg_parse_file(view->newzone.file, &cfg_type_addzoneconf, 0, &view->newzone.nzconfig); if (result != ISC_R_SUCCESS) { isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER, @@ -12496,8 +12495,8 @@ load_nzf(dns_view_t *view) { * config type, giving us a guarantee that valid configuration * will be written to DB. */ - result = cfg_parse_file(isc_g_mctx, view->newzone.file, - &cfg_type_addzoneconf, 0, &nzf_config); + result = cfg_parse_file(view->newzone.file, &cfg_type_addzoneconf, 0, + &nzf_config); if (result != ISC_R_SUCCESS) { isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER, ISC_LOG_ERROR, "Error parsing NZF file '%s': %s", @@ -12647,8 +12646,8 @@ newzone_parse(named_server_t *server, char *command, dns_view_t **viewp, */ isc_buffer_forward(&argbuf, 3); - CHECK(cfg_parse_buffer(server->mctx, &argbuf, bn, 0, - &cfg_type_addzoneconf, 0, &zoneconf)); + CHECK(cfg_parse_buffer(&argbuf, bn, 0, &cfg_type_addzoneconf, 0, + &zoneconf)); CHECK(cfg_map_get(zoneconf, "zone", &zlist)); if (!cfg_obj_islist(zlist)) { diff --git a/bin/nsupdate/nsupdate.c b/bin/nsupdate/nsupdate.c index cc8e5b4cd6..820029d3e8 100644 --- a/bin/nsupdate/nsupdate.c +++ b/bin/nsupdate/nsupdate.c @@ -569,8 +569,7 @@ read_sessionkey(isc_mem_t *mctx) { return ISC_R_FILENOTFOUND; } - CHECK(cfg_parse_file(mctx, keyfile, &cfg_type_sessionkey, 0, - &sessionkey)); + CHECK(cfg_parse_file(keyfile, &cfg_type_sessionkey, 0, &sessionkey)); CHECK(cfg_map_get(sessionkey, "key", &key)); diff --git a/bin/plugins/filter-a.c b/bin/plugins/filter-a.c index d5a9d0b268..541bb7ebc5 100644 --- a/bin/plugins/filter-a.c +++ b/bin/plugins/filter-a.c @@ -272,8 +272,8 @@ parse_parameters(filter_instance_t *inst, const char *parameters, isc_buffer_constinit(&b, parameters, strlen(parameters)); isc_buffer_add(&b, strlen(parameters)); - CHECK(cfg_parse_buffer(mctx, &b, cfg_file, cfg_line, - &cfg_type_parameters, 0, ¶m_obj)); + CHECK(cfg_parse_buffer(&b, cfg_file, cfg_line, &cfg_type_parameters, 0, + ¶m_obj)); CHECK(parse_filter_a_on(param_obj, "filter-a-on-v6", &inst->v6_a)); CHECK(parse_filter_a_on(param_obj, "filter-a-on-v4", &inst->v4_a)); @@ -359,8 +359,8 @@ plugin_check(const char *parameters, const void *cfg, const char *cfg_file, isc_buffer_constinit(&b, parameters, strlen(parameters)); isc_buffer_add(&b, strlen(parameters)); - CHECK(cfg_parse_buffer(mctx, &b, cfg_file, cfg_line, - &cfg_type_parameters, 0, ¶m_obj)); + CHECK(cfg_parse_buffer(&b, cfg_file, cfg_line, &cfg_type_parameters, 0, + ¶m_obj)); CHECK(check_syntax(param_obj, cfg, mctx, aclctx)); diff --git a/bin/plugins/filter-aaaa.c b/bin/plugins/filter-aaaa.c index 007d952e7e..8173b736c7 100644 --- a/bin/plugins/filter-aaaa.c +++ b/bin/plugins/filter-aaaa.c @@ -273,8 +273,8 @@ parse_parameters(filter_instance_t *inst, const char *parameters, isc_buffer_constinit(&b, parameters, strlen(parameters)); isc_buffer_add(&b, strlen(parameters)); - CHECK(cfg_parse_buffer(mctx, &b, cfg_file, cfg_line, - &cfg_type_parameters, 0, ¶m_obj)); + CHECK(cfg_parse_buffer(&b, cfg_file, cfg_line, &cfg_type_parameters, 0, + ¶m_obj)); CHECK(parse_filter_aaaa_on(param_obj, "filter-aaaa-on-v4", &inst->v4_aaaa)); @@ -363,8 +363,8 @@ plugin_check(const char *parameters, const void *cfg, const char *cfg_file, isc_buffer_constinit(&b, parameters, strlen(parameters)); isc_buffer_add(&b, strlen(parameters)); - CHECK(cfg_parse_buffer(mctx, &b, cfg_file, cfg_line, - &cfg_type_parameters, 0, ¶m_obj)); + CHECK(cfg_parse_buffer(&b, cfg_file, cfg_line, &cfg_type_parameters, 0, + ¶m_obj)); CHECK(check_syntax(param_obj, cfg, mctx, aclctx)); diff --git a/bin/plugins/synthrecord.c b/bin/plugins/synthrecord.c index 8dc3e257b1..895f2f7df2 100644 --- a/bin/plugins/synthrecord.c +++ b/bin/plugins/synthrecord.c @@ -554,15 +554,14 @@ synthrecord_parseconfig(synthrecord_t *inst, const char *parameters, unsigned long cfgline, cfg_aclconfctx_t *aclctx, const dns_name_t *zname) { isc_result_t result; - isc_mem_t *mctx = inst->mctx; cfg_obj_t *synthrecordcfg = NULL; isc_buffer_t b; isc_buffer_constinit(&b, parameters, strlen(parameters)); isc_buffer_add(&b, strlen(parameters)); - CHECK(cfg_parse_buffer(mctx, &b, cfgfile, cfgline, - &synthrecord_cfgparams, 0, &synthrecordcfg)); + CHECK(cfg_parse_buffer(&b, cfgfile, cfgline, &synthrecord_cfgparams, 0, + &synthrecordcfg)); synthrecord_setconfigmode(inst, zname); CHECK(synthrecord_initorigin(inst, synthrecordcfg, zname)); diff --git a/bin/rndc/rndc.c b/bin/rndc/rndc.c index 66660351ba..dc5b536f4e 100644 --- a/bin/rndc/rndc.c +++ b/bin/rndc/rndc.c @@ -537,7 +537,7 @@ rndc_start(void *arg) { } static void -parse_config(isc_mem_t *mctx, const char *keyname, cfg_obj_t **configp) { +parse_config(const char *keyname, cfg_obj_t **configp) { isc_result_t result; const char *conffile = admin_conffile; const cfg_obj_t *addresses = NULL; @@ -581,7 +581,7 @@ parse_config(isc_mem_t *mctx, const char *keyname, cfg_obj_t **configp) { /* * The parser will output its own errors, so DO() is not used. */ - result = cfg_parse_file(mctx, conffile, conftype, 0, &config); + result = cfg_parse_file(conffile, conftype, 0, &config); if (result != ISC_R_SUCCESS) { fatal("could not load rndc configuration"); } @@ -961,7 +961,7 @@ main(int argc, char **argv) { ISC_LOG_PRINTTAG | ISC_LOG_PRINTLEVEL, ISC_LOGCATEGORY_DEFAULT, ISC_LOGMODULE_DEFAULT); - parse_config(isc_g_mctx, keyname, &config); + parse_config(keyname, &config); isc_buffer_allocate(isc_g_mctx, &databuf, 2048); diff --git a/bin/tests/system/hooks/driver/test-syncplugin.c b/bin/tests/system/hooks/driver/test-syncplugin.c index 36409bbda9..c125f335d6 100644 --- a/bin/tests/system/hooks/driver/test-syncplugin.c +++ b/bin/tests/system/hooks/driver/test-syncplugin.c @@ -126,8 +126,8 @@ plugin_register(const char *parameters, const void *cfg, const char *cfgfile, isc_buffer_constinit(&b, parameters, strlen(parameters)); isc_buffer_add(&b, strlen(parameters)); - CHECK(cfg_parse_buffer(mctx, &b, cfgfile, cfgline, - &syncplugin__cfgparams, 0, &syncplugincfg)); + CHECK(cfg_parse_buffer(&b, cfgfile, cfgline, &syncplugin__cfgparams, 0, + &syncplugincfg)); CHECK(syncplugin__parse_rcode(syncplugincfg, &inst->rcode)); diff --git a/doc/misc/cfg_test.c b/doc/misc/cfg_test.c index f29600c2aa..cb17b35e1b 100644 --- a/doc/misc/cfg_test.c +++ b/doc/misc/cfg_test.c @@ -133,7 +133,7 @@ main(int argc, char **argv) { if (type == NULL || filename == NULL) { usage(); } - result = cfg_parse_file(mctx, filename, type, 0, &cfg); + result = cfg_parse_file(filename, type, 0, &cfg); fprintf(stderr, "read config: %s\n", isc_result_totext(result)); @@ -147,6 +147,10 @@ main(int argc, char **argv) { } if (memstats) { + /* + * TODO: this is memstat of config that we are interested in + * here, right? + */ isc_mem_stats(mctx, stderr); } isc_mem_detach(&mctx); diff --git a/lib/isccfg/include/isccfg/cfg.h b/lib/isccfg/include/isccfg/cfg.h index 882ac2cca1..5012f49217 100644 --- a/lib/isccfg/include/isccfg/cfg.h +++ b/lib/isccfg/include/isccfg/cfg.h @@ -91,13 +91,12 @@ typedef isc_result_t (*cfg_parsecallback_t)(const char *clausename, ***/ isc_result_t -cfg_parse_file(isc_mem_t *mctx, const char *file, const cfg_type_t *type, - unsigned int flags, cfg_obj_t **ret); +cfg_parse_file(const char *file, const cfg_type_t *type, unsigned int flags, + cfg_obj_t **ret); isc_result_t -cfg_parse_buffer(isc_mem_t *mctx, isc_buffer_t *buffer, const char *file, - unsigned int line, const cfg_type_t *type, unsigned int flags, - cfg_obj_t **ret); +cfg_parse_buffer(isc_buffer_t *buffer, const char *file, unsigned int line, + const cfg_type_t *type, unsigned int flags, cfg_obj_t **ret); /*%< * Read a configuration containing data of type 'type' * and make '*ret' point to its parse tree. diff --git a/lib/isccfg/parser.c b/lib/isccfg/parser.c index 188d34226b..202609a6f4 100644 --- a/lib/isccfg/parser.c +++ b/lib/isccfg/parser.c @@ -680,17 +680,16 @@ static cfg_type_t cfg_type_filelist = { "filelist", NULL, &cfg_rep_list, &cfg_type_qstring }; static void -parser_create(isc_mem_t *mctx, cfg_parser_t **ret) { +parser_create(cfg_parser_t **ret) { cfg_parser_t *pctx; isc_lexspecials_t specials; - REQUIRE(mctx != NULL); REQUIRE(ret != NULL && *ret == NULL); - pctx = isc_mem_get(mctx, sizeof(*pctx)); + pctx = isc_mem_get(isc_g_mctx, sizeof(*pctx)); pctx->mctx = NULL; - isc_mem_attach(mctx, &pctx->mctx); + isc_mem_attach(isc_g_mctx, &pctx->mctx); pctx->lexer = NULL; pctx->seen_eof = false; @@ -712,14 +711,14 @@ parser_create(isc_mem_t *mctx, cfg_parser_t **ret) { specials['"'] = 1; specials['!'] = 1; - isc_lex_create(pctx->mctx, 1024, &pctx->lexer); + isc_lex_create(isc_g_mctx, 1024, &pctx->lexer); isc_lex_setspecials(pctx->lexer, specials); isc_lex_setcomments(pctx->lexer, ISC_LEXCOMMENT_C | ISC_LEXCOMMENT_CPLUSPLUS | ISC_LEXCOMMENT_SHELL); - create_list(pctx->mctx, cfg_parser_currentfile(pctx), pctx->line, + create_list(isc_g_mctx, cfg_parser_currentfile(pctx), pctx->line, &cfg_type_filelist, &pctx->open_files); create_list(pctx->mctx, cfg_parser_currentfile(pctx), pctx->line, &cfg_type_filelist, &pctx->closed_files); @@ -811,19 +810,18 @@ cleanup: CFG_PCTX_NOEXPERIMENTAL | CFG_PCTX_BUILTIN)) == 0) isc_result_t -cfg_parse_file(isc_mem_t *mctx, const char *filename, const cfg_type_t *type, - unsigned int flags, cfg_obj_t **ret) { +cfg_parse_file(const char *filename, const cfg_type_t *type, unsigned int flags, + cfg_obj_t **ret) { isc_result_t result; cfg_listelt_t *elt; cfg_parser_t *pctx = NULL; - REQUIRE(mctx != NULL); REQUIRE(filename != NULL); REQUIRE(type != NULL); REQUIRE(ret != NULL && *ret == NULL); REQUIRE_PCTX_FLAGS(flags); - parser_create(mctx, &pctx); + parser_create(&pctx); pctx->flags = flags; CHECK(parser_openfile(pctx, filename)); @@ -843,19 +841,17 @@ cleanup: } isc_result_t -cfg_parse_buffer(isc_mem_t *mctx, isc_buffer_t *buffer, const char *file, - unsigned int line, const cfg_type_t *type, unsigned int flags, - cfg_obj_t **ret) { +cfg_parse_buffer(isc_buffer_t *buffer, const char *file, unsigned int line, + const cfg_type_t *type, unsigned int flags, cfg_obj_t **ret) { isc_result_t result; cfg_parser_t *pctx = NULL; - REQUIRE(mctx != NULL); REQUIRE(type != NULL); REQUIRE(buffer != NULL); REQUIRE(ret != NULL && *ret == NULL); REQUIRE_PCTX_FLAGS(flags); - parser_create(mctx, &pctx); + parser_create(&pctx); CHECK(isc_lex_openbuffer(pctx->lexer, buffer)); pctx->buf_name = file; diff --git a/tests/isccfg/duration_test.c b/tests/isccfg/duration_test.c index a9cb1fd021..fbe63046a2 100644 --- a/tests/isccfg/duration_test.c +++ b/tests/isccfg/duration_test.c @@ -143,7 +143,7 @@ ISC_RUN_TEST_IMPL(duration) { isc_buffer_add(&buf1, strlen(conf) - 1); /* Parse with default line numbering */ - result = cfg_parse_buffer(isc_g_mctx, &buf1, "text1", 0, + result = cfg_parse_buffer(&buf1, "text1", 0, &cfg_type_namedconf, 0, &c1); if (must_fail) { assert_int_equal(result, DNS_R_BADTTL); diff --git a/tests/isccfg/grammar_test.c b/tests/isccfg/grammar_test.c index 59ea824112..ad524dcbdd 100644 --- a/tests/isccfg/grammar_test.c +++ b/tests/isccfg/grammar_test.c @@ -115,8 +115,8 @@ test__query_source_print(const char *config, const char *expected) { isc_buffer_constinit(&buffer, config, strlen(config)); isc_buffer_add(&buffer, strlen(config)); - result = cfg_parse_buffer(isc_g_mctx, &buffer, "text1", 0, - &cfg_type_namedconf, 0, &output_conf); + result = cfg_parse_buffer(&buffer, "text1", 0, &cfg_type_namedconf, 0, + &output_conf); assert_int_equal(result, ISC_R_SUCCESS); assert_non_null(output_conf); diff --git a/tests/isccfg/parser_test.c b/tests/isccfg/parser_test.c index e1e6beb093..d817d3eeaf 100644 --- a/tests/isccfg/parser_test.c +++ b/tests/isccfg/parser_test.c @@ -79,8 +79,8 @@ ISC_RUN_TEST_IMPL(addzoneconf) { isc_buffer_constinit(&b, tests[i], strlen(tests[i])); isc_buffer_add(&b, strlen(tests[i])); - result = cfg_parse_buffer(isc_g_mctx, &b, "text1", 0, - &cfg_type_namedconf, 0, &conf); + result = cfg_parse_buffer(&b, "text1", 0, &cfg_type_namedconf, + 0, &conf); assert_int_equal(result, ISC_R_SUCCESS); /* @@ -130,22 +130,20 @@ ISC_RUN_TEST_IMPL(parse_buffer) { /* Parse with default line numbering. */ isc_buffer_init(&buf, &text[0], sizeof(text) - 1); isc_buffer_add(&buf, sizeof(text) - 1); - result = cfg_parse_buffer(isc_g_mctx, &buf, "text1", 0, - &cfg_type_namedconf, 0, &c); + result = cfg_parse_buffer(&buf, "text1", 0, &cfg_type_namedconf, 0, &c); assert_int_equal(result, ISC_R_FAILURE); assert_null(c); /* Parse with changed line number. */ isc_buffer_first(&buf); - result = cfg_parse_buffer(isc_g_mctx, &buf, "text2", 100, - &cfg_type_namedconf, 0, &c); + result = cfg_parse_buffer(&buf, "text2", 100, &cfg_type_namedconf, 0, + &c); assert_int_equal(result, ISC_R_FAILURE); assert_null(c); /* Parse with changed line number and no name. */ isc_buffer_first(&buf); - result = cfg_parse_buffer(isc_g_mctx, &buf, NULL, 100, - &cfg_type_namedconf, 0, &c); + result = cfg_parse_buffer(&buf, NULL, 100, &cfg_type_namedconf, 0, &c); assert_int_equal(result, ISC_R_FAILURE); assert_null(c); @@ -262,8 +260,7 @@ view \"_bind\" chaos {\n\ isc_buffer_init(&buf, conf, sizeof(conf)); isc_buffer_add(&buf, sizeof(conf) - 1); - result = cfg_parse_buffer(isc_g_mctx, &buf, "", 0, &cfg_type_namedconf, - 0, &orig); + result = cfg_parse_buffer(&buf, "", 0, &cfg_type_namedconf, 0, &orig); assert_int_equal(result, ISC_R_SUCCESS); isc_buffer_init(&dumpb1, dumpbdata1, sizeof(dumpbdata1)); From 93f8b2f5bfff038a376a9057451cacaf4f139007 Mon Sep 17 00:00:00 2001 From: Colin Vidal Date: Tue, 4 Nov 2025 10:49:40 +0100 Subject: [PATCH 4/6] remove memory context from parser context As the isccfg library now uses the global memory context, it is now used directly instead of passing the parser context around to grab its memory context. Also remove the memory context from the parser, as well as from `cfg_obj_t`, as it's now useless. --- lib/isccfg/include/isccfg/grammar.h | 9 +- lib/isccfg/namedconf.c | 38 +++--- lib/isccfg/parser.c | 179 +++++++++++++--------------- 3 files changed, 107 insertions(+), 119 deletions(-) diff --git a/lib/isccfg/include/isccfg/grammar.h b/lib/isccfg/include/isccfg/grammar.h index 0018942fb5..975385409e 100644 --- a/lib/isccfg/include/isccfg/grammar.h +++ b/lib/isccfg/include/isccfg/grammar.h @@ -199,7 +199,6 @@ struct cfg_rep { struct cfg_obj { unsigned int magic; - isc_mem_t *mctx; isc_refcount_t references; /*% @@ -238,7 +237,6 @@ struct cfg_listelt { /*% The parser object. */ struct cfg_parser { - isc_mem_t *mctx; isc_lex_t *lexer; unsigned int errors; unsigned int warnings; @@ -376,8 +374,8 @@ cfg_ungettoken(cfg_parser_t *pctx); #define CFG_LEXOPT_QSTRING (ISC_LEXOPT_QSTRING | ISC_LEXOPT_QSTRINGMULTILINE) void -cfg_obj_create(isc_mem_t *mctx, cfg_obj_t *file, size_t line, - const cfg_type_t *type, cfg_obj_t **ret); +cfg_obj_create(cfg_obj_t *file, size_t line, const cfg_type_t *type, + cfg_obj_t **ret); void cfg_string_create(cfg_parser_t *pctx, const char *contents, @@ -465,6 +463,9 @@ isc_result_t cfg_parse_listelt(cfg_parser_t *pctx, cfg_obj_t *list, const cfg_type_t *elttype, cfg_listelt_t **ret); +void +cfg_listelt_create(cfg_listelt_t **ret); + isc_result_t cfg_parse_bracketed_list(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret); diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c index 455ef114ae..c6ecbf041b 100644 --- a/lib/isccfg/namedconf.c +++ b/lib/isccfg/namedconf.c @@ -963,8 +963,8 @@ parse_qstringornone(cfg_parser_t *pctx, const cfg_type_t *type, if (pctx->token.type == isc_tokentype_string && strcasecmp(TOKEN_STRING(pctx), "none") == 0) { - cfg_obj_create(pctx->mctx, cfg_parser_currentfile(pctx), - pctx->line, &cfg_type_none, ret); + cfg_obj_create(cfg_parser_currentfile(pctx), pctx->line, + &cfg_type_none, ret); return ISC_R_SUCCESS; } cfg_ungettoken(pctx); @@ -1007,8 +1007,8 @@ parse_boolorauto(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { if (pctx->token.type == isc_tokentype_string && strcasecmp(TOKEN_STRING(pctx), "auto") == 0) { - cfg_obj_create(pctx->mctx, cfg_parser_currentfile(pctx), - pctx->line, &cfg_type_auto, ret); + cfg_obj_create(cfg_parser_currentfile(pctx), pctx->line, + &cfg_type_auto, ret); return ISC_R_SUCCESS; } cfg_ungettoken(pctx); @@ -1063,15 +1063,15 @@ parse_serverid(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { if (pctx->token.type == isc_tokentype_string && strcasecmp(TOKEN_STRING(pctx), "none") == 0) { - cfg_obj_create(pctx->mctx, cfg_parser_currentfile(pctx), - pctx->line, &cfg_type_none, ret); + cfg_obj_create(cfg_parser_currentfile(pctx), pctx->line, + &cfg_type_none, ret); return ISC_R_SUCCESS; } if (pctx->token.type == isc_tokentype_string && strcasecmp(TOKEN_STRING(pctx), "hostname") == 0) { - cfg_obj_create(pctx->mctx, cfg_parser_currentfile(pctx), - pctx->line, &cfg_type_hostname, ret); + cfg_obj_create(cfg_parser_currentfile(pctx), pctx->line, + &cfg_type_hostname, ret); (*ret)->value.boolean = true; return ISC_R_SUCCESS; } @@ -2306,9 +2306,9 @@ checknames_merge(const cfg_obj_t *config ISC_ATTR_UNUSED, } if (found == false) { - cfg_listelt_t *eelt = isc_mem_get(effectiveobj->mctx, - sizeof(*eelt)); + cfg_listelt_t *eelt = NULL; + cfg_listelt_create(&eelt); *eelt = (cfg_listelt_t){ .link = ISC_LINK_INITIALIZER }; cfg_obj_clone(checkname, &eelt->obj); ISC_LIST_APPEND(effectiveobj->value.list, eelt, link); @@ -3158,7 +3158,7 @@ parse_sizeval(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { } CHECK(parse_unitstring(TOKEN_STRING(pctx), &val)); - cfg_obj_create(pctx->mctx, cfg_parser_currentfile(pctx), pctx->line, + cfg_obj_create(cfg_parser_currentfile(pctx), pctx->line, &cfg_type_uint64, &obj); obj->value.uint64 = val; *ret = obj; @@ -3189,15 +3189,15 @@ parse_sizeval_percent(cfg_parser_t *pctx, const cfg_type_t *type, percent = strtoull(TOKEN_STRING(pctx), &endp, 10); if (*endp == '%' && *(endp + 1) == 0) { - cfg_obj_create(pctx->mctx, cfg_parser_currentfile(pctx), - pctx->line, &cfg_type_percentage, &obj); + cfg_obj_create(cfg_parser_currentfile(pctx), pctx->line, + &cfg_type_percentage, &obj); obj->value.uint32 = (uint32_t)percent; *ret = obj; return ISC_R_SUCCESS; } else { CHECK(parse_unitstring(TOKEN_STRING(pctx), &val)); - cfg_obj_create(pctx->mctx, cfg_parser_currentfile(pctx), - pctx->line, &cfg_type_uint64, &obj); + cfg_obj_create(cfg_parser_currentfile(pctx), pctx->line, + &cfg_type_uint64, &obj); obj->value.uint64 = val; *ret = obj; return ISC_R_SUCCESS; @@ -3623,8 +3623,8 @@ parse_querysource(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { strcasecmp(TOKEN_STRING(pctx), "none") == 0) { CHECK(cfg_gettoken(pctx, 0)); - cfg_obj_create(pctx->mctx, cfg_parser_currentfile(pctx), - pctx->line, &cfg_type_none, ret); + cfg_obj_create(cfg_parser_currentfile(pctx), pctx->line, + &cfg_type_none, ret); } else { CHECK(cfg_parse_sockaddr_generic(pctx, &cfg_type_querysource, type, ret)); @@ -3825,8 +3825,8 @@ parse_logseverity(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { * This makes little sense, but we support it for * compatibility with BIND 8. */ - cfg_obj_create(pctx->mctx, cfg_parser_currentfile(pctx), - pctx->line, &cfg_type_uint32, ret); + cfg_obj_create(cfg_parser_currentfile(pctx), pctx->line, + &cfg_type_uint32, ret); (*ret)->value.uint32 = 1; } (*ret)->type = &cfg_type_debuglevel; /* XXX kludge */ diff --git a/lib/isccfg/parser.c b/lib/isccfg/parser.c index 202609a6f4..8b9a99c8e4 100644 --- a/lib/isccfg/parser.c +++ b/lib/isccfg/parser.c @@ -39,7 +39,6 @@ /*! \file */ -#include #include #include #include @@ -109,10 +108,8 @@ static void free_list(cfg_obj_t *obj); static void -create_list(isc_mem_t *mctx, cfg_obj_t *file, size_t line, - const cfg_type_t *type, cfg_obj_t **obj); -static void -create_listelt(cfg_obj_t *list, cfg_listelt_t **eltp); +create_list(cfg_obj_t *file, size_t line, const cfg_type_t *type, + cfg_obj_t **obj); static void free_string(cfg_obj_t *obj); @@ -162,8 +159,7 @@ cfg_obj_clone(const cfg_obj_t *source, cfg_obj_t **target) { REQUIRE(source->type->rep->copy != NULL); REQUIRE(target != NULL && *target == NULL); - cfg_obj_create(source->mctx, source->file, source->line, source->type, - target); + cfg_obj_create(source->file, source->line, source->type, target); (*target)->cloned = source->cloned; source->type->rep->copy(*target, source); } @@ -185,14 +181,14 @@ copy_boolean(cfg_obj_t *to, const cfg_obj_t *from) { static void copy_sockaddr(cfg_obj_t *to, const cfg_obj_t *from) { - to->value.sockaddr = isc_mem_get(to->mctx, sizeof(isc_sockaddr_t)); + to->value.sockaddr = isc_mem_get(isc_g_mctx, sizeof(isc_sockaddr_t)); memmove(to->value.sockaddr, from->value.sockaddr, sizeof(isc_sockaddr_t)); } static void copy_sockaddrtls(cfg_obj_t *to, const cfg_obj_t *from) { - to->value.sockaddrtls.sockaddr = isc_mem_get(to->mctx, + to->value.sockaddrtls.sockaddr = isc_mem_get(isc_g_mctx, sizeof(isc_sockaddr_t)); memmove(to->value.sockaddrtls.sockaddr, from->value.sockaddrtls.sockaddr, sizeof(isc_sockaddr_t)); @@ -200,7 +196,8 @@ copy_sockaddrtls(cfg_obj_t *to, const cfg_obj_t *from) { if (from->value.sockaddrtls.tls.base != NULL) { size_t len = from->value.sockaddrtls.tls.length; - to->value.sockaddrtls.tls.base = isc_mem_get(to->mctx, len + 1); + to->value.sockaddrtls.tls.base = isc_mem_get(isc_g_mctx, + len + 1); to->value.sockaddrtls.tls.length = len; memmove(to->value.sockaddrtls.tls.base, from->value.sockaddrtls.tls.base, len + 1); @@ -209,24 +206,24 @@ copy_sockaddrtls(cfg_obj_t *to, const cfg_obj_t *from) { static void free_netprefix(cfg_obj_t *obj) { - isc_mem_put(obj->mctx, obj->value.netprefix, sizeof(cfg_netprefix_t)); + isc_mem_put(isc_g_mctx, obj->value.netprefix, sizeof(cfg_netprefix_t)); } static void copy_netprefix(cfg_obj_t *to, const cfg_obj_t *from) { - to->value.netprefix = isc_mem_get(to->mctx, sizeof(cfg_netprefix_t)); + to->value.netprefix = isc_mem_get(isc_g_mctx, sizeof(cfg_netprefix_t)); memmove(to->value.netprefix, from->value.netprefix, sizeof(cfg_netprefix_t)); } static void free_duration(cfg_obj_t *obj) { - isc_mem_put(obj->mctx, obj->value.duration, sizeof(isccfg_duration_t)); + isc_mem_put(isc_g_mctx, obj->value.duration, sizeof(isccfg_duration_t)); } static void copy_duration(cfg_obj_t *to, const cfg_obj_t *from) { - to->value.duration = isc_mem_get(to->mctx, sizeof(isccfg_duration_t)); + to->value.duration = isc_mem_get(isc_g_mctx, sizeof(isccfg_duration_t)); memmove(to->value.duration, from->value.duration, sizeof(isccfg_duration_t)); } @@ -234,7 +231,7 @@ copy_duration(cfg_obj_t *to, const cfg_obj_t *from) { static void copy_string(cfg_obj_t *to, const cfg_obj_t *from) { to->value.string.length = from->value.string.length; - to->value.string.base = isc_mem_get(to->mctx, + to->value.string.base = isc_mem_get(isc_g_mctx, to->value.string.length + 1); memmove(to->value.string.base, from->value.string.base, to->value.string.length + 1); @@ -278,7 +275,7 @@ copy_map(cfg_obj_t *to, const cfg_obj_t *from) { if (from->value.map.id != NULL) { cfg_obj_clone(from->value.map.id, &to->value.map.id); } - isc_symtab_create(to->mctx, copy_map_destroy, NULL, false, + isc_symtab_create(isc_g_mctx, copy_map_destroy, NULL, false, &to->value.map.symtab); isc_symtab_foreach(from->value.map.symtab, copy_map_add, to); @@ -295,7 +292,7 @@ copy_list(cfg_obj_t *to, const cfg_obj_t *from) { ISC_LIST_INIT(to->value.list); while (fromelt != NULL) { - cfg_listelt_t *toelt = isc_mem_get(to->mctx, sizeof(*toelt)); + cfg_listelt_t *toelt = isc_mem_get(isc_g_mctx, sizeof(*toelt)); *toelt = (cfg_listelt_t){ .link = ISC_LINK_INITIALIZER }; cfg_obj_clone(fromelt->obj, &toelt->obj); @@ -318,7 +315,7 @@ copy_tuple(cfg_obj_t *to, const cfg_obj_t *from) { size++; } - to->value.tuple = isc_mem_cget(to->mctx, size, sizeof(cfg_obj_t *)); + to->value.tuple = isc_mem_cget(isc_g_mctx, size, sizeof(cfg_obj_t *)); for (size_t j = 0; j < size; j++) { cfg_obj_clone(from->value.tuple[j], &to->value.tuple[j]); @@ -488,9 +485,8 @@ cfg_tuple_create(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { nfields++; } - cfg_obj_create(pctx->mctx, cfg_parser_currentfile(pctx), pctx->line, - type, &obj); - obj->value.tuple = isc_mem_cget(pctx->mctx, nfields, + cfg_obj_create(cfg_parser_currentfile(pctx), pctx->line, type, &obj); + obj->value.tuple = isc_mem_cget(isc_g_mctx, nfields, sizeof(cfg_obj_t *)); for (f = fields, i = 0; f->name != NULL; f++, i++) { obj->value.tuple[i] = NULL; @@ -583,7 +579,8 @@ free_tuple(cfg_obj_t *obj) { CLEANUP_OBJ(obj->value.tuple[i]); nfields++; } - isc_mem_cput(obj->mctx, obj->value.tuple, nfields, sizeof(cfg_obj_t *)); + isc_mem_cput(isc_g_mctx, obj->value.tuple, nfields, + sizeof(cfg_obj_t *)); } bool @@ -688,9 +685,6 @@ parser_create(cfg_parser_t **ret) { pctx = isc_mem_get(isc_g_mctx, sizeof(*pctx)); - pctx->mctx = NULL; - isc_mem_attach(isc_g_mctx, &pctx->mctx); - pctx->lexer = NULL; pctx->seen_eof = false; pctx->ungotten = false; @@ -718,9 +712,9 @@ parser_create(cfg_parser_t **ret) { ISC_LEXCOMMENT_CPLUSPLUS | ISC_LEXCOMMENT_SHELL); - create_list(isc_g_mctx, cfg_parser_currentfile(pctx), pctx->line, + create_list(cfg_parser_currentfile(pctx), pctx->line, &cfg_type_filelist, &pctx->open_files); - create_list(pctx->mctx, cfg_parser_currentfile(pctx), pctx->line, + create_list(cfg_parser_currentfile(pctx), pctx->line, &cfg_type_filelist, &pctx->closed_files); *ret = pctx; @@ -742,7 +736,7 @@ parser_destroy(cfg_parser_t **pctxp) { */ CLEANUP_OBJ(pctx->open_files); CLEANUP_OBJ(pctx->closed_files); - isc_mem_putanddetach(&pctx->mctx, pctx, sizeof(*pctx)); + isc_mem_put(isc_g_mctx, pctx, sizeof(*pctx)); } static isc_result_t @@ -758,8 +752,8 @@ parser_openfile(cfg_parser_t *pctx, const char *filename) { goto cleanup; } - create_listelt(pctx->open_files, &elt); cfg_string_create(pctx, filename, &cfg_type_qstring, &stringobj); + cfg_listelt_create(&elt); elt->obj = stringobj; ISC_LIST_APPEND(pctx->open_files->value.list, elt, link); @@ -879,8 +873,8 @@ cfg_parse_void(cfg_parser_t *pctx, const cfg_type_t *type ISC_ATTR_UNUSED, REQUIRE(pctx != NULL); REQUIRE(ret != NULL && *ret == NULL); - cfg_obj_create(pctx->mctx, cfg_parser_currentfile(pctx), pctx->line, - &cfg_type_void, ret); + cfg_obj_create(cfg_parser_currentfile(pctx), pctx->line, &cfg_type_void, + ret); return ISC_R_SUCCESS; } @@ -931,7 +925,7 @@ cfg_parse_percentage(cfg_parser_t *pctx, const cfg_type_t *type ISC_ATTR_UNUSED, return ISC_R_UNEXPECTEDTOKEN; } - cfg_obj_create(pctx->mctx, cfg_parser_currentfile(pctx), pctx->line, + cfg_obj_create(cfg_parser_currentfile(pctx), pctx->line, &cfg_type_percentage, &obj); obj->value.uint32 = (uint32_t)percent; *ret = obj; @@ -1003,7 +997,7 @@ cfg_parse_fixedpoint(cfg_parser_t *pctx, const cfg_type_t *type ISC_ATTR_UNUSED, return ISC_R_UNEXPECTEDTOKEN; } - cfg_obj_create(pctx->mctx, cfg_parser_currentfile(pctx), pctx->line, + cfg_obj_create(cfg_parser_currentfile(pctx), pctx->line, &cfg_type_fixedpoint, &obj); obj->value.uint32 = strtoul(p, NULL, 10) * 100; @@ -1070,7 +1064,7 @@ cfg_parse_uint32(cfg_parser_t *pctx, const cfg_type_t *type ISC_ATTR_UNUSED, return ISC_R_UNEXPECTEDTOKEN; } - cfg_obj_create(pctx->mctx, cfg_parser_currentfile(pctx), pctx->line, + cfg_obj_create(cfg_parser_currentfile(pctx), pctx->line, &cfg_type_uint32, &obj); obj->value.uint32 = pctx->token.value.as_ulong; @@ -1298,9 +1292,10 @@ parse_duration(cfg_parser_t *pctx, cfg_obj_t **ret) { goto cleanup; } - cfg_obj_create(pctx->mctx, cfg_parser_currentfile(pctx), pctx->line, + cfg_obj_create(cfg_parser_currentfile(pctx), pctx->line, &cfg_type_duration, &obj); - obj->value.duration = isc_mem_get(obj->mctx, sizeof(isccfg_duration_t)); + obj->value.duration = isc_mem_get(isc_g_mctx, + sizeof(isccfg_duration_t)); *obj->value.duration = duration; *ret = obj; @@ -1350,9 +1345,9 @@ cfg_parse_duration_or_unlimited(cfg_parser_t *pctx, duration.iso8601 = false; duration.unlimited = true; - cfg_obj_create(pctx->mctx, cfg_parser_currentfile(pctx), - pctx->line, &cfg_type_duration, &obj); - obj->value.duration = isc_mem_get(obj->mctx, + cfg_obj_create(cfg_parser_currentfile(pctx), pctx->line, + &cfg_type_duration, &obj); + obj->value.duration = isc_mem_get(isc_g_mctx, sizeof(isccfg_duration_t)); *obj->value.duration = duration; *ret = obj; @@ -1404,11 +1399,10 @@ cfg_string_create(cfg_parser_t *pctx, const char *contents, cfg_obj_t *obj = NULL; int len; - cfg_obj_create(pctx->mctx, cfg_parser_currentfile(pctx), pctx->line, - type, &obj); + cfg_obj_create(cfg_parser_currentfile(pctx), pctx->line, type, &obj); len = strlen(contents); obj->value.string.length = len; - obj->value.string.base = isc_mem_get(pctx->mctx, len + 1); + obj->value.string.base = isc_mem_get(isc_g_mctx, len + 1); memmove(obj->value.string.base, contents, len); obj->value.string.base[len] = '\0'; @@ -1680,22 +1674,22 @@ print_sstring(cfg_printer_t *pctx, const cfg_obj_t *obj) { static void free_string(cfg_obj_t *obj) { - isc_mem_put(obj->mctx, obj->value.string.base, + isc_mem_put(isc_g_mctx, obj->value.string.base, obj->value.string.length + 1); } static void free_sockaddr(cfg_obj_t *obj) { - isc_mem_put(obj->mctx, obj->value.sockaddr, sizeof(isc_sockaddr_t)); + isc_mem_put(isc_g_mctx, obj->value.sockaddr, sizeof(isc_sockaddr_t)); } static void free_sockaddrtls(cfg_obj_t *obj) { - isc_mem_put(obj->mctx, obj->value.sockaddrtls.sockaddr, + isc_mem_put(isc_g_mctx, obj->value.sockaddrtls.sockaddr, sizeof(isc_sockaddr_t)); if (obj->value.sockaddrtls.tls.base != NULL) { INSIST(obj->value.sockaddrtls.tls.length != 0); - isc_mem_put(obj->mctx, obj->value.sockaddrtls.tls.base, + isc_mem_put(isc_g_mctx, obj->value.sockaddrtls.tls.base, obj->value.sockaddrtls.tls.length + 1); } } @@ -2018,7 +2012,7 @@ cfg_parse_boolean(cfg_parser_t *pctx, const cfg_type_t *type ISC_ATTR_UNUSED, goto bad_boolean; } - cfg_obj_create(pctx->mctx, cfg_parser_currentfile(pctx), pctx->line, + cfg_obj_create(cfg_parser_currentfile(pctx), pctx->line, &cfg_type_boolean, &obj); obj->value.boolean = value; *ret = obj; @@ -2050,28 +2044,26 @@ cfg_type_t cfg_type_boolean = { "boolean", cfg_parse_boolean, */ static void -create_list(isc_mem_t *mctx, cfg_obj_t *file, size_t line, - const cfg_type_t *type, cfg_obj_t **obj) { - REQUIRE(mctx != NULL); +create_list(cfg_obj_t *file, size_t line, const cfg_type_t *type, + cfg_obj_t **obj) { REQUIRE(type != NULL); REQUIRE(obj != NULL && *obj == NULL); - cfg_obj_create(mctx, file, line, type, obj); + cfg_obj_create(file, line, type, obj); ISC_LIST_INIT((*obj)->value.list); } -static void -create_listelt(cfg_obj_t *list, cfg_listelt_t **eltp) { +void +cfg_listelt_create(cfg_listelt_t **eltp) { cfg_listelt_t *elt; - REQUIRE(VALID_CFGOBJ(list)); - elt = isc_mem_get(list->mctx, sizeof(*elt)); + elt = isc_mem_get(isc_g_mctx, sizeof(*elt)); *elt = (cfg_listelt_t){ .link = ISC_LINK_INITIALIZER }; *eltp = elt; } static void -free_listelt(cfg_obj_t *list, cfg_listelt_t **eltp) { +free_listelt(cfg_listelt_t **eltp) { cfg_listelt_t *elt = *eltp; *eltp = NULL; @@ -2079,13 +2071,13 @@ free_listelt(cfg_obj_t *list, cfg_listelt_t **eltp) { if (elt->obj != NULL) { cfg_obj_detach(&elt->obj); } - isc_mem_put(list->mctx, elt, sizeof(*elt)); + isc_mem_put(isc_g_mctx, elt, sizeof(*elt)); } static void free_list(cfg_obj_t *obj) { ISC_LIST_FOREACH(obj->value.list, elt, link) { - free_listelt(obj, &elt); + free_listelt(&elt); } } @@ -2102,7 +2094,7 @@ cfg_parse_listelt(cfg_parser_t *pctx, cfg_obj_t *list, RETERR(cfg_parse_obj(pctx, elttype, &value)); - create_listelt(list, &elt); + cfg_listelt_create(&elt); elt->obj = value; *ret = elt; @@ -2120,8 +2112,8 @@ parse_list(cfg_parser_t *pctx, const cfg_type_t *listtype, cfg_obj_t **ret) { isc_result_t result; cfg_listelt_t *elt = NULL; - create_list(pctx->mctx, cfg_parser_currentfile(pctx), pctx->line, - listtype, &listobj); + create_list(cfg_parser_currentfile(pctx), pctx->line, listtype, + &listobj); for (;;) { CHECK(cfg_peektoken(pctx, 0)); @@ -2140,7 +2132,7 @@ parse_list(cfg_parser_t *pctx, const cfg_type_t *listtype, cfg_obj_t **ret) { cleanup: if (elt != NULL) { - free_listelt(listobj, &elt); + free_listelt(&elt); } CLEANUP_OBJ(listobj); return result; @@ -2219,8 +2211,8 @@ cfg_parse_spacelist(cfg_parser_t *pctx, const cfg_type_t *listtype, listof = listtype->of; - create_list(pctx->mctx, cfg_parser_currentfile(pctx), pctx->line, - listtype, &listobj); + create_list(cfg_parser_currentfile(pctx), pctx->line, listtype, + &listobj); for (;;) { cfg_listelt_t *elt = NULL; @@ -2285,7 +2277,7 @@ void cfg_list_unlink(cfg_obj_t *list, cfg_listelt_t *elt) { REQUIRE(VALID_CFGOBJ(list)); ISC_LIST_UNLINK(list->value.list, elt, link); - free_listelt(list, &elt); + free_listelt(&elt); } /* @@ -2502,9 +2494,8 @@ cfg_parse_mapbody(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { cfg_obj_t *listobj = NULL; cfg_listelt_t *elt = NULL; - create_list(pctx->mctx, cfg_parser_currentfile(pctx), - pctx->line, &cfg_type_implicitlist, - &listobj); + create_list(cfg_parser_currentfile(pctx), pctx->line, + &cfg_type_implicitlist, &listobj); symval.as_pointer = listobj; result = isc_symtab_define_and_return( obj->value.map.symtab, clause->name, @@ -2978,7 +2969,7 @@ parse_token(cfg_parser_t *pctx, const cfg_type_t *type ISC_ATTR_UNUSED, isc_result_t result; isc_region_t r; - cfg_obj_create(pctx->mctx, cfg_parser_currentfile(pctx), pctx->line, + cfg_obj_create(cfg_parser_currentfile(pctx), pctx->line, &cfg_type_token, &obj); CHECK(cfg_gettoken(pctx, CFG_LEXOPT_QSTRING)); if (pctx->token.type == isc_tokentype_eof) { @@ -2988,7 +2979,7 @@ parse_token(cfg_parser_t *pctx, const cfg_type_t *type ISC_ATTR_UNUSED, isc_lex_getlasttokentext(pctx->lexer, &pctx->token, &r); - obj->value.string.base = isc_mem_get(pctx->mctx, r.length + 1); + obj->value.string.base = isc_mem_get(isc_g_mctx, r.length + 1); obj->value.string.length = r.length; memmove(obj->value.string.base, r.base, r.length); obj->value.string.base[r.length] = '\0'; @@ -2997,7 +2988,7 @@ parse_token(cfg_parser_t *pctx, const cfg_type_t *type ISC_ATTR_UNUSED, cleanup: if (obj != NULL) { - isc_mem_put(pctx->mctx, obj, sizeof(*obj)); + isc_mem_put(isc_g_mctx, obj, sizeof(*obj)); } return result; } @@ -3017,8 +3008,7 @@ parse_unsupported(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { isc_result_t result; int braces = 0; - create_list(pctx->mctx, cfg_parser_currentfile(pctx), pctx->line, type, - &listobj); + create_list(cfg_parser_currentfile(pctx), pctx->line, type, &listobj); for (;;) { cfg_listelt_t *elt = NULL; @@ -3244,9 +3234,8 @@ parse_netaddr(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { unsigned int flags = *(const unsigned int *)type->of; CHECK(cfg_parse_rawaddr(pctx, flags, &netaddr)); - cfg_obj_create(pctx->mctx, cfg_parser_currentfile(pctx), pctx->line, - type, &obj); - obj->value.sockaddr = isc_mem_get(obj->mctx, sizeof(isc_sockaddr_t)); + cfg_obj_create(cfg_parser_currentfile(pctx), pctx->line, type, &obj); + obj->value.sockaddr = isc_mem_get(isc_g_mctx, sizeof(isc_sockaddr_t)); isc_sockaddr_fromnetaddr(obj->value.sockaddr, &netaddr, 0); *ret = obj; return ISC_R_SUCCESS; @@ -3372,9 +3361,9 @@ cfg_parse_netprefix(cfg_parser_t *pctx, const cfg_type_t *type ISC_ATTR_UNUSED, } prefixlen = addrlen; } - cfg_obj_create(pctx->mctx, cfg_parser_currentfile(pctx), pctx->line, + cfg_obj_create(cfg_parser_currentfile(pctx), pctx->line, &cfg_type_netprefix, &obj); - obj->value.netprefix = isc_mem_get(obj->mctx, sizeof(cfg_netprefix_t)); + obj->value.netprefix = isc_mem_get(isc_g_mctx, sizeof(cfg_netprefix_t)); obj->value.netprefix->address = netaddr; obj->value.netprefix->prefixlen = prefixlen; *ret = obj; @@ -3469,7 +3458,7 @@ parse_sockaddrsub(cfg_parser_t *pctx, const cfg_type_t *type, int flags, CHECK(cfg_getstringtoken(pctx)); isc_textregion_t tok = TOKEN_REGION(pctx); - copy_textregion(pctx->mctx, &tls, tok); + copy_textregion(isc_g_mctx, &tls, tok); ++have_tls; } else { @@ -3499,12 +3488,11 @@ parse_sockaddrsub(cfg_parser_t *pctx, const cfg_type_t *type, int flags, CLEANUP(ISC_R_UNEXPECTEDTOKEN); } - cfg_obj_create(pctx->mctx, cfg_parser_currentfile(pctx), pctx->line, - type, &obj); + cfg_obj_create(cfg_parser_currentfile(pctx), pctx->line, type, &obj); if (have_tls == 1) { obj->value.sockaddrtls.tls = tls; } - obj->value.sockaddrtls.sockaddr = isc_mem_get(obj->mctx, + obj->value.sockaddrtls.sockaddr = isc_mem_get(isc_g_mctx, sizeof(isc_sockaddr_t)); isc_sockaddr_fromnetaddr(obj->value.sockaddrtls.sockaddr, &netaddr, port); @@ -3513,7 +3501,7 @@ parse_sockaddrsub(cfg_parser_t *pctx, const cfg_type_t *type, int flags, cleanup: if (tls.base != NULL) { - isc_mem_put(pctx->mctx, tls.base, tls.length + 1); + isc_mem_put(isc_g_mctx, tls.base, tls.length + 1); } CLEANUP_OBJ(obj); return result; @@ -3891,19 +3879,18 @@ cfg_obj_line(const cfg_obj_t *obj) { } void -cfg_obj_create(isc_mem_t *mctx, cfg_obj_t *file, size_t line, - const cfg_type_t *type, cfg_obj_t **ret) { +cfg_obj_create(cfg_obj_t *file, size_t line, const cfg_type_t *type, + cfg_obj_t **ret) { cfg_obj_t *obj; - REQUIRE(mctx != NULL); REQUIRE(type != NULL); REQUIRE(ret != NULL && *ret == NULL); - obj = isc_mem_get(mctx, sizeof(cfg_obj_t)); + INSIST(isc_g_mctx != NULL); + obj = isc_mem_get(isc_g_mctx, sizeof(cfg_obj_t)); *obj = (cfg_obj_t){ .magic = CFGOBJ_MAGIC, .type = type, .line = line }; isc_refcount_init(&obj->references, 1); - isc_mem_attach(mctx, &obj->mctx); if (file != NULL) { cfg_obj_attach(file, &obj->file); } @@ -3927,9 +3914,8 @@ create_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { isc_symtab_t *symtab = NULL; cfg_obj_t *obj = NULL; - cfg_obj_create(pctx->mctx, cfg_parser_currentfile(pctx), pctx->line, - type, &obj); - isc_symtab_create(pctx->mctx, map_symtabitem_destroy, pctx, false, + cfg_obj_create(cfg_parser_currentfile(pctx), pctx->line, type, &obj); + isc_symtab_create(isc_g_mctx, map_symtabitem_destroy, pctx, false, &symtab); obj->value.map.symtab = symtab; obj->value.map.id = NULL; @@ -3963,7 +3949,7 @@ destroy_cfgobj(cfg_obj_t *obj) { obj->magic = 0; isc_refcount_destroy(&obj->references); - isc_mem_putanddetach(&obj->mctx, obj, sizeof(cfg_obj_t)); + isc_mem_put(isc_g_mctx, obj, sizeof(*obj)); } ISC_REFCOUNT_IMPL(cfg_obj, destroy_cfgobj); @@ -4016,9 +4002,9 @@ map_define(cfg_obj_t *mapobj, cfg_obj_t *obj, const cfg_clausedef_t *clause) { cfg_obj_t *destobj = NULL; cfg_listelt_t *elt = NULL; - create_list(mapobj->mctx, obj->file, obj->line, + create_list(obj->file, obj->line, &cfg_type_implicitlist, &destobj); - create_listelt(destobj, &elt); + cfg_listelt_create(&elt); cfg_obj_attach(obj, &elt->obj); ISC_LIST_APPEND(destobj->value.list, elt, link); symval.as_pointer = destobj; @@ -4037,7 +4023,7 @@ map_define(cfg_obj_t *mapobj, cfg_obj_t *obj, const cfg_clausedef_t *clause) { INSIST(result == ISC_R_SUCCESS); if (destobj->type == &cfg_type_implicitlist) { - create_listelt(destobj, &elt); + cfg_listelt_create(&elt); cfg_obj_attach(obj, &elt->obj); ISC_LIST_APPEND(destobj->value.list, elt, link); } else { @@ -4119,7 +4105,8 @@ cfg_list_addclone(cfg_obj_t *dst, const cfg_obj_t *src, bool prepend) { srcelt = cfg_list_first(src); while (srcelt != NULL) { - cfg_listelt_t *dstelt = isc_mem_get(dst->mctx, sizeof(*dstelt)); + cfg_listelt_t *dstelt = isc_mem_get(isc_g_mctx, + sizeof(*dstelt)); *dstelt = (cfg_listelt_t){ .link = ISC_LINK_INITIALIZER }; cfg_obj_clone(srcelt->obj, &dstelt->obj); From 15aa160e2e4c5bbfa2764be9437d3787d4ad453e Mon Sep 17 00:00:00 2001 From: Colin Vidal Date: Fri, 7 Nov 2025 18:56:39 +0100 Subject: [PATCH 5/6] remove --memstats from cfg_test The `--memstats` option from cfg_test is unused, and even if used, does nothing because `--memstats` relies on `isc_mem_stats` which dump memory pools statistics, which are not used at all for configuration. Also, dropping the option avoid to add a parser API to get the memory stats (as the parser now uses the global memory context). --- doc/misc/cfg_test.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/doc/misc/cfg_test.c b/doc/misc/cfg_test.c index cb17b35e1b..5ef29e45fc 100644 --- a/doc/misc/cfg_test.c +++ b/doc/misc/cfg_test.c @@ -35,7 +35,7 @@ static void usage(void) { fprintf(stderr, "usage: cfg_test --rndc|--named " "[--grammar] [--zonegrammar] [--active] " - "[--memstats] conffile\n"); + "conffile\n"); exit(EXIT_FAILURE); } @@ -55,7 +55,6 @@ main(int argc, char **argv) { cfg_obj_t *cfg = NULL; cfg_type_t *type = NULL; bool grammar = false; - bool memstats = false; char *filename = NULL; unsigned int zonetype = 0; unsigned int pflags = 0; @@ -108,8 +107,6 @@ main(int argc, char **argv) { } else { usage(); } - } else if (strcmp(argv[1], "--memstats") == 0) { - memstats = true; } else if (strcmp(argv[1], "--named") == 0) { type = &cfg_type_namedconf; } else if (strcmp(argv[1], "--rndc") == 0) { @@ -146,13 +143,6 @@ main(int argc, char **argv) { cfg_obj_detach(&cfg); } - if (memstats) { - /* - * TODO: this is memstat of config that we are interested in - * here, right? - */ - isc_mem_stats(mctx, stderr); - } isc_mem_detach(&mctx); fflush(stdout); From c3b7b56dd0345b155d8b98c01eca62b791eb6d45 Mon Sep 17 00:00:00 2001 From: Colin Vidal Date: Thu, 4 Dec 2025 14:02:01 +0100 Subject: [PATCH 6/6] document usage of BIND9 constructors/destructors Document the way `__attribute__((__constructor__))` and `__attribute__((__destructor__))` must be used in BIND9 libraries in order to avoid unexpected behaviors with other third-party libraries. --- lib/dns/include/dns/lib.h | 4 ++++ lib/isc/include/isc/lib.h | 28 ++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/lib/dns/include/dns/lib.h b/lib/dns/include/dns/lib.h index cb88744bbe..9cf053a7c2 100644 --- a/lib/dns/include/dns/lib.h +++ b/lib/dns/include/dns/lib.h @@ -11,6 +11,10 @@ * information regarding copyright ownership. */ +/* + * See `lib/isc/include/isc/lib.h` README + */ + #pragma once #include diff --git a/lib/isc/include/isc/lib.h b/lib/isc/include/isc/lib.h index ee918e7899..412dd9746d 100644 --- a/lib/isc/include/isc/lib.h +++ b/lib/isc/include/isc/lib.h @@ -11,6 +11,34 @@ * information regarding copyright ownership. */ +/* + * BIND9 constructor/destructor README + * ----------------------------------- + * + * A function tagged with `__attribute__((__destructor__))` is called right + * after `main()` returns (or `exit()` is called; see `man atexit` for more + * details). However is a valid assumption _only_ if the function is defined + * inside the binary. + * + * If the function is defined as part of a shared library, it will + * be called only when the library is unloaded by the OS linker. There is no + * way to control the order in which two destructor functions "A" and "B" are + * called if they are defined in separate libraries, because it depends + * on the order in which the OS linker unloads the libraries. + * + * As a consequence, all contructor/destructor functions of BIND9 must be + * defined in `lib//include//lib.h` header and such header must be + * included in each binaries (in each C file defining `main()`) and must not be + * included in any library. + * + * Otherwise, there might be interference. For example, LSAN which could run + * before the BIND9 destructor functions have cleaned up remaining non-root + * memory. + * + * The order of the calls between the BIND9 constructors/destructors is enforced + * by a reference counter in the `__lib_{initialize,shutdown}` functions. + */ + #pragma once #include