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 <pspa...@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 <pspa...@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.

_______________________________________________
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel

Reply via email to