Commit f8cd4fec authored by Libor Peltan's avatar Libor Peltan Committed by Daniel Salzman

load: implemented option loading diff from ZF ignoring serial

parent 5620e738
......@@ -982,7 +982,7 @@ zone:
semantic\-checks: BOOL
disable\-any: BOOL
zonefile\-sync: TIME
zonefile\-load: none | difference | whole
zonefile\-load: none | difference | difference\-no\-serial | whole
journal\-content: none | changes | all
max\-journal\-usage: SIZE
max\-journal\-depth: INT
......@@ -1141,8 +1141,11 @@ Possible values:
.IP \(bu 2
\fBnone\fP – The zonefile is not used at all.
.IP \(bu 2
\fBdifference\fP – If the zone contents are available during server start or reload,
the difference is computed between them and the zonefile, checked and applied afterwards.
\fBdifference\fP – If the zone contents is available during server start or reload,
the difference is computed between them and the zonefile, checked, and applied afterwards.
.IP \(bu 2
\fBdifference\-no\-serial\fP – Same as \fBdifference\fP, but the SOA serial in the zonefile is
ignored, the server takes care of incrementing the serial automatically.
.IP \(bu 2
\fBwhole\fP – Zone contents are loaded from zonefile.
.UNINDENT
......
......@@ -1113,7 +1113,7 @@ Definition of zones served by the server.
semantic-checks: BOOL
disable-any: BOOL
zonefile-sync: TIME
zonefile-load: none | difference | whole
zonefile-load: none | difference | difference-no-serial | whole
journal-content: none | changes | all
max-journal-usage: SIZE
max-journal-depth: INT
......@@ -1288,8 +1288,10 @@ Selects how the zonefile contents are applied during zone load.
Possible values:
- ``none`` – The zonefile is not used at all.
- ``difference`` – If the zone contents are available during server start or reload,
the difference is computed between them and the zonefile, checked and applied afterwards.
- ``difference`` – If the zone contents is available during server start or reload,
the difference is computed between them and the zonefile, checked, and applied afterwards.
- ``difference-no-serial`` – Same as ``difference``, but the SOA serial in the zonefile is
ignored, the server takes care of incrementing the serial automatically.
- ``whole`` – Zone contents are loaded from zonefile.
When ``difference`` is configured and there are no zone contents yet (cold start of Knot
......
......@@ -103,6 +103,7 @@ static const knot_lookup_t journal_content[] = {
static const knot_lookup_t zonefile_load[] = {
{ ZONEFILE_LOAD_NONE, "none" },
{ ZONEFILE_LOAD_DIFF, "difference" },
{ ZONEFILE_LOAD_DIFSE, "difference-no-serial" },
{ ZONEFILE_LOAD_WHOLE, "whole" },
{ 0, NULL }
};
......
......@@ -145,6 +145,7 @@ enum {
ZONEFILE_LOAD_NONE = 0,
ZONEFILE_LOAD_DIFF = 1,
ZONEFILE_LOAD_WHOLE = 2,
ZONEFILE_LOAD_DIFSE = 3,
};
extern const knot_lookup_t acl_actions[];
......
......@@ -95,6 +95,17 @@ int event_load(conf_t *conf, zone_t *zone)
}
goto cleanup;
}
// If configured and possible, fix the SOA serial of zonefile.
if (zf_conts != NULL && zf_from == ZONEFILE_LOAD_DIFSE) {
zone_contents_t *relevant = (zone->contents != NULL ? zone->contents : journal_conts);
if (relevant != NULL) {
uint32_t serial = zone_contents_serial(relevant);
conf_val_t policy = conf_zone_get(conf, C_SERIAL_POLICY, zone->name);
zone_contents_set_soa_serial(zf_conts, serial_next(serial, conf_opt(&policy)));
}
}
// If configured and appliable to zonefile, load journal changes.
zone->zonefile.serial = zone_contents_serial(zf_conts);
zone->zonefile.exists = (zf_conts != NULL);
......@@ -201,6 +212,17 @@ int event_load(conf_t *conf, zone_t *zone)
zf_conts = NULL;
journal_conts = NULL;
// If the change is only automatically incremented SOA serial, make it no change.
if (zf_from == ZONEFILE_LOAD_DIFSE && (up.flags & UPDATE_INCREMENTAL) &&
changeset_differs_just_serial(&up.change)) {
uint32_t orig_ser = knot_soa_serial(&up.change.soa_from->rrs);
ret = changeset_remove_addition(&up.change, up.change.soa_to);
zone_contents_set_soa_serial(up.new_cont, orig_ser);
if (ret != KNOT_EOK) {
goto cleanup;
}
}
// Sign zone using DNSSEC if configured.
zone_sign_reschedule_t dnssec_refresh = { .allow_rollover = true, .allow_nsec3resalt = true, };
if (dnssec_enable) {
......
......@@ -531,6 +531,25 @@ int changeset_cancelout(changeset_t *ch)
return ret;
}
bool changeset_differs_just_serial(const changeset_t *ch)
{
if (ch == NULL || ch->soa_from == NULL || ch->soa_to == NULL) {
return false;
}
if (!zone_contents_is_empty(ch->remove) || !zone_contents_is_empty(ch->add)) {
return false;
}
knot_rrset_t *soa_to_cpy = knot_rrset_copy(ch->soa_to, NULL);
knot_soa_serial_set(&soa_to_cpy->rrs, knot_soa_serial(&ch->soa_from->rrs));
bool res = knot_rrset_equal(ch->soa_from, soa_to_cpy, KNOT_RRSET_COMPARE_WHOLE);
knot_rrset_free(soa_to_cpy, NULL);
return res;
}
int changeset_to_contents(changeset_t *ch, zone_contents_t **out)
{
assert(ch->soa_from == NULL);
......
......@@ -158,6 +158,16 @@ int changeset_preapply_fix(const zone_contents_t *zone, changeset_t *ch);
*/
int changeset_cancelout(changeset_t *ch);
/*!
* \brief Check the changes and SOA, ignoring possibly updated SOA serial.
*
* \param ch Changeset in question.
*
* \return false if the changeset changes other records than SOA, or some SOA field other than serial changed
* true otherwise
*/
bool changeset_differs_just_serial(const changeset_t *ch);
/*!
* \brief Loads zone contents from botstrap 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