RE: Can I add RIP Server online?

2013-08-22 Thread Mason(MyungSik) Jang
Hi Baptiste;

Thanks for your prompt response.

If I restart HAProxy, what will happen to existing sessions.

I’m afraid if all existing sessions might be failed.

 

Mason.

 

From: Baptiste [mailto:bed...@gmail.com] 
Sent: Thursday, August 22, 2013 5:21 PM
To: Mason(MyungSik) Jang
Cc: HAProxy
Subject: Re: Can I add RIP Server online?

 

Hi Mason,

 

There is no API for HAProxy opensource.

HAProxy owns a socket which can be used to inject some commands to modify
the running configuration, but unfortunately, you won't be able to insert a
new server through this socket.

 

2 choices for you now:

1. if new servers have a random and unpredictable IP address, then your
scheduler must modify HAProxy configuration file then restart HAProxy with
the command line argument "-sf ".

a New HAProxy process will be started with the new configuration and the
new server list inside.

 

2. if you know in advance your server IP addresses, they can be pre-
configured in HAProxy, but in a disabled state (anyway, if the servers are
down, the health check will fail).

Well, your scheduler can startup the VM, then get connected on HAProxy
management socket to enable this server. Don't forget to enable the server
in the configuration file to keep a consistent state with HAProxy's running
config.

 

Baptiste

 

 

 

On Thu, Aug 22, 2013 at 3:43 AM, Mason(MyungSik) Jang 
wrote:

Dear subscribers;

 

I would like to use HAProxy in my private cloud.

 

And I have a plan to write my code like followings.

 

1. Monitor the number of concurrent sessions per each backend(RIP)
servers.

2. If the number exceeded predefined number.

A. Dynamically provision new server to increase capacity.

B.  Add this server to HAProxy as RIP.

3. If the number is smaller than predefined number.

A. Do nothing.

4. Goto 1.

 

To do so, I should have a function to add RIP server in HAProxy online.

I couldn’t find any API manual or command to handle this.

 

Any recommendation would be appreciated.

 

Thank you.

 

 

Mason (MyungSik) Jang

CTO / Executive Director

YKP3 Corp.

T. +82-2-780.-1237D. +82-70-4618-0344   

F. +82-70-8610-0460  M. +82-10-3899-5089

E-mail. maso...@ykp3.com

설명: 설명: 설명: 설명: MailTrailer

 

 

<>

Track headers with tcp-request in listen only work with "if HTTP"

2013-08-22 Thread Ricardo F
Hello,

I have been testing the connection tracking in the frontend based on headers, 
but it only work if the "if HTTP" option is set:

tcp-request inspect-delay 10s
tcp-request content track-sc0 hdr(x-forwarded-for,-1) if HTTP

Without this option, the table doesn't fill, the connections aren't tracked.

As is shown in the documentation, with tcp-request is possible to match layer 7 
conditions, but i don't know why is neccesary the "if HTTP" condition.

This is a sample testing code:
global
        maxconn 1000
        log 127.0.0.1 local5 info err
        stats socket /var/run/haproxy.sock mode 0600 level admin
        pidfile /var/run/haproxy.pid

defaults
        mode    http
        log global
        retries 3
        option redispatch
        timeout contimeout     5000
        timeout client         5000
        timeout srvtimeout     5000

listen proxy-http *:80
       mode http
       option httplog
       stats enable
       option http-server-close
       balance roundrobin
       capture request header x-forwarded-for len 15
       stick-table type ip size 200k expire 60m store gpc0
       tcp-request inspect-delay 10s
       tcp-request content track-sc0 hdr_ip(x-forwarded-for,1) if HTTP
       http-request deny if { sc1_get_gpc0 eq 0 }



The version is HA-Proxy 1.5-dev19 2013/06/17


Thanks,

RicardoF  


Re: HAProxy v1.5-dev19 OpenSSL Support Issue

2013-08-22 Thread Simon Horman
On Thu, Aug 22, 2013 at 09:36:34AM +0100, Scott McKeown wrote:
> Sorry I must have forgot/overlooked replying to this.
> 
> However, I did manage to get the OpenSSL Support working with the current
> v1.5-dev19 downloaded directly from the the HAProxy website using the tar
> image.
> Saying that though I'm glad I can still manage to break things ;)

Thanks again for breaking things, it was very helpful to me.



Re: HAProxy v1.5-dev19 OpenSSL Support Issue

2013-08-22 Thread Scott McKeown
Sorry I must have forgot/overlooked replying to this.

However, I did manage to get the OpenSSL Support working with the current
v1.5-dev19 downloaded directly from the the HAProxy website using the tar
image.
Saying that though I'm glad I can still manage to break things ;)


~Scott


On 22 August 2013 09:01, Simon Horman  wrote:

> On Tue, Aug 13, 2013 at 04:56:57PM +0200, Willy Tarreau wrote:
> > On Tue, Aug 13, 2013 at 03:36:09PM +0100, Scott McKeown wrote:
> > > Hi Guys,
> > >
> > > I've not applied any patches to the download as this was a direct
> 'wget'
> > > from the Git repository.
> > > As follows is the OpenSSL v1.0.0 Centos 6.4 x64 build
> > >
> > > [root@localhost ~]# wget
> > > https://github.com/horms/haproxy/archive/agent-check-20130806.zip
> >
> > Hmmm it looks to me that this is not the mainstream code, but Simon's
> tree.
> > Oh BTW that reminds me that I have still not reviewed his patch set,
> shame
> > on me :-(
>
> Although Scott would have been better off using your tree it it does seem
> that Scott has uncovered a bug in the patches in my tree, thanks for that.
> I will squash the following into "MEDIUM: Split up struct server's check
> element" before reposting to resolve this problem.
>
>
> diff --git a/src/ssl_sock.c b/src/ssl_sock.c
> index ce1712d..23bf4a3 100644
> --- a/src/ssl_sock.c
> +++ b/src/ssl_sock.c
> @@ -793,7 +793,7 @@ int ssl_sock_prepare_srv_ctx(struct server *srv,
> struct proxy *curproxy)
> if (srv->use_ssl)
> srv->xprt = &ssl_sock;
> if (srv->check.use_ssl)
> -   srv->check.xprt = &ssl_sock;
> +   srv->check_common.xprt = &ssl_sock;
>
> srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
> if (!srv->ssl_ctx.ctx) {
>



-- 
With Kind Regards.

Scott McKeown
Loadbalancer.org
http://www.loadbalancer.org


Re: If anyone is interested in testing Simon Hormans patches for the server feedback agent

2013-08-22 Thread Willy Tarreau
On Thu, Aug 22, 2013 at 05:16:26PM +0900, Simon Horman wrote:
> On Thu, Aug 22, 2013 at 10:11:27AM +0200, Baptiste wrote:
> > Let us know there, so I can test it as soon as released :)
> 
> I have just released v6 to the mailing list as
> "[PATCH v6 00/22] Agent Check Enhancements and External Check".
> 
> It can be found in git at
> 
> https://github.com/horms/haproxy.git agent-check-20130822

Thank you Simon, I'll do my best to start reviewing it today.

Willy




Re: Can I add RIP Server online?

2013-08-22 Thread Baptiste
Hi Mason,

There is no API for HAProxy opensource.
HAProxy owns a socket which can be used to inject some commands to modify
the running configuration, but unfortunately, you won't be able to insert a
new server through this socket.

2 choices for you now:
1. if new servers have a random and unpredictable IP address, then your
scheduler must modify HAProxy configuration file then restart HAProxy with
the command line argument "-sf ".
a New HAProxy process will be started with the new configuration and the
new server list inside.

2. if you know in advance your server IP addresses, they can be
pre-configured in HAProxy, but in a disabled state (anyway, if the servers
are down, the health check will fail).
Well, your scheduler can startup the VM, then get connected on HAProxy
management socket to enable this server. Don't forget to enable the server
in the configuration file to keep a consistent state with HAProxy's running
config.

Baptiste




On Thu, Aug 22, 2013 at 3:43 AM, Mason(MyungSik) Jang wrote:

> Dear subscribers;
>
> ** **
>
> I would like to use HAProxy in my private cloud.
>
> ** **
>
> And I have a plan to write my code like followings.
>
> ** **
>
> **1. **Monitor the number of concurrent sessions per each
> backend(RIP) servers.
>
> **2. **If the number exceeded predefined number.
>
> **A. **Dynamically provision new server to increase capacity.
>
> **B.  **Add this server to HAProxy as RIP.
>
> **3. **If the number is smaller than predefined number.
>
> **A. **Do nothing.
>
> **4. **Goto 1.
>
> ** **
>
> To do so, I should have a function to add RIP server in HAProxy online.***
> *
>
> I couldn’t find any API manual or command to handle this.
>
> ** **
>
> Any recommendation would be appreciated.
>
> ** **
>
> Thank you.
>
> ** **
>
> ** **
>
> *Mason (MyungSik) Jang*
>
> CTO / Executive Director
>
> *YKP3 Corp.*
>
> *T.* +82-2-780.-1237*D.* +82-70-4618-0344   
>
> *F.* +82-70-8610-0460  *M.* +82-10-3899-5089
>
> *E-mail*. *maso...@ykp3.com*
>
> [image: 설명: 설명: 설명: 설명: MailTrailer]
>
> ** **
>
<>

RE: junk at end of syslog packets in 1.5dev19

2013-08-22 Thread Lukas Tribus
> Is this happen randomly or can you pin point this to specifc requests, maybe
> errors/timeouts? How can we reproduce this?

Nevermind, its easily reproducible (just generate some syslog messages).

The whole thing seems random: most of the times, the syslog msg ends
with \n\0\0, other times with \n\n\0 or even \n"\n.


I've tracked this down to:

2a4a44f0f9f08d130a9a7211746728c38f670032 is the first bad commit
commit 2a4a44f0f9f08d130a9a7211746728c38f670032
Author: William Lallemand 
Date:   Mon Feb 6 16:00:33 2012 +0100

    REORG: log: split send_log function


Heres a tcpdump output:
10:11:45.854741 IP 10.0.0.55.39079> 10.0.0.3.514: SYSLOG syslog.notice, length: 
64
        0x:  4500 005c  4000 4011 2658 0a00 0037  E..\..@.@.&X...7
        0x0010:  0a00 0003 98a7 0202 0048 1493 3c34 353e  .H..<45>
        0x0020:  4175 6720 3232 2031 303a 3131 3a34 3520  Aug.22.10:11:45.
        0x0030:  6861 7072 6f78 795b 3135 3034 315d 3a20  haproxy[15041]:.
        0x0040:  5072 6f78 7920 6d79 6672 6f6e 7465 6e64  Proxy.myfrontend
        0x0050:  2073 7461 7274 6564 2e0a             .started
10:11:50.113766 IP 10.0.0.55.39079> 10.0.0.3.514: SYSLOG syslog.info, length: 
170
        0x:  4500 00c6  4000 4011 25ee 0a00 0037  E.@.@.%7
        0x0010:  0a00 0003 98a7 0202 00b2 14fd 3c34 363e  <46>
        0x0020:  4175 6720 3232 2031 303a 3131 3a35 3020  Aug.22.10:11:50.
        0x0030:  6861 7072 6f78 795b 3135 3034 315d 3a20  haproxy[15041]:.
        0x0040:  3a3a   3a31 302e 302e 302e 333a  :::10.0.0.3:
        0x0050:  3536 3437 3020 5b32 322f 4175 672f 3230  56470.[22/Aug/20
        0x0060:  3133 3a31 303a 3131 3a35 302e 3130 385d  13:10:11:50.108]
        0x0070:  206d 7966 726f 6e74 656e 6420 6d79 6261  .myfrontend.myba
        0x0080:  636b 656e 642f 7333 2030 2f30 2f30 2f34  ckend/s3.0/0/0/4
        0x0090:  2f34 2034 3034 2031 3434 3320 2d20 2d20  /4.404.1443.-.-.
        0x00a0:  2d2d 2d2d 2031 2f31 2f30 2f30 2f30 2030  .1/1/0/0/0.0
        0x00b0:  2f30 2022 4745 5420 2f20 4854 5450 2f31  /0."GET./.HTTP/1
        0x00c0:  2e31 220a                            .1"...
10:11:53.595881 IP 10.0.0.55.39079> 10.0.0.3.514: SYSLOG syslog.info, length: 
171
        0x:  4500 00c7  4000 4011 25ed 0a00 0037  E.@.@.%7
        0x0010:  0a00 0003 98a7 0202 00b3 14fe 3c34 363e  <46>
        0x0020:  4175 6720 3232 2031 303a 3131 3a35 3320  Aug.22.10:11:53.
        0x0030:  6861 7072 6f78 795b 3135 3034 315d 3a20  haproxy[15041]:.
        0x0040:  3a3a   3a31 302e 302e 302e 333a  :::10.0.0.3:
        0x0050:  3536 3437 3120 5b32 322f 4175 672f 3230  56471.[22/Aug/20
        0x0060:  3133 3a31 303a 3131 3a35 332e 3538 315d  13:10:11:53.581]
        0x0070:  206d 7966 726f 6e74 656e 6420 6d79 6261  .myfrontend.myba
        0x0080:  636b 656e 642f 7333 2039 2f30 2f31 2f34  ckend/s3.9/0/1/4
        0x0090:  2f31 3420 3430 3420 3134 3433 202d 202d  /14.404.1443.-.-
        0x00a0:  202d 2d2d 2d20 312f 312f 302f 312f 3020  ..1/1/0/1/0.
        0x00b0:  302f 3020 2247 4554 202f 2048 5454 502f  0/0."GET./.HTTP/
        0x00c0:  312e 3122 0a00 00                        1.1"...
10:11:57.830360 IP 10.0.0.55.39079> 10.0.0.3.514: SYSLOG syslog.info, length: 
170
        0x:  4500 00c6  4000 4011 25ee 0a00 0037  E.@.@.%7
        0x0010:  0a00 0003 98a7 0202 00b2 14fd 3c34 363e  <46>
        0x0020:  4175 6720 3232 2031 303a 3131 3a35 3720  Aug.22.10:11:57.
        0x0030:  6861 7072 6f78 795b 3135 3034 315d 3a20  haproxy[15041]:.
        0x0040:  3a3a   3a31 302e 302e 302e 333a  :::10.0.0.3:
        0x0050:  3536 3437 3220 5b32 322f 4175 672f 3230  56472.[22/Aug/20
        0x0060:  3133 3a31 303a 3131 3a35 372e 3832 365d  13:10:11:57.826]
        0x0070:  206d 7966 726f 6e74 656e 6420 6d79 6261  .myfrontend.myba
        0x0080:  636b 656e 642f 7333 2030 2f30 2f30 2f33  ckend/s3.0/0/0/3
        0x0090:  2f33 2034 3034 2031 3434 3320 2d20 2d20  /3.404.1443.-.-.
        0x00a0:  2d2d 2d2d 2031 2f31 2f30 2f31 2f30 2030  .1/1/0/1/0.0
        0x00b0:  2f30 2022 4745 5420 2f20 4854 5450 2f31  /0."GET./.HTTP/1
        0x00c0:  2e31 220a 0a00                           .1"...
10:12:05.793157 IP 10.0.0.55.39079> 10.0.0.3.514: SYSLOG syslog.info, length: 
170
        0x:  4500 00c6  4000 4011 25ee 0a00 0037  E.@.@.%7
        0x0010:  0a00 0003 98a7 0202 00b2 14fd 3c34 363e  <46>
        0x0020:  4175 6720 3232 2031 303a 3132 3a30 3520  Aug.22.10:12:05.
        0x0030:  6861 7072 6f78 795b 3135 3034 315d 3a20  haproxy[15041]:.
        0x0040:  3a3a   3a31 302e 302e 302e 333a  :::10.0.0.3:
        0x0050:  3536 3437 3320 5b32 322f 4175 672f 3230  56473.[22/Aug/20
        0x0060:  3133 3a31 303a 3132 3a30 352e 3738 385d  13:10:12:05.788]
        0x0070:  206d 7966 726f 6e74 656e 6420 6d79 6261  .myfrontend.myba
        0x0080:  636b 656e 642f 7333 2030 2f3

Re: If anyone is interested in testing Simon Hormans patches for the server feedback agent

2013-08-22 Thread Simon Horman
On Thu, Aug 22, 2013 at 10:11:27AM +0200, Baptiste wrote:
> Let us know there, so I can test it as soon as released :)

