Skip to content
Snippets Groups Projects
Commit 49fc8198 authored by Marek Vavruša's avatar Marek Vavruša
Browse files

ddns: excluded ddns/zone discard, release the zone after the ddns lock

parent 0edc879e
No related branches found
No related tags found
No related merge requests found
......@@ -142,6 +142,12 @@ int update_answer(knot_pkt_t *pkt, struct query_data *qdata)
return NS_PROC_FAIL;
}
/* Check if the zone is not discarded. */
if (zone->flags & ZONE_DISCARDED) {
pthread_mutex_unlock(&zone->ddns_lock);
return NS_PROC_FAIL;
}
struct timeval t_start = {0}, t_end = {0};
gettimeofday(&t_start, NULL);
UPDATE_LOG(LOG_INFO, "Started (serial %u).", knot_zone_serial(qdata->zone->contents));
......@@ -149,10 +155,22 @@ int update_answer(knot_pkt_t *pkt, struct query_data *qdata)
/* Reserve space for TSIG. */
knot_pkt_reserve(pkt, tsig_wire_maxsize(qdata->sign.tsig_key));
/* Retain zone for the whole processing so it doesn't disappear
* for example during reload.
* @note This is going to be fixed when this is made a zone event. */
zone_retain(zone);
/* Process UPDATE. */
rcu_read_unlock();
int ret = update_process(pkt, qdata);
rcu_read_lock();
/* Since we unlocked RCU read lock, it is possible that the
* zone was modified/removed in the background. Therefore,
* we must NOT touch the zone after we release it here. */
pthread_mutex_unlock(&zone->ddns_lock);
zone_release(zone);
qdata->zone = NULL;
/* Evaluate */
switch(ret) {
......@@ -335,7 +353,6 @@ static int zones_process_update_auth(struct query_data *qdata)
}
// Apply changeset to zone created by DDNS processing
if (zone_config->dnssec_enable) {
/*!
* Check if the UPDATE changed DNSKEYs. If yes, resign the whole
......@@ -436,10 +453,7 @@ static int zones_process_update_auth(struct query_data *qdata)
}
// Switch zone contents.
zone_retain(zone); /* Retain pointer for safe RCU unlock. */
rcu_read_unlock(); /* Unlock for switch. */
ret = xfrin_switch_zone(zone, new_contents, XFR_TYPE_UPDATE);
rcu_read_lock(); /* Relock */
if (ret != KNOT_EOK) {
log_zone_error("%s: Failed to replace current zone (%s)\n",
msg, knot_strerror(ret));
......@@ -449,8 +463,6 @@ static int zones_process_update_auth(struct query_data *qdata)
/* Free changesets, but not the data. */
zones_free_merged_changesets(chgsets, sec_chs);
zone_release(zone);
qdata->zone = NULL;
return KNOT_ERROR;
}
......@@ -479,12 +491,6 @@ static int zones_process_update_auth(struct query_data *qdata)
zones_schedule_zonefile_sync(zone, 0);
}
/* Since we unlocked RCU read lock, it is possible that the
* zone was modified/removed in the background. Therefore,
* we must NOT touch the zone after we release it here. */
zone_release(zone);
qdata->zone = NULL;
return ret;
}
......
......@@ -519,8 +519,6 @@ static int remove_old_zonedb(const knot_zonedb_t *db_new, knot_zonedb_t *db_old)
knot_zonedb_iter_next(&it);
}
synchronize_rcu();
/* Delete all deprecated zones and delete the old database. */
knot_zonedb_deep_free(&db_old);
......
......@@ -40,8 +40,12 @@
/*! \brief Discard zone in zone database. */
static void discard_zone(zone_t *zone)
{
synchronize_rcu();
/* @note Exclude DDNS. */
pthread_mutex_lock(&zone->ddns_lock);
zone->flags |= ZONE_DISCARDED;
pthread_mutex_unlock(&zone->ddns_lock);
/* Wait for current operations. */
synchronize_rcu();
zone_release(zone);
}
......
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