[Freeipa-devel] [PATCH 0123-0126] Separate master and forward zones (add idnsForwardZone object class)
Adam Tkac
atkac at redhat.com
Tue Apr 2 15:30:05 UTC 2013
On Fri, Mar 22, 2013 at 01:03:12PM +0100, Petr Spacek wrote:
> Hello,
>
> this patch set separates master zones (idnsZone objectClass) from
> forward zones (idnsForwardZone objectClass). Support for forward
> zones in idnsZone objectClass is still present to ease upgrades.
>
> See each commit message for all the gory details.
>
> --
> Petr^2 Spacek
Ack for patch 125 as is.
> From 48fb17f8242d2d5d71898758ef6e58f0341df3f3 Mon Sep 17 00:00:00 2001
> From: Petr Spacek <pspacek at redhat.com>
> Date: Fri, 22 Mar 2013 12:32:40 +0100
> Subject: [PATCH] Use new RBT iterators for zone deletion.
>
> https://fedorahosted.org/bind-dyndb-ldap/ticket/99
>
> Signed-off-by: Petr Spacek <pspacek at redhat.com>
> ---
> src/ldap_helper.c | 109 ++++++++++------------------------------------------
> src/ldap_helper.h | 4 ++
> src/zone_register.c | 44 +++++++++++++++++++--
> src/zone_register.h | 9 ++++-
> 4 files changed, 74 insertions(+), 92 deletions(-)
>
> diff --git a/src/ldap_helper.c b/src/ldap_helper.c
> index 72105e6093cea7b0bc9fdfc96229afded7650dce..ed1b76857116579f9f9e8ce2fc1ef2af67c9608e 100644
> --- a/src/ldap_helper.c
> +++ b/src/ldap_helper.c
> @@ -327,10 +327,6 @@ static isc_result_t modify_ldap_common(dns_name_t *owner, ldap_instance_t *ldap_
> static isc_result_t soa_serial_increment(isc_mem_t *mctx, ldap_instance_t *inst,
> dns_name_t *zone_name);
>
> -static isc_result_t
> -ldap_delete_zone2(ldap_instance_t *inst, dns_name_t *name, isc_boolean_t lock,
> - isc_boolean_t preserve_forwarding);
> -
> /* Functions for maintaining pool of LDAP connections */
> static isc_result_t ldap_pool_create(isc_mem_t *mctx, unsigned int connections,
> ldap_pool_t **poolp);
> @@ -521,7 +517,7 @@ new_ldap_instance(isc_mem_t *mctx, const char *db_name,
> CHECK(setting_get_bool("psearch", ldap_inst->local_settings, &psearch));
> CHECK(setting_get_uint("connections", ldap_inst->local_settings, &connections));
>
> - CHECK(zr_create(mctx, ldap_inst->global_settings,
> + CHECK(zr_create(mctx, ldap_inst, ldap_inst->global_settings,
> &ldap_inst->zone_register));
>
> CHECK(isc_mutex_init(&ldap_inst->kinit_lock));
> @@ -579,9 +575,6 @@ void
> destroy_ldap_instance(ldap_instance_t **ldap_instp)
> {
> ldap_instance_t *ldap_inst;
> - dns_rbtnodechain_t chain;
> - dns_rbt_t *rbt = NULL;
> - isc_result_t result = ISC_R_SUCCESS;
> const char *db_name;
> isc_sockaddr_t *addr;
>
> @@ -593,68 +586,6 @@ destroy_ldap_instance(ldap_instance_t **ldap_instp)
>
> db_name = ldap_inst->db_name; /* points to DB instance: outside ldap_inst */
>
> - /*
> - * Unregister all zones already registered in BIND.
> - *
> - * NOTE: This should be probably done in zone_register.c
> - */
> - if (ldap_inst->zone_register != NULL)
> - rbt = zr_get_rbt(ldap_inst->zone_register);
> - if (rbt == NULL)
> - result = ISC_R_NOTFOUND;
> -
> - /* Potentially ISC_R_NOSPACE can occur. Destroy codepath has no way to
> - * return errors, so kill BIND.
> - * DNS_R_NAMETOOLONG should never happen, because all names were checked
> - * while loading. */
> -
> - dns_rbtnodechain_init(&chain, ldap_inst->mctx);
> - while (result != ISC_R_NOMORE && result != ISC_R_NOTFOUND) {
> - dns_fixedname_t name;
> - dns_fixedname_t origin;
> - dns_fixedname_t concat;
> - dns_fixedname_init(&name);
> - dns_fixedname_init(&origin);
> - dns_fixedname_init(&concat);
> -
> - dns_rbtnodechain_reset(&chain);
> - result = dns_rbtnodechain_first(&chain, rbt, NULL, NULL);
> - RUNTIME_CHECK(result == ISC_R_SUCCESS || result == DNS_R_NEWORIGIN ||
> - result == ISC_R_NOTFOUND);
> -
> - /* Search for first zone in zone register and omit auxiliary nodes. */
> - while (result != ISC_R_NOMORE && result != ISC_R_NOTFOUND) {
> - dns_rbtnode_t *node = NULL;
> -
> - result = dns_rbtnodechain_current(&chain, dns_fixedname_name(&name),
> - dns_fixedname_name(&origin), &node);
> - RUNTIME_CHECK(result == ISC_R_SUCCESS);
> -
> - if (node->data != NULL) { /* Auxiliary nodes have data == NULL. */
> - result = dns_name_concatenate(dns_fixedname_name(&name),
> - dns_fixedname_name(&origin),
> - dns_fixedname_name(&concat),
> - NULL);
> - RUNTIME_CHECK(result == ISC_R_SUCCESS);
> - break;
> - }
> -
> - result = dns_rbtnodechain_next(&chain, NULL, NULL);
> - RUNTIME_CHECK(result == ISC_R_SUCCESS || result == DNS_R_NEWORIGIN ||
> - result == ISC_R_NOMORE);
> - }
> - if (result == ISC_R_NOMORE || result == ISC_R_NOTFOUND)
> - break;
> -
> - result = ldap_delete_zone2(ldap_inst,
> - dns_fixedname_name(&concat),
> - ISC_TRUE, ISC_FALSE);
> - RUNTIME_CHECK(result == ISC_R_SUCCESS);
> - }
> -
> - dns_rbtnodechain_invalidate(&chain);
> -
> - /* TODO: Terminate psearch watcher sooner? */
> if (ldap_inst->watcher != 0) {
> ldap_inst->exiting = ISC_TRUE;
> /*
> @@ -671,13 +602,15 @@ destroy_ldap_instance(ldap_instance_t **ldap_instp)
> ldap_inst->watcher = 0;
> }
>
> + /* Unregister all zones already registered in BIND. */
> + zr_destroy(&ldap_inst->zone_register);
> + fwdr_destroy(&ldap_inst->fwd_register);
> +
> ldap_pool_destroy(&ldap_inst->pool);
> dns_view_detach(&ldap_inst->view);
>
> DESTROYLOCK(&ldap_inst->kinit_lock);
>
> - zr_destroy(&ldap_inst->zone_register);
> -
> while (!ISC_LIST_EMPTY(ldap_inst->orig_global_forwarders.addrs)) {
> addr = ISC_LIST_HEAD(ldap_inst->orig_global_forwarders.addrs);
> ISC_LIST_UNLINK(ldap_inst->orig_global_forwarders.addrs, addr, link);
> @@ -853,6 +786,22 @@ configure_zone_ssutable(dns_zone_t *zone, const char *update_str)
>
> /* Delete zone by dns zone name */
> static isc_result_t
> +delete_forwarding_table(ldap_instance_t *inst, dns_name_t *name,
> + const char *msg_obj_type, const char *dn) {
> + isc_result_t result;
> +
> + result = dns_fwdtable_delete(inst->view->fwdtable, name);
> + if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
> + log_error_r("%s '%s': failed to delete forwarders",
> + msg_obj_type, dn);
> + return result;
> + } else {
> + return ISC_R_SUCCESS; /* ISC_R_NOTFOUND = nothing to delete */
> + }
> +}
> +
> +/* Delete zone by dns zone name */
> +isc_result_t
> ldap_delete_zone2(ldap_instance_t *inst, dns_name_t *name, isc_boolean_t lock,
> isc_boolean_t preserve_forwarding)
> {
> @@ -941,22 +890,6 @@ cleanup:
> return result;
> }
>
> -static isc_result_t
> -delete_forwarding_table(ldap_instance_t *inst, dns_name_t *name,
> - const char *msg_obj_type, const char *dn) {
> - isc_result_t result;
> -
> - /* Clean old fwdtable. */
> - result = dns_fwdtable_delete(inst->view->fwdtable, name);
> - if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
> - log_error_r("%s '%s': failed to delete forwarders",
> - msg_obj_type, dn);
> - return result;
> - } else {
> - return ISC_R_SUCCESS; /* ISC_R_NOTFOUND = nothing to delete */
> - }
> -}
> -
> /**
> * Read forwarding policy (from idnsForwardingPolicy attribute) and
> * list of forwarders (from idnsForwarders multi-value attribute)
> diff --git a/src/ldap_helper.h b/src/ldap_helper.h
> index 86c3d4ec040a073df8c89d67b93cbd9e1b3bfb77..fe54687fa1e8ec16d83105e08e1a17cdec68614e 100644
> --- a/src/ldap_helper.h
> +++ b/src/ldap_helper.h
> @@ -84,6 +84,10 @@ void destroy_ldap_instance(ldap_instance_t **ldap_inst);
> isc_result_t
> refresh_zones_from_ldap(ldap_instance_t *ldap_inst, isc_boolean_t delete_only);
>
> +isc_result_t
> +ldap_delete_zone2(ldap_instance_t *inst, dns_name_t *name, isc_boolean_t lock,
> + isc_boolean_t preserve_forwarding);
> +
> /* Functions for writing to LDAP. */
> isc_result_t write_to_ldap(dns_name_t *owner, ldap_instance_t *ldap_inst,
> dns_rdatalist_t *rdlist);
> diff --git a/src/zone_register.c b/src/zone_register.c
> index e8d844f7bd1de83a6c894ea18fed127af081fd0f..949219ffc2e2adb40943709a3420014e672c88e6 100644
> --- a/src/zone_register.c
> +++ b/src/zone_register.c
> @@ -35,6 +35,7 @@
> #include "zone_register.h"
> #include "rdlist.h"
> #include "settings.h"
> +#include "rbt_helper.h"
>
> /*
> * The zone register is a red-black tree that maps a dns name of a zone to the
> @@ -50,6 +51,7 @@ struct zone_register {
> isc_rwlock_t rwlock;
> dns_rbt_t *rbt;
> settings_set_t *global_settings;
> + ldap_instance_t *ldap_inst;
> };
>
> typedef struct {
> @@ -88,6 +90,15 @@ static const setting_t zone_settings[] = {
> end_of_settings
> };
>
> +isc_result_t
> +zr_rbt_iter_init(zone_register_t *zr, rbt_iterator_t *iter,
> + dns_name_t *nodename) {
> + if (zr->rbt == NULL)
> + return ISC_R_NOTFOUND;
> +
> + return rbt_iter_first(zr->mctx, zr->rbt, &zr->rwlock, iter, nodename);
> +}
> +
> dns_rbt_t *
> zr_get_rbt(zone_register_t *zr)
> {
> @@ -105,19 +116,23 @@ zr_get_mctx(zone_register_t *zr) {
> * Create a new zone register.
> */
> isc_result_t
> -zr_create(isc_mem_t *mctx, settings_set_t *glob_settings, zone_register_t **zrp)
> +zr_create(isc_mem_t *mctx, ldap_instance_t *ldap_inst,
> + settings_set_t *glob_settings, zone_register_t **zrp)
> {
> isc_result_t result;
> zone_register_t *zr = NULL;
>
> + REQUIRE(ldap_inst != NULL);
> + REQUIRE(glob_settings != NULL);
> REQUIRE(zrp != NULL && *zrp == NULL);
>
> CHECKED_MEM_GET_PTR(mctx, zr);
> ZERO_PTR(zr);
> isc_mem_attach(mctx, &zr->mctx);
> CHECK(dns_rbt_create(mctx, delete_zone_info, mctx, &zr->rbt));
> CHECK(isc_rwlock_init(&zr->rwlock, 0, 0));
> zr->global_settings = glob_settings;
> + zr->ldap_inst = ldap_inst;
>
> *zrp = zr;
> return ISC_R_SUCCESS;
> @@ -132,19 +147,42 @@ cleanup:
> return result;
> }
>
> -/*
> - * Destroy a zone register.
> +/**
> + * Destroy a zone register and unload all zones registered in it.
> + *
> + * @warning
> + * Potentially ISC_R_NOSPACE can occur. Destroy codepath has no way to
> + * return errors, so kill BIND. DNS_R_NAMETOOLONG should never happen,
> + * because all names were checked while loading.
> */
> void
> zr_destroy(zone_register_t **zrp)
> {
> + DECLARE_BUFFERED_NAME(name);
> zone_register_t *zr;
> + rbt_iterator_t iter;
> + isc_result_t result;
>
> if (zrp == NULL || *zrp == NULL)
> return;
>
> zr = *zrp;
>
> + /* It is not safe to iterate over RBT and delete nodes at the same
> + * time. Restart iteration after each change. */
> + do {
> + INIT_BUFFERED_NAME(name);
> + result = zr_rbt_iter_init(zr, &iter, &name);
> + RUNTIME_CHECK(result == ISC_R_SUCCESS || result == ISC_R_NOTFOUND);
> + if (result == ISC_R_SUCCESS) {
> + rbt_iter_stop(&iter);
> + result = ldap_delete_zone2(zr->ldap_inst,
> + &name,
> + ISC_TRUE, ISC_FALSE);
> + RUNTIME_CHECK(result == ISC_R_SUCCESS);
> + }
> + } while (result == ISC_R_SUCCESS);
> +
> RWLOCK(&zr->rwlock, isc_rwlocktype_write);
> dns_rbt_destroy(&zr->rbt);
> RWUNLOCK(&zr->rwlock, isc_rwlocktype_write);
> diff --git a/src/zone_register.h b/src/zone_register.h
> index 3f4114d2256c1e8af5f67c69f1829900c9c7b2e9..7ef40f7abdf4ed17cb32414907b5b7283456bb22 100644
> --- a/src/zone_register.h
> +++ b/src/zone_register.h
> @@ -23,11 +23,14 @@
>
> #include "cache.h"
> #include "settings.h"
> +#include "rbt_helper.h"
> +#include "ldap_helper.h"
>
> typedef struct zone_register zone_register_t;
>
> isc_result_t
> -zr_create(isc_mem_t *mctx, settings_set_t *glob_settings, zone_register_t **zrp);
> +zr_create(isc_mem_t *mctx, ldap_instance_t *ldap_inst,
> + settings_set_t *glob_settings, zone_register_t **zrp);
>
> void
> zr_destroy(zone_register_t **zrp);
> @@ -54,6 +57,10 @@ zr_get_zone_ptr(zone_register_t *zr, dns_name_t *name, dns_zone_t **zonep);
> isc_result_t
> zr_get_zone_settings(zone_register_t *zr, dns_name_t *name, settings_set_t **set);
>
> +isc_result_t
> +zr_rbt_iter_init(zone_register_t *zr, rbt_iterator_t *iter,
> + dns_name_t *nodename);
> +
> dns_rbt_t *
> zr_get_rbt(zone_register_t *zr);
>
> --
> 1.7.11.7
>
--
Adam Tkac, Red Hat, Inc.
More information about the Freeipa-devel
mailing list