]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: checks: Associate a session to each tcp-check healthcheck
authorGaetan Rivet <grive@u256.net>
Fri, 14 Feb 2020 16:42:54 +0000 (17:42 +0100)
committerChristopher Faulet <cfaulet@haproxy.com>
Mon, 27 Apr 2020 07:39:37 +0000 (09:39 +0200)
Create a session for each healthcheck relying on a tcp-check ruleset. When such
check is started, a session is allocated, which will be freed when the check
finishes. A dummy static frontend is used to create these sessions. This will be
useful to support variables and sample expression. This will also be used,
later, by HTTP healthchecks to rely on HTTP muxes.

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

index 6826ac3f5f26c7adb1a3af6f86a52f389a61f48a..f92f0da60ddfede5aadd044382a91974c79112ae 100644 (file)
@@ -158,6 +158,7 @@ enum {
 };
 
 struct check {
+       struct session *sess;                   /* Health check session. */
        struct xprt_ops *xprt;                  /* transport layer operations for health checks */
        struct conn_stream *cs;                 /* conn_stream state for health checks */
        struct buffer bi, bo;                   /* input and output buffers to send/recv check */
index 0a1390c1dcb77a7c134a9901e7e0a48245f10f36..49a0f3da64b1fb4fae0151fce4b3bb082fcd27fa 100644 (file)
@@ -76,6 +76,8 @@ static int srv_check_healthcheck_port(struct check *chk);
 DECLARE_STATIC_POOL(pool_head_email_alert,   "email_alert",   sizeof(struct email_alert));
 DECLARE_STATIC_POOL(pool_head_tcpcheck_rule, "tcpcheck_rule", sizeof(struct tcpcheck_rule));
 
+/* Dummy frontend used to create all checks sessions. */
+static struct proxy checks_fe;
 
 static const struct check_status check_statuses[HCHK_STATUS_SIZE] = {
        [HCHK_STATUS_UNKNOWN]   = { CHK_RES_UNKNOWN,  "UNK",     "Unknown" },
@@ -2405,6 +2407,13 @@ static struct task *process_chk_conn(struct task *t, void *context, unsigned sho
                }
 
                /* check complete or aborted */
+
+               check->current_step = NULL;
+               if (check->sess != NULL) {
+                       session_free(check->sess);
+                       check->sess = NULL;
+               }
+
                if (conn && conn->xprt) {
                        /* The check was aborted and the connection was not yet closed.
                         * This can happen upon timeout, or when an external event such
@@ -2527,6 +2536,15 @@ static int start_checks()
        struct task *t;
        int nbcheck=0, mininter=0, srvpos=0;
 
+       /* 0- init the dummy frontend used to create all checks sessions */
+       init_new_proxy(&checks_fe);
+       checks_fe.cap = PR_CAP_FE | PR_CAP_BE;
+        checks_fe.mode = PR_MODE_TCP;
+       checks_fe.maxconn = 0;
+       checks_fe.conn_retries = CONN_RETRIES;
+       checks_fe.options2 |= PR_O2_INDEPSTR | PR_O2_SMARTCON | PR_O2_SMARTACC;
+       checks_fe.timeout.client = TICK_ETERNITY;
+
        /* 1- count the checkers to run simultaneously.
         * We also determine the minimum interval among all of those which
         * have an interval larger than SRV_CHK_INTER_THRES. This interval
@@ -2859,7 +2877,7 @@ static enum tcpcheck_eval_ret tcpcheck_eval_connect(struct check *check, struct
                : ((connect->options & TCPCHK_OPT_SSL) ? xprt_get(XPRT_SSL) : xprt_get(XPRT_RAW)));
 
        conn_prepare(conn, proto, xprt);
-       if (conn_install_mux(conn, &mux_pt_ops, cs, proxy, NULL) < 0) {
+       if (conn_install_mux(conn, &mux_pt_ops, cs, proxy, check->sess) < 0) {
                status = SF_ERR_RESOURCE;
                goto fail_check;
        }
@@ -3204,8 +3222,16 @@ static int tcpcheck_main(struct check *check)
                else
                        rule = check->current_step;
        }
-       else
+       else {
+               /* First evaluation, create a session */
+               check->sess = session_new(&checks_fe, NULL, NULL);
+               if (!check->sess) {
+                       chunk_printf(&trash, "TCPCHK error allocating check session");
+                       set_server_check_status(check, HCHK_STATUS_SOCKERR, trash.area);
+                       goto out_end_tcpcheck;
+               }
                rule = LIST_NEXT(check->tcpcheck_rules, typeof(rule), list);
+       }
 
        list_for_each_entry_from(rule, check->tcpcheck_rules, list) {
                enum tcpcheck_eval_ret eval_ret;
@@ -3305,10 +3331,6 @@ static int tcpcheck_main(struct check *check)
 
        /* All rules was evaluated */
        set_server_check_status(check, HCHK_STATUS_L7OKD, "(tcp-check)");
-       check->current_step = NULL;
-
-  out:
-       return retcode;
 
   out_end_tcpcheck:
        if ((conn && conn->flags & CO_FL_ERROR) || (cs && cs->flags & CS_FL_ERROR))
@@ -3316,8 +3338,13 @@ static int tcpcheck_main(struct check *check)
 
        /* cleanup before leaving */
        check->current_step = NULL;
+       if (check->sess != NULL) {
+               session_free(check->sess);
+               check->sess = NULL;
+       }
+  out:
+       return retcode;
 
-       goto out;
 }
 
 static const char *init_check(struct check *check, int type)