rem: usr: Remove NZF file support in favor of NZD (New Zone Database)

The NZF (New Zone File) backend for storing rndc addzone configurations
has been removed; LMDB-based NZD is now the only storage backend and
LMDB is now a required build dependency.

Existing NZF files are automatically migrated to NZD on startup, so no manual
intervention is required when upgrading.

Merge branch 'ondrej/drop-nzf-support' into 'main'

See merge request isc-projects/bind9!11688
This commit is contained in:
Ondřej Surý 2026-03-18 11:37:31 +01:00
commit 929eccdfdc
20 changed files with 633 additions and 1070 deletions

View file

@ -1424,7 +1424,6 @@ unit:gcc:ossl3:amd64:
artifacts: true artifacts: true
# Jobs for regular GCC builds on Debian "sid" (amd64) # Jobs for regular GCC builds on Debian "sid" (amd64)
# Also tests configration option: -Dlmdb=disabled
gcc:sid:amd64: gcc:sid:amd64:
<<: *debian_sid_amd64_image <<: *debian_sid_amd64_image
@ -1432,7 +1431,7 @@ gcc:sid:amd64:
variables: variables:
CC: gcc CC: gcc
CFLAGS: "${CFLAGS_COMMON}" CFLAGS: "${CFLAGS_COMMON}"
EXTRA_CONFIGURE: "-Doptimization=3 -Didn=enabled -Dlmdb=disabled" EXTRA_CONFIGURE: "-Doptimization=3 -Didn=enabled"
system:gcc:sid:amd64: system:gcc:sid:amd64:
<<: *debian_sid_amd64_image <<: *debian_sid_amd64_image

View file

@ -138,11 +138,9 @@ options {\n\
fetch-quota-params 100 0.1 0.3 0.7;\n\ fetch-quota-params 100 0.1 0.3 0.7;\n\
fetches-per-server 0;\n\ fetches-per-server 0;\n\
fetches-per-zone 0;\n\ fetches-per-zone 0;\n\
lame-ttl 0;\n" lame-ttl 0;\n\
#ifdef HAVE_LMDB lmdb-mapsize 32M;\n\
" lmdb-mapsize 32M;\n" max-cache-size default;\n\
#endif /* ifdef HAVE_LMDB */
" max-cache-size default;\n\
max-cache-ttl 604800; /* 1 week */\n\ max-cache-ttl 604800; /* 1 week */\n\
max-clients-per-query 100;\n\ max-clients-per-query 100;\n\
max-delegation-servers 13;\n\ max-delegation-servers 13;\n\

View file

@ -0,0 +1,55 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* SPDX-License-Identifier: MPL-2.0
*
* 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 https://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
#pragma once
#include <lmdb.h>
#include <isc/buffer.h>
#include <isc/magic.h>
#include <isc/result.h>
#include <dns/view.h>
#define DZARG_MAGIC ISC_MAGIC('D', 'z', 'a', 'r')
typedef struct {
unsigned int magic;
isc_buffer_t *text;
isc_result_t result;
} ns_dzarg_t;
isc_result_t
nzd_writable(dns_view_t *view);
isc_result_t
nzd_open(dns_view_t *view, unsigned int flags, MDB_txn **txnp, MDB_dbi *dbi);
isc_result_t
nzd_env_reopen(dns_view_t *view);
void
nzd_env_close(dns_view_t *view);
isc_result_t
nzd_close(MDB_txn **txnp, bool commit);
isc_result_t
nzd_save(MDB_txn **txnp, MDB_dbi dbi, dns_zone_t *zone,
const cfg_obj_t *zconfig);
isc_result_t
nzd_load_nzf(dns_view_t *view);
void
nzd_setkey(MDB_val *key, dns_name_t *name, char *namebuf, size_t buflen);

View file

@ -32,6 +32,7 @@ named_srcset.add(
'log.c', 'log.c',
'logconf.c', 'logconf.c',
'main.c', 'main.c',
'nzd.c',
'os.c', 'os.c',
'server.c', 'server.c',
'statschannel.c', 'statschannel.c',

492
bin/named/nzd.c Normal file
View file

@ -0,0 +1,492 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* SPDX-License-Identifier: MPL-2.0
*
* 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 https://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
#include <lmdb.h>
#include <isc/file.h>
#include <dns/fixedname.h>
#include <dns/name.h>
#include <dns/zone.h>
#include <isccfg/cfg.h>
#include <isccfg/namedconf.h>
#include <named/nzd.h>
#include <named/os.h>
void
nzd_setkey(MDB_val *key, dns_name_t *name, char *namebuf, size_t buflen) {
dns_fixedname_t fixed;
dns_fixedname_init(&fixed);
dns_name_downcase(name, dns_fixedname_name(&fixed));
dns_name_format(dns_fixedname_name(&fixed), namebuf, buflen);
key->mv_data = namebuf;
key->mv_size = strlen(namebuf);
}
static void
dumpzone(void *arg, const char *buf, int len) {
ns_dzarg_t *dzarg = arg;
isc_result_t result;
REQUIRE(dzarg != NULL && ISC_MAGIC_VALID(dzarg, DZARG_MAGIC));
result = isc_buffer_reserve(dzarg->text, (unsigned int)len);
if (result == ISC_R_SUCCESS) {
isc_buffer_putmem(dzarg->text, (const unsigned char *)buf, len);
} else if (dzarg->result == ISC_R_SUCCESS) {
dzarg->result = result;
}
}
isc_result_t
nzd_save(MDB_txn **txnp, MDB_dbi dbi, dns_zone_t *zone,
const cfg_obj_t *zconfig) {
isc_result_t result;
int status;
dns_view_t *view;
bool commit = false;
isc_buffer_t *text = NULL;
char namebuf[1024];
MDB_val key, data;
ns_dzarg_t dzarg;
view = dns_zone_getview(zone);
nzd_setkey(&key, dns_zone_getorigin(zone), namebuf, sizeof(namebuf));
if (zconfig == NULL) {
/* We're deleting the zone from the database */
status = mdb_del(*txnp, dbi, &key, NULL);
if (status != MDB_SUCCESS && status != MDB_NOTFOUND) {
isc_log_write(NAMED_LOGCATEGORY_GENERAL,
NAMED_LOGMODULE_SERVER, ISC_LOG_ERROR,
"Error deleting zone %s "
"from NZD database: %s",
namebuf, mdb_strerror(status));
CLEANUP(ISC_R_FAILURE);
} else if (status != MDB_NOTFOUND) {
commit = true;
}
} else {
/* We're creating or overwriting the zone */
const cfg_obj_t *zoptions = cfg_tuple_get(zconfig, "options");
isc_buffer_allocate(view->mctx, &text, 256);
if (zoptions == NULL) {
isc_log_write(NAMED_LOGCATEGORY_GENERAL,
NAMED_LOGMODULE_SERVER, ISC_LOG_ERROR,
"Unable to get options from config in "
"nzd_save()");
CLEANUP(ISC_R_FAILURE);
}
dzarg.magic = DZARG_MAGIC;
dzarg.text = text;
dzarg.result = ISC_R_SUCCESS;
cfg_printx(zoptions, CFG_PRINTER_ONELINE, dumpzone, &dzarg);
if (dzarg.result != ISC_R_SUCCESS) {
isc_log_write(NAMED_LOGCATEGORY_GENERAL,
NAMED_LOGMODULE_SERVER, ISC_LOG_ERROR,
"Error writing zone config to "
"buffer in nzd_save(): %s",
isc_result_totext(dzarg.result));
CHECK(dzarg.result);
}
data.mv_data = isc_buffer_base(text);
data.mv_size = isc_buffer_usedlength(text);
status = mdb_put(*txnp, dbi, &key, &data, 0);
if (status != MDB_SUCCESS) {
isc_log_write(NAMED_LOGCATEGORY_GENERAL,
NAMED_LOGMODULE_SERVER, ISC_LOG_ERROR,
"Error inserting zone in "
"NZD database: %s",
mdb_strerror(status));
CLEANUP(ISC_R_FAILURE);
}
commit = true;
}
result = ISC_R_SUCCESS;
cleanup:
if (!commit || result != ISC_R_SUCCESS) {
(void)mdb_txn_abort(*txnp);
} else {
status = mdb_txn_commit(*txnp);
if (status != MDB_SUCCESS) {
isc_log_write(NAMED_LOGCATEGORY_GENERAL,
NAMED_LOGMODULE_SERVER, ISC_LOG_ERROR,
"Error committing "
"NZD database: %s",
mdb_strerror(status));
result = ISC_R_FAILURE;
}
}
*txnp = NULL;
if (text != NULL) {
isc_buffer_free(&text);
}
return result;
}
/*
* Check whether the new zone database for 'view' can be opened for writing.
*
* Caller must hold 'view->newzone.lock'.
*/
isc_result_t
nzd_writable(dns_view_t *view) {
isc_result_t result = ISC_R_SUCCESS;
int status;
MDB_dbi dbi;
MDB_txn *txn = NULL;
REQUIRE(view != NULL);
status = mdb_txn_begin(view->newzone.dbenv, 0, 0, &txn);
if (status != MDB_SUCCESS) {
isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER,
ISC_LOG_WARNING, "mdb_txn_begin: %s",
mdb_strerror(status));
return ISC_R_FAILURE;
}
status = mdb_dbi_open(txn, NULL, 0, &dbi);
if (status != MDB_SUCCESS) {
isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER,
ISC_LOG_WARNING, "mdb_dbi_open: %s",
mdb_strerror(status));
result = ISC_R_FAILURE;
}
mdb_txn_abort(txn);
return result;
}
/*
* Open the new zone database for 'view' and start a transaction for it.
*
* Caller must hold 'view->newzone.lock'.
*/
isc_result_t
nzd_open(dns_view_t *view, unsigned int flags, MDB_txn **txnp, MDB_dbi *dbi) {
int status;
MDB_txn *txn = NULL;
REQUIRE(view != NULL);
REQUIRE(txnp != NULL && *txnp == NULL);
REQUIRE(dbi != NULL);
status = mdb_txn_begin(view->newzone.dbenv, 0, flags, &txn);
if (status != MDB_SUCCESS) {
isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER,
ISC_LOG_WARNING, "mdb_txn_begin: %s",
mdb_strerror(status));
goto cleanup;
}
status = mdb_dbi_open(txn, NULL, 0, dbi);
if (status != MDB_SUCCESS) {
isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER,
ISC_LOG_WARNING, "mdb_dbi_open: %s",
mdb_strerror(status));
goto cleanup;
}
*txnp = txn;
cleanup:
if (status != MDB_SUCCESS) {
if (txn != NULL) {
mdb_txn_abort(txn);
}
return ISC_R_FAILURE;
}
return ISC_R_SUCCESS;
}
/*
* nzd_env_close() and nzd_env_reopen() are a kluge to address the
* problem of an NZD file possibly being created before we drop
* root privileges.
*/
void
nzd_env_close(dns_view_t *view) {
const char *dbpath = NULL;
char dbpath_copy[PATH_MAX];
char lockpath[PATH_MAX];
int status, ret;
if (view->newzone.dbenv == NULL) {
return;
}
status = mdb_env_get_path(view->newzone.dbenv, &dbpath);
INSIST(status == MDB_SUCCESS);
snprintf(lockpath, sizeof(lockpath), "%s-lock", dbpath);
strlcpy(dbpath_copy, dbpath, sizeof(dbpath_copy));
mdb_env_close(view->newzone.dbenv);
/*
* Database files must be owned by the eventual user, not by root.
*/
ret = chown(dbpath_copy, named_os_uid(), -1);
UNUSED(ret);
/*
* Some platforms need the lockfile not to exist when we reopen the
* environment.
*/
(void)isc_file_remove(lockpath);
view->newzone.dbenv = NULL;
}
isc_result_t
nzd_env_reopen(dns_view_t *view) {
isc_result_t result;
MDB_env *env = NULL;
int status;
if (view->newzone.db == NULL) {
return ISC_R_SUCCESS;
}
nzd_env_close(view);
status = mdb_env_create(&env);
if (status != MDB_SUCCESS) {
isc_log_write(DNS_LOGCATEGORY_GENERAL, ISC_LOGMODULE_OTHER,
ISC_LOG_ERROR, "mdb_env_create failed: %s",
mdb_strerror(status));
CLEANUP(ISC_R_FAILURE);
}
if (view->newzone.mapsize != 0ULL) {
status = mdb_env_set_mapsize(env, view->newzone.mapsize);
if (status != MDB_SUCCESS) {
isc_log_write(DNS_LOGCATEGORY_GENERAL,
ISC_LOGMODULE_OTHER, ISC_LOG_ERROR,
"mdb_env_set_mapsize failed: %s",
mdb_strerror(status));
CLEANUP(ISC_R_FAILURE);
}
}
status = mdb_env_open(env, view->newzone.db, DNS_LMDB_FLAGS, 0600);
if (status != MDB_SUCCESS) {
isc_log_write(DNS_LOGCATEGORY_GENERAL, ISC_LOGMODULE_OTHER,
ISC_LOG_ERROR, "mdb_env_open of '%s' failed: %s",
view->newzone.db, mdb_strerror(status));
CLEANUP(ISC_R_FAILURE);
}
view->newzone.dbenv = env;
env = NULL;
result = ISC_R_SUCCESS;
cleanup:
if (env != NULL) {
mdb_env_close(env);
}
return result;
}
/*
* If 'commit' is true, commit the new zone database transaction pointed to by
* 'txnp'; otherwise, abort that transaction.
*
* Caller must hold 'view->newzone.lock' for the view that the transaction
* pointed to by 'txnp' was started for.
*/
isc_result_t
nzd_close(MDB_txn **txnp, bool commit) {
isc_result_t result = ISC_R_SUCCESS;
int status;
REQUIRE(txnp != NULL);
if (*txnp != NULL) {
if (commit) {
status = mdb_txn_commit(*txnp);
if (status != MDB_SUCCESS) {
result = ISC_R_FAILURE;
}
} else {
mdb_txn_abort(*txnp);
}
*txnp = NULL;
}
return result;
}
/*
* If there's an existing NZF file, load it and migrate its data
* to the NZD.
*
* Caller must hold view->newzone.lock.
*/
isc_result_t
nzd_load_nzf(dns_view_t *view) {
isc_result_t result;
cfg_obj_t *nzf_config = NULL;
int status;
isc_buffer_t *text = NULL;
bool commit = false;
const cfg_obj_t *zonelist = NULL;
char tempname[PATH_MAX];
MDB_txn *txn = NULL;
MDB_dbi dbi;
MDB_val key, data;
ns_dzarg_t dzarg;
/*
* If NZF file doesn't exist, or NZD DB exists and already
* has data, return without attempting migration.
*/
if (!isc_file_exists(view->newzone.file)) {
result = ISC_R_SUCCESS;
goto cleanup;
}
isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER,
ISC_LOG_INFO,
"Migrating zones from NZF file '%s' to "
"NZD database '%s'",
view->newzone.file, view->newzone.db);
/*
* Instead of blindly copying lines, we parse the NZF file using
* the configuration parser, because it validates it against the
* config type, giving us a guarantee that valid configuration
* will be written to DB.
*/
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",
view->newzone.file, isc_result_totext(result));
goto cleanup;
}
zonelist = NULL;
CHECK(cfg_map_get(nzf_config, "zone", &zonelist));
if (!cfg_obj_islist(zonelist)) {
CLEANUP(ISC_R_FAILURE);
}
CHECK(nzd_open(view, 0, &txn, &dbi));
isc_buffer_allocate(view->mctx, &text, 256);
CFG_LIST_FOREACH(zonelist, element) {
const cfg_obj_t *zconfig = cfg_listelt_value(element);
const cfg_obj_t *zoptions;
char zname[DNS_NAME_FORMATSIZE];
dns_fixedname_t fname;
dns_name_t *name = NULL;
const char *origin = NULL;
isc_buffer_t b;
origin = cfg_obj_asstring(cfg_tuple_get(zconfig, "name"));
if (origin == NULL) {
CLEANUP(ISC_R_FAILURE);
}
/* Normalize zone name */
isc_buffer_constinit(&b, origin, strlen(origin));
isc_buffer_add(&b, strlen(origin));
name = dns_fixedname_initname(&fname);
CHECK(dns_name_fromtext(name, &b, dns_rootname,
DNS_NAME_DOWNCASE));
dns_name_format(name, zname, sizeof(zname));
key.mv_data = zname;
key.mv_size = strlen(zname);
zoptions = cfg_tuple_get(zconfig, "options");
if (zoptions == NULL) {
CLEANUP(ISC_R_FAILURE);
}
isc_buffer_clear(text);
dzarg.magic = DZARG_MAGIC;
dzarg.text = text;
dzarg.result = ISC_R_SUCCESS;
cfg_printx(zoptions, CFG_PRINTER_ONELINE, dumpzone, &dzarg);
if (dzarg.result != ISC_R_SUCCESS) {
isc_log_write(NAMED_LOGCATEGORY_GENERAL,
NAMED_LOGMODULE_SERVER, ISC_LOG_ERROR,
"Error writing zone config to "
"buffer in load_nzf(): %s",
isc_result_totext(result));
CHECK(dzarg.result);
}
data.mv_data = isc_buffer_base(text);
data.mv_size = isc_buffer_usedlength(text);
status = mdb_put(txn, dbi, &key, &data, MDB_NOOVERWRITE);
if (status != MDB_SUCCESS) {
isc_log_write(NAMED_LOGCATEGORY_GENERAL,
NAMED_LOGMODULE_SERVER, ISC_LOG_ERROR,
"Error inserting zone in "
"NZD database: %s",
mdb_strerror(status));
CLEANUP(ISC_R_FAILURE);
}
commit = true;
}
result = ISC_R_SUCCESS;
/*
* Leaving the NZF file in place is harmless as we won't use it
* if an NZD database is found for the view. But we rename NZF file
* to a backup name here.
*/
strlcpy(tempname, view->newzone.file, sizeof(tempname));
if (strlen(tempname) < sizeof(tempname) - 1) {
strlcat(tempname, "~", sizeof(tempname));
isc_file_rename(view->newzone.file, tempname);
}
cleanup:
if (result != ISC_R_SUCCESS) {
(void)nzd_close(&txn, false);
} else {
result = nzd_close(&txn, commit);
}
if (text != NULL) {
isc_buffer_free(&text);
}
if (nzf_config != NULL) {
cfg_obj_detach(&nzf_config);
}
return result;
}

