1 /* $NetBSD: journal.h,v 1.5 2014/12/10 04:37:58 christos Exp $ */ 2 3 /* 4 * Copyright (C) 2004-2009, 2011, 2013 Internet Systems Consortium, Inc. ("ISC") 5 * Copyright (C) 1999-2001 Internet Software Consortium. 6 * 7 * Permission to use, copy, modify, and/or distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 13 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 16 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 /* Id: journal.h,v 1.43 2011/12/22 07:32:41 each Exp */ 21 22 #ifndef DNS_JOURNAL_H 23 #define DNS_JOURNAL_H 1 24 25 /***** 26 ***** Module Info 27 *****/ 28 29 /*! \file dns/journal.h 30 * \brief 31 * Database journaling. 32 */ 33 34 /*** 35 *** Imports 36 ***/ 37 38 #include <isc/lang.h> 39 #include <isc/magic.h> 40 41 #include <dns/name.h> 42 #include <dns/diff.h> 43 #include <dns/rdata.h> 44 #include <dns/types.h> 45 46 /*** 47 *** Defines. 48 ***/ 49 #define DNS_JOURNALOPT_RESIGN 0x00000001 50 51 #define DNS_JOURNAL_READ 0x00000000 /* ISC_FALSE */ 52 #define DNS_JOURNAL_CREATE 0x00000001 /* ISC_TRUE */ 53 #define DNS_JOURNAL_WRITE 0x00000002 54 55 /*** 56 *** Types 57 ***/ 58 59 /*% 60 * A dns_journal_t represents an open journal file. This is an opaque type. 61 * 62 * A particular dns_journal_t object may be opened for writing, in which case 63 * it can be used for writing transactions to a journal file, or it can be 64 * opened for reading, in which case it can be used for reading transactions 65 * from (iterating over) a journal file. A single dns_journal_t object may 66 * not be used for both purposes. 67 */ 68 typedef struct dns_journal dns_journal_t; 69 70 71 /*** 72 *** Functions 73 ***/ 74 75 ISC_LANG_BEGINDECLS 76 77 /**************************************************************************/ 78 79 isc_result_t 80 dns_db_createsoatuple(dns_db_t *db, dns_dbversion_t *ver, isc_mem_t *mctx, 81 dns_diffop_t op, dns_difftuple_t **tp); 82 /*!< brief 83 * Create a diff tuple for the current database SOA. 84 * XXX this probably belongs somewhere else. 85 */ 86 87 88 /*@{*/ 89 #define DNS_SERIAL_GT(a, b) ((int)(((a) - (b)) & 0xFFFFFFFF) > 0) 90 #define DNS_SERIAL_GE(a, b) ((int)(((a) - (b)) & 0xFFFFFFFF) >= 0) 91 /*!< brief 92 * Compare SOA serial numbers. DNS_SERIAL_GT(a, b) returns true iff 93 * a is "greater than" b where "greater than" is as defined in RFC1982. 94 * DNS_SERIAL_GE(a, b) returns true iff a is "greater than or equal to" b. 95 */ 96 /*@}*/ 97 98 /**************************************************************************/ 99 /* 100 * Journal object creation and destruction. 101 */ 102 103 isc_result_t 104 dns_journal_open(isc_mem_t *mctx, const char *filename, unsigned int mode, 105 dns_journal_t **journalp); 106 /*%< 107 * Open the journal file 'filename' and create a dns_journal_t object for it. 108 * 109 * DNS_JOURNAL_CREATE open the journal for reading and writing and create 110 * the journal if it does not exist. 111 * DNS_JOURNAL_WRITE open the journal for reading and writing. 112 * DNS_JOURNAL_READ open the journal for reading only. 113 */ 114 115 void 116 dns_journal_destroy(dns_journal_t **journalp); 117 /*%< 118 * Destroy a dns_journal_t, closing any open files and freeing its memory. 119 */ 120 121 /**************************************************************************/ 122 /* 123 * Writing transactions to journals. 124 */ 125 126 isc_result_t 127 dns_journal_begin_transaction(dns_journal_t *j); 128 /*%< 129 * Prepare to write a new transaction to the open journal file 'j'. 130 * 131 * Requires: 132 * \li 'j' is open for writing. 133 */ 134 135 isc_result_t 136 dns_journal_writediff(dns_journal_t *j, dns_diff_t *diff); 137 /*%< 138 * Write 'diff' to the current transaction of journal file 'j'. 139 * 140 * Requires: 141 * \li 'j' is open for writing and dns_journal_begin_transaction() 142 * has been called. 143 * 144 *\li 'diff' is a full or partial, correctly ordered IXFR 145 * difference sequence. 146 */ 147 148 isc_result_t 149 dns_journal_commit(dns_journal_t *j); 150 /*%< 151 * Commit the current transaction of journal file 'j'. 152 * 153 * Requires: 154 * \li 'j' is open for writing and dns_journal_begin_transaction() 155 * has been called. 156 * 157 * \li dns_journal_writediff() has been called one or more times 158 * to form a complete, correctly ordered IXFR difference 159 * sequence. 160 */ 161 162 isc_result_t 163 dns_journal_write_transaction(dns_journal_t *j, dns_diff_t *diff); 164 /*% 165 * Write a complete transaction at once to a journal file, 166 * sorting it if necessary, and commit it. Equivalent to calling 167 * dns_diff_sort(), dns_journal_begin_transaction(), 168 * dns_journal_writediff(), and dns_journal_commit(). 169 * 170 * Requires: 171 *\li 'j' is open for writing. 172 * 173 * \li 'diff' contains exactly one SOA deletion, one SOA addition 174 * with a greater serial number, and possibly other changes, 175 * in arbitrary order. 176 */ 177 178 /**************************************************************************/ 179 /* 180 * Reading transactions from journals. 181 */ 182 183 isc_uint32_t 184 dns_journal_first_serial(dns_journal_t *j); 185 isc_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, 193 isc_uint32_t begin_serial, isc_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, isc_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, 265 dns_db_t *dba, dns_dbversion_t *dbvera, 266 dns_db_t *dbb, dns_dbversion_t *dbverb, 267 const char *journal_filename); 268 269 isc_result_t 270 dns_db_diffx(dns_diff_t *diff, dns_db_t *dba, dns_dbversion_t *dbvera, 271 dns_db_t *dbb, dns_dbversion_t *dbverb, 272 const char *journal_filename); 273 /*%< 274 * Compare the databases 'dba' and 'dbb' and generate a diff/journal 275 * entry containing the changes to make 'dba' from 'dbb' (note 276 * the order). This journal entry will consist of a single, 277 * possibly very large transaction. Append the journal 278 * entry to the journal file specified by 'journal_filename' if 279 * non-NULL. 280 */ 281 282 isc_result_t 283 dns_journal_compact(isc_mem_t *mctx, char *filename, isc_uint32_t serial, 284 isc_uint32_t target_size); 285 /*%< 286 * Attempt to compact the journal if it is greater that 'target_size'. 287 * Changes from 'serial' onwards will be preserved. If the journal 288 * exists and is non-empty 'serial' must exist in the journal. 289 */ 290 291 isc_boolean_t 292 dns_journal_get_sourceserial(dns_journal_t *j, isc_uint32_t *sourceserial); 293 void 294 dns_journal_set_sourceserial(dns_journal_t *j, isc_uint32_t sourceserial); 295 /*%< 296 * Get and set source serial. 297 * 298 * Returns: 299 * ISC_TRUE if sourceserial has previously been set. 300 */ 301 302 ISC_LANG_ENDDECLS 303 304 #endif /* DNS_JOURNAL_H */ 305