]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
[master] Fix LMDB support on OpenBSD; clean up and refactor LMDB-related code
authorMichał Kępień <michal@isc.org>
Thu, 30 Nov 2017 12:43:46 +0000 (13:43 +0100)
committerMichał Kępień <michal@isc.org>
Thu, 30 Nov 2017 13:34:04 +0000 (14:34 +0100)
4835. [cleanup] Clean up and refactor LMDB-related code. [RT #46718]

4834. [port] Fix LMDB support on OpenBSD. [RT #46718]

CHANGES
bin/named/server.c
bin/tools/named-nzd2nzf.c
lib/dns/include/dns/view.h
lib/dns/view.c

diff --git a/CHANGES b/CHANGES
index c7cdff34d0b4f95d32fcdcd8e2b7ee35be2082b5..66a230aa32c9816fd5dc366954e51868b36ca490 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,7 @@
+4835.  [cleanup]       Clean up and refactor LMDB-related code. [RT #46718]
+
+4834.  [port]          Fix LMDB support on OpenBSD. [RT #46718]
+
 4833.  [bug]           isc_event_free should check that the event is not
                        linked when called. [RT #46725]
 
index 69a52693bd81682d59b2d11652569e242a3c04de..d46e9efbc33cc4fda8835b182daa2d95083084af 100644 (file)
@@ -7333,110 +7333,160 @@ data_to_cfg(dns_view_t *view, MDB_val *key, MDB_val *data,
        return (result);
 }
 
+/*%
+ * Prototype for a callback which can be used with for_all_newzone_cfgs().
+ */
+typedef isc_result_t (*newzone_cfg_cb_t)(const cfg_obj_t *zconfig,
+                                        cfg_obj_t *config, cfg_obj_t *vconfig,
+                                        isc_mem_t *mctx, dns_view_t *view,
+                                        cfg_aclconfctx_t *actx);
+
+/*%
+ * For each zone found in a NZD opened by the caller, create an object
+ * representing its configuration and invoke "callback" with the created
+ * object, "config", "vconfig", "mctx", "view" and "actx" as arguments (all
+ * these are non-global variables required to invoke configure_zone()).
+ * Immediately interrupt processing if an error is encountered while
+ * transforming NZD data into a zone configuration object or if "callback"
+ * returns an error.
+ */
 static isc_result_t
-configure_newzones(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
-                  isc_mem_t *mctx, cfg_aclconfctx_t *actx)
+for_all_newzone_cfgs(newzone_cfg_cb_t callback, cfg_obj_t *config,
+                    cfg_obj_t *vconfig, isc_mem_t *mctx, dns_view_t *view,
+                    cfg_aclconfctx_t *actx, MDB_txn *txn, MDB_dbi dbi)
 {
+       const cfg_obj_t *zconfig, *zlist = NULL;
        isc_result_t result = ISC_R_SUCCESS;
-       int status;
+       cfg_obj_t *zconfigobj = NULL;
        isc_buffer_t *text = NULL;
-       cfg_obj_t *zoneconf = NULL;
        MDB_cursor *cursor = NULL;
-       MDB_txn *txn = NULL;
-       MDB_dbi dbi;
-       MDB_val key, data;
-
-       if (view->new_zone_config == NULL) {
-               return (ISC_R_SUCCESS);
-       }
-
-       result = nzd_open(view, MDB_RDONLY, &txn, &dbi);
-       if (result != ISC_R_SUCCESS) {
-               return (ISC_R_SUCCESS);
-       }
-
-       isc_log_write(named_g_lctx,
-                     NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER,
-                     ISC_LOG_INFO, "loading NZD configs from '%s' "
-                     "for view '%s'",
-                     view->new_zone_db, view->name);
+       MDB_val data, key;
+       int status;
 
        status = mdb_cursor_open(txn, dbi, &cursor);
-       if (status != 0) {
-               result = ISC_R_FAILURE;
-               goto cleanup;
+       if (status != MDB_SUCCESS) {
+               return (ISC_R_FAILURE);
        }
 
-       while (mdb_cursor_get(cursor, &key, &data, MDB_NEXT) == 0) {
-               const cfg_obj_t *zlist = NULL;
-               const cfg_obj_t *zoneobj = NULL;
-
-               result = data_to_cfg(view, &key, &data, &text, &zoneconf);
+       for (status = mdb_cursor_get(cursor, &key, &data, MDB_FIRST);
+            status == MDB_SUCCESS;
+            status = mdb_cursor_get(cursor, &key, &data, MDB_NEXT))
+       {
+               /*
+                * Create a configuration object from data fetched from NZD.
+                */
+               result = data_to_cfg(view, &key, &data, &text, &zconfigobj);
                if (result != ISC_R_SUCCESS) {
-                       goto cleanup;
+                       break;
                }
 
-               CHECK(cfg_map_get(zoneconf, "zone", &zlist));
-               if (!cfg_obj_islist(zlist)) {
-                       CHECK(ISC_R_FAILURE);
+               /*
+                * Extract zone configuration from configuration object.
+                */
+               result = cfg_map_get(zconfigobj, "zone", &zlist);
+               if (result != ISC_R_SUCCESS) {
+                       break;
+               } else if (!cfg_obj_islist(zlist)) {
+                       result = ISC_R_FAILURE;
+                       break;
                }
+               zconfig = cfg_listelt_value(cfg_list_first(zlist));
 
-               zoneobj = cfg_listelt_value(cfg_list_first(zlist));
-               CHECK(configure_zone(config, zoneobj, vconfig, mctx,
-                                    view, &named_g_server->viewlist, actx,
-                                    ISC_TRUE, ISC_FALSE, ISC_FALSE));
+               /*
+                * Invoke callback.
+                */
+               result = callback(zconfig, config, vconfig, mctx, view, actx);
+               if (result != ISC_R_SUCCESS) {
+                       break;
+               }
 
-               cfg_obj_destroy(named_g_addparser, &zoneconf);
+               /*
+                * Destroy the configuration object created in this iteration.
+                */
+               cfg_obj_destroy(named_g_addparser, &zconfigobj);
        }
 
-       result = ISC_R_SUCCESS;
-
- cleanup:
-       if (zoneconf != NULL) {
-               cfg_obj_destroy(named_g_addparser, &zoneconf);
+       if (text != NULL) {
+               isc_buffer_free(&text);
        }
-       if (cursor != NULL) {
-               mdb_cursor_close(cursor);
-               cursor = NULL;
+       if (zconfigobj != NULL) {
+               cfg_obj_destroy(named_g_addparser, &zconfigobj);
        }
-       if (result != ISC_R_SUCCESS) {
-               status = mdb_cursor_open(txn, dbi, &cursor);
-               if (status != 0) {
-                       goto cleanup2;
-               }
-               while (mdb_cursor_get(cursor, &key, &data, MDB_NEXT) == 0) {
-                       const cfg_obj_t *zlist = NULL;
-                       const cfg_obj_t *zconfig = NULL;
-                       isc_result_t result2;
+       mdb_cursor_close(cursor);
 
-                       result2 = data_to_cfg(view, &key, &data, &text,
-                                             &zoneconf);
-                       if (result2 != ISC_R_SUCCESS) {
-                               goto cleanup2;
-                       }
+       return (result);
+}
 
-                       result2 = cfg_map_get(zoneconf, "zone", &zlist);
-                       if (result2 != ISC_R_SUCCESS) {
-                               goto cleanup2;
-                       }
+/*%
+ * Attempt to configure a zone found in NZD and return the result.
+ */
+static isc_result_t
+configure_newzone(const cfg_obj_t *zconfig, cfg_obj_t *config,
+                 cfg_obj_t *vconfig, isc_mem_t *mctx, dns_view_t *view,
+                 cfg_aclconfctx_t *actx)
+{
+       return (configure_zone(config, zconfig, vconfig, mctx, view,
+                              &named_g_server->viewlist, actx, ISC_TRUE,
+                              ISC_FALSE, ISC_FALSE));
+}
 
-                       zconfig = cfg_listelt_value(cfg_list_first(zlist));
-                       configure_zone_setviewcommit(result, zconfig, view);
+/*%
+ * Revert new view assignment for a zone found in NZD.
+ */
+static isc_result_t
+configure_newzone_revert(const cfg_obj_t *zconfig, cfg_obj_t *config,
+                        cfg_obj_t *vconfig, isc_mem_t *mctx, dns_view_t *view,
+                        cfg_aclconfctx_t *actx)
+{
+       UNUSED(config);
+       UNUSED(vconfig);
+       UNUSED(mctx);
+       UNUSED(actx);
 
-                       cfg_obj_destroy(named_g_addparser, &zoneconf);
-               }
-       }
+       configure_zone_setviewcommit(ISC_R_FAILURE, zconfig, view);
 
- cleanup2:
-       if (text != NULL) {
-               isc_buffer_free(&text);
+       return (ISC_R_SUCCESS);
+}
+
+static isc_result_t
+configure_newzones(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
+                  isc_mem_t *mctx, cfg_aclconfctx_t *actx)
+{
+       isc_result_t result;
+       MDB_txn *txn = NULL;
+       MDB_dbi dbi;
+
+       if (view->new_zone_config == NULL) {
+               return (ISC_R_SUCCESS);
        }
-       if (zoneconf != NULL) {
-               cfg_obj_destroy(named_g_addparser, &zoneconf);
+
+       result = nzd_open(view, MDB_RDONLY, &txn, &dbi);
+       if (result != ISC_R_SUCCESS) {
+               return (ISC_R_SUCCESS);
        }
-       if (cursor != NULL) {
-               mdb_cursor_close(cursor);
+
+       isc_log_write(named_g_lctx,
+                     NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER,
+                     ISC_LOG_INFO, "loading NZD configs from '%s' "
+                     "for view '%s'",
+                     view->new_zone_db, view->name);
+
+       result = for_all_newzone_cfgs(configure_newzone, config, vconfig, mctx,
+                                     view, actx, txn, dbi);
+       if (result != ISC_R_SUCCESS) {
+               /*
+                * An error was encountered while attempting to configure zones
+                * found in NZD.  As this error may have been caused by a
+                * configure_zone() failure, try restoring a sane configuration
+                * by reattaching all zones found in NZD to the old view.  If
+                * this also fails, too bad, there is nothing more we can do in
+                * terms of trying to make things right.
+                */
+               (void) for_all_newzone_cfgs(configure_newzone_revert, config,
+                                           vconfig, mctx, view, actx, txn,
+                                           dbi);
        }
+
        (void) nzd_close(&txn, ISC_FALSE);
        return (result);
 }
@@ -7480,8 +7530,9 @@ get_newzone_config(dns_view_t *view, const char *zonename,
        key.mv_size = strlen(zname);
 
        status = mdb_get(txn, dbi, &key, &data);
-       if (status != 0)
+       if (status != MDB_SUCCESS) {
                CHECK(ISC_R_FAILURE);
+       }
 
        CHECK(data_to_cfg(view, &key, &data, &text, &zoneconf));
 
@@ -7492,10 +7543,12 @@ get_newzone_config(dns_view_t *view, const char *zonename,
  cleanup:
        (void) nzd_close(&txn, ISC_FALSE);
 
-       if (zoneconf != NULL)
+       if (zoneconf != NULL) {
                cfg_obj_destroy(named_g_addparser, &zoneconf);
-       if (text != NULL)
+       }
+       if (text != NULL) {
                isc_buffer_free(&text);
+       }
 
        return (result);
 }
@@ -11853,7 +11906,7 @@ nzd_save(MDB_txn **txnp, MDB_dbi dbi, dns_zone_t *zone,
        if (zconfig == NULL) {
                /* We're deleting the zone from the database */
                status = mdb_del(*txnp, dbi, &key, NULL);
-               if (status != 0 && status != MDB_NOTFOUND) {
+               if (status != MDB_SUCCESS && status != MDB_NOTFOUND) {
                        isc_log_write(named_g_lctx,
                                      NAMED_LOGCATEGORY_GENERAL,
                                      NAMED_LOGMODULE_SERVER,
@@ -11863,8 +11916,9 @@ nzd_save(MDB_txn **txnp, MDB_dbi dbi, dns_zone_t *zone,
                                      namebuf, mdb_strerror(status));
                        result = ISC_R_FAILURE;
                        goto cleanup;
-               } else if (status != MDB_NOTFOUND)
+               } else if (status != MDB_NOTFOUND) {
                        commit = ISC_TRUE;
+               }
        } else {
                /* We're creating or overwriting the zone */
                const cfg_obj_t *zoptions;
@@ -11899,7 +11953,7 @@ nzd_save(MDB_txn **txnp, MDB_dbi dbi, dns_zone_t *zone,
                data.mv_size = isc_buffer_usedlength(text);
 
                status = mdb_put(*txnp, dbi, &key, &data, 0);
-               if (status != 0) {
+               if (status != MDB_SUCCESS) {
                        isc_log_write(named_g_lctx,
                                      NAMED_LOGCATEGORY_GENERAL,
                                      NAMED_LOGMODULE_SERVER,
@@ -11917,11 +11971,11 @@ nzd_save(MDB_txn **txnp, MDB_dbi dbi, dns_zone_t *zone,
        result = ISC_R_SUCCESS;
 
  cleanup:
-       if (!commit || result != ISC_R_SUCCESS)
+       if (!commit || result != ISC_R_SUCCESS) {
                (void) mdb_txn_abort(*txnp);
-       else {
+       else {
                status = mdb_txn_commit(*txnp);
-               if (status != 0) {
+               if (status != MDB_SUCCESS) {
                        isc_log_write(named_g_lctx,
                                      NAMED_LOGCATEGORY_GENERAL,
                                      NAMED_LOGMODULE_SERVER,
@@ -11936,8 +11990,10 @@ nzd_save(MDB_txn **txnp, MDB_dbi dbi, dns_zone_t *zone,
 
        UNLOCK(&view->new_zone_lock);
 
-       if (text != NULL)
+       if (text != NULL) {
                isc_buffer_free(&text);
+       }
+
        return (result);
 }
 
@@ -11951,7 +12007,7 @@ nzd_writable(dns_view_t *view) {
        REQUIRE(view != NULL);
 
        status = mdb_txn_begin((MDB_env *) view->new_zone_dbenv, 0, 0, &txn);
-       if (status != 0) {
+       if (status != MDB_SUCCESS) {
                isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
                              NAMED_LOGMODULE_SERVER, ISC_LOG_WARNING,
                              "mdb_txn_begin: %s",
@@ -11960,7 +12016,7 @@ nzd_writable(dns_view_t *view) {
        }
 
        status = mdb_dbi_open(txn, NULL, 0, &dbi);
-       if (status != 0) {
+       if (status != MDB_SUCCESS) {
                isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
                              NAMED_LOGMODULE_SERVER, ISC_LOG_WARNING,
                              "mdb_dbi_open: %s",
@@ -11983,7 +12039,7 @@ nzd_open(dns_view_t *view, unsigned int flags, MDB_txn **txnp, MDB_dbi *dbi) {
 
        status = mdb_txn_begin((MDB_env *) view->new_zone_dbenv, 0,
                               flags, &txn);
-       if (status != 0) {
+       if (status != MDB_SUCCESS) {
                isc_log_write(named_g_lctx,
                              NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER,
                              ISC_LOG_WARNING, "mdb_txn_begin: %s",
@@ -11992,7 +12048,7 @@ nzd_open(dns_view_t *view, unsigned int flags, MDB_txn **txnp, MDB_dbi *dbi) {
        }
 
        status = mdb_dbi_open(txn, NULL, 0, dbi);
-       if (status != 0) {
+       if (status != MDB_SUCCESS) {
                isc_log_write(named_g_lctx,
                      NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER,
                              ISC_LOG_WARNING, "mdb_dbi_open: %s",
@@ -12003,9 +12059,10 @@ nzd_open(dns_view_t *view, unsigned int flags, MDB_txn **txnp, MDB_dbi *dbi) {
        *txnp = txn;
 
  cleanup:
-       if (status != 0) {
-               if (txn != NULL)
+       if (status != MDB_SUCCESS) {
+               if (txn != NULL) {
                        mdb_txn_abort(txn);
+               }
                return (ISC_R_FAILURE);
        }
 
@@ -12019,38 +12076,34 @@ nzd_open(dns_view_t *view, unsigned int flags, MDB_txn **txnp, MDB_dbi *dbi) {
  */
 static void
 nzd_env_close(dns_view_t *view) {
-       if (view->new_zone_dbenv != NULL) {
-               const char *dbpath = NULL;
-               isc_boolean_t have_dbpath = ISC_FALSE;
-               char dbpath_copy[PATH_MAX];
-               char lockpath[PATH_MAX];
-               int ret;
+       const char *dbpath = NULL;
+       char dbpath_copy[PATH_MAX];
+       char lockpath[PATH_MAX];
+       int status, ret;
 
-               if (mdb_env_get_path(view->new_zone_dbenv, &dbpath) == 0) {
-                       have_dbpath = ISC_TRUE;
-                       snprintf(lockpath, sizeof(lockpath), "%s-lock",
-                                dbpath);
-                       strlcpy(dbpath_copy, dbpath, sizeof(dbpath_copy));
-               }
+       if (view->new_zone_dbenv == NULL) {
+               return;
+       }
 
-               mdb_env_close((MDB_env *) view->new_zone_dbenv);
-               view->new_zone_dbenv = NULL;
+       status = mdb_env_get_path(view->new_zone_dbenv, &dbpath);
+       INSIST(status == MDB_SUCCESS);
+       snprintf(lockpath, sizeof(lockpath), "%s-lock", dbpath);
+       strlcpy(dbpath_copy, dbpath, sizeof(dbpath_copy));
+       mdb_env_close((MDB_env *) view->new_zone_dbenv);
 
-               if (have_dbpath) {
-                       /*
-                        * Database files must be owned by the eventual user, not
-                        * by root.
-                        */
-                       ret = chown(dbpath_copy, ns_os_uid(), -1);
-                       UNUSED(ret);
+       /*
+        * Database files must be owned by the eventual user, not by root.
+        */
+       ret = chown(dbpath_copy, ns_os_uid(), -1);
+       UNUSED(ret);
 
-                       /*
-                        * Some platforms need the lockfile not to exist when we
-                        * reopen the environment.
-                        */
-                       (void) isc_file_remove(lockpath);
-               }
-       }
+       /*
+        * Some platforms need the lockfile not to exist when we reopen the
+        * environment.
+        */
+       (void) isc_file_remove(lockpath);
+
+       view->new_zone_dbenv = NULL;
 }
 
 static isc_result_t
@@ -12066,7 +12119,7 @@ nzd_env_reopen(dns_view_t *view) {
        nzd_env_close(view);
 
        status = mdb_env_create(&env);
-       if (status != 0) {
+       if (status != MDB_SUCCESS) {
                isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
                              ISC_LOGMODULE_OTHER, ISC_LOG_ERROR,
                              "mdb_env_create failed: %s",
@@ -12076,7 +12129,7 @@ nzd_env_reopen(dns_view_t *view) {
 
        if (view->new_zone_mapsize != 0ULL) {
                status = mdb_env_set_mapsize(env, view->new_zone_mapsize);
-               if (status != 0) {
+               if (status != MDB_SUCCESS) {
                        isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
                                      ISC_LOGMODULE_OTHER, ISC_LOG_ERROR,
                                      "mdb_env_set_mapsize failed: %s",
@@ -12085,14 +12138,8 @@ nzd_env_reopen(dns_view_t *view) {
                }
        }
 
-       /*
-        * MDB_NOTLS is used to prevent problems after configuration is
-        * reloaded, due to the way LMDB's use of thread-local storage (TLS)
-        * interacts with the BIND9 thread model.
-        */
-       status = mdb_env_open(env, view->new_zone_db,
-                             MDB_NOSUBDIR|MDB_NOTLS|MDB_CREATE, 0600);
-       if (status != 0) {
+       status = mdb_env_open(env, view->new_zone_db, DNS_LMDB_FLAGS, 0600);
+       if (status != MDB_SUCCESS) {
                isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
                              ISC_LOGMODULE_OTHER, ISC_LOG_ERROR,
                              "mdb_env_open of '%s' failed: %s",
@@ -12121,10 +12168,12 @@ nzd_close(MDB_txn **txnp, isc_boolean_t commit) {
        if (*txnp != NULL) {
                if (commit) {
                        status = mdb_txn_commit(*txnp);
-                       if (status != 0)
+                       if (status != MDB_SUCCESS) {
                                result = ISC_R_FAILURE;
-               } else
+                       }
+               } else {
                        mdb_txn_abort(*txnp);
+               }
                *txnp = NULL;
        }
 
@@ -12142,11 +12191,12 @@ nzd_count(dns_view_t *view, int *countp) {
        REQUIRE(countp != NULL);
 
        result = nzd_open(view, MDB_RDONLY, &txn, &dbi);
-       if (result != ISC_R_SUCCESS)
+       if (result != ISC_R_SUCCESS) {
                goto cleanup;
+       }
 
        status = mdb_stat(txn, dbi, &statbuf);
-       if (status != 0) {
+       if (status != MDB_SUCCESS) {
                isc_log_write(named_g_lctx,
                              NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER,
                              ISC_LOG_WARNING, "mdb_stat: %s",
@@ -12219,8 +12269,9 @@ migrate_nzf(dns_view_t *view) {
 
        zonelist = NULL;
        CHECK(cfg_map_get(nzf_config, "zone", &zonelist));
-       if (!cfg_obj_islist(zonelist))
+       if (!cfg_obj_islist(zonelist)) {
                CHECK(ISC_R_FAILURE);
+       }
 
        CHECK(nzd_open(view, 0, &txn, &dbi));
 
@@ -12271,7 +12322,7 @@ migrate_nzf(dns_view_t *view) {
                data.mv_size = isc_buffer_usedlength(text);
 
                status = mdb_put(txn, dbi, &key, &data, MDB_NOOVERWRITE);
-               if (status != 0) {
+               if (status != MDB_SUCCESS) {
                        isc_log_write(named_g_lctx,
                                      NAMED_LOGCATEGORY_GENERAL,
                                      NAMED_LOGMODULE_SERVER,
@@ -12300,15 +12351,19 @@ migrate_nzf(dns_view_t *view) {
        }
 
  cleanup:
-       if (result != ISC_R_SUCCESS)
+       if (result != ISC_R_SUCCESS) {
                (void) nzd_close(&txn, ISC_FALSE);
-       else
+       } else {
                result = nzd_close(&txn, commit);
+       }
 
-       if (text != NULL)
+       if (text != NULL) {
                isc_buffer_free(&text);
-       if (nzf_config != NULL)
+       }
+
+       if (nzf_config != NULL) {
                cfg_obj_destroy(named_g_addparser, &nzf_config);
+       }
 
        return (result);
 }
index 1c5406e07bba2002fda95696752cfaf6d8c471c7..0c24b49defb666ac7202ea43a2d07982e4a973d3 100644 (file)
@@ -16,6 +16,8 @@
 #include <stdlib.h>
 #include <lmdb.h>
 
+#include <dns/view.h>
+
 #include <isc/print.h>
 
 int
@@ -36,42 +38,44 @@ main (int argc, char *argv[]) {
        path = argv[1];
 
        status = mdb_env_create(&env);
-       if (status != 0) {
+       if (status != MDB_SUCCESS) {
                fprintf(stderr, "named-nzd2nzf: mdb_env_create: %s",
                        mdb_strerror(status));
                exit(1);
        }
 
-       status = mdb_env_open(env, path,
-                             MDB_RDONLY|MDB_NOTLS|MDB_NOSUBDIR, 0600);
-       if (status != 0) {
+       status = mdb_env_open(env, path, DNS_LMDB_FLAGS, 0600);
+       if (status != MDB_SUCCESS) {
                fprintf(stderr, "named-nzd2nzf: mdb_env_open: %s",
                        mdb_strerror(status));
                exit(1);
        }
 
        status = mdb_txn_begin(env, 0, MDB_RDONLY, &txn);
-       if (status != 0) {
+       if (status != MDB_SUCCESS) {
                fprintf(stderr, "named-nzd2nzf: mdb_txn_begin: %s",
                        mdb_strerror(status));
                exit(1);
        }
 
        status = mdb_dbi_open(txn, NULL, 0, &dbi);
-       if (status != 0) {
+       if (status != MDB_SUCCESS) {
                fprintf(stderr, "named-nzd2nzf: mdb_dbi_open: %s",
                        mdb_strerror(status));
                exit(1);
        }
 
        status = mdb_cursor_open(txn, dbi, &cursor);
-       if (status != 0) {
+       if (status != MDB_SUCCESS) {
                fprintf(stderr, "named-nzd2nzf: mdb_cursor_open: %s",
                        mdb_strerror(status));
                exit(1);
        }
 
-       while (mdb_cursor_get(cursor, &key, &data, MDB_NEXT) == 0) {
+       for (status = mdb_cursor_get(cursor, &key, &data, MDB_FIRST);
+            status == MDB_SUCCESS;
+            status = mdb_cursor_get(cursor, &key, &data, MDB_NEXT))
+       {
                if (key.mv_data == NULL || key.mv_size == 0 ||
                    data.mv_data == NULL || data.mv_size == 0)
                {
index 2a0412038aeb809c5c14cb55b08f7ceab71cfd40..3bb4bfb0888adabd25a0e2e37f725463e5206bab 100644 (file)
@@ -237,6 +237,25 @@ struct dns_view {
 #define DNS_VIEWATTR_ADBSHUTDOWN       0x02
 #define DNS_VIEWATTR_REQSHUTDOWN       0x04
 
+#ifdef HAVE_LMDB
+#include <lmdb.h>
+/*
+ * MDB_NOTLS is used to prevent problems after configuration is reloaded, due
+ * to the way LMDB's use of thread-local storage (TLS) interacts with the BIND9
+ * thread model.
+ */
+#define DNS_LMDB_COMMON_FLAGS          (MDB_CREATE | MDB_NOSUBDIR | MDB_NOTLS)
+#ifndef __OpenBSD__
+#define DNS_LMDB_FLAGS                 (DNS_LMDB_COMMON_FLAGS)
+#else /* __OpenBSD__ */
+/*
+ * OpenBSD does not have a unified buffer cache, which requires both reads and
+ * writes to be performed using mmap().
+ */
+#define DNS_LMDB_FLAGS                 (DNS_LMDB_COMMON_FLAGS | MDB_WRITEMAP)
+#endif /* __OpenBSD__ */
+#endif /* HAVE_LMDB */
+
 isc_result_t
 dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
                const char *name, dns_view_t **viewp);
index df5d8f4b66d26bf33b3165e85612d55e95a27055..5195734b715a0dfd79bc54b1aa101976f82a7bbd 100644 (file)
@@ -519,8 +519,10 @@ destroy(dns_view_t *view) {
                view->new_zone_dir = NULL;
        }
 #ifdef HAVE_LMDB
-       if (view->new_zone_dbenv != NULL)
+       if (view->new_zone_dbenv != NULL) {
                mdb_env_close((MDB_env *) view->new_zone_dbenv);
+               view->new_zone_dbenv = NULL;
+       }
        if (view->new_zone_db != NULL) {
                isc_mem_free(view->mctx, view->new_zone_db);
                view->new_zone_db = NULL;
@@ -2102,7 +2104,7 @@ dns_view_setnewzones(dns_view_t *view, isc_boolean_t allow, void *cfgctx,
        }
 
        status = mdb_env_create(&env);
-       if (status != 0) {
+       if (status != MDB_SUCCESS) {
                isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
                              ISC_LOGMODULE_OTHER, ISC_LOG_ERROR,
                              "mdb_env_create failed: %s",
@@ -2112,24 +2114,18 @@ dns_view_setnewzones(dns_view_t *view, isc_boolean_t allow, void *cfgctx,
 
        if (mapsize != 0ULL) {
                status = mdb_env_set_mapsize(env, mapsize);
-               view->new_zone_mapsize = mapsize;
-               if (status != 0) {
+               if (status != MDB_SUCCESS) {
                        isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
                                      ISC_LOGMODULE_OTHER, ISC_LOG_ERROR,
                                      "mdb_env_set_mapsize failed: %s",
                                      mdb_strerror(status));
                        CHECK(ISC_R_FAILURE);
                }
+               view->new_zone_mapsize = mapsize;
        }
 
-       /*
-        * MDB_NOTLS is used to prevent problems after configuration is
-        * reloaded, due to the way LMDB's use of thread-local storage (TLS)
-        * interacts with the BIND9 thread model.
-        */
-       status = mdb_env_open(env, view->new_zone_db,
-                             MDB_NOSUBDIR|MDB_NOTLS|MDB_CREATE, 0600);
-       if (status != 0) {
+       status = mdb_env_open(env, view->new_zone_db, DNS_LMDB_FLAGS, 0600);
+       if (status != MDB_SUCCESS) {
                isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
                              ISC_LOGMODULE_OTHER, ISC_LOG_ERROR,
                              "mdb_env_open of '%s' failed: %s",
@@ -2156,8 +2152,9 @@ dns_view_setnewzones(dns_view_t *view, isc_boolean_t allow, void *cfgctx,
                        isc_mem_free(view->mctx, view->new_zone_db);
                        view->new_zone_db = NULL;
                }
-               if (env != NULL)
+               if (env != NULL) {
                        mdb_env_close(env);
+               }
 #endif /* HAVE_LMDB */
                view->new_zone_config = NULL;
                view->cfg_destroy = NULL;