Skip to content
Snippets Groups Projects
Commit 9063724d authored by Libor Peltan's avatar Libor Peltan Committed by Daniel Salzman
Browse files

catalog: enable catalog update from zone diff

parent 7fc63d71
No related branches found
No related tags found
1 merge request!1412journal: compute serialized changeset directly from bi-nodes...
/* Copyright (C) 2021 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
/* Copyright (C) 2022 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -18,7 +18,7 @@
#include <stdio.h>
#include "knot/catalog/interpret.h"
#include "knot/zone/contents.h"
#include "knot/journal/serialization.h"
struct cat_upd_ctx;
typedef int (*cat_interpret_cb_t)(zone_node_t *node, struct cat_upd_ctx *ctx);
......@@ -28,6 +28,7 @@ typedef struct cat_upd_ctx {
const zone_contents_t *complete_conts;
int apex_labels;
bool remove;
bool zone_diff;
catalog_t *check;
cat_interpret_cb_t member_cb;
cat_interpret_cb_t property_cb;
......@@ -80,19 +81,19 @@ static int interpret_node(zone_node_t *node, void * _ctx)
}
}
static int interpret_zone(const zone_contents_t *zone, cat_upd_ctx_t *ctx)
static int interpret_zone(zone_diff_t *zdiff, cat_upd_ctx_t *ctx)
{
knot_dname_storage_t sub;
if (knot_dname_store(sub, (uint8_t *)CATALOG_ZONES_LABEL) == 0 ||
catalog_dname_append(sub, zone->apex->owner) == 0) {
catalog_dname_append(sub, zdiff->apex->owner) == 0) {
return KNOT_EINVAL;
}
if (zone_contents_find_node(zone, sub) == NULL) {
if (zone_tree_get(&zdiff->nodes, sub) == NULL) {
return KNOT_EOK;
}
return zone_tree_sub_apply(zone->nodes, sub, true, interpret_node, ctx);
return zone_tree_sub_apply(&zdiff->nodes, sub, true, interpret_node, ctx);
}
static const knot_dname_t *property_get_member(const zone_node_t *prop_node,
......@@ -127,6 +128,11 @@ static int cat_update_add_memb(zone_node_t *node, cat_upd_ctx_t *ctx)
return KNOT_ERROR;
}
const knot_rdataset_t *counter_ptr = node_rdataset(binode_counterpart(node), KNOT_RRTYPE_PTR);
if (knot_rdataset_subset(ptr, counter_ptr)) {
return KNOT_EOK;
}
knot_rdata_t *rdata = ptr->rdata;
int ret = KNOT_EOK;
for (int i = 0; ret == KNOT_EOK && i < ptr->count; i++) {
......@@ -158,6 +164,11 @@ static int cat_update_add_grp(zone_node_t *node, cat_upd_ctx_t *ctx)
return KNOT_ERROR;
}
const knot_rdataset_t *counter_txt = node_rdataset(binode_counterpart(node), KNOT_RRTYPE_TXT);
if (knot_rdataset_subset(txt, counter_txt)) {
return KNOT_EOK;
}
const char *newgr = "";
size_t grlen = 0;
if (!ctx->remove) {
......@@ -175,15 +186,34 @@ static int cat_update_add_grp(zone_node_t *node, cat_upd_ctx_t *ctx)
}
int catalog_update_from_zone(catalog_update_t *u, struct zone_contents *zone,
const zone_diff_t *zone_diff,
const struct zone_contents *complete_contents,
bool remove, catalog_t *check, ssize_t *upd_count)
{
cat_upd_ctx_t ctx = { u, complete_contents, knot_dname_labels(zone->apex->owner, NULL),
remove, check, cat_update_add_memb, cat_update_add_grp };
int ret = KNOT_EOK;
zone_diff_t zdiff;
assert(zone == NULL || zone_diff == NULL);
if (zone != NULL) {
zone_diff_from_zone(&zdiff, zone);
} else {
zdiff = *zone_diff;
}
cat_upd_ctx_t ctx = { u, complete_contents, knot_dname_labels(zdiff.apex->owner, NULL),
remove, zone_diff != NULL, check, cat_update_add_memb, cat_update_add_grp };
pthread_mutex_lock(&u->mutex);
*upd_count -= trie_weight(u->upd);
int ret = interpret_zone(zone, &ctx);
if (zone_diff != NULL) {
zone_diff_reverse(&zdiff);
ctx.remove = true;
ret = interpret_zone(&zdiff, &ctx);
zone_diff_reverse(&zdiff);
ctx.remove = false;
ctx.check = NULL;
}
if (ret == KNOT_EOK) {
ret = interpret_zone(&zdiff, &ctx);
}
*upd_count += trie_weight(u->upd);
pthread_mutex_unlock(&u->mutex);
return ret;
......@@ -213,11 +243,14 @@ static int prop_verify(zone_node_t *node, cat_upd_ctx_t *ctx)
int catalog_zone_verify(const struct zone_contents *zone)
{
cat_upd_ctx_t ctx = { NULL, zone, knot_dname_labels(zone->apex->owner, NULL),
false, NULL, member_verify, prop_verify };
false, false, NULL, member_verify, prop_verify };
if (!check_zone_version(zone)) {
return KNOT_EZONEINVAL;
}
return interpret_zone(zone, &ctx);
zone_diff_t zdiff;
zone_diff_from_zone(&zdiff, zone);
return interpret_zone(&zdiff, &ctx);
}
/* Copyright (C) 2021 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
/* Copyright (C) 2022 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -19,6 +19,7 @@
#include "knot/catalog/catalog_update.h"
struct zone_contents;
struct zone_diff;
/*!
* \brief Validate if given zone is valid catalog.
......@@ -36,6 +37,7 @@ int catalog_zone_verify(const struct zone_contents *zone);
*
* \param u Catalog update to be updated.
* \param zone Zone contents to be searched for member PTR records.
* \param zone_diff Zone diff to interpret for removals and additions.
* \param complete_contents Complete zone contents (zone might be from a changeset).
* \param remove Add removals of found member zones.
* \param check Optional: existing catalog database to be checked for existence
......@@ -45,5 +47,6 @@ int catalog_zone_verify(const struct zone_contents *zone);
* \return KNOT_E*
*/
int catalog_update_from_zone(catalog_update_t *u, struct zone_contents *zone,
const struct zone_diff *zone_diff,
const struct zone_contents *complete_contents,
bool remove, catalog_t *check, ssize_t *upd_count);
......@@ -23,7 +23,7 @@
#include "knot/updates/changesets.h"
#include "contrib/wire_ctx.h"
typedef struct {
typedef struct zone_diff {
zone_tree_t nodes;
zone_tree_t nsec3s;
zone_node_t *apex;
......
......@@ -671,6 +671,13 @@ int zone_update_increment_soa(zone_update_t *update, conf_t *conf)
return set_new_soa(update, conf_opt(&val));
}
static void get_zone_diff(zone_diff_t *zdiff, zone_update_t *up)
{
zdiff->nodes = *up->a_ctx->node_ptrs;
zdiff->nsec3s = *up->a_ctx->nsec3_ptrs;
zdiff->apex = up->new_cont->apex;
}
static int commit_journal(conf_t *conf, zone_update_t *update)
{
conf_val_t val = conf_zone_get(conf, C_JOURNAL_CONTENT, update->zone->name);
......@@ -678,9 +685,7 @@ static int commit_journal(conf_t *conf, zone_update_t *update)
int ret = KNOT_EOK;
if (update->flags & UPDATE_NO_CHSET) {
zone_diff_t diff;
diff.nodes = *update->a_ctx->node_ptrs;
diff.nsec3s = *update->a_ctx->nsec3_ptrs;
diff.apex = update->new_cont->apex;
get_zone_diff(&diff, update);
return zone_diff_store(conf, update->zone, &diff);
} else if ((update->flags & UPDATE_INCREMENTAL) ||
(update->flags & UPDATE_HYBRID)) {
......@@ -742,13 +747,19 @@ static int update_catalog(conf_t *conf, zone_update_t *update)
}
ssize_t upd_count = 0;
if ((update->flags & UPDATE_INCREMENTAL)) {
if ((update->flags & UPDATE_NO_CHSET)) {
zone_diff_t diff;
get_zone_diff(&diff, update);
ret = catalog_update_from_zone(zone_catalog_upd(update->zone),
NULL, &diff, update->new_cont,
false, zone_catalog(update->zone), &upd_count);
} else if ((update->flags & UPDATE_INCREMENTAL)) {
ret = catalog_update_from_zone(zone_catalog_upd(update->zone),
update->change.remove, update->new_cont,
update->change.remove, NULL, update->new_cont,
true, zone_catalog(update->zone), &upd_count);
if (ret == KNOT_EOK) {
ret = catalog_update_from_zone(zone_catalog_upd(update->zone),
update->change.add, update->new_cont,
update->change.add, NULL, update->new_cont,
false, NULL, &upd_count);
}
} else {
......@@ -757,7 +768,7 @@ static int update_catalog(conf_t *conf, zone_update_t *update)
update->zone->name, &upd_count);
if (ret == KNOT_EOK) {
ret = catalog_update_from_zone(zone_catalog_upd(update->zone),
update->new_cont, update->new_cont,
update->new_cont, NULL, update->new_cont,
false, NULL, &upd_count);
}
}
......@@ -1015,9 +1026,7 @@ bool zone_update_no_change(zone_update_t *update)
if (update->flags & UPDATE_NO_CHSET) {
zone_diff_t diff;
diff.nodes = *update->a_ctx->node_ptrs;
diff.nsec3s = *update->a_ctx->nsec3_ptrs;
diff.apex = update->new_cont->apex;
get_zone_diff(&diff, update);
return (zone_diff_serialized_size(diff) == 0);
} else if (update->flags & (UPDATE_INCREMENTAL | UPDATE_HYBRID)) {
return changeset_empty(&update->change);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment