Commit b2a745fe authored by Jan Kadlec's avatar Jan Kadlec

journal: added a per-zone lock for journal access.

 - When reloading a server, there's a possibility of two readers reading
   the journal, but that should be fine. This is because the zone
structure is recreated during reloads, and so is the lock. Only events
can write to journal though, so there's no possibility of concurrent
read and write.
parent f0538033
......@@ -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;
......
......@@ -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. */
......
......@@ -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;
}
......
......@@ -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. */
......
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