MAJOR: dns: runtime resolution can change server admin state

WARNING: this is a MAJOR (and disruptive) change with previous HAProxy's
behavior: before, HAProxy never ever used to change a server administrative
status when the DNS resolution failed at run time.

This patch gives HAProxy the ability to change the administrative status
of a server to MAINT (RMAINT actually) when an error is encountered for
a period longer than its own allowed by the corresponding 'hold'
parameter.

IE if the configuration sets "hold nx 10s" and a server's hostname
points to a NX for more than 10s, then the server will be set to RMAINT,
hence in MAINTENANCE mode.
This commit is contained in:
Baptiste Assmann 2016-11-02 22:58:18 +01:00 committed by Willy Tarreau
parent 987e16d6f4
commit 3b9fe9f8f4

View file

@ -2845,6 +2845,9 @@ out:
int snr_update_srv_status(struct server *s)
{
struct dns_resolution *resolution = s->resolution;
struct dns_resolvers *resolvers;
resolvers = resolution->resolvers;
switch (resolution->status) {
case RSLV_STATUS_NONE:
@ -2852,7 +2855,59 @@ int snr_update_srv_status(struct server *s)
trigger_resolution(s);
break;
case RSLV_STATUS_VALID:
/*
* resume health checks
* server will be turned back on if health check is safe
*/
if (!(s->admin & SRV_ADMF_RMAINT))
return 1;
srv_clr_admin_flag(s, SRV_ADMF_RMAINT);
chunk_printf(&trash, "Server %s/%s administratively READY thanks to valid DNS answer",
s->proxy->id, s->id);
Warning("%s.\n", trash.str);
send_log(s->proxy, LOG_NOTICE, "%s.\n", trash.str);
return 0;
case RSLV_STATUS_NX:
/* stop server if resolution is NX for a long enough period */
if (tick_is_expired(tick_add(resolution->last_status_change, resolvers->hold.nx), now_ms)) {
if (s->admin & SRV_ADMF_RMAINT)
return 1;
srv_set_admin_flag(s, SRV_ADMF_RMAINT, "DNS NX status");
return 0;
}
break;
case RSLV_STATUS_TIMEOUT:
/* stop server if resolution is TIMEOUT for a long enough period */
if (tick_is_expired(tick_add(resolution->last_status_change, resolvers->hold.timeout), now_ms)) {
if (s->admin & SRV_ADMF_RMAINT)
return 1;
srv_set_admin_flag(s, SRV_ADMF_RMAINT, "DNS timeout status");
return 0;
}
break;
case RSLV_STATUS_REFUSED:
/* stop server if resolution is REFUSED for a long enough period */
if (tick_is_expired(tick_add(resolution->last_status_change, resolvers->hold.refused), now_ms)) {
if (s->admin & SRV_ADMF_RMAINT)
return 1;
srv_set_admin_flag(s, SRV_ADMF_RMAINT, "DNS refused status");
return 0;
}
break;
default:
/* stop server if resolution is in unmatched error for a long enough period */
if (tick_is_expired(tick_add(resolution->last_status_change, resolvers->hold.other), now_ms)) {
if (s->admin & SRV_ADMF_RMAINT)
return 1;
srv_set_admin_flag(s, SRV_ADMF_RMAINT, "unspecified DNS error");
return 0;
}
break;
}