[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