2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-31 06:25:31 +00:00

Use minimal-sized caches for non-recursive views

Currently the implicit default for the "max-cache-size" option is "90%".
As this option is inherited by all configured views, using multiple
views can lead to memory exhaustion over time due to overcommitment.
The "max-cache-size 90%;" default also causes cache RBT hash tables to
be preallocated for every configured view, which does not really make
sense for views which do not allow recursion.

To limit this problem's potential for causing operational issues, use a
minimal-sized cache for views which do not allow recursion and do not
have "max-cache-size" explicitly set (either in global configuration or
in view configuration).

For configurations which include multiple views allowing recursion,
adjusting "max-cache-size" appropriately is still left to the operator.
This commit is contained in:
Michał Kępień
2021-06-22 15:28:31 +02:00
parent a02710a476
commit 86541b39d3

View File

@@ -3971,6 +3971,42 @@ register_one_plugin(const cfg_obj_t *config, const cfg_obj_t *obj,
return (result);
}
/*
* Determine if a minimal-sized cache can be used for a given view, according
* to 'maps' (implicit defaults, global options, view options) and 'optionmaps'
* (global options, view options). This is only allowed for views which have
* recursion disabled and do not have "max-cache-size" set explicitly. Using
* minimal-sized caches prevents a situation in which all explicitly configured
* and built-in views inherit the default "max-cache-size 90%;" setting, which
* could lead to memory exhaustion with multiple views configured.
*/
static bool
minimal_cache_allowed(const cfg_obj_t *maps[4],
const cfg_obj_t *optionmaps[3]) {
const cfg_obj_t *obj;
/*
* Do not use a minimal-sized cache for a view with recursion enabled.
*/
obj = NULL;
(void)named_config_get(maps, "recursion", &obj);
INSIST(obj != NULL);
if (cfg_obj_asboolean(obj)) {
return (false);
}
/*
* Do not use a minimal-sized cache if a specific size was requested.
*/
obj = NULL;
(void)named_config_get(optionmaps, "max-cache-size", &obj);
if (obj != NULL) {
return (false);
}
return (true);
}
/*
* Configure 'view' according to 'vconfig', taking defaults from
* 'config' where values are missing in 'vconfig'.
@@ -4236,6 +4272,12 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config,
*/
if (named_g_maxcachesize != 0) {
max_cache_size = named_g_maxcachesize;
} else if (minimal_cache_allowed(maps, optionmaps)) {
/*
* dns_cache_setcachesize() will adjust this to the smallest
* allowed value.
*/
max_cache_size = 1;
} else if (cfg_obj_isstring(obj)) {
str = cfg_obj_asstring(obj);
INSIST(strcasecmp(str, "unlimited") == 0);