static void
usage(void) {
- fprintf(stderr, "Usage: %s [-x] journal\n", progname);
+ fprintf(stderr, "Usage: %s [-dux] journal\n", progname);
exit(1);
}
isc_log_t *lctx = NULL;
uint32_t flags = 0U;
char ch;
+ bool downgrade = false;
+ bool upgrade = false;
progname = argv[0];
- while ((ch = isc_commandline_parse(argc, argv, "x")) != -1) {
+ while ((ch = isc_commandline_parse(argc, argv, "dux")) != -1) {
switch (ch) {
+ case 'd':
+ downgrade = true;
+ break;
+ case 'u':
+ upgrade = true;
+ break;
case 'x':
flags |= DNS_JOURNAL_PRINTXHDR;
break;
isc_mem_create(&mctx);
RUNTIME_CHECK(setup_logging(mctx, stderr, &lctx) == ISC_R_SUCCESS);
- result = dns_journal_print(mctx, flags, file, stdout);
- if (result == DNS_R_NOJOURNAL) {
- fprintf(stderr, "%s\n", dns_result_totext(result));
+ if (upgrade) {
+ flags = DNS_JOURNAL_COMPACTALL;
+ result = dns_journal_compact(mctx, file, 0, flags, 0);
+ } else if (downgrade) {
+ flags = DNS_JOURNAL_COMPACTALL | DNS_JOURNAL_VERSION1;
+ result = dns_journal_compact(mctx, file, 0, flags, 0);
+ } else {
+ result = dns_journal_print(mctx, flags, file, stdout);
+ if (result == DNS_R_NOJOURNAL) {
+ fprintf(stderr, "%s\n", dns_result_totext(result));
+ }
}
isc_log_destroy(&lctx);
isc_mem_detach(&mctx);
Synopsis
~~~~~~~~
-:program:`named-journalprint` [**-x**] {journal}
+:program:`named-journalprint` [**-dux**] {journal}
Description
~~~~~~~~~~~
-``named-journalprint`` prints the contents of a zone journal file in a
-human-readable form.
+``named-journalprint`` scans the contents of a zone journal file,
+printing it in a human-readable form, or, optionally, converting it
+to a different journal file format.
Journal files are automatically created by ``named`` when changes are
made to dynamic zones (e.g., by ``nsupdate``). They record each addition
to indicate whether the record was added or deleted, and continues with
the resource record in master-file format.
-The ``-x`` option causes additional information about the transaction
-header to be printed before each group of changes.
+The ``-x`` option causes additional data about the journal file to be
+printed at the beginning of the output and before each group of changes.
+
+The ``-u`` (upgrade) and ``-d`` (downgrade) options recreate the journal
+file with a modified format version. The existing journal file is
+replaced. ``-d`` writes out the journal in the format used by
+versions of BIND up to 9.16.11; ``-u`` writes it out in the format used
+by versions since 9.16.13. (9.16.12 is omitted due to a journal-formatting
+bug in that release.) Note that these options *must not* be used while
+``named`` is running.
See Also
~~~~~~~~
..
.SH SYNOPSIS
.sp
-\fBnamed\-journalprint\fP [\fB\-x\fP] {journal}
+\fBnamed\-journalprint\fP [\fB\-dux\fP] {journal}
.SH DESCRIPTION
.sp
-\fBnamed\-journalprint\fP prints the contents of a zone journal file in a
-human\-readable form.
+\fBnamed\-journalprint\fP scans the contents of a zone journal file,
+printing it in a human\-readable form, or, optionally, converting it
+to a different journal file format.
.sp
Journal files are automatically created by \fBnamed\fP when changes are
made to dynamic zones (e.g., by \fBnsupdate\fP). They record each addition
to indicate whether the record was added or deleted, and continues with
the resource record in master\-file format.
.sp
-The \fB\-x\fP option causes additional information about the transaction
-header to be printed before each group of changes.
+The \fB\-x\fP option causes additional data about the journal file to be
+printed at the beginning of the output and before each group of changes.
+.sp
+The \fB\-u\fP (upgrade) and \fB\-d\fP (downgrade) options recreate the journal
+file with a modified format version. The existing journal file is
+replaced. \fB\-d\fP writes out the journal in the format used by
+versions of BIND up to 9.16.11; \fB\-u\fP writes it out in the format used
+by versions since 9.16.13. (9.16.12 is omitted due to a journal\-formatting
+bug in that release.) Note that these options \fImust not\fP be used while
+\fBnamed\fP is running.
.SH SEE ALSO
.sp
\fBnamed(8)\fP, \fBnsupdate(1)\fP, BIND 9 Administrator Reference Manual.
static isc_result_t
journal_write_xhdr(dns_journal_t *j, uint32_t size, uint32_t count,
uint32_t serial0, uint32_t serial1) {
- journal_rawxhdr_t raw;
-
- encode_uint32(size, raw.size);
- encode_uint32(count, raw.count);
- encode_uint32(serial0, raw.serial0);
- encode_uint32(serial1, raw.serial1);
- return (journal_write(j, &raw, sizeof(raw)));
+ if (j->header_ver1) {
+ journal_rawxhdr_ver1_t raw;
+ encode_uint32(size, raw.size);
+ encode_uint32(serial0, raw.serial0);
+ encode_uint32(serial1, raw.serial1);
+ return (journal_write(j, &raw, sizeof(raw)));
+ } else {
+ journal_rawxhdr_t raw;
+ encode_uint32(size, raw.size);
+ encode_uint32(count, raw.count);
+ encode_uint32(serial0, raw.serial0);
+ encode_uint32(serial1, raw.serial1);
+ return (journal_write(j, &raw, sizeof(raw)));
+ }
}
/*
}
static isc_result_t
-journal_file_create(isc_mem_t *mctx, const char *filename) {
+journal_file_create(isc_mem_t *mctx, bool downgrade, const char *filename) {
FILE *fp = NULL;
isc_result_t result;
journal_header_t header;
return (ISC_R_UNEXPECTED);
}
- header = initial_journal_header;
+ if (downgrade) {
+ header = journal_header_ver1;
+ } else {
+ header = initial_journal_header;
+ }
header.index_size = index_size;
journal_header_encode(&header, &rawheader);
static isc_result_t
journal_open(isc_mem_t *mctx, const char *filename, bool writable, bool create,
- dns_journal_t **journalp) {
+ bool downgrade, dns_journal_t **journalp) {
FILE *fp = NULL;
isc_result_t result;
journal_rawheader_t rawheader;
"journal file %s does not exist, "
"creating it",
j->filename);
- CHECK(journal_file_create(mctx, filename));
+ CHECK(journal_file_create(mctx, downgrade, filename));
/*
* Retry.
*/
create = ((mode & DNS_JOURNAL_CREATE) != 0);
writable = ((mode & (DNS_JOURNAL_WRITE | DNS_JOURNAL_CREATE)) != 0);
- result = journal_open(mctx, filename, writable, create, journalp);
+ result = journal_open(mctx, filename, writable, create, false,
+ journalp);
if (result == ISC_R_NOTFOUND) {
namelen = strlen(filename);
if (namelen > 4U && strcmp(filename + namelen - 4, ".jnl") == 0)
if (result >= sizeof(backup)) {
return (ISC_R_NOSPACE);
}
- result = journal_open(mctx, backup, writable, writable,
+ result = journal_open(mctx, backup, writable, writable, false,
journalp);
}
return (result);
return (result);
}
+ if (printxhdr) {
+ fprintf(file, "Journal format = %sHeader version = %d\n",
+ j->header.format + 1, j->header_ver1 ? 1 : 2);
+ }
if (j->header.serialset) {
fprintf(file, "Source serial = %u\n", j->header.sourceserial);
}
char backup[PATH_MAX];
bool is_backup = false;
bool rewrite = false;
+ bool downgrade = false;
REQUIRE(filename != NULL);
filename);
RUNTIME_CHECK(result < sizeof(backup));
- result = journal_open(mctx, filename, false, false, &j1);
+ result = journal_open(mctx, filename, false, false, false, &j1);
if (result == ISC_R_NOTFOUND) {
is_backup = true;
- result = journal_open(mctx, backup, false, false, &j1);
+ result = journal_open(mctx, backup, false, false, false, &j1);
}
if (result != ISC_R_SUCCESS) {
return (result);
* file (for example, to upversion it).
*/
if ((flags & DNS_JOURNAL_COMPACTALL) != 0) {
+ if ((flags & DNS_JOURNAL_VERSION1) != 0) {
+ downgrade = true;
+ }
rewrite = true;
serial = dns_journal_first_serial(j1);
} else if (JOURNAL_EMPTY(&j1->header)) {
return (ISC_R_SUCCESS);
}
- CHECK(journal_open(mctx, newname, true, true, &j2));
+ CHECK(journal_open(mctx, newname, true, true, downgrade, &j2));
CHECK(journal_seek(j2, indexend));
/*