I have just released v6 to the mailing list as
"[PATCH v6 00/22] Agent Check Enhancements and External Check".

It can be found in git at

https://github.com/horms/haproxy.git agent-check-20130822



[PATCH v6 15/22] MEDIUM: Add http-check agent-hdr option

2013-08-22 Thread Simon Horman
Allow agent checks to obtain information in
an HTTP header of the response to an http check.

Signed-off-by: Simon Horman 

---

v4
* Do not duplicate code that is in process_result()

v2 - v3
* No change
---
 doc/configuration.txt | 24 +--
 include/types/proxy.h |  2 ++
 src/cfgparse.c| 20 +++-
 src/checks.c  | 85 ---
 4 files changed, 104 insertions(+), 27 deletions(-)

diff --git a/doc/configuration.txt b/doc/configuration.txt
index 9c5f5ee..233be4e 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -1139,6 +1139,7 @@ force-persist -  X
 X X
 fullconn  X  - X X
 grace X  X X X
 hash-type X  - X X
+http-check agent-hdr  X  - X X
 http-check disable-on-404 X  - X X
 http-check expect -  - X X
 http-check send-state X  - X X
@@ -2527,6 +2528,24 @@ hash-type 
   See also : "balance", "server"
 
 
+http-check agent-hdr
+  Use the value of the given http header as the result of an agent check
+  May be used in sections :   defaults | frontend | listen | backend
+ yes   |no|   yes  |   yes
+  Arguments :
+
+  The header string to use to send the server name
+
+  When this option is set an http check is enhanced to read the value
+  of the given header in the response to an http check and interpret
+  it as the result of an agent check. In this way an http and agent check
+  may be performed simultaneously.
+
+  This option is overridden by the agent-port parameter.
+
+  See also : "option lb-agent-chk", "agent-port"
+
+
 http-check disable-on-404
   Enable a maintenance mode upon HTTP/404 response to health-checks
   May be used in sections :   defaults | frontend | listen | backend
@@ -7682,10 +7701,11 @@ agent-port 
 
   In this the agent check is run in conjunction with another check
   and as such the check backend should be set to some value other than
-  "lb-agent-check". An alternative scenario is to run only an agent check
+  "lb-agent-check". A second scenario is to run only an agent check
   in which case the check backend should be set to "lb-agent-check" and
   "agent-port" should not be set; in that scenario the port may be set
-  using the "port" parameter.
+  using the "port" parameter. A third scenario is to use "http-check
+  agent-hdr" to run an agent and http checks simultaneously over HTTP.
 
   See also the "agent-inter" parameter.
 
diff --git a/include/types/proxy.h b/include/types/proxy.h
index e6bc755..66e5db7 100644
--- a/include/types/proxy.h
+++ b/include/types/proxy.h
@@ -328,6 +328,7 @@ struct proxy {
int check_len;  /* Length of the HTTP or SSL3 
request */
char *expect_str;   /* http-check expected content 
: string or text version of the regex */
regex_t *expect_regex;  /* http-check expected content 
*/
+   const char *agent_http_header;  /* http-check header to use for 
agent checks */
struct chunk errmsg[HTTP_ERR_SIZE]; /* default or customized error 
messages for known errors */
int uuid;   /* universally unique proxy ID, 
used for SNMP */
unsigned int backlog;   /* force the frontend's listen 
backlog */
@@ -359,6 +360,7 @@ struct proxy {
} conf; /* config information */
void *parent;   /* parent of the proxy when 
applicable */
struct comp *comp;  /* http compression */
+
 };
 
 struct switching_rule {
diff --git a/src/cfgparse.c b/src/cfgparse.c
index 780275e..6329b59 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -3869,7 +3869,25 @@ stats_error_parsing:
if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], 
NULL))
err_code |= ERR_WARN;
 
