mirror of
https://gitlab.nic.cz/knot/knot-dns.git
synced 2026-02-03 18:49:28 -05:00
zone/purge: refactoring: perform as zone event instead by main thread...
...but only in case of knotc zone-purge; catalog-induced purges are still performed by main thread while zone events all frozen for all zones
This commit is contained in:
parent
c1eb463e45
commit
605ddcc9dc
11 changed files with 76 additions and 56 deletions
|
|
@ -268,6 +268,7 @@ src/knot/events/handlers/flush.c
|
|||
src/knot/events/handlers/freeze_thaw.c
|
||||
src/knot/events/handlers/load.c
|
||||
src/knot/events/handlers/notify.c
|
||||
src/knot/events/handlers/purge.c
|
||||
src/knot/events/handlers/refresh.c
|
||||
src/knot/events/handlers/update.c
|
||||
src/knot/events/handlers/validate.c
|
||||
|
|
|
|||
|
|
@ -94,6 +94,7 @@ libknotd_la_SOURCES = \
|
|||
knot/events/handlers/freeze_thaw.c \
|
||||
knot/events/handlers/load.c \
|
||||
knot/events/handlers/notify.c \
|
||||
knot/events/handlers/purge.c \
|
||||
knot/events/handlers/refresh.c \
|
||||
knot/events/handlers/update.c \
|
||||
knot/events/handlers/validate.c \
|
||||
|
|
|
|||
|
|
@ -1811,31 +1811,17 @@ static int orphans_purge(ctl_args_t *args)
|
|||
|
||||
static int zone_purge(zone_t *zone, ctl_args_t *args)
|
||||
{
|
||||
if (MATCH_OR_FILTER(args, CTL_FILTER_PURGE_EXPIRE)) {
|
||||
// Abort possible editing transaction.
|
||||
int ret = zone_txn_abort(zone, args);
|
||||
if (ret != KNOT_EOK && ret != KNOT_TXN_ENOTEXISTS) {
|
||||
log_zone_error(zone->name,
|
||||
"failed to abort pending transaction (%s)",
|
||||
knot_strerror(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Expire the zone.
|
||||
// No ret, KNOT_EOK is the only return value from event_expire().
|
||||
(void)zone_events_schedule_blocking(zone, ZONE_EVENT_EXPIRE, true);
|
||||
}
|
||||
|
||||
const purge_flag_t params =
|
||||
MATCH_OR_FILTER(args, CTL_FILTER_PURGE_TIMERS) * PURGE_ZONE_TIMERS |
|
||||
MATCH_OR_FILTER(args, CTL_FILTER_PURGE_ZONEFILE) * PURGE_ZONE_ZONEFILE |
|
||||
MATCH_OR_FILTER(args, CTL_FILTER_PURGE_JOURNAL) * PURGE_ZONE_JOURNAL |
|
||||
MATCH_OR_FILTER(args, CTL_FILTER_PURGE_KASPDB) * PURGE_ZONE_KASPDB |
|
||||
MATCH_OR_FILTER(args, CTL_FILTER_PURGE_CATALOG) * PURGE_ZONE_CATALOG |
|
||||
MATCH_OR_FILTER(args, CTL_FILTER_PURGE_EXPIRE) * PURGE_ZONE_EXPIRE |
|
||||
PURGE_ZONE_NOSYNC; // Purge even zonefiles with disabled syncing.
|
||||
|
||||
// Purge the requested zone data.
|
||||
return selective_zone_purge(conf(), zone, params);
|
||||
zone_set_flag(zone, (zone_flag_t)params);
|
||||
return schedule_trigger(zone, args, ZONE_EVENT_PURGE, true);
|
||||
}
|
||||
|
||||
int ctl_dump_ctr(stats_dump_params_t *params, stats_dump_ctx_t *ctx)
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ static const event_info_t EVENT_INFO[] = {
|
|||
{ ZONE_EVENT_REFRESH, event_refresh, "refresh" },
|
||||
{ ZONE_EVENT_UPDATE, event_update, "update" },
|
||||
{ ZONE_EVENT_EXPIRE, event_expire, "expiration" },
|
||||
{ ZONE_EVENT_PURGE, event_purge, "purge" },
|
||||
{ ZONE_EVENT_FLUSH, event_flush, "flush" },
|
||||
{ ZONE_EVENT_BACKUP, event_backup, "backup/restore" },
|
||||
{ ZONE_EVENT_NOTIFY, event_notify, "notify" },
|
||||
|
|
@ -68,6 +69,7 @@ bool ufreeze_applies(zone_event_type_t type)
|
|||
case ZONE_EVENT_LOAD:
|
||||
case ZONE_EVENT_REFRESH:
|
||||
case ZONE_EVENT_UPDATE:
|
||||
case ZONE_EVENT_PURGE:
|
||||
case ZONE_EVENT_FLUSH:
|
||||
case ZONE_EVENT_DNSSEC:
|
||||
case ZONE_EVENT_DS_CHECK:
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ typedef enum zone_event_type {
|
|||
ZONE_EVENT_REFRESH,
|
||||
ZONE_EVENT_UPDATE,
|
||||
ZONE_EVENT_EXPIRE,
|
||||
ZONE_EVENT_PURGE,
|
||||
ZONE_EVENT_FLUSH,
|
||||
ZONE_EVENT_BACKUP,
|
||||
ZONE_EVENT_NOTIFY,
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@ int event_refresh(conf_t *conf, zone_t *zone);
|
|||
int event_update(conf_t *conf, zone_t *zone);
|
||||
/*! \brief Empties in-memory zone contents. */
|
||||
int event_expire(conf_t *conf, zone_t *zone);
|
||||
/*! \brief Expires the zone and purges metadata based on zone->flags. */
|
||||
int event_purge(conf_t *conf, zone_t *zone);
|
||||
/*! \brief Flushes zone contents into text file. */
|
||||
int event_flush(conf_t *conf, zone_t *zone);
|
||||
/*! \brief Backs up zone contents, metadata, keys, etc to a directory. */
|
||||
|
|
|
|||
|
|
@ -3,41 +3,11 @@
|
|||
* For more information, see <https://www.knot-dns.cz/>
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <urcu.h>
|
||||
|
||||
#include "knot/common/log.h"
|
||||
#include "knot/conf/conf.h"
|
||||
#include "knot/events/handlers.h"
|
||||
#include "knot/events/replan.h"
|
||||
#include "knot/zone/contents.h"
|
||||
#include "knot/zone/zone.h"
|
||||
|
||||
int event_expire(conf_t *conf, zone_t *zone)
|
||||
{
|
||||
assert(zone);
|
||||
|
||||
zone_contents_t *expired = zone_switch_contents(zone, NULL);
|
||||
log_zone_info(zone->name, "zone expired");
|
||||
|
||||
synchronize_rcu();
|
||||
|
||||
pthread_mutex_lock(&zone->cu_lock);
|
||||
assert(zone->control_update == NULL || !(zone->control_update->flags & UPDATE_WFEV));
|
||||
zone_control_clear(zone);
|
||||
pthread_mutex_unlock(&zone->cu_lock);
|
||||
|
||||
knot_sem_wait(&zone->cow_lock);
|
||||
zone_contents_deep_free(expired);
|
||||
knot_sem_post(&zone->cow_lock);
|
||||
|
||||
zone->zonefile.exists = false;
|
||||
|
||||
zone_set_last_master(zone, NULL);
|
||||
|
||||
zone->timers.next_expire = time(NULL);
|
||||
zone->timers.next_refresh = zone->timers.next_expire;
|
||||
replan_from_timers(conf, zone);
|
||||
zone_perform_expire(conf, zone);
|
||||
|
||||
return KNOT_EOK;
|
||||
}
|
||||
|
|
|
|||
17
src/knot/events/handlers/purge.c
Normal file
17
src/knot/events/handlers/purge.c
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
/* Copyright (C) CZ.NIC, z.s.p.o. and contributors
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* For more information, see <https://www.knot-dns.cz/>
|
||||
*/
|
||||
|
||||
#include "knot/zone/zone.h"
|
||||
|
||||
int event_purge(conf_t *conf, zone_t *zone)
|
||||
{
|
||||
purge_flag_t what = (purge_flag_t)zone_get_flag(zone, (zone_flag_t)PURGE_ZONE_FLAGS, true);
|
||||
|
||||
if (what & PURGE_ZONE_EXPIRE) {
|
||||
zone_perform_expire(conf, zone);
|
||||
}
|
||||
|
||||
return selective_zone_purge(conf, zone, what);
|
||||
}
|
||||
|
|
@ -49,6 +49,7 @@ static void replan_from_zone(zone_t *zone, zone_t *old_zone)
|
|||
|
||||
const zone_event_type_t types[] = {
|
||||
ZONE_EVENT_REFRESH,
|
||||
ZONE_EVENT_PURGE,
|
||||
ZONE_EVENT_FLUSH,
|
||||
ZONE_EVENT_BACKUP,
|
||||
ZONE_EVENT_NOTIFY,
|
||||
|
|
|
|||
|
|
@ -359,6 +359,31 @@ int selective_zone_purge(conf_t *conf, zone_t *zone, purge_flag_t params)
|
|||
return KNOT_EOK;
|
||||
}
|
||||
|
||||
void zone_perform_expire(conf_t *conf, zone_t *zone)
|
||||
{
|
||||
zone_contents_t *expired = zone_switch_contents(zone, NULL);
|
||||
log_zone_info(zone->name, "zone expired");
|
||||
|
||||
synchronize_rcu();
|
||||
|
||||
pthread_mutex_lock(&zone->cu_lock);
|
||||
assert(zone->control_update == NULL || !(zone->control_update->flags & UPDATE_WFEV));
|
||||
zone_control_clear(zone);
|
||||
pthread_mutex_unlock(&zone->cu_lock);
|
||||
|
||||
knot_sem_wait(&zone->cow_lock);
|
||||
zone_contents_deep_free(expired);
|
||||
knot_sem_post(&zone->cow_lock);
|
||||
|
||||
zone->zonefile.exists = false;
|
||||
|
||||
zone_set_last_master(zone, NULL);
|
||||
|
||||
zone->timers.next_expire = time(NULL);
|
||||
zone->timers.next_refresh = zone->timers.next_expire;
|
||||
replan_from_timers(conf, zone);
|
||||
}
|
||||
|
||||
knot_lmdb_db_t *zone_journaldb(const zone_t *zone)
|
||||
{
|
||||
return &zone->server->journaldb;
|
||||
|
|
|
|||
|
|
@ -40,6 +40,9 @@ typedef enum {
|
|||
ZONE_USER_FLUSH = 1 << 8, /*!< User-triggered flush. */
|
||||
ZONE_LAST_SIGN_OK = 1 << 9, /*!< Last full-sign event finished OK. */
|
||||
ZONE_PREF_MASTER_2X = 1 << 10, /*!< Preferred master has been overwritten at least once. */
|
||||
|
||||
ZONE_FLAG_MAX = 1 << 19, /*!< Maximal usable flag below purge_flag_t. */
|
||||
ZONE_FLAG_TYPESIZE = 1 << 30, /*!< Enforces the compiler to use 32-bit variable for this enum. */
|
||||
} zone_flag_t;
|
||||
|
||||
/*!
|
||||
|
|
@ -50,16 +53,19 @@ knot_dynarray_declare(notifailed_rmt, notifailed_rmt_hash, DYNARRAY_VISIBILITY_N
|
|||
|
||||
/*!
|
||||
* \brief Zone purging parameter flags.
|
||||
*
|
||||
* \warning Note they are and must be mutually exclusive with zone_flag_t so that they can be stored in zone->flags.
|
||||
*/
|
||||
typedef enum {
|
||||
PURGE_ZONE_BEST = 1 << 0, /*!< Best effort -- continue on failures. */
|
||||
PURGE_ZONE_LOG = 1 << 1, /*!< Log a purged zone even if requested less. */
|
||||
PURGE_ZONE_NOSYNC = 1 << 2, /*!< Remove even zone files with disabled syncing. */
|
||||
PURGE_ZONE_TIMERS = 1 << 3, /*!< Purge the zone timers. */
|
||||
PURGE_ZONE_ZONEFILE = 1 << 4, /*!< Purge the zone file. */
|
||||
PURGE_ZONE_JOURNAL = 1 << 5, /*!< Purge the zone journal. */
|
||||
PURGE_ZONE_KASPDB = 1 << 6, /*!< Purge KASP DB. */
|
||||
PURGE_ZONE_CATALOG = 1 << 7, /*!< Purge the catalog. */
|
||||
PURGE_ZONE_BEST = 1 << 20, /*!< Best effort -- continue on failures. */
|
||||
PURGE_ZONE_LOG = 1 << 21, /*!< Log a purged zone even if requested less. */
|
||||
PURGE_ZONE_NOSYNC = 1 << 22, /*!< Remove even zone files with disabled syncing. */
|
||||
PURGE_ZONE_TIMERS = 1 << 23, /*!< Purge the zone timers. */
|
||||
PURGE_ZONE_ZONEFILE = 1 << 24, /*!< Purge the zone file. */
|
||||
PURGE_ZONE_JOURNAL = 1 << 25, /*!< Purge the zone journal. */
|
||||
PURGE_ZONE_KASPDB = 1 << 26, /*!< Purge KASP DB. */
|
||||
PURGE_ZONE_CATALOG = 1 << 27, /*!< Purge the catalog. */
|
||||
PURGE_ZONE_EXPIRE = 1 << 28, /*!< Expire the zone, free contents. */
|
||||
} purge_flag_t;
|
||||
|
||||
/*!< All data. */
|
||||
|
|
@ -69,6 +75,9 @@ typedef enum {
|
|||
/*!< Standard purge (respect C_ZONEFILE_SYNC param). */
|
||||
#define PURGE_ZONE_ALL (PURGE_ZONE_DATA | PURGE_ZONE_BEST | PURGE_ZONE_LOG)
|
||||
|
||||
/*!< All purge-related flags. */
|
||||
#define PURGE_ZONE_FLAGS (PURGE_ZONE_ALL | PURGE_ZONE_NOSYNC | PURGE_ZONE_EXPIRE)
|
||||
|
||||
/*!
|
||||
* \brief Structure for holding DNS zone.
|
||||
*/
|
||||
|
|
@ -187,6 +196,11 @@ void zone_reset(conf_t *conf, zone_t *zone);
|
|||
*/
|
||||
int selective_zone_purge(conf_t *conf, zone_t *zone, purge_flag_t params);
|
||||
|
||||
/*!
|
||||
* \brief Expire zone, NULL and free zone->contents, clear CTL txn, expire timers, replan events.
|
||||
*/
|
||||
void zone_perform_expire(conf_t *conf, zone_t *zone);
|
||||
|
||||
/*!
|
||||
* \brief Clears possible control update transaction.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in a new issue