Commit fe3ecd05 authored by Dominik Taborsky's avatar Dominik Taborsky

apply: move rollback/update lists from changeset to a apply context structure

parent 6148338b
......@@ -380,8 +380,11 @@ static int ixfrin_finalize(struct answer_data *adata)
struct ixfr_proc *ixfr = adata->ext;
assert(ixfr->state == IXFR_DONE);
apply_ctx_t a_ctx;
apply_init_ctx(&a_ctx);
zone_contents_t *new_contents;
int ret = apply_changesets(ixfr->zone, &ixfr->changesets, &new_contents);
int ret = apply_changesets(&a_ctx, ixfr->zone, &ixfr->changesets, &new_contents);
if (ret != KNOT_EOK) {
IXFRIN_LOG(LOG_WARNING, "failed to apply changes to zone (%s)",
knot_strerror(ret));
......@@ -393,7 +396,7 @@ static int ixfrin_finalize(struct answer_data *adata)
if (ret != KNOT_EOK) {
IXFRIN_LOG(LOG_WARNING, "failed to write changes to journal (%s)",
knot_strerror(ret));
updates_rollback(&ixfr->changesets);
update_rollback(&a_ctx);
update_free_zone(&new_contents);
return ret;
}
......@@ -404,7 +407,7 @@ static int ixfrin_finalize(struct answer_data *adata)
synchronize_rcu();
update_free_zone(&old_contents);
updates_cleanup(&ixfr->changesets);
update_cleanup(&a_ctx);
struct timeval now = {0};
gettimeofday(&now, NULL);
......
This diff is collapsed.
......@@ -34,6 +34,20 @@
#include "knot/zone/zone.h"
#include "knot/updates/changesets.h"
struct apply_ctx {
list_t old_data; /*!< Old data, to be freed after successful update. */
list_t new_data; /*!< New data, to be freed after failed update. */
};
typedef struct apply_ctx apply_ctx_t;
/*!
* \brief Initialize a new context structure.
*
* \param ctx Context to be initialized.
*/
void apply_init_ctx(apply_ctx_t *ctx);
/*!
* \brief Applies changesets *with* zone shallow copy.
*
......@@ -43,7 +57,7 @@
*
* \return KNOT_E*
*/
int apply_changesets(zone_t *zone, list_t *chsets,
int apply_changesets(apply_ctx_t *ctx, zone_t *zone, list_t *chsets,
zone_contents_t **new_contents);
/*!
......@@ -55,7 +69,7 @@ int apply_changesets(zone_t *zone, list_t *chsets,
*
* \return KNOT_E*
*/
int apply_changeset(zone_t *zone, changeset_t *ch,
int apply_changeset(apply_ctx_t *ctx, zone_t *zone, changeset_t *ch,
zone_contents_t **new_contents);
/*!
......@@ -66,7 +80,7 @@ int apply_changeset(zone_t *zone, changeset_t *ch,
*
* \return KNOT_E*
*/
int apply_changesets_directly(zone_contents_t *contents, list_t *chsets);
int apply_changesets_directly(apply_ctx_t *ctx, zone_contents_t *contents, list_t *chsets);
/*!
* \brief Applies changeset directly to the zone, without copying it.
......@@ -76,35 +90,21 @@ int apply_changesets_directly(zone_contents_t *contents, list_t *chsets);
*
* \return KNOT_E*
*/
int apply_changeset_directly(zone_contents_t *contents, changeset_t *ch);
/*!
* \brief Cleanups successful zone updates.
* \param chgs Changesets used to create the update.
*/
void updates_cleanup(list_t *chgs);
int apply_changeset_directly(apply_ctx_t *ctx, zone_contents_t *contents, changeset_t *ch);
/*!
* \brief Cleanups successful zone update.
* \param chgs Changeset used to create the update.
*/
void update_cleanup(changeset_t *change);
/*!
* \brief Rollbacks failed zone updates.
*
* \param chgs Changesets used to create the update.
*/
void updates_rollback(list_t *chgs);
void update_cleanup(apply_ctx_t *ctx);
/*!
* \brief Rollbacks failed zone update.
*
* \param chgs Changeset. used to create the update.
*/
void update_rollback(changeset_t *change);
void update_rollback(apply_ctx_t *ctx);
/*!
* \brief Shallow frees zone contents - either shallow copy after failed update
......
......@@ -203,10 +203,6 @@ int changeset_init(changeset_t *ch, const knot_dname_t *apex)
return KNOT_ENOMEM;
}
// Init change lists
init_list(&ch->new_data);
init_list(&ch->old_data);
return KNOT_EOK;
}
......@@ -329,14 +325,6 @@ int changeset_merge(changeset_t *ch1, const changeset_t *ch2)
knot_rrset_free(&ch1->soa_to, NULL);
ch1->soa_to = soa_copy;
ptrnode_t *n;
WALK_LIST(n, ch2->old_data) {
ptrlist_add(&ch1->old_data, (void *)n->d, NULL);
};
WALK_LIST(n, ch2->new_data) {
ptrlist_add(&ch1->new_data, (void *)n->d, NULL);
};
return KNOT_EOK;
}
......@@ -377,14 +365,6 @@ void changeset_clear(changeset_t *ch)
knot_rrset_free(&ch->soa_from, NULL);
knot_rrset_free(&ch->soa_to, NULL);
node_t *n, *nxt;
WALK_LIST_DELSAFE(n, nxt, ch->old_data) {
mm_free(NULL, n);
};
WALK_LIST_DELSAFE(n, nxt, ch->new_data) {
mm_free(NULL, n);
};
// Delete binary data
free(ch->data);
}
......
......@@ -37,8 +37,6 @@ typedef struct {
knot_rrset_t *soa_to; /*!< Destination SOA. */
zone_contents_t *add; /*!< Change additions. */
zone_contents_t *remove; /*!< Change removals. */
list_t old_data; /*!< Old data, to be freed after successful update. */
list_t new_data; /*!< New data, to be freed after failed update. */
size_t size; /*!< Size of serialized changeset. */
uint8_t *data; /*!< Serialized changeset. */
} changeset_t;
......
......@@ -279,28 +279,6 @@ static void remove_rr_from_changeset(zone_contents_t *z, const knot_rrset_t *rr)
}
}
/*!< \brief Removes RR from list, owner and type check. */
static void remove_header_from_changeset(zone_contents_t *z, const knot_rrset_t *rr)
{
zone_node_t *n = zone_contents_find_node_for_rr(z, rr);
if (n == NULL) {
return;
}
knot_rdataset_t *rrs = node_rdataset(n, rr->type);
if (rrs) {
knot_rdataset_clear(rrs, NULL);
node_remove_rdataset(n, rr->type);
}
}
/*!< \brief Removes RR from list, owner check. */
static void remove_owner_from_changeset(zone_contents_t *z, const knot_dname_t *owner)
{
zone_node_t *n = (zone_node_t *)zone_contents_find_node(z, owner);
node_free_rrsets(n, NULL);
}
/* --------------------- true/false helper functions ------------------------ */
static inline bool is_addition(const knot_rrset_t *rr)
......
......@@ -18,7 +18,6 @@
#include "knot/common/log.h"
#include "knot/dnssec/zone-events.h"
#include "knot/updates/apply.h"
#include "knot/zone/serial.h"
#include "libknot/internal/lists.h"
......@@ -121,11 +120,14 @@ static zone_node_t *node_deep_copy(const zone_node_t *node, mm_ctx_t *mm)
static int init_incremental(zone_update_t *update, zone_t *zone)
{
assert(zone->contents);
int ret = changeset_init(&update->change, zone->name);
if (ret != KNOT_EOK) {
return ret;
}
assert(zone->contents);
apply_init_ctx(&update->a_ctx);
// Copy base SOA RR.
update->change.soa_from =
......@@ -253,7 +255,7 @@ const knot_rdataset_t *zone_update_to(zone_update_t *update)
void zone_update_clear(zone_update_t *update)
{
if (update) {
update_cleanup(&update->change);
update_cleanup(&update->a_ctx);
changeset_clear(&update->change);
mp_delete(update->mm.ctx);
memset(update, 0, sizeof(*update));
......@@ -335,7 +337,7 @@ static int sign_update(zone_update_t *update,
}
// Apply DNSSEC changeset
ret = apply_changeset_directly(new_contents, &sec_ch);
ret = apply_changeset_directly(&update->a_ctx, new_contents, &sec_ch);
if (ret != KNOT_EOK) {
changeset_clear(&sec_ch);
return ret;
......@@ -344,7 +346,7 @@ static int sign_update(zone_update_t *update,
// Merge changesets
ret = changeset_merge(&update->change, &sec_ch);
if (ret != KNOT_EOK) {
update_rollback(&sec_ch);
update_rollback(&update->a_ctx);
changeset_clear(&sec_ch);
return ret;
}
......@@ -408,7 +410,7 @@ static int commit_incremental(zone_update_t *update, zone_contents_t **contents_
// Apply changes.
zone_contents_t *new_contents = NULL;
ret = apply_changeset(update->zone, &update->change, &new_contents);
ret = apply_changeset(&update->a_ctx, update->zone, &update->change, &new_contents);
if (ret != KNOT_EOK) {
changeset_clear(&update->change);
return ret;
......@@ -423,7 +425,7 @@ static int commit_incremental(zone_update_t *update, zone_contents_t **contents_
if (dnssec_enable) {
ret = sign_update(update, new_contents);
if (ret != KNOT_EOK) {
update_rollback(&update->change);
update_rollback(&update->a_ctx);
update_free_zone(&new_contents);
changeset_clear(&update->change);
return ret;
......@@ -433,7 +435,7 @@ static int commit_incremental(zone_update_t *update, zone_contents_t **contents_
// Write changes to journal if all went well. (DNSSEC merged)
ret = zone_change_store(update->zone, &update->change);
if (ret != KNOT_EOK) {
update_rollback(&update->change);
update_rollback(&update->a_ctx);
update_free_zone(&new_contents);
return ret;
}
......
......@@ -26,6 +26,7 @@
#pragma once
#include "knot/updates/apply.h"
#include "knot/updates/changesets.h"
#include "knot/zone/contents.h"
#include "knot/zone/zone.h"
......@@ -37,6 +38,7 @@ typedef struct {
zone_t *zone; /*!< Zone being updated. */
zone_contents_t *new_cont; /*!< New zone contents for full updates. */
changeset_t change; /*!< Changes we want to apply. */
apply_ctx_t a_ctx; /*!< Context for applying changesets. */
uint8_t flags; /*!< Zone update flags. */
mm_ctx_t mm; /*!< Memory context used for intermediate nodes. */
} zone_update_t;
......
......@@ -628,8 +628,11 @@ int event_dnssec(zone_t *zone)
bool zone_changed = !changeset_empty(&ch);
if (zone_changed) {
/* Apply change. */
apply_ctx_t a_ctx;
apply_init_ctx(&a_ctx);
zone_contents_t *new_contents = NULL;
int ret = apply_changeset(zone, &ch, &new_contents);
int ret = apply_changeset(&a_ctx, zone, &ch, &new_contents);
if (ret != KNOT_EOK) {
log_zone_error(zone->name, "DNSSEC, failed to sign zone (%s)",
knot_strerror(ret));
......@@ -641,7 +644,7 @@ int event_dnssec(zone_t *zone)
if (ret != KNOT_EOK) {
log_zone_error(zone->name, "DNSSEC, failed to sign zone (%s)",
knot_strerror(ret));
update_rollback(&ch);
update_rollback(&a_ctx);
update_free_zone(&new_contents);
goto done;
}
......@@ -652,7 +655,7 @@ int event_dnssec(zone_t *zone)
synchronize_rcu();
update_free_zone(&old_contents);
update_cleanup(&ch);
update_cleanup(&a_ctx);
}
// Schedule dependent events.
......
......@@ -121,12 +121,15 @@ int zone_load_journal(conf_t *conf, zone_t *zone, zone_contents_t *contents)
}
/* Apply changesets. */
ret = apply_changesets_directly(contents, &chgs);
apply_ctx_t a_ctx;
apply_init_ctx(&a_ctx);
ret = apply_changesets_directly(&a_ctx, contents, &chgs);
log_zone_info(zone->name, "changes from journal applied %u -> %u (%s)",
serial, zone_contents_serial(contents),
knot_strerror(ret));
updates_cleanup(&chgs);
update_cleanup(&a_ctx);
changesets_free(&chgs);
return ret;
}
......@@ -158,8 +161,11 @@ int zone_load_post(conf_t *conf, zone_contents_t *contents, zone_t *zone,
/* Apply DNSSEC changes. */
if (!changeset_empty(&change)) {
ret = apply_changeset_directly(contents, &change);
update_cleanup(&change);
apply_ctx_t a_ctx;
apply_init_ctx(&a_ctx);
ret = apply_changeset_directly(&a_ctx, contents, &change);
update_cleanup(&a_ctx);
if (ret != KNOT_EOK) {
changeset_clear(&change);
return ret;
......
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