cache.c revision 6098d364b690cb9dabf96e9664c4689c8559bd2e
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
5347c0fcb04eaea19d9f39795646239f487c6207Tinderbox User * Copyright (C) 1999-2003 Internet Software Consortium.
5347c0fcb04eaea19d9f39795646239f487c6207Tinderbox User * Permission to use, copy, modify, and/or distribute this software for any
83217b5fdc70ea66fedf2ab3e9b9169c2b8a200aRob Austein * purpose with or without fee is hereby granted, provided that the above
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * copyright notice and this permission notice appear in all copies.
2eeb74d1cf5355dd98f6d507a10086e16bb08c4bTinderbox User * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
71c66a876ecca77923638d3f94cc0783152b2f03Mark Andrews * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
71c66a876ecca77923638d3f94cc0783152b2f03Mark Andrews * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
2eeb74d1cf5355dd98f6d507a10086e16bb08c4bTinderbox User * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
71c66a876ecca77923638d3f94cc0783152b2f03Mark Andrews * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
2eeb74d1cf5355dd98f6d507a10086e16bb08c4bTinderbox User * PERFORMANCE OF THIS SOFTWARE.
2eeb74d1cf5355dd98f6d507a10086e16bb08c4bTinderbox User/* $Id: cache.c,v 1.80 2008/09/24 02:46:22 marka Exp $ */
3eb9ec750c9088869170dda63e8899b2ba462823Mark Andrews#define CACHE_MAGIC ISC_MAGIC('$', '$', '$', '$')
3eb9ec750c9088869170dda63e8899b2ba462823Mark Andrews#define VALID_CACHE(cache) ISC_MAGIC_VALID(cache, CACHE_MAGIC)
cedb0bd0c1e3c461b7e479a16d3adfd5b150f1f4Mark Andrews * Control incremental cleaning.
2eeb74d1cf5355dd98f6d507a10086e16bb08c4bTinderbox User * DNS_CACHE_MINSIZE is how many bytes is the floor for dns_cache_setcachesize().
3eb9ec750c9088869170dda63e8899b2ba462823Mark Andrews * See also DNS_CACHE_CLEANERINCREMENT
cedb0bd0c1e3c461b7e479a16d3adfd5b150f1f4Mark Andrews#define DNS_CACHE_MINSIZE 2097152 /*%< Bytes. 2097152 = 2 MB */
2eeb74d1cf5355dd98f6d507a10086e16bb08c4bTinderbox User * Control incremental cleaning.
2eeb74d1cf5355dd98f6d507a10086e16bb08c4bTinderbox User * CLEANERINCREMENT is how many nodes are examined in one pass.
2eeb74d1cf5355dd98f6d507a10086e16bb08c4bTinderbox User * See also DNS_CACHE_MINSIZE
2eeb74d1cf5355dd98f6d507a10086e16bb08c4bTinderbox User#define DNS_CACHE_CLEANERINCREMENT 1000U /*%< Number of nodes. */
2eeb74d1cf5355dd98f6d507a10086e16bb08c4bTinderbox User * A cache_cleaner_t encapsulsates the state of the periodic
2eeb74d1cf5355dd98f6d507a10086e16bb08c4bTinderbox User * cache cleaning.
2eeb74d1cf5355dd98f6d507a10086e16bb08c4bTinderbox Usertypedef enum {
2eeb74d1cf5355dd98f6d507a10086e16bb08c4bTinderbox User cleaner_s_idle, /*%< Waiting for cleaning-interval to expire. */
71c66a876ecca77923638d3f94cc0783152b2f03Mark Andrews cleaner_s_done /*%< Freed enough memory after being overmem. */
2eeb74d1cf5355dd98f6d507a10086e16bb08c4bTinderbox User * Convenience macros for comprehensive assertion checking.
2eeb74d1cf5355dd98f6d507a10086e16bb08c4bTinderbox User#define CLEANER_IDLE(c) ((c)->state == cleaner_s_idle && \
2eeb74d1cf5355dd98f6d507a10086e16bb08c4bTinderbox User#define CLEANER_BUSY(c) ((c)->state == cleaner_s_busy && \
680033ce4d5858bb9016cfa50944eea4ff0111e3Automatic Updater * Accesses to a cache cleaner object are synchronized through
2eeb74d1cf5355dd98f6d507a10086e16bb08c4bTinderbox User * task/event serialization, or locked from the cache object.
b46346eb3026ba4bebc093bc93cfe159131e541eTinderbox User * Locks overmem_event, overmem. Note: never allocate memory
2eeb74d1cf5355dd98f6d507a10086e16bb08c4bTinderbox User * while holding this lock - that could lead to deadlock since
3eb9ec750c9088869170dda63e8899b2ba462823Mark Andrews * the lock is take by water() which is called from the memory
e21a2904f02a03fa06b6db04d348f65fe9c67b2bMark Andrews * allocator.
2eeb74d1cf5355dd98f6d507a10086e16bb08c4bTinderbox User unsigned int cleaning_interval; /*% The cleaning-interval from
e21a2904f02a03fa06b6db04d348f65fe9c67b2bMark Andrews named.conf, in seconds. */
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein isc_event_t *resched_event; /*% Sent by cleaner task to
e21a2904f02a03fa06b6db04d348f65fe9c67b2bMark Andrews itself to reschedule */
cedb0bd0c1e3c461b7e479a16d3adfd5b150f1f4Mark Andrews clean in one increment */
cedb0bd0c1e3c461b7e479a16d3adfd5b150f1f4Mark Andrews isc_boolean_t overmem; /*% The cache is in an overmem state. */
e21a2904f02a03fa06b6db04d348f65fe9c67b2bMark Andrews * The actual cache object.
3eb9ec750c9088869170dda63e8899b2ba462823Mark Andrews /* Unlocked. */
e21a2904f02a03fa06b6db04d348f65fe9c67b2bMark Andrews unsigned int magic;
e21a2904f02a03fa06b6db04d348f65fe9c67b2bMark Andrews /* Locked by 'lock'. */
e21a2904f02a03fa06b6db04d348f65fe9c67b2bMark Andrews /* Locked by 'filelock'. */
3eb9ec750c9088869170dda63e8899b2ba462823Mark Andrews /* Access to the on-disk cache file is also locked by 'filelock'. */
e21a2904f02a03fa06b6db04d348f65fe9c67b2bMark Andrews *** Functions
e21a2904f02a03fa06b6db04d348f65fe9c67b2bMark Andrewscache_cleaner_init(dns_cache_t *cache, isc_taskmgr_t *taskmgr,
e21a2904f02a03fa06b6db04d348f65fe9c67b2bMark Andrews isc_timermgr_t *timermgr, cache_cleaner_t *cleaner);
2eeb74d1cf5355dd98f6d507a10086e16bb08c4bTinderbox Usercleaning_timer_action(isc_task_t *task, isc_event_t *event);
cedb0bd0c1e3c461b7e479a16d3adfd5b150f1f4Mark Andrewsincremental_cleaning_action(isc_task_t *task, isc_event_t *event);
e21a2904f02a03fa06b6db04d348f65fe9c67b2bMark Andrewscleaner_shutdown_action(isc_task_t *task, isc_event_t *event);
cedb0bd0c1e3c461b7e479a16d3adfd5b150f1f4Mark Andrewsovermem_cleaning_action(isc_task_t *task, isc_event_t *event);
e21a2904f02a03fa06b6db04d348f65fe9c67b2bMark Andrewscache_create_db(dns_cache_t *cache, dns_db_t **db) {
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein return (dns_db_create(cache->mctx, cache->db_type, dns_rootname,
3eb9ec750c9088869170dda63e8899b2ba462823Mark Andrewsdns_cache_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
e21a2904f02a03fa06b6db04d348f65fe9c67b2bMark Andrews isc_timermgr_t *timermgr, dns_rdataclass_t rdclass,
e21a2904f02a03fa06b6db04d348f65fe9c67b2bMark Andrews const char *db_type, unsigned int db_argc, char **db_argv,
e21a2904f02a03fa06b6db04d348f65fe9c67b2bMark Andrews cache->db_type = isc_mem_strdup(mctx, db_type);
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein cache->db_argv[i] = isc_mem_strdup(mctx, db_argv[i]);
e21a2904f02a03fa06b6db04d348f65fe9c67b2bMark Andrews * RBT-type cache DB has its own mechanism of cache cleaning and doesn't
c32570b3191fdfb38a65567b8bb729fdb42ff847Tinderbox User * need the control of the generic cleaner.
cedb0bd0c1e3c461b7e479a16d3adfd5b150f1f4Mark Andrews result = cache_cleaner_init(cache, NULL, NULL, &cache->cleaner);
e21a2904f02a03fa06b6db04d348f65fe9c67b2bMark Andrews result = cache_cleaner_init(cache, taskmgr, timermgr,
2eeb74d1cf5355dd98f6d507a10086e16bb08c4bTinderbox User isc_mem_setwater(cache->mctx, NULL, NULL, 0, 0);
e21a2904f02a03fa06b6db04d348f65fe9c67b2bMark Andrews dns_dbiterator_destroy(&cache->cleaner.iterator);
if (free_cache) {
if (free_cache)
char *newname;
return (ISC_R_NOMEMORY);
return (ISC_R_SUCCESS);
return (ISC_R_SUCCESS);
return (result);
return (ISC_R_SUCCESS);
return (result);
goto unlock;
static isc_result_t
goto fail;
goto cleanup;
goto cleanup;
goto cleanup;
goto cleanup;
goto cleanup;
goto cleanup;
return (ISC_R_SUCCESS);
fail:
return (result);
* This is run once for every cache-cleaning-interval as defined in named.conf.
if (want_cleaning)
unsigned int n_names;
while (n_names-- > 0) {
NULL);
iterator);
return result;
return (result);
if (should_free)
return (result);
return (ISC_R_SUCCESS);
return (ISC_R_SUCCESS);
goto cleanup_db;
goto cleanup_db;
goto cleanup_node;
return (result);