diff --git a/src/knot/nameserver/ixfr.c b/src/knot/nameserver/ixfr.c index 77e85d9d0035e19e89b6861dafa74cb0e7dea8a2..825f59b5b6a553119874c911074eeec7d3c7b7bd 100644 --- a/src/knot/nameserver/ixfr.c +++ b/src/knot/nameserver/ixfr.c @@ -162,7 +162,7 @@ static int ixfr_process_changeset(knot_pkt_t *pkt, const void *item, #undef IXFR_SAFE_PUT /*! \brief Loads IXFRs from journal. */ -static int ixfr_load_chsets(list_t *chgsets, const zone_t *zone, +static int ixfr_load_chsets(list_t *chgsets, zone_t *zone, const knot_rrset_t *their_soa) { assert(chgsets); @@ -176,7 +176,10 @@ static int ixfr_load_chsets(list_t *chgsets, const zone_t *zone, return KNOT_EUPTODATE; } + pthread_mutex_lock(&zone->journal_lock); ret = journal_load_changesets(zone, chgsets, serial_from, serial_to); + pthread_mutex_unlock(&zone->journal_lock); + if (ret != KNOT_EOK) { changesets_free(chgsets); } @@ -241,7 +244,7 @@ static int ixfr_answer_init(struct query_data *qdata) const knot_rrset_t *their_soa = &knot_pkt_section(qdata->query, KNOT_AUTHORITY)->rr[0]; list_t chgsets; init_list(&chgsets); - int ret = ixfr_load_chsets(&chgsets, qdata->zone, their_soa); + int ret = ixfr_load_chsets(&chgsets, (zone_t *)qdata->zone, their_soa); if (ret != KNOT_EOK) { dbg_ns("%s: failed to load changesets => %d\n", __func__, ret); return ret; diff --git a/src/knot/zone/zone-load.c b/src/knot/zone/zone-load.c index 777737d77e0386508a891b57ee5e14137595bd1a..d643596e608ebe76f4d3f5d55bfb9621b99e3dc4 100644 --- a/src/knot/zone/zone-load.c +++ b/src/knot/zone/zone-load.c @@ -97,7 +97,11 @@ int zone_load_journal(zone_t *zone, zone_contents_t *contents) /*! \todo Check what should be the upper bound. */ list_t chgs; init_list(&chgs); + + pthread_mutex_lock(&zone->journal_lock); int ret = journal_load_changesets(zone, &chgs, serial, serial - 1); + pthread_mutex_unlock(&zone->journal_lock); + if ((ret != KNOT_EOK && ret != KNOT_ERANGE) || EMPTY_LIST(chgs)) { changesets_free(&chgs); /* Absence of records is not an error. */ diff --git a/src/knot/zone/zone.c b/src/knot/zone/zone.c index 8d7f5d496bca8d2d04b38f7821eb0c79071d826d..7584a0801c602567d31ac0ae993cee8aae775fd8 100644 --- a/src/knot/zone/zone.c +++ b/src/knot/zone/zone.c @@ -75,6 +75,9 @@ zone_t* zone_new(conf_zone_t *conf) zone->ddns_queue_size = 0; init_list(&zone->ddns_queue); + // Journal lock + pthread_mutex_init(&zone->journal_lock, NULL); + // Initialize events zone_events_init(zone); @@ -95,6 +98,7 @@ void zone_free(zone_t **zone_ptr) free_ddns_queue(zone); pthread_mutex_destroy(&zone->ddns_lock); + pthread_mutex_destroy(&zone->journal_lock); /* Free assigned config. */ conf_free_zone(zone->conf); @@ -113,18 +117,18 @@ int zone_change_store(zone_t *zone, changeset_t *change) conf_zone_t *conf = zone->conf; + pthread_mutex_lock(&zone->journal_lock); int ret = journal_store_changeset(change, conf->ixfr_db, conf->ixfr_fslimit); if (ret == KNOT_EBUSY) { log_zone_notice(zone->name, "journal is full, flushing"); /* Transaction rolled back, journal released, we may flush. */ ret = zone_flush_journal(zone); - if (ret != KNOT_EOK) { - return ret; + if (ret == KNOT_EOK) { + ret = journal_store_changeset(change, conf->ixfr_db, conf->ixfr_fslimit); } - - return journal_store_changeset(change, conf->ixfr_db, conf->ixfr_fslimit); } + pthread_mutex_unlock(&zone->journal_lock); return ret; } @@ -136,18 +140,19 @@ int zone_changes_store(zone_t *zone, list_t *chgs) conf_zone_t *conf = zone->conf; + pthread_mutex_lock(&zone->journal_lock); int ret = journal_store_changesets(chgs, conf->ixfr_db, conf->ixfr_fslimit); + if (ret == KNOT_EBUSY) { log_zone_notice(zone->name, "journal is full, flushing"); /* Transaction rolled back, journal released, we may flush. */ ret = zone_flush_journal(zone); - if (ret != KNOT_EOK) { - return ret; + if (ret == KNOT_EOK) { + ret = journal_store_changesets(chgs, conf->ixfr_db, conf->ixfr_fslimit); } - - return journal_store_changesets(chgs, conf->ixfr_db, conf->ixfr_fslimit); } + pthread_mutex_unlock(&zone->journal_lock); return ret; } diff --git a/src/knot/zone/zone.h b/src/knot/zone/zone.h index 0fc39821a8e0b5e5827d4a0a15f09f18c155c6e7..2d8c2fc1f35dc1775761b0b8b11d5995b2e39d5a 100644 --- a/src/knot/zone/zone.h +++ b/src/knot/zone/zone.h @@ -61,6 +61,9 @@ typedef struct zone pthread_mutex_t ddns_lock; size_t ddns_queue_size; list_t ddns_queue; + + /*! \brief Journal access lock. */ + pthread_mutex_t journal_lock; /*! \brief Zone events. */ zone_events_t events; /*!< Zone events timers. */