Commit 6a6fe7c6 authored by Jan Kadlec's avatar Jan Kadlec

changesets: Removed changesets structure.

- turned it to plain list
- reused ptrnode_t list nodes
parent 17f14a22
......@@ -79,7 +79,7 @@ static int zone_sign(zone_contents_t *zone, const conf_zone_t *zone_config,
uint32_t new_serial = zone_contents_next_serial(zone, zone_config->serial_policy);
dbg_dnssec_verb("Changeset empty before generating NSEC chain: %d\n",
changeset_is_empty(out_ch));
changeset_empty(out_ch));
// Init needed structs
knot_zone_keys_t zone_keys;
......@@ -103,7 +103,7 @@ static int zone_sign(zone_contents_t *zone, const conf_zone_t *zone_config,
return result;
}
dbg_dnssec_verb("Changeset empty after generating NSEC chain: %d\n",
changeset_is_empty(out_ch));
changeset_empty(out_ch));
// add missing signatures
result = knot_zone_sign(zone, &zone_keys, &policy, out_ch,
......@@ -116,16 +116,16 @@ static int zone_sign(zone_contents_t *zone, const conf_zone_t *zone_config,
return result;
}
dbg_dnssec_verb("Changeset emtpy after signing: %d\n",
changeset_is_empty(out_ch));
changeset_empty(out_ch));
// Check if only SOA changed
if (changeset_is_empty(out_ch) &&
if (changeset_empty(out_ch) &&
!knot_zone_sign_soa_expired(zone, &zone_keys, &policy)) {
log_zone_info("%s No signing performed, zone is valid.\n",
msgpref);
free(msgpref);
knot_free_zone_keys(&zone_keys);
assert(changeset_is_empty(out_ch));
assert(changeset_empty(out_ch));
return KNOT_EOK;
}
......
......@@ -24,9 +24,11 @@ enum ixfr_states {
/*! \brief Extended structure for IXFR-in/IXFR-out processing. */
struct ixfr_proc {
struct xfr_proc proc; /* Generic transfer processing context. */
node_t *cur;
ptrnode_t *cur;
int state; /* IXFR-in state. */
changesets_t *changesets; /* Processed changesets. */
knot_rrset_t *final_soa; /* First SOA received via IXFR. */
list_t changesets; /* Processed changesets. */
size_t change_count; /* Count of changes received. */
zone_t *zone; /* Modified zone - for journal access. */
mm_ctx_t *mm; /* Memory context for RR allocations. */
struct query_data *qdata;
......@@ -59,15 +61,11 @@ static int ixfr_put_rrlist(knot_pkt_t *pkt, struct ixfr_proc *ixfr, list_t *list
/* Now iterate until it hits the last one,
* this is done without for() loop because we can
* rejoin the iteration at any point. */
while(ixfr->cur->next) {
knot_rr_ln_t *rr_item = (knot_rr_ln_t *)(ixfr->cur);
if (rr_item->rr->rrs.rr_count > 0) {
IXFR_SAFE_PUT(pkt, rr_item->rr);
} else {
dbg_ns("%s: empty RR %p, skipping\n", __func__, rr_item->rr);
}
while(ixfr->cur->n.next) {
knot_rrset_t *rr = (knot_rrset_t *)ixfr->cur->d;
IXFR_SAFE_PUT(pkt, rr);
ixfr->cur = ixfr->cur->next;
ixfr->cur = (ptrnode_t *)ixfr->cur->n.next;
}
ixfr->cur = NULL;
......@@ -133,8 +131,8 @@ static int ixfr_process_changeset(knot_pkt_t *pkt, const void *item,
#undef IXFR_SAFE_PUT
static int ixfr_load_chsets(changesets_t **chgsets, const zone_t *zone,
const knot_rrset_t *their_soa)
static int ixfr_load_chsets(list_t *chgsets, const zone_t *zone,
const knot_rrset_t *their_soa)
{
assert(chgsets);
assert(zone);
......@@ -147,12 +145,7 @@ static int ixfr_load_chsets(changesets_t **chgsets, const zone_t *zone,
return KNOT_EUPTODATE;
}
*chgsets = changesets_create(0);
if (*chgsets == NULL) {
return KNOT_ENOMEM;
}
ret = journal_load_changesets(zone->conf->ixfr_db, *chgsets,
ret = journal_load_changesets(zone->conf->ixfr_db, chgsets,
serial_from, serial_to);
if (ret != KNOT_EOK) {
changesets_free(chgsets, NULL);
......@@ -212,7 +205,8 @@ static int ixfr_answer_init(struct query_data *qdata)
/* Compare serials. */
const knot_rrset_t *their_soa = &knot_pkt_section(qdata->query, KNOT_AUTHORITY)->rr[0];
changesets_t *chgsets = NULL;
list_t chgsets;
init_list(&chgsets);
int ret = ixfr_load_chsets(&chgsets, qdata->zone, their_soa);
if (ret != KNOT_EOK) {
dbg_ns("%s: failed to load changesets => %d\n", __func__, ret);
......@@ -235,14 +229,14 @@ static int ixfr_answer_init(struct query_data *qdata)
/* Put all changesets to processing queue. */
xfer->changesets = chgsets;
changeset_t *chs = NULL;
WALK_LIST(chs, chgsets->sets) {
WALK_LIST(chs, chgsets) {
ptrlist_add(&xfer->proc.nodes, chs, mm);
}
/* Keep first and last serial. */
chs = HEAD(chgsets->sets);
chs = HEAD(chgsets);
xfer->soa_from = chs->soa_from;
chs = TAIL(chgsets->sets);
chs = TAIL(chgsets);
xfer->soa_to = chs->soa_to;
/* Set up cleanup callback. */
......@@ -313,11 +307,8 @@ static int ixfrin_answer_init(struct answer_data *data)
memset(proc, 0, sizeof(struct ixfr_proc));
gettimeofday(&proc->proc.tstamp, NULL);
proc->changesets = changesets_create(0);
if (proc->changesets == NULL) {
mm_free(data->mm, proc);
return KNOT_ENOMEM;
}
init_list(&proc->changesets);
proc->state = IXFR_START;
proc->zone = data->param->zone;
proc->mm = data->mm;
......@@ -352,16 +343,16 @@ static int ixfrin_finalize(struct answer_data *adata)
}
/*! \brief Stores starting SOA into changesets structure. */
static int solve_start(const knot_rrset_t *rr, changesets_t *changesets, mm_ctx_t *mm)
static int solve_start(const knot_rrset_t *rr, struct ixfr_proc *proc)
{
assert(changesets->first_soa == NULL);
assert(proc->final_soa == NULL);
if (rr->type != KNOT_RRTYPE_SOA) {
return KNOT_EMALF;
}
// Store the first SOA for later use.
changesets->first_soa = knot_rrset_copy(rr, mm);
if (changesets->first_soa == NULL) {
proc->final_soa = knot_rrset_copy(rr, proc->mm);
if (proc->final_soa == NULL) {
return KNOT_ENOMEM;
}
......@@ -369,25 +360,29 @@ static int solve_start(const knot_rrset_t *rr, changesets_t *changesets, mm_ctx_
}
/*! \brief Decides what to do with a starting SOA (deletions). */
static int solve_soa_del(const knot_rrset_t *rr, changesets_t *changesets,
mm_ctx_t *mm)
static int solve_soa_del(const knot_rrset_t *rr, struct ixfr_proc *proc)
{
if (rr->type != KNOT_RRTYPE_SOA) {
return KNOT_EMALF;
}
// Create new changeset.
changeset_t *change = changesets_create_changeset(changesets);
changeset_t *change = changeset_new(proc->mm);
if (change == NULL) {
return KNOT_ENOMEM;
}
// Store SOA into changeset.
change->soa_from = knot_rrset_copy(rr, mm);
change->soa_from = knot_rrset_copy(rr, proc->mm);
if (change->soa_from == NULL) {
changeset_clear(change, NULL);
return KNOT_ENOMEM;
}
// Add changeset.
add_tail(&proc->changesets, &change->n);
++proc->change_count;
return KNOT_EOK;
}
......@@ -438,7 +433,7 @@ static int ixfrin_next_state(struct ixfr_proc *proc, const knot_rrset_t *rr)
if (soa &&
(proc->state == IXFR_SOA_ADD || proc->state == IXFR_ADD)) {
// Check end of transfer.
if (knot_rrset_equal(rr, proc->changesets->first_soa,
if (knot_rrset_equal(rr, proc->final_soa,
KNOT_RRSET_COMPARE_WHOLE)) {
// Final SOA encountered, transfer done.
return IXFR_DONE;
......@@ -448,7 +443,7 @@ static int ixfrin_next_state(struct ixfr_proc *proc, const knot_rrset_t *rr)
switch (proc->state) {
case IXFR_START:
// Final SOA already stored or transfer start.
return proc->changesets->first_soa ? IXFR_SOA_DEL : IXFR_START;
return proc->final_soa ? IXFR_SOA_DEL : IXFR_START;
case IXFR_SOA_DEL:
// Empty delete section or start of delete section.
return soa ? IXFR_SOA_ADD : IXFR_DEL;
......@@ -480,13 +475,13 @@ static int ixfrin_next_state(struct ixfr_proc *proc, const knot_rrset_t *rr)
static int ixfrin_step(const knot_rrset_t *rr, struct ixfr_proc *proc)
{
proc->state = ixfrin_next_state(proc, rr);
changeset_t *change = changesets_get_last(proc->changesets);
changeset_t *change = TAIL(proc->changesets);
switch (proc->state) {
case IXFR_START:
return solve_start(rr, proc->changesets, proc->mm);
return solve_start(rr, proc);
case IXFR_SOA_DEL:
return solve_soa_del(rr, proc->changesets, proc->mm);
return solve_soa_del(rr, proc);
case IXFR_DEL:
return solve_del(rr, change, proc->mm);
case IXFR_SOA_ADD:
......@@ -503,7 +498,7 @@ static int ixfrin_step(const knot_rrset_t *rr, struct ixfr_proc *proc)
/*! \brief Checks whether journal node limit has not been exceeded. */
static bool journal_limit_exceeded(struct ixfr_proc *proc)
{
return proc->changesets->count > JOURNAL_NCOUNT;
return proc->change_count > JOURNAL_NCOUNT;
}
/*! \brief Checks whether RR belongs into zone. */
......
......@@ -84,11 +84,8 @@ static int sign_update(zone_t *zone, const zone_contents_t *old_contents,
assert(new_contents != NULL);
assert(ddns_ch != NULL);
changesets_t *sec_chs = changesets_create(1);
if (sec_chs == NULL) {
return KNOT_ENOMEM;
}
changeset_t *sec_ch = changesets_get_last(sec_chs);
changeset_t sec_ch;
changeset_init(&sec_ch, NULL);
/*
* Check if the UPDATE changed DNSKEYs or NSEC3PARAM.
......@@ -100,37 +97,34 @@ static int sign_update(zone_t *zone, const zone_contents_t *old_contents,
if (zones_dnskey_changed(old_contents, new_contents) ||
zones_nsec3param_changed(old_contents, new_contents)) {
ret = knot_dnssec_zone_sign(new_contents, zone->conf,
sec_ch, KNOT_SOA_SERIAL_KEEP,
&sec_ch, KNOT_SOA_SERIAL_KEEP,
&refresh_at);
} else {
// Sign the created changeset
ret = knot_dnssec_sign_changeset(new_contents, zone->conf,
ddns_ch, sec_ch,
ddns_ch, &sec_ch,
&refresh_at);
}
if (ret != KNOT_EOK) {
changesets_free(&sec_chs, NULL);
changeset_clear(&sec_ch, NULL);
return ret;
}
// Apply DNSSEC changeset
ret = apply_changesets_directly(new_contents, sec_chs);
list_t changes;
init_list(&changes);
add_head(&changes, &sec_ch.n);
ret = apply_changesets_directly(new_contents, &changes);
if (ret != KNOT_EOK) {
changesets_free(&sec_chs, NULL);
changeset_clear(&sec_ch, NULL);
return ret;
}
// Merge changesets
ret = changeset_merge(ddns_ch, sec_ch);
if (ret != KNOT_EOK) {
changesets_free(&sec_chs, NULL);
return ret;
}
changeset_merge(ddns_ch, &sec_ch);
// Free the DNSSEC changeset's SOA from (not used anymore)
knot_rrset_free(&sec_ch->soa_from, NULL);
// Shallow free DNSSEC changesets
free(sec_chs);
knot_rrset_free(&sec_ch.soa_from, NULL);
// Plan next zone resign.
const time_t resign_time = zone_events_get_time(zone, ZONE_EVENT_DNSSEC);
......@@ -154,56 +148,56 @@ static int process_authenticated(uint16_t *rcode, struct query_data *qdata)
return ret;
}
// Create DDNS changesets
changesets_t *ddns_chs = changesets_create(1);
if (ddns_chs == NULL) {
*rcode = KNOT_RCODE_SERVFAIL;
return KNOT_ENOMEM;
}
changeset_t *ddns_ch = changesets_get_last(ddns_chs);
ret = ddns_process_update(zone, query, ddns_ch, rcode);
// Create DDNS change
changeset_t ddns_ch;
changeset_init(&ddns_ch, NULL);
ret = ddns_process_update(zone, query, &ddns_ch, rcode);
if (ret != KNOT_EOK) {
assert(*rcode != KNOT_RCODE_NOERROR);
changesets_free(&ddns_chs, NULL);
changeset_clear(&ddns_ch, NULL);
return ret;
}
assert(*rcode == KNOT_RCODE_NOERROR);
zone_contents_t *new_contents = NULL;
const bool change_made = !changeset_is_empty(ddns_ch);
const bool change_made = !changeset_empty(&ddns_ch);
list_t apply;
if (change_made) {
ret = apply_changesets(zone, ddns_chs, &new_contents);
init_list(&apply);
add_head(&apply, &ddns_ch.n);
ret = apply_changesets(zone, &apply, &new_contents);
if (ret != KNOT_EOK) {
if (ret == KNOT_ETTL) {
*rcode = KNOT_RCODE_REFUSED;
} else {
*rcode = KNOT_RCODE_SERVFAIL;
}
changesets_free(&ddns_chs, NULL);
changeset_clear(&ddns_ch, NULL);
return ret;
}
} else {
changesets_free(&ddns_chs, NULL);
changeset_clear(&ddns_ch, NULL);
*rcode = KNOT_RCODE_NOERROR;
return KNOT_EOK;
}
assert(new_contents);
if (zone->conf->dnssec_enable) {
ret = sign_update(zone, zone->contents, new_contents, ddns_ch);
ret = sign_update(zone, zone->contents, new_contents, &ddns_ch);
if (ret != KNOT_EOK) {
update_rollback(ddns_chs, &new_contents);
changesets_free(&ddns_chs, NULL);
update_rollback(&apply, &new_contents);
changeset_clear(&ddns_ch, NULL);
*rcode = KNOT_RCODE_SERVFAIL;
return ret;
}
}
// Write changes to journal if all went well. (DNSSEC merged)
ret = zone_change_store(zone, ddns_chs);
ret = zone_change_store(zone, &apply);
if (ret != KNOT_EOK) {
update_rollback(ddns_chs, &new_contents);
changesets_free(&ddns_chs, NULL);
update_rollback(&apply, &new_contents);
changeset_clear(&ddns_ch, NULL);
*rcode = KNOT_RCODE_SERVFAIL;
return ret;
}
......@@ -213,8 +207,8 @@ static int process_authenticated(uint16_t *rcode, struct query_data *qdata)
synchronize_rcu();
update_free_old_zone(&old_contents);
update_cleanup(ddns_chs);
changesets_free(&ddns_chs, NULL);
update_cleanup(&apply);
changeset_clear(&ddns_ch, NULL);
/* Sync zonefile immediately if configured. */
if (zone->conf->dbsync_timeout == 0) {
......
......@@ -1021,9 +1021,9 @@ static int serialize_and_store_chgset(const changeset_t *chs,
}
/* Serialize RRSets from the 'remove' section. */
knot_rr_ln_t *rr_node = NULL;
WALK_LIST(rr_node, chs->remove) {
knot_rrset_t *rrset = rr_node->rr;
ptrnode_t *n;
WALK_LIST(n, chs->remove) {
knot_rrset_t *rrset = (knot_rrset_t *)n->d;
ret = rrset_write_to_mem(rrset, &entry, &max_size);
if (ret != KNOT_EOK) {
return ret;
......@@ -1037,8 +1037,8 @@ static int serialize_and_store_chgset(const changeset_t *chs,
}
/* Serialize RRSets from the 'add' section. */
WALK_LIST(rr_node, chs->add) {
knot_rrset_t *rrset = rr_node->rr;
WALK_LIST(n, chs->add) {
knot_rrset_t *rrset = (knot_rrset_t *)n->d;
ret = rrset_write_to_mem(rrset, &entry, &max_size);
if (ret != KNOT_EOK) {
return ret;
......@@ -1132,30 +1132,34 @@ finish:
static int load_changeset(journal_t *journal, journal_node_t *n, void *data)
{
changesets_t *chsets = (changesets_t *)data;
changeset_t *chs = changesets_create_changeset(chsets);
if (chs == NULL) {
return KNOT_ERROR;
list_t *chgs = (list_t *)data;
changeset_t *ch = changeset_new(NULL);
if (ch == NULL) {
return KNOT_ENOMEM;
}
/* Insert into changeset list. */
add_tail(chgs, &ch->n);
/* Initialize changeset. */
chs->data = malloc(n->len);
if (!chs->data) {
ch->data = malloc(n->len);
if (!ch->data) {
return KNOT_ENOMEM;
}
/* Read journal entry. */
int ret = journal_read_node(journal, n, (char*)chs->data);
int ret = journal_read_node(journal, n, (char*)ch->data);
if (ret != KNOT_EOK) {
return ret;
}
/* Update changeset binary size. */
chs->size = n->len;
ch->size = n->len;
return KNOT_EOK;
}
int journal_load_changesets(const char *path, changesets_t *dst,
int journal_load_changesets(const char *path, list_t *dst,
uint32_t from, uint32_t to)
{
int ret = journal_walk(path, from, to, &load_changeset, dst);
......@@ -1170,7 +1174,7 @@ int journal_load_changesets(const char *path, changesets_t *dst,
* into the changeset_t structures.
*/
changeset_t* chs = NULL;
WALK_LIST(chs, dst->sets) {
WALK_LIST(chs, *dst) {
ret = changesets_unpack(chs);
if (ret != KNOT_EOK) {
return ret;
......@@ -1178,7 +1182,7 @@ int journal_load_changesets(const char *path, changesets_t *dst,
}
/* Check for complete history. */
changeset_t *last = changesets_get_last(dst);
changeset_t *last = TAIL(*dst);
if (to != knot_soa_serial(&last->soa_to->rrs)) {
return KNOT_ERANGE;
}
......@@ -1186,7 +1190,7 @@ int journal_load_changesets(const char *path, changesets_t *dst,
return KNOT_EOK;
}
int journal_store_changesets(changesets_t *src, const char *path, size_t size_limit)
int journal_store_changesets(list_t *src, const char *path, size_t size_limit)
{
if (src == NULL || path == NULL) {
return KNOT_EINVAL;
......@@ -1201,7 +1205,7 @@ int journal_store_changesets(changesets_t *src, const char *path, size_t size_li
/* Begin writing to journal. */
changeset_t *chs = NULL;
WALK_LIST(chs, src->sets) {
WALK_LIST(chs, *src) {
/* Make key from serials. */
ret = changeset_pack(chs, journal);
if (ret != KNOT_EOK) {
......
......@@ -176,7 +176,7 @@ bool journal_exists(const char *path);
* \retval KNOT_ERANGE if given entry was not found.
* \return < KNOT_EOK on error.
*/
int journal_load_changesets(const char *path, changesets_t *dst,
int journal_load_changesets(const char *path, list_t *dst,
uint32_t from, uint32_t to);
/*!
......@@ -190,7 +190,7 @@ int journal_load_changesets(const char *path, changesets_t *dst,
* \retval KNOT_EBUSY when journal is full.
* \return < KNOT_EOK on other errors.
*/
int journal_store_changesets(changesets_t *src, const char *path, size_t size_limit);
int journal_store_changesets(list_t *src, const char *path, size_t size_limit);
/*! \brief Function for unmarking dirty nodes. */
/*!
......
......@@ -79,15 +79,15 @@ int changeset_binary_size(const changeset_t *chgset, size_t *size)
size_t soa_to_size = rrset_binary_size(chgset->soa_to);
size_t remove_size = 0;
knot_rr_ln_t *rr_node = NULL;
WALK_LIST(rr_node, chgset->remove) {
knot_rrset_t *rrset = rr_node->rr;
ptrnode_t *n;
WALK_LIST(n, chgset->remove) {
knot_rrset_t *rrset = (knot_rrset_t *)n->d;
remove_size += rrset_binary_size(rrset);
}
size_t add_size = 0;
WALK_LIST(rr_node, chgset->add) {
knot_rrset_t *rrset = rr_node->rr;
WALK_LIST(n, chgset->add) {
knot_rrset_t *rrset = (knot_rrset_t *)n->d;
add_size += rrset_binary_size(rrset);
}
......
......@@ -198,9 +198,9 @@ static int remove_rr(zone_node_t *node, const knot_rrset_t *rr,
/*! \brief Removes all RRs from changeset from zone contents. */
static int apply_remove(zone_contents_t *contents, changeset_t *chset)
{
knot_rr_ln_t *rr_node = NULL;
WALK_LIST(rr_node, chset->remove) {
const knot_rrset_t *rr = rr_node->rr;
ptrnode_t *n;
WALK_LIST(n, chset->remove) {
const knot_rrset_t *rr = (knot_rrset_t *)n->d;
// Find node for this owner
zone_node_t *node = zone_contents_find_node_for_rr(contents, rr);
......@@ -267,9 +267,9 @@ static int add_rr(zone_node_t *node, const knot_rrset_t *rr,
static int apply_add(zone_contents_t *contents, changeset_t *chset,
bool master)
{
knot_rr_ln_t *rr_node = NULL;
WALK_LIST(rr_node, chset->add) {
knot_rrset_t *rr = rr_node->rr;
ptrnode_t *n;
WALK_LIST(n, chset->add) {
knot_rrset_t *rr = (knot_rrset_t *)n->d;
// Get or create node with this owner
zone_node_t *node = zone_contents_get_node_for_rr(contents, rr);
......@@ -454,10 +454,9 @@ static int finalize_updated_zone(zone_contents_t *contents_copy,
/* ------------------------------- API -------------------------------------- */
int apply_changesets(zone_t *zone, changesets_t *chsets,
zone_contents_t **new_contents)
int apply_changesets(zone_t *zone, list_t *chsets, zone_contents_t **new_contents)
{
if (zone == NULL || changesets_empty(chsets) || new_contents == NULL) {
if (zone == NULL || chsets == NULL || EMPTY_LIST(*chsets) || new_contents == NULL) {
return KNOT_EINVAL;
}
......@@ -477,7 +476,7 @@ int apply_changesets(zone_t *zone, changesets_t *chsets,
*/
changeset_t *set = NULL;
const bool master = (zone_master(zone) == NULL);
WALK_LIST(set, chsets->sets) {
WALK_LIST(set, *chsets) {
ret = apply_changeset(contents_copy, set, master);
if (ret != KNOT_EOK) {
update_rollback(chsets, &contents_copy);
......@@ -498,14 +497,14 @@ int apply_changesets(zone_t *zone, changesets_t *chsets,
return KNOT_EOK;
}
int apply_changesets_directly(zone_contents_t *contents, changesets_t *chsets)
int apply_changesets_directly(zone_contents_t *contents, list_t *chsets)
{
if (contents == NULL || chsets == NULL) {
return KNOT_EINVAL;
}
changeset_t *set = NULL;
WALK_LIST(set, chsets->sets) {
WALK_LIST(set, *chsets) {
const bool master = true; // Only DNSSEC changesets are applied directly.
int ret = apply_changeset(contents, set, master);
if (ret != KNOT_EOK) {
......@@ -524,14 +523,14 @@ int apply_changesets_directly(zone_contents_t *contents, changesets_t *chsets)
return ret;
}
void update_cleanup(changesets_t *chgs)
void update_cleanup(list_t *chgs)
{
if (chgs == NULL) {
if (chgs == NULL || EMPTY_LIST(*chgs)) {
return;
}
changeset_t *change = NULL;
WALK_LIST(change, chgs->sets) {
WALK_LIST(change, *chgs) {
// Delete old RR data
rrs_list_clear(&change->old_data, NULL);
init_list(&change->old_data);
......@@ -541,11 +540,11 @@ void update_cleanup(changesets_t *chgs)
};
}
void update_rollback(changesets_t *chgs, zone_contents_t **new_contents)
void update_rollback(list_t *chgs, zone_contents_t **new_contents)
{
if (chgs != NULL) {
if (chgs != NULL && !EMPTY_LIST(*chgs)) {
changeset_t *change = NULL;
WALK_LIST(change, chgs->sets) {
WALK_LIST(change, *chgs) {
// Delete new RR data
rrs_list_clear(&change->new_data, NULL);
init_list(&change->new_data);
......
......@@ -42,7 +42,7 @@
*
* \return KNOT_E*
*/
int apply_changesets(zone_t *zone, changesets_t *chsets,
int apply_changesets(zone_t *zone, list_t *chsets,
zone_contents_t **new_contents);
/*!
......@@ -53,14 +53,13 @@ int apply_changesets(zone_t *zone, changesets_t *chsets,
*
* \return KNOT_E*
*/
int apply_changesets_directly(zone_contents_t *contents,
changesets_t *chsets);
int apply_changesets_directly(zone_contents_t *contents, list_t *chsets);
/*!
* \brief Cleanups successful update. (IXFR, DNSSEC, DDNS).
* \param chgs Changesets used to create the update.
*/
void update_cleanup(changesets_t *chgs);
void update_cleanup(list_t *chgs);
/*!
* \brief Rollbacks failed update (IXFR, DNSSEC, DDNS).
......@@ -68,7 +67,7 @@ void update_cleanup(changesets_t *chgs);
* \param chgs Changesets used to create the update.
* \param new_contents Created zone contents.
*/
void update_rollback(changesets_t *chgs, zone_contents_t **new_contents);
void update_rollback(list_t *chgs, zone_contents_t **new_contents);
/*!
* \brief Frees old zone contents - i.e. contents that were used to create the
......
......@@ -27,143 +27,50 @@
#include "libknot/rrtype/soa.h"
#include "common/debug.h"
static int knot_changesets_init(changesets_t *chs)
void changeset_init(changeset_t *ch, mm_ctx_t *mm)
{
assert(chs != NULL);
memset(ch, 0, sizeof(changeset_t));
// Create new changesets structure
memset(chs, 0, sizeof(changesets_t));
// Initialize memory context for changesets (xmalloc'd)
struct mempool *chs_pool = mp_new(sizeof(changeset_t));
chs->mmc_chs.ctx = chs_pool;
chs->mmc_chs.alloc = (mm_alloc_t)mp_alloc;
chs->mmc_chs.free = NULL;
// Initialize memory context for RRs in changesets (xmalloc'd)
struct mempool *rr_pool = mp_new(sizeof(knot_rr_ln_t));
chs->mmc_rr.ctx = rr_pool;
chs->mmc_rr.alloc = (mm_alloc_t)mp_alloc;
chs->mmc_rr.free = NULL;
if (chs_pool == NULL || rr_pool == NULL) {
ERR_ALLOC_FAILED;
return KNOT_ENOMEM;
}
// Init list with changesets
init_list(&chs->sets);
return KNOT_EOK;
}
changesets_t *changesets_create(unsigned count)
{
changesets_t *ch = malloc(sizeof(changesets_t));
if (ch == NULL) {
ERR_ALLOC_FAILED;
return NULL;
}
int ret = knot_changesets_init(ch);
if (ret != KNOT_EOK) {
changesets_free(&ch, NULL);
return NULL;
}
for (unsigned i = 0; i < count; ++i) {
changeset_t *change = changesets_create_changeset(ch);
if (change == NULL) {
changesets_free(&ch, NULL);
return NULL;
}
}
return ch;
}
changeset_t *changesets_create_changeset(changesets_t *chs)
{
if (chs == NULL) {
return NULL;
}
// Create set changesets' memory allocator
changeset_t *set = chs->mmc_chs.alloc(chs->mmc_chs.ctx,
sizeof(changeset_t));
if (set == NULL) {