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

📄 journal.c

📁 bind 9.3结合mysql数据库
💻 C
📖 第 1 页 / 共 4 页
字号:
				&j->it.dctx, 0, &j->it.target));	/*	 * Check that the RR header is there, and parse it.	 */	if (isc_buffer_remaininglength(&j->it.source) < 10)		FAIL(DNS_R_FORMERR);	rdtype = isc_buffer_getuint16(&j->it.source);	rdclass = isc_buffer_getuint16(&j->it.source);	ttl = isc_buffer_getuint32(&j->it.source);	rdlen = isc_buffer_getuint16(&j->it.source);	/*	 * Parse the rdata.	 */	isc_buffer_setactive(&j->it.source, rdlen);	dns_rdata_reset(&j->it.rdata);	CHECK(dns_rdata_fromwire(&j->it.rdata, rdclass,				 rdtype, &j->it.source, &j->it.dctx,				 0, &j->it.target));	j->it.ttl = ttl;	j->it.xpos += sizeof(journal_rawrrhdr_t) + rrhdr.size;	if (rdtype == dns_rdatatype_soa) {		/* XXX could do additional consistency checks here */		j->it.current_serial = dns_soa_getserial(&j->it.rdata);	}	result = ISC_R_SUCCESS; failure:	j->it.result = result;	return (result);}isc_result_tdns_journal_next_rr(dns_journal_t *j) {	j->it.result = read_one_rr(j);	return (j->it.result);}voiddns_journal_current_rr(dns_journal_t *j, dns_name_t **name, isc_uint32_t *ttl,		   dns_rdata_t **rdata){	REQUIRE(j->it.result == ISC_R_SUCCESS);	*name = &j->it.name;	*ttl = j->it.ttl;	*rdata = &j->it.rdata;}/**************************************************************************//* * Generating diffs from databases *//* * Construct a diff containing all the RRs at the current name of the * database iterator 'dbit' in database 'db', version 'ver'. * Set '*name' to the current name, and append the diff to 'diff'. * All new tuples will have the operation 'op'. * * Requires: 'name' must have buffer large enough to hold the name. * Typically, a dns_fixedname_t would be used. */static isc_result_tget_name_diff(dns_db_t *db, dns_dbversion_t *ver, isc_stdtime_t now,	      dns_dbiterator_t *dbit, dns_name_t *name, dns_diffop_t op,	      dns_diff_t *diff){	isc_result_t result;	dns_dbnode_t *node = NULL;	dns_rdatasetiter_t *rdsiter = NULL;	dns_difftuple_t *tuple = NULL;	result = dns_dbiterator_current(dbit, &node, name);	if (result != ISC_R_SUCCESS)		return (result);	result = dns_db_allrdatasets(db, node, ver, now, &rdsiter);	if (result != ISC_R_SUCCESS)		goto cleanup_node;	for (result = dns_rdatasetiter_first(rdsiter);	     result == ISC_R_SUCCESS;	     result = dns_rdatasetiter_next(rdsiter))	{		dns_rdataset_t rdataset;		dns_rdataset_init(&rdataset);		dns_rdatasetiter_current(rdsiter, &rdataset);		for (result = dns_rdataset_first(&rdataset);		     result == ISC_R_SUCCESS;		     result = dns_rdataset_next(&rdataset))		{			dns_rdata_t rdata = DNS_RDATA_INIT;			dns_rdataset_current(&rdataset, &rdata);			result = dns_difftuple_create(diff->mctx, op, name,						      rdataset.ttl, &rdata,						      &tuple);			if (result != ISC_R_SUCCESS) {				dns_rdataset_disassociate(&rdataset);				goto cleanup_iterator;			}			dns_diff_append(diff, &tuple);		}		dns_rdataset_disassociate(&rdataset);		if (result != ISC_R_NOMORE)			goto cleanup_iterator;	}	if (result != ISC_R_NOMORE)		goto cleanup_iterator;	result = ISC_R_SUCCESS; cleanup_iterator:	dns_rdatasetiter_destroy(&rdsiter); cleanup_node:	dns_db_detachnode(db, &node);	return (result);}/* * Comparison function for use by dns_diff_subtract when sorting * the diffs to be subtracted.  The sort keys are the rdata type * and the rdata itself.  The owner name is ignored, because * it is known to be the same for all tuples. */static intrdata_order(const void *av, const void *bv) {	dns_difftuple_t const * const *ap = av;	dns_difftuple_t const * const *bp = bv;	dns_difftuple_t const *a = *ap;	dns_difftuple_t const *b = *bp;	int r;	r = (b->rdata.type - a->rdata.type);	if (r != 0)		return (r);	r = dns_rdata_compare(&a->rdata, &b->rdata);	return (r);}static isc_result_tdns_diff_subtract(dns_diff_t diff[2], dns_diff_t *r) {	isc_result_t result;	dns_difftuple_t *p[2];	int i, t;	CHECK(dns_diff_sort(&diff[0], rdata_order));	CHECK(dns_diff_sort(&diff[1], rdata_order));	for (;;) {		p[0] = ISC_LIST_HEAD(diff[0].tuples);		p[1] = ISC_LIST_HEAD(diff[1].tuples);		if (p[0] == NULL && p[1] == NULL)			break;		for (i = 0; i < 2; i++)			if (p[!i] == NULL) {				ISC_LIST_UNLINK(diff[i].tuples, p[i], link);				ISC_LIST_APPEND(r->tuples, p[i], link);				goto next;			}		t = rdata_order(&p[0], &p[1]);		if (t < 0) {			ISC_LIST_UNLINK(diff[0].tuples, p[0], link);			ISC_LIST_APPEND(r->tuples, p[0], link);			goto next;		}		if (t > 0) {			ISC_LIST_UNLINK(diff[1].tuples, p[1], link);			ISC_LIST_APPEND(r->tuples, p[1], link);			goto next;		}		INSIST(t == 0);		/*		 * Identical RRs in both databases; skip them both.		 */		for (i = 0; i < 2; i++) {			ISC_LIST_UNLINK(diff[i].tuples, p[i], link);			dns_difftuple_free(&p[i]);		}	next: ;	}	result = ISC_R_SUCCESS; failure:	return (result);}/* * Compare the databases 'dba' and 'dbb' and generate a journal * entry containing the changes to make 'dba' from 'dbb' (note * the order).  This journal entry will consist of a single, * possibly very large transaction. */isc_result_tdns_db_diff(isc_mem_t *mctx,	    dns_db_t *dba, dns_dbversion_t *dbvera,	    dns_db_t *dbb, dns_dbversion_t *dbverb,	    const char *journal_filename){	dns_db_t *db[2];	dns_dbversion_t *ver[2];	dns_dbiterator_t *dbit[2] = { NULL, NULL };	isc_boolean_t have[2] = { ISC_FALSE, ISC_FALSE };	dns_fixedname_t fixname[2];	isc_result_t result, itresult[2];	dns_diff_t diff[2], resultdiff;	int i, t;	dns_journal_t *journal = NULL;	db[0] = dba, db[1] = dbb;	ver[0] = dbvera, ver[1] = dbverb;	dns_diff_init(mctx, &diff[0]);	dns_diff_init(mctx, &diff[1]);	dns_diff_init(mctx, &resultdiff);	dns_fixedname_init(&fixname[0]);	dns_fixedname_init(&fixname[1]);	result = dns_journal_open(mctx, journal_filename, ISC_TRUE, &journal);	if (result != ISC_R_SUCCESS)		return (result);	result = dns_db_createiterator(db[0], ISC_FALSE, &dbit[0]);	if (result != ISC_R_SUCCESS)		goto cleanup_journal;	result = dns_db_createiterator(db[1], ISC_FALSE, &dbit[1]);	if (result != ISC_R_SUCCESS)		goto cleanup_interator0;	itresult[0] = dns_dbiterator_first(dbit[0]);	itresult[1] = dns_dbiterator_first(dbit[1]);	for (;;) {		for (i = 0; i < 2; i++) {			if (! have[i] && itresult[i] == ISC_R_SUCCESS) {				CHECK(get_name_diff(db[i], ver[i], 0, dbit[i],					    dns_fixedname_name(&fixname[i]),					    i == 0 ?					    DNS_DIFFOP_ADD :					    DNS_DIFFOP_DEL,					    &diff[i]));				itresult[i] = dns_dbiterator_next(dbit[i]);				have[i] = ISC_TRUE;			}		}		if (! have[0] && ! have[1]) {			INSIST(ISC_LIST_EMPTY(diff[0].tuples));			INSIST(ISC_LIST_EMPTY(diff[1].tuples));			break;		}		for (i = 0; i < 2; i++) {			if (! have[!i]) {				ISC_LIST_APPENDLIST(resultdiff.tuples,						    diff[i].tuples, link);				INSIST(ISC_LIST_EMPTY(diff[i].tuples));				have[i] = ISC_FALSE;				goto next;			}		}		t = dns_name_compare(dns_fixedname_name(&fixname[0]),				     dns_fixedname_name(&fixname[1]));		if (t < 0) {			ISC_LIST_APPENDLIST(resultdiff.tuples,					    diff[0].tuples, link);			INSIST(ISC_LIST_EMPTY(diff[0].tuples));			have[0] = ISC_FALSE;			continue;		}		if (t > 0) {			ISC_LIST_APPENDLIST(resultdiff.tuples,					    diff[1].tuples, link);			INSIST(ISC_LIST_EMPTY(diff[1].tuples));			have[1] = ISC_FALSE;			continue;		}		INSIST(t == 0);		CHECK(dns_diff_subtract(diff, &resultdiff));		INSIST(ISC_LIST_EMPTY(diff[0].tuples));		INSIST(ISC_LIST_EMPTY(diff[1].tuples));		have[0] = have[1] = ISC_FALSE;	next: ;	}	if (itresult[0] != ISC_R_NOMORE)		FAIL(itresult[0]);	if (itresult[1] != ISC_R_NOMORE)		FAIL(itresult[1]);	if (ISC_LIST_EMPTY(resultdiff.tuples)) {		isc_log_write(JOURNAL_DEBUG_LOGARGS(3), "no changes");	} else {		CHECK(dns_journal_write_transaction(journal, &resultdiff));	}	INSIST(ISC_LIST_EMPTY(diff[0].tuples));	INSIST(ISC_LIST_EMPTY(diff[1].tuples)); failure:	dns_diff_clear(&resultdiff);	dns_dbiterator_destroy(&dbit[1]); cleanup_interator0:	dns_dbiterator_destroy(&dbit[0]); cleanup_journal:	dns_journal_destroy(&journal);	return (result);}isc_result_tdns_journal_compact(isc_mem_t *mctx, char *filename, isc_uint32_t serial,		    isc_uint32_t target_size){	unsigned int i;	journal_pos_t best_guess;	journal_pos_t current_pos;	dns_journal_t *j = NULL;	journal_rawheader_t rawheader;	unsigned int copy_length;	unsigned int len;	char *buf = NULL;	unsigned int size = 0;	isc_result_t result;	unsigned int indexend;	CHECK(journal_open(mctx, filename, ISC_TRUE, ISC_FALSE, &j));	if (JOURNAL_EMPTY(&j->header)) {		dns_journal_destroy(&j);		return (ISC_R_SUCCESS);	}			if (DNS_SERIAL_GT(j->header.begin.serial, serial) ||	    DNS_SERIAL_GT(serial, j->header.end.serial)) {		dns_journal_destroy(&j);		return (ISC_R_RANGE);	}	/*	 * Cope with very small target sizes.	 */	indexend = sizeof(journal_rawheader_t) +		   j->header.index_size * sizeof(journal_rawpos_t);	if (target_size < indexend * 2)		target_size = target_size/2 + indexend;	/*	 * See if there is any work to do.	 */	if ((isc_uint32_t) j->header.end.offset < target_size) {		dns_journal_destroy(&j);		return (ISC_R_SUCCESS);	}		/*	 * Remove overhead so space test below can succeed.	 */	if (target_size >= indexend)		target_size -= indexend;	/*	 * Find if we can create enough free space.	 */	best_guess = j->header.begin;	for (i = 0; i < j->header.index_size; i++) {		if (POS_VALID(j->index[i]) &&		    DNS_SERIAL_GE(serial, j->index[i].serial) &&		    ((isc_uint32_t)(j->header.end.offset - j->index[i].offset)		     >= target_size / 2) &&		    j->index[i].offset > best_guess.offset)			best_guess = j->index[i];	}	current_pos = best_guess;	while (current_pos.serial != serial) {		CHECK(journal_next(j, &current_pos));		if (current_pos.serial == j->header.end.serial)			break;		if (DNS_SERIAL_GE(serial, current_pos.serial) &&		   ((isc_uint32_t)(j->header.end.offset - current_pos.offset)		     >= (target_size / 2)) &&		    current_pos.offset > best_guess.offset)			best_guess = current_pos;		else			break;	}	INSIST(best_guess.serial != j->header.end.serial);	if (best_guess.serial != serial)		CHECK(journal_next(j, &best_guess));	/*	 * Enough space to proceed?	 */	if ((isc_uint32_t) (j->header.end.offset - best_guess.offset) >	     (isc_uint32_t) (best_guess.offset - indexend)) {		dns_journal_destroy(&j);		return (ISC_R_NOSPACE);	}	copy_length = j->header.end.offset - best_guess.offset;	/*	 * Invalidate entire index, will be rebuilt at end.	 */	for (i = 0; i < j->header.index_size; i++) {		if (POS_VALID(j->index[i]))			POS_INVALIDATE(j->index[i]);	}	/*	 * Convert the index into on-disk format and write	 * it to disk.	 */	CHECK(index_to_disk(j));	CHECK(journal_fsync(j));	/*	 * Update the journal header.	 */	if (copy_length == 0) {		j->header.begin.serial = 0;		j->header.end.serial = 0;		j->header.begin.offset = 0;		j->header.end.offset = 0;	} else {		j->header.begin = best_guess;	}	journal_header_encode(&j->header, &rawheader);	CHECK(journal_seek(j, 0));	CHECK(journal_write(j, &rawheader, sizeof(rawheader)));	CHECK(journal_fsync(j));	if (copy_length != 0) {		/*		 * Copy best_guess to end into space just freed.		 */		size = 64*1024;		if (copy_length < size)			size = copy_length;		buf = isc_mem_get(mctx, size);		if (buf == NULL) {			result = ISC_R_NOMEMORY;			goto failure;		}			for (i = 0; i < copy_length; i += size) {			len = (copy_length - i) > size ? size :							 (copy_length - i);			CHECK(journal_seek(j, best_guess.offset + i));			CHECK(journal_read(j, buf, len));			CHECK(journal_seek(j, indexend + i));			CHECK(journal_write(j, buf, len));		}		CHECK(journal_fsync(j));		/*		 * Compute new header.		 */		j->header.begin.offset = indexend;		j->header.end.offset = indexend + copy_length;		/*		 * Update the journal header.		 */		journal_header_encode(&j->header, &rawheader);		CHECK(journal_seek(j, 0));		CHECK(journal_write(j, &rawheader, sizeof(rawheader)));		CHECK(journal_fsync(j));		/*		 * Build new index.		 */		current_pos = j->header.begin;		while (current_pos.serial != j->header.end.serial) {			index_add(j, &current_pos);			CHECK(journal_next(j, &current_pos));		}		/*		 * Write index.		 */		CHECK(index_to_disk(j));		CHECK(journal_fsync(j));		indexend = j->header.end.offset;	}	dns_journal_destroy(&j);	(void)isc_file_truncate(filename, (isc_offset_t)indexend);	result = ISC_R_SUCCESS; failure:	if (buf != NULL)		isc_mem_put(mctx, buf, size);	if (j != NULL)		dns_journal_destroy(&j);	return (result);}static isc_result_tindex_to_disk(dns_journal_t *j) {	isc_result_t result = ISC_R_SUCCESS;	if (j->header.index_size != 0) {		unsigned int i;		unsigned char *p;		unsigned int rawbytes;		rawbytes = j->header.index_size * sizeof(journal_rawpos_t);		p = j->rawindex;		for (i = 0; i < j->header.index_size; i++) {			encode_uint32(j->index[i].serial, p);			p += 4;			encode_uint32(j->index[i].offset, p);			p += 4;		}		INSIST(p == j->rawindex + rawbytes);		CHECK(journal_seek(j, sizeof(journal_rawheader_t)));		CHECK(journal_write(j, j->rawindex, rawbytes));	}failure:	return (result);}

⌨️ 快捷键说明

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