[Freeipa-devel] [PATCH 92] Flush whole zone from cache during zone renaming/removal.

Adam Tkac atkac at redhat.com
Thu Dec 13 16:07:21 UTC 2012


On Wed, Dec 05, 2012 at 01:25:56PM +0100, Petr Spacek wrote:
> On 12/04/2012 02:36 PM, Adam Tkac wrote:
> >On Thu, Nov 15, 2012 at 07:06:37PM +0100, Petr Spacek wrote:
> >>>Hello,
> >>>
> >>>attached patch is preliminary implementation of selective zone flush.
> >>>
> >>>
> >>>Implementation is not so straight-forward as I want to see. Before
> >>>discussing the patch itself - can we consider per-zone caches? In
> >>>that case, we can simply deallocate whole per-zone RBT and we are
> >>>done.
> >>>
> >>>Pros:
> >>>* Potentially better concurrency, simpler code, much less corner cases.
> >>>
> >>>Cons:
> >>>* We have to look into Zone register before searching the cache.
> >>>* It can limit concurrency ... with many extra small zones? I'm not sure.
> >Hi Peter,
> >
> >In my opinion per-zone caches are better. Look into zone register isn't
> >costly operation.
> Second version of the patch with per-zone caches is attached. I cut
> all debugging code so this version could be considered as final.

Ack

