]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
REORG/MEDIUM: server: move the maintenance bits out of the server state
authorWilly Tarreau <w@1wt.eu>
Tue, 13 May 2014 17:44:56 +0000 (19:44 +0200)
committerWilly Tarreau <w@1wt.eu>
Thu, 22 May 2014 09:27:00 +0000 (11:27 +0200)
Now we introduce srv->admin and srv->prev_admin which are bitfields
containing one bit per source of administrative status (maintenance only
for now). For the sake of backwards compatibility we implement a single
source (ADMF_FMAINT) but the code already checks any source (ADMF_MAINT)
where the STF_MAINTAIN bit was previously checked. This will later allow
us to add ADMF_IMAINT for maintenance mode inherited from tracked servers.

Along doing these changes, it appeared that some places will need to be
revisited when implementing the inherited bit, this concerns all those
modifying the ADMF_FMAINT bit (enable/disable actions on the CLI or stats
page), and the checks to report "via" on the stats page. But currently
the code is harmless.

include/proto/backend.h
include/types/server.h
src/backend.c
src/cfgparse.c
src/checks.c
src/dumpstats.c
src/server.c

index 8043613f15ab7efd22dd304ec0b6092ead928e20..601a61ada0fdb4e5b4d34272787f057f539f625e 100644 (file)
@@ -61,7 +61,9 @@ static inline int srv_is_usable(const struct server *srv)
 
        if (!srv->eweight)
                return 0;
-       if (state & (SRV_STF_GOINGDOWN | SRV_STF_MAINTAIN))
+       if (srv->admin & SRV_ADMF_MAINT)
+               return 0;
+       if (state & SRV_STF_GOINGDOWN)
                return 0;
        if (!(state & SRV_STF_RUNNING))
                return 0;
@@ -77,7 +79,9 @@ static inline int srv_was_usable(const struct server *srv)
 
        if (!srv->prev_eweight)
                return 0;
-       if (state & (SRV_STF_GOINGDOWN | SRV_STF_MAINTAIN))
+       if (srv->prev_admin & SRV_ADMF_MAINT)
+               return 0;
+       if (state & SRV_STF_GOINGDOWN)
                return 0;
        if (!(state & SRV_STF_RUNNING))
                return 0;
@@ -90,6 +94,7 @@ static inline int srv_was_usable(const struct server *srv)
 static inline void srv_lb_commit_status(struct server *srv)
 {
        srv->prev_state = srv->state;
+       srv->prev_admin = srv->admin;
        srv->prev_eweight = srv->eweight;
 }
 
@@ -99,6 +104,7 @@ static inline void srv_lb_commit_status(struct server *srv)
 static inline int srv_lb_status_changed(const struct server *srv)
 {
        return (srv->state != srv->prev_state ||
+               srv->admin != srv->prev_admin ||
                srv->eweight != srv->prev_eweight);
 }
 
index 6b77b15818c0165fe4f99ce76d549e27a38f79f5..ba0a1a51f3210b9ee0e1e4ffafaa9da06b1a83a3 100644 (file)
@@ -48,7 +48,16 @@ enum srv_state {
        SRV_STF_RUNNING    = 0x1,        /* the server is UP */
        SRV_STF_GOINGDOWN  = 0x2,        /* the server is going down (eg: 404) */
        SRV_STF_WARMINGUP  = 0x4,        /* the server is warming up after a failure */
-       SRV_STF_MAINTAIN   = 0x8,        /* the server is in maintenance mode */
+};
+
+/* Maintenance mode : each server may be in maintenance by itself or may inherit
+ * this status from another server it tracks. Let's store these origins here as
+ * flags. If no maintenance origin is specified, the server is not in maintenance.
+ */
+enum srv_admin {
+       SRV_ADMF_FMAINT    = 0x1,        /* the server was explicitly forced into maintenance */
+       SRV_ADMF_IMAINT    = 0x2,        /* the server has inherited the maintenance status from a tracked server */
+       SRV_ADMF_MAINT     = 0x3,        /* mask to check if any maintenance flag is present */
 };
 
 /* server flags */
