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

📄 journal.c

📁 bind 9.3结合mysql数据库
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * Copyright (C) 2004  Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002  Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. *//* $Id: journal.c,v 1.77.2.1.10.8 2004/05/14 05:27:47 marka Exp $ */#include <config.h>#include <stdlib.h>#include <isc/file.h>#include <isc/mem.h>#include <isc/stdio.h>#include <isc/string.h>#include <isc/util.h>#include <dns/compress.h>#include <dns/db.h>#include <dns/dbiterator.h>#include <dns/diff.h>#include <dns/fixedname.h>#include <dns/journal.h>#include <dns/log.h>#include <dns/rdataset.h>#include <dns/rdatasetiter.h>#include <dns/result.h>#include <dns/soa.h>/* * When true, accept IXFR difference sequences where the * SOA serial number does not change (BIND 8 sends such * sequences). */static isc_boolean_t bind8_compat = ISC_TRUE; /* XXX config *//**************************************************************************//* * Miscellaneous utilities. */#define JOURNAL_COMMON_LOGARGS \	dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_JOURNAL#define JOURNAL_DEBUG_LOGARGS(n) \	JOURNAL_COMMON_LOGARGS, ISC_LOG_DEBUG(n)/* * It would be non-sensical (or at least obtuse) to use FAIL() with an * ISC_R_SUCCESS code, but the test is there to keep the Solaris compiler * from complaining about "end-of-loop code not reached". */#define FAIL(code) \	do { result = (code);					\		if (result != ISC_R_SUCCESS) goto failure;	\	} while (0)#define CHECK(op) \     	do { result = (op); 					\		if (result != ISC_R_SUCCESS) goto failure; 	\	} while (0)static isc_result_t index_to_disk(dns_journal_t *);static inline isc_uint32_tdecode_uint32(unsigned char *p) {	return ((p[0] << 24) +		(p[1] << 16) +		(p[2] <<  8) +		(p[3] <<  0));}static inline voidencode_uint32(isc_uint32_t val, unsigned char *p) {	p[0] = (isc_uint8_t)(val >> 24);	p[1] = (isc_uint8_t)(val >> 16);	p[2] = (isc_uint8_t)(val >>  8);	p[3] = (isc_uint8_t)(val >>  0);}isc_result_tdns_db_createsoatuple(dns_db_t *db, dns_dbversion_t *ver, isc_mem_t *mctx,		      dns_diffop_t op, dns_difftuple_t **tp){	isc_result_t result;	dns_dbnode_t *node;	dns_rdataset_t rdataset;	dns_rdata_t rdata = DNS_RDATA_INIT;	dns_name_t *zonename;	zonename = dns_db_origin(db);	node = NULL;	result = dns_db_findnode(db, zonename, ISC_FALSE, &node);	if (result != ISC_R_SUCCESS)		goto nonode;	dns_rdataset_init(&rdataset);	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_soa, 0,				     (isc_stdtime_t)0, &rdataset, NULL); 	if (result != ISC_R_SUCCESS)		goto freenode;	result = dns_rdataset_first(&rdataset); 	if (result != ISC_R_SUCCESS)		goto freenode;	dns_rdataset_current(&rdataset, &rdata);	result = dns_difftuple_create(mctx, op, zonename, rdataset.ttl,				      &rdata, tp);	dns_rdataset_disassociate(&rdataset);	dns_db_detachnode(db, &node);	return (ISC_R_SUCCESS); freenode:	dns_db_detachnode(db, &node); nonode:	UNEXPECTED_ERROR(__FILE__, __LINE__, "missing SOA");	return (result);}/**************************************************************************//* * Journalling. *//* * A journal file consists of * *   - A fixed-size header of type journal_rawheader_t. * *   - The index.  This is an unordered array of index entries *     of type journal_rawpos_t giving the locations *     of some arbitrary subset of the journal's addressable *     transactions.  The index entries are used as hints to *     speed up the process of locating a transaction with a given *     serial number.  Unused index entries have an "offset" *     field of zero.  The size of the index can vary between *     journal files, but does not change during the lifetime *     of a file.  The size can be zero. * *   - The journal data.  This  consists of one or more transactions. *     Each transaction begins with a transaction header of type *     journal_rawxhdr_t.  The transaction header is followed by a *     sequence of RRs, similar in structure to an IXFR difference *     sequence (RFC1995).  That is, the pre-transaction SOA, *     zero or more other deleted RRs, the post-transaction SOA, *     and zero or more other added RRs.  Unlike in IXFR, each RR *     is prefixed with a 32-bit length. * *     The journal data part grows as new transactions are *     appended to the file.  Only those transactions *     whose serial number is current-(2^31-1) to current *     are considered "addressable" and may be pointed *     to from the header or index.  They may be preceded *     by old transactions that are no longer addressable, *     and they may be followed by transactions that were *     appended to the journal but never committed by updating *     the "end" position in the header.  The latter will *     be overwritten when new transactions are added. *//* * On-disk representation of a "pointer" to a journal entry. * These are used in the journal header to locate the beginning * and end of the journal, and in the journal index to locate * other transactions. */typedef struct {	unsigned char	serial[4];  /* SOA serial before update. */	/*	 * XXXRTH  Should offset be 8 bytes?	 * XXXDCL ... probably, since isc_offset_t is 8 bytes on many OSs.	 * XXXAG  ... but we will not be able to seek >2G anyway on many	 *            platforms as long as we are using fseek() rather	 *            than lseek().	 */	unsigned char	offset[4];  /* Offset from beginning of file. */} journal_rawpos_t;/* * The on-disk representation of the journal header. * All numbers are stored in big-endian order. *//* * The header is of a fixed size, with some spare room for future * extensions. */#define JOURNAL_HEADER_SIZE 64 /* Bytes. */typedef union {	struct {		/* File format version ID. */		unsigned char 		format[16];		/* Position of the first addressable transaction */		journal_rawpos_t 	begin;		/* Position of the next (yet nonexistent) transaction. */		journal_rawpos_t 	end;		/* Number of index entries following the header. */		unsigned char 		index_size[4];	} h;	/* Pad the header to a fixed size. */	unsigned char pad[JOURNAL_HEADER_SIZE];} journal_rawheader_t;/* * The on-disk representation of the transaction header. * There is one of these at the beginning of each transaction. */typedef struct {	unsigned char	size[4]; 	/* In bytes, excluding header. */	unsigned char	serial0[4];	/* SOA serial before update. */	unsigned char	serial1[4];	/* SOA serial after update. */} journal_rawxhdr_t;/* * The on-disk representation of the RR header. * There is one of these at the beginning of each RR. */typedef struct {	unsigned char	size[4]; 	/* In bytes, excluding header. */} journal_rawrrhdr_t;/* * The in-core representation of the journal header. */typedef struct {	isc_uint32_t	serial;	isc_offset_t	offset;} journal_pos_t;#define POS_VALID(pos) 		((pos).offset != 0)#define POS_INVALIDATE(pos) 	((pos).offset = 0, (pos).serial = 0)typedef struct {	unsigned char 	format[16];	journal_pos_t 	begin;	journal_pos_t 	end;	isc_uint32_t	index_size;} journal_header_t;/* * The in-core representation of the transaction header. */typedef struct {	isc_uint32_t	size;	isc_uint32_t	serial0;	isc_uint32_t	serial1;} journal_xhdr_t;/* * The in-core representation of the RR header. */typedef struct {	isc_uint32_t	size;} journal_rrhdr_t;/* * Initial contents to store in the header of a newly created * journal file. * * The header starts with the magic string ";BIND LOG V9\n" * to identify the file as a BIND 9 journal file.  An ASCII * identification string is used rather than a binary magic * number to be consistent with BIND 8 (BIND 8 journal files * are ASCII text files). */static journal_header_tinitial_journal_header = { ";BIND LOG V9\n", { 0, 0 }, { 0, 0 }, 0 };#define JOURNAL_EMPTY(h) ((h)->begin.offset == (h)->end.offset)typedef enum {	JOURNAL_STATE_INVALID,	JOURNAL_STATE_READ,	JOURNAL_STATE_WRITE,	JOURNAL_STATE_TRANSACTION} journal_state_t;struct dns_journal {	unsigned int		magic;		/* JOUR */	isc_mem_t		*mctx;		/* Memory context */	journal_state_t		state;	const char 		*filename;	/* Journal file name */	FILE *			fp;		/* File handle */	isc_offset_t		offset;		/* Current file offset */	journal_header_t 	header;		/* In-core journal header */	unsigned char		*rawindex;	/* In-core buffer for journal						   index in on-disk format */	journal_pos_t		*index;		/* In-core journal index */	/* Current transaction state (when writing). */	struct {		unsigned int	n_soa;		/* Number of SOAs seen */		journal_pos_t	pos[2];		/* Begin/end position */	} x;	/* Iteration state (when reading). */	struct {		/* These define the part of the journal we iterate over. */		journal_pos_t bpos;		/* Position before first, */		journal_pos_t epos;		/* and after last						   transaction */		/* The rest is iterator state. */		isc_uint32_t current_serial;	/* Current SOA serial */		isc_buffer_t source;		/* Data from disk */		isc_buffer_t target;		/* Data from _fromwire check */		dns_decompress_t dctx;		/* Dummy decompression ctx */		dns_name_t name;		/* Current domain name */		dns_rdata_t rdata;		/* Current rdata */		isc_uint32_t ttl;		/* Current TTL */		unsigned int xsize;		/* Size of transaction data */		unsigned int xpos;		/* Current position in it */		isc_result_t result;		/* Result of last call */	} it;};#define DNS_JOURNAL_MAGIC	ISC_MAGIC('J', 'O', 'U', 'R')#define DNS_JOURNAL_VALID(t)	ISC_MAGIC_VALID(t, DNS_JOURNAL_MAGIC)static voidjournal_pos_decode(journal_rawpos_t *raw, journal_pos_t *cooked) {	cooked->serial = decode_uint32(raw->serial);	cooked->offset = decode_uint32(raw->offset);}static voidjournal_pos_encode(journal_rawpos_t *raw, journal_pos_t *cooked) {	encode_uint32(cooked->serial, raw->serial);	encode_uint32(cooked->offset, raw->offset);}static voidjournal_header_decode(journal_rawheader_t *raw, journal_header_t *cooked) {	INSIST(sizeof(cooked->format) == sizeof(raw->h.format));	memcpy(cooked->format, raw->h.format, sizeof(cooked->format));	journal_pos_decode(&raw->h.begin, &cooked->begin);	journal_pos_decode(&raw->h.end, &cooked->end);	cooked->index_size = decode_uint32(raw->h.index_size);}static voidjournal_header_encode(journal_header_t *cooked, journal_rawheader_t *raw) {	INSIST(sizeof(cooked->format) == sizeof(raw->h.format));	memset(raw->pad, 0, sizeof(raw->pad));	memcpy(raw->h.format, cooked->format, sizeof(raw->h.format));	journal_pos_encode(&raw->h.begin, &cooked->begin);	journal_pos_encode(&raw->h.end, &cooked->end);	encode_uint32(cooked->index_size, raw->h.index_size);}/* * Journal file I/O subroutines, with error checking and reporting. */static isc_result_tjournal_seek(dns_journal_t *j, isc_uint32_t offset) {	isc_result_t result;	result = isc_stdio_seek(j->fp, (long)offset, SEEK_SET);	if (result != ISC_R_SUCCESS) {		isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR,			      "%s: seek: %s", j->filename,			      isc_result_totext(result));		return (ISC_R_UNEXPECTED);	}	j->offset = offset;	return (ISC_R_SUCCESS);}static isc_result_tjournal_read(dns_journal_t *j, void *mem, size_t nbytes) {	isc_result_t result;	result = isc_stdio_read(mem, 1, nbytes, j->fp, NULL);	if (result != ISC_R_SUCCESS) {		if (result == ISC_R_EOF)			return (ISC_R_NOMORE);		isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR,			      "%s: read: %s",			      j->filename, isc_result_totext(result));		return (ISC_R_UNEXPECTED);	}	j->offset += nbytes;	return (ISC_R_SUCCESS);}static isc_result_tjournal_write(dns_journal_t *j, void *mem, size_t nbytes) {	isc_result_t result;	result = isc_stdio_write(mem, 1, nbytes, j->fp, NULL);	if (result != ISC_R_SUCCESS) {		isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR,			      "%s: write: %s",			      j->filename, isc_result_totext(result));		return (ISC_R_UNEXPECTED);	}	j->offset += nbytes;	return (ISC_R_SUCCESS);}static isc_result_tjournal_fsync(dns_journal_t *j) {	isc_result_t result;	result = isc_stdio_flush(j->fp);	if (result != ISC_R_SUCCESS) {		isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR,			      "%s: flush: %s",			      j->filename, isc_result_totext(result));		return (ISC_R_UNEXPECTED);	}	result = isc_stdio_sync(j->fp);	if (result != ISC_R_SUCCESS) {		isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR,			      "%s: fsync: %s",			      j->filename, isc_result_totext(result));		return (ISC_R_UNEXPECTED);	}	return (ISC_R_SUCCESS);}/* * Read/write a transaction header at the current file position. */static isc_result_tjournal_read_xhdr(dns_journal_t *j, journal_xhdr_t *xhdr) {	journal_rawxhdr_t raw;	isc_result_t result;	result = journal_read(j, &raw, sizeof(raw));	if (result != ISC_R_SUCCESS)		return (result);	xhdr->size = decode_uint32(raw.size);	xhdr->serial0 = decode_uint32(raw.serial0);	xhdr->serial1 = decode_uint32(raw.serial1);	return (ISC_R_SUCCESS);}static isc_result_tjournal_write_xhdr(dns_journal_t *j, isc_uint32_t size,		   isc_uint32_t serial0, isc_uint32_t serial1){	journal_rawxhdr_t raw;	encode_uint32(size, raw.size);	encode_uint32(serial0, raw.serial0);	encode_uint32(serial1, raw.serial1);	return (journal_write(j, &raw, sizeof(raw)));}/* * Read an RR header at the current file position. */static isc_result_tjournal_read_rrhdr(dns_journal_t *j, journal_rrhdr_t *rrhdr) {	journal_rawrrhdr_t raw;	isc_result_t result;	result = journal_read(j, &raw, sizeof(raw));	if (result != ISC_R_SUCCESS)		return (result);	rrhdr->size = decode_uint32(raw.size);	return (ISC_R_SUCCESS);}static isc_result_tjournal_file_create(isc_mem_t *mctx, const char *filename) {	FILE *fp = NULL;	isc_result_t result;	journal_header_t header;	journal_rawheader_t rawheader;	int index_size = 56; /* XXX configurable */	int size;	void *mem; /* Memory for temporary index image. */	INSIST(sizeof(journal_rawheader_t) == JOURNAL_HEADER_SIZE);	result = isc_stdio_open(filename, "wb", &fp);	if (result != ISC_R_SUCCESS) {		isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR,			      "%s: create: %s",			      filename, isc_result_totext(result));		return (ISC_R_UNEXPECTED);	}	header = initial_journal_header;	header.index_size = index_size;	journal_header_encode(&header, &rawheader);	size = sizeof(journal_rawheader_t) +		index_size * sizeof(journal_rawpos_t);	mem = isc_mem_get(mctx, size);	if (mem == NULL) {		(void)isc_stdio_close(fp);		(void)isc_file_remove(filename);		return (ISC_R_NOMEMORY);	}	memset(mem, 0, size);	memcpy(mem, &rawheader, sizeof(rawheader));	result = isc_stdio_write(mem, 1, (size_t) size, fp, NULL);	if (result != ISC_R_SUCCESS) {		isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR,				 "%s: write: %s",				 filename, isc_result_totext(result));		(void)isc_stdio_close(fp);		(void)isc_file_remove(filename);		isc_mem_put(mctx, mem, size);		return (ISC_R_UNEXPECTED);	}	isc_mem_put(mctx, mem, size);	result = isc_stdio_close(fp);	if (result != ISC_R_SUCCESS) {		isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR,

⌨️ 快捷键说明

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