> From 9b1fe8c26049d0aeff8cc48c36b4faa4aca12b30 Mon Sep 17 00:00:00 2001
> From: Petr Spacek <pspacek at redhat.com>
> Date: Wed, 5 Dec 2012 12:52:41 +0100
> Subject: [PATCH] Create separate record cache for each zone.
> 
> This separation should solve all problems with stale records
> after zone deletion and renaming.
> 
> https://fedorahosted.org/bind-dyndb-ldap/ticket/91
> 
> Signed-off-by: Petr Spacek <pspacek at redhat.com>
> ---
>  src/cache.c         | 45 +++++++++++++++++----------------
>  src/cache.h         |  3 ++-
>  src/ldap_helper.c   | 72 +++++++++++++++++++++++++++++------------------------
>  src/ldap_helper.h   |  3 ---
>  src/zone_register.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++----
>  src/zone_register.h | 11 +++++++-
>  6 files changed, 139 insertions(+), 64 deletions(-)
> 
> diff --git a/src/cache.c b/src/cache.c
> index 898d48b291a83da7f77dbcf79e2bd3e7ff8281aa..fd57fd92eb35dcbbd5c1e1911a93730624e30002 100644
> --- a/src/cache.c
> +++ b/src/cache.c
> @@ -38,11 +38,11 @@
>  #include "util.h"
>  
>  struct ldap_cache {
> -	isc_mutex_t	mutex; /* TODO: RWLOCK? */
> -	isc_mem_t	*mctx;
> -	dns_rbt_t	*rbt;
> -	isc_interval_t	cache_ttl;
> -	isc_boolean_t	psearch;
> +	isc_mutex_t		mutex;		/* TODO: RWLOCK? */
> +	isc_mem_t		*mctx;
> +	dns_rbt_t		*rbt;
> +	const isc_interval_t	*cache_ttl;	/* pointer to LDAP instance */
> +	const isc_boolean_t	*psearch;	/* pointer to LDAP instance */
>  };
>  
>  typedef struct {
> @@ -78,8 +78,9 @@ cache_node_create(ldap_cache_t *cache, cache_node_t **nodep)
>  	isc_mem_attach(cache->mctx, &node->mctx);
>  	ZERO_PTR(&node->rdatalist);
>  	/* Do not set the ttl when psearch is enabled. */
> -	if (!cache->psearch)
> -		CHECK(isc_time_nowplusinterval(&node->valid_until, &cache->cache_ttl));
> +	if (*cache->psearch == ISC_FALSE)
> +		CHECK(isc_time_nowplusinterval(&node->valid_until,
> +					       cache->cache_ttl));
>  
>  	*nodep = node;
>  	return ISC_R_SUCCESS;
> @@ -90,29 +91,27 @@ cleanup:
>  	return result;
>  }
>  
> +/**
> + * @param[in] cache_ttl ISC interval in LDAP instance shared by all caches
> + * @param[in] psearch   boolean in LDAP instance shared by all caches
> + */
>  isc_result_t
> -new_ldap_cache(isc_mem_t *mctx, const char *const *argv, ldap_cache_t **cachep, isc_boolean_t psearch)
> +new_ldap_cache(isc_mem_t *mctx, const isc_interval_t *cache_ttl,
> +	       const isc_boolean_t *psearch, ldap_cache_t **cachep)
>  {
>  	isc_result_t result;
>  	ldap_cache_t *cache = NULL;
> -	unsigned int cache_ttl;
> -	setting_t cache_settings[] = {
> -		{ "cache_ttl", default_uint(120) },
> -		end_of_settings
> -	};
>  
> +	REQUIRE(cache_ttl != NULL);
> +	REQUIRE(psearch != NULL);
>  	REQUIRE(cachep != NULL && *cachep == NULL);
>  
> -	cache_settings[0].target = &cache_ttl;
> -	CHECK(set_settings(cache_settings, argv));
> -
>  	CHECKED_MEM_GET_PTR(mctx, cache);
>  	ZERO_PTR(cache);
>  	isc_mem_attach(mctx, &cache->mctx);
>  
> -	isc_interval_set(&cache->cache_ttl, cache_ttl, 0);
> -	
> -	if (cache_ttl) {
> +	cache->cache_ttl = cache_ttl;
> +	if (!isc_interval_iszero(cache_ttl)) {
>  		CHECK(dns_rbt_create(mctx, cache_node_deleter, NULL,
>  				     &cache->rbt));
>  		CHECK(isc_mutex_init(&cache->mutex));
> @@ -123,21 +122,23 @@ new_ldap_cache(isc_mem_t *mctx, const char *const *argv, ldap_cache_t **cachep,
>  	return ISC_R_SUCCESS;
>  
>  cleanup:
> -	if (cache != NULL)
> -		destroy_ldap_cache(&cache);
> +	destroy_ldap_cache(&cache);
>  
>  	return result;
>  }
>  
>  void
>  destroy_ldap_cache(ldap_cache_t **cachep)
>  {
>  	ldap_cache_t *cache;
>  
> -	REQUIRE(cachep != NULL && *cachep != NULL);
> +	REQUIRE(cachep != NULL);
>  
>  	cache = *cachep;
>  
> +	if (cache == NULL)
> +		return;
> +
>  	if (cache->rbt) {
>  		LOCK(&cache->mutex);
>  		dns_rbt_destroy(&cache->rbt);
> diff --git a/src/cache.h b/src/cache.h
> index a7aa5b7e889d9e195484a11dcf4f9a10d811f623..7c7e69b305d3021f154ebb17d5b879ba8f34590e 100644
> --- a/src/cache.h
> +++ b/src/cache.h
> @@ -30,7 +30,8 @@ typedef struct ldap_cache ldap_cache_t;
>   * Create a new cache.
>   */
>  isc_result_t
> -new_ldap_cache(isc_mem_t *mctx, const char * const *argv, ldap_cache_t **cachep, isc_boolean_t psearch);
> +new_ldap_cache(isc_mem_t *mctx, const isc_interval_t *cache_ttl,
> +	       const isc_boolean_t *psearch, ldap_cache_t **cachep);
>  
>  /*
>   * Free all resources used up by the cache.
> diff --git a/src/ldap_helper.c b/src/ldap_helper.c
> index 436985247803240f9ec4f2c3e5118adf8466beec..5c0d914d3af89dac9739b75a4d92be09ddf27532 100644
> --- a/src/ldap_helper.c
> +++ b/src/ldap_helper.c
> @@ -67,6 +67,7 @@
>  
>  #include "acl.h"
>  #include "krb5_helper.h"
> +#include "cache.h"
>  #include "ldap_convert.h"
>  #include "ldap_entry.h"
>  #include "ldap_helper.h"
> @@ -150,9 +151,6 @@ struct ldap_instance {
>  	/* Pool of LDAP connections */
>  	ldap_pool_t		*pool;
>  
> -	/* RRs cache */
> -	ldap_cache_t		*cache;
> -
>  	/* Our own list of zones. */
>  	zone_register_t		*zone_register;
>  
> @@ -177,6 +175,7 @@ struct ldap_instance {
>  	ld_string_t		*krb5_keytab;
>  	ld_string_t		*fake_mname;
>  	isc_boolean_t		psearch;
> +	isc_interval_t		cache_ttl;
>  	ld_string_t		*ldap_hostname;
>  	isc_task_t		*task;
>  	isc_thread_t		watcher;
> @@ -344,6 +343,7 @@ new_ldap_instance(isc_mem_t *mctx, const char *db_name,
>  	dns_view_t *view = NULL;
>  	ld_string_t *auth_method_str = NULL;
>  	dns_forwarders_t *orig_global_forwarders = NULL;
> +	isc_uint32_t cache_ttl_seconds;
>  	setting_t ldap_settings[] = {
>  		{ "uri",	 no_default_string		},
>  		{ "connections", default_uint(2)		},
> @@ -362,6 +362,7 @@ new_ldap_instance(isc_mem_t *mctx, const char *db_name,
>  		{ "krb5_keytab", default_string("")		},
>  		{ "fake_mname",	 default_string("")		},
>  		{ "psearch",	 default_boolean(ISC_FALSE)	},
> +		{ "cache_ttl",	 default_uint(120)		},
>  		{ "ldap_hostname", default_string("")		},
>  		{ "sync_ptr",	 default_boolean(ISC_FALSE) },
>  		{ "dyn_update",	 default_boolean(ISC_FALSE) },
> @@ -417,12 +418,14 @@ new_ldap_instance(isc_mem_t *mctx, const char *db_name,
>  	ldap_settings[i++].target = ldap_inst->sasl_password;
>  	ldap_settings[i++].target = ldap_inst->krb5_keytab;
>  	ldap_settings[i++].target = ldap_inst->fake_mname;
> -	ldap_settings[i++].target = &ldap_inst->psearch; 
> +	ldap_settings[i++].target = &ldap_inst->psearch;
> +	ldap_settings[i++].target = &cache_ttl_seconds;
>  	ldap_settings[i++].target = ldap_inst->ldap_hostname;
>  	ldap_settings[i++].target = &ldap_inst->sync_ptr;
>  	ldap_settings[i++].target = &ldap_inst->dyn_update;
>  	ldap_settings[i++].target = &ldap_inst->serial_autoincrement;
>  	CHECK(set_settings(ldap_settings, argv));
> +	isc_interval_set(&ldap_inst->cache_ttl, cache_ttl_seconds, 0);
>  
>  	/* Set timer for deadlock detection inside semaphore_wait_timed . */
>  	if (semaphore_wait_timeout.seconds < ldap_inst->timeout*SEM_WAIT_TIMEOUT_MUL)
> @@ -493,7 +496,6 @@ new_ldap_instance(isc_mem_t *mctx, const char *db_name,
>  		goto cleanup;
>  	}
>  
> -	CHECK(new_ldap_cache(mctx, argv, &ldap_inst->cache, ldap_inst->psearch));
>  	CHECK(ldap_pool_create(mctx, ldap_inst->connections, &ldap_inst->pool));
>  	CHECK(ldap_pool_connect(ldap_inst->pool, ldap_inst));
>  
> @@ -661,9 +663,6 @@ destroy_ldap_instance(ldap_instance_t **ldap_instp)
>  
>  	DESTROYLOCK(&ldap_inst->kinit_lock);
>  
> -	if (ldap_inst->cache != NULL)
> -		destroy_ldap_cache(&ldap_inst->cache);
> -
>  	zr_destroy(&ldap_inst->zone_register);
>  
>  	while (!ISC_LIST_EMPTY(ldap_inst->orig_global_forwarders.addrs)) {
> @@ -860,9 +859,6 @@ ldap_delete_zone2(ldap_instance_t *inst, dns_name_t *name, isc_boolean_t lock,
>  				    zone_name_char);
>  	}
>  
> -	/* TODO: flush cache records belonging to deleted zone */
> -	CHECK(discard_from_cache(inst->cache, name));
> -
>  	result = zr_get_zone_ptr(inst->zone_register, name, &zone);
>  	if (result == ISC_R_NOTFOUND || result == DNS_R_PARTIALMATCH) {
>  		log_debug(1, "zone '%s' not found in zone register", zone_name_char);
> @@ -1235,6 +1231,7 @@ ldap_parse_zoneentry(ldap_entry_t *entry, ldap_instance_t *inst)
>  	unsigned char *zr_digest = NULL;
>  	ldapdb_rdatalist_t rdatalist;
>  	isc_boolean_t zone_dynamic = ISC_FALSE;
> +	ldap_cache_t *cache = NULL;
>  
>  	REQUIRE(entry != NULL);
>  	REQUIRE(inst != NULL);
> @@ -1251,7 +1248,12 @@ ldap_parse_zoneentry(ldap_entry_t *entry, ldap_instance_t *inst)
>  	if (result == ISC_R_SUCCESS)
>  		unlock = ISC_TRUE;
>  
> -	CHECK(discard_from_cache(inst->cache, &name));
> +	/* cache will not exist before zone load */
> +	result = zr_get_zone_cache(inst->zone_register, &name, &cache);
> +	if (result == ISC_R_SUCCESS)
> +		CHECK(discard_from_cache(cache, &name));
> +	else if (result != ISC_R_NOTFOUND)
> +		goto cleanup;
>  
>  	/*
>  	 * Forwarding has top priority hence when the forwarders are properly
> @@ -1276,7 +1278,8 @@ ldap_parse_zoneentry(ldap_entry_t *entry, ldap_instance_t *inst)
>  	result = zr_get_zone_ptr(inst->zone_register, &name, &zone);
>  	if (result == ISC_R_NOTFOUND || result == DNS_R_PARTIALMATCH) {
>  		CHECK(create_zone(inst, &name, &zone));
> -		CHECK(zr_add_zone(inst->zone_register, zone, dn));
> +		CHECK(zr_add_zone(inst->zone_register, zone, dn,
> +				  &inst->cache_ttl, &inst->psearch));
>  		publish = ISC_TRUE;
>  		log_debug(2, "created zone %p: %s", zone, dn);
>  	} else if (result != ISC_R_SUCCESS)
> @@ -1801,14 +1804,14 @@ ldapdb_rdatalist_get(isc_mem_t *mctx, ldap_instance_t *ldap_inst, dns_name_t *na
>  	ldap_qresult_t *ldap_qresult = NULL;
>  	ldap_entry_t *entry;
>  	ld_string_t *string = NULL;
> -	ldap_cache_t *cache;
> +	ldap_cache_t *cache = NULL;
>  
>  	REQUIRE(ldap_inst != NULL);
>  	REQUIRE(name != NULL);
>  	REQUIRE(rdatalist != NULL);
>  
>  	/* Check if RRs are in the cache */
> -	cache = ldap_instance_getcache(ldap_inst);
> +	CHECK(zr_get_zone_cache(ldap_inst->zone_register, name, &cache));
>  	result = ldap_cache_getrdatalist(mctx, cache, name, rdatalist);
>  	if (result == ISC_R_SUCCESS)
>  		return ISC_R_SUCCESS;
> @@ -2700,7 +2703,7 @@ modify_ldap_common(dns_name_t *owner, ldap_instance_t *ldap_inst,
>  	ld_string_t *owner_dn = NULL;
>  	LDAPMod *change[3] = { NULL };
>  	LDAPMod *change_ptr = NULL;
> -	ldap_cache_t *cache;
> +	ldap_cache_t *cache = NULL;
>  	ldap_entry_t *entry;
>  	ldap_valuelist_t values;
>  	isc_boolean_t zone_dyn_update = ldap_inst->dyn_update;
> @@ -2757,7 +2760,7 @@ modify_ldap_common(dns_name_t *owner, ldap_instance_t *ldap_inst,
>  		goto cleanup;
>  	}
>  	/* Flush modified record from the cache */
> -	cache = ldap_instance_getcache(ldap_inst);
> +	CHECK(zr_get_zone_cache(ldap_inst->zone_register, owner, &cache));
>  	CHECK(discard_from_cache(cache, owner));
>  
>  	if (rdlist->type == dns_rdatatype_soa) {
> @@ -2949,10 +2952,12 @@ modify_ldap_common(dns_name_t *owner, ldap_instance_t *ldap_inst,
>  
>  		/* Modify PTR record. */
>  		CHECK(ldap_modify_do(ldap_inst, ldap_conn, str_buf(owner_dn_ptr), change, delete_node));
> -		(void) discard_from_cache(ldap_instance_getcache(ldap_inst),
> -					  dns_fixedname_name(&name)); 
> +		cache = NULL;
> +		CHECK(zr_get_zone_cache(ldap_inst->zone_register,
> +					dns_fixedname_name(&name), &cache));
> +		CHECK(discard_from_cache(cache, dns_fixedname_name(&name)));
>  	}
> -	
> +
>  cleanup:
>  	ldap_query_free(ISC_FALSE, &ldap_qresult);
>  	ldap_pool_putconnection(ldap_inst->pool, &ldap_conn);
> @@ -2982,12 +2987,6 @@ remove_from_ldap(dns_name_t *owner, ldap_instance_t *ldap_inst,
>  				  delete_node);
>  }
>  
> -ldap_cache_t *
> -ldap_instance_getcache(ldap_instance_t *ldap_inst)
> -{
> -	return ldap_inst->cache;
> -}
> -
>  static isc_result_t
>  ldap_pool_create(isc_mem_t *mctx, unsigned int connections, ldap_pool_t **poolp)
>  {
> @@ -3203,6 +3202,7 @@ soa_serial_increment(isc_mem_t *mctx, ldap_instance_t *inst,
>  	isc_uint32_t old_serial;
>  	isc_uint32_t new_serial;
>  	isc_time_t curr_time;
> +	ldap_cache_t *cache = NULL;
>  
>  	REQUIRE(inst != NULL);
>  	REQUIRE(zone_name != NULL);
> @@ -3236,7 +3236,8 @@ soa_serial_increment(isc_mem_t *mctx, ldap_instance_t *inst,
>  
>  	/* write the new serial back to DB */
>  	CHECK(modify_soa_record(inst, NULL, str_buf(zone_dn), soa_rdata));
> -	CHECK(discard_from_cache(ldap_instance_getcache(inst), zone_name));
> +	CHECK(zr_get_zone_cache(inst->zone_register, zone_name, &cache));
> +	CHECK(discard_from_cache(cache, zone_name));
>  
>  	/* put the new SOA to inst->cache and compare old and new serials */
>  	CHECK(ldap_get_zone_serial(inst, zone_name, &new_serial));
> @@ -3410,7 +3411,7 @@ update_record(isc_task_t *task, isc_event_t *event)
>  	ldap_psearchevent_t *pevent = (ldap_psearchevent_t *)event;
>  	isc_result_t result;
>  	ldap_instance_t *inst = NULL;
> -	ldap_cache_t *cache;
> +	ldap_cache_t *cache = NULL;
>  	isc_mem_t *mctx;
>  	mctx = pevent->mctx;
>  
> @@ -3437,16 +3438,23 @@ update_record(isc_task_t *task, isc_event_t *event)
>  	}
>  
>  	/* Get cache instance & clean old record */
> -	cache = ldap_instance_getcache(inst);
> +	CHECK(zr_get_zone_cache(inst->zone_register, &name, &cache));
>  	CHECK(discard_from_cache(cache, &name));
>  
> +	/* TODO: double check correctness before replacing ldap_query() with
> +	 *       data from *event */
>  	if (PSEARCH_MODDN(pevent->chgtype)) {
>  		/* remove previous name only if it was inside DNS subtree */
> -		if(dn_to_dnsname(mctx, pevent->prevdn, &prevname, &prevorigin)
> +		if (dn_to_dnsname(mctx, pevent->prevdn, &prevname, &prevorigin)
>  				== ISC_R_SUCCESS) {
>  			log_debug(5, "psearch_update: removing name from cache, dn: '%s'",
>  					  pevent->prevdn);
> -			CHECK(discard_from_cache(cache, &prevname));
> +			cache = NULL;
> +			result = zr_get_zone_cache(inst->zone_register, &prevname, &cache);
> +			if (result == ISC_R_SUCCESS)
> +				CHECK(discard_from_cache(cache, &prevname));
> +			else if (result != ISC_R_NOTFOUND)
> +				goto cleanup;
>  		} else {
>  			log_debug(5, "psearch_update: old name wasn't managed "
>  					"by plugin, dn '%s'", pevent->prevdn);
> @@ -3807,7 +3815,7 @@ restart:
>  			 * We want to save cache in case of search timeout during restart.
>  			 */
>  			CHECK(refresh_zones_from_ldap(inst, ISC_TRUE));
> -			CHECK(flush_ldap_cache(inst->cache));
> +			CHECK(zr_flush_all_caches(inst->zone_register));
>  			flush_required = ISC_FALSE;
>  		}
>  
> diff --git a/src/ldap_helper.h b/src/ldap_helper.h
> index f6cbdc593d91485f767ae5ea6017e114f95733d1..a1e52f044d5e81ace7fb2d3c2ab082ad838944d1 100644
> --- a/src/ldap_helper.h
> +++ b/src/ldap_helper.h
> @@ -90,7 +90,4 @@ isc_result_t write_to_ldap(dns_name_t *owner, ldap_instance_t *ldap_inst,
>  isc_result_t remove_from_ldap(dns_name_t *owner, ldap_instance_t *ldap_inst,
>  		dns_rdatalist_t *rdlist, isc_boolean_t delete_node);
>  
> -/* Get cache associated with ldap_inst */
> -ldap_cache_t *ldap_instance_getcache(ldap_instance_t *ldap_inst);
> -
>  #endif /* !_LD_LDAP_HELPER_H_ */
> diff --git a/src/zone_register.c b/src/zone_register.c
> index 18438bf937a6482ddf058adbecdc21e7cf2e7f26..03eb1d0765de371420e4da6beb1a7b2e2e52db94 100644
> --- a/src/zone_register.c
> +++ b/src/zone_register.c
> @@ -53,7 +53,8 @@ typedef struct {
>  	dns_zone_t	*zone;
>  	char		*dn;
>  	isc_uint32_t	serial; /* last value processed by plugin (!= value in DB) */
> -	unsigned char digest[RDLIST_DIGESTLENGTH]; /* MD5 digest from all RRs in zone record */
> +	unsigned char	digest[RDLIST_DIGESTLENGTH]; /* MD5 digest from all RRs in zone record */
> +	ldap_cache_t	*cache;
>  } zone_info_t;
>  
>  /* Callback for dns_rbt_create(). */
> @@ -129,6 +130,7 @@ zr_destroy(zone_register_t **zrp)
>   */
>  static isc_result_t
>  create_zone_info(isc_mem_t *mctx, dns_zone_t *zone, const char *dn,
> +		 const isc_interval_t *cache_ttl, const isc_boolean_t *psearch,
>  		 zone_info_t **zinfop)
>  {
>  	isc_result_t result;
> @@ -139,9 +141,9 @@ create_zone_info(isc_mem_t *mctx, dns_zone_t *zone, const char *dn,
>  	REQUIRE(zinfop != NULL && *zinfop == NULL);
>  
>  	CHECKED_MEM_GET_PTR(mctx, zinfo);
> +	ZERO_PTR(zinfo);
>  	CHECKED_MEM_STRDUP(mctx, dn, zinfo->dn);
> -	zinfo->serial = 0;
> -	zinfo->zone = NULL;
> +	CHECK(new_ldap_cache(mctx, cache_ttl, psearch, &zinfo->cache));
>  	dns_zone_attach(zone, &zinfo->zone);
>  
>  	*zinfop = zinfo;
> @@ -165,6 +167,7 @@ delete_zone_info(void *arg1, void *arg2)
>  	if (zinfo == NULL)
>  		return;
>  
> +	destroy_ldap_cache(&zinfo->cache);
>  	isc_mem_free(mctx, zinfo->dn);
>  	dns_zone_detach(&zinfo->zone);
>  	SAFE_MEM_PUT_PTR(mctx, zinfo);
> @@ -175,7 +178,8 @@ delete_zone_info(void *arg1, void *arg2)
>   * must be absolute and the zone cannot already be in the zone register.
>   */
>  isc_result_t
> -zr_add_zone(zone_register_t *zr, dns_zone_t *zone, const char *dn)
> +zr_add_zone(zone_register_t *zr, dns_zone_t *zone, const char *dn,
> +	    const isc_interval_t *cache_ttl, const isc_boolean_t *psearch)
>  {
>  	isc_result_t result;
>  	dns_name_t *name;
> @@ -206,7 +210,8 @@ zr_add_zone(zone_register_t *zr, dns_zone_t *zone, const char *dn)
>  		goto cleanup;
>  	}
>  
> -	CHECK(create_zone_info(zr->mctx, zone, dn, &new_zinfo));
> +	CHECK(create_zone_info(zr->mctx, zone, dn, cache_ttl, psearch,
> +			       &new_zinfo));
>  	CHECK(dns_rbt_addname(zr->rbt, name, new_zinfo));
>  
>  cleanup:
> @@ -248,6 +253,60 @@ cleanup:
>  	return result;
>  }
>  
> +isc_result_t
> +zr_flush_all_caches(zone_register_t *zr) {
> +	dns_rbtnodechain_t chain;
> +	isc_result_t result;
> +
> +	dns_rbtnodechain_init(&chain, zr->mctx);
> +	RWLOCK(&zr->rwlock, isc_rwlocktype_write);
> +
> +	result = dns_rbtnodechain_first(&chain, zr->rbt, NULL, NULL);
> +	while (result == DNS_R_NEWORIGIN || result == ISC_R_SUCCESS) {
> +		dns_rbtnode_t *node = NULL;
> +		ldap_cache_t *cache;
> +
> +		CHECK(dns_rbtnodechain_current(&chain, NULL, NULL, &node));
> +		cache = ((zone_info_t *)(node->data))->cache;
> +		CHECK(flush_ldap_cache(cache));
> +		result = dns_rbtnodechain_next(&chain, NULL, NULL);
> +	}
> +
> +cleanup:
> +	RWUNLOCK(&zr->rwlock, isc_rwlocktype_write);
> +	if (result == ISC_R_NOMORE || result == ISC_R_NOTFOUND)
> +		result = ISC_R_SUCCESS;
> +
> +	return result;
> +}
> +
> +isc_result_t
> +zr_get_zone_cache(zone_register_t *zr, dns_name_t *name, ldap_cache_t **cachep) {
> +	isc_result_t result;
> +	void *zinfo = NULL;
> +
> +	REQUIRE(zr != NULL);
> +	REQUIRE(name != NULL);
> +	REQUIRE(cachep != NULL && *cachep == NULL);
> +
> +	if (!dns_name_isabsolute(name)) {
> +		log_bug("trying to find zone with a relative name");
> +		return ISC_R_FAILURE;
> +	}
> +
> +	RWLOCK(&zr->rwlock, isc_rwlocktype_read);
> +
> +	result = dns_rbt_findname(zr->rbt, name, 0, NULL, &zinfo);
> +	if (result == DNS_R_PARTIALMATCH)
> +		result = ISC_R_SUCCESS;
> +	if (result == ISC_R_SUCCESS)
> +		*cachep = ((zone_info_t *)zinfo)->cache;
> +
> +	RWUNLOCK(&zr->rwlock, isc_rwlocktype_read);
> +
> +	return result;
> +}
> +
>  /*
>   * Find the closest match to zone with origin 'name' in the zone register 'zr'.
>   * The 'matched_name' will be set to the name that was matched while finding
> diff --git a/src/zone_register.h b/src/zone_register.h
> index dea2c9dce054daf1764ba31154627419acada27d..cec7400ff893842d499d15f6897d448710ac5407 100644
> --- a/src/zone_register.h
> +++ b/src/zone_register.h
> @@ -21,21 +21,30 @@
>  #ifndef _LD_ZONE_REGISTER_H_
>  #define _LD_ZONE_REGISTER_H_
>  
> +#include "cache.h"
> +
>  typedef struct zone_register zone_register_t;
>  
>  isc_result_t
>  zr_create(isc_mem_t *mctx, zone_register_t **zrp);
>  
>  void
>  zr_destroy(zone_register_t **zrp);
>  
>  isc_result_t
> -zr_add_zone(zone_register_t *zr, dns_zone_t *zone, const char *dn);
> +zr_add_zone(zone_register_t *zr, dns_zone_t *zone, const char *dn,
> +	    const isc_interval_t *cache_ttl, const isc_boolean_t *psearch);
>  
>  isc_result_t
>  zr_del_zone(zone_register_t *zr, dns_name_t *origin);
>  
>  isc_result_t
> +zr_flush_all_caches(zone_register_t *zr);
> +
> +isc_result_t
> +zr_get_zone_cache(zone_register_t *zr, dns_name_t *name, ldap_cache_t **cachep);
> +
> +isc_result_t
>  zr_get_zone_dn(zone_register_t *zr, dns_name_t *name, const char **dn,
>  	       dns_name_t *matched_name);
>  
> -- 
> 1.7.11.7
> 


-- 
Adam Tkac, Red Hat, Inc.




More information about the Freeipa-devel mailing list