Commit fb30a035 authored by Libor Peltan's avatar Libor Peltan

zone/journal: zone-in-journal implemented (as an option for now)...

 - including the changes in ixfr-from-differences, better handling unchanged SOA
 - breaking the tests-extra/zone/reload test because it tries changed zone with unchanged SOA
parent 042416c3
......@@ -924,6 +924,7 @@ zone:
semantic\-checks: BOOL
disable\-any: BOOL
zonefile\-sync: TIME
zone\-in\-journal: BOOL
ixfr\-from\-differences: BOOL
max\-journal\-usage: SIZE
max\-journal\-depth: INT
......@@ -1090,6 +1091,28 @@ Otherwise the journal can\(aqt be applied.
.UNINDENT
.sp
\fIDefault:\fP 0 (immediate)
.SS zone\-in\-journal
.sp
If enabled, the server stores the zone file contents in journal. When starting server,
the zone is loaded preferably from journal, the changes from zone file are applied
afterwards.
.sp
\fBNOTE:\fP
.INDENT 0.0
.INDENT 3.5
Implies \fI\%ixfr\-from\-differences\fP\&.
.UNINDENT
.UNINDENT
.sp
\fBWARNING:\fP
.INDENT 0.0
.INDENT 3.5
If you modify the zone file, expecting the changes to be applied to the zone,
you shall set the SOA serial significatnly higher than current zone serial.
.UNINDENT
.UNINDENT
.sp
\fIDefault:\fP off
.SS ixfr\-from\-differences
.sp
If enabled, the server creates zone differences from changes you made to the
......
......@@ -1059,6 +1059,7 @@ Definition of zones served by the server.
semantic-checks: BOOL
disable-any: BOOL
zonefile-sync: TIME
zone-in-journal: BOOL
ixfr-from-differences: BOOL
max-journal-usage: SIZE
max-journal-depth: INT
......@@ -1232,6 +1233,24 @@ using the ``-f`` option.
*Default:* 0 (immediate)
.. _zone_zone-in-journal:
zone-in-journal
---------------
If enabled, the server stores the zone file contents in journal. When starting server,
the zone is loaded preferably from journal, the changes from zone file are applied
afterwards.
.. NOTE::
Implies :ref:`ixfr-from-differences<zone_ixfr-from-differences>`.
.. WARNING::
If you modify the zone file, expecting the changes to be applied to the zone,
you shall set the SOA serial significatnly higher than current zone serial.
*Default:* off
.. _zone_ixfr-from-differences:
ixfr-from-differences
......
......@@ -260,6 +260,7 @@ static const yp_item_t desc_policy[] = {
{ C_SEM_CHECKS, YP_TBOOL, YP_VNONE, FLAGS }, \
{ C_DISABLE_ANY, YP_TBOOL, YP_VNONE }, \
{ C_ZONEFILE_SYNC, YP_TINT, YP_VINT = { -1, INT32_MAX, 0, YP_STIME } }, \
{ C_ZONE_IN_JOURNAL, YP_TBOOL, YP_VNONE }, \
{ C_IXFR_DIFF, YP_TBOOL, YP_VNONE }, \
{ C_MAX_ZONE_SIZE, YP_TINT, YP_VINT = { 0, INT64_MAX, INT64_MAX, YP_SSIZE }, FLAGS }, \
{ C_MAX_JOURNAL_USAGE, YP_TINT, YP_VINT = { KILO(40), INT64_MAX, MEGA(100), YP_SSIZE } }, \
......
......@@ -124,6 +124,7 @@
#define C_VERSION "\x07""version"
#define C_VIA "\x03""via"
#define C_ZONE "\x04""zone"
#define C_ZONE_IN_JOURNAL "\x0F""zone-in-journal"
#define C_ZONEFILE_SYNC "\x0D""zonefile-sync"
#define C_ZSK_LIFETIME "\x0C""zsk-lifetime"
#define C_ZSK_SIZE "\x08""zsk-size"
......
......@@ -23,6 +23,7 @@
#include "knot/events/handlers.h"
#include "knot/events/log.h"
#include "knot/events/replan.h"
#include "knot/zone/zone-diff.h"
#include "knot/zone/zone-load.h"
#include "knot/zone/zone.h"
#include "knot/zone/zonefile.h"
......@@ -56,18 +57,25 @@ int event_load(conf_t *conf, zone_t *zone)
conf_val_t val;
zone_contents_t *contents = NULL;
bool load_from_journal = false;
bool contents_in_update = true;
zone_sign_reschedule_t dnssec_refresh = { 0 };
dnssec_refresh.allow_rollover = true;
/* Take zone file mtime and load it. */
time_t mtime;
char *filename = conf_zonefile(conf, zone->name);
int ret = zonefile_exists(filename, &mtime);
bool load_from_journal = (ret != KNOT_EOK);
free(filename);
if (ret != KNOT_EOK) {
load_from_journal = true;
bool load_journal_first = false;
bool loaded_from_journal = false;
if (zone->contents == NULL) {
conf_val_t val = conf_zone_get(conf, C_ZONE_IN_JOURNAL, zone->name);
load_journal_first = conf_bool(&val);
}
if (load_from_journal) {
ret = zone_load_from_journal(conf, zone, &contents);
if (ret != KNOT_EOK) {
if (zone_load_can_bootstrap(conf, zone->name)) {
......@@ -78,6 +86,15 @@ int event_load(conf_t *conf, zone_t *zone)
goto fail;
}
goto load_post;
} else if (load_journal_first) {
ret = zone_load_from_journal(conf, zone, &contents);
if (ret != KNOT_EOK && ret != KNOT_ENOENT) {
goto fail;
}
loaded_from_journal = (ret == KNOT_EOK);
if (loaded_from_journal) {
goto load_post;
}
}
ret = zone_load_contents(conf, zone->name, &contents);
......@@ -85,6 +102,14 @@ int event_load(conf_t *conf, zone_t *zone)
goto fail;
}
if (load_journal_first && !loaded_from_journal) {
ret = zone_in_journal_store(conf, zone, contents);
if (ret != KNOT_EOK) {
log_zone_warning(zone->name, "failed to write zone-in-journal (%s)",
knot_strerror(ret));
}
}
/* Store the zonefile SOA serial. */
zone->zonefile.serial = zone_contents_serial(contents);
......@@ -105,6 +130,10 @@ load_post:
bool dnssec_enable = conf_bool(&val);
val = conf_zone_get(conf, C_IXFR_DIFF, zone->name);
bool build_diffs = conf_bool(&val);
if (!build_diffs) {
val = conf_zone_get(conf, C_ZONE_IN_JOURNAL, zone->name);
build_diffs = conf_bool(&val);
}
bool old_contents = (zone->contents != NULL);
const bool contents_changed = old_contents && (contents != zone->contents);
......@@ -114,8 +143,8 @@ load_post:
if (old_contents) {
if (build_diffs && contents_changed) {
ret = zone_update_from_differences(&post_load, zone, contents, UPDATE_INCREMENTAL);
if (ret == KNOT_ERANGE || ret == KNOT_ENODIFF) {
log_zone_warning(zone->name, (ret == KNOT_ENODIFF ?
if (ret == KNOT_ERANGE || ret == KNOT_ESEMCHECK) {
log_zone_warning(zone->name, (ret == KNOT_ESEMCHECK ?
"failed to create journal entry, zone file changed without "
"SOA serial update" : "IXFR history will be lost, "
"zone file changed, but SOA serial decreased"));
......@@ -184,6 +213,11 @@ load_post:
zone_events_schedule_now(zone, ZONE_EVENT_NOTIFY);
}
if (loaded_from_journal) {
// this enforces further load from zone file and applying ixfr from diff
zone_events_schedule_now(zone, ZONE_EVENT_LOAD);
}
return KNOT_EOK;
fail:
......
......@@ -352,17 +352,26 @@ int zone_contents_diff(const zone_contents_t *zone1, const zone_contents_t *zone
return KNOT_EINVAL;
}
int ret = load_soas(zone1, zone2, changeset);
int ret_soa = load_soas(zone1, zone2, changeset);
if (ret_soa != KNOT_EOK && ret_soa != KNOT_ENODIFF) {
return ret_soa;
}
int ret = load_trees(zone1->nodes, zone2->nodes, changeset);
if (ret != KNOT_EOK) {
return ret;
}
ret = load_trees(zone1->nodes, zone2->nodes, changeset);
ret = load_trees(zone1->nsec3_nodes, zone2->nsec3_nodes, changeset);
if (ret != KNOT_EOK) {
return ret;
}
return load_trees(zone1->nsec3_nodes, zone2->nsec3_nodes, changeset);
if (ret_soa == KNOT_ENODIFF && !changeset_empty(changeset)) {
return KNOT_ESEMCHECK;
}
return ret_soa;
}
int zone_tree_add_diff(zone_tree_t *t1, zone_tree_t *t2, changeset_t *changeset)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment