00001 /* 00002 * Copyright (C) 2004-2009, 2011, 2013 Internet Systems Consortium, Inc. ("ISC") 00003 * Copyright (C) 1999-2001 Internet Software Consortium. 00004 * 00005 * Permission to use, copy, modify, and/or distribute this software for any 00006 * purpose with or without fee is hereby granted, provided that the above 00007 * copyright notice and this permission notice appear in all copies. 00008 * 00009 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 00010 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 00011 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 00012 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 00013 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 00014 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 00015 * PERFORMANCE OF THIS SOFTWARE. 00016 */ 00017 00018 /* $Id: journal.h,v 1.43 2011/12/22 07:32:41 each Exp $ */ 00019 00020 #ifndef DNS_JOURNAL_H 00021 #define DNS_JOURNAL_H 1 00022 00023 /***** 00024 ***** Module Info 00025 *****/ 00026 00027 /*! \file dns/journal.h 00028 * \brief 00029 * Database journaling. 00030 */ 00031 00032 /*** 00033 *** Imports 00034 ***/ 00035 00036 #include <isc/lang.h> 00037 #include <isc/magic.h> 00038 00039 #include <dns/name.h> 00040 #include <dns/diff.h> 00041 #include <dns/rdata.h> 00042 #include <dns/types.h> 00043 00044 /*** 00045 *** Defines. 00046 ***/ 00047 #define DNS_JOURNALOPT_RESIGN 0x00000001 00048 00049 #define DNS_JOURNAL_READ 0x00000000 /* ISC_FALSE */ 00050 #define DNS_JOURNAL_CREATE 0x00000001 /* ISC_TRUE */ 00051 #define DNS_JOURNAL_WRITE 0x00000002 00052 00053 /*** 00054 *** Types 00055 ***/ 00056 00057 /*% 00058 * A dns_journal_t represents an open journal file. This is an opaque type. 00059 * 00060 * A particular dns_journal_t object may be opened for writing, in which case 00061 * it can be used for writing transactions to a journal file, or it can be 00062 * opened for reading, in which case it can be used for reading transactions 00063 * from (iterating over) a journal file. A single dns_journal_t object may 00064 * not be used for both purposes. 00065 */ 00066 typedef struct dns_journal dns_journal_t; 00067 00068 00069 /*** 00070 *** Functions 00071 ***/ 00072 00073 ISC_LANG_BEGINDECLS 00074 00075 /**************************************************************************/ 00076 00077 isc_result_t 00078 dns_db_createsoatuple(dns_db_t *db, dns_dbversion_t *ver, isc_mem_t *mctx, 00079 dns_diffop_t op, dns_difftuple_t **tp); 00080 /*!< brief 00081 * Create a diff tuple for the current database SOA. 00082 * XXX this probably belongs somewhere else. 00083 */ 00084 00085 00086 /*@{*/ 00087 #define DNS_SERIAL_GT(a, b) ((int)(((a) - (b)) & 0xFFFFFFFF) > 0) 00088 #define DNS_SERIAL_GE(a, b) ((int)(((a) - (b)) & 0xFFFFFFFF) >= 0) 00089 /*!< brief 00090 * Compare SOA serial numbers. DNS_SERIAL_GT(a, b) returns true iff 00091 * a is "greater than" b where "greater than" is as defined in RFC1982. 00092 * DNS_SERIAL_GE(a, b) returns true iff a is "greater than or equal to" b. 00093 */ 00094 /*@}*/ 00095 00096 /**************************************************************************/ 00097 /* 00098 * Journal object creation and destruction. 00099 */ 00100 00101 isc_result_t 00102 dns_journal_open(isc_mem_t *mctx, const char *filename, unsigned int mode, 00103 dns_journal_t **journalp); 00104 /*%< 00105 * Open the journal file 'filename' and create a dns_journal_t object for it. 00106 * 00107 * DNS_JOURNAL_CREATE open the journal for reading and writing and create 00108 * the journal if it does not exist. 00109 * DNS_JOURNAL_WRITE open the journal for reading and writing. 00110 * DNS_JOURNAL_READ open the journal for reading only. 00111 */ 00112 00113 void 00114 dns_journal_destroy(dns_journal_t **journalp); 00115 /*%< 00116 * Destroy a dns_journal_t, closing any open files and freeing its memory. 00117 */ 00118 00119 /**************************************************************************/ 00120 /* 00121 * Writing transactions to journals. 00122 */ 00123 00124 isc_result_t 00125 dns_journal_begin_transaction(dns_journal_t *j); 00126 /*%< 00127 * Prepare to write a new transaction to the open journal file 'j'. 00128 * 00129 * Requires: 00130 * \li 'j' is open for writing. 00131 */ 00132 00133 isc_result_t 00134 dns_journal_writediff(dns_journal_t *j, dns_diff_t *diff); 00135 /*%< 00136 * Write 'diff' to the current transaction of journal file 'j'. 00137 * 00138 * Requires: 00139 * \li 'j' is open for writing and dns_journal_begin_transaction() 00140 * has been called. 00141 * 00142 *\li 'diff' is a full or partial, correctly ordered IXFR 00143 * difference sequence. 00144 */ 00145 00146 isc_result_t 00147 dns_journal_commit(dns_journal_t *j); 00148 /*%< 00149 * Commit the current transaction of journal file 'j'. 00150 * 00151 * Requires: 00152 * \li 'j' is open for writing and dns_journal_begin_transaction() 00153 * has been called. 00154 * 00155 * \li dns_journal_writediff() has been called one or more times 00156 * to form a complete, correctly ordered IXFR difference 00157 * sequence. 00158 */ 00159 00160 isc_result_t 00161 dns_journal_write_transaction(dns_journal_t *j, dns_diff_t *diff); 00162 /*% 00163 * Write a complete transaction at once to a journal file, 00164 * sorting it if necessary, and commit it. Equivalent to calling 00165 * dns_diff_sort(), dns_journal_begin_transaction(), 00166 * dns_journal_writediff(), and dns_journal_commit(). 00167 * 00168 * Requires: 00169 *\li 'j' is open for writing. 00170 * 00171 * \li 'diff' contains exactly one SOA deletion, one SOA addition 00172 * with a greater serial number, and possibly other changes, 00173 * in arbitrary order. 00174 */ 00175 00176 /**************************************************************************/ 00177 /* 00178 * Reading transactions from journals. 00179 */ 00180 00181 isc_uint32_t 00182 dns_journal_first_serial(dns_journal_t *j); 00183 isc_uint32_t 00184 dns_journal_last_serial(dns_journal_t *j); 00185 /*%< 00186 * Get the first and last addressable serial number in the journal. 00187 */ 00188 00189 isc_result_t 00190 dns_journal_iter_init(dns_journal_t *j, 00191 isc_uint32_t begin_serial, isc_uint32_t end_serial); 00192 /*%< 00193 * Prepare to iterate over the transactions that will bring the database 00194 * from SOA serial number 'begin_serial' to 'end_serial'. 00195 * 00196 * Returns: 00197 *\li ISC_R_SUCCESS 00198 *\li ISC_R_RANGE begin_serial is outside the addressable range. 00199 *\li ISC_R_NOTFOUND begin_serial is within the range of addressable 00200 * serial numbers covered by the journal, but 00201 * this particular serial number does not exist. 00202 */ 00203 00204 /*@{*/ 00205 isc_result_t 00206 dns_journal_first_rr(dns_journal_t *j); 00207 isc_result_t 00208 dns_journal_next_rr(dns_journal_t *j); 00209 /*%< 00210 * Position the iterator at the first/next RR in a journal 00211 * transaction sequence established using dns_journal_iter_init(). 00212 * 00213 * Requires: 00214 * \li dns_journal_iter_init() has been called. 00215 * 00216 */ 00217 /*@}*/ 00218 00219 void 00220 dns_journal_current_rr(dns_journal_t *j, dns_name_t **name, isc_uint32_t *ttl, 00221 dns_rdata_t **rdata); 00222 /*%< 00223 * Get the name, ttl, and rdata of the current journal RR. 00224 * 00225 * Requires: 00226 * \li The last call to dns_journal_first_rr() or dns_journal_next_rr() 00227 * returned ISC_R_SUCCESS. 00228 */ 00229 00230 /**************************************************************************/ 00231 /* 00232 * Database roll-forward. 00233 */ 00234 00235 isc_result_t 00236 dns_journal_rollforward(isc_mem_t *mctx, dns_db_t *db, unsigned int options, 00237 const char *filename); 00238 /*%< 00239 * Roll forward (play back) the journal file "filename" into the 00240 * database "db". This should be called when the server starts 00241 * after a shutdown or crash. 00242 * 00243 * Requires: 00244 *\li 'mctx' is a valid memory context. 00245 *\li 'db' is a valid database which does not have a version 00246 * open for writing. 00247 *\li 'filename' is the name of the journal file belonging to 'db'. 00248 * 00249 * Returns: 00250 *\li DNS_R_NOJOURNAL when journal does not exist. 00251 *\li ISC_R_NOTFOUND when current serial in not in journal. 00252 *\li ISC_R_RANGE when current serial in not in journals range. 00253 *\li ISC_R_SUCCESS journal has been applied successfully to database. 00254 * others 00255 */ 00256 00257 isc_result_t 00258 dns_journal_print(isc_mem_t *mctx, const char *filename, FILE *file); 00259 /* For debugging not general use */ 00260 00261 isc_result_t 00262 dns_db_diff(isc_mem_t *mctx, 00263 dns_db_t *dba, dns_dbversion_t *dbvera, 00264 dns_db_t *dbb, dns_dbversion_t *dbverb, 00265 const char *journal_filename); 00266 00267 isc_result_t 00268 dns_db_diffx(dns_diff_t *diff, dns_db_t *dba, dns_dbversion_t *dbvera, 00269 dns_db_t *dbb, dns_dbversion_t *dbverb, 00270 const char *journal_filename); 00271 /*%< 00272 * Compare the databases 'dba' and 'dbb' and generate a diff/journal 00273 * entry containing the changes to make 'dba' from 'dbb' (note 00274 * the order). This journal entry will consist of a single, 00275 * possibly very large transaction. Append the journal 00276 * entry to the journal file specified by 'journal_filename' if 00277 * non-NULL. 00278 */ 00279 00280 isc_result_t 00281 dns_journal_compact(isc_mem_t *mctx, char *filename, isc_uint32_t serial, 00282 isc_uint32_t target_size); 00283 /*%< 00284 * Attempt to compact the journal if it is greater that 'target_size'. 00285 * Changes from 'serial' onwards will be preserved. If the journal 00286 * exists and is non-empty 'serial' must exist in the journal. 00287 */ 00288 00289 isc_boolean_t 00290 dns_journal_get_sourceserial(dns_journal_t *j, isc_uint32_t *sourceserial); 00291 void 00292 dns_journal_set_sourceserial(dns_journal_t *j, isc_uint32_t sourceserial); 00293 /*%< 00294 * Get and set source serial. 00295 * 00296 * Returns: 00297 * ISC_TRUE if sourceserial has previously been set. 00298 */ 00299 00300 ISC_LANG_ENDDECLS 00301 00302 #endif /* DNS_JOURNAL_H */