+4611. [bug] The default LMDB mapsize was too low and caused
+ errors after few thousand zones were added using
+ rndc addzone. A new config option "lmdb-mapsize"
+ has been introduced to configure the LMDB
+ mapsize depending on operational needs.
+ [RT #44954]
+
4610. [func] The "new-zones-directory" option specifies the
location of NZF or NZD files for storing
configuration of zones added by "rndc addzone".
zero-no-soa-ttl-cache no;\n\
nsec3-test-zone no;\n\
allow-new-zones no;\n\
+ lmdb-mapsize 32M;\n\
fetches-per-server 0;\n\
require-server-cookie no;\n\
v6-bias 50;\n\
<!--
- - Copyright (C) 2004-2017 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2017 Internet Systems Consortium, Inc. ("ISC")
-
- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
<refentry xmlns:db="http://docbook.org/ns/docbook" version="5.0" xml:id="man.named.conf">
<info>
- <date>2017-03-08</date>
+ <date>2017-04-25</date>
</info>
<refentryinfo>
<corpname>ISC</corpname>
listen-on-v6 <optional> port <replaceable>integer</replaceable> </optional> <optional> dscp
<replaceable>integer</replaceable> </optional> {
<replaceable>address_match_element</replaceable>; ... };
+ lmdb-mapsize <replaceable>sizeval</replaceable>;
lock-file ( <replaceable>quoted_string</replaceable> | none );
managed-keys-directory <replaceable>quoted_string</replaceable>;
masterfile-format ( map | raw | text );
};
key-directory <replaceable>quoted_string</replaceable>;
lame-ttl <replaceable>ttlval</replaceable>;
+ lmdb-mapsize <replaceable>sizeval</replaceable>;
managed-keys { <replaceable>string</replaceable> <replaceable>string</replaceable>
<replaceable>integer</replaceable> <replaceable>integer</replaceable> <replaceable>integer</replaceable>
<replaceable>quoted_string</replaceable>; ... };
const cfg_obj_t *nz = NULL;
const cfg_obj_t *nzdir = NULL;
const char *dir = NULL;
+ const cfg_obj_t *obj = NULL;
int i = 0;
+ isc_uint64_t mapsize = 0ULL;
REQUIRE (config != NULL);
dns_view_setnewzonedir(view, dir);
}
+#ifdef HAVE_LMDB
+ result = ns_config_get(maps, "lmdb-mapsize", &obj);
+ if (result == ISC_R_SUCCESS && obj != NULL) {
+ mapsize = cfg_obj_asuint64(obj);
+ if (mapsize < (1ULL << 20)) { /* 1 megabyte */
+ cfg_obj_log(obj, ns_g_lctx,
+ ISC_LOG_ERROR,
+ "'lmdb-mapsize "
+ "%" ISC_PRINT_QUADFORMAT "d' "
+ "is too small",
+ mapsize);
+ return (ISC_R_FAILURE);
+ } else if (mapsize > (1ULL << 40)) { /* 1 terabyte */
+ cfg_obj_log(obj, ns_g_lctx,
+ ISC_LOG_ERROR,
+ "'lmdb-mapsize "
+ "%" ISC_PRINT_QUADFORMAT "d' "
+ "is too large",
+ mapsize);
+ return (ISC_R_FAILURE);
+ }
+ }
+#else
+ UNUSED(obj);
+#endif /* HAVE_LMDB */
+
/*
* A non-empty catalog-zones statement implies allow-new-zones
*/
}
if (!allow) {
- dns_view_setnewzones(view, ISC_FALSE, NULL, NULL);
+ dns_view_setnewzones(view, ISC_FALSE, NULL, NULL, 0ULL);
if (num_zones != NULL)
*num_zones = 0;
return (ISC_R_SUCCESS);
nzcfg = isc_mem_get(view->mctx, sizeof(*nzcfg));
if (nzcfg == NULL) {
- dns_view_setnewzones(view, ISC_FALSE, NULL, NULL);
+ dns_view_setnewzones(view, ISC_FALSE, NULL, NULL, 0ULL);
return (ISC_R_NOMEMORY);
}
memset(nzcfg, 0, sizeof(*nzcfg));
result = dns_view_setnewzones(view, ISC_TRUE, nzcfg,
- newzone_cfgctx_destroy);
+ newzone_cfgctx_destroy, mapsize);
if (result != ISC_R_SUCCESS) {
isc_mem_free(view->mctx, nzcfg);
return (result);
const cfg_obj_t *zoptions;
result = isc_buffer_allocate(view->mctx, &text, 256);
- if (result != ISC_R_SUCCESS)
+ if (result != ISC_R_SUCCESS) {
+ isc_log_write(ns_g_lctx,
+ NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_SERVER,
+ ISC_LOG_ERROR,
+ "Unable to allocate buffer in "
+ "nzd_save(): %s",
+ isc_result_totext(result));
goto cleanup;
+ }
zoptions = cfg_tuple_get(zconfig, "options");
if (zoptions == NULL) {
+ isc_log_write(ns_g_lctx,
+ NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_SERVER,
+ ISC_LOG_ERROR,
+ "Unable to get options from config in "
+ "nzd_save()");
result = ISC_R_FAILURE;
goto cleanup;
}
(void) mdb_txn_abort(*txnp);
else {
status = mdb_txn_commit(*txnp);
- if (status != 0)
+ if (status != 0) {
+ isc_log_write(ns_g_lctx,
+ NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_SERVER,
+ ISC_LOG_ERROR,
+ "Error committing "
+ "NZD database: %s",
+ mdb_strerror(status));
result = ISC_R_FAILURE;
+ }
}
*txnp = NULL;
if (view->redirect == NULL)
CHECK(ISC_R_NOTFOUND);
dns_zone_attach(view->redirect, &zone);
- } else
- CHECK(dns_zt_find(view->zonetable, name, 0, NULL, &zone));
+ } else {
+ result = dns_zt_find(view->zonetable, name, 0, NULL, &zone);
+ if (result != ISC_R_SUCCESS) {
+ isc_log_write(ns_g_lctx,
+ NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_SERVER,
+ ISC_LOG_ERROR,
+ "added new zone was not found: %s",
+ isc_result_totext(result));
+ goto cleanup;
+ }
+ }
#ifndef HAVE_LMDB
/*
--- /dev/null
+/*
+ * Copyright (C) 2016 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+options {
+ lmdb-mapsize bogusvalue;
+};
--- /dev/null
+/*
+ * Copyright (C) 2016 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+options {
+ lmdb-mapsize 2048G;
+};
--- /dev/null
+/*
+ * Copyright (C) 2016 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+options {
+ lmdb-mapsize 1;
+};
--- /dev/null
+/*
+ * Copyright (C) 2016 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+options {
+ lmdb-mapsize unlimited;
+};
--- /dev/null
+/*
+ * Copyright (C) 2016 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+options {
+ lmdb-mapsize 1024G;
+};
--- /dev/null
+/*
+ * Copyright (C) 2016 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+options {
+ lmdb-mapsize 1M;
+};
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><command>lmdb-mapsize</command></term>
+ <listitem>
+ <para>
+ When <command>named</command> is built with liblmdb,
+ this option sets a maximum size for the memory map of
+ the new-zone database (NZD) in LMDB database format.
+ This database is used to store configuration information
+ for zones added using <command>rndc addzone</command>.
+ Note that this is not the NZD database file size, but
+ the largest size that the database may grow to.
+ </para>
+ <para>
+ Because the database file is memory mapped, its size is
+ limited by the address space of the named process. The
+ default of 32 megabytes was chosen to be usable with
+ 32-bit <command>named</command> builds. The largest
+ permitted value is 1 terabyte. Given typical zone
+ configurations without elaborate ACLs, a 32 MB NZD file
+ ought to be able to hold configurations of about 100,000
+ zones.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term><command>managed-keys-directory</command></term>
<listitem>
incompatible with use as a file name, in which case a
cryptographic hash of the view name is used instead.
</para>
+ <para>
+ Zones added at runtime will have their configuration
+ stored either in a new-zone file (NZF) or a new-zone
+ database (NZD) depending on whether
+ <command>named</command> was linked with
+ liblmdb at compile time.
+ See <xref linkend="man.rndc"/> for further details
+ about <command>rndc addzone</command>.
+ </para>
</listitem>
</varlistentry>
listen-on-v6 [ port <integer> ] [ dscp
<integer> ] {
<address_match_element>; ... }; // may occur multiple times
+ lmdb-mapsize <sizeval>;
lock-file ( <quoted_string> | none );
maintain-ixfr-base <boolean>; // obsolete
managed-keys-directory <quoted_string>;
}; // may occur multiple times
key-directory <quoted_string>;
lame-ttl <ttlval>;
+ lmdb-mapsize <sizeval>;
maintain-ixfr-base <boolean>; // obsolete
managed-keys { <string> <string>
<integer> <integer> <integer>
#include <isc/netaddr.h>
#include <isc/parseint.h>
#include <isc/platform.h>
+#include <isc/print.h>
#include <isc/region.h>
#include <isc/result.h>
#include <isc/sha1.h>
}
#endif
+ obj = NULL;
+ (void)cfg_map_get(options, "lmdb-mapsize", &obj);
+ if (obj != NULL) {
+ isc_uint64_t mapsize = cfg_obj_asuint64(obj);
+
+ if (mapsize < (1ULL << 20)) { /* 1 megabyte */
+ cfg_obj_log(obj, logctx,
+ ISC_LOG_ERROR,
+ "'lmdb-mapsize "
+ "%" ISC_PRINT_QUADFORMAT "d' "
+ "is too small",
+ mapsize);
+ return (ISC_R_RANGE);
+ } else if (mapsize > (1ULL << 40)) { /* 1 terabyte */
+ cfg_obj_log(obj, logctx,
+ ISC_LOG_ERROR,
+ "'lmdb-mapsize "
+ "%" ISC_PRINT_QUADFORMAT "d' "
+ "is too large",
+ mapsize);
+ return (ISC_R_RANGE);
+ }
+ }
+
return (result);
}
isc_result_t
dns_view_setnewzones(dns_view_t *view, isc_boolean_t allow, void *cfgctx,
- void (*cfg_destroy)(void **));
+ void (*cfg_destroy)(void **), isc_uint64_t mapsize);
/*%<
* Set whether or not to allow zones to be created or deleted at runtime.
*
if (view->dtenv != NULL)
dns_dt_detach(&view->dtenv);
#endif /* HAVE_DNSTAP */
- dns_view_setnewzones(view, ISC_FALSE, NULL, NULL);
+ dns_view_setnewzones(view, ISC_FALSE, NULL, NULL, 0ULL);
if (view->new_zone_file != NULL) {
isc_mem_free(view->mctx, view->new_zone_file);
view->new_zone_file = NULL;
isc_result_t
dns_view_setnewzones(dns_view_t *view, isc_boolean_t allow, void *cfgctx,
- void (*cfg_destroy)(void **))
+ void (*cfg_destroy)(void **), isc_uint64_t mapsize)
{
isc_result_t result;
char buffer[1024];
goto out;
}
+ if (mapsize != 0ULL) {
+ status = mdb_env_set_mapsize(env, mapsize);
+ if (status != 0) {
+ result = ISC_R_FAILURE;
+ goto out;
+ }
+ }
+
status = mdb_env_open(env, view->new_zone_db,
MDB_NOSUBDIR|MDB_CREATE, 0600);
if (status != 0) {
#define CFG_CLAUSEFLAG_NOTCONFIGURED 0x00000080
/*% A option for a experimental feature. */
#define CFG_CLAUSEFLAG_EXPERIMENTAL 0x00000100
+/*% A configuration option that is ineffective due to
+ * compile time options, but is harmless. */
+#define CFG_CLAUSEFLAG_NOOP 0x00000200
typedef struct cfg_clausedef cfg_clausedef_t;
typedef struct cfg_tuplefielddef cfg_tuplefielddef_t;
static cfg_type_t cfg_type_size;
static cfg_type_t cfg_type_sizenodefault;
static cfg_type_t cfg_type_sizeorpercent;
+static cfg_type_t cfg_type_sizeval;
static cfg_type_t cfg_type_sockaddr4wild;
static cfg_type_t cfg_type_sockaddr6wild;
static cfg_type_t cfg_type_statschannels;
#endif
{ "ixfr-from-differences", &cfg_type_ixfrdifftype, 0 },
{ "lame-ttl", &cfg_type_ttlval, 0 },
+#ifdef HAVE_LMDB
+ { "lmdb-mapsize", &cfg_type_sizeval, 0 },
+#else
+ { "lmdb-mapsize", &cfg_type_sizeval, CFG_CLAUSEFLAG_NOOP },
+#endif
{ "nocookie-udp-size", &cfg_type_uint32, 0 },
{ "nosit-udp-size", &cfg_type_uint32, CFG_CLAUSEFLAG_OBSOLETE },
{ "max-acache-size", &cfg_type_sizenodefault,
cfg_parser_warning(pctx, 0, "option '%s' is "
"not implemented", clause->name);
+ if ((clause->flags & CFG_CLAUSEFLAG_NOOP) != 0) {
+ cfg_parser_warning(pctx, 0, "option '%s' was not "
+ "enabled at compile time "
+ "(ignored)", clause->name);
+ }
+
if ((clause->flags & CFG_CLAUSEFLAG_NOTCONFIGURED) != 0) {
cfg_parser_warning(pctx, 0, "option '%s' was not "
"enabled at compile time",
{ CFG_CLAUSEFLAG_NOTCONFIGURED, "not configured" },
{ CFG_CLAUSEFLAG_MULTI, "may occur multiple times" },
{ CFG_CLAUSEFLAG_EXPERIMENTAL, "experimental" },
+ { CFG_CLAUSEFLAG_NOOP, "non-operational" },
{ 0, NULL }
};