diff --git a/src/common/evsched.c b/src/common/evsched.c index 5061fe670047370cb22bc4ccc446f6bc982cc13c..6fa0fa8c6f178924893ad6a6a00daf17ccf5dc5f 100644 --- a/src/common/evsched.c +++ b/src/common/evsched.c @@ -19,6 +19,7 @@ #include <stdlib.h> #include <stdio.h> +#include "common/errcode.h" #include "common/evsched.h" /*! \todo Fix properly (issue #1581). */ @@ -64,13 +65,13 @@ static void evsched_settimer(event_t *e, uint32_t dt) } /*! \brief Singleton application-wide event scheduler. */ -evsched_t *s_evsched = 0; +evsched_t *s_evsched = NULL; evsched_t *evsched_new() { evsched_t *s = malloc(sizeof(evsched_t)); if (!s) { - return 0; + return NULL; } memset(s, 0, sizeof(evsched_t)); @@ -88,10 +89,7 @@ evsched_t *evsched_new() void evsched_delete(evsched_t **s) { - if (!s) { - return; - } - if (!*s) { + if (s == NULL || *s == NULL) { return; } @@ -119,13 +117,13 @@ void evsched_delete(evsched_t **s) /* Free scheduler. */ free(*s); - *s = 0; + *s = NULL; } event_t *evsched_event_new(evsched_t *s, int type) { if (!s) { - return 0; + return NULL; } /* Allocate. */ @@ -165,7 +163,7 @@ event_t* evsched_next(evsched_t *s) { /* Check. */ if (!s) { - return 0; + return NULL; } /* Lock calendar. */ @@ -214,31 +212,31 @@ event_t* evsched_next(evsched_t *s) /* Unlock calendar, this shouldn't happen. */ pthread_mutex_unlock(&s->mx); - return 0; + return NULL; } int evsched_event_finished(evsched_t *s) { if (!s) { - return -1; + return KNOT_EINVAL; } /* Mark as finished. */ if (s->cur) { s->cur = NULL; pthread_mutex_unlock(&s->rl); - return 0; + return KNOT_EOK; } - /* Finished event is not current. */ - return -1; + /* No event running. */ + return KNOT_ENOTRUNNING; } int evsched_schedule(evsched_t *s, event_t *ev, uint32_t dt) { if (!s || !ev) { - return -1; + return KNOT_EINVAL; } /* Update event timer. */ @@ -254,19 +252,19 @@ int evsched_schedule(evsched_t *s, event_t *ev, uint32_t dt) pthread_cond_broadcast(&s->notify); pthread_mutex_unlock(&s->mx); - return 0; + return KNOT_EOK; } event_t* evsched_schedule_cb(evsched_t *s, event_cb_t cb, void *data, uint32_t dt) { if (!s) { - return 0; + return NULL; } /* Create event. */ event_t *e = evsched_event_new(s, EVSCHED_CB); if (!e) { - return 0; + return NULL; } e->cb = cb; e->data = data; @@ -274,7 +272,7 @@ event_t* evsched_schedule_cb(evsched_t *s, event_cb_t cb, void *data, uint32_t d /* Schedule. */ if (evsched_schedule(s, e, dt) != 0) { evsched_event_free(s, e); - e = 0; + e = NULL; } return e; @@ -283,30 +281,30 @@ event_t* evsched_schedule_cb(evsched_t *s, event_cb_t cb, void *data, uint32_t d event_t* evsched_schedule_term(evsched_t *s, uint32_t dt) { if (!s) { - return 0; + return NULL; } /* Create event. */ event_t *e = evsched_event_new(s, EVSCHED_TERM); if (!e) { - return 0; + return NULL; } /* Schedule. */ if (evsched_schedule(s, e, dt) != 0) { evsched_event_free(s, e); - e = 0; + e = NULL; } return e; } -int evsched_cancel(evsched_t *s, event_t *ev) +static int evsched_try_cancel(evsched_t *s, event_t *ev) { - int found; + int found = 0; if (!s || !ev) { - return -1; + return KNOT_EINVAL; } /* Make sure not running. */ @@ -325,7 +323,7 @@ int evsched_cancel(evsched_t *s, event_t *ev) */ if (s->cur == ev) { s->cur = NULL; /* Invalidate */ - found = 1; /* Mark as found (although not in heap). */ + found = KNOT_EAGAIN; /* Already ran, try again. */ } /* Unlock calendar. */ @@ -334,6 +332,25 @@ int evsched_cancel(evsched_t *s, event_t *ev) /* Enable running events. */ pthread_mutex_unlock(&s->rl); + if (found) { + return KNOT_EOK; + } + + return KNOT_ENOENT; +} + +int evsched_cancel(evsched_t *s, event_t *ev) +{ + if (!s || !ev) { + return KNOT_EINVAL; + } + + /* Event may have already run, try again. */ + int ret = KNOT_EAGAIN; + while (ret == KNOT_EAGAIN) { + ret = evsched_try_cancel(s, ev); + } - return found; + /* Now we're sure event is cancelled or finished. */ + return KNOT_EOK; } diff --git a/src/common/evsched.h b/src/common/evsched.h index 907874985310685f422bbb0476622f82ea54729f..4e710a59b803cf1e1e1dd4224bebe4775a7aecbe 100644 --- a/src/common/evsched.h +++ b/src/common/evsched.h @@ -155,8 +155,9 @@ event_t* evsched_next(evsched_t *s); * * \param s Event scheduler. * - * \retval 0 if successful. - * \retval -1 on errors. + * \retval KNOT_EOK if successful. + * \retval KNOT_EINVAL + * \retval KNOT_ENOTRUNNING */ int evsched_event_finished(evsched_t *s); @@ -167,8 +168,8 @@ int evsched_event_finished(evsched_t *s); * \param ev Prepared event. * \param dt Time difference in milliseconds from now (dt is relative). * - * \retval 0 on success. - * \retval <0 on error. + * \retval KNOT_EOK on success. + * \retval KNOT_EINVAL */ int evsched_schedule(evsched_t *s, event_t *ev, uint32_t dt); @@ -212,9 +213,8 @@ event_t* evsched_schedule_term(evsched_t *s, uint32_t dt); * \param s Event scheduler. * \param ev Scheduled event. * - * \retval 0 if already ran. - * \retval 1 if found and cancelled. - * \retval <0 on error. + * \retval KNOT_EOK + * \retval KNOT_EINVAL */ int evsched_cancel(evsched_t *s, event_t *ev); diff --git a/src/knot/server/zones.c b/src/knot/server/zones.c index 2ce56164513cab547f5170a98ce6fa0dca481937..6541777ce52c37ef4d9cfe0adcc476ee5e45c857 100644 --- a/src/knot/server/zones.c +++ b/src/knot/server/zones.c @@ -470,6 +470,9 @@ int zones_changesets_from_binary(knot_changesets_t *chgsets) knot_changeset_t* chs = NULL; WALK_LIST(chs, chgsets->sets) { /* Read changeset flags. */ + if (chs->data == NULL) { + return KNOT_EMALF; + } size_t remaining = chs->size; memcpy(&chs->flags, chs->data, sizeof(uint32_t)); remaining -= sizeof(uint32_t); @@ -2569,8 +2572,6 @@ done: knot_changesets_free(&chs); free(msgpref); - evsched_event_free(event->parent, event); - zd->dnssec_timer = NULL; if (expires_at != 0) { ret = zones_schedule_dnssec(zone, expiration_to_relative(expires_at, @@ -2613,8 +2614,6 @@ int zones_cancel_dnssec(knot_zone_t *zone) if (zd->dnssec_timer) { evsched_cancel(scheduler, zd->dnssec_timer); - evsched_event_free(scheduler, zd->dnssec_timer); - zd->dnssec_timer = NULL; } return KNOT_EOK; @@ -2635,16 +2634,20 @@ int zones_schedule_dnssec(knot_zone_t *zone, uint32_t time, bool force) time / 3600000); free(zname); -// TODO: throw an error if the new signing event is more in the future than the old one - - if (force) { - zd->dnssec_timer = evsched_schedule_cb(scheduler, - zones_dnssec_forced_ev, - zone, time); + if (zd->dnssec_timer) { + // Event created already, just reschedule + evsched_schedule(scheduler, zd->dnssec_timer, time); } else { - zd->dnssec_timer = evsched_schedule_cb(scheduler, - zones_dnssec_regular_ev, - zone, time); + // 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; @@ -2912,6 +2915,8 @@ 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, @@ -2963,6 +2968,7 @@ int zones_do_diff_and_sign(const conf_zone_t *z, knot_zone_t *zone, knot_changesets_t *sec_chs = NULL; knot_changeset_t *sec_ch = NULL; knot_zone_contents_t *new_contents = NULL; + uint32_t expires_at = 0; if (z->dnssec_enable) { sec_chs = knot_changesets_create(); if (sec_chs == NULL) { @@ -2988,7 +2994,6 @@ int zones_do_diff_and_sign(const conf_zone_t *z, knot_zone_t *zone, log_zone_info("DNSSEC: Zone %s - Signing started...\n", z->name); - uint32_t expires_at = 0; int ret = knot_dnssec_zone_sign(zone, sec_ch, soa_up, &expires_at); if (ret != KNOT_EOK) { @@ -2997,21 +3002,6 @@ int zones_do_diff_and_sign(const conf_zone_t *z, knot_zone_t *zone, rcu_read_unlock(); return ret; } - - // Schedule next zone signing - zones_cancel_dnssec(zone); - ret = zones_schedule_dnssec(zone, - expiration_to_relative(expires_at, - zone), - false); - if (ret != KNOT_EOK) { - knot_changesets_free(&diff_chs); - knot_changesets_free(&sec_chs); - rcu_read_unlock(); - return ret; - } - } else { - zones_cancel_dnssec(zone); } /* Merge changesets created by diff and sign. */ @@ -3078,5 +3068,14 @@ int zones_do_diff_and_sign(const conf_zone_t *z, knot_zone_t *zone, rcu_read_unlock(); zones_free_merged_changesets(diff_chs, sec_chs); + + // Schedule next zone signing + if (z->dnssec_enable) { + ret = zones_schedule_dnssec(zone, + expiration_to_relative(expires_at, + zone), + false); + } + return ret; } diff --git a/tests/events.c b/tests/events.c index 664409d30253f6cbbe141987d2751cfcd6fc4415..2ba8177c19ebaccd36f44c8dd347c586a5e9d105 100644 --- a/tests/events.c +++ b/tests/events.c @@ -22,6 +22,7 @@ #include "common/evqueue.h" #include "common/evsched.h" +#include "common/errcode.h" void* term_thr(void *arg) { @@ -146,7 +147,7 @@ int main(int argc, char *argv[]) // 7. Insert and immediately cancel an event e = evsched_schedule_cb(s, 0, (void*)0xdead, 1000); ret = evsched_cancel(s, e); - ok(ret >= 0, "evsched: inserted and cancelled an event"); + ok(ret == KNOT_EOK, "evsched: inserted and cancelled an event"); if (e) { evsched_event_free(s, e); }