-   if (strcmp(args[1], "disable-on-404") == 0) {
+   if (strcmp(args[1], "agent-hdr") == 0) {
+   int cur_arg;
+
+   if (curproxy->agent_http_header) {
+   Alert("parsing [%s:%d] : '%s %s' already 
specified.\n", file, linenum, args[0], args[1]);
+   err_code |= ERR_ALERT | ERR_FATAL;
+   goto out;
+   }
+
+   cur_arg = 2;
+   if (!*(args[cur_arg ])) {
+   Alert("parsing [%s:%d] : '%s %s' expects 
 as an argument.\n",
+ f

[PATCH v6 19/22] MEDIUM: Set rise and fall of agent checks to 1

2013-08-22 Thread Simon Horman
This is achieved by moving rise and fall from struct server to struct check.

After this move the behaviour of the primary check, server->check is
unchanged. However, the secondary agent check, server->agent now has
independent rise and fall values each of which are set to 1.

The result is that receiving "fail", "stopped" or "down" just once from the
agent will mark the server as down. And receiving a weight just once will
allow the server to be marked up if its primary check is in good health.

This opens up the scope to allow the rise and fall values of the agent
check to be configurable, however this has not been implemented at this
stage.

Signed-off-by: Simon Horman 

---

v7
When checking health against rise in set_server_up the health of a check
should be checked against the rise of the same check. Otherwise the condition
for the s->agent may be false when it should be true as s->agent's rise and
thus healthy health value is 1 whereas the default rise for check is likely to
be 3, as check may be s->check and the the default value for s->check.rise is 3.

v5
* Rebase
---
 include/common/defaults.h |  2 ++
 include/types/server.h|  6 +++---
 src/cfgparse.c| 28 +++-
 src/checks.c  | 36 ++--
 src/dumpstats.c   | 14 +++---
 src/proto_http.c  |  2 +-
 src/server.c  |  2 +-
 7 files changed, 47 insertions(+), 43 deletions(-)

diff --git a/include/common/defaults.h b/include/common/defaults.h
index 30ab148..13fb1e3 100644
--- a/include/common/defaults.h
+++ b/include/common/defaults.h
@@ -127,6 +127,8 @@
 #defineDEF_CHKINTR 2000
 #define DEF_FALLTIME3
 #define DEF_RISETIME2
+#define DEF_AGENT_FALLTIME1
+#define DEF_AGENT_RISETIME1
 #define DEF_CHECK_REQ   "OPTIONS / HTTP/1.0\r\n"
 #define DEF_SMTP_CHECK_REQ   "HELO localhost\r\n"
 #define DEF_LDAP_CHECK_REQ   
"\x30\x0c\x02\x01\x01\x60\x07\x02\x01\x03\x04\x00\x80\x00"
diff --git a/include/types/server.h b/include/types/server.h
index f316e01..379b7dd 100644
--- a/include/types/server.h
+++ b/include/types/server.h
@@ -122,8 +122,9 @@ struct check {
int inter, fastinter, downinter;/* checks: time in milliseconds 
*/
int result; /* health-check result : 
SRV_CHK_* */
int state;  /* health-check result : CHK_* 
*/
-   int health; /* 0 to server->rise-1 = bad;
-* rise to 
server->rise+server->fall-1 = good */
+   int health; /* 0 to rise-1 = bad;
+* rise to rise+server->fall-1 
= good */
+   int rise, fall; /* time in iterations */
int type;   /* Check type, one of 
PR_O2_*_CHK */
const char *name;   /* Name of check: "Health" or 
"Agent" */
struct server *server;  /* back-pointer to server */
@@ -157,7 +158,6 @@ struct server {
struct server *tracknext, *track;   /* next server in a tracking 
list, tracked server */
char *trackit;  /* temporary variable to make 
assignment deferrable */
int consecutive_errors; /* current number of 
consecutive errors */
-   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: 
one of HANA_ONMARKEDDOWN_* */
diff --git a/src/cfgparse.c b/src/cfgparse.c
index 6329b59..f67cb7b 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -1328,8 +1328,10 @@ void init_default_instance()
defproxy.defsrv.agent.inter = DEF_CHKINTR;
defproxy.defsrv.agent.fastinter = 0;
defproxy.defsrv.agent.downinter = 0;
-   defproxy.defsrv.rise = DEF_RISETIME;
-   defproxy.defsrv.fall = DEF_FALLTIME;
+   defproxy.defsrv.check.rise = DEF_RISETIME;
+   defproxy.defsrv.check.fall = DEF_FALLTIME;
+   defproxy.defsrv.agent.rise = DEF_AGENT_RISETIME;
+   defproxy.defsrv.agent.fall = DEF_AGENT_FALLTIME;
defproxy.defsrv.check.port = 0;
defproxy.defsrv.agent.port = 0;
defproxy.defsrv.maxqueue = 0;
@@ -4270,8 +4272,6 @@ stats_error_parsing:
newsrv->agent.inter = curproxy->defsrv.agent.inter;
newsrv->agent.fastinter = 
curproxy->defsrv.agent.fastinter;
newsrv->agent.downinter = 
curproxy->defsrv.agent.downinter;
-   newsrv->rise= curproxy->defsrv.rise;
-   newsrv->fall   

[PATCH v6 20/22] MEDIUM: Add set agent pause|unpause unix socket command

2013-08-22 Thread Simon Horman
The syntax of this new command is:

set agent / 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 
---
 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 / 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  
   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_RUNNING0x0001  /* 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 */
 

[PATCH v6 21/22] MEDIUM: Break out check establishment into establish_chk()

2013-08-22 Thread Simon Horman
This is in preparation for adding a new type of check that
uses a process rather than a socket.

Signed-off-by: Simon Horman 

---

v4
* Use check->type in establish_conn_chk()

  Use check->type instead of s->proxy->options2 & PR_O2_CHK_ANY
  as the former is specific to the check being processed whereas
  the latter relates only to the primary check of a server.

v2 - v3
* No change
---
 src/checks.c | 131 +++
 1 file changed, 70 insertions(+), 61 deletions(-)

diff --git a/src/checks.c b/src/checks.c
index 1f6a9ea..d2c43d2 100644
--- a/src/checks.c
+++ b/src/checks.c
@@ -1385,6 +1385,75 @@ static void process_result(struct check *check)
 }
 
 /*
+ * establish a server health-check.
+ *
+ * It can return one of :
+ *  - SN_ERR_NONE if everything's OK
+ *  - SN_ERR_SRVTO if there are no more servers
+ *  - SN_ERR_SRVCL if the connection was refused by the server
+ *  - SN_ERR_PRXCOND if the connection has been limited by the proxy (maxconn)
+ *  - SN_ERR_RESOURCE if a system resource is lacking (eg: fd limits, ports, 
...)
+ *  - SN_ERR_INTERNAL for any other purely internal errors
+ * Additionnally, in the case of SN_ERR_RESOURCE, an emergency log will be 
emitted.
+ */
+static int establish_chk(struct task *t)
+{
+   struct check *check = t->context;
+   struct server *s = check->server;
+   struct connection *conn = check->conn;
+   int ret;
+
+   /* prepare the check buffer
+* This should not be used if check is the secondary agent check
+* of a server as s->proxy->check_req will relate to the
+* configuration of the primary check */
+   if (check->type && check != &s->agent) {
+   bo_putblk(check->bo, s->proxy->check_req, s->proxy->check_len);
+
+   /* we want to check if this host replies to HTTP or SSLv3 
requests
+* so we'll send the request, and won't wake the checker up now.
+*/
+   if (check->type == PR_O2_SSL3_CHK) {
+   /* SSL requires that we put Unix time in the request */
+   int gmt_time = htonl(date.tv_sec);
+   memcpy(check->bo->data + 11, &gmt_time, 4);
+   }
+   else if (check->type == PR_O2_HTTP_CHK) {
+   if (s->proxy->options2 & PR_O2_CHK_SNDST)
+   bo_putblk(check->bo, trash.str, 
httpchk_build_status_header(s, trash.str));
+   bo_putstr(check->bo, "\r\n");
+   *check->bo->p = '\0'; /* to make gdb output easier to 
read */
+   }
+   }
+
+   /* prepare a new connection */
+   conn->flags = CO_FL_NONE;
+   conn->err_code = CO_ER_NONE;
+   conn->target = &s->obj_type;
+   conn_prepare(conn, &check_conn_cb, s->check_common.proto, 
s->check_common.xprt, check);
+
+   /* no client address */
+   clear_addr(&conn->addr.from);
+
+   if (is_addr(&s->check_common.addr))
+   /* we'll connect to the check addr specified on the server */
+   conn->addr.to = s->check_common.addr;
+   else
+   /* we'll connect to the addr on the server */
+   conn->addr.to = s->addr;
+
+   set_host_port(&conn->addr.to, check->port);
+
+   ret = SN_ERR_INTERNAL;
+   if (s->check_common.proto->connect)
+   ret = s->check_common.proto->connect(conn, check->type,
+ check->send_proxy ? 1 : 
check->type ? 0 : 2);
+   conn->flags |= CO_FL_WAKE_DATA;
+
+   return ret;
+}
+
+/*
  * manages a server health-check. Returns
  * the time the task accepts to wait, or TIME_ETERNITY for infinity.
  */
@@ -1421,67 +1490,7 @@ static struct task *process_chk(struct task *t)
check->bo->p = check->bo->data;
check->bo->o = 0;
 
-
-  /* prepare the check buffer
-   * This should not be used if check is the secondary agent check
-   * of a server as s->proxy->check_req will relate to the
-   * configuration of the primary check */
-  if (check->type && check != &s->agent) {
-   bo_putblk(check->bo, s->proxy->check_req, 
s->proxy->check_len);
-
-   /* we want to check if this host replies to HTTP or 
SSLv3 requests
-* so we'll send the request, and won't wake the 
checker up now.
-*/
-   if ((s->proxy->options2 & PR_O2_CHK_ANY) == 
PR_O2_SSL3_CHK) {
-   /* SSL requires that we put Unix time in the 
request */
-   int gmt_time = htonl(date.tv_sec);
-   memcpy(check->bo->data + 11, &gmt_time, 4);
-   }
-   else if ((s->proxy->options2 & PR_O2_CHK_ANY) == 
PR_O2_HTTP_CHK) {
-   if (s->

[PATCH v6 16/22] MEDIUM: Add DRAIN state and report it on the stats page

2013-08-22 Thread Simon Horman
Add a DRAIN sub-state for a server which
will be shown on the stats page instead of UP if
an agent check is in use and the agent has most recently returned "drain".

Signed-off-by: Simon Horman 
---
 include/types/server.h |  3 ++-
 src/checks.c   |  7 +++
 src/dumpstats.c| 12 +---
 3 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/include/types/server.h b/include/types/server.h
index 9f7a23c..dd17d61 100644
--- a/include/types/server.h
+++ b/include/types/server.h
@@ -52,7 +52,8 @@
 #define SRV_GOINGDOWN  0x0020  /* this server says that it's going down (404) 
*/
 #define SRV_WARMINGUP  0x0040  /* this server is warming up after a failure */
 #define SRV_MAINTAIN   0x0080  /* this server is in maintenance mode */
-/* unused: 0x0100, 0x0200, 0x0400 */
+#define SRV_DRAIN  0x0100  /* this server has been requested to drain its 
connections */
+/* unused: 0x0200, 0x0400 */
 #define SRV_SEND_PROXY 0x0800  /* this server talks the PROXY protocol */
 #define SRV_NON_STICK  0x1000  /* never add connections allocated to this 
server to a stick table */
 
diff --git a/src/checks.c b/src/checks.c
index 5d893f8..a9a93ae 100644
--- a/src/checks.c
+++ b/src/checks.c
@@ -829,6 +829,7 @@ static void agent_expect(struct check *check, char *data)
short status = HCHK_STATUS_L7RSP;
const char *desc = "Unknown feedback string";
const char *down_cmd = NULL;
+   int drain = 0;
 
cut_crlf(data);
 
@@ -843,6 +844,7 @@ static void agent_expect(struct check *check, char *data)
if (!desc) {
desc = "drain";
status = HCHK_STATUS_L7OKD;
+   drain = 1;
}
} else if (!strncasecmp(data, "down", strlen("down"))) {
down_cmd = "down";
@@ -852,6 +854,11 @@ static void agent_expect(struct check *check, char *data)
down_cmd = "fail";
}
 
+   if (drain)
+   check->server->state |= SRV_DRAIN;
+   else
+   check->server->state &= ~SRV_DRAIN;
+
if (down_cmd) {
const char *end = data + strlen(down_cmd);
/*
diff --git a/src/dumpstats.c b/src/dumpstats.c
index a7dce57..d9795fa 100644
--- a/src/dumpstats.c
+++ b/src/dumpstats.c
@@ -2112,13 +2112,15 @@ static int stats_dump_sv_stats(struct stream_interface 
*si, struct proxy *px, in
int i;
 
if (si->applet.ctx.stats.flags & STAT_FMT_HTML) {
-   static char *srv_hlt_st[7] = {
+   static char *srv_hlt_st[9] = {
"DOWN",
"DN %d/%d ↑",
"UP %d/%d ↓",
"UP",
"NOLB %d/%d ↓",
"NOLB",
+   "DRAIN %d/%d ↓",
+   "DRAIN",
"no check"
};
 
@@ -2336,13 +2338,15 @@ static int stats_dump_sv_stats(struct stream_interface 
*si, struct proxy *px, in
chunk_appendf(&trash, "-\n");
}
else { /* CSV mode */
-   static char *srv_hlt_st[7] = {
+   static char *srv_hlt_st[9] = {
"DOWN,",
"DOWN %d/%d,",
"UP %d/%d,",
"UP,",
"NOLB %d/%d,",
"NOLB,",
+   "DRAIN %d/%d,",
+   "DRAIN,",
"no check,"
};
 
@@ -2948,7 +2952,7 @@ static int stats_dump_proxy_to_buffer(struct 
stream_interface *si, struct proxy
 
/* FIXME: produce some small strings for "UP/DOWN x/y 
&#;" */
if (!(svs->state & SRV_CHECKED))
-   sv_state = 6;
+   sv_state = 8;
else if (svs->state & SRV_RUNNING) {
if (svs->check.health == svs->rise + svs->fall 
- 1)
sv_state = 3; /* UP */
@@ -2957,6 +2961,8 @@ static int stats_dump_proxy_to_buffer(struct 
stream_interface *si, struct proxy
 
if (svs->state & SRV_GOINGDOWN)
sv_state += 2;
+   else if (svs->state & SRV_DRAIN)
+   sv_state += 4;
}
else
if (svs->check.health)
-- 
1.8.3.2




[PATCH v6 10/22] MEDIUM: Move health element to struct check

2013-08-22 Thread Simon Horman
This is in preparation for associating a agent check
with a server which runs as well as the server's existing check.

Signed-off-by: Simon Horman 
---
 include/types/server.h |  3 ++-
 src/cfgparse.c | 10 +-
 src/checks.c   | 50 +-
 src/dumpstats.c| 12 ++--
 src/proto_http.c   |  2 +-
 src/server.c   |  4 ++--
 6 files changed, 41 insertions(+), 40 deletions(-)

diff --git a/include/types/server.h b/include/types/server.h
index cb65dbc..ebd827b 100644
--- a/include/types/server.h
+++ b/include/types/server.h
@@ -120,6 +120,8 @@ struct check {
int inter, fastinter, downinter;/* checks: time in milliseconds 
*/
int result; /* health-check result : 
SRV_CHK_* */
int state;  /* health-check result : CHK_* 
*/
+   int health; /* 0 to server->rise-1 = bad;
+* rise to 
server->rise+server->fall-1 = good */
int type;   /* Check type, one of 
PR_O2_*_CHK */
const char *name;   /* Name of check: "Health" or 
"Agent" */
struct server *server;  /* back-pointer to server */
@@ -152,7 +154,6 @@ struct server {
 
struct server *tracknext, *track;   /* next server in a tracking 
list, tracked server */
char *trackit;  /* temporary variable to make 
assignment deferrable */
-   int health; /* 0->rise-1 = bad; 
rise->rise+fall-1 = good */
int consecutive_errors; /* current number of 
consecutive errors */
int rise, fall; /* time in iterations */
int consecutive_errors_limit;   /* number of consecutive errors 
that triggers an event */
diff --git a/src/cfgparse.c b/src/cfgparse.c
index 631a36a..ba90454 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -4257,7 +4257,7 @@ stats_error_parsing:
newsrv->uweight = newsrv->iweight
= curproxy->defsrv.iweight;
 
-   newsrv->health = newsrv->rise;  /* up, but will fall 
down at first failure */
+   newsrv->check.health = newsrv->rise;/* up, but will 
fall down at first failure */
 
newsrv->check.status= HCHK_STATUS_INI;
newsrv->check.name  = "Health";
@@ -4296,8 +4296,8 @@ stats_error_parsing:
goto out;
}
 
-   if (newsrv->health)
-   newsrv->health = newsrv->rise;
+   if (newsrv->check.health)
+   newsrv->check.health = newsrv->rise;
cur_arg += 2;
}
else if (!strcmp(args[cur_arg], "fall")) {
@@ -4478,7 +4478,7 @@ stats_error_parsing:
else if (!defsrv && !strcmp(args[cur_arg], "disabled")) 
{
newsrv->state |= SRV_MAINTAIN;
newsrv->state &= ~SRV_RUNNING;
-   newsrv->health = 0;
+   newsrv->check.health = 0;
cur_arg += 1;
}
else if (!defsrv && !strcmp(args[cur_arg], "observe")) {
@@ -6768,7 +6768,7 @@ out_uri_auth_compat:
if (srv->state & SRV_MAINTAIN) {
newsrv->state |= SRV_MAINTAIN;
newsrv->state &= ~SRV_RUNNING;
-   newsrv->health = 0;
+   newsrv->check.health = 0;
}
 
newsrv->track = srv;
diff --git a/src/checks.c b/src/checks.c
index 6659b6b..c7e2345 100644
--- a/src/checks.c
+++ b/src/checks.c
@@ -229,8 +229,8 @@ static void set_server_check_status(struct check *check, 
short status, const cha
}
 
if (s->proxy->options2 & PR_O2_LOGHCHKS &&
-   (((s->health != 0) && (check->result & SRV_CHK_FAILED)) ||
-   ((s->health != s->rise + s->fall - 1) && (check->result & 
SRV_CHK_PASSED)) ||
+   (((check->health != 0) && (check->result & SRV_CHK_FAILED)) ||
+   ((check->health != s->rise + s->fall - 1) && (check->result & 
SRV_CHK_PASSED)) ||
((s->state & SRV_GOINGDOWN) && !(check->result & SRV_CHK_DISABLE)) 
||
(!(s->state & SRV_GOINGDOWN) && (check->result & 
SRV_CHK_DISABLE {
 
@@ -239,7 +239,7 @@ static void set_server_check_status(struct check *check, 
short status, const cha
chunk_reset(&trash);
 

[PATCH v6 18/22] MEDIUM: Do not mark a server as down if the agent is unavailable

2013-08-22 Thread Simon Horman
In the case where agent-port is used and the agent
check is a secondary check to not mark a server as down
if the agent becomes unavailable.

In this configuration the agent should only cause a server to be marked
as down if the agent returns "fail", "stopped" or "down".

Signed-off-by: Simon Horman 

---

v4
* Never update health of agent on failure to connect

  Previously the health was recharged on such cases.
  But this causes the health to be recharged even
  if the most recent result from the agent was "fail", "stopped", or "down".

  The result was unnecessary logging of "fail", "stopped", or "down"
  results from the agent if they were interleaved with timeouts.
  Or in other words, if the agent responded only occasionally
  but consistently with "fail", "stopped", or "down".

v3
* No change

v2
* Only log agent server status if the change in status
  will affect the server's state
---
 doc/configuration.txt  |  3 ++
 include/types/server.h |  5 ++--
 src/checks.c   | 77 +-
 3 files changed, 57 insertions(+), 28 deletions(-)

diff --git a/doc/configuration.txt b/doc/configuration.txt
index 233be4e..40675f4 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -7707,6 +7707,9 @@ agent-port 
   using the "port" parameter. A third scenario is to use "http-check
   agent-hdr" to run an agent and http checks simultaneously over HTTP.
 
+  When run in this manner failure to connect to the agent is not
+  considered an error as connectivity is tested by the primary check.
+
   See also the "agent-inter" parameter.
 
 backup
diff --git a/include/types/server.h b/include/types/server.h
index dd17d61..f316e01 100644
--- a/include/types/server.h
+++ b/include/types/server.h
@@ -52,8 +52,9 @@
 #define SRV_GOINGDOWN  0x0020  /* this server says that it's going down (404) 
*/
 #define SRV_WARMINGUP  0x0040  /* this server is warming up after a failure */
 #define SRV_MAINTAIN   0x0080  /* this server is in maintenance mode */
-#define SRV_DRAIN  0x0100  /* this server has been requested to drain its 
connections */
-/* unused: 0x0200, 0x0400 */
+#define SRV_WILLDRAIN  0x0100  /* this server has been requested to drain its 
connections but has not started doing so yet */
+#define SRV_DRAIN  0x0200  /* this been requested to drain its connections 
*/
+/* unused: 0x0400 */
 #define SRV_SEND_PROXY 0x0800  /* this server talks the PROXY protocol */
 #define SRV_NON_STICK  0x1000  /* never add connections allocated to this 
server to a stick table */
 
diff --git a/src/checks.c b/src/checks.c
index 706ed31..88a34ea 100644
--- a/src/checks.c
+++ b/src/checks.c
@@ -228,11 +228,19 @@ static void set_server_check_status(struct check *check, 
short status, const cha
tv_zero(&check->start);
}
 
+   /* Failure to connect to the agent as a secondary check should not
+* cause the server to be marked down. So only log status changes
+* for HCHK_STATUS_* statuses */
+   if (check == &s->agent && check->status < HCHK_STATUS_L7TOUT)
+   return;
+
if (s->proxy->options2 & PR_O2_LOGHCHKS &&
(((check->health != 0) && (check->result & SRV_CHK_FAILED)) ||
((check->health != s->rise + s->fall - 1) && (check->result & 
SRV_CHK_PASSED)) ||
((s->state & SRV_GOINGDOWN) && !(check->result & SRV_CHK_DISABLE)) 
||
-   (!(s->state & SRV_GOINGDOWN) && (check->result & 
SRV_CHK_DISABLE {
+   (!(s->state & SRV_GOINGDOWN) && (check->result & SRV_CHK_DISABLE)) 
||
+   ((s->state & SRV_WILLDRAIN) && !(s->state & SRV_DRAIN)) ||
+   (!(s->state & SRV_WILLDRAIN) && (s->state & SRV_DRAIN {
 
int health, rise, fall, state;
 
@@ -284,7 +292,8 @@ static void set_server_check_status(struct check *check, 
short status, const cha
chunk_appendf(&trash, ", status: %d/%d %s",
 (state & SRV_RUNNING) ? (health - rise + 1) : 
(health),
 (state & SRV_RUNNING) ? (fall) : (rise),
-(state & SRV_RUNNING)?"UP":"DOWN");
+(state & SRV_RUNNING) ?
+((state & SRV_WILLDRAIN) ? "DRAIN" : "UP") : 
"DOWN");
 
Warning("%s.\n", trash.str);
send_log(s->proxy, LOG_NOTICE, "%s.\n", trash.str);
@@ -611,6 +620,27 @@ static void set_server_enabled(struct server *s) {
set_server_enabled(srv);
 }
 
+static void check_failed(struct check *check)
+{
+   struct server *s = check->server;
+
+   /* The agent secondary check should only cause a server to be marked
+* as down if check->status is HCHK_STATUS_L7STS, which indicates
+* that the agent returned "fail", "stopped" or "down".
+* The implication here is that failure to connect to the agent
+* as a secondary check should not cause the server to be marked
+*

[PATCH v6 03/22] MEDIUM: Split up struct server's check element

2013-08-22 Thread Simon Horman
This is in preparation for associating a agent check
with a server which runs as well as the server's existing check.

The split has been made by:
* Moving elements of struct server's check element that will
  be shared by both checks into a new check_common element
  of struct server.
* Moving the remaining elements to a new struct check and
  making struct server's check element a struct check.
* Adding a server element to struct check, a back-pointer
  to the server element it is a member of.
  - At this time the server could be obtained using
container_of, however, this will not be so easy
once a second struct check element is added to struct server
to accommodate an agent health check.

Signed-off-by: Simon Horman 

---

v6
* Correct use of srv->check_common.xprt ssl_sock_prepare_srv_ctx().
  Previously srv->check.xprt was used which causes a build failure
  when compiled with make USE_OPENSSL=1 ...
  Thanks to Scott McKeown for discovering this.

v2 - v5
* No change
---
 include/types/server.h | 31 +++
 src/cfgparse.c | 15 ---
 src/checks.c   | 12 ++--
 src/ssl_sock.c |  2 +-
 4 files changed, 34 insertions(+), 26 deletions(-)

diff --git a/include/types/server.h b/include/types/server.h
index e70ad8f..1befae6 100644
--- a/include/types/server.h
+++ b/include/types/server.h
@@ -103,6 +103,21 @@ struct tree_occ {
struct eb32_node node;
 };
 
+struct check {
+   struct connection *conn;/* connection state for health 
checks */
+
+   short port; /* the port to use for the 
health checks */
+   struct buffer *bi, *bo; /* input and output buffers to 
send/recv check */
+   struct task *task;  /* the task associated to the 
health check processing, NULL if disabled */
+   struct timeval start;   /* last health check start time 
*/
+   long duration;  /* time in ms took to finish 
last health check */
+   short status, code; /* check result, check code */
+   char desc[HCHK_DESC_LEN];   /* health check descritpion */
+   int use_ssl;/* use SSL for health checks */
+   int send_proxy; /* send a PROXY protocol header 
with checks */
+   struct server *server;  /* back-pointer to server */
+};
+
 struct server {
enum obj_type obj_type; /* object type == 
OBJ_TYPE_SERVER */
struct server *next;
@@ -163,21 +178,13 @@ struct server {
 
int puid;   /* proxy-unique server ID, used 
for SNMP, and "first" LB algo */
 
-   struct {/* health-check specific 
configuration */
-   struct connection *conn;/* connection state for health 
checks */
+   struct {/* configuration  used by 
halth-check and agent-check */
struct protocol *proto; /* server address protocol for 
health checks */
struct xprt_ops *xprt;  /* transport layer operations 
for health checks */
struct sockaddr_storage addr;   /* the address to check, if 
different from  */
-   short port; /* the port to use for the 
health checks */
-   struct buffer *bi, *bo; /* input and output buffers to 
send/recv check */
-   struct task *task;  /* the task associated to the 
health check processing, NULL if disabled */
-   struct timeval start;   /* last health check start time 
*/
-   long duration;  /* time in ms took to finish 
last health check */
-   short status, code; /* check result, check code */
-   char desc[HCHK_DESC_LEN];   /* health check descritpion */
-   int use_ssl;/* use SSL for health checks */
-   int send_proxy; /* send a PROXY protocol header 
with checks */
-   } check;
+   } check_common;
+
+   struct check check; /* health-check specific 
configuration */
 
 #ifdef USE_OPENSSL
int use_ssl;/* ssl enabled */
diff --git a/src/cfgparse.c b/src/cfgparse.c
index 41c1949..fc0b34a 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -4199,8 +4199,8 @@ stats_error_parsing:
}
 
newsrv->addr = *sk;
-   newsrv->proto = newsrv->check.proto = 
protocol_by_family(newsrv->addr.ss_family);
-   newsrv->xprt  = newsrv->check.xprt  = &raw_sock;
+   newsrv->proto = newsrv->check_common.proto = 
protocol_by_family(newsrv->addr.ss_family);
+   newsrv->xprt  = newsrv->check_common.xprt

[PATCH v6 01/22] DOC: Clarify documentation of option lb-agent-chk

2013-08-22 Thread Simon Horman
Avoid referring to check-port as this is not a configuration parameter.

Signed-off-by: Simon Horman 
---
 doc/configuration.txt | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/doc/configuration.txt b/doc/configuration.txt
index 87de595..796537e 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -3944,10 +3944,10 @@ option lb-agent-chk
 
 This currently has the same behaviour as down (iii).
 
-  The use of an alternate check-port, used to obtain agent heath check
-  information described above as opposed to the port of the service, may be
-  useful in conjunction with this option.
-
+  The use of the port parameter to a server may in conjunction with this
+  option be used to set the TCP port used to obtain agent heath check
+  information described above. Otherwise the port of the serivce will be
+  used.
 
 option ldap-check
   Use LDAPv3 health checks for server testing
-- 
1.8.3.2




[PATCH v6 12/22] MEDIUM: checks: Add supplementary agent checks

2013-08-22 Thread Simon Horman
Allow an agent check to be run in conjunction with one other server
health check.

If the backend for a server check is not lb-agent-chk then an agent
check may also be run using the agent-check parameter to a server,
which sets the TCP port to be used for the agent check.

e.g.
server  web1_1 127.0.0.1:80 check agent-port 1

The agent-inter parameter may also be used to specify the interval
and timeout for agent checks.

If either the health or agent check determines that a server is down
then it is marked as being down, otherwise it is marked as being up.

Signed-off-by: Simon Horman 

---

v5
* Rebase for removal of server argument from init_check
* Rebase for setting of type in init_check

v4
*  Increment global.maxsock for agent-port.

   If agent-port is configured then an extra socket is required.

* Do not send requests to secondary agent checks

  The request configuration of a proxy relates to the primary health
  check and should not be sent to the secondary health check if it
  is in operation.

* Correct usage of PR_O2_LB_AGENT_CHK

  The correct way to check for PR_O2_LB_AGENT_CHK is
  not to use x & PR_O2_LB_AGENT_CHK, but rather to use
  (x & PR_O2_CHK_ANY ) == PR_O2_LB_AGENT_CHK.

v2 - v3
* No change
---
 doc/configuration.txt  | 61 +---
 include/types/server.h |  1 +
 src/cfgparse.c | 76 --
 src/checks.c   | 20 ++---
 src/haproxy.c  |  6 
 5 files changed, 147 insertions(+), 17 deletions(-)

diff --git a/doc/configuration.txt b/doc/configuration.txt
index 796537e..9c5f5ee 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -777,11 +777,12 @@ nosplice
   "option splice-response".
 
 spread-checks <0..50, in percent>
-  Sometimes it is desirable to avoid sending health checks to servers at exact
-  intervals, for instance when many logical servers are located on the same
-  physical server. With the help of this parameter, it becomes possible to add
-  some randomness in the check interval between 0 and +/- 50%. A value between
-  2 and 5 seems to show good results. The default value remains at 0.
+  Sometimes it is desirable to avoid sending agent and health checks to
+  servers at exact intervals, for instance when many logical servers are
+  located on the same physical server. With the help of this parameter, it
+  becomes possible to add some randomness in the check interval between 0
+  and +/- 50%. A value between 2 and 5 seems to show good results. The
+  default value remains at 0.
 
 tune.bufsize 
   Sets the buffer size to this size (in bytes). Lower values allow more
@@ -3949,6 +3950,9 @@ option lb-agent-chk
   information described above. Otherwise the port of the serivce will be
   used.
 
+  This option conflicts with the agent-port parameter to a server.
+
+
 option ldap-check
   Use LDAPv3 health checks for server testing
   May be used in sections :   defaults | frontend | listen | backend
@@ -7648,6 +7652,43 @@ addr 
 
   Supported in default-server: No
 
+agent-inter 
+  The "agent-inter" parameter sets the interval between two agent checks
+  to  milliseconds. If left unspecified, the delay defaults to 2000 ms.
+
+  Just as with every other time-based parameter, it may be entered in any
+  other explicit unit among { us, ms, s, m, h, d }. The "agent-inter"
+  parameter also serves as a timeout for agent checks "timeout check" is
+  not set. In order to reduce "resonance" effects when multiple servers are
+  hosted on the same hardware, the agent and health checks of all servers
+  are started with a small time offset between them. It is also possible to
+  add some random noise in the agent and health checks interval using the
+  global "spread-checks" keyword. This makes sense for instance when a lot
+  of backends use the same servers.
+
+  Requires the "agent-port" parameter to be set.
+
+  Supported in default-server: Yes
+
+agent-port 
+  Using the "agent-port" parameter, it becomes possible to run an agent
+  check in conjunction with a regular health check. In this scenario the
+  "agent-port" parameter specifies the TCP that an agent check should
+  connect to. Typically this is different to the port of the service and
+  health-check.
+
+  For a description agent checks and the protocol used by them see the
+  description of "lb-agent-check".
+
+  In this the agent check is run in conjunction with another check
+  and as such the check backend should be set to some value other than
+  "lb-agent-check". An alternative scenario is to run only an agent check
+  in which case the check backend should be set to "lb-agent-check" and
+  "agent-port" should not be set; in that scenario the port may be set
+  using the "port" parameter.
+
+  See also the "agent-inter" parameter.
+
 backup
   When "backup" is present on a server line, the server is only used in load
   balancing when all other non-backup servers are unavailable. Reques

[PATCH v6 13/22] MEDIUM: Add helper for agent check events.

2013-08-22 Thread Simon Horman
Break agent check handling out of event_srv_chk_r().

This is in preparation for supporting agent check results
returned in an HTTP header.

Signed-off-by: Simon Horman 
---
 src/checks.c | 97 
 1 file changed, 52 insertions(+), 45 deletions(-)

diff --git a/src/checks.c b/src/checks.c
index f2b11c5..e5d65c7 100644
--- a/src/checks.c
+++ b/src/checks.c
@@ -819,6 +819,56 @@ static void event_srv_chk_w(struct connection *conn)
goto out_wakeup;
 }
 
+/*
+ * Perform content verification check on data buffer.
+ * The buffer MUST be terminated by a null byte before calling this function.
+ * Sets server status appropriately.
+ */
+static void agent_expect(struct check *check, char *data)
+{
+   short status = HCHK_STATUS_L7RSP;
+   const char *desc = "Unknown feedback string";
+   const char *down_cmd = NULL;
+
+   cut_crlf(data);
+
+   if (strchr(data, '%')) {
+   desc = server_parse_weight_change_request(check->server, data);
+   if (!desc) {
+   status = HCHK_STATUS_L7OKD;
+   desc = data;
+   }
+   } else if (!strcasecmp(data, "drain")) {
+   desc = server_parse_weight_change_request(check->server, "0%");
+   if (!desc) {
+   desc = "drain";
+   status = HCHK_STATUS_L7OKD;
+   }
+   } else if (!strncasecmp(data, "down", strlen("down"))) {
+   down_cmd = "down";
+   } else if (!strncasecmp(data, "stopped", strlen("stopped"))) {
+   down_cmd = "stopped";
+   } else if (!strncasecmp(data, "fail", strlen("fail"))) {
+   down_cmd = "fail";
+   }
+
+   if (down_cmd) {
+   const char *end = data + strlen(down_cmd);
+   /*
+* The command keyword must terminated the string or
+* be followed by a blank.
+*/
+   if (end[0] == '\0' || end[0] == ' ' || end[0] == '\t') {
+   status = HCHK_STATUS_L7STS;
+   /* Skip over leading blanks */
+   while (end[0] != '\0' && (end[0] == ' ' || end[0] == 
'\t'))
+   end++;
+   desc = end;
+   }
+   }
+
+   set_server_check_status(check, status, desc);
+}
 
 /*
  * This function is used only for server health-checks. It handles the server's
@@ -971,54 +1021,11 @@ static void event_srv_chk_r(struct connection *conn)
set_server_check_status(check, HCHK_STATUS_L7STS, desc);
break;
 
-   case PR_O2_LB_AGENT_CHK: {
-   short status = HCHK_STATUS_L7RSP;
-   const char *desc = "Unknown feedback string";
-   const char *down_cmd = NULL;
-
+   case PR_O2_LB_AGENT_CHK:
if (!done)
goto wait_more_data;
-
-   cut_crlf(check->bi->data);
-
-   if (strchr(check->bi->data, '%')) {
-   desc = server_parse_weight_change_request(s, 
check->bi->data);
-   if (!desc) {
-   status = HCHK_STATUS_L7OKD;
-   desc = check->bi->data;
-   }
-   } else if (!strcasecmp(check->bi->data, "drain")) {
-   desc = server_parse_weight_change_request(s, "0%");
-   if (!desc) {
-   desc = "drain";
-   status = HCHK_STATUS_L7OKD;
-   }
-   } else if (!strncasecmp(check->bi->data, "down", 
strlen("down"))) {
-   down_cmd = "down";
-   } else if (!strncasecmp(check->bi->data, "stopped", 
strlen("stopped"))) {
-   down_cmd = "stopped";
-   } else if (!strncasecmp(check->bi->data, "fail", 
strlen("fail"))) {
-   down_cmd = "fail";
-   }
-
-   if (down_cmd) {
-   const char *end = check->bi->data + strlen(down_cmd);
-   /*
-* The command keyword must terminated the string or
-* be followed by a blank.
-*/
-   if (end[0] == '\0' || end[0] == ' ' || end[0] == '\t') {
-   status = HCHK_STATUS_L7STS;
-   /* Skip over leading blanks */
-   while (end[0] != '\0' && (end[0] == ' ' || 
end[0] == '\t'))
-   end++;
-   desc = end;
-   }
-   }
-
-   set_server_check_status(check, status, desc);
+   agent_expect(check, check->bi->data);
break;
-   }
 
case PR_O2_PGSQL_CHK:
   

[PATCH v6 11/22] MEDIUM: Add helper for task creation for checks

2013-08-22 Thread Simon Horman
This helper is in preparation for adding a second struct check element
to struct server.

Signed-off-by: Simon Horman 

---

v5
* Rebase
---
 src/cfgparse.c |  3 +--
 src/checks.c   | 45 +++--
 2 files changed, 28 insertions(+), 20 deletions(-)

diff --git a/src/cfgparse.c b/src/cfgparse.c
index ba90454..29b9507 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -4257,9 +4257,8 @@ stats_error_parsing:
newsrv->uweight = newsrv->iweight
= curproxy->defsrv.iweight;
 
-   newsrv->check.health = newsrv->rise;/* up, but will 
fall down at first failure */
-
newsrv->check.status= HCHK_STATUS_INI;
+   newsrv->check.health= newsrv->rise; /* up, but will 
fall down at first failure */
newsrv->check.name  = "Health";
newsrv->check.server= newsrv;
 
diff --git a/src/checks.c b/src/checks.c
index c7e2345..9642666 100644
--- a/src/checks.c
+++ b/src/checks.c
@@ -1529,6 +1529,32 @@ static struct task *process_chk(struct task *t)
return t;
 }
 
+static int start_check_task(struct check *check, int mininter,
+   int nbcheck, int srvpos)
+{
+   struct task *t;
+   /* task for the check */
+   if ((t = task_new()) == NULL) {
+   Alert("Starting [%s:%s] check: out of memory.\n",
+ check->server->proxy->id, check->server->id);
+   return -1;
+   }
+
+   check->task = t;
+   t->process = process_chk;
+   t->context = check;
+
+   /* check this every ms */
+   t->expire = tick_add(now_ms,
+MS_TO_TICKS(((mininter &&
+  mininter >= srv_getinter(check)) ?
+ mininter : srv_getinter(check)) * 
srvpos / nbcheck));
+   check->start = now;
+   task_queue(t);
+
+   return 0;
+}
+
 /*
  * Start health-check.
  * Returns 0 if OK, -1 if error, and prints the error in this case.
@@ -1589,25 +1615,8 @@ int start_checks() {
if (!(s->state & SRV_CHECKED))
continue;
 
-   /* one task for the checks */
-   if ((t = task_new()) == NULL) {
-   Alert("Starting [%s:%s] check: out of 
memory.\n", px->id, s->id);
+   if (start_check_task(&s->check, mininter, nbcheck, 
srvpos++))
return -1;
-   }
-
-   s->check.task = t;
-   t->process = process_chk;
-   t->context = &s->check;
-
-   /* check this every ms */
-   t->expire = tick_add(now_ms,
-MS_TO_TICKS(((mininter &&
-  mininter >= 
srv_getinter(&s->check)) ?
- mininter : 
srv_getinter(&s->check)) * srvpos / nbcheck));
-   s->check.start = now;
-   task_queue(t);
-
-   srvpos++;
}
}
return 0;
-- 
1.8.3.2




[PATCH v6 06/22] MEDIUM: Paramatise functions over the check of a server

2013-08-22 Thread Simon Horman
Paramatise the following functions over the check of a server

* set_server_down
* set_server_up
* srv_getinter
* server_status_printf
* set_server_check_status
* set_server_disabled

Generally the server parameter of these functions has been removed.
Where it is still needed it is obtained using check->server.

This is in preparation for associating a agent check
with a server which runs as well as the server's existing check.
By paramatising these functions they may act on each of the checks
without further significant modification.

Signed-off-by: Simon Horman 

---

This is a rather large patch and I would be happy to split it up
on request.

v4
* Use check->type in process_check()

  Use check->type instead of s->proxy->options2 & PR_O2_CHK_ANY
  as the former is specific to the check being processed whereas
  the latter relates only to the primary check of a server.

* Add type to struct check

  This is used to indicate the type of a check independent of
  its server's proxy's check type.

v2 - v3
* No Change
---
 include/proto/checks.h |   4 +-
 include/proto/server.h |   2 +-
 include/types/server.h |   1 +
 src/cfgparse.c |   1 +
 src/checks.c   | 470 +
 src/dumpstats.c|   8 +-
 src/proto_http.c   |   4 +-
 src/server.c   |  10 +-
 8 files changed, 254 insertions(+), 246 deletions(-)

diff --git a/include/proto/checks.h b/include/proto/checks.h
index 042b854..f4f9c49 100644
--- a/include/proto/checks.h
+++ b/include/proto/checks.h
@@ -27,8 +27,8 @@
 
 const char *get_check_status_description(short check_status);
 const char *get_check_status_info(short check_status);
-void set_server_down(struct server *s);
-void set_server_up(struct server *s);
+void set_server_down(struct check *check);
+void set_server_up(struct check *check);
 int start_checks();
 void health_adjust(struct server *s, short status);
 
diff --git a/include/proto/server.h b/include/proto/server.h
index b2df045..1151b3c 100644
--- a/include/proto/server.h
+++ b/include/proto/server.h
@@ -33,7 +33,7 @@
 #include 
 
 int srv_downtime(const struct server *s);
-int srv_getinter(const struct server *s);
+int srv_getinter(const struct check *check);
 
 /* increase the number of cumulated connections on the designated server */
 static void inline srv_inc_sess_ctr(struct server *s)
diff --git a/include/types/server.h b/include/types/server.h
index 81968e7..57b32e3 100644
--- a/include/types/server.h
+++ b/include/types/server.h
@@ -117,6 +117,7 @@ struct check {
int send_proxy; /* send a PROXY protocol header 
with checks */
int inter, fastinter, downinter;/* checks: time in milliseconds 
*/
int result; /* health-check result : 
SRV_CHK_* */
+   int type;   /* Check type, one of 
PR_O2_*_CHK */
struct server *server;  /* back-pointer to server */
 };
 
diff --git a/src/cfgparse.c b/src/cfgparse.c
index 7df94e3..efbdad8 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -4860,6 +4860,7 @@ stats_error_parsing:
 
newsrv->check.conn->t.sock.fd = -1; /* no check in 
progress yet */
newsrv->check.status = HCHK_STATUS_INI;
+   newsrv->check.type = curproxy->options2 & PR_O2_CHK_ANY;
newsrv->check.server = newsrv;
newsrv->state |= SRV_CHECKED;
}
diff --git a/src/checks.c b/src/checks.c
index c0b8c0e..5e298ad 100644
--- a/src/checks.c
+++ b/src/checks.c
@@ -147,33 +147,30 @@ const char *get_analyze_status(short analyze_status) {
return analyze_statuses[HANA_STATUS_UNKNOWN].desc;
 }
 
-#define SSP_O_HCHK 0x0002
-
-static void server_status_printf(struct chunk *msg, struct server *s, unsigned 
options, int xferred) {
-
+static void server_status_printf(struct chunk *msg, struct server *s, struct 
check *check, int xferred) {
if (s->track)
chunk_appendf(msg, " via %s/%s",
s->track->proxy->id, s->track->id);
 
-   if (options & SSP_O_HCHK) {
-   chunk_appendf(msg, ", reason: %s", 
get_check_status_description(s->check.status));
+   if (check) {
+   chunk_appendf(msg, ", reason: %s", 
get_check_status_description(check->status));
 
-   if (s->check.status >= HCHK_STATUS_L57DATA)
-   chunk_appendf(msg, ", code: %d", s->check.code);
+   if (check->status >= HCHK_STATUS_L57DATA)
+   chunk_appendf(msg, ", code: %d", check->code);
 
-   if (*s->check.desc) {
+   if (*check->desc) {
struct chunk src;
 
chunk_appendf(msg, ", info: \"");
 
-   chunk_initlen(&src, s->check.desc, 0, 
strlen(s->check.desc));
+   chunk_initlen(&src, check->d

[PATCH v6 07/22] MEDIUM: cfgparse: Factor out check initialisation

2013-08-22 Thread Simon Horman
This is in preparation for struct server having two elements
of type struct check.

Signed-off-by: Simon Horman 

---

v5
* Remove server argument from init_check. It is not used.
* Set type in init_check

  This allows a zero type to be used to indicate that
  a task for a secondary agent check should not be stated.
---
 src/cfgparse.c | 62 +++---
 1 file changed, 38 insertions(+), 24 deletions(-)

diff --git a/src/cfgparse.c b/src/cfgparse.c
index efbdad8..c70700d 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -1620,6 +1620,34 @@ out:
return err_code;
 }
 
+static int init_check(struct check *check, int type, const char * file, int 
linenum)
+{
+   check->type = type;
+
+   /* Allocate buffer for requests... */
+   if ((check->bi = calloc(sizeof(struct buffer) + global.tune.chksize, 
sizeof(char))) == NULL) {
+   Alert("parsing [%s:%d] : out of memory while allocating check 
buffer.\n", file, linenum);
+   return ERR_ALERT | ERR_ABORT;
+   }
+   check->bi->size = global.tune.chksize;
+
+   /* Allocate buffer for responses... */
+   if ((check->bo = calloc(sizeof(struct buffer) + global.tune.chksize, 
sizeof(char))) == NULL) {
+   Alert("parsing [%s:%d] : out of memory while allocating check 
buffer.\n", file, linenum);
+   return ERR_ALERT | ERR_ABORT;
+   }
+   check->bo->size = global.tune.chksize;
+
+   /* Allocate buffer for partial results... */
+   if ((check->conn = calloc(1, sizeof(struct connection))) == NULL) {
+   Alert("parsing [%s:%d] : out of memory while allocating check 
connection.\n", file, linenum);
+   return ERR_ALERT | ERR_ABORT;
+   }
+
+   check->conn->t.sock.fd = -1; /* no agent in progress yet */
+
+   return 0;
+}
 
 int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
 {
@@ -4231,6 +4259,9 @@ stats_error_parsing:
 
newsrv->health = newsrv->rise;  /* up, but will fall 
down at first failure */
 
+   newsrv->check.status= HCHK_STATUS_INI;
+   newsrv->check.server= newsrv;
+
cur_arg = 3;
} else {
newsrv = &curproxy->defsrv;
@@ -4790,6 +4821,8 @@ stats_error_parsing:
}
 
if (do_check) {
+   int ret;
+
if (newsrv->trackit) {
Alert("parsing [%s:%d]: unable to enable checks 
and tracking at the same time!\n",
file, linenum);
@@ -4835,33 +4868,14 @@ stats_error_parsing:
goto out;
}
 
-   /* Allocate buffer for check requests... */
-   if ((newsrv->check.bi = calloc(sizeof(struct buffer) + 
global.tune.chksize, sizeof(char))) == NULL) {
-   Alert("parsing [%s:%d] : out of memory while 
allocating check buffer.\n", file, linenum);
-   err_code |= ERR_ALERT | ERR_ABORT;
-   goto out;
-   }
-   newsrv->check.bi->size = global.tune.chksize;
-
-   /* Allocate buffer for check responses... */
-   if ((newsrv->check.bo = calloc(sizeof(struct buffer) + 
global.tune.chksize, sizeof(char))) == NULL) {
-   Alert("parsing [%s:%d] : out of memory while 
allocating check buffer.\n", file, linenum);
-   err_code |= ERR_ALERT | ERR_ABORT;
-   goto out;
-   }
-   newsrv->check.bo->size = global.tune.chksize;
-
-   /* Allocate buffer for partial check results... */
-   if ((newsrv->check.conn = calloc(1, sizeof(struct 
connection))) == NULL) {
-   Alert("parsing [%s:%d] : out of memory while 
allocating check connection.\n", file, linenum);
-   err_code |= ERR_ALERT | ERR_ABORT;
+   ret = init_check(&newsrv->check,
+curproxy->options2 & PR_O2_CHK_ANY,
+file, linenum);
+   if (ret) {
+   err_code |= ret;
goto out;
}
 
-   newsrv->check.conn->t.sock.fd = -1; /* no check in 
progress yet */
-   newsrv->check.status = HCHK_STATUS_INI;
-   newsrv->check.type = curproxy->options2 & PR_O2_CHK_ANY;
-   newsrv->check.server = newsrv;
newsrv->state |= SRV_CHECKED;
}
 
-- 
1.8.3.2




[PATCH v6 08/22] MEDIUM: Add state to struct check

2013-08-22 Thread Simon Horman
Add state to struct check. This is currently used to store one bit,
CHK_RUNNING, which is set if a check is running and clear otherwise.
This bit was previously SRV_CHK_RUNNING of the state element of struct
server.

This is in preparation for associating a agent check
with a server which runs as well as the server's existing check.

Signed-off-by: Simon Horman 
---
 include/types/server.h | 5 -
 src/checks.c   | 8 
 src/dumpstats.c| 2 +-
 3 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/include/types/server.h b/include/types/server.h
index 57b32e3..584dadb 100644
--- a/include/types/server.h
+++ b/include/types/server.h
@@ -55,7 +55,6 @@
 /* unused: 0x0100, 0x0200, 0x0400 */
 #define SRV_SEND_PROXY 0x0800  /* this server talks the PROXY protocol */
 #define SRV_NON_STICK  0x1000  /* never add connections allocated to this 
server to a stick table */
-#define SRV_CHK_RUNNING 0x2000  /* a check is currently running on this server 
*/
 
 /* function which act on servers need to return various errors */
 #define SRV_STATUS_OK   0   /* everything is OK. */
@@ -70,6 +69,9 @@
 #define SRV_CHK_PASSED  0x0002   /* server check succeeded unless FAILED is 
also set */
 #define SRV_CHK_DISABLE 0x0004   /* server returned a "disable" code */
 
+/* check flags */
+#define CHK_RUNNING0x0001  /* this check is currently running */
+
 /* various constants */
 #define SRV_UWGHT_RANGE 256
 #define SRV_UWGHT_MAX   (SRV_UWGHT_RANGE)
@@ -117,6 +119,7 @@ struct check {
int send_proxy; /* send a PROXY protocol header 
with checks */
int inter, fastinter, downinter;/* checks: time in milliseconds 
*/
int result; /* health-check result : 
SRV_CHK_* */
+   int state;  /* health-check result : CHK_* 
*/
int type;   /* Check type, one of 
PR_O2_*_CHK */
struct server *server;  /* back-pointer to server */
 };
diff --git a/src/checks.c b/src/checks.c
index 5e298ad..75ad516 100644
--- a/src/checks.c
+++ b/src/checks.c
@@ -1311,7 +1311,7 @@ static struct task *process_chk(struct task *t)
int ret;
int expired = tick_is_expired(t->expire, now_ms);
 
-   if (!(s->state & SRV_CHK_RUNNING)) {
+   if (!(check->state & CHK_RUNNING)) {
/* no check currently running */
if (!expired) /* woke up too early */
return t;
@@ -1325,7 +1325,7 @@ static struct task *process_chk(struct task *t)
/* we'll initiate a new check */
set_server_check_status(check, HCHK_STATUS_START, NULL);
 
-   s->state |= SRV_CHK_RUNNING;
+   check->state |= CHK_RUNNING;
check->bi->p = check->bi->data;
check->bi->i = 0;
check->bo->p = check->bo->data;
@@ -1416,7 +1416,7 @@ static struct task *process_chk(struct task *t)
 
/* here, we have seen a synchronous error, no fd was allocated 
*/
 
-   s->state &= ~SRV_CHK_RUNNING;
+   check->state &= ~CHK_RUNNING;
if (s->health > s->rise) {
s->health--; /* still good */
s->counters.failed_checks++;
@@ -1512,7 +1512,7 @@ static struct task *process_chk(struct task *t)
set_server_up(check);
}
}
-   s->state &= ~SRV_CHK_RUNNING;
+   check->state &= ~CHK_RUNNING;
 
rv = 0;
if (global.spread_checks > 0) {
diff --git a/src/dumpstats.c b/src/dumpstats.c
index 9a422c1..19f9848 100644
--- a/src/dumpstats.c
+++ b/src/dumpstats.c
@@ -2273,7 +2273,7 @@ static int stats_dump_sv_stats(struct stream_interface 
*si, struct proxy *px, in
if (sv->state & SRV_CHECKED) {
chunk_appendf(&trash,
  " %s%s",
- (sv->state & SRV_CHK_RUNNING) ? "* " : "",
+ (sv->check.state & CHK_RUNNING) ? "* " : 
"",
  get_check_status_info(sv->check.status));
 
if (sv->check.status >= HCHK_STATUS_L57DATA)
-- 
1.8.3.2




[PATCH v6 00/22] Agent Check Enhancements and External Check

2013-08-22 Thread Simon Horman
Hi,

this series comprises of several components

I have combined them because they depend on each other.

It should be possible to review the components
in order without particular regard for subsequent components.
That is, it should be possible to review small subsets of this series.

A. Patches 0-1 are cleanup patches

  DOC: Clarify documentation of option lb-agent-chk
  CLEANUP: Make parameters of srv_downtime and srv_getinter const

B. Patches 2 - 12 add support for a secondary agent health check

   In this mode, a non-agent health check is run as the primary
   health check and a secondary agent health check is also run.

  MEDIUM: Split up struct server's check element
  MEDIUM: Move {,fast,down}inter to struct check
  MEDIUM: Move result element to struct check
  MEDIUM: Paramatise functions over the check of a server
  MEDIUM: cfgparse: Factor out check initialisation
  MEDIUM: Add state to struct check
  MEDIUM: Add name element to struct check
  MEDIUM: Move health element to struct check
  MEDIUM: Add helper for task creation for checks
  MEDIUM: checks: Add supplementary agent checks


C. Patches 13 - 15 add support for the agent-hdr option to http-check.

   This allows agent information to be passed in the HTTP header
   returned as part of an http check. In this way an HTTP health
   check and an agent check can be run simultaneously as part
   of the same health check.

  MEDIUM: Add helper for agent check events.
  MEDIUM: Parser to allow matching of HTTP header
  MEDIUM: Add http-check agent-hdr option

D. Patches 16 - 20 enhance the behaviour of agent checks.

   These behavioural changes were requested by loadbalancer.org.
   They reflect differences be their desired implementation and
   my supplied implementation and solutions to problems they
   encountered during testing.

  MEDIUM: Add DRAIN state and report it on the stats page
  MEDIUM: Log agent fail, stopped or down as info
  MEDIUM: Do not mark a server as down if the agent is unavailable
  MEDIUM: Set rise and fall of agent checks to 1
  MEDIUM: Add set agent pause|unpause unix socket command

E. Patches 21 - 23 add support for checking using an
   external short-lived process

   This is not strictly related to the agent health check work,
   but common code paths are touched making many of the preceding
   patches dependencies for the external health check patches.

  MEDIUM: Break out check establishment into establish_chk()
  MEDIUM: Add external check


Key Changes since v5 (posted on the 31st July)

* Use the same command-line arguments for external checks as are
  used by ldirectord agent checks to allow check-programs
  to be shared between ldirectord and haproxy.

  Changes to "MEDIUM: Add external check"

* Correct usage of srv->check_common.xprt in ssl_sock_prepare_srv_ctx()

  Changes to ""MEDIUM: Split up struct server's check element"


Key Changes since v4 (posted on the 20th July)

* Move the initialisation of the type field of struct check
  into init_check(). This means that it is uninitialised for server->agent
  if agent-port is not set and thus a task for the agent check will not be
  erroneously started start_checks().


Base


Based on 9f09521f2d2deacfb4b1b10b23eb5525b9941c62
("BUG/MEDIUM: unique_id: HTTP request counter must be unique!")
which is 55 commits after v1.5-dev19.


Availability

To aid review I have made this series available in git at:
https://github.com/horms/haproxy.git agent-check-20130822


Overall Diffstat:

 doc/configuration.txt |  140 -
 include/common/defaults.h |2 +
 include/proto/checks.h|4 +-
 include/proto/server.h|4 +-
 include/types/checks.h|4 +
 include/types/proxy.h |3 +
 include/types/server.h|   69 ++-
 src/cfgparse.c|  222 ++--
 src/checks.c  | 1303 +++--
 src/dumpstats.c   |   55 +-
 src/haproxy.c |6 +
 src/proto_http.c  |6 +-
 src/server.c  |   16 +-
 src/ssl_sock.c|2 +-
 14 files changed, 1313 insertions(+), 523 deletions(-)

-- 
1.8.3.2




[PATCH v6 22/22] MEDIUM: Add external check

2013-08-22 Thread Simon Horman
Add an external check which makes use of an external process to
check the status of a server.

---

v6
* Correct implementation and documentation of arguments to external-check
  command so that they are consistent with both each other and ldirectord's
  external check. The motivation being to allow the same scripts to be used
  with both haproxy and ldirectord.

v5
* Rebase

v4
* Remove stray use of s->check in process_chk()
  The check parameter should be used throughout process_chk()
* Layer 7 timeouts of agent checks should be ignored
* Ensure that argc is never used uninitialised in prepare_external_check()

v3
* Rebase: basically a rewrite of large sections of the code
* Merge with the following patches
  + "external-check: Actually execute command"
  + "Allow selection of of external-check in configuration file"

v2
* If the external command exits normally (WIFEXITED()) is true)
  then set the check's code to the exit status (WEXITSTATUS())
  of the process.
* Treat a timeout is a failure case rather than the test having passed
* Remove duplicate getnameinfo() call in start_checks()
* Remove duplicate assignment of sockaddr argument to getnameinfo(9
  which caused the check port and check addr configuration of
  a server to be ignored.
---
 doc/configuration.txt  |  26 
 include/types/checks.h |   4 +
 include/types/proxy.h  |   1 +
 include/types/server.h |  26 +++-
 src/cfgparse.c |  20 +++
 src/checks.c   | 339 +++--
 6 files changed, 398 insertions(+), 18 deletions(-)

diff --git a/doc/configuration.txt b/doc/configuration.txt
index a82d48a..2d7af6d 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -3995,6 +3995,32 @@ option ldap-check
   See also : "option httpchk"
 
 
+option external-check
+  Use external processes for server health checks
+  May be used in sections :   defaults | frontend | listen | backend
+ yes   |no|   yes  |   yes
+  Arguments : external command to run
+
+  It is possible to test the health of a server using an external command.
+  This is achieved by running the command given as the argument to the
+  external-check option. The arguments to the command are:
+
+  proxy_address proxy_port server_address server_port
+
+  The proxy_address and proxy_port are derived from the first listener
+  that is either IPv4, IPv6 or a UNIX socket. It is an error for no such
+  listeners to exist. In the case of a UNIX socket listener the
+  proxy_address will be the path of the socket and the proxy_port will
+  be the string "NOT_USED".
+
+  If the command executed and exits with a zero status then the check is
+  considered to have passed, otherwise the check is considered to have
+  failed.
+
+  Example :
+option external-check /bin/true
+
+
 option log-health-checks
 no option log-health-checks
   Enable or disable logging of health checks
diff --git a/include/types/checks.h b/include/types/checks.h
index 09a4eee..731db37 100644
--- a/include/types/checks.h
+++ b/include/types/checks.h
@@ -44,6 +44,10 @@ enum {
HCHK_STATUS_L7OKCD, /* L7 check conditionally passed */
HCHK_STATUS_L7STS,  /* L7 response error, for example HTTP 
5xx */
 
+   HCHK_STATUS_PROCERR,/* External process check failure */
+   HCHK_STATUS_PROCTOUT,   /* External process check timeout */
+   HCHK_STATUS_PROCOK, /* External process check passed */
+
HCHK_STATUS_SIZE
 };
 
diff --git a/include/types/proxy.h b/include/types/proxy.h
index 66e5db7..e608b9f 100644
--- a/include/types/proxy.h
+++ b/include/types/proxy.h
@@ -152,6 +152,7 @@ enum {
 #define PR_O2_LDAP_CHK  0x6000  /* use LDAP check for server health */
 #define PR_O2_SSL3_CHK  0x7000  /* use SSLv3 CLIENT_HELLO packets for 
server health */
 #define PR_O2_LB_AGENT_CHK 0x8000   /* use a TCP connection to obtain a 
metric of server health */
+#define PR_O2_EXT_CHK   0x9000  /* use external command for server 
health */
 /* unused: 0x9000 to 0xF00, reserved for health checks */
 #define PR_O2_CHK_ANY   0xF000  /* Mask to cover any check */
 /* end of proxy->options2 */
diff --git a/include/types/server.h b/include/types/server.h
index 24462eb..80db519 100644
--- a/include/types/server.h
+++ b/include/types/server.h
@@ -24,6 +24,7 @@
 
 #include 
 #include 
+#include 
 
 #ifdef USE_OPENSSL
 #include 
@@ -99,6 +100,14 @@
 #define SRV_SSL_O_NO_TLS_TICKETS 0x0100 /* disable session resumption tickets 
*/
 #endif
 
+struct pid_list {
+   struct list list;
+   pid_t pid;
+   struct task *t;
+   int status;
+   bool exited;
+};
+
 /* A tree occurrence is a descriptor of a place in a tree, with a pointer back
  * to the server itself.
  */
@@ -109,17 +118,24 @@ struct tree_occ {
 };
 
 struct check {
-   struct connection *conn;/* connection state for health 
checks */

[PATCH v6 04/22] MEDIUM: Move {,fast,down}inter to struct check

2013-08-22 Thread Simon Horman
Move {,fast,down}inter elements from struct server to struct check.
This allows those elements of a check to be independent of the check's server.

This is in preparation for associating a agent check
with a server which runs as well as the server's existing check.

Signed-off-by: Simon Horman 
---
 include/types/server.h |  2 +-
 src/cfgparse.c | 18 +-
 src/checks.c   | 10 +-
 src/server.c   |  6 +++---
 4 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/include/types/server.h b/include/types/server.h
index 1befae6..4894932 100644
--- a/include/types/server.h
+++ b/include/types/server.h
@@ -115,6 +115,7 @@ struct check {
char desc[HCHK_DESC_LEN];   /* health check descritpion */
int use_ssl;/* use SSL for health checks */
int send_proxy; /* send a PROXY protocol header 
with checks */
+   int inter, fastinter, downinter;/* checks: time in milliseconds 
*/
struct server *server;  /* back-pointer to server */
 };
 
@@ -152,7 +153,6 @@ struct server {
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: 
one of HANA_ONMARKEDDOWN_* */
short onmarkedup;   /* what to do when marked up: 
one of HANA_ONMARKEDUP_* */
-   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 fc0b34a..7df94e3 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -1322,9 +1322,9 @@ void init_default_instance()
defproxy.maxconn = cfg_maxpconn;
defproxy.conn_retries = CONN_RETRIES;
 
-   defproxy.defsrv.inter = DEF_CHKINTR;
-   defproxy.defsrv.fastinter = 0;
-   defproxy.defsrv.downinter = 0;
+   defproxy.defsrv.check.inter = DEF_CHKINTR;
+   defproxy.defsrv.check.fastinter = 0;
+   defproxy.defsrv.check.downinter = 0;
defproxy.defsrv.rise = DEF_RISETIME;
defproxy.defsrv.fall = DEF_FALLTIME;
defproxy.defsrv.check.port = 0;
@@ -4211,9 +4211,9 @@ stats_error_parsing:
 
newsrv->check.use_ssl = curproxy->defsrv.check.use_ssl;
newsrv->check.port  = curproxy->defsrv.check.port;
-   newsrv->inter   = curproxy->defsrv.inter;
-   newsrv->fastinter   = curproxy->defsrv.fastinter;
-   newsrv->downinter   = curproxy->defsrv.downinter;
+   newsrv->check.inter = curproxy->defsrv.check.inter;
+   newsrv->check.fastinter = 
curproxy->defsrv.check.fastinter;
+   newsrv->check.downinter = 
curproxy->defsrv.check.downinter;
newsrv->rise= curproxy->defsrv.rise;
newsrv->fall= curproxy->defsrv.fall;
newsrv->maxqueue= curproxy->defsrv.maxqueue;
@@ -4301,7 +4301,7 @@ stats_error_parsing:
err_code |= ERR_ALERT | ERR_FATAL;
goto out;
}
-   newsrv->inter = val;
+   newsrv->check.inter = val;
cur_arg += 2;
}
else if (!strcmp(args[cur_arg], "fastinter")) {
@@ -4318,7 +4318,7 @@ stats_error_parsing:
err_code |= ERR_ALERT | ERR_FATAL;
goto out;
}
-   newsrv->fastinter = val;
+   newsrv->check.fastinter = val;
cur_arg += 2;
}
else if (!strcmp(args[cur_arg], "downinter")) {
@@ -4335,7 +4335,7 @@ stats_error_parsing:
err_code |= ERR_ALERT | ERR_FATAL;
goto out;
}
-   newsrv->downinter = val;
+   newsrv->check.downinter = val;
cur_arg += 2;
}
else if (!defsrv && !strcmp(args[cur_arg], "addr")) {
diff --git a/src/checks.c b/src/checks.c
index ca0d404..84de6ad 100644
--- a/src/checks.c
+++ b/src/checks.c
@@ -691,8 +691,8 @@ void health_adjust(struct server *s, short status)
s->consecutive_errors = 0;
s->counters.failed_hana++;
 
-   if (s->fastinter

[PATCH v6 14/22] MEDIUM: Parser to allow matching of HTTP header

2013-08-22 Thread Simon Horman
Replace the current header parser, which simply skips the headers,
with a version that allows matching of a key in a header.

This is in preparation for supporting agent check results
returned in an HTTP header.

Signed-off-by: Simon Horman 
---
 src/checks.c | 94 ++--
 1 file changed, 66 insertions(+), 28 deletions(-)

diff --git a/src/checks.c b/src/checks.c
index e5d65c7..249a6ee 100644
--- a/src/checks.c
+++ b/src/checks.c
@@ -1641,6 +1641,70 @@ int start_checks() {
return 0;
 }
 
+enum httpchk_parse_header_state {
+   in_key,
+   in_value,
+   invalid,
+};
+
+static char *httpchk_parse_header(const struct server *s, const char *key, 
char **value_p)
+{
+   enum httpchk_parse_header_state state = key ? in_key : invalid;
+   state = (key && !*value_p) ? in_key : invalid;
+   size_t key_offset = 0;
+   char *contentptr;
+   int crlf = 0;
+
+   *value_p = NULL;
+
+   /* very simple response parser:
+* + Ignore CR.
+* + End of headers is determined by counting consecutive LFs
+* + Stop and return a pointer to the first char after the double
+*   CRLF or to '\0' if no double CRLF is found.
+* + If key is non-NULL then it will be matched against keys in
+*   headers.  The value of the first match of a header with a
+*   non-NULL value is returned in *value_p.
+*   The value is truncated at the first CRLF, and the key and
+*   value are treated as literals: gross simplifications.
+* + pointers described above point to data at an offset to
+*   s->check.bi->data.
+*/
+
+   for (contentptr = s->check.bi->data; *contentptr; contentptr++) {
+   if (crlf >= 2)
+   break;
+   if (*contentptr == '\r' || *contentptr == '\n') {
+   key_offset = 0;
+   state = (key && !*value_p) ? in_key : invalid;
+   if (*contentptr == '\n')
+   crlf++;
+   } else {
+   crlf = 0;
+   switch (state) {
+   case in_key:
+   if (key[key_offset] == '\0' && *contentptr == 
':') {
+   state = in_value;
+   key_offset = 0;
+   } else if (key[key_offset] != *contentptr) {
+   state = invalid;
+   } else {
+   key_offset++;
+   }
+   break;
+   case in_value:
+   if (!*value_p && *contentptr != ' ' && 
*contentptr != '\t')
+   *value_p = contentptr;
+   break;
+   case invalid:
+   break;
+   }
+   }
+   }
+
+   return contentptr;
+}
+
 /*
  * Perform content verification check on data in s->check.buffer buffer.
  * The buffer MUST be terminated by a null byte before calling this function.
@@ -1653,7 +1717,6 @@ static int httpchk_expect(struct server *s, int done)
static char status_msg[] = "HTTP status check returned code <000>";
char status_code[] = "000";
char *contentptr;
-   int crlf;
int ret;
 
switch (s->proxy->options2 & PR_O2_EXP_TYPE) {
@@ -1676,39 +1739,14 @@ static int httpchk_expect(struct server *s, int done)
 
case PR_O2_EXP_STR:
case PR_O2_EXP_RSTR:
-   /* very simple response parser: ignore CR and only count 
consecutive LFs,
-* stop with contentptr pointing to first char after the double 
CRLF or
-* to '\0' if crlf < 2.
-*/
-   crlf = 0;
-   for (contentptr = s->check.bi->data; *contentptr; contentptr++) 
{
-   if (crlf >= 2)
-   break;
-   if (*contentptr == '\r')
-   continue;
-   else if (*contentptr == '\n')
-   crlf++;
-   else
-   crlf = 0;
-   }
+   contentptr = httpchk_parse_header(s, NULL, NULL);
 
/* Check that response contains a body... */
-   if (crlf < 2) {
-   if (!done)
-   return 0;
-
-   set_server_check_status(&s->check, HCHK_STATUS_L7RSP,
-   "HTTP content check could not 
find a response body");
-   return 1;
-   }
-
-   /* Check that response body is not empty... */
  

[PATCH v6 05/22] MEDIUM: Move result element to struct check

2013-08-22 Thread Simon Horman
Move result element from struct server to struct check
This allows check results to be independent of the check's server.

This is in preparation for associating a agent check
with a server which runs as well as the server's existing check.

Signed-off-by: Simon Horman 
---
 include/types/server.h |  2 +-
 src/checks.c   | 50 +-
 2 files changed, 26 insertions(+), 26 deletions(-)

diff --git a/include/types/server.h b/include/types/server.h
index 4894932..81968e7 100644
--- a/include/types/server.h
+++ b/include/types/server.h
@@ -116,6 +116,7 @@ struct check {
int use_ssl;/* use SSL for health checks */
int send_proxy; /* send a PROXY protocol header 
with checks */
int inter, fastinter, downinter;/* checks: time in milliseconds 
*/
+   int result; /* health-check result : 
SRV_CHK_* */
struct server *server;  /* back-pointer to server */
 };
 
@@ -154,7 +155,6 @@ struct server {
short onmarkeddown; /* what to do when marked down: 
one of HANA_ONMARKEDDOWN_* */
short onmarkedup;   /* what to do when marked up: 
one of HANA_ONMARKEDUP_* */
int slowstart;  /* slowstart time in seconds 
(ms in the conf) */
-   int result; /* health-check result : 
SRV_CHK_* */
 
char *id;   /* just for identification */
unsigned iweight,uweight, eweight;  /* initial weight, 
user-specified weight, and effective weight */
diff --git a/src/checks.c b/src/checks.c
index 84de6ad..c0b8c0e 100644
--- a/src/checks.c
+++ b/src/checks.c
@@ -193,7 +193,7 @@ static void server_status_printf(struct chunk *msg, struct 
server *s, unsigned o
 }
 
 /*
- * Set s->check.status, update s->check.duration and fill s->result with
+ * Set s->check.status, update s->check.duration and fill s->check.result with
  * an adequate SRV_CHK_* value.
  *
  * Show information in logs about failed health check if server is UP
@@ -202,7 +202,7 @@ static void server_status_printf(struct chunk *msg, struct 
server *s, unsigned o
 static void set_server_check_status(struct server *s, short status, const char 
*desc)
 {
if (status == HCHK_STATUS_START) {
-   s->result = SRV_CHK_UNKNOWN;/* no result yet */
+   s->check.result = SRV_CHK_UNKNOWN;  /* no result yet */
s->check.desc[0] = '\0';
s->check.start = now;
return;
@@ -219,7 +219,7 @@ static void set_server_check_status(struct server *s, short 
status, const char *
 
s->check.status = status;
if (check_statuses[status].result)
-   s->result = check_statuses[status].result;
+   s->check.result = check_statuses[status].result;
 
if (status == HCHK_STATUS_HANA)
s->check.duration = -1;
@@ -230,10 +230,10 @@ static void set_server_check_status(struct server *s, 
short status, const char *
}
 
if (s->proxy->options2 & PR_O2_LOGHCHKS &&
-   (((s->health != 0) && (s->result & SRV_CHK_FAILED)) ||
-   ((s->health != s->rise + s->fall - 1) && (s->result & 
SRV_CHK_PASSED)) ||
-   ((s->state & SRV_GOINGDOWN) && !(s->result & SRV_CHK_DISABLE)) ||
-   (!(s->state & SRV_GOINGDOWN) && (s->result & SRV_CHK_DISABLE {
+   (((s->health != 0) && (s->check.result & SRV_CHK_FAILED)) ||
+   ((s->health != s->rise + s->fall - 1) && (s->check.result & 
SRV_CHK_PASSED)) ||
+   ((s->state & SRV_GOINGDOWN) && !(s->check.result & 
SRV_CHK_DISABLE)) ||
+   (!(s->state & SRV_GOINGDOWN) && (s->check.result & 
SRV_CHK_DISABLE {
 
int health, rise, fall, state;
 
@@ -245,7 +245,7 @@ static void set_server_check_status(struct server *s, short 
status, const char *
fall   = s->fall;
state  = s->state;
 
-   if (s->result & SRV_CHK_FAILED) {
+   if (s->check.result & SRV_CHK_FAILED) {
if (health > rise) {
health--; /* still good */
} else {
@@ -256,7 +256,7 @@ static void set_server_check_status(struct server *s, short 
status, const char *
}
}
 
-   if (s->result & SRV_CHK_PASSED) {
+   if (s->check.result & SRV_CHK_PASSED) {
if (health < rise + fall - 1) {
health++; /* was bad, stays for a while */
 
@@ -277,8 +277,8 @@ static void set_server_check_status(struct server *s, short 
status, const char *
 "Health check for %sserver %s/%s %s%s",
 s->state & SRV_BACKUP ? "backup " : "",
 s->proxy->id, s->id,
-   

[PATCH v6 02/22] CLEANUP: Make parameters of srv_downtime and srv_getinter const

2013-08-22 Thread Simon Horman
The parameters of srv_downtime and srv_getinter are not modified
and thus may be const.

Signed-off-by: Simon Horman 
---
 include/proto/server.h | 4 ++--
 src/server.c   | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/include/proto/server.h b/include/proto/server.h
index ded640a..b2df045 100644
--- a/include/proto/server.h
+++ b/include/proto/server.h
@@ -32,8 +32,8 @@
 #include 
 #include 
 
-int srv_downtime(struct server *s);
-int srv_getinter(struct server *s);
+int srv_downtime(const struct server *s);
+int srv_getinter(const struct server *s);
 
 /* increase the number of cumulated connections on the designated server */
 static void inline srv_inc_sess_ctr(struct server *s)
diff --git a/src/server.c b/src/server.c
index 98a9fbe..e542bb7 100644
--- a/src/server.c
+++ b/src/server.c
@@ -22,7 +22,7 @@ static struct srv_kw_list srv_keywords = {
.list = LIST_HEAD_INIT(srv_keywords.list)
 };
 
-int srv_downtime(struct server *s)
+int srv_downtime(const struct server *s)
 {
if ((s->state & SRV_RUNNING) && s->last_change < now.tv_sec)
// ignore negative time
return s->down_time;
@@ -30,7 +30,7 @@ int srv_downtime(struct server *s)
return now.tv_sec - s->last_change + s->down_time;
 }
 
-int srv_getinter(struct server *s)
+int srv_getinter(const struct server *s)
 {
if ((s->state & SRV_CHECKED) && (s->health == s->rise + s->fall - 1))
return s->inter;
-- 
1.8.3.2




[PATCH v6 09/22] MEDIUM: Add name element to struct check

2013-08-22 Thread Simon Horman
This is in preparation for associating a agent check
with a server which runs as well as the server's existing check.

Signed-off-by: Simon Horman 

---

v5
* Rebase
---
 include/types/server.h | 1 +
 src/cfgparse.c | 1 +
 src/checks.c   | 2 +-
 3 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/include/types/server.h b/include/types/server.h
index 584dadb..cb65dbc 100644
--- a/include/types/server.h
+++ b/include/types/server.h
@@ -121,6 +121,7 @@ struct check {
int result; /* health-check result : 
SRV_CHK_* */
int state;  /* health-check result : CHK_* 
*/
int type;   /* Check type, one of 
PR_O2_*_CHK */
+   const char *name;   /* Name of check: "Health" or 
"Agent" */
struct server *server;  /* back-pointer to server */
 };
 
diff --git a/src/cfgparse.c b/src/cfgparse.c
index c70700d..631a36a 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -4260,6 +4260,7 @@ stats_error_parsing:
newsrv->health = newsrv->rise;  /* up, but will fall 
down at first failure */
 
newsrv->check.status= HCHK_STATUS_INI;
+   newsrv->check.name  = "Health";
newsrv->check.server= newsrv;
 
cur_arg = 3;
diff --git a/src/checks.c b/src/checks.c
index 75ad516..6659b6b 100644
--- a/src/checks.c
+++ b/src/checks.c
@@ -273,7 +273,7 @@ static void set_server_check_status(struct check *check, 
short status, const cha
/* FIXME end: calculate local version of the 
health/rise/fall/state */
 
chunk_appendf(&trash,
-"Health check for %sserver %s/%s %s%s",
+"%s check for %sserver %s/%s %s%s", check->name,
 s->state & SRV_BACKUP ? "backup " : "",
 s->proxy->id, s->id,
 (check->result & SRV_CHK_DISABLE)?"conditionally 
":"",
-- 
1.8.3.2




[PATCH v6 17/22] MEDIUM: Log agent fail, stopped or down as info

2013-08-22 Thread Simon Horman
In the case where an agent check returns fail, stopped or down,
log this as info when logging the server status along with any
trailing message returned by the agent after fail, stopped or down.

Previously only the trailing message was logged as info and
if omitted no info was logged.

Signed-off-by: Simon Horman 
---
 src/checks.c | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/src/checks.c b/src/checks.c
index a9a93ae..706ed31 100644
--- a/src/checks.c
+++ b/src/checks.c
@@ -867,10 +867,7 @@ static void agent_expect(struct check *check, char *data)
 */
if (end[0] == '\0' || end[0] == ' ' || end[0] == '\t') {
status = HCHK_STATUS_L7STS;
-   /* Skip over leading blanks */
-   while (end[0] != '\0' && (end[0] == ' ' || end[0] == 
'\t'))
-   end++;
-   desc = end;
+   desc = data;
}
}
 
-- 
1.8.3.2




Re: If anyone is interested in testing Simon Hormans patches for the server feedback agent

2013-08-22 Thread Baptiste
Let us know there, so I can test it as soon as released :)

Baptiste

On Thu, Aug 22, 2013 at 9:01 AM, Willy Tarreau  wrote:
> On Thu, Aug 22, 2013 at 03:55:23PM +0900, Simon Horman wrote:
>> On Wed, Aug 21, 2013 at 10:25:58AM +0200, Willy Tarreau wrote:
>> > Hi Malcolm,
>> >
>> > On Thu, Aug 15, 2013 at 06:34:16PM +0100, Malcolm Turnbull wrote:
>> > > I've put up a quick blog entry here:
>> > > http://blog.loadbalancer.org/open-source-windows-service-for-reporting-server-load-back-to-haproxy-load-balancer-feedback-agent/
>> > >
>> > > With links to a source code tar ball for haproxy including Simons 
>> > > patches.
>> > >
>> > > I've also just open sourced (GPL'd) our Windows based service and GUI
>> > > for sending load information back to HAProxy. Links included in the
>> > > post.
>> > >
>> > > Its not fully debuged or tested yet, but its getting very close if
>> > > anyone wants to give it a go.
>> > >
>> > > Any feedback appreciated , thanks.
>> > >
>> > > Ps. We've also got ldirectord patches to work with it if anyone wants 
>> > > those...
>> >
>> > I'd like to find the time to review all of Simon's patches and merge them.
>> > The problem is to find enough contiguous spare time to review all of his
>> > work. I don't want to let this work die outside of mainline, it would be a
>> > total waste, but at the same time I have a hard time assigning time to this
>> > review for the moment :-(
>> >
>> > And BTW, I wanted to publicly thank you (loadbalancer.org) for sponsoring
>> > all this work on the agent code, this significantly improves haproxy's
>> > deployment flexibility, that's really great.
>>
>> Not that it will help the review, but I have a fresh version available
>> which I will post shortly. The only changes are to the top-most patch.
>
> Great, thanks Simon !
>
> Willy
>
>



Re: HAProxy v1.5-dev19 OpenSSL Support Issue

2013-08-22 Thread Simon Horman
On Tue, Aug 13, 2013 at 04:56:57PM +0200, Willy Tarreau wrote:
> On Tue, Aug 13, 2013 at 03:36:09PM +0100, Scott McKeown wrote:
> > Hi Guys,
> > 
> > I've not applied any patches to the download as this was a direct 'wget'
> > from the Git repository.
> > As follows is the OpenSSL v1.0.0 Centos 6.4 x64 build
> > 
> > [root@localhost ~]# wget
> > https://github.com/horms/haproxy/archive/agent-check-20130806.zip
> 
> Hmmm it looks to me that this is not the mainstream code, but Simon's tree.
> Oh BTW that reminds me that I have still not reviewed his patch set, shame
> on me :-(

Although Scott would have been better off using your tree it it does seem
that Scott has uncovered a bug in the patches in my tree, thanks for that.
I will squash the following into "MEDIUM: Split up struct server's check
element" before reposting to resolve this problem.


diff --git a/src/ssl_sock.c b/src/ssl_sock.c
index ce1712d..23bf4a3 100644
--- a/src/ssl_sock.c
+++ b/src/ssl_sock.c
@@ -793,7 +793,7 @@ int ssl_sock_prepare_srv_ctx(struct server *srv, struct 
proxy *curproxy)
if (srv->use_ssl)
srv->xprt = &ssl_sock;
if (srv->check.use_ssl)
-   srv->check.xprt = &ssl_sock;
+   srv->check_common.xprt = &ssl_sock;
 
srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
if (!srv->ssl_ctx.ctx) {



RE: junk at end of syslog packets in 1.5dev19

2013-08-22 Thread Lukas Tribus
Hi Sam!



> It appears that the syslog packets generated by 1.5dev19 do not always
> end in a newline. They appear to end in a newline, followed by two bytes
> of the last syslog buffer.

Is this happen randomly or can you pin point this to specifc requests, maybe
errors/timeouts? How can we reproduce this?

We had a similar report a few days ago, but it doesn't quite match your
description.

Would you take a look at this:
http://www.mail-archive.com/haproxy@formilux.org/msg10851.html

Its a patch, but it hasn't been reviewed yet.



Regards,

Lukas 


Re: If anyone is interested in testing Simon Hormans patches for the server feedback agent

2013-08-22 Thread Willy Tarreau
On Thu, Aug 22, 2013 at 03:55:23PM +0900, Simon Horman wrote:
> On Wed, Aug 21, 2013 at 10:25:58AM +0200, Willy Tarreau wrote:
> > Hi Malcolm,
> > 
> > On Thu, Aug 15, 2013 at 06:34:16PM +0100, Malcolm Turnbull wrote:
> > > I've put up a quick blog entry here:
> > > http://blog.loadbalancer.org/open-source-windows-service-for-reporting-server-load-back-to-haproxy-load-balancer-feedback-agent/
> > > 
> > > With links to a source code tar ball for haproxy including Simons patches.
> > > 
> > > I've also just open sourced (GPL'd) our Windows based service and GUI
> > > for sending load information back to HAProxy. Links included in the
> > > post.
> > > 
> > > Its not fully debuged or tested yet, but its getting very close if
> > > anyone wants to give it a go.
> > > 
> > > Any feedback appreciated , thanks.
> > > 
> > > Ps. We've also got ldirectord patches to work with it if anyone wants 
> > > those...
> > 
> > I'd like to find the time to review all of Simon's patches and merge them.
> > The problem is to find enough contiguous spare time to review all of his
> > work. I don't want to let this work die outside of mainline, it would be a
> > total waste, but at the same time I have a hard time assigning time to this
> > review for the moment :-(
> > 
> > And BTW, I wanted to publicly thank you (loadbalancer.org) for sponsoring
> > all this work on the agent code, this significantly improves haproxy's
> > deployment flexibility, that's really great.
> 
> Not that it will help the review, but I have a fresh version available
> which I will post shortly. The only changes are to the top-most patch.

Great, thanks Simon !

Willy