]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: server: don't always trust srv_check_health when loading a server state
authorJérôme Magnin <jmagnin@haproxy.com>
Sun, 20 Jan 2019 10:27:40 +0000 (11:27 +0100)
committerWilly Tarreau <w@1wt.eu>
Mon, 21 Jan 2019 10:09:03 +0000 (11:09 +0100)
When we load health values from a server state file, make sure what we assign
to srv->check.health actually matches the state we restore.

This should be backported as far as 1.6.

src/server.c

index 6ff4c3ad9d88b1cfb23c4dad9620f7afb36c665c..7fbe558c5d8c58bf5f98f2c8c339289b11bb3b5f 100644 (file)
@@ -3039,16 +3039,37 @@ static void srv_update_state(struct server *srv, int version, char **params)
                        HA_SPIN_LOCK(SERVER_LOCK, &srv->lock);
                        /* recover operational state and apply it to this server
                         * and all servers tracking this one */
+                       srv->check.health = srv_check_health;
                        switch (srv_op_state) {
                                case SRV_ST_STOPPED:
                                        srv->check.health = 0;
                                        srv_set_stopped(srv, "changed from server-state after a reload", NULL);
                                        break;
                                case SRV_ST_STARTING:
+                                       /* If rise == 1 there is no STARTING state, let's switch to
+                                        * RUNNING
+                                        */
+                                       if (srv->check.rise == 1) {
+                                               srv->check.health = srv->check.rise + srv->check.fall - 1;
+                                               srv_set_running(srv, "", NULL);
+                                               break;
+                                       }
+                                       if (srv->check.health < 1 || srv->check.health >= srv->check.rise)
+                                               srv->check.health = srv->check.rise - 1;
                                        srv->next_state = srv_op_state;
                                        break;
                                case SRV_ST_STOPPING:
-                                       srv->check.health = srv->check.rise + srv->check.fall - 1;
+                                       /* If fall == 1 there is no STOPPING state, let's switch to
+                                        * STOPPED
+                                        */
+                                       if (srv->check.fall == 1) {
+                                               srv->check.health = 0;
+                                               srv_set_stopped(srv, "changed from server-state after a reload", NULL);
+                                               break;
+                                       }
+                                       if (srv->check.health < srv->check.rise ||
+                                           srv->check.health > srv->check.rise + srv->check.fall - 2)
+                                               srv->check.health = srv->check.rise;
                                        srv_set_stopping(srv, "changed from server-state after a reload", NULL);
                                        break;
                                case SRV_ST_RUNNING:
@@ -3102,7 +3123,6 @@ static void srv_update_state(struct server *srv, int version, char **params)
                        srv->last_change = date.tv_sec - srv_last_time_change;
                        srv->check.status = srv_check_status;
                        srv->check.result = srv_check_result;
-                       srv->check.health = srv_check_health;
 
                        /* Only case we want to apply is removing ENABLED flag which could have been
                         * done by the "disable health" command over the stats socket