@@ -105,6 +114,7 @@ struct tree_occ {
 struct server {
        enum obj_type obj_type;                 /* object type == OBJ_TYPE_SERVER */
        enum srv_state state, prev_state;       /* server state among SRV_STF_* */
+       enum srv_admin admin, prev_admin;       /* server maintenance status : SRV_ADMF_* */
        unsigned char flags;                    /* server flags (SRV_F_*) */
        struct server *next;
        int cklen;                              /* the len of the cookie, to speed up checks */
index 3ce7415da8286f178467574291be1f70472bf13b..0b4ff4dec28c920f7a7da634c94660fd2d644f8f 100644 (file)
@@ -1489,7 +1489,7 @@ smp_fetch_srv_is_up(struct proxy *px, struct session *l4, void *l7, unsigned int
 
        smp->flags = SMP_F_VOL_TEST;
        smp->type = SMP_T_BOOL;
-       if (!(srv->state & SRV_STF_MAINTAIN) &&
+       if (!(srv->admin & SRV_ADMF_MAINT) &&
            (!(srv->check.state & CHK_ST_CONFIGURED) || (srv->state & SRV_STF_RUNNING)))
                smp->data.uint = 1;
        else
index a002cb2344c1236a6911b6756e5aefa66c5fc685..037eaa913b41b715da0103ddb759247d705c2248 100644 (file)
@@ -6617,7 +6617,7 @@ out_uri_auth_compat:
                                }
 
                                /* if the other server is forced disabled, we have to do the same here */
-                               if (srv->state & SRV_STF_MAINTAIN) {
+                               if (srv->admin & SRV_ADMF_MAINT) {
                                        newsrv->state &= ~SRV_STF_RUNNING;
                                        newsrv->check.health = 0;
                                        newsrv->agent.health = 0;
index 9228c89580c4108c887686b89de20ee4941db0ca..f4bfd54b4bb18196811d9aa4aeba5ca7a3646751 100644 (file)
@@ -412,7 +412,7 @@ void set_server_down(struct check *check)
        struct server *srv;
        int xferred;
 
-       if (s->state & SRV_STF_MAINTAIN) {
+       if (s->admin & SRV_ADMF_MAINT) {
                check->health = check->rise;
        }
 
@@ -436,7 +436,7 @@ void set_server_down(struct check *check)
 
                chunk_reset(&trash);
 
-               if (s->state & SRV_STF_MAINTAIN) {
+               if (s->admin & SRV_ADMF_MAINT) {
                        chunk_appendf(&trash,
                                     "%sServer %s/%s is DOWN for maintenance", s->flags & SRV_F_BACKUP ? "Backup " : "",
                                     s->proxy->id, s->id);
@@ -463,7 +463,7 @@ void set_server_down(struct check *check)
                s->counters.down_trans++;
 
                for (srv = s->trackers; srv; srv = srv->tracknext)
-                       if (!(srv->state & SRV_STF_MAINTAIN))
+                       if (!(srv->admin & SRV_ADMF_MAINT))
                                /* Only notify tracking servers that are not already in maintenance. */
                                set_server_down(&srv->check);
        }
@@ -476,9 +476,9 @@ void set_server_up(struct check *check) {
        struct server *s = check->server;
        struct server *srv;
        int xferred;
-       enum srv_state old_state = s->state;
+       enum srv_admin old_admin = s->admin;
 
-       if (s->state & SRV_STF_MAINTAIN) {
+       if (s->admin & SRV_ADMF_MAINT) {
                check->health = check->rise;
        }
 
@@ -499,7 +499,7 @@ void set_server_up(struct check *check) {
 
                s->last_change = now.tv_sec;
                s->state |= SRV_STF_RUNNING;
-               s->state &= ~SRV_STF_MAINTAIN;
+               s->admin &= ~SRV_ADMF_FMAINT;
                s->check.state &= ~CHK_ST_PAUSED;
 
                if (s->slowstart > 0) {
@@ -525,7 +525,7 @@ void set_server_up(struct check *check) {
 
                chunk_reset(&trash);
 
-               if (old_state & SRV_STF_MAINTAIN) {
+               if (old_admin) {
                        chunk_appendf(&trash,
                                     "%sServer %s/%s is UP (leaving maintenance)", s->flags & SRV_F_BACKUP ? "Backup " : "",
                                     s->proxy->id, s->id);
@@ -543,7 +543,7 @@ void set_server_up(struct check *check) {
                send_log(s->proxy, LOG_NOTICE, "%s.\n", trash.str);
 
                for (srv = s->trackers; srv; srv = srv->tracknext)
-                       if (!(srv->state & SRV_STF_MAINTAIN))
+                       if (!(srv->admin & SRV_ADMF_MAINT))
                                /* Only notify tracking servers if they're not in maintenance. */
                                set_server_up(&srv->check);
        }
@@ -1480,7 +1480,8 @@ static struct task *server_warmup(struct task *t)
 
        /* by default, plan on stopping the task */
        t->expire = TICK_ETERNITY;
-       if ((s->state & (SRV_STF_RUNNING|SRV_STF_WARMINGUP|SRV_STF_MAINTAIN)) != (SRV_STF_RUNNING|SRV_STF_WARMINGUP))
+       if ((s->admin & SRV_ADMF_MAINT) ||
+           (s->state & (SRV_STF_RUNNING|SRV_STF_WARMINGUP)) != (SRV_STF_RUNNING|SRV_STF_WARMINGUP))
                return t;
 
        server_recalc_eweight(s);
@@ -1707,7 +1708,7 @@ static struct task *process_chk(struct task *t)
                                        set_server_disabled(check);
                        }
 
-                       if (!(s->state & SRV_STF_MAINTAIN) &&
+                       if (!(s->admin & SRV_ADMF_MAINT) &&
                            check->health < check->rise + check->fall - 1) {
                                check->health++; /* was bad, stays for a while */
                                set_server_up(check);
index 47328cecc77a5797be3788e9d47473b2c83e9b58..1de4199fd20204523864c416cbaa73bc45e0fa22 100644 (file)
@@ -1710,7 +1710,7 @@ static int stats_sock_parse_request(struct stream_interface *si, char *line)
                        if (!sv)
                                return 1;
 
-                       if (sv->state & SRV_STF_MAINTAIN) {
+                       if (sv->admin & SRV_ADMF_MAINT) {
                                /* The server is really in maintenance, we can change the server state */
                                if (sv->track) {
                                        /* If this server tracks the status of another one,
@@ -1720,7 +1720,7 @@ static int stats_sock_parse_request(struct stream_interface *si, char *line)
                                                set_server_up(&sv->check);
                                                sv->check.health = sv->check.rise;      /* up, but will fall down at first failure */
                                        } else {
-                                               sv->state &= ~SRV_STF_MAINTAIN;
+                                               sv->admin &= ~SRV_ADMF_FMAINT;
                                                sv->check.state &= ~CHK_ST_PAUSED;
                                                set_server_down(&sv->check);
                                        }
@@ -1782,9 +1782,9 @@ static int stats_sock_parse_request(struct stream_interface *si, char *line)
                        if (!sv)
                                return 1;
 
-                       if (! (sv->state & SRV_STF_MAINTAIN)) {
+                       if (!(sv->admin & SRV_ADMF_MAINT)) {
                                /* Not already in maintenance, we can change the server state */
-                               sv->state |= SRV_STF_MAINTAIN;
+                               sv->admin |= SRV_ADMF_FMAINT;
                                sv->check.state |= CHK_ST_PAUSED;
                                set_server_down(&sv->check);
                        }
@@ -2780,7 +2780,7 @@ static int stats_dump_sv_stats(struct stream_interface *si, struct proxy *px, in
                        "<i>no check</i>"
                };
 
-               if ((sv->state & SRV_STF_MAINTAIN) || (ref->state & SRV_STF_MAINTAIN))
+               if ((sv->admin | ref->admin) & SRV_ADMF_MAINT)
                        chunk_appendf(&trash, "<tr class=\"maintain\">");
                else
                        chunk_appendf(&trash,
@@ -2911,11 +2911,11 @@ static int stats_dump_sv_stats(struct stream_interface *si, struct proxy *px, in
                /* status, lest check */
                chunk_appendf(&trash, "<td class=ac>");
 
-               if (sv->state & SRV_STF_MAINTAIN) {
+               if (sv->admin & SRV_ADMF_MAINT) {
                        chunk_appendf(&trash, "%s ", human_time(now.tv_sec - sv->last_change, 1));
                        chunk_appendf(&trash, "MAINT");
                }
-               else if (ref != sv && ref->state & SRV_STF_MAINTAIN) {
+               else if (ref != sv && (ref->admin & SRV_ADMF_MAINT)) {
                        chunk_appendf(&trash, "%s ", human_time(now.tv_sec - ref->last_change, 1));
                        chunk_appendf(&trash, "MAINT(via)");
                }
@@ -2976,7 +2976,7 @@ static int stats_dump_sv_stats(struct stream_interface *si, struct proxy *px, in
                                      ref->counters.down_trans, human_time(srv_downtime(sv), 1));
                }
                else if (sv != ref) {
-                       if (sv->state & SRV_STF_MAINTAIN)
+                       if (sv->admin & SRV_ADMF_MAINT)
                                chunk_appendf(&trash, "<td class=ac colspan=3></td>");
                        else
                                chunk_appendf(&trash,
@@ -3030,9 +3030,9 @@ static int stats_dump_sv_stats(struct stream_interface *si, struct proxy *px, in
                              sv->counters.retries, sv->counters.redispatches);
 
                /* status */
-               if (sv->state & SRV_STF_MAINTAIN)
+               if (sv->admin & SRV_ADMF_MAINT)
                        chunk_appendf(&trash, "MAINT,");
-               else if (ref != sv && ref->state & SRV_STF_MAINTAIN)
+               else if (ref != sv && (ref->admin & SRV_ADMF_MAINT))
                        chunk_appendf(&trash, "MAINT(via),");
                else
                        chunk_appendf(&trash,
@@ -3638,7 +3638,7 @@ static int stats_dump_proxy_to_buffer(struct stream_interface *si, struct proxy
                                else
                                        sv_state = 0; /* DOWN */
 
-                       if (((sv_state == 0) || (sv->state & SRV_STF_MAINTAIN)) && (appctx->ctx.stats.flags & STAT_HIDE_DOWN)) {
+                       if (((sv_state == 0) || (sv->admin & SRV_ADMF_MAINT)) && (appctx->ctx.stats.flags & STAT_HIDE_DOWN)) {
                                /* do not report servers which are DOWN */
                                appctx->ctx.stats.sv = sv->next;
                                continue;
@@ -4249,9 +4249,9 @@ static int stats_process_http_post(struct stream_interface *si)
                                else if ((sv = findserver(px, value)) != NULL) {
                                        switch (action) {
                                        case ST_ADM_ACTION_DISABLE:
-                                               if ((px->state != PR_STSTOPPED) && !(sv->state & SRV_STF_MAINTAIN)) {
+                                               if ((px->state != PR_STSTOPPED) && !(sv->admin & SRV_ADMF_MAINT)) {
                                                        /* Not already in maintenance, we can change the server state */
-                                                       sv->state |= SRV_STF_MAINTAIN;
+                                                       sv->admin |= SRV_ADMF_FMAINT;
                                                        sv->check.state |= CHK_ST_PAUSED;
                                                        set_server_down(&sv->check);
                                                        altered_servers++;
@@ -4259,7 +4259,7 @@ static int stats_process_http_post(struct stream_interface *si)
                                                }
                                                break;
                                        case ST_ADM_ACTION_ENABLE:
-                                               if ((px->state != PR_STSTOPPED) && (sv->state & SRV_STF_MAINTAIN)) {
+                                               if ((px->state != PR_STSTOPPED) && (sv->admin & SRV_ADMF_MAINT)) {
                                                        /* Already in maintenance, we can change the server state.
                                                         * If this server tracks the status of another one,
                                                         * we must restore the good status.
@@ -4269,7 +4269,7 @@ static int stats_process_http_post(struct stream_interface *si)
                                                                sv->check.health = sv->check.rise;      /* up, but will fall down at first failure */
                                                        }
                                                        else {
-                                                               sv->state &= ~SRV_STF_MAINTAIN;
+                                                               sv->admin &= ~SRV_ADMF_FMAINT;
                                                                sv->check.state &= ~CHK_ST_PAUSED;
                                                                set_server_down(&sv->check);
                                                        }
index dc0883e8da0152c65c3cc387beecef6af9ddc592..7309f4281c2d53edca5b37b1309f7d4ba99cd405 100644 (file)
@@ -346,6 +346,7 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr
                        do_check = 0;
                        do_agent = 0;
                        newsrv->flags = 0;
+                       newsrv->admin = 0;
                        newsrv->state = SRV_STF_RUNNING; /* early server setup */
                        newsrv->last_change = now.tv_sec;
                        newsrv->id = strdup(args[1]);
@@ -680,7 +681,7 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr
                                cur_arg += 1;
                        }
                        else if (!defsrv && !strcmp(args[cur_arg], "disabled")) {
-                               newsrv->state |= SRV_STF_MAINTAIN;
+                               newsrv->admin |= SRV_ADMF_FMAINT;
                                newsrv->state &= ~SRV_STF_RUNNING;
                                newsrv->check.state |= CHK_ST_PAUSED;
                                newsrv->check.health = 0;