---

v2
* Iterate per-server session list instead of global session list
  in shutdown_sessions()
* Set nice level of tasks of sessions to be closed to 1024
* Use TASK_WOKEN_OTHER instead of TASK_WOKEN_RES in shutdown_sessions()
  As suggested by Willy Tarreau
* Use list_for_each_entry_safe() instead of FOR_ITEM_SAFE in
  shutdown_sessions()
* Rather than shutting down both the read and write side of the response,
  shut down the read side of the response and the write side of the request.
  As suggested by Willy Tarreau
v3
* Rename server element of session as by_srv
* Don't close sessions unless on-marked-down shutdown-sessions is set
  - fixed logic bug

Signed-off-by: Simon Horman <ho...@verge.net.au>
---
 doc/configuration.txt   |    9 +++++++++
 include/proto/session.h |    4 ++--
 include/types/checks.h  |    6 ++++++
 include/types/server.h  |    1 +
 src/cfgparse.c          |   14 +++++++++++++-
 src/checks.c            |   22 ++++++++++++++++++++++
 6 files changed, 53 insertions(+), 3 deletions(-)

diff --git a/doc/configuration.txt b/doc/configuration.txt
index b22ac98..b788c13 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -6667,6 +6667,15 @@ on-error <mode>
 
   See also the "check", "observe" and "error-limit".
 
+on-marked-down <action>
+  Modify what occurs when a server is marked down.
+  Currently one action is available:
+  - shutdown-sessions: Shutdown peer sessions
+
+  Actions are disabled by default
+
+  Supported in default-server: Yes
+
 port <port>
   Using the "port" parameter, it becomes possible to use a different port to
   send health-checks. On some servers, it may be desirable to dedicate a port
diff --git a/include/proto/session.h b/include/proto/session.h
index a7055bf..810fe44 100644
--- a/include/proto/session.h
+++ b/include/proto/session.h
@@ -228,7 +228,7 @@ static void inline session_inc_http_err_ctr(struct session 
*s)
 static void inline session_add_srv_conn(struct session *sess, struct server 
*srv)
 {
        sess->srv_conn = srv;
-       LIST_ADD(&srv->actconns, &sess->server);
+       LIST_ADD(&srv->actconns, &sess->by_srv);
 }
 
 static void inline session_del_srv_conn(struct session *sess)
@@ -237,7 +237,7 @@ static void inline session_del_srv_conn(struct session 
*sess)
                return;
 
        sess->srv_conn = NULL;
-       LIST_DEL(&sess->server);
+       LIST_DEL(&sess->by_srv);
 }
 
 #endif /* _PROTO_SESSION_H */
