From: Evan Hunt Date: Thu, 6 Feb 2025 07:08:27 +0000 (-0800) Subject: load the journal file if it already exists X-Git-Tag: v9.21.10~51^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=365e4de077168de6b14e732dcb4809731dc53265;p=thirdparty%2Fbind9.git load the journal file if it already exists apply the existing journal file, if any, to the old version of the database before diffing it against the new version. then, append the diff to the end of the journal. this allows easy creation of a journal file with multiple deltas, by running named-makejournal successively. --- diff --git a/bin/tools/named-makejournal.c b/bin/tools/named-makejournal.c index d67c970be90..2c974dc0785 100644 --- a/bin/tools/named-makejournal.c +++ b/bin/tools/named-makejournal.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -67,6 +68,48 @@ loadzone(dns_db_t **db, const char *origin, const char *filename) { 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; @@ -75,6 +118,7 @@ main(int argc, char **argv) { 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); @@ -130,22 +174,35 @@ main(int argc, char **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); @@ -166,5 +223,5 @@ cleanup: isc_mem_detach(&mctx); } - return result != ISC_R_SUCCESS ? 1 : 0; + return (result != ISC_R_SUCCESS) ? 1 : 0; } diff --git a/bin/tools/named-makejournal.rst b/bin/tools/named-makejournal.rst index 1a39a4d8f21..1724d0bfb48 100644 --- a/bin/tools/named-makejournal.rst +++ b/bin/tools/named-makejournal.rst @@ -40,10 +40,12 @@ If the optional argument ``journal`` is not specified, then the journal 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 ~~~~~~~