From 9ac1f6a9bce355948f413de60a74cbded0f6a2be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20K=C4=99pie=C5=84?= Date: Mon, 31 Aug 2020 13:15:33 +0200 Subject: [PATCH] Add "-T maxcachesize=..." command line option An implicit default of "max-cache-size 90%;" may cause memory use issues on hosts which run numerous named instances in parallel (e.g. GitLab CI runners) due to the cache RBT hash table now being pre-allocated [1] at startup. Add a new command line option, "-T maxcachesize=...", to allow the default value of "max-cache-size" to be overridden at runtime. When this new option is in effect, it overrides any other "max-cache-size" setting in the configuration, either implicit or explicit. This approach was chosen because it is arguably the simplest one to implement. The following alternative approaches to solving this problem were considered and ultimately rejected (after it was decided they were not worth the extra code complexity): - adding the same command line option, but making explicit configuration statements have priority over it, - adding a build-time option that allows the implicit default of "max-cache-size 90%;" to be overridden. [1] see commit e24bc324b455d9cad7b51acd3d5c7b4e40c66187 --- bin/named/include/named/globals.h | 1 + bin/named/main.c | 2 ++ bin/named/server.c | 11 ++++++++++- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/bin/named/include/named/globals.h b/bin/named/include/named/globals.h index 3b6e8d7d65..c923d7c6e5 100644 --- a/bin/named/include/named/globals.h +++ b/bin/named/include/named/globals.h @@ -143,6 +143,7 @@ EXTERN bool named_g_memstatistics INIT(false); EXTERN bool named_g_keepstderr INIT(false); EXTERN unsigned int named_g_tat_interval INIT(24 * 3600); +EXTERN unsigned int named_g_maxcachesize INIT(0); #if defined(HAVE_GEOIP2) EXTERN dns_geoip_databases_t *named_g_geoip INIT(NULL); diff --git a/bin/named/main.c b/bin/named/main.c index b369eed069..d6b7154246 100644 --- a/bin/named/main.c +++ b/bin/named/main.c @@ -650,6 +650,8 @@ parse_T_opt(char *option) { named_g_nosyslog = true; } else if (!strcmp(option, "notcp")) { notcp = true; + } else if (!strncmp(option, "maxcachesize=", 13)) { + named_g_maxcachesize = atoi(option + 13); } else if (!strcmp(option, "maxudp512")) { maxudp = 512; } else if (!strcmp(option, "maxudp1460")) { diff --git a/bin/named/server.c b/bin/named/server.c index 547df1147a..ec66cbcc9e 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -4114,7 +4114,16 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config, obj = NULL; result = named_config_get(maps, "max-cache-size", &obj); INSIST(result == ISC_R_SUCCESS); - if (cfg_obj_isstring(obj)) { + /* + * If "-T maxcachesize=..." is in effect, it overrides any other + * "max-cache-size" setting found in configuration, either implicit or + * explicit. For simplicity, the value passed to that command line + * option is always treated as the number of bytes to set + * "max-cache-size" to. + */ + if (named_g_maxcachesize != 0) { + max_cache_size = named_g_maxcachesize; + } else if (cfg_obj_isstring(obj)) { str = cfg_obj_asstring(obj); INSIST(strcasecmp(str, "unlimited") == 0); max_cache_size = 0;