MEDIUM: Split up struct server's check element

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 <horms@verge.net.au>
This commit is contained in:
Simon Horman 2013-02-23 10:16:43 +09:00 committed by Willy Tarreau
parent c69d547638
commit 6618300e13
5 changed files with 52 additions and 44 deletions

View File

@ -103,6 +103,22 @@ struct tree_occ {
struct eb32_node node; 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 */
int inter, fastinter, downinter; /* checks: time in milliseconds */
struct server *server; /* back-pointer to server */
};
struct server { struct server {
enum obj_type obj_type; /* object type == OBJ_TYPE_SERVER */ enum obj_type obj_type; /* object type == OBJ_TYPE_SERVER */
struct server *next; struct server *next;
@ -137,7 +153,6 @@ struct server {
short observe, onerror; /* observing mode: one of HANA_OBS_*; what to do on error: on of ANA_ONERR_* */ 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 onmarkeddown; /* what to do when marked down: one of HANA_ONMARKEDDOWN_* */
short onmarkedup; /* what to do when marked up: one of HANA_ONMARKEDUP_* */ 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 slowstart; /* slowstart time in seconds (ms in the conf) */
int result; /* health-check result : SRV_CHK_* */ int result; /* health-check result : SRV_CHK_* */
@ -163,21 +178,13 @@ struct server {
int puid; /* proxy-unique server ID, used for SNMP, and "first" LB algo */ int puid; /* proxy-unique server ID, used for SNMP, and "first" LB algo */
struct { /* health-check specific configuration */ struct { /* configuration used by health-check and agent-check */
struct connection *conn; /* connection state for health checks */
struct protocol *proto; /* server address protocol for health checks */ struct protocol *proto; /* server address protocol for health checks */
struct xprt_ops *xprt; /* transport layer operations for health checks */ struct xprt_ops *xprt; /* transport layer operations for health checks */
struct sockaddr_storage addr; /* the address to check, if different from <addr> */ struct sockaddr_storage addr; /* the address to check, if different from <addr> */
short port; /* the port to use for the health checks */ } check_common;
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 check check; /* health-check specific configuration */
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;
#ifdef USE_OPENSSL #ifdef USE_OPENSSL
int use_ssl; /* ssl enabled */ int use_ssl; /* ssl enabled */

View File

@ -1322,9 +1322,9 @@ void init_default_instance()
defproxy.maxconn = cfg_maxpconn; defproxy.maxconn = cfg_maxpconn;
defproxy.conn_retries = CONN_RETRIES; defproxy.conn_retries = CONN_RETRIES;
defproxy.defsrv.inter = DEF_CHKINTR; defproxy.defsrv.check.inter = DEF_CHKINTR;
defproxy.defsrv.fastinter = 0; defproxy.defsrv.check.fastinter = 0;
defproxy.defsrv.downinter = 0; defproxy.defsrv.check.downinter = 0;
defproxy.defsrv.rise = DEF_RISETIME; defproxy.defsrv.rise = DEF_RISETIME;
defproxy.defsrv.fall = DEF_FALLTIME; defproxy.defsrv.fall = DEF_FALLTIME;
defproxy.defsrv.check.port = 0; defproxy.defsrv.check.port = 0;
@ -4241,8 +4241,8 @@ stats_error_parsing:
} }
newsrv->addr = *sk; newsrv->addr = *sk;
newsrv->proto = newsrv->check.proto = protocol_by_family(newsrv->addr.ss_family); newsrv->proto = newsrv->check_common.proto = protocol_by_family(newsrv->addr.ss_family);
newsrv->xprt = newsrv->check.xprt = &raw_sock; newsrv->xprt = newsrv->check_common.xprt = &raw_sock;
if (!newsrv->proto) { if (!newsrv->proto) {
Alert("parsing [%s:%d] : Unknown protocol family %d '%s'\n", Alert("parsing [%s:%d] : Unknown protocol family %d '%s'\n",
@ -4251,11 +4251,11 @@ stats_error_parsing:
goto out; goto out;
} }
newsrv->check.use_ssl = curproxy->defsrv.check.use_ssl; newsrv->check.use_ssl = curproxy->defsrv.check.use_ssl;
newsrv->check.port = curproxy->defsrv.check.port; newsrv->check.port = curproxy->defsrv.check.port;
newsrv->inter = curproxy->defsrv.inter; newsrv->check.inter = curproxy->defsrv.check.inter;
newsrv->fastinter = curproxy->defsrv.fastinter; newsrv->check.fastinter = curproxy->defsrv.check.fastinter;
newsrv->downinter = curproxy->defsrv.downinter; newsrv->check.downinter = curproxy->defsrv.check.downinter;
newsrv->rise = curproxy->defsrv.rise; newsrv->rise = curproxy->defsrv.rise;
newsrv->fall = curproxy->defsrv.fall; newsrv->fall = curproxy->defsrv.fall;
newsrv->maxqueue = curproxy->defsrv.maxqueue; newsrv->maxqueue = curproxy->defsrv.maxqueue;
@ -4343,7 +4343,7 @@ stats_error_parsing:
err_code |= ERR_ALERT | ERR_FATAL; err_code |= ERR_ALERT | ERR_FATAL;
goto out; goto out;
} }
newsrv->inter = val; newsrv->check.inter = val;
cur_arg += 2; cur_arg += 2;
} }
else if (!strcmp(args[cur_arg], "fastinter")) { else if (!strcmp(args[cur_arg], "fastinter")) {
@ -4360,7 +4360,7 @@ stats_error_parsing:
err_code |= ERR_ALERT | ERR_FATAL; err_code |= ERR_ALERT | ERR_FATAL;
goto out; goto out;
} }
newsrv->fastinter = val; newsrv->check.fastinter = val;
cur_arg += 2; cur_arg += 2;
} }
else if (!strcmp(args[cur_arg], "downinter")) { else if (!strcmp(args[cur_arg], "downinter")) {
@ -4377,7 +4377,7 @@ stats_error_parsing:
err_code |= ERR_ALERT | ERR_FATAL; err_code |= ERR_ALERT | ERR_FATAL;
goto out; goto out;
} }
newsrv->downinter = val; newsrv->check.downinter = val;
cur_arg += 2; cur_arg += 2;
} }
else if (!defsrv && !strcmp(args[cur_arg], "addr")) { else if (!defsrv && !strcmp(args[cur_arg], "addr")) {
@ -4408,7 +4408,7 @@ stats_error_parsing:
goto out; goto out;
} }
newsrv->check.addr = *sk; newsrv->check_common.addr = *sk;
cur_arg += 2; cur_arg += 2;
} }
else if (!strcmp(args[cur_arg], "port")) { else if (!strcmp(args[cur_arg], "port")) {
@ -4844,15 +4844,15 @@ stats_error_parsing:
* same as for the production traffic. Otherwise we use raw_sock by * same as for the production traffic. Otherwise we use raw_sock by
* default, unless one is specified. * default, unless one is specified.
*/ */
if (!newsrv->check.port && !is_addr(&newsrv->check.addr)) { if (!newsrv->check.port && !is_addr(&newsrv->check_common.addr)) {
#ifdef USE_OPENSSL #ifdef USE_OPENSSL
newsrv->check.use_ssl |= newsrv->use_ssl; newsrv->check.use_ssl |= newsrv->use_ssl;
#endif #endif
newsrv->check.send_proxy |= (newsrv->state & SRV_SEND_PROXY); newsrv->check.send_proxy |= (newsrv->state & SRV_SEND_PROXY);
} }
/* try to get the port from check.addr if check.port not set */ /* try to get the port from check_core.addr if check.port not set */
if (!newsrv->check.port) if (!newsrv->check.port)
newsrv->check.port = get_host_port(&newsrv->check.addr); newsrv->check.port = get_host_port(&newsrv->check_common.addr);
if (!newsrv->check.port) if (!newsrv->check.port)
newsrv->check.port = realport; /* by default */ newsrv->check.port = realport; /* by default */
@ -4902,6 +4902,7 @@ stats_error_parsing:
newsrv->check.conn->t.sock.fd = -1; /* no check in progress yet */ newsrv->check.conn->t.sock.fd = -1; /* no check in progress yet */
newsrv->check.status = HCHK_STATUS_INI; newsrv->check.status = HCHK_STATUS_INI;
newsrv->check.server = newsrv;
newsrv->state |= SRV_CHECKED; newsrv->state |= SRV_CHECKED;
} }

