On Wed, Jun 08, 2011 at 09:19:21AM +0900, Simon Horman wrote:
> ---
>  doc/configuration.txt  |    9 +++++++++
>  include/types/checks.h |    6 ++++++
>  include/types/server.h |    1 +
>  src/cfgparse.c         |   14 +++++++++++++-
>  src/checks.c           |   22 ++++++++++++++++++++++
>  5 files changed, 51 insertions(+), 1 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/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 fb31215..c76ccd1 100644
> --- a/include/types/server.h
> +++ b/include/types/server.h
> @@ -124,6 +124,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 40c46d5..1bd9715 100644
> --- a/src/cfgparse.c
> +++ b/src/cfgparse.c
> @@ -4249,6 +4249,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",
> @@ -4428,7 +4440,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..ab59d73 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, *session_end;
> +
> +     FOREACH_ITEM_SAFE(session, session_bck,
> +                       LIST_ELEM(&sessions, struct session *, list),
> +                       session_end, struct session *, list) {
> +             if (session->srv_conn == srv &&
> +                 !(session->rep->flags & (BF_SHUTW|BF_SHUTW_NOW))) {
> +                             buffer_shutr_now(session->rep);
> +                             buffer_shutw_now(session->rep);
> +                             task_wakeup(session->task, TASK_WOKEN_RES);
> +             }
> +     }
> +}

I should note that I'm not entirely sure about the performance implications
of looping through all sessions like this. Perhaps a per-server list is needed.

I'm also unsure of the performance implications of waking up a potentially
large number of sessions. Perhaps their priority should be reduced?

> +
>  /* 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.4.4
> 

Reply via email to