Commit 0f8d1c8f authored by Jan Včelák's avatar Jan Včelák 🚀

Merge branch 'events-no-free' of /git/repositories/labs/knot

parents fa759ec0 cd3e5eb4
......@@ -141,6 +141,18 @@ event_t *evsched_event_new(evsched_t *s, int type)
/* Initialize. */
memset(e, 0, sizeof(event_t));
e->type = type;
e->parent = s;
return e;
}
event_t *evsched_event_new_cb(evsched_t *s, event_cb_t cb, void *data)
{
/* Create event. */
event_t *e = evsched_event_new(s, EVSCHED_CB);
if (e != NULL) {
e->cb = cb;
e->data = data;
}
return e;
}
......@@ -184,7 +196,7 @@ event_t* evsched_next(evsched_t *s)
/* Immediately return. */
if (timercmp_ge(&dt, &next_ev->tv)) {
s->cur = next_ev;
heap_delmin(&s->heap);
heap_delmin(&s->heap);
pthread_mutex_unlock(&s->mx);
pthread_mutex_lock(&s->rl);
......@@ -262,12 +274,10 @@ event_t* evsched_schedule_cb(evsched_t *s, event_cb_t cb, void *data, uint32_t d
}
/* Create event. */
event_t *e = evsched_event_new(s, EVSCHED_CB);
event_t *e = evsched_event_new_cb(s, cb, data);
if (!e) {
return NULL;
}
e->cb = cb;
e->data = data;
/* Schedule. */
if (evsched_schedule(s, e, dt) != 0) {
......@@ -332,10 +342,13 @@ static int evsched_try_cancel(evsched_t *s, event_t *ev)
/* Enable running events. */
pthread_mutex_unlock(&s->rl);
if (found) {
if (found > 0) { /* Event canceled. */
return KNOT_EOK;
} else if (found < 0) {
return found; /* Error */
}
/* Not found. */
return KNOT_ENOENT;
}
......@@ -351,6 +364,6 @@ int evsched_cancel(evsched_t *s, event_t *ev)
ret = evsched_try_cancel(s, ev);
}
/* Now we're sure event is cancelled or finished. */
/* Now we're sure event is canceled or finished. */
return KNOT_EOK;
}
......@@ -125,6 +125,17 @@ void evsched_delete(evsched_t **s);
*/
event_t *evsched_event_new(evsched_t *s, int type);
/*!
* \brief Create a callback event.
*
* \param s Pointer to event scheduler instance.
* \param cb Callback handler.
* \param data Data for callback.
* \retval New instance on success.
* \retval NULL on error.
*/
event_t *evsched_event_new_cb(evsched_t *s, event_cb_t cb, void *data);
/*!
* \brief Dispose event instance.
*
......
......@@ -178,7 +178,12 @@ static int remote_zone_sign(server_t *server, const knot_zone_t *zone)
log_server_info("Requested zone resign for '%s'.\n", zone_name);
free(zone_name);
zones_schedule_dnssec((knot_zone_t *)zone, 0, true);
uint32_t expires_at = 0;
zones_cancel_dnssec((knot_zone_t *)zone);
rcu_read_lock();
zones_dnssec_sign((knot_zone_t *)zone, true, &expires_at);
rcu_read_unlock();
zones_schedule_dnssec((knot_zone_t *)zone, expires_at);
return KNOT_EOK;
}
......
......@@ -53,32 +53,29 @@ static int zonedata_destroy(knot_zone_t *zone)
}
/* Cancel REFRESH timer. */
evsched_t *sch = zd->server->sched;
if (zd->xfr_in.timer) {
evsched_t *sch = zd->xfr_in.timer->parent;
evsched_cancel(sch, zd->xfr_in.timer);
evsched_event_free(sch, zd->xfr_in.timer);
zd->xfr_in.timer = 0;
zd->xfr_in.timer = NULL;
}
/* Cancel EXPIRE timer. */
if (zd->xfr_in.expire) {
evsched_t *sch = zd->xfr_in.expire->parent;
evsched_cancel(sch, zd->xfr_in.expire);
evsched_event_free(sch, zd->xfr_in.expire);
zd->xfr_in.expire = 0;
zd->xfr_in.expire = NULL;
}
/* Cancel IXFR DB sync timer. */
if (zd->ixfr_dbsync) {
evsched_t *sch = zd->ixfr_dbsync->parent;
evsched_cancel(sch, zd->ixfr_dbsync);
evsched_event_free(sch, zd->ixfr_dbsync);
zd->ixfr_dbsync = 0;
zd->ixfr_dbsync = NULL;
}
/* Cancel DNSSEC timer. */
if (zd->dnssec_timer) {
evsched_t *sch = zd->dnssec_timer->parent;
evsched_cancel(sch, zd->dnssec_timer);
evsched_event_free(sch, zd->dnssec_timer);
zd->dnssec_timer = NULL;
......@@ -118,27 +115,16 @@ static int zonedata_init(conf_zone_t *cfg, knot_zone_t *zone)
/* Link to config. */
zd->conf = cfg;
zd->server = 0;
/* Initialize mutex. */
pthread_mutex_init(&zd->lock, 0);
/* Initialize ACLs. */
zd->xfr_out = NULL;
zd->notify_in = NULL;
zd->notify_out = NULL;
zd->update_in = NULL;
/* Initialize XFR-IN. */
sockaddr_init(&zd->xfr_in.master, -1);
zd->xfr_in.timer = 0;
zd->xfr_in.expire = 0;
zd->xfr_in.acl = 0;
zd->xfr_in.bootstrap_retry = (XFRIN_BOOTSTRAP_DELAY * tls_rand());
/* Initialize IXFR database. */
zd->ixfr_db = journal_open(cfg->ixfr_db, cfg->ixfr_fslimit, JOURNAL_DIRTY);
if (zd->ixfr_db == NULL) {
char ebuf[256] = {0};
if (strerror_r(errno, ebuf, sizeof(ebuf)) == 0) {
......@@ -148,9 +134,6 @@ static int zonedata_init(conf_zone_t *cfg, knot_zone_t *zone)
}
}
/* Initialize IXFR database syncing event. */
zd->ixfr_dbsync = 0;
/* Set and install destructor. */
zone->data = zd;
knot_zone_set_dtor(zone, zonedata_destroy);
......@@ -231,6 +214,17 @@ static int set_acl(acl_t **acl, list_t* acl_list)
return KNOT_EOK;
}
/*! \brief Create timer if not exists, cancel if running. */
static void timer_reset(evsched_t *sched, event_t **ev,
event_cb_t cb, knot_zone_t *zone)
{
if (*ev == NULL) {
*ev = evsched_event_new_cb(sched, cb, zone);
} else {
evsched_cancel(sched, *ev);
}
}
/*!
* \brief Update zone data from new configuration.
*
......@@ -258,16 +252,19 @@ static void zonedata_update(knot_zone_t *zone, conf_zone_t *conf,
zd->server = (server_t *)ns->data;
// cancel IXFR sync timer
if (zd->ixfr_dbsync) {
assert(zd->server->sched);
evsched_t *scheduler = zd->server->sched;
/* Create or cancel existing events. They must not be freed during their
* lifetime since they are referenced from numerous places.
* So each reload does following:
* 1. all events are cancelled on zonedata update, but initialized
* 2. all events may be scheduled (without changing the callback)
* 3. events may be freed _ONLY_ on zone teardown
*/
evsched_cancel(scheduler, zd->ixfr_dbsync);
evsched_event_free(scheduler, zd->ixfr_dbsync);
zd->ixfr_dbsync = NULL;
}
evsched_t *scheduler = zd->server->sched;
timer_reset(scheduler, &zd->ixfr_dbsync, zones_flush_ev, zone);
timer_reset(scheduler, &zd->xfr_in.timer, zones_refresh_ev, zone);
timer_reset(scheduler, &zd->xfr_in.expire, zones_expire_ev, zone);
timer_reset(scheduler, &zd->dnssec_timer, zones_dnssec_ev, zone);
// ACLs
......
......@@ -136,7 +136,7 @@ static uint32_t zones_soa_expire(knot_zone_t *zone)
/*!
* \brief XFR/IN expire event handler.
*/
static int zones_expire_ev(event_t *e)
int zones_expire_ev(event_t *e)
{
assert(e);
......@@ -177,14 +177,6 @@ static int zones_expire_ev(event_t *e)
/* Cancel REFRESH timer. */
if (zd->xfr_in.timer) {
evsched_cancel(e->parent, zd->xfr_in.timer);
evsched_event_free(e->parent, zd->xfr_in.timer);
zd->xfr_in.timer = 0;
}
/* Free EXPIRE timer. */
if (zd->xfr_in.expire) {
evsched_event_free(e->parent, zd->xfr_in.expire);
zd->xfr_in.expire = 0;
}
knot_zone_contents_deep_free(&contents);
......@@ -197,7 +189,7 @@ static int zones_expire_ev(event_t *e)
/*!
* \brief Zone REFRESH or RETRY event.
*/
static int zones_refresh_ev(event_t *e)
int zones_refresh_ev(event_t *e)
{
assert(e);
......@@ -381,7 +373,7 @@ static int zones_zonefile_sync_from_ev(knot_zone_t *zone, zonedata_t *zd)
/*!
* \brief Sync chagnes in zone to zonefile.
*/
static int zones_zonefile_sync_ev(event_t *e)
int zones_flush_ev(event_t *e)
{
assert(e);
dbg_zones("zones: IXFR database SYNC timer event\n");
......@@ -988,8 +980,7 @@ static int replan_zone_sign_after_ddns(knot_zone_t *zone, zonedata_t *zd,
zones_cancel_dnssec(zone);
ret = zones_schedule_dnssec(zone,
expiration_to_relative(new_expire,
zone),
false);
zone));
}
return ret;
}
......@@ -2541,15 +2532,11 @@ int zones_schedule_refresh(knot_zone_t *zone, int64_t time)
evsched_t *sch = zd->server->sched;
if (zd->xfr_in.timer) {
evsched_cancel(sch, zd->xfr_in.timer);
evsched_event_free(sch, zd->xfr_in.timer);
zd->xfr_in.timer = 0;
}
/* Cancel EXPIRE timer. */
if (zd->xfr_in.expire) {
evsched_cancel(sch, zd->xfr_in.expire);
evsched_event_free(sch, zd->xfr_in.expire);
zd->xfr_in.expire = 0;
}
/* Check XFR/IN master server. */
......@@ -2566,8 +2553,7 @@ int zones_schedule_refresh(knot_zone_t *zone, int64_t time)
time = zd->xfr_in.bootstrap_retry;
}
zd->xfr_in.timer = evsched_schedule_cb(sch, zones_refresh_ev,
zone, time);
evsched_schedule(sch, zd->xfr_in.timer, time);
dbg_zones("zone: REFRESH '%s' set to %"PRIi64"\n",
zd->conf->name, time);
zd->xfr_in.state = XFR_SCHED;
......@@ -2578,17 +2564,11 @@ int zones_schedule_refresh(knot_zone_t *zone, int64_t time)
return KNOT_EOK;
}
static int zones_dnssec_ev(event_t *event, bool force)
int zones_dnssec_sign(knot_zone_t *zone, bool force, uint32_t *expires_at)
{
// We will be working with zone, don't want it to change in the meantime
knot_zone_t *zone = (knot_zone_t *)event->data;
zonedata_t *zd = (zonedata_t *)zone->data;
rcu_read_lock();
assert(zd->conf->dnssec_enable);
int ret = KNOT_EOK;
char *msgpref = NULL;
uint32_t expires_at = 0;
*expires_at = 0;
knot_changesets_t *chs = knot_changesets_create();
if (chs == NULL) {
......@@ -2611,16 +2591,16 @@ static int zones_dnssec_ev(event_t *event, bool force)
if (force) {
log_zone_info("%s Complete resign started (dropping all "
"previous signatures)...\n", msgpref);
"previous signatures)...\n", msgpref);
} else {
log_zone_info("%s Signing zone...\n", msgpref);
}
if (force) {
ret = knot_dnssec_zone_sign_force(zone, ch, &expires_at);
ret = knot_dnssec_zone_sign_force(zone, ch, expires_at);
} else {
ret = knot_dnssec_zone_sign(zone, ch, KNOT_SOA_SERIAL_INC,
&expires_at);
expires_at);
}
if (ret != KNOT_EOK) {
goto done;
......@@ -2629,11 +2609,11 @@ static int zones_dnssec_ev(event_t *event, bool force)
if (!zones_changesets_empty(chs)) {
knot_zone_contents_t *new_c = NULL;
ret = zones_store_and_apply_chgsets(chs, zone, &new_c, "DNSSEC",
XFR_TYPE_UPDATE);
XFR_TYPE_UPDATE);
chs = NULL; // freed by zones_store_and_apply_chgsets()
if (ret != KNOT_EOK) {
log_zone_error("%s Could not sign zone (%s).\n",
msgpref, knot_strerror(ret));
msgpref, knot_strerror(ret));
goto done;
}
}
......@@ -2643,38 +2623,27 @@ static int zones_dnssec_ev(event_t *event, bool force)
done:
knot_changesets_free(&chs);
free(msgpref);
return ret;
}
int zones_dnssec_ev(event_t *event)
{
// We will be working with zone, don't want it to change in the meantime
rcu_read_lock();
knot_zone_t *zone = (knot_zone_t *)event->data;
uint32_t expires_at = 0;
int ret = zones_dnssec_sign(zone, false, &expires_at);
if (expires_at != 0) {
ret = zones_schedule_dnssec(zone,
expiration_to_relative(expires_at,
zone),
false);
zone));
}
rcu_read_unlock();
return ret;
}
static int zones_dnssec_regular_ev(event_t *event)
{
assert(event);
if (event->data == NULL) {
return KNOT_EINVAL;
}
return zones_dnssec_ev(event, false);
}
static int zones_dnssec_forced_ev(event_t *event)
{
assert(event);
if (event->data == NULL) {
return KNOT_EINVAL;
}
return zones_dnssec_ev(event, true);
}
int zones_cancel_dnssec(knot_zone_t *zone)
{
if (!zone || !zone->data) {
......@@ -2691,7 +2660,7 @@ int zones_cancel_dnssec(knot_zone_t *zone)
return KNOT_EOK;
}
int zones_schedule_dnssec(knot_zone_t *zone, uint32_t time, bool force)
int zones_schedule_dnssec(knot_zone_t *zone, uint32_t time)
{
if (!zone || !zone->data) {
return KNOT_EINVAL;
......@@ -2709,17 +2678,6 @@ int zones_schedule_dnssec(knot_zone_t *zone, uint32_t time, bool force)
if (zd->dnssec_timer) {
// Event created already, just reschedule
evsched_schedule(scheduler, zd->dnssec_timer, time);
} else {
// Create new event
if (force) {
zd->dnssec_timer = evsched_schedule_cb(scheduler,
zones_dnssec_forced_ev,
zone, time);
} else {
zd->dnssec_timer = evsched_schedule_cb(scheduler,
zones_dnssec_regular_ev,
zone, time);
}
}
return KNOT_EOK;
......@@ -2732,20 +2690,12 @@ int zones_schedule_dnssec(knot_zone_t *zone, uint32_t time, bool force)
void zones_schedule_ixfr_sync(knot_zone_t *zone, int dbsync_timeout)
{
assert(zone);
assert(zone->data);
zonedata_t *zd = zone->data;
evsched_t *scheduler = zd->server->sched;
if (zd->ixfr_db != NULL) {
assert(zd->ixfr_dbsync == NULL);
assert(zd->server && zd->server->iosched);
evsched_t *scheduler = zd->server->sched;
zd->ixfr_dbsync = evsched_schedule_cb(scheduler,
zones_zonefile_sync_ev,
zone,
dbsync_timeout * 1000);
if (zd->ixfr_dbsync != NULL) {
evsched_schedule(scheduler, zd->ixfr_dbsync, dbsync_timeout * 1000);
}
}
......@@ -2987,8 +2937,6 @@ int zones_journal_apply(knot_zone_t *zone)
int zones_do_diff_and_sign(const conf_zone_t *z, knot_zone_t *zone,
const knot_nameserver_t *ns, bool zone_changed)
{
/* Cancel possibly running signing event. */
zones_cancel_dnssec(zone);
/* Calculate differences. */
rcu_read_lock();
knot_zone_t *z_old = knot_zonedb_find_zone(ns->zone_db,
......@@ -3145,8 +3093,7 @@ int zones_do_diff_and_sign(const conf_zone_t *z, knot_zone_t *zone,
if (z->dnssec_enable) {
ret = zones_schedule_dnssec(zone,
expiration_to_relative(expires_at,
zone),
false);
zone));
}
return ret;
......
......@@ -319,7 +319,7 @@ int zones_cancel_dnssec(knot_zone_t *zone);
*
* \return Error code, KNOT_OK if successful.
*/
int zones_schedule_dnssec(knot_zone_t *zone, uint32_t time, bool force);
int zones_schedule_dnssec(knot_zone_t *zone, uint32_t time);
/*!
* \brief Schedule IXFR sync for given zone.
......@@ -376,6 +376,17 @@ int zones_journal_apply(knot_zone_t *zone);
int zones_do_diff_and_sign(const conf_zone_t *z, knot_zone_t *zone,
const knot_nameserver_t *ns, bool zone_changed);
/*! \brief Just sign current zone. */
int zones_dnssec_sign(knot_zone_t *zone, bool force, uint32_t *expires_at);
/*
* Event callbacks.
*/
int zones_expire_ev(event_t *e);
int zones_refresh_ev(event_t *e);
int zones_flush_ev(event_t *e);
int zones_dnssec_ev(event_t *event);
#endif // _KNOTD_ZONES_H_
......
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