BUG/MEDIUM: server: support changing the slowstart value from state-file

If the slowstart value in a state file implies the latest state change
is within the slowstart period, we end up calling srv_update_status()
to reschedule the server's state change but its task is not yet
allocated and remains null, causing a crash on startup.

Make sure srv_update_status() supports being called with partially
initialized servers which do not yet have a task. If the task has to
be scheduled, it will necessarily happen after initialization since
it will result from a state change.

This should be backported wherever server-state is present.
This commit is contained in:
Willy Tarreau 2020-10-22 11:30:59 +02:00
parent 5c643f37d0
commit 1e690bb6c4

View File

@ -4630,7 +4630,9 @@ INITCALL1(STG_REGISTER, cli_register_kw, &cli_kws);
* This function applies server's status changes, it is
* is designed to be called asynchronously.
*
* Must be called with the server lock held.
* Must be called with the server lock held. This may also be called at init
* time as the result of parsing the state file, in which case no lock will be
* held, and the server's warmup task can be null.
*/
static void srv_update_status(struct server *s)
{
@ -4730,7 +4732,7 @@ static void srv_update_status(struct server *s)
s->down_time += now.tv_sec - s->last_change;
s->last_change = now.tv_sec;
if (s->next_state == SRV_ST_STARTING)
if (s->next_state == SRV_ST_STARTING && s->warmup)
task_schedule(s->warmup, tick_add(now_ms, MS_TO_TICKS(MAX(1000, s->slowstart / 20))));
server_recalc_eweight(s, 0);
@ -4908,8 +4910,10 @@ static void srv_update_status(struct server *s)
}
else {
s->next_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->next_state = SRV_ST_RUNNING;
}