1 /* 2 * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 3 * 4 * This Source Code Form is subject to the terms of the Mozilla Public 5 * License, v. 2.0. If a copy of the MPL was not distributed with this 6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 * 8 * See the COPYRIGHT file distributed with this work for additional 9 * information regarding copyright ownership. 10 */ 11 12 #ifndef DNS_JOURNAL_H 13 #define DNS_JOURNAL_H 1 14 15 /***** 16 ***** Module Info 17 *****/ 18 19 /*! \file dns/journal.h 20 * \brief 21 * Database journaling. 22 */ 23 24 /*** 25 *** Imports 26 ***/ 27 28 #include <inttypes.h> 29 #include <stdbool.h> 30 31 #include <isc/lang.h> 32 #include <isc/magic.h> 33 34 #include <dns/diff.h> 35 #include <dns/name.h> 36 #include <dns/rdata.h> 37 #include <dns/types.h> 38 39 /*** 40 *** Defines. 41 ***/ 42 #define DNS_JOURNALOPT_RESIGN 0x00000001 43 44 #define DNS_JOURNAL_READ 0x00000000 /* false */ 45 #define DNS_JOURNAL_CREATE 0x00000001 /* true */ 46 #define DNS_JOURNAL_WRITE 0x00000002 47 48 #define DNS_JOURNAL_SIZE_MAX INT32_MAX 49 #define DNS_JOURNAL_SIZE_MIN 4096 50 51 /*** 52 *** Types 53 ***/ 54 55 /*% 56 * A dns_journal_t represents an open journal file. This is an opaque type. 57 * 58 * A particular dns_journal_t object may be opened for writing, in which case 59 * it can be used for writing transactions to a journal file, or it can be 60 * opened for reading, in which case it can be used for reading transactions 61 * from (iterating over) a journal file. A single dns_journal_t object may 62 * not be used for both purposes. 63 */ 64 typedef struct dns_journal dns_journal_t; 65 66 /*** 67 *** Functions 68 ***/ 69 70 ISC_LANG_BEGINDECLS 71 72 /**************************************************************************/ 73 74 isc_result_t 75 dns_db_createsoatuple(dns_db_t *db, dns_dbversion_t *ver, isc_mem_t *mctx, 76 dns_diffop_t op, dns_difftuple_t **tp); 77 /*!< brief 78 * Create a diff tuple for the current database SOA. 79 * XXX this probably belongs somewhere else. 80 */ 81 82 /*@{*/ 83 #define DNS_SERIAL_GT(a, b) ((int)(((a) - (b)) & 0xFFFFFFFF) > 0) 84 #define DNS_SERIAL_GE(a, b) ((int)(((a) - (b)) & 0xFFFFFFFF) >= 0) 85 /*!< brief 86 * Compare SOA serial numbers. DNS_SERIAL_GT(a, b) returns true iff 87 * a is "greater than" b where "greater than" is as defined in RFC1982. 88 * DNS_SERIAL_GE(a, b) returns true iff a is "greater than or equal to" b. 89 */ 90 /*@}*/ 91 92 /**************************************************************************/ 93 /* 94 * Journal object creation and destruction. 95 */ 96 97 isc_result_t 98 dns_journal_open(isc_mem_t *mctx, const char *filename, unsigned int mode, 99 dns_journal_t **journalp); 100 /*%< 101 * Open the journal file 'filename' and create a dns_journal_t object for it. 102 * 103 * DNS_JOURNAL_CREATE open the journal for reading and writing and create 104 * the journal if it does not exist. 105 * DNS_JOURNAL_WRITE open the journal for reading and writing. 106 * DNS_JOURNAL_READ open the journal for reading only. 107 */ 108 109 void 110 dns_journal_destroy(dns_journal_t **journalp); 111 /*%< 112 * Destroy a dns_journal_t, closing any open files and freeing its memory. 113 */ 114 115 /**************************************************************************/ 116 /* 117 * Writing transactions to journals. 118 */ 119 120 isc_result_t 121 dns_journal_begin_transaction(dns_journal_t *j); 122 /*%< 123 * Prepare to write a new transaction to the open journal file 'j'. 124 * 125 * Requires: 126 * \li 'j' is open for writing. 127 */ 128 129 isc_result_t 130 dns_journal_writediff(dns_journal_t *j, dns_diff_t *diff); 131 /*%< 132 * Write 'diff' to the current transaction of journal file 'j'. 133 * 134 * Requires: 135 * \li 'j' is open for writing and dns_journal_begin_transaction() 136 * has been called. 137 * 138 *\li 'diff' is a full or partial, correctly ordered IXFR 139 * difference sequence. 140 */ 141 142 isc_result_t 143 dns_journal_commit(dns_journal_t *j); 144 /*%< 145 * Commit the current transaction of journal file 'j'. 146 * 147 * Requires: 148 * \li 'j' is open for writing and dns_journal_begin_transaction() 149 * has been called. 150 * 151 * \li dns_journal_writediff() has been called one or more times 152 * to form a complete, correctly ordered IXFR difference 153 * sequence. 154 */ 155 156 isc_result_t 157 dns_journal_write_transaction(dns_journal_t *j, dns_diff_t *diff); 158 /*% 159 * Write a complete transaction at once to a journal file, 160 * sorting it if necessary, and commit it. Equivalent to calling 161 * dns_diff_sort(), dns_journal_begin_transaction(), 162 * dns_journal_writediff(), and dns_journal_commit(). 163 * 164 * Requires: 165 *\li 'j' is open for writing. 166 * 167 * \li 'diff' contains exactly one SOA deletion, one SOA addition 168 * with a greater serial number, and possibly other changes, 169 * in arbitrary order. 170 */ 171 172 /**************************************************************************/ 173 /* 174 * Reading transactions from journals. 175 */ 176 177 bool 178 dns_journal_empty(dns_journal_t *j); 179 /*< 180 * Find out if a journal is empty. 181 */ 182 183 uint32_t 184 dns_journal_first_serial(dns_journal_t *j); 185 uint32_t 186 dns_journal_last_serial(dns_journal_t *j); 187 /*%< 188 * Get the first and last addressable serial number in the journal. 189 */ 190 191 isc_result_t 192 dns_journal_iter_init(dns_journal_t *j, uint32_t begin_serial, 193 uint32_t end_serial); 194 /*%< 195 * Prepare to iterate over the transactions that will bring the database 196 * from SOA serial number 'begin_serial' to 'end_serial'. 197 * 198 * Returns: 199 *\li ISC_R_SUCCESS 200 *\li ISC_R_RANGE begin_serial is outside the addressable range. 201 *\li ISC_R_NOTFOUND begin_serial is within the range of addressable 202 * serial numbers covered by the journal, but 203 * this particular serial number does not exist. 204 */ 205 206 /*@{*/ 207 isc_result_t 208 dns_journal_first_rr(dns_journal_t *j); 209 isc_result_t 210 dns_journal_next_rr(dns_journal_t *j); 211 /*%< 212 * Position the iterator at the first/next RR in a journal 213 * transaction sequence established using dns_journal_iter_init(). 214 * 215 * Requires: 216 * \li dns_journal_iter_init() has been called. 217 * 218 */ 219 /*@}*/ 220 221 void 222 dns_journal_current_rr(dns_journal_t *j, dns_name_t **name, uint32_t *ttl, 223 dns_rdata_t **rdata); 224 /*%< 225 * Get the name, ttl, and rdata of the current journal RR. 226 * 227 * Requires: 228 * \li The last call to dns_journal_first_rr() or dns_journal_next_rr() 229 * returned ISC_R_SUCCESS. 230 */ 231 232 /**************************************************************************/ 233 /* 234 * Database roll-forward. 235 */ 236 237 isc_result_t 238 dns_journal_rollforward(isc_mem_t *mctx, dns_db_t *db, unsigned int options, 239 const char *filename); 240 /*%< 241 * Roll forward (play back) the journal file "filename" into the 242 * database "db". This should be called when the server starts 243 * after a shutdown or crash. 244 * 245 * Requires: 246 *\li 'mctx' is a valid memory context. 247 *\li 'db' is a valid database which does not have a version 248 * open for writing. 249 *\li 'filename' is the name of the journal file belonging to 'db'. 250 * 251 * Returns: 252 *\li DNS_R_NOJOURNAL when journal does not exist. 253 *\li ISC_R_NOTFOUND when current serial in not in journal. 254 *\li ISC_R_RANGE when current serial in not in journals range. 255 *\li ISC_R_SUCCESS journal has been applied successfully to database. 256 * others 257 */ 258 259 isc_result_t 260 dns_journal_print(isc_mem_t *mctx, const char *filename, FILE *file); 261 /* For debugging not general use */ 262 263 isc_result_t 264 dns_db_diff(isc_mem_t *mctx, dns_db_t *dba, dns_dbversion_t *dbvera, 265 dns_db_t *dbb, dns_dbversion_t *dbverb, 266 const char *journal_filename); 267 268 isc_result_t 269 dns_db_diffx(dns_diff_t *diff, dns_db_t *dba, dns_dbversion_t *dbvera, 270 dns_db_t *dbb, dns_dbversion_t *dbverb, 271 const char *journal_filename); 272 /*%< 273 * Compare the databases 'dba' and 'dbb' and generate a diff/journal 274 * entry containing the changes to make 'dba' from 'dbb' (note 275 * the order). This journal entry will consist of a single, 276 * possibly very large transaction. Append the journal 277 * entry to the journal file specified by 'journal_filename' if 278 * non-NULL. 279 */ 280 281 isc_result_t 282 dns_journal_compact(isc_mem_t *mctx, char *filename, uint32_t serial, 283 uint32_t target_size); 284 /*%< 285 * Attempt to compact the journal if it is greater that 'target_size'. 286 * Changes from 'serial' onwards will be preserved. If the journal 287 * exists and is non-empty 'serial' must exist in the journal. 288 */ 289 290 bool 291 dns_journal_get_sourceserial(dns_journal_t *j, uint32_t *sourceserial); 292 void 293 dns_journal_set_sourceserial(dns_journal_t *j, uint32_t sourceserial); 294 /*%< 295 * Get and set source serial. 296 * 297 * Returns: 298 * true if sourceserial has previously been set. 299 */ 300 301 ISC_LANG_ENDDECLS 302 303 #endif /* DNS_JOURNAL_H */ 304