File diff suppressed because it is too large Load diff

View file

@ -133,8 +133,7 @@ Currently supported commands are:
string specified on the command line is the zone configuration text string specified on the command line is the zone configuration text
that would ordinarily be placed in :iscman:`named.conf`. that would ordinarily be placed in :iscman:`named.conf`.
The configuration is saved in a file called ``viewname.nzf`` (or, if The configuration is saved in an LMDB database file called
:iscman:`named` is compiled with liblmdb, an LMDB database file called
``viewname.nzd``). ``viewname`` is the name of the view, unless the view ``viewname.nzd``). ``viewname`` is the name of the view, unless the view
name contains characters that are incompatible with use as a file name contains characters that are incompatible with use as a file
name, in which case a cryptographic hash of the view name is used name, in which case a cryptographic hash of the view name is used

View file

@ -67,13 +67,11 @@ n=$((n + 1))
if [ $ret != 0 ]; then echo_i "failed"; fi if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status + ret)) status=$((status + ret))
if $FEATURETEST --with-lmdb; then echo_i "checking that existing NZF file was renamed after migration ($n)"
echo_i "checking that existing NZF file was renamed after migration ($n)" [ -e ns2/3bf305731dd26307.nzf~ ] || ret=1
[ -e ns2/3bf305731dd26307.nzf~ ] || ret=1 n=$((n + 1))
n=$((n + 1)) if [ $ret != 0 ]; then echo_i "failed"; fi
if [ $ret != 0 ]; then echo_i "failed"; fi status=$((status + ret))
status=$((status + ret))
fi
echo_i "adding new zone ($n)" echo_i "adding new zone ($n)"
ret=0 ret=0
@ -146,16 +144,6 @@ n=$((n + 1))
if [ $ret != 0 ]; then echo_i "failed"; fi if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status + ret)) status=$((status + ret))
if ! $FEATURETEST --with-lmdb; then
echo_i "verifying no comments in NZF file ($n)"
ret=0
hcount=$(grep "^# New zone file for view: _default" ns2/3bf305731dd26307.nzf | wc -l)
[ $hcount -eq 0 ] || ret=1
n=$((n + 1))
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status + ret))
fi
echo_i "checking rndc showzone with previously added zone ($n)" echo_i "checking rndc showzone with previously added zone ($n)"
ret=0 ret=0
$RNDCCMD 10.53.0.2 showzone previous.example >rndc.out.ns2.$n $RNDCCMD 10.53.0.2 showzone previous.example >rndc.out.ns2.$n
@ -165,13 +153,11 @@ n=$((n + 1))
if [ $ret != 0 ]; then echo_i "failed"; fi if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status + ret)) status=$((status + ret))
if $FEATURETEST --with-lmdb; then echo_i "checking zone is present in NZD ($n)"
echo_i "checking zone is present in NZD ($n)" ret=0
ret=0 $NZD2NZF ns2/_default.nzd | grep previous.example >/dev/null || ret=1
$NZD2NZF ns2/_default.nzd | grep previous.example >/dev/null || ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi
if [ $ret != 0 ]; then echo_i "failed"; fi status=$((status + ret))
status=$((status + ret))
fi
echo_i "deleting previously added zone ($n)" echo_i "deleting previously added zone ($n)"
ret=0 ret=0
@ -191,22 +177,10 @@ check_nzd2nzf() (
&& ! grep previous.example nzd2nzf.out.$n >/dev/null && ! grep previous.example nzd2nzf.out.$n >/dev/null
) )
if $FEATURETEST --with-lmdb; then echo_i "checking zone was deleted from NZD ($n)"
echo_i "checking zone was deleted from NZD ($n)" retry_quiet 10 check_nzd2nzf || ret=1
retry_quiet 10 check_nzd2nzf || ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi
if [ $ret != 0 ]; then echo_i "failed"; fi status=$((status + ret))
status=$((status + ret))
fi
if ! $FEATURETEST --with-lmdb; then
echo_i "checking NZF file now has comment ($n)"
ret=0
hcount=$(grep "^# New zone file for view: _default" ns2/3bf305731dd26307.nzf | wc -l)
[ $hcount -eq 1 ] || ret=1
n=$((n + 1))
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status + ret))
fi
echo_i "deleting newly added zone added.example ($n)" echo_i "deleting newly added zone added.example ($n)"
ret=0 ret=0
@ -526,24 +500,12 @@ n=$((n + 1))
if [ $ret != 0 ]; then echo_i "failed"; fi if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status + ret)) status=$((status + ret))
if ! $FEATURETEST --with-lmdb; then echo_i "verifying added.example in external view created an external.nzd DB ($n)"
echo_i "checking new NZF file has comment ($n)" ret=0
ret=0 [ -e ns2/external.nzd ] || ret=1
hcount=$(grep "^# New zone file for view: external" ns2/external.nzf | wc -l) n=$((n + 1))
[ $hcount -eq 1 ] || ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi
n=$((n + 1)) status=$((status + ret))
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status + ret))
fi
if $FEATURETEST --with-lmdb; then
echo_i "verifying added.example in external view created an external.nzd DB ($n)"
ret=0
[ -e ns2/external.nzd ] || ret=1
n=$((n + 1))
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status + ret))
fi
echo_i "checking rndc reload causes named to reload the external view's new zone config ($n)" echo_i "checking rndc reload causes named to reload the external view's new zone config ($n)"
ret=0 ret=0
@ -562,11 +524,7 @@ status=$((status + ret))
echo_i "checking rndc showzone with newly added zone ($n)" echo_i "checking rndc showzone with newly added zone ($n)"
_check_rndc_showzone_newly_added() ( _check_rndc_showzone_newly_added() (
if ! $FEATURETEST --with-lmdb; then expected='zone "added.example" { type primary; file "added.db"; };'
expected='zone "added.example" in external { type primary; file "added.db"; };'
else
expected='zone "added.example" { type primary; file "added.db"; };'
fi
$RNDCCMD 10.53.0.2 showzone added.example in external >rndc.out.ns2.$n 2>/dev/null \ $RNDCCMD 10.53.0.2 showzone added.example in external >rndc.out.ns2.$n 2>/dev/null \
&& [ "$(cat rndc.out.ns2.$n)" = "$expected" ] && [ "$(cat rndc.out.ns2.$n)" = "$expected" ]
) )
@ -668,13 +626,8 @@ n=$((n + 1))
if [ $ret != 0 ]; then echo_i "failed"; fi if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status + ret)) status=$((status + ret))
if $FEATURETEST --with-lmdb; then echo_i "checking NZD file was created in new-zones-directory ($n)"
echo_i "checking NZD file was created in new-zones-directory ($n)" expect=ns2/new-zones/directory.nzd
expect=ns2/new-zones/directory.nzd
else
echo_i "checking NZF file was created in new-zones-directory ($n)"
expect=ns2/new-zones/directory.nzf
fi
$RNDCCMD 10.53.0.2 sync 'added.example IN directory' 2>&1 | sed 's/^/I:ns2 /' $RNDCCMD 10.53.0.2 sync 'added.example IN directory' 2>&1 | sed 's/^/I:ns2 /'
sleep 2 sleep 2
[ -e "$expect" ] || ret=1 [ -e "$expect" ] || ret=1
@ -710,19 +663,6 @@ n=$((n + 1))
if [ $ret != 0 ]; then echo_i "failed"; fi if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status + ret)) status=$((status + ret))
if ! $FEATURETEST --with-lmdb; then
echo_i "check that addzone is fully reversed on failure (--with-lmdb=no) ($n)"
ret=0
$RNDCCMD 10.53.0.3 addzone "test1.baz" '{ type primary; file "e.db"; };' >/dev/null 2>&1 || ret=1
$RNDCCMD 10.53.0.3 addzone "test2.baz" '{ type primary; file "dne.db"; };' >/dev/null 2>&1 && ret=1
$RNDCCMD 10.53.0.3 addzone "test3.baz" '{ type primary; file "e.db"; };' >/dev/null 2>&1 || ret=1
$RNDCCMD 10.53.0.3 delzone "test3.baz" >/dev/null 2>&1 || ret=1
grep test2.baz ns3/_default.nzf >/dev/null && ret=1
n=$((n + 1))
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status + ret))
fi
_check_version_bind() ( _check_version_bind() (
$DIG $DIGOPTS @10.53.0.3 version.bind txt ch >dig.out.test$n \ $DIG $DIGOPTS @10.53.0.3 version.bind txt ch >dig.out.test$n \
&& grep "status: NOERROR" dig.out.test$n >/dev/null && grep "status: NOERROR" dig.out.test$n >/dev/null

View file

@ -109,26 +109,14 @@ for lmdb in lmdb-*.conf; do
n=$((n + 1)) n=$((n + 1))
ret=0 ret=0
if $FEATURETEST --with-lmdb; then echo_i "checking that named-checkconf detects no error in $lmdb ($n)"
echo_i "checking that named-checkconf detects no error in $lmdb ($n)" {
{ $CHECKCONF $lmdb >checkconf.out$n 2>&1
$CHECKCONF $lmdb >checkconf.out$n 2>&1 rc=$?
rc=$? } || true
} || true if [ $rc -ne 0 ]; then
if [ $rc -ne 0 ]; then echo_i "failed"
echo_i "failed" ret=1
ret=1
fi
else
echo_i "checking that named-checkconf detects error in $lmdb ($n)"
{
$CHECKCONF $lmdb >checkconf.out$n 2>&1
rc=$?
} || true
if [ $rc -eq 0 ]; then
echo_i "failed"
ret=1
fi
fi fi
status=$((status + ret)) status=$((status + ret))
done done

View file

@ -56,7 +56,6 @@ usage(void) {
fprintf(stderr, "\t--rsasha1\n"); fprintf(stderr, "\t--rsasha1\n");
fprintf(stderr, "\t--tsan\n"); fprintf(stderr, "\t--tsan\n");
fprintf(stderr, "\t--with-libidn2\n"); fprintf(stderr, "\t--with-libidn2\n");
fprintf(stderr, "\t--with-lmdb\n");
fprintf(stderr, "\t--with-libnghttp2\n"); fprintf(stderr, "\t--with-libnghttp2\n");
fprintf(stderr, "\t--with-zlib\n"); fprintf(stderr, "\t--with-zlib\n");
} }
@ -221,14 +220,6 @@ main(int argc, char **argv) {
#endif /* ifdef HAVE_LIBIDN2 */ #endif /* ifdef HAVE_LIBIDN2 */
} }
if (strcmp(argv[1], "--with-lmdb") == 0) {
#ifdef HAVE_LMDB
return 0;
#else /* ifdef HAVE_LMDB */
return 1;
#endif /* ifdef HAVE_LMDB */
}
if (strcmp(argv[1], "--with-libnghttp2") == 0) { if (strcmp(argv[1], "--with-libnghttp2") == 0) {
#ifdef HAVE_LIBNGHTTP2 #ifdef HAVE_LIBNGHTTP2
return 0; return 0;

View file

@ -26,7 +26,6 @@ FEATURES = {
"LIBIDN2": "--with-libidn2", "LIBIDN2": "--with-libidn2",
"LIBNGHTTP2": "--with-libnghttp2", "LIBNGHTTP2": "--with-libnghttp2",
"LIBXML2": "--have-libxml2", "LIBXML2": "--have-libxml2",
"LMDB": "--with-lmdb",
"MD5": "--md5", "MD5": "--md5",
"QUERYTRACE": "--enable-querytrace", "QUERYTRACE": "--enable-querytrace",
"RSASHA1": "--rsasha1", "RSASHA1": "--rsasha1",

View file

@ -19,7 +19,6 @@ named_rrchecker_src += files('named-rrchecker.c')
nsec3hash_src += files('nsec3hash.c') nsec3hash_src += files('nsec3hash.c')
manrst_srcset.add(when: 'HAVE_DNSTAP', if_true: files('dnstap-read.rst')) manrst_srcset.add(when: 'HAVE_DNSTAP', if_true: files('dnstap-read.rst'))
manrst_srcset.add(when: 'HAVE_LMDB', if_true: files('named-nzd2nzf.rst'))
manrst_srcset.add( manrst_srcset.add(
files( files(
'arpaname.rst', 'arpaname.rst',

View file

@ -11,10 +11,6 @@
* information regarding copyright ownership. * information regarding copyright ownership.
*/ */
#ifndef HAVE_LMDB
#error This program requires the LMDB library.
#endif /* ifndef HAVE_LMDB */
#include <lmdb.h> #include <lmdb.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>

View file

@ -1364,12 +1364,11 @@ default is used.
:tags: server :tags: server
:short: Sets a maximum size for the memory map of the new-zone database in LMDB database format. :short: Sets a maximum size for the memory map of the new-zone database in LMDB database format.
When :iscman:`named` is built with liblmdb, this option sets a maximum size This option sets a maximum size for the memory map of the new-zone database
for the memory map of the new-zone database (NZD) in LMDB database (NZD) in LMDB database format. This database is used to store configuration
format. This database is used to store configuration information for information for zones added using :option:`rndc addzone`. Note that this is
zones added using :option:`rndc addzone`. Note that this is not the NZD not the NZD database file size, but the largest size that the database may
database file size, but the largest size that the database may grow grow to.
to.
Because the database file is memory-mapped, its size is limited by Because the database file is memory-mapped, its size is limited by
the address space of the :iscman:`named` process. The default of 32 megabytes the address space of the :iscman:`named` process. The default of 32 megabytes
@ -1960,17 +1959,13 @@ Boolean Options
Newly added zones' configuration parameters are stored so that they Newly added zones' configuration parameters are stored so that they
can persist after the server is restarted. The configuration can persist after the server is restarted. The configuration
information is saved in a file called ``viewname.nzf`` (or, if information is saved in an LMDB database file called ``viewname.nzd``.
:iscman:`named` is compiled with liblmdb, in an LMDB database file called "viewname" is the name of the view, unless the view name contains
``viewname.nzd``). "viewname" is the name of the view, unless the view characters that are incompatible with use as a file name, in which case a
name contains characters that are incompatible with use as a file cryptographic hash of the view name is used instead.
name, in which case a cryptographic hash of the view name is used
instead.
Configurations for zones added at runtime are stored either in Configurations for zones added at runtime are stored in a new-zone database
a new-zone file (NZF) or a new-zone database (NZD), depending on (NZD). See :ref:`man_rndc` for further details about :option:`rndc addzone`.
whether :iscman:`named` was linked with liblmdb at compile time. See
:ref:`man_rndc` for further details about :option:`rndc addzone`.
.. namedconf:statement:: auth-nxdomain .. namedconf:statement:: auth-nxdomain
:tags: query :tags: query

View file

@ -10,7 +10,6 @@
# information regarding copyright ownership. # information regarding copyright ownership.
manrst_srcset.add(when: 'HAVE_DNSTAP', if_true: files('dnstap-read.rst')) manrst_srcset.add(when: 'HAVE_DNSTAP', if_true: files('dnstap-read.rst'))
manrst_srcset.add(when: 'HAVE_LMDB', if_true: files('named-nzd2nzf.rst'))
manrst_srcset.add( manrst_srcset.add(
files('conf.py'), files('conf.py'),
@ -39,6 +38,7 @@ manrst_srcset.add(
'named-compilezone.rst', 'named-compilezone.rst',
'named-journalprint.rst', 'named-journalprint.rst',
'named-makejournal.rst', 'named-makejournal.rst',
'named-nzd2nzf.rst',
'named-rrchecker.rst', 'named-rrchecker.rst',
'named.conf.rst', 'named.conf.rst',
'named.rst', 'named.rst',
@ -55,7 +55,6 @@ manrst_srcset.add(
if fs.is_file('arpaname.1.in') if fs.is_file('arpaname.1.in')
man_srcset.add(when: 'HAVE_DNSTAP', if_true: files('dnstap-read.1.in')) man_srcset.add(when: 'HAVE_DNSTAP', if_true: files('dnstap-read.1.in'))
man_srcset.add(when: 'HAVE_LMDB', if_true: files('named-nzd2nzf.1.in'))
man_srcset.add( man_srcset.add(
files( files(
@ -82,6 +81,7 @@ if fs.is_file('arpaname.1.in')
'named-compilezone.1.in', 'named-compilezone.1.in',
'named-journalprint.1.in', 'named-journalprint.1.in',
'named-makejournal.1.in', 'named-makejournal.1.in',
'named-nzd2nzf.1.in',
'named-rrchecker.1.in', 'named-rrchecker.1.in',
'named.8.in', 'named.8.in',
'named.conf.5.in', 'named.conf.5.in',

View file

@ -261,7 +261,6 @@ struct dns_view {
*/ */
#define MAX_DELEGATION_SERVERS 100 #define MAX_DELEGATION_SERVERS 100
#ifdef HAVE_LMDB
#define DNS_LMDB_COMMON_FLAGS (MDB_CREATE | MDB_NOSUBDIR | MDB_NOLOCK) #define DNS_LMDB_COMMON_FLAGS (MDB_CREATE | MDB_NOSUBDIR | MDB_NOLOCK)
#ifndef __OpenBSD__ #ifndef __OpenBSD__
#define DNS_LMDB_FLAGS (DNS_LMDB_COMMON_FLAGS) #define DNS_LMDB_FLAGS (DNS_LMDB_COMMON_FLAGS)
@ -272,7 +271,6 @@ struct dns_view {
*/ */
#define DNS_LMDB_FLAGS (DNS_LMDB_COMMON_FLAGS | MDB_WRITEMAP) #define DNS_LMDB_FLAGS (DNS_LMDB_COMMON_FLAGS | MDB_WRITEMAP)
#endif /* __OpenBSD__ */ #endif /* __OpenBSD__ */
#endif /* HAVE_LMDB */
void void
dns_view_create(isc_mem_t *mctx, dns_dispatchmgr_t *dispmgr, dns_view_create(isc_mem_t *mctx, dns_dispatchmgr_t *dispmgr,

View file

@ -15,11 +15,8 @@
#include <inttypes.h> #include <inttypes.h>
#include <limits.h> #include <limits.h>
#include <stdbool.h>
#ifdef HAVE_LMDB
#include <lmdb.h> #include <lmdb.h>
#endif /* ifdef HAVE_LMDB */ #include <stdbool.h>
#include <isc/async.h> #include <isc/async.h>
#include <isc/atomic.h> #include <isc/atomic.h>
@ -341,7 +338,6 @@ destroy(dns_view_t *view) {
if (view->newzone.cleanup != NULL) { if (view->newzone.cleanup != NULL) {
view->newzone.cleanup(view); view->newzone.cleanup(view);
} }
#ifdef HAVE_LMDB
if (view->newzone.dbenv != NULL) { if (view->newzone.dbenv != NULL) {
mdb_env_close((MDB_env *)view->newzone.dbenv); mdb_env_close((MDB_env *)view->newzone.dbenv);
view->newzone.dbenv = NULL; view->newzone.dbenv = NULL;
@ -349,7 +345,6 @@ destroy(dns_view_t *view) {
if (view->newzone.db != NULL) { if (view->newzone.db != NULL) {
isc_mem_free(view->mctx, view->newzone.db); isc_mem_free(view->mctx, view->newzone.db);
} }
#endif /* HAVE_LMDB */
dns_fwdtable_destroy(&view->fwdtable); dns_fwdtable_destroy(&view->fwdtable);
dns_aclenv_detach(&view->aclenv); dns_aclenv_detach(&view->aclenv);
if (view->failcache != NULL) { if (view->failcache != NULL) {

View file

@ -2388,12 +2388,7 @@ static cfg_clausedef_t view_clauses[] = {
{ "ipv4only-server", &cfg_type_astring, 0, NULL }, { "ipv4only-server", &cfg_type_astring, 0, NULL },
{ "ixfr-from-differences", &cfg_type_ixfrdifftype, 0, NULL }, { "ixfr-from-differences", &cfg_type_ixfrdifftype, 0, NULL },
{ "lame-ttl", &cfg_type_duration, 0, NULL }, { "lame-ttl", &cfg_type_duration, 0, NULL },
#ifdef HAVE_LMDB
{ "lmdb-mapsize", &cfg_type_sizeval, CFG_CLAUSEFLAG_OPTIONAL, NULL }, { "lmdb-mapsize", &cfg_type_sizeval, CFG_CLAUSEFLAG_OPTIONAL, NULL },
#else /* ifdef HAVE_LMDB */
{ "lmdb-mapsize", &cfg_type_sizeval, CFG_CLAUSEFLAG_NOTCONFIGURED,
NULL },
#endif /* ifdef HAVE_LMDB */
{ "max-acache-size", NULL, CFG_CLAUSEFLAG_ANCIENT, NULL }, { "max-acache-size", NULL, CFG_CLAUSEFLAG_ANCIENT, NULL },
{ "max-cache-size", &cfg_type_maxcachesize, 0, NULL }, { "max-cache-size", &cfg_type_maxcachesize, 0, NULL },
{ "max-cache-ttl", &cfg_type_duration, 0, NULL }, { "max-cache-ttl", &cfg_type_duration, 0, NULL },

View file

@ -63,7 +63,6 @@ idn_opt = get_option('idn')
jemalloc_opt = get_option('jemalloc').disable_auto_if(sanitizer != 'none') jemalloc_opt = get_option('jemalloc').disable_auto_if(sanitizer != 'none')
leak_opt = get_option('leak-detection') leak_opt = get_option('leak-detection')
line_opt = get_option('line') line_opt = get_option('line')
lmdb_opt = get_option('lmdb')
locktype_opt = get_option('locktype') locktype_opt = get_option('locktype')
named_lto_opt = get_option('named-lto') named_lto_opt = get_option('named-lto')
oss_fuzz_args_opt = get_option('oss-fuzz-args') oss_fuzz_args_opt = get_option('oss-fuzz-args')
@ -875,13 +874,7 @@ if idn_opt.allowed()
endif endif
## LMDB ## LMDB
lmdb_dep = null_dep lmdb_dep = dependency('lmdb')
if lmdb_opt.allowed()
lmdb_dep = dependency('lmdb', required: lmdb_opt)
if lmdb_dep.found()
config.set('HAVE_LMDB', 1)
endif
endif
## zlib ## zlib
@ -1578,21 +1571,19 @@ executable(
], ],
) )
if config.has('HAVE_LMDB') executable(
executable( 'named-nzd2nzf',
'named-nzd2nzf', named_nzd2nzf_src,
named_nzd2nzf_src, export_dynamic: true,
export_dynamic: true, implicit_include_directories: false,
implicit_include_directories: false, install: true,
install: true, dependencies: [
dependencies: [ libdns_dep,
libdns_dep, libisc_dep,
libisc_dep,
lmdb_dep, lmdb_dep,
], ],
) )
endif
executable( executable(
'named-rrchecker', 'named-rrchecker',

View file

@ -66,13 +66,6 @@ option(
description: 'Enable line editing in nsupdate and nslookup, requires libedit', description: 'Enable line editing in nsupdate and nslookup, requires libedit',
) )
option(
'lmdb',
type: 'feature',
value: 'auto',
description: 'LMDB database to store configuration for "addzone" zones',
)
option( option(
'stats-json', 'stats-json',
type: 'feature', type: 'feature',