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

📄 journal.c

📁 bind-3.2.
💻 C
📖 第 1 页 / 共 4 页
字号:
				j->x.pos[j->x.n_soa].serial =					dns_soa_getserial(&t->rdata);			j->x.n_soa++;		}		size += sizeof(journal_rawrrhdr_t);		size += t->name.length; /* XXX should have access macro? */		size += 10;		size += t->rdata.length;	}	mem = isc_mem_get(j->mctx, size);	if (mem == NULL)		return (ISC_R_NOMEMORY);	isc_buffer_init(&buffer, mem, size);	/*	 * Pass 2.  Write RRs to buffer.	 */	for (t = ISC_LIST_HEAD(diff->tuples); t != NULL;	     t = ISC_LIST_NEXT(t, link))	{		/*		 * Write the RR header.		 */		isc_buffer_putuint32(&buffer, t->name.length + 10 +				     t->rdata.length);		/*		 * Write the owner name, RR header, and RR data.		 */		isc_buffer_putmem(&buffer, t->name.ndata, t->name.length);		isc_buffer_putuint16(&buffer, t->rdata.type);		isc_buffer_putuint16(&buffer, t->rdata.rdclass);		isc_buffer_putuint32(&buffer, t->ttl);		INSIST(t->rdata.length < 65536);		isc_buffer_putuint16(&buffer, (isc_uint16_t)t->rdata.length);		INSIST(isc_buffer_availablelength(&buffer) >= t->rdata.length);		isc_buffer_putmem(&buffer, t->rdata.data, t->rdata.length);	}	isc_buffer_usedregion(&buffer, &used);	INSIST(used.length == size);	j->x.pos[1].offset += used.length;	/*	 * Write the buffer contents to the journal file.	 */	CHECK(journal_write(j, used.base, used.length));	result = ISC_R_SUCCESS; failure:	if (mem != NULL)		isc_mem_put(j->mctx, mem, size);	return (result);}isc_result_tdns_journal_commit(dns_journal_t *j) {	isc_result_t result;	journal_rawheader_t rawheader;	REQUIRE(DNS_JOURNAL_VALID(j));	REQUIRE(j->state == JOURNAL_STATE_TRANSACTION);	/*	 * Perform some basic consistency checks.	 */	if (j->x.n_soa != 2) {		isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR,			      "malformed transaction: %d SOAs",			      j->x.n_soa);		return (ISC_R_UNEXPECTED);	}	if (! (DNS_SERIAL_GT(j->x.pos[1].serial, j->x.pos[0].serial) ||	       (bind8_compat &&		j->x.pos[1].serial == j->x.pos[0].serial)))	{		isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR,			      "malformed transaction: serial number "			      "would decrease");		return (ISC_R_UNEXPECTED);	}	if (! JOURNAL_EMPTY(&j->header)) {		if (j->x.pos[0].serial != j->header.end.serial) {			isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR,					 "malformed transaction: "					 "%s last serial %u != "					 "transaction first serial %u",					 j->filename,					 j->header.end.serial,					 j->x.pos[0].serial);			return (ISC_R_UNEXPECTED);		}	}	/*	 * Some old journal entries may become non-addressable	 * when we increment the current serial number.  Purge them	 * 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.	 */	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_write(j, j->rawindex, rawbytes));	}	/*	 * 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 == 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");			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");		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);

⌨️ 快捷键说明

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