The syntax of this new command is:

set agent <backend>/<server> pause|unpause

This command changes the behaviour of agent checks as follows:

In the case where an agent check is being run as a secondary check,
due to the agent-port parameter of a server directive, new checks
are only initialised when the agent is in the unpaused state. Thus,
setting the agent to pause will prevent any new agent checks from
begin initiated until the agent is set to unpaused.

When set pause is in effect the processing of an agent check run as the
primary check, due to either option lb-agent-check or http-check
agent-hdr being set, or processing of a secondary agent check that was
initiated while the agent was set as unpaused is as follows: All results
that would alter the weight, specifically "drain" or a weight returned by
the agent, are ignored. The processing of agent check is otherwise
unchanged.

The motivation for this option is to allow weight setting is to allow the
weight changing effects of the agent checks to be paused to allow the
weight of a server to be configured using set weight without being
overridden by the agent.

The default state is unpaused.

Signed-off-by: Simon Horman <ho...@verge.net.au>
---
 doc/configuration.txt  | 24 ++++++++++++++++++++++++
 include/types/server.h |  1 +
 src/checks.c           | 25 ++++++++++++++++++++++---
 src/dumpstats.c        | 17 +++++++++++++++++
 4 files changed, 64 insertions(+), 3 deletions(-)

diff --git a/doc/configuration.txt b/doc/configuration.txt
index 40675f4..a82d48a 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -12088,6 +12088,30 @@ prompt
 quit
   Close the connection when in interactive mode.
 
+set agent <backend>/<server> pause|unpause
+  Change the behaviour of agent checks.
+
+  In the case where an agent check is being run as a secondary check,
+  due to the agent-port parameter of a server directive, new checks
+  are only initialised when the agent is in the unpaused state. Thus,
+  setting the agent to pause will prevent any new agent checks from
+  begin initiated until the agent is set to unpaused.
+
+  When set pause is in effect the processing of an agent check run as the
+  primary check, due to either option lb-agent-check or http-check
+  agent-hdr being set, or processing of a secondary agent check that was
+  initiated while the agent was set as unpaused is as follows: All results
+  that would alter the weight, specifically "drain" or a weight returned by
+  the agent, are ignored. The processing of agent check is otherwise
+  unchanged.
+
+  The motivation for this option is to allow weight setting is to allow the
+  weight changing effects of the agent checks to be paused to allow the
+  weight of a server to be configured using set weight without being
+  overridden by the agent.
+
+  The default state is unpaused.
+
 set maxconn frontend <frontend> <value>
   Dynamically change the specified frontend's maxconn setting. Any positive
   value is allowed including zero, but setting values larger than the global
diff --git a/include/types/server.h b/include/types/server.h
index 379b7dd..24462eb 100644
--- a/include/types/server.h
+++ b/include/types/server.h
@@ -73,6 +73,7 @@
 
 /* check flags */
 #define CHK_RUNNING    0x0001  /* this check is currently running */
+#define CHK_PAUSED     0x0002  /* this check is currently administratively 
paused */
 
 /* various constants */
 #define SRV_UWGHT_RANGE 256
diff --git a/src/checks.c b/src/checks.c
index c43d8ae..1f6a9ea 100644
--- a/src/checks.c
+++ b/src/checks.c
@@ -854,16 +854,31 @@ static void agent_expect(struct check *check, char *data)
        const char *desc = "Unknown feedback string";
        const char *down_cmd = NULL;
        int drain = 0;
+       int paused;
+
+       /* The agent may have been paused after a check was initialised.
+        * If so, ignore weight changes and drain settings from the agent.
+        * Note that the seting is always present in the the state of the
+        * agent the server, regardless of if the agent is being run
+        * as a primary or secondary check. That is, regardless
+        * of if the check parameter of this function is the agent or
+        * check field of the server.
+        */
+       paused = check->server->agent.state & CHK_PAUSED;
 
        cut_crlf(data);
 
        if (strchr(data, '%')) {
                desc = server_parse_weight_change_request(check->server, data);
                if (!desc) {
+                       if (paused)
+                               return;
                        status = HCHK_STATUS_L7OKD;
                        desc = data;
                }
        } else if (!strcasecmp(data, "drain")) {
+               if (paused)
+                       return;
                desc = server_parse_weight_change_request(check->server, "0%");
                if (!desc) {
                        desc = "drain";
@@ -1387,10 +1402,14 @@ static struct task *process_chk(struct task *t)
                if (!expired) /* woke up too early */
                        return t;
 
-               /* we don't send any health-checks when the proxy is stopped or 
when
-                * the server should not be checked.
+               /* we don't send any health-checks when the proxy is
+                * stopped, the server should not be checked or the check
+                * is paused.
                 */
-               if (!(s->state & SRV_CHECKED) || s->proxy->state == 
PR_STSTOPPED || (s->state & SRV_MAINTAIN))
+               if (!(s->state & SRV_CHECKED) ||
+                   s->proxy->state == PR_STSTOPPED ||
+                   (s->state & SRV_MAINTAIN) ||
+                   (check->state & CHK_PAUSED))
                        goto reschedule;
 
                /* we'll initiate a new check */
diff --git a/src/dumpstats.c b/src/dumpstats.c
index 0d15b51..b6ebf9a 100644
--- a/src/dumpstats.c
+++ b/src/dumpstats.c
@@ -1145,6 +1145,23 @@ static int stats_sock_parse_request(struct 
stream_interface *si, char *line)
                                return 1;
                        }
                }
+               else if (strcmp(args[1], "agent") == 0) {
+                       struct server *sv;
+
+                       sv = expect_server_admin(s, si, args[2]);
+                       if (!sv)
+                               return 1;
+
+                       if (strcmp(args[3], "pause") == 0) {
+                               sv->agent.state |= CHK_PAUSED;
+                       } else if (strcmp(args[3], "unpause") == 0) {
+                               sv->agent.state &= ~CHK_PAUSED;
+                       } else {
+                               si->applet.ctx.cli.msg = "unknown agent state, 
should be pause or unpause";
+                               si->applet.st0 = STAT_CLI_PRINT;
+                       }
+                       return 1;
+               }
                else if (strcmp(args[1], "maxconn") == 0) {
                        if (strcmp(args[2], "frontend") == 0) {
                                struct proxy *px;
-- 
1.8.3.2


Reply via email to