From 7d541a91ec6d51e3765d1776a6230f8d2a9b5e04 Mon Sep 17 00:00:00 2001 From: Aurelien DARRAGON Date: Wed, 7 Dec 2022 12:17:24 +0100 Subject: [PATCH] BUG/MINOR: checks: restore legacy on-error fastinter behavior With previous commit, 9e080bf ("BUG/MINOR: checks: make sure fastinter is used even on forced transitions"), on-error mark-down|sudden-death|fail-check are now working as expected. However, on-error fastinter remains broken because srv_getinter(), used in the above commit to check the expiration date, won't return fastinter interval if server health is maxed out (which is the case with on-error fastinter mode). To fix this, we introduce a check flag named CHK_ST_FASTINTER. This flag is set when on-error is triggered. This way we can force srv_getinter() to return fastinter interval whenever the flag is set. The flag is automatically cleared as soon as the new check task expiry is recalculated in process_chk_conn(). This restores original behavior prior to d114f4a ("MEDIUM: checks: spread the checks load over random threads"). It must be backported to 2.7 along with the aforementioned commits. --- include/haproxy/check-t.h | 1 + src/check.c | 9 +++++++++ src/server.c | 3 ++- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/include/haproxy/check-t.h b/include/haproxy/check-t.h index 6c569c39d..c489ae351 100644 --- a/include/haproxy/check-t.h +++ b/include/haproxy/check-t.h @@ -57,6 +57,7 @@ enum chk_result { #define CHK_ST_CLOSE_CONN 0x0100 /* check is waiting that the connection gets closed */ #define CHK_ST_PURGE 0x0200 /* check must be freed */ #define CHK_ST_SLEEPING 0x0400 /* check was sleeping */ +#define CHK_ST_FASTINTER 0x0800 /* force fastinter check */ /* check status */ enum healthcheck_status { diff --git a/src/check.c b/src/check.c index 0f5202898..931829fb5 100644 --- a/src/check.c +++ b/src/check.c @@ -670,6 +670,11 @@ void __health_adjust(struct server *s, short status) HA_SPIN_LOCK(SERVER_LOCK, &s->lock); + /* force fastinter for upcoming check + * (does nothing if fastinter is not enabled) + */ + s->check.state |= CHK_ST_FASTINTER; + switch (s->onerror) { case HANA_ONERR_FASTINTER: /* force fastinter - nothing to do here as all modes force it */ @@ -1285,6 +1290,10 @@ struct task *process_chk_conn(struct task *t, void *context, unsigned int state) rv -= (int) (2 * rv * (statistical_prng() / 4294967295.0)); } t->expire = tick_add(now_ms, MS_TO_TICKS(srv_getinter(check) + rv)); + /* reset fastinter flag (if set) so that srv_getinter() + * only returns fastinter if server health is degraded + */ + check->state &= ~CHK_ST_FASTINTER; } reschedule: diff --git a/src/server.c b/src/server.c index ed06687d5..0ad51b3ab 100644 --- a/src/server.c +++ b/src/server.c @@ -124,7 +124,8 @@ int srv_getinter(const struct check *check) { const struct server *s = check->server; - if ((check->state & CHK_ST_CONFIGURED) && (check->health == check->rise + check->fall - 1)) + if ((check->state & (CHK_ST_CONFIGURED|CHK_ST_FASTINTER)) == CHK_ST_CONFIGURED && + (check->health == check->rise + check->fall - 1)) return check->inter; if ((s->next_state == SRV_ST_STOPPED) && check->health == 0)