#include <isc/log.h>
#include <isc/mem.h>
#include <isc/result.h>
+#include <isc/serial.h>
#include <isc/util.h>
#include <dns/db.h>
return result;
}
+static isc_result_t
+loadjournal(dns_db_t *db, const char *file) {
+ dns_journal_t *jnl = NULL;
+ isc_result_t result;
+
+ result = dns_journal_open(mctx, file, DNS_JOURNAL_READ, &jnl);
+ if (result == ISC_R_NOTFOUND) {
+ return ISC_R_SUCCESS;
+ } else if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "Error: unable to open journal %s: %s\n", file,
+ isc_result_totext(result));
+ return result;
+ }
+
+ if (dns_journal_empty(jnl)) {
+ dns_journal_destroy(&jnl);
+ return ISC_R_SUCCESS;
+ }
+
+ result = dns_journal_rollforward(jnl, db, 0);
+ switch (result) {
+ case ISC_R_SUCCESS:
+ break;
+ case DNS_R_UPTODATE:
+ result = ISC_R_SUCCESS;
+ break;
+
+ case ISC_R_NOTFOUND:
+ case ISC_R_RANGE:
+ fprintf(stderr, "Error: journal %s out of sync with zone",
+ file);
+ break;
+
+ default:
+ fprintf(stderr, "Error: journal %s: %s\n", file,
+ isc_result_totext(result));
+ }
+
+ dns_journal_destroy(&jnl);
+ return result;
+}
+
int
main(int argc, char **argv) {
isc_result_t result;
const char *journal = NULL;
dns_db_t *olddb = NULL, *newdb = NULL;
isc_logconfig_t *logconfig = NULL;
+ uint32_t s1, s2, s3;
int ch;
isc_commandline_init(argc, argv);
goto cleanup;
}
- uint32_t s1, s2;
result = dns_db_getsoaserial(olddb, NULL, &s1);
if (result != ISC_R_SUCCESS) {
- fprintf(stderr, "Error: no SOA found in %s\n", file1);
+ fprintf(stderr, "Error: %s: SOA lookup failed\n", file1);
goto cleanup;
}
- result = dns_db_getsoaserial(newdb, NULL, &s2);
+
+ result = loadjournal(olddb, journal);
if (result != ISC_R_SUCCESS) {
- fprintf(stderr, "Error: no SOA found in %s\n", file2);
goto cleanup;
}
- if (s1 == s2) {
+
+ result = dns_db_getsoaserial(olddb, NULL, &s2);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
+
+ result = dns_db_getsoaserial(newdb, NULL, &s3);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "Error: %s: SOA lookup failed\n", file2);
+ goto cleanup;
+ }
+
+ if (isc_serial_eq(s1, s3)) {
fprintf(stderr,
"Error: SOA serial (%u) unchanged between files\n", s1);
result = ISC_R_FAILURE;
goto cleanup;
+ } else if (isc_serial_eq(s2, s3)) {
+ fprintf(stderr, "Journal %s already has serial %u\n", journal,
+ s3);
+ goto cleanup;
}
result = dns_db_diff(mctx, newdb, NULL, olddb, NULL, journal);
isc_mem_detach(&mctx);
}
- return result != ISC_R_SUCCESS ? 1 : 0;
+ return (result != ISC_R_SUCCESS) ? 1 : 0;
}
file name will be formed by appending the extension ``.jnl`` to the
zone file name specified as ``oldfile``.
-If the journal file already exists, a new transaction will be appended
-onto the end of it. (Note, however, that the most recent serial number in
-the existing journal file must match the serial number in ``oldfile``.
-This will be corrected later.)
+If the journal file already exists, then it will be applied to ``oldfile``
+immediately after loading. The difference between the resulting zone and
+the one in ``newfile`` will then be appended onto the end of the journal.
+This allows creation of journal files with multiple transactions, by
+running ``named-makejournal`` multiple times, updating ``newfile`` each
+time.
Options
~~~~~~~