diff --git a/lib/dns/cache.c b/lib/dns/cache.c index f69b2f912b..b5d2b0995f 100644 --- a/lib/dns/cache.c +++ b/lib/dns/cache.c @@ -131,6 +131,7 @@ struct dns_cache { isc_mutex_t filelock; isc_mem_t *mctx; /* Main cache memory */ isc_mem_t *hmctx; /* Heap memory */ + isc_taskmgr_t *taskmgr; char *name; isc_refcount_t references; isc_refcount_t live_tasks; @@ -172,12 +173,46 @@ overmem_cleaning_action(isc_task_t *task, isc_event_t *event); static isc_result_t cache_create_db(dns_cache_t *cache, dns_db_t **db) { isc_result_t result; + isc_task_t *dbtask = NULL; + isc_task_t *prunetask = NULL; + result = dns_db_create(cache->mctx, cache->db_type, dns_rootname, dns_dbtype_cache, cache->rdclass, cache->db_argc, cache->db_argv, db); - if (result == ISC_R_SUCCESS) { - dns_db_setservestalettl(*db, cache->serve_stale_ttl); + if (result != ISC_R_SUCCESS) { + return (result); } + + dns_db_setservestalettl(*db, cache->serve_stale_ttl); + + if (cache->taskmgr == NULL) { + return (ISC_R_SUCCESS); + } + + result = isc_task_create(cache->taskmgr, 1, &dbtask); + if (result != ISC_R_SUCCESS) { + goto cleanup_db; + } + isc_task_setname(dbtask, "cache_dbtask", NULL); + + result = isc_task_create(cache->taskmgr, UINT_MAX, &prunetask); + if (result != ISC_R_SUCCESS) { + goto cleanup_dbtask; + } + isc_task_setname(prunetask, "cache_prunetask", NULL); + + dns_db_settask(*db, dbtask, prunetask); + + isc_task_detach(&prunetask); + isc_task_detach(&dbtask); + + return (ISC_R_SUCCESS); + +cleanup_dbtask: + isc_task_detach(&dbtask); +cleanup_db: + dns_db_detach(db); + return (result); } @@ -194,6 +229,7 @@ dns_cache_create(isc_mem_t *cmctx, isc_mem_t *hmctx, isc_taskmgr_t *taskmgr, REQUIRE(*cachep == NULL); REQUIRE(cmctx != NULL); REQUIRE(hmctx != NULL); + REQUIRE(taskmgr != NULL || strcmp(db_type, "rbt") != 0); REQUIRE(cachename != NULL); cache = isc_mem_get(cmctx, sizeof(*cache)); @@ -202,6 +238,11 @@ dns_cache_create(isc_mem_t *cmctx, isc_mem_t *hmctx, isc_taskmgr_t *taskmgr, isc_mem_attach(cmctx, &cache->mctx); isc_mem_attach(hmctx, &cache->hmctx); + cache->taskmgr = NULL; + if (taskmgr != NULL) { + isc_taskmgr_attach(taskmgr, &cache->taskmgr); + } + cache->name = NULL; if (cachename != NULL) { cache->name = isc_mem_strdup(cmctx, cachename); @@ -259,27 +300,6 @@ dns_cache_create(isc_mem_t *cmctx, isc_mem_t *hmctx, isc_taskmgr_t *taskmgr, if (result != ISC_R_SUCCESS) { goto cleanup_dbargv; } - if (taskmgr != NULL) { - isc_task_t *dbtask = NULL; - isc_task_t *prunetask = NULL; - - result = isc_task_create(taskmgr, 1, &dbtask); - if (result != ISC_R_SUCCESS) { - goto cleanup_db; - } - isc_task_setname(dbtask, "cache_dbtask", NULL); - - result = isc_task_create(taskmgr, UINT_MAX, &prunetask); - if (result != ISC_R_SUCCESS) { - isc_task_detach(&dbtask); - goto cleanup_db; - } - isc_task_setname(prunetask, "cache_prunetask", NULL); - - dns_db_settask(cache->db, dbtask, prunetask); - isc_task_detach(&dbtask); - isc_task_detach(&prunetask); - } cache->filename = NULL; @@ -327,6 +347,9 @@ cleanup_filelock: if (cache->name != NULL) { isc_mem_free(cmctx, cache->name); } + if (cache->taskmgr != NULL) { + isc_taskmgr_detach(&cache->taskmgr); + } isc_mem_detach(&cache->hmctx); isc_mem_putanddetach(&cache->mctx, cache, sizeof(*cache)); return (result); @@ -398,6 +421,10 @@ cache_free(dns_cache_t *cache) { isc_stats_detach(&cache->stats); } + if (cache->taskmgr != NULL) { + isc_taskmgr_detach(&cache->taskmgr); + } + isc_mutex_destroy(&cache->lock); isc_mutex_destroy(&cache->filelock); diff --git a/lib/dns/include/dns/cache.h b/lib/dns/include/dns/cache.h index b840a543ac..02dd1ac4d0 100644 --- a/lib/dns/include/dns/cache.h +++ b/lib/dns/include/dns/cache.h @@ -62,25 +62,20 @@ dns_cache_create(isc_mem_t *cmctx, isc_mem_t *hmctx, isc_taskmgr_t *taskmgr, const char *cachename, const char *db_type, unsigned int db_argc, char **db_argv, dns_cache_t **cachep); /*%< - * Create a new DNS cache. - * - * dns_cache_create2() will create a named cache. - * - * dns_cache_create3() will create a named cache using two separate memory - * contexts, one for cache data which can be cleaned and a separate one for - * memory allocated for the heap (which can grow without an upper limit and - * has no mechanism for shrinking). - * - * dns_cache_create() is a backward compatible version that internally - * specifies an empty cache name and a single memory context. + * Create a new named DNS cache using two separate memory contexts, one for + * cache data which can be cleaned and a separate one for memory allocated for + * the heap (which can grow without an upper limit and has no mechanism for + * shrinking). * * Requires: * - *\li 'cmctx' (and 'hmctx' if applicable) is a valid memory context. + *\li 'cmctx' and 'hmctx' are valid memory contexts. + * + *\li 'taskmgr' is a valid task manager (if 'db_type' is "rbt"). * *\li 'taskmgr' is a valid task manager and 'timermgr' is a valid timer - * manager, or both are NULL. If NULL, no periodic cleaning of the - * cache will take place. + * manager, or both are NULL (if 'db_type' is not "rbt"). If NULL, no + * periodic cleaning of the cache will take place. * *\li 'cachename' is a valid string. This must not be NULL. *