⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cache.c

📁 bind 9.3结合mysql数据库
💻 C
📖 第 1 页 / 共 2 页
字号:
		cleaner->cleaning_interval = 0; /* Initially turned off. */		result = isc_timer_create(timermgr, isc_timertype_inactive,					   NULL, NULL,					   cleaner->task,					   cleaning_timer_action, cleaner,					   &cleaner->cleaning_timer);		if (result != ISC_R_SUCCESS) {			UNEXPECTED_ERROR(__FILE__, __LINE__,					 "isc_timer_create() failed: %s",					 dns_result_totext(result));			result = ISC_R_UNEXPECTED;			goto cleanup;		}		cleaner->resched_event =			isc_event_allocate(cache->mctx, cleaner,					   DNS_EVENT_CACHECLEAN,					   incremental_cleaning_action,					   cleaner, sizeof(isc_event_t));		if (cleaner->resched_event == NULL) {			result = ISC_R_NOMEMORY;			goto cleanup;		}				cleaner->overmem_event =			isc_event_allocate(cache->mctx, cleaner,					   DNS_EVENT_CACHEOVERMEM,					   overmem_cleaning_action,					   cleaner, sizeof(isc_event_t));		if (cleaner->overmem_event == NULL) {			result = ISC_R_NOMEMORY;			goto cleanup;		}	}	return (ISC_R_SUCCESS); cleanup:	if (cleaner->overmem_event != NULL)		isc_event_free(&cleaner->overmem_event);	if (cleaner->resched_event != NULL)		isc_event_free(&cleaner->resched_event);	if (cleaner->cleaning_timer != NULL)		isc_timer_detach(&cleaner->cleaning_timer);	if (cleaner->task != NULL)		isc_task_detach(&cleaner->task);	DESTROYLOCK(&cleaner->lock); fail:	return (result);}static voidbegin_cleaning(cache_cleaner_t *cleaner) {	isc_result_t result;	REQUIRE(CLEANER_IDLE(cleaner));	/*	 * Create an iterator and position it at the beginning of the cache.	 */	result = dns_db_createiterator(cleaner->cache->db, ISC_FALSE,				       &cleaner->iterator);	if (result != ISC_R_SUCCESS)		isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,			      DNS_LOGMODULE_CACHE, ISC_LOG_WARNING,			      "cache cleaner could not create "			      "iterator: %s", isc_result_totext(result));	else {		dns_dbiterator_setcleanmode(cleaner->iterator, ISC_TRUE);		result = dns_dbiterator_first(cleaner->iterator);	}	if (result != ISC_R_SUCCESS) {		/*		 * If the result is ISC_R_NOMORE, the database is empty,		 * so there is nothing to be cleaned.		 */		if (result != ISC_R_NOMORE)			UNEXPECTED_ERROR(__FILE__, __LINE__,					 "cache cleaner: "					 "dns_dbiterator_first() failed: %s",					 dns_result_totext(result));		if (cleaner->iterator != NULL)			dns_dbiterator_destroy(&cleaner->iterator);	} else {		/*		 * Pause the iterator to free its lock.		 */		result = dns_dbiterator_pause(cleaner->iterator);		RUNTIME_CHECK(result == ISC_R_SUCCESS);		isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,			      DNS_LOGMODULE_CACHE, ISC_LOG_DEBUG(1),			      "begin cache cleaning, mem inuse %lu",		            (unsigned long)isc_mem_inuse(cleaner->cache->mctx));		cleaner->state = cleaner_s_busy;		isc_task_send(cleaner->task, &cleaner->resched_event);	}	return;}static voidend_cleaning(cache_cleaner_t *cleaner, isc_event_t *event) {	REQUIRE(CLEANER_BUSY(cleaner));	REQUIRE(event != NULL);	dns_dbiterator_destroy(&cleaner->iterator);	dns_cache_setcleaninginterval(cleaner->cache,				      cleaner->cleaning_interval);	isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_CACHE,		      ISC_LOG_DEBUG(1), "end cache cleaning, mem inuse %lu",		      (unsigned long)isc_mem_inuse(cleaner->cache->mctx));	cleaner->state = cleaner_s_idle;	cleaner->resched_event = event;}/* * This is run once for every cache-cleaning-interval as defined in named.conf. */static voidcleaning_timer_action(isc_task_t *task, isc_event_t *event) {	cache_cleaner_t *cleaner = event->ev_arg;	UNUSED(task);	INSIST(task == cleaner->task);	INSIST(event->ev_type == ISC_TIMEREVENT_TICK);	isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_CACHE,		      ISC_LOG_DEBUG(1), "cache cleaning timer fired, "		      "cleaner state = %d", cleaner->state);	if (cleaner->state == cleaner_s_idle)		begin_cleaning(cleaner);	isc_event_free(&event);}/* * This is called when the cache either surpasses its upper limit * or shrinks beyond its lower limit. */static voidovermem_cleaning_action(isc_task_t *task, isc_event_t *event) {	cache_cleaner_t *cleaner = event->ev_arg;	isc_boolean_t want_cleaning = ISC_FALSE;		UNUSED(task);	INSIST(task == cleaner->task);	INSIST(event->ev_type == DNS_EVENT_CACHEOVERMEM);	INSIST(cleaner->overmem_event == NULL);	isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_CACHE,		      ISC_LOG_DEBUG(1), "overmem_cleaning_action called, "		      "overmem = %d, state = %d", cleaner->overmem,		      cleaner->state);	LOCK(&cleaner->lock);	if (cleaner->overmem) {		if (cleaner->state == cleaner_s_idle)			want_cleaning = ISC_TRUE;	} else {		if (cleaner->state == cleaner_s_busy)			/*			 * end_cleaning() can't be called here because			 * then both cleaner->overmem_event and			 * cleaner->resched_event will point to this			 * event.  Set the state to done, and then			 * when the incremental_cleaning_action() event			 * is posted, it will handle the end_cleaning.			 */			cleaner->state = cleaner_s_done;	}	cleaner->overmem_event = event;	UNLOCK(&cleaner->lock);	if (want_cleaning)		begin_cleaning(cleaner);}/* * Do incremental cleaning. */static voidincremental_cleaning_action(isc_task_t *task, isc_event_t *event) {	cache_cleaner_t *cleaner = event->ev_arg;	isc_result_t result;	int n_names;	UNUSED(task);	INSIST(task == cleaner->task);	INSIST(event->ev_type == DNS_EVENT_CACHECLEAN);	if (cleaner->state == cleaner_s_done) {		cleaner->state = cleaner_s_busy;		end_cleaning(cleaner, event);		return;	}	INSIST(CLEANER_BUSY(cleaner));	n_names = cleaner->increment;	REQUIRE(DNS_DBITERATOR_VALID(cleaner->iterator));	while (n_names-- > 0) {		dns_dbnode_t *node = NULL;		result = dns_dbiterator_current(cleaner->iterator, &node,						NULL);		if (result != ISC_R_SUCCESS) {			UNEXPECTED_ERROR(__FILE__, __LINE__,				 "cache cleaner: dns_dbiterator_current() "				 "failed: %s", dns_result_totext(result));			end_cleaning(cleaner, event);			return;		}		/*		 * The node was not needed, but was required by		 * dns_dbiterator_current().  Give up its reference.		 */		dns_db_detachnode(cleaner->cache->db, &node);		/*		 * Step to the next node.		 */		result = dns_dbiterator_next(cleaner->iterator);		if (result != ISC_R_SUCCESS) {			/*			 * Either the end was reached (ISC_R_NOMORE) or			 * some error was signaled.  If the cache is still			 * overmem and no error was encountered,			 * keep trying to clean it, otherwise stop cleanng.			 */			if (result != ISC_R_NOMORE)				UNEXPECTED_ERROR(__FILE__, __LINE__,						 "cache cleaner: "						 "dns_dbiterator_next() "						 "failed: %s",						 dns_result_totext(result));			else if (cleaner->overmem) {				result = dns_dbiterator_first(cleaner->							      iterator);				if (result == ISC_R_SUCCESS) {					isc_log_write(dns_lctx,						      DNS_LOGCATEGORY_DATABASE,						      DNS_LOGMODULE_CACHE,						      ISC_LOG_DEBUG(1),						      "cache cleaner: "						      "still overmem, "						      "reset and try again");					continue;				}			}			end_cleaning(cleaner, event);			return;		}	}	/*	 * We have successfully performed a cleaning increment but have	 * not gone through the entire cache.  Free the iterator locks	 * and reschedule another batch.  If it fails, just try to continue	 * anyway.	 */	result = dns_dbiterator_pause(cleaner->iterator);	RUNTIME_CHECK(result == ISC_R_SUCCESS);	isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_CACHE,		      ISC_LOG_DEBUG(1), "cache cleaner: checked %d nodes, "		      "mem inuse %lu, sleeping", cleaner->increment,		      (unsigned long)isc_mem_inuse(cleaner->cache->mctx));	isc_task_send(task, &event);	INSIST(CLEANER_BUSY(cleaner));	return;}/* * Do immediate cleaning. */isc_result_tdns_cache_clean(dns_cache_t *cache, isc_stdtime_t now) {	isc_result_t result;	dns_dbiterator_t *iterator = NULL;	REQUIRE(VALID_CACHE(cache));	result = dns_db_createiterator(cache->db, ISC_FALSE, &iterator);	if (result != ISC_R_SUCCESS)		return result;	result = dns_dbiterator_first(iterator);	while (result == ISC_R_SUCCESS) {		dns_dbnode_t *node = NULL;		result = dns_dbiterator_current(iterator, &node,						(dns_name_t *)NULL);		if (result != ISC_R_SUCCESS)			break;		/*		 * Check TTLs, mark expired rdatasets stale.		 */		result = dns_db_expirenode(cache->db, node, now);		if (result != ISC_R_SUCCESS) {			UNEXPECTED_ERROR(__FILE__, __LINE__,					 "cache cleaner: dns_db_expirenode() "					 "failed: %s",					 dns_result_totext(result));			/*			 * Continue anyway.			 */		}		/*		 * This is where the actual freeing takes place.		 */		dns_db_detachnode(cache->db, &node);		result = dns_dbiterator_next(iterator);	}	dns_dbiterator_destroy(&iterator);	if (result == ISC_R_NOMORE)		result = ISC_R_SUCCESS;	return (result);}static voidwater(void *arg, int mark) {	dns_cache_t *cache = arg;	isc_boolean_t overmem = ISC_TF(mark == ISC_MEM_HIWATER);	REQUIRE(VALID_CACHE(cache));	LOCK(&cache->cleaner.lock);		dns_db_overmem(cache->db, overmem);	cache->cleaner.overmem = overmem;	if (cache->cleaner.overmem_event != NULL)		isc_task_send(cache->cleaner.task,			      &cache->cleaner.overmem_event);	UNLOCK(&cache->cleaner.lock);}voiddns_cache_setcachesize(dns_cache_t *cache, isc_uint32_t size) {	isc_uint32_t lowater;	isc_uint32_t hiwater;	REQUIRE(VALID_CACHE(cache));	/*	 * Impose a minumum cache size; pathological things happen if there	 * is too little room.	 */	if (size != 0 && size < DNS_CACHE_MINSIZE)		size = DNS_CACHE_MINSIZE;	hiwater = size - (size >> 3);	/* Approximately 7/8ths. */	lowater = size - (size >> 2);	/* Approximately 3/4ths. */	/*	 * If the cache was overmem and cleaning, but now with the new limits	 * it is no longer in an overmem condition, then the next	 * isc_mem_put for cache memory will do the right thing and trigger	 * water().	 */	if (size == 0 || hiwater == 0 || lowater == 0)		/*		 * Disable cache memory limiting.		 */		isc_mem_setwater(cache->mctx, water, cache, 0, 0);	else		/*		 * Establish new cache memory limits (either for the first		 * time, or replacing other limits).		 */		isc_mem_setwater(cache->mctx, water, cache, hiwater, lowater);}/* * The cleaner task is shutting down; do the necessary cleanup. */static voidcleaner_shutdown_action(isc_task_t *task, isc_event_t *event) {	dns_cache_t *cache = event->ev_arg;	isc_boolean_t should_free = ISC_FALSE;	UNUSED(task);	INSIST(task == cache->cleaner.task);	INSIST(event->ev_type == ISC_TASKEVENT_SHUTDOWN);	if (CLEANER_BUSY(&cache->cleaner))		end_cleaning(&cache->cleaner, event);	else		isc_event_free(&event);	LOCK(&cache->lock);	cache->live_tasks--;	INSIST(cache->live_tasks == 0);	if (cache->references == 0)		should_free = ISC_TRUE;	/*	 * By detaching the timer in the context of its task,	 * we are guaranteed that there will be no further timer	 * events.	 */	if (cache->cleaner.cleaning_timer != NULL)		isc_timer_detach(&cache->cleaner.cleaning_timer);	/* Make sure we don't reschedule anymore. */	(void)isc_task_purge(task, NULL, DNS_EVENT_CACHECLEAN, NULL);	UNLOCK(&cache->lock);	if (should_free)		cache_free(cache);}isc_result_tdns_cache_flush(dns_cache_t *cache) {	dns_db_t *db = NULL;	isc_result_t result;	result = cache_create_db(cache, &db);	if (result != ISC_R_SUCCESS)		return (result);	dns_db_detach(&cache->db);	cache->db = db;	return (ISC_R_SUCCESS);}isc_result_tdns_cache_flushname(dns_cache_t *cache, dns_name_t *name) {	isc_result_t result;	dns_rdatasetiter_t *iter = NULL;	dns_dbnode_t *node = NULL;	dns_db_t *db = NULL;		LOCK(&cache->lock);	if (cache->db != NULL)		dns_db_attach(cache->db, &db);	UNLOCK(&cache->lock);	if (db == NULL)		return (ISC_R_SUCCESS);	result = dns_db_findnode(cache->db, name, ISC_FALSE, &node);	if (result == ISC_R_NOTFOUND) {		result = ISC_R_SUCCESS;		goto cleanup_db;	}	if (result != ISC_R_SUCCESS)		goto cleanup_db;	result = dns_db_allrdatasets(cache->db, node, NULL,				     (isc_stdtime_t)0, &iter);	if (result != ISC_R_SUCCESS)		goto cleanup_node;	for (result = dns_rdatasetiter_first(iter);	     result == ISC_R_SUCCESS;	     result = dns_rdatasetiter_next(iter))	{		dns_rdataset_t rdataset;		dns_rdataset_init(&rdataset);		dns_rdatasetiter_current(iter, &rdataset);		for (result = dns_rdataset_first(&rdataset);		     result == ISC_R_SUCCESS;		     result = dns_rdataset_next(&rdataset))		{			dns_rdata_t rdata = DNS_RDATA_INIT;			dns_rdatatype_t covers;			dns_rdataset_current(&rdataset, &rdata);			if (rdata.type == dns_rdatatype_rrsig)				covers = dns_rdata_covers(&rdata);			else				covers = 0;			result = dns_db_deleterdataset(cache->db, node, NULL,						       rdata.type, covers);			if (result != ISC_R_SUCCESS &&			    result != DNS_R_UNCHANGED)				break;		}		dns_rdataset_disassociate(&rdataset);		if (result != ISC_R_NOMORE)			break;	}	if (result == ISC_R_NOMORE)		result = ISC_R_SUCCESS;	dns_rdatasetiter_destroy(&iter); cleanup_node:	dns_db_detachnode(cache->db, &node); cleanup_db:	dns_db_detach(&db);	return (result);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -