diff --git a/backport-BUG-MINOR-server-fix-slowstart-behavior.patch b/backport-BUG-MINOR-server-fix-slowstart-behavior.patch new file mode 100644 index 0000000000000000000000000000000000000000..b197eb9c7765e4e2c77f96051fb36eeb746dc779 --- /dev/null +++ b/backport-BUG-MINOR-server-fix-slowstart-behavior.patch @@ -0,0 +1,80 @@ +From c4a7d314dee32ffc6d9bc70171594f8142ecee87 Mon Sep 17 00:00:00 2001 +From: Damien Claisse +Date: Tue, 9 Apr 2024 15:37:07 +0000 +Subject: [PATCH] BUG/MINOR: server: fix slowstart behavior + +We observed that a dynamic server which health check is down for longer +than slowstart delay at startup doesn't trigger the warmup phase, it +receives full traffic immediately. This has been confirmed by checking +haproxy UI, weight is immediately the full one (e.g. 75/75), without any +throttle applied. Further tests showed that it was similar if it was in +maintenance, and even when entering a down or maintenance state after +being up. +Another issue is that if the server is down for less time than +slowstart, when it comes back up, it briefly has a much higher weight +than expected for a slowstart. + +An easy way to reproduce is to do the following: +- Add a server with e.g. a 20s slowstart and a weight of 10 in config + file +- Put it in maintenance using CLI (set server be1/srv1 state maint) +- Wait more than 20s, enable it again (set server be1/srv1 state ready) +- Observe UI, weight will show 10/10 immediately. +If server was down for less than 20s, you'd briefly see a weight and +throttle value that is inconsistent, e.g. 50% throttle value and a +weight of 5 if server comes back up after 10s before going back to +6% after a second or two. + +Code analysis shows that the logic in server_recalc_eweight stops the +warmup task by setting server's next state to SRV_ST_RUNNING if it +didn't change state for longer than the slowstart duration, regardless +of its current state. As a consequence, a server being down or disabled +for longer than the slowstart duration will never enter the warmup phase +when it will be up again. + +Regarding the weight when server comes back up, issue is that even if +the server is down, we still compute its next weight as if it was up, +hence when it comes back up, it can briefly have a much higher weight +than expected during slowstart, until the warmup task is called again +after last_change is updated. + +This patch aims to fix both issues. + +(cherry picked from commit 0797e05d9f0577d9239d4265667ea536a2439db0) +Signed-off-by: Christopher Faulet +(cherry picked from commit a6c0926ba1ca5eac00b0bcd25934f89b9693ddb0) +Signed-off-by: Christopher Faulet +(cherry picked from commit 2c2699ecd4f1a552a199fb50caa610575e7b2b76) +Signed-off-by: Christopher Faulet + +Conflict: NA +Reference:https://github.com/haproxy/haproxy/commit/c4a7d314dee32ffc6d9bc70171594f8142ecee87 +--- + src/server.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/src/server.c b/src/server.c +index 6112464f3f41..181794926924 100644 +--- a/src/server.c ++++ b/src/server.c +@@ -1835,15 +1835,17 @@ void server_recalc_eweight(struct server *sv, int must_update) + unsigned w; + + if (now.tv_sec < sv->last_change || now.tv_sec >= sv->last_change + sv->slowstart) { +- /* go to full throttle if the slowstart interval is reached */ +- if (sv->next_state == SRV_ST_STARTING) ++ /* go to full throttle if the slowstart interval is reached unless server is currently down */ ++ if ((sv->cur_state != SRV_ST_STOPPED) && (sv->next_state == SRV_ST_STARTING)) + sv->next_state = SRV_ST_RUNNING; + } + + /* We must take care of not pushing the server to full throttle during slow starts. + * It must also start immediately, at least at the minimal step when leaving maintenance. + */ +- if ((sv->next_state == SRV_ST_STARTING) && (px->lbprm.algo & BE_LB_PROP_DYN)) ++ if ((sv->cur_state == SRV_ST_STOPPED) && (sv->next_state == SRV_ST_STARTING) && (px->lbprm.algo & BE_LB_PROP_DYN)) ++ w = 1; ++ else if ((sv->next_state == SRV_ST_STARTING) && (px->lbprm.algo & BE_LB_PROP_DYN)) + w = (px->lbprm.wdiv * (now.tv_sec - sv->last_change) + sv->slowstart) / sv->slowstart; + else + w = px->lbprm.wdiv; diff --git a/haproxy.spec b/haproxy.spec index bfd815bfdc90caaae03902faa809c2e9c8603a98..fa5113c5c3fa1ce46d264135e410ead30da33c14 100644 --- a/haproxy.spec +++ b/haproxy.spec @@ -5,7 +5,7 @@ Name: haproxy Version: 2.6.6 -Release: 16 +Release: 17 Summary: The Reliable, High Performance TCP/HTTP Load Balancer License: GPLv2+ @@ -45,6 +45,7 @@ Patch24: backport-BUG-MEDIUM-queues-Do-not-use-pendconn_grab_from_px.pa Patch25: backport-BUG-MEDIUM-queues-Make-sure-we-call-process_srv_queu.patch Patch26: backport-BUG-MEDIUM-queue-Make-process_srv_queue-return-the-n.patch Patch27: backport-CVE-2025-32464.patch +Patch28: backport-BUG-MINOR-server-fix-slowstart-behavior.patch BuildRequires: gcc lua-devel pcre2-devel openssl-devel systemd-devel systemd libatomic %ifarch sw_64 @@ -149,6 +150,12 @@ exit 0 %{_mandir}/man1/* %changelog +* Mon Jun 23 2025 xinghe - 2.6.6-17 +- Type:bugfix +- CVE:NA +- SUG:NA +- DESC:fix slowstart behavior + * Tue Apr 29 2025 xinghe - 2.6.6-16 - Type:cves - CVE:CVE-2025-32464