View File

@ -691,8 +691,8 @@ void health_adjust(struct server *s, short status)
s->consecutive_errors = 0; s->consecutive_errors = 0;
s->counters.failed_hana++; s->counters.failed_hana++;
if (s->fastinter) { if (s->check.fastinter) {
expire = tick_add(now_ms, MS_TO_TICKS(s->fastinter)); expire = tick_add(now_ms, MS_TO_TICKS(s->check.fastinter));
if (s->check.task->expire > expire) { if (s->check.task->expire > expire) {
s->check.task->expire = expire; s->check.task->expire = expire;
/* requeue check task with new expire */ /* requeue check task with new expire */
@ -1354,14 +1354,14 @@ static struct task *process_chk(struct task *t)
conn->flags = CO_FL_NONE; conn->flags = CO_FL_NONE;
conn->err_code = CO_ER_NONE; conn->err_code = CO_ER_NONE;
conn->target = &s->obj_type; conn->target = &s->obj_type;
conn_prepare(conn, &check_conn_cb, s->check.proto, s->check.xprt, s); conn_prepare(conn, &check_conn_cb, s->check_common.proto, s->check_common.xprt, s);
/* no client address */ /* no client address */
clear_addr(&conn->addr.from); clear_addr(&conn->addr.from);
if (is_addr(&s->check.addr)) if (is_addr(&s->check_common.addr))
/* we'll connect to the check addr specified on the server */ /* we'll connect to the check addr specified on the server */
conn->addr.to = s->check.addr; conn->addr.to = s->check_common.addr;
else else
/* we'll connect to the addr on the server */ /* we'll connect to the addr on the server */
conn->addr.to = s->addr; conn->addr.to = s->addr;
@ -1380,9 +1380,9 @@ static struct task *process_chk(struct task *t)
* connect() when a pure TCP check is used (without PROXY protocol). * connect() when a pure TCP check is used (without PROXY protocol).
*/ */
ret = SN_ERR_INTERNAL; ret = SN_ERR_INTERNAL;
if (s->check.proto->connect) if (s->check_common.proto->connect)
ret = s->check.proto->connect(conn, s->proxy->options2 & PR_O2_CHK_ANY, ret = s->check_common.proto->connect(conn, s->proxy->options2 & PR_O2_CHK_ANY,
s->check.send_proxy ? 1 : (s->proxy->options2 & PR_O2_CHK_ANY) ? 0 : 2); s->check.send_proxy ? 1 : (s->proxy->options2 & PR_O2_CHK_ANY) ? 0 : 2);
conn->flags |= CO_FL_WAKE_DATA; conn->flags |= CO_FL_WAKE_DATA;
if (s->check.send_proxy) if (s->check.send_proxy)
conn->flags |= CO_FL_LOCAL_SPROXY; conn->flags |= CO_FL_LOCAL_SPROXY;
@ -1393,7 +1393,7 @@ static struct task *process_chk(struct task *t)
* to establish but only when timeout.check is set * to establish but only when timeout.check is set
* as it may be to short for a full check otherwise * as it may be to short for a full check otherwise
*/ */
t->expire = tick_add(now_ms, MS_TO_TICKS(s->inter)); t->expire = tick_add(now_ms, MS_TO_TICKS(s->check.inter));
if (s->proxy->timeout.check && s->proxy->timeout.connect) { if (s->proxy->timeout.check && s->proxy->timeout.connect) {
int t_con = tick_add(now_ms, s->proxy->timeout.connect); int t_con = tick_add(now_ms, s->proxy->timeout.connect);
@ -1431,7 +1431,7 @@ static struct task *process_chk(struct task *t)
int t_con; int t_con;
t_con = tick_add(t->expire, s->proxy->timeout.connect); t_con = tick_add(t->expire, s->proxy->timeout.connect);
t->expire = tick_add(t->expire, MS_TO_TICKS(s->inter)); t->expire = tick_add(t->expire, MS_TO_TICKS(s->check.inter));
if (s->proxy->timeout.check) if (s->proxy->timeout.check)
t->expire = tick_first(t->expire, t_con); t->expire = tick_first(t->expire, t_con);
@ -1524,7 +1524,7 @@ static struct task *process_chk(struct task *t)
reschedule: reschedule:
while (tick_is_expired(t->expire, now_ms)) while (tick_is_expired(t->expire, now_ms))
t->expire = tick_add(t->expire, MS_TO_TICKS(s->inter)); t->expire = tick_add(t->expire, MS_TO_TICKS(s->check.inter));
out_wait: out_wait:
return t; return t;
} }

View File

@ -33,12 +33,12 @@ int srv_downtime(const struct server *s)
int srv_getinter(const struct server *s) int srv_getinter(const struct server *s)
{ {
if ((s->state & SRV_CHECKED) && (s->health == s->rise + s->fall - 1)) if ((s->state & SRV_CHECKED) && (s->health == s->rise + s->fall - 1))
return s->inter; return s->check.inter;
if (!(s->state & SRV_RUNNING) && s->health==0) if (!(s->state & SRV_RUNNING) && s->health==0)
return (s->downinter)?(s->downinter):(s->inter); return (s->check.downinter)?(s->check.downinter):(s->check.inter);
return (s->fastinter)?(s->fastinter):(s->inter); return (s->check.fastinter)?(s->check.fastinter):(s->check.inter);
} }
/* /*

View File

@ -916,7 +916,7 @@ int ssl_sock_prepare_srv_ctx(struct server *srv, struct proxy *curproxy)
if (srv->use_ssl) if (srv->use_ssl)
srv->xprt = &ssl_sock; srv->xprt = &ssl_sock;
if (srv->check.use_ssl) 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()); srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
if (!srv->ssl_ctx.ctx) { if (!srv->ssl_ctx.ctx) {