From: Willy Tarreau Date: Tue, 20 May 2014 20:32:27 +0000 (+0200) Subject: MEDIUM: checks: simplify failure notification using srv_set_stopped() X-Git-Tag: v1.5-dev26~23 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4eec547f32fd111d321483fd4f249a1cb78a3c82;p=thirdparty%2Fhaproxy.git MEDIUM: checks: simplify failure notification using srv_set_stopped() Function check_set_server_down() used to set a server down. Now it first checks if the health check's result differs from the server's state, and only calls srv_set_stopped() if the check reports a failure while the server is not down. Thanks to this, the conditions that were present around its call could be removed. The function was also renamed check_notify_failure() to better report this change. --- diff --git a/src/checks.c b/src/checks.c index a92d5d77da..a30368f93d 100644 --- a/src/checks.c +++ b/src/checks.c @@ -292,21 +292,12 @@ static void set_server_check_status(struct check *check, short status, const cha } } -/* Marks the check 's server down, notifies by all available means, - * recounts the remaining servers on the proxy and transfers queued sessions - * whenever possible to other servers. It automatically recomputes the number - * of servers, but not the map. Maintenance servers are ignored. +/* Marks the check 's server down if the current check is already failed + * and the server is not down yet nor in maintenance. */ -static void check_set_server_down(struct check *check) +static void check_notify_failure(struct check *check) { struct server *s = check->server; - struct server *srv; - int prev_srv_count = s->proxy->srv_bck + s->proxy->srv_act; - int srv_was_stopping = (s->state == SRV_ST_STOPPING); - int xferred; - - if ((s->admin & SRV_ADMF_MAINT) || s->state == SRV_ST_STOPPED) - return; /* The agent secondary check should only cause a server to be marked * as down if check->status is HCHK_STATUS_L7STS, which indicates @@ -317,44 +308,11 @@ static void check_set_server_down(struct check *check) if ((check->state & CHK_ST_AGENT) && check->status != HCHK_STATUS_L7STS) return; - check->health = 0; /* failure */ - s->last_change = now.tv_sec; - s->state = SRV_ST_STOPPED; - if (s->proxy->lbprm.set_server_status_down) - s->proxy->lbprm.set_server_status_down(s); - - if (s->onmarkeddown & HANA_ONMARKEDDOWN_SHUTDOWNSESSIONS) - srv_shutdown_sessions(s, SN_ERR_DOWN); - - /* we might have sessions queued on this server and waiting for - * a connection. Those which are redispatchable will be queued - * to another server or to the proxy itself. - */ - xferred = pendconn_redistribute(s); - - chunk_printf(&trash, - "%sServer %s/%s is DOWN", s->flags & SRV_F_BACKUP ? "Backup " : "", - s->proxy->id, s->id); - - srv_append_status(&trash, s, - ((!s->track && !(s->proxy->options2 & PR_O2_LOGHCHKS)) ? check_reason_string(check) : NULL), - xferred, 0); - - Warning("%s.\n", trash.str); - - /* we don't send an alert if the server was previously paused */ - if (srv_was_stopping) - send_log(s->proxy, LOG_NOTICE, "%s.\n", trash.str); - else - send_log(s->proxy, LOG_ALERT, "%s.\n", trash.str); - - if (prev_srv_count && s->proxy->srv_bck == 0 && s->proxy->srv_act == 0) - set_backend_down(s->proxy); - - s->counters.down_trans++; + if (check->health > 0) + return; - for (srv = s->trackers; srv; srv = srv->tracknext) - check_set_server_down(&srv->check); + /* We only report a reason for the check if we did not do so previously */ + srv_set_stopped(s, (!s->track && !(s->proxy->options2 & PR_O2_LOGHCHKS)) ? check_reason_string(check) : NULL); } /* Marks the check as valid and tries to set its server up, provided @@ -542,18 +500,14 @@ void __health_adjust(struct server *s, short status) case HANA_ONERR_FAILCHK: /* simulate a failed health check */ set_server_check_status(&s->check, HCHK_STATUS_HANA, trash.str); - if (!s->check.health) - check_set_server_down(&s->check); - + check_notify_failure(&s->check); break; case HANA_ONERR_MARKDWN: /* mark server down */ s->check.health = s->check.rise; set_server_check_status(&s->check, HCHK_STATUS_HANA, trash.str); - if (!s->check.health) - check_set_server_down(&s->check); - + check_notify_failure(&s->check); break; default: @@ -1495,8 +1449,7 @@ static struct task *process_chk(struct task *t) /* here, we have seen a synchronous error, no fd was allocated */ check->state &= ~CHK_ST_INPROGRESS; - if (!check->health) - check_set_server_down(check); + check_notify_failure(check); /* we allow up to min(inter, timeout.connect) for a connection * to establish but only when timeout.check is set @@ -1545,8 +1498,7 @@ static struct task *process_chk(struct task *t) if (check->result == CHK_RES_FAILED) { /* a failure or timeout detected */ - if (!check->health && check->server->state != SRV_ST_STOPPED) - check_set_server_down(check); + check_notify_failure(check); } else if (check->result == CHK_RES_CONDPASS && s->state != SRV_ST_STOPPED && !(s->admin & SRV_ADMF_MAINT)) { /* check is OK but asks for drain mode */