Hello Raghu,

On Thu, Jan 11, 2018 at 02:20:34PM +0530, Raghu Udiyar wrote:
> Hello,
> 
> Haproxy 1.7.10 segfaults when the srv_admin_state is set to
> SRV_ADMF_CMAINT (0x04)
> for a backend server, and that backend has the `slowstart` option set.
> 
> The following configuration reproduces it :
(...)

Thanks for all the details, they made it easy to reproduce.

>From what I'm seeing, it's a fundamental design issue in the state
file handling in 1.7. It starts checks before they have been
initialized, and try to wake up a NULL task. In 1.8 due to the more
dynamic config, the initialization sequence has changed and checks
are initialized before parsing the state file, but I don't feel at
ease with doing in 1.7 since I don't know if some config elements
may remain non-updated.

So instead I've just protected against using the task wakeups during
the state file parsing, and they will be initialized later with the
appropriate parameters.

Could you please check the attached patch on top of 1.7.10 ?

Thanks,
Willy
diff --git a/src/server.c b/src/server.c
index 66e8f8a..e847723 100644
--- a/src/server.c
+++ b/src/server.c
@@ -318,8 +318,10 @@ void srv_set_running(struct server *s, const char *reason)
        s->last_change = now.tv_sec;
 
        s->state = SRV_ST_STARTING;
-       if (s->slowstart > 0)
-               task_schedule(s->warmup, tick_add(now_ms, MS_TO_TICKS(MAX(1000, 
s->slowstart / 20))));
+       if (s->slowstart > 0) {
+               if (s->warmup)
+                       task_schedule(s->warmup, tick_add(now_ms, 
MS_TO_TICKS(MAX(1000, s->slowstart / 20))));
+       }
        else
                s->state = SRV_ST_RUNNING;
 
@@ -622,8 +624,10 @@ void srv_clr_admin_flag(struct server *s, enum srv_admin 
mode)
                                s->state = SRV_ST_STOPPING;
                        else {
                                s->state = SRV_ST_STARTING;
-                               if (s->slowstart > 0)
-                                       task_schedule(s->warmup, 
tick_add(now_ms, MS_TO_TICKS(MAX(1000, s->slowstart / 20))));
+                               if (s->slowstart > 0) {
+                                       if (s->warmup)
+                                               task_schedule(s->warmup, 
tick_add(now_ms, MS_TO_TICKS(MAX(1000, s->slowstart / 20))));
+                               }
                                else
                                        s->state = SRV_ST_RUNNING;
                        }

Reply via email to