]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: checks: use an enum instead of flags to report a check result
authorWilly Tarreau <w@1wt.eu>
Wed, 11 Dec 2013 16:09:34 +0000 (17:09 +0100)
committerWilly Tarreau <w@1wt.eu>
Sat, 14 Dec 2013 15:02:19 +0000 (16:02 +0100)
We used to have up to 4 sets of flags which were almost all exclusive
to report a check result. And the names were inherited from the old
server states, adding to the confusion. Let's replace that with an
enum handling only the possible combinations :

   SRV_CHK_UNKNOWN                   => CHK_RES_UNKNOWN
   SRV_CHK_FAILED                    => CHK_RES_FAILED
   SRV_CHK_PASSED                    => CHK_RES_PASSED
   SRV_CHK_PASSED | SRV_CHK_DISABLE  => CHK_RES_CONDPASS

include/types/checks.h
src/checks.c

index 381c990fbd7f6e359d9d4948d5539e10fe28e424..0af329b6c5f6d70cc79150a61f829fb99be14f19 100644 (file)
 #include <types/task.h>
 #include <types/server.h>
 
-
-/* bits for s->result used for health-checks */
-#define SRV_CHK_UNKNOWN 0x0000
-#define SRV_CHK_FAILED  0x0001
-#define SRV_CHK_PASSED  0x0002
-#define SRV_CHK_DISABLE 0x0004
+/* enum used by check->result. Must remain in this order, as some code uses
+ * result >= CHK_RES_PASSED to declare success.
+ */
+enum chk_result {
+       CHK_RES_UNKNOWN = 0,            /* initialized to this by default */
+       CHK_RES_FAILED,                 /* check failed */
+       CHK_RES_PASSED,                 /* check succeeded and server is fully up again */
+       CHK_RES_CONDPASS,               /* check reports the server doesn't want new sessions */
+};
 
 /* check flags */
 #define CHK_STATE_RUNNING      0x0001  /* this check is currently running */