diff --git a/include/types/checks.h b/include/types/checks.h
index 75e32b6..a414630 100644
--- a/include/types/checks.h
+++ b/include/types/checks.h
@@ -74,6 +74,12 @@ enum {
 };
 
 enum {
+       HANA_ONMARKEDDOWN_NONE  = 0,
+
+       HANA_ONMARKEDDOWN_SHUTDOWNSESSIONS,     /* Shutdown peer sessions */
+};
+
+enum {
        HANA_OBS_NONE           = 0,
 
        HANA_OBS_LAYER4,                /* Observe L4 - for example tcp */
diff --git a/include/types/server.h b/include/types/server.h
index cf0a0df..1a9d60d 100644
--- a/include/types/server.h
+++ b/include/types/server.h
@@ -125,6 +125,7 @@ struct server {
        int rise, fall;                         /* time in iterations */
        int consecutive_errors_limit;           /* number of consecutive errors 
that triggers an event */
        short observe, onerror;                 /* observing mode: one of 
HANA_OBS_*; what to do on error: on of ANA_ONERR_* */
+       short onmarkeddown;                     /* what to do when marked down: 
on of HANA_ONMARKEDDOWN_* */
        int inter, fastinter, downinter;        /* checks: time in milliseconds 
*/
        int slowstart;                          /* slowstart time in seconds 
(ms in the conf) */
        int result;                             /* health-check result : 
SRV_CHK_* */
diff --git a/src/cfgparse.c b/src/cfgparse.c
index 9626e36..c19f430 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -4250,6 +4250,18 @@ stats_error_parsing:
 
                                cur_arg += 2;
                        }
+                       else if (!strcmp(args[cur_arg], "on-marked-down")) {
+                               if (!strcmp(args[cur_arg + 1], 
"shutdown-sessions"))
+                                       newsrv->onmarkeddown = 
HANA_ONMARKEDDOWN_SHUTDOWNSESSIONS;
+                               else {
+                                       Alert("parsing [%s:%d]: '%s' expects 
'shutdown-sessions' but got '%s'\n",
+                                               file, linenum, args[cur_arg], 
args[cur_arg + 1]);
+                                       err_code |= ERR_ALERT | ERR_FATAL;
+                                       goto out;
+                               }
+
+                               cur_arg += 2;
+                       }
                        else if (!strcmp(args[cur_arg], "error-limit")) {
                                if (!*args[cur_arg + 1]) {
                                        Alert("parsing [%s:%d]: '%s' expects an 
integer argument.\n",
@@ -4429,7 +4441,7 @@ stats_error_parsing:
                        }
                        else {
                                if (!defsrv)
-                                       Alert("parsing [%s:%d] : server %s only 
supports options 'backup', 'cookie', 'redir', 'observer', 'on-error', 
'error-limit', 'check', 'disabled', 'track', 'id', 'inter', 'fastinter', 
'downinter', 'rise', 'fall', 'addr', 'port', 'source', 'send-proxy', 'minconn', 
'maxconn', 'maxqueue', 'slowstart' and 'weight'.\n",
+                                       Alert("parsing [%s:%d] : server %s only 
supports options 'backup', 'cookie', 'redir', 'observer', 'on-error', 
'on-marked-down', 'error-limit', 'check', 'disabled', 'track', 'id', 'inter', 
'fastinter', 'downinter', 'rise', 'fall', 'addr', 'port', 'source', 
'send-proxy', 'minconn', 'maxconn', 'maxqueue', 'slowstart' and 'weight'.\n",
                                              file, linenum, newsrv->id);
                                else
                                        Alert("parsing [%s:%d]: default-server 
only supports options 'on-error', 'error-limit', 'inter', 'fastinter', 
'downinter', 'rise', 'fall', 'port', 'minconn', 'maxconn', 'maxqueue', 
'slowstart' and 'weight'.\n",
diff --git a/src/checks.c b/src/checks.c
index 82aceaa..6b34a37 100644
--- a/src/checks.c
+++ b/src/checks.c
@@ -45,6 +45,7 @@
 #include <proto/proto_tcp.h>
 #include <proto/proxy.h>
 #include <proto/server.h>
+#include <proto/session.h>
 #include <proto/stream_interface.h>
 #include <proto/task.h>
 
@@ -357,6 +358,24 @@ static int check_for_pending(struct server *s)
        return xferred;
 }
 
+/* Shutdown connections when their server goes down.
+ */
+static void shutdown_sessions(struct server *srv)
+{
+       struct session *session, *session_bck;
+
+       list_for_each_entry_safe(session, session_bck,
+                                &srv->actconns, by_srv) {
+               if (session->srv_conn == srv &&
+                   !(session->req->flags & (BF_SHUTW|BF_SHUTW_NOW))) {
+                               buffer_shutw_now(session->req);
+                               buffer_shutr_now(session->rep);
+                               session->task->nice = 1024;
+                               task_wakeup(session->task, TASK_WOKEN_OTHER);
+               }
+       }
+}
+
 /* Sets server <s> down, notifies by all available means, recounts the
  * remaining servers on the proxy and transfers queued sessions whenever
  * possible to other servers. It automatically recomputes the number of
@@ -380,6 +399,9 @@ void set_server_down(struct server *s)
                s->state &= ~(SRV_RUNNING | SRV_GOINGDOWN);
                s->proxy->lbprm.set_server_status_down(s);
 
+               if (s->onmarkeddown & HANA_ONMARKEDDOWN_SHUTDOWNSESSIONS)
+                       shutdown_sessions(s);
+
                /* we might have sessions queued on this server and waiting for
                 * a connection. Those which are redispatchable will be queued
                 * to another server or to the proxy itself.
-- 
1.7.5.3


Reply via email to