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

📄 journal.c

📁 bind 9.3结合mysql数据库
💻 C
📖 第 1 页 / 共 4 页
字号:
	 * by stepping header.begin forward to the first addressable	 * transaction.  Also purge them from the index.	 */	if (! JOURNAL_EMPTY(&j->header)) {		while (! DNS_SERIAL_GT(j->x.pos[1].serial,				       j->header.begin.serial)) {			CHECK(journal_next(j, &j->header.begin));		}		index_invalidate(j, j->x.pos[1].serial);	}#ifdef notyet	if (DNS_SERIAL_GT(last_dumped_serial, j->x.pos[1].serial)) {		force_dump(...);	}#endif	/*	 * Commit the transaction data to stable storage.	 */	CHECK(journal_fsync(j));	/*	 * Update the transaction header.	 */	CHECK(journal_seek(j, j->x.pos[0].offset));	CHECK(journal_write_xhdr(j, (j->x.pos[1].offset - j->x.pos[0].offset) -				 sizeof(journal_rawxhdr_t),				 j->x.pos[0].serial, j->x.pos[1].serial));	/*	 * Update the journal header.	 */	if (JOURNAL_EMPTY(&j->header)) {		j->header.begin = j->x.pos[0];	}	j->header.end = j->x.pos[1];	journal_header_encode(&j->header, &rawheader);	CHECK(journal_seek(j, 0));	CHECK(journal_write(j, &rawheader, sizeof(rawheader)));	/*	 * Update the index.	 */	index_add(j, &j->x.pos[0]);	/*	 * Convert the index into on-disk format and write	 * it to disk.	 */	CHECK(index_to_disk(j));	/*	 * Commit the header to stable storage.	 */	CHECK(journal_fsync(j));	/*	 * We no longer have a transaction open.	 */	j->state = JOURNAL_STATE_WRITE;	result = ISC_R_SUCCESS; failure:	return (result);}isc_result_tdns_journal_write_transaction(dns_journal_t *j, dns_diff_t *diff) {	isc_result_t result;	CHECK(dns_diff_sort(diff, ixfr_order));	CHECK(dns_journal_begin_transaction(j));	CHECK(dns_journal_writediff(j, diff));	CHECK(dns_journal_commit(j));	result = ISC_R_SUCCESS; failure:	return (result);}voiddns_journal_destroy(dns_journal_t **journalp) {	dns_journal_t *j = *journalp;	REQUIRE(DNS_JOURNAL_VALID(j));	j->it.result = ISC_R_FAILURE;	dns_name_invalidate(&j->it.name);	dns_decompress_invalidate(&j->it.dctx);	if (j->rawindex != NULL)		isc_mem_put(j->mctx, j->rawindex, j->header.index_size *			    sizeof(journal_rawpos_t));	if (j->index != NULL)		isc_mem_put(j->mctx, j->index, j->header.index_size *			    sizeof(journal_pos_t));	if (j->it.target.base != NULL)		isc_mem_put(j->mctx, j->it.target.base, j->it.target.length);	if (j->it.source.base != NULL)		isc_mem_put(j->mctx, j->it.source.base, j->it.source.length);	if (j->fp != NULL)		(void)isc_stdio_close(j->fp);	j->magic = 0;	isc_mem_put(j->mctx, j, sizeof(*j));	*journalp = NULL;}/* * Roll the open journal 'j' into the database 'db'. * A new database version will be created. *//* XXX Share code with incoming IXFR? */static isc_result_troll_forward(dns_journal_t *j, dns_db_t *db) {	isc_buffer_t source;		/* Transaction data from disk */	isc_buffer_t target;		/* Ditto after _fromwire check */	isc_uint32_t db_serial;		/* Database SOA serial */	isc_uint32_t end_serial;	/* Last journal SOA serial */	isc_result_t result;	dns_dbversion_t *ver = NULL;	journal_pos_t pos;	dns_diff_t diff;	unsigned int n_soa = 0;	unsigned int n_put = 0;	REQUIRE(DNS_JOURNAL_VALID(j));	REQUIRE(DNS_DB_VALID(db));	dns_diff_init(j->mctx, &diff);	/*	 * Set up empty initial buffers for uncheched and checked	 * wire format transaction data.  They will be reallocated	 * later.	 */	isc_buffer_init(&source, NULL, 0);	isc_buffer_init(&target, NULL, 0);	/*	 * Create the new database version.	 */	CHECK(dns_db_newversion(db, &ver));	/*	 * Get the current database SOA serial number.	 */	CHECK(dns_db_getsoaserial(db, ver, &db_serial));	/*	 * Locate a journal entry for the current database serial.	 */	CHECK(journal_find(j, db_serial, &pos));	/*	 * XXX do more drastic things, like marking zone stale,	 * if this fails?	 */	/*	 * XXXRTH  The zone code should probably mark the zone as bad and	 *         scream loudly into the log if this is a dynamic update	 *	   log reply that failed.	 */	end_serial = dns_journal_last_serial(j);	if (db_serial == end_serial)		CHECK(DNS_R_UPTODATE);	CHECK(dns_journal_iter_init(j, db_serial, end_serial));	for (result = dns_journal_first_rr(j);	     result == ISC_R_SUCCESS;	     result = dns_journal_next_rr(j))	{		dns_name_t *name;		isc_uint32_t ttl;		dns_rdata_t *rdata;		dns_difftuple_t *tuple = NULL;		name = NULL;		rdata = NULL;		dns_journal_current_rr(j, &name, &ttl, &rdata);		if (rdata->type == dns_rdatatype_soa) {			n_soa++;			if (n_soa == 2)				db_serial = j->it.current_serial;		}		if (n_soa == 3)			n_soa = 1;		if (n_soa == 0) {			isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR,					 "%s: journal file corrupt: missing "					 "initial SOA", j->filename);			FAIL(ISC_R_UNEXPECTED);		}		CHECK(dns_difftuple_create(diff.mctx, n_soa == 1 ?					   DNS_DIFFOP_DEL : DNS_DIFFOP_ADD,					   name, ttl, rdata, &tuple));		dns_diff_append(&diff, &tuple);		if (++n_put > 100)  {			isc_log_write(JOURNAL_DEBUG_LOGARGS(3),				      "applying diff to database (%u)",				      db_serial);			(void)dns_diff_print(&diff, NULL);			CHECK(dns_diff_apply(&diff, db, ver));			dns_diff_clear(&diff);			n_put = 0;		}	}	if (result == ISC_R_NOMORE)		result = ISC_R_SUCCESS;	CHECK(result);	if (n_put != 0) {		isc_log_write(JOURNAL_DEBUG_LOGARGS(3),			      "applying final diff to database (%u)",			      db_serial);		(void)dns_diff_print(&diff, NULL);		CHECK(dns_diff_apply(&diff, db, ver));		dns_diff_clear(&diff);	} failure:	if (ver != NULL)		dns_db_closeversion(db, &ver, result == ISC_R_SUCCESS ?				    ISC_TRUE : ISC_FALSE);	if (source.base != NULL)		isc_mem_put(j->mctx, source.base, source.length);	if (target.base != NULL)		isc_mem_put(j->mctx, target.base, target.length);	dns_diff_clear(&diff);	return (result);}isc_result_tdns_journal_rollforward(isc_mem_t *mctx, dns_db_t *db, const char *filename) {	dns_journal_t *j;	isc_result_t result;	REQUIRE(DNS_DB_VALID(db));	REQUIRE(filename != NULL);	j = NULL;	result = dns_journal_open(mctx, filename, ISC_FALSE, &j);	if (result == ISC_R_NOTFOUND) {		isc_log_write(JOURNAL_DEBUG_LOGARGS(3),			      "no journal file, but that's OK");		return (DNS_R_NOJOURNAL);	}	if (result != ISC_R_SUCCESS)		return (result);	if (JOURNAL_EMPTY(&j->header))		result = DNS_R_UPTODATE;	else		result = roll_forward(j, db);	dns_journal_destroy(&j);	return (result);}isc_result_tdns_journal_print(isc_mem_t *mctx, const char *filename, FILE *file) {	dns_journal_t *j;	isc_buffer_t source;		/* Transaction data from disk */	isc_buffer_t target;		/* Ditto after _fromwire check */	isc_uint32_t start_serial;		/* Database SOA serial */	isc_uint32_t end_serial;	/* Last journal SOA serial */	isc_result_t result;	dns_diff_t diff;	unsigned int n_soa = 0;	unsigned int n_put = 0;	REQUIRE(filename != NULL);	j = NULL;	result = dns_journal_open(mctx, filename, ISC_FALSE, &j);	if (result == ISC_R_NOTFOUND) {		isc_log_write(JOURNAL_DEBUG_LOGARGS(3), "no journal file");		return (DNS_R_NOJOURNAL);	}	if (result != ISC_R_SUCCESS) {		isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR,			      "journal open failure");		return (result);	}	dns_diff_init(j->mctx, &diff);	/*	 * Set up empty initial buffers for uncheched and checked	 * wire format transaction data.  They will be reallocated	 * later.	 */	isc_buffer_init(&source, NULL, 0);	isc_buffer_init(&target, NULL, 0);	start_serial = dns_journal_first_serial(j);	end_serial = dns_journal_last_serial(j);	CHECK(dns_journal_iter_init(j, start_serial, end_serial));	for (result = dns_journal_first_rr(j);	     result == ISC_R_SUCCESS;	     result = dns_journal_next_rr(j))	{		dns_name_t *name;		isc_uint32_t ttl;		dns_rdata_t *rdata;		dns_difftuple_t *tuple = NULL;		name = NULL;		rdata = NULL;		dns_journal_current_rr(j, &name, &ttl, &rdata);		if (rdata->type == dns_rdatatype_soa)			n_soa++;		if (n_soa == 3)			n_soa = 1;		if (n_soa == 0) {		isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR,					 "%s: journal file corrupt: missing "					 "initial SOA", j->filename);			FAIL(ISC_R_UNEXPECTED);		}		CHECK(dns_difftuple_create(diff.mctx, n_soa == 1 ?					   DNS_DIFFOP_DEL : DNS_DIFFOP_ADD,					   name, ttl, rdata, &tuple));		dns_diff_append(&diff, &tuple);		if (++n_put > 100)  {			result = dns_diff_print(&diff, file);			dns_diff_clear(&diff);			n_put = 0;			if (result != ISC_R_SUCCESS)				break;		}	}	if (result == ISC_R_NOMORE)		result = ISC_R_SUCCESS;	CHECK(result);	if (n_put != 0) {		result = dns_diff_print(&diff, file);		dns_diff_clear(&diff);	}	goto cleanup; failure:	isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR,		      "%s: cannot print: journal file corrupt", j->filename); cleanup:	if (source.base != NULL)		isc_mem_put(j->mctx, source.base, source.length);	if (target.base != NULL)		isc_mem_put(j->mctx, target.base, target.length);	dns_diff_clear(&diff);	dns_journal_destroy(&j);	return (result);}/**************************************************************************//* * Miscellaneous accessors. */isc_uint32_t dns_journal_first_serial(dns_journal_t *j) {	return (j->header.begin.serial);}isc_uint32_t dns_journal_last_serial(dns_journal_t *j) {	return (j->header.end.serial);}/**************************************************************************//* * Iteration support. * * When serving an outgoing IXFR, we transmit a part the journal starting * at the serial number in the IXFR request and ending at the serial * number that is current when the IXFR request arrives.  The ending * serial number is not necessarily at the end of the journal: * the journal may grow while the IXFR is in progress, but we stop * when we reach the serial number that was current when the IXFR started. */static isc_result_t read_one_rr(dns_journal_t *j);/* * Make sure the buffer 'b' is has at least 'size' bytes * allocated, and clear it. * * Requires: *	Either b->base is NULL, or it points to b->length bytes of memory *	previously allocated by isc_mem_get(). */static isc_result_tsize_buffer(isc_mem_t *mctx, isc_buffer_t *b, unsigned size) {	if (b->length < size) {		void *mem = isc_mem_get(mctx, size);		if (mem == NULL)			return (ISC_R_NOMEMORY);		if (b->base != NULL)			isc_mem_put(mctx, b->base, b->length);		b->base = mem;		b->length = size;	}	isc_buffer_clear(b);	return (ISC_R_SUCCESS);}isc_result_tdns_journal_iter_init(dns_journal_t *j,		      isc_uint32_t begin_serial, isc_uint32_t end_serial){	isc_result_t result;	CHECK(journal_find(j, begin_serial, &j->it.bpos));	INSIST(j->it.bpos.serial == begin_serial);	CHECK(journal_find(j, end_serial, &j->it.epos));	INSIST(j->it.epos.serial == end_serial);	result = ISC_R_SUCCESS; failure:	j->it.result = result;	return (j->it.result);}isc_result_tdns_journal_first_rr(dns_journal_t *j) {	isc_result_t result;	/*	 * Seek to the beginning of the first transaction we are	 * interested in.	 */	CHECK(journal_seek(j, j->it.bpos.offset));	j->it.current_serial = j->it.bpos.serial;	j->it.xsize = 0;  /* We have no transaction data yet... */	j->it.xpos = 0;	  /* ...and haven't used any of it. */	return (read_one_rr(j)); failure:	return (result);}static isc_result_tread_one_rr(dns_journal_t *j) {	isc_result_t result;	dns_rdatatype_t rdtype;	dns_rdataclass_t rdclass;	unsigned int rdlen;	isc_uint32_t ttl;	journal_xhdr_t xhdr;	journal_rrhdr_t rrhdr;	INSIST(j->offset <= j->it.epos.offset);	if (j->offset == j->it.epos.offset)		return (ISC_R_NOMORE);	if (j->it.xpos == j->it.xsize) {		/*		 * We are at a transaction boundary.		 * Read another transaction header.		 */		CHECK(journal_read_xhdr(j, &xhdr));		if (xhdr.size == 0) {			isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR,				      "journal corrupt: empty transaction");			FAIL(ISC_R_UNEXPECTED);		}		if (xhdr.serial0 != j->it.current_serial) {			isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR,					 "%s: journal file corrupt: "					 "expected serial %u, got %u",					 j->filename,					 j->it.current_serial, xhdr.serial0);			FAIL(ISC_R_UNEXPECTED);		}		j->it.xsize = xhdr.size;		j->it.xpos = 0;	}	/*	 * Read an RR.	 */	result = journal_read_rrhdr(j, &rrhdr);	/*	 * Perform a sanity check on the journal RR size.	 * The smallest possible RR has a 1-byte owner name	 * and a 10-byte header.  The largest possible	 * RR has 65535 bytes of data, a header, and a maximum-	 * size owner name, well below 70 k total.	 */	if (rrhdr.size < 1+10 || rrhdr.size > 70000) {		isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR,				 "%s: journal corrupt: impossible RR size "				 "(%d bytes)", j->filename, rrhdr.size);		FAIL(ISC_R_UNEXPECTED);	}	CHECK(size_buffer(j->mctx, &j->it.source, rrhdr.size));	CHECK(journal_read(j, j->it.source.base, rrhdr.size));	isc_buffer_add(&j->it.source, rrhdr.size);	/*	 * The target buffer is made the same size	 * as the source buffer, with the assumption that when	 * no compression in present, the output of dns_*_fromwire()	 * is no larger than the input.	 */	CHECK(size_buffer(j->mctx, &j->it.target, rrhdr.size));	/*	 * Parse the owner name.  We don't know where it	 * ends yet, so we make the entire "remaining"	 * part of the buffer "active".	 */	isc_buffer_setactive(&j->it.source,			     j->it.source.used - j->it.source.current);	CHECK(dns_name_fromwire(&j->it.name, &j->it.source,

⌨️ 快捷键说明

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