@@ -130,7 +133,7 @@ struct check {
        int send_proxy;                         /* send a PROXY protocol header with checks */
        struct tcpcheck_rule *current_step;     /* current step when using tcpcheck */
        int inter, fastinter, downinter;        /* checks: time in milliseconds */
-       int result;                             /* health-check result : SRV_CHK_* */
+       enum chk_result result;                 /* health-check result : CHK_RES_* */
        int state;                              /* health-check result : CHK_* */
        int health;                             /* 0 to rise-1 = bad;
                                                 * rise to rise+fall-1 = good */
index 069d06d448f2bbc41a1d506cfe04fb1120d694b9..b00654289f792e343fbb5506fccafe8cea162dc2 100644 (file)
@@ -56,30 +56,30 @@ static int tcpcheck_get_step_id(struct server *);
 static void tcpcheck_main(struct connection *);
 
 static const struct check_status check_statuses[HCHK_STATUS_SIZE] = {
-       [HCHK_STATUS_UNKNOWN]   = { SRV_CHK_UNKNOWN,                   "UNK",     "Unknown" },
-       [HCHK_STATUS_INI]       = { SRV_CHK_UNKNOWN,                   "INI",     "Initializing" },
+       [HCHK_STATUS_UNKNOWN]   = { CHK_RES_UNKNOWN,  "UNK",     "Unknown" },
+       [HCHK_STATUS_INI]       = { CHK_RES_UNKNOWN,  "INI",     "Initializing" },
        [HCHK_STATUS_START]     = { /* SPECIAL STATUS*/ },
 
-       [HCHK_STATUS_HANA]      = { SRV_CHK_FAILED,                    "HANA",    "Health analyze" },
+       [HCHK_STATUS_HANA]      = { CHK_RES_FAILED,   "HANA",    "Health analyze" },
 
-       [HCHK_STATUS_SOCKERR]   = { SRV_CHK_FAILED,                    "SOCKERR", "Socket error" },
+       [HCHK_STATUS_SOCKERR]   = { CHK_RES_FAILED,   "SOCKERR", "Socket error" },
 
-       [HCHK_STATUS_L4OK]      = { SRV_CHK_PASSED,                    "L4OK",    "Layer4 check passed" },
-       [HCHK_STATUS_L4TOUT]    = { SRV_CHK_FAILED,                    "L4TOUT",  "Layer4 timeout" },
-       [HCHK_STATUS_L4CON]     = { SRV_CHK_FAILED,                    "L4CON",   "Layer4 connection problem" },
+       [HCHK_STATUS_L4OK]      = { CHK_RES_PASSED,   "L4OK",    "Layer4 check passed" },
+       [HCHK_STATUS_L4TOUT]    = { CHK_RES_FAILED,   "L4TOUT",  "Layer4 timeout" },
+       [HCHK_STATUS_L4CON]     = { CHK_RES_FAILED,   "L4CON",   "Layer4 connection problem" },
 
-       [HCHK_STATUS_L6OK]      = { SRV_CHK_PASSED,                    "L6OK",    "Layer6 check passed" },
-       [HCHK_STATUS_L6TOUT]    = { SRV_CHK_FAILED,                    "L6TOUT",  "Layer6 timeout" },
-       [HCHK_STATUS_L6RSP]     = { SRV_CHK_FAILED,                    "L6RSP",   "Layer6 invalid response" },
+       [HCHK_STATUS_L6OK]      = { CHK_RES_PASSED,   "L6OK",    "Layer6 check passed" },
+       [HCHK_STATUS_L6TOUT]    = { CHK_RES_FAILED,   "L6TOUT",  "Layer6 timeout" },
+       [HCHK_STATUS_L6RSP]     = { CHK_RES_FAILED,   "L6RSP",   "Layer6 invalid response" },
 
-       [HCHK_STATUS_L7TOUT]    = { SRV_CHK_FAILED,                    "L7TOUT",  "Layer7 timeout" },
-       [HCHK_STATUS_L7RSP]     = { SRV_CHK_FAILED,                    "L7RSP",   "Layer7 invalid response" },
+       [HCHK_STATUS_L7TOUT]    = { CHK_RES_FAILED,   "L7TOUT",  "Layer7 timeout" },
+       [HCHK_STATUS_L7RSP]     = { CHK_RES_FAILED,   "L7RSP",   "Layer7 invalid response" },
 
        [HCHK_STATUS_L57DATA]   = { /* DUMMY STATUS */ },
 
-       [HCHK_STATUS_L7OKD]     = { SRV_CHK_PASSED,                    "L7OK",    "Layer7 check passed" },
-       [HCHK_STATUS_L7OKCD]    = { SRV_CHK_PASSED | SRV_CHK_DISABLE,  "L7OKC",   "Layer7 check conditionally passed" },
-       [HCHK_STATUS_L7STS]     = { SRV_CHK_FAILED,                    "L7STS",   "Layer7 wrong status" },
+       [HCHK_STATUS_L7OKD]     = { CHK_RES_PASSED,   "L7OK",    "Layer7 check passed" },
+       [HCHK_STATUS_L7OKCD]    = { CHK_RES_CONDPASS, "L7OKC",   "Layer7 check conditionally passed" },
+       [HCHK_STATUS_L7STS]     = { CHK_RES_FAILED,   "L7STS",   "Layer7 wrong status" },
 };
 
 static const struct analyze_status analyze_statuses[HANA_STATUS_SIZE] = {              /* 0: ignore, 1: error, 2: OK */
@@ -193,7 +193,7 @@ static void server_status_printf(struct chunk *msg, struct server *s, struct che
 
 /*
  * Set check->status, update check->duration and fill check->result with
- * an adequate SRV_CHK_* value.
+ * an adequate CHK_RES_* value.
  *
  * Show information in logs about failed health check if server is UP
  * or succeeded health checks if server is DOWN.
@@ -203,7 +203,7 @@ static void set_server_check_status(struct check *check, short status, const cha
        struct server *s = check->server;
 
        if (status == HCHK_STATUS_START) {
-               check->result = SRV_CHK_UNKNOWN;        /* no result yet */
+               check->result = CHK_RES_UNKNOWN;        /* no result yet */
                check->desc[0] = '\0';
                check->start = now;
                return;
@@ -237,13 +237,13 @@ static void set_server_check_status(struct check *check, short status, const cha
                return;
 
        if (s->proxy->options2 & PR_O2_LOGHCHKS &&
-       (((check->health != 0) && (check->result & SRV_CHK_FAILED)) ||
+       (((check->health != 0) && (check->result == CHK_RES_FAILED)) ||
            (((check->health != check->rise + check->fall - 1) ||
              (!s->uweight && !(s->state & SRV_DRAIN)) ||
              (s->uweight && (s->state & SRV_DRAIN))) &&
-            (check->result & SRV_CHK_PASSED)) ||
-           ((s->state & SRV_GOINGDOWN) && !(check->result & SRV_CHK_DISABLE)) ||
-           (!(s->state & SRV_GOINGDOWN) && (check->result & SRV_CHK_DISABLE)))) {
+            (check->result >= CHK_RES_PASSED)) ||
+           ((s->state & SRV_GOINGDOWN) && (check->result != CHK_RES_CONDPASS)) ||
+           (!(s->state & SRV_GOINGDOWN) && (check->result == CHK_RES_CONDPASS)))) {
 
                int health, rise, fall, state;
 
@@ -255,7 +255,8 @@ static void set_server_check_status(struct check *check, short status, const cha
                fall   = check->fall;
                state  = s->state;
 
-               if (check->result & SRV_CHK_FAILED) {
+               switch (check->result) {
+               case CHK_RES_FAILED:
                        if (health > rise) {
                                health--; /* still good */
                        } else {
@@ -264,9 +265,10 @@ static void set_server_check_status(struct check *check, short status, const cha
 
                                health = 0;
                        }
-               }
+                       break;
 
-               if (check->result & SRV_CHK_PASSED) {
+               case CHK_RES_PASSED:
+               case CHK_RES_CONDPASS:
                        if (health < rise + fall - 1) {
                                health++; /* was bad, stays for a while */
 
@@ -280,15 +282,17 @@ static void set_server_check_status(struct check *check, short status, const cha
                        /* clear consecutive_errors if observing is enabled */
                        if (s->onerror)
                                s->consecutive_errors = 0;
+                       break;
+               default:
+                       break;
                }
-               /* FIXME end: calculate local version of the health/rise/fall/state */
 
                chunk_appendf(&trash,
                             "Health check for %sserver %s/%s %s%s",
                             s->state & SRV_BACKUP ? "backup " : "",
                             s->proxy->id, s->id,
-                            (check->result & SRV_CHK_DISABLE)?"conditionally ":"",
-                            (check->result & SRV_CHK_PASSED)?"succeeded":"failed");
+                            (check->result == CHK_RES_CONDPASS) ? "conditionally ":"",
+                            (check->result >= CHK_RES_PASSED)   ? "succeeded":"failed");
 
                server_status_printf(&trash, s, check, -1);
 
@@ -834,7 +838,7 @@ static void chk_report_conn_err(struct connection *conn, int errno_bck, int expi
        const char *err_msg;
        struct chunk *chk;
 
-       if (check->result != SRV_CHK_UNKNOWN)
+       if (check->result != CHK_RES_UNKNOWN)
                return;
 
        errno = errno_bck;
@@ -923,7 +927,7 @@ static void event_srv_chk_w(struct connection *conn)
        struct server *s = check->server;
        struct task *t = check->task;
 
-       if (unlikely(check->result & SRV_CHK_FAILED))
+       if (unlikely(check->result == CHK_RES_FAILED))
                goto out_wakeup;
 
        if (conn->flags & (CO_FL_HANDSHAKE | CO_FL_WAIT_WR))
@@ -1000,7 +1004,7 @@ static void event_srv_chk_r(struct connection *conn)
        int done;
        unsigned short msglen;
 
-       if (unlikely(check->result & SRV_CHK_FAILED))
+       if (unlikely(check->result == CHK_RES_FAILED))
                goto out_wakeup;
 
        if (conn->flags & (CO_FL_HANDSHAKE | CO_FL_WAIT_RD))
@@ -1400,7 +1404,7 @@ static void event_srv_chk_r(struct connection *conn)
                conn->xprt->shutw(conn, 0);
 
        /* OK, let's not stay here forever */
-       if (check->result & SRV_CHK_FAILED)
+       if (check->result == CHK_RES_FAILED)
                conn->flags |= CO_FL_ERROR;
 
        __conn_data_stop_both(conn);
@@ -1433,7 +1437,7 @@ static int wake_srv_chk(struct connection *conn)
                task_wakeup(check->task, TASK_WOKEN_IO);
        }
 
-       if (check->result & (SRV_CHK_FAILED|SRV_CHK_PASSED)) {
+       if (check->result != CHK_RES_UNKNOWN) {
                /* We're here because nobody wants to handle the error, so we
                 * sure want to abort the hard way.
                 */
@@ -1637,7 +1641,7 @@ static struct task *process_chk(struct task *t)
                 * First, let's check whether there was an uncaught error,
                 * which can happen on connect timeout or error.
                 */
-               if (s->check.result == SRV_CHK_UNKNOWN) {
+               if (s->check.result == CHK_RES_UNKNOWN) {
                        /* good connection is enough for pure TCP check */
                        if ((conn->flags & CO_FL_CONNECTED) && !check->type) {
                                if (check->use_ssl)
@@ -1667,14 +1671,14 @@ static struct task *process_chk(struct task *t)
                        conn_force_close(conn);
                }
 
-               if (check->result & SRV_CHK_FAILED)  /* a failure or timeout detected */
+               if (check->result == CHK_RES_FAILED)  /* a failure or timeout detected */
                        check_failed(check);
                else {  /* check was OK */
                        /* we may have to add/remove this server from the LB group */
                        if ((s->state & SRV_RUNNING) && (s->proxy->options & PR_O_DISABLE404)) {
-                               if ((s->state & SRV_GOINGDOWN) && !(check->result & SRV_CHK_DISABLE))
+                               if ((s->state & SRV_GOINGDOWN) && (check->result != CHK_RES_CONDPASS))
                                        set_server_enabled(check);
-                               else if (!(s->state & SRV_GOINGDOWN) && (check->result & SRV_CHK_DISABLE))
+                               else if (!(s->state & SRV_GOINGDOWN) && (check->result == CHK_RES_CONDPASS))
                                        set_server_disabled(check);
                        }
 
@@ -1962,9 +1966,8 @@ static void tcpcheck_main(struct connection *conn)
        }
 
        /* here, we know that the connection is established */
-       if (check->result & (SRV_CHK_FAILED | SRV_CHK_PASSED)) {
+       if (check->result != CHK_RES_UNKNOWN)
                goto out_end_tcpcheck;
-       }
 
        /* head is be the first element of the double chained list */
        head = &s->proxy->tcpcheck_rules;
@@ -2052,7 +2055,7 @@ static void tcpcheck_main(struct connection *conn)
                        check->current_step = cur;
                } /* end 'send' */
                else if (check->current_step->action == TCPCHK_ACT_EXPECT) {
-                       if (unlikely(check->result & SRV_CHK_FAILED))
+                       if (unlikely(check->result == CHK_RES_FAILED))
                                goto out_end_tcpcheck;
 
                        if ((conn->flags & CO_FL_WAIT_RD) ||
@@ -2194,7 +2197,7 @@ static void tcpcheck_main(struct connection *conn)
 
        check->current_step = NULL;
 
-       if (check->result & SRV_CHK_FAILED)
+       if (check->result == CHK_RES_FAILED)
                conn->flags |= CO_FL_ERROR;
 
        __conn_data_stop_both(conn);