Skip to content

Commit c8b16fc

Browse files
ole2plwtarreau
authored andcommitted
[MEDIUM] Implement "track [<backend>/]<server>"
This patch implements ability to set the current state of one server by tracking another one. It: - adds two variables: *tracknext, *tracked to struct server - implements findserver(), similar to findproxy() - adds "track" keyword accepting both "proxy/server" and "server" (assuming current proxy) - verifies if both checks and tracking is not enabled at the same time - changes set_server_down() to notify tracking server - creates set_server_up(), set_server_disabled(), set_server_enabled() by moving the code from process_chk() and adding notifications - changes stats to show a name of tracked server instead of Chk/Dwn/Dwntime(html) or by adding new variable (csv) Changes from the previuos version: - it is possibile to track independently of the declaration order - one extra comma bug is fixed - new condition to check if there is no disable-on-404 inconsistency
1 parent f14358b commit c8b16fc

File tree

8 files changed

+332
-114
lines changed

8 files changed

+332
-114
lines changed

TODO

-3
Original file line numberDiff line numberDiff line change
@@ -174,9 +174,6 @@ TODO for 1.3
174174
filters and backend, on which every entity could rely.
175175
- implement 'on uri <uri> <proxy>', 'on host <host> <proxy>'
176176
- remove the first now useless hop in hdr_idx
177-
- implement "track XXX.YYY" for each server as an alternative to
178-
health checks. This will automatically set the server state to
179-
the same as server YYY of proxy XXX.
180177
- balance on URI hash (specify length or depth)
181178
- balance on any header hash (eg: host)
182179
- balance with redirections to real servers

doc/configuration.txt

+7
Original file line numberDiff line numberDiff line change
@@ -3893,6 +3893,13 @@ source <addr>[:<port>] [usesrc { <addr2>[:<port2>] | client | clientip } ]
38933893
as the backend "source" keyword, except that it only applies to the server
38943894
referencing it. Please consult the "source" keyword for details.
38953895

3896+
track [<proxy>/]<server>
3897+
This option enables ability to set the current state of the server by
3898+
tracking another one. Only a server with checks enabled can be tracked
3899+
so it is not possible for example to track a server that tracks another
3900+
one. If <proxy> is omitted the current one is used. If disable-on-404 is
3901+
used, it has to be enabled on both proxies.
3902+
38963903
weight <weight>
38973904
The "weight" parameter is used to adjust the server's weight relative to
38983905
other servers. All servers will receive a load proportional to their weight

include/proto/proxy.h

+1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ void listen_proxies(void);
3636
const char *proxy_cap_str(int cap);
3737
const char *proxy_mode_str(int mode);
3838
struct proxy *findproxy(const char *name, int mode, int cap);
39+
struct server *findserver(const struct proxy *px, const char *name);
3940
int proxy_parse_timeout(const char **args, struct proxy *proxy,
4041
struct proxy *defpx, char *err, int errlen);
4142

include/types/server.h

+2
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,8 @@ struct server {
9191
struct sockaddr_in tproxy_addr; /* non-local address we want to bind to for connect() */
9292
#endif
9393

94+
struct server *tracknext, *tracked; /* next server in a tracking list, tracked server */
95+
char *trackit; /* temporary variable to make assignment deferrable */
9496
struct sockaddr_in check_addr; /* the address to check, if different from <addr> */
9597
short check_port; /* the port to use for the health checks */
9698
int health; /* 0->rise-1 = bad; rise->rise+fall-1 = good */

src/cfgparse.c

+79-1
Original file line numberDiff line numberDiff line change
@@ -1625,6 +1625,18 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int inv)
16251625
newsrv->slowstart = (val + 999) / 1000;
16261626
cur_arg += 2;
16271627
}
1628+
else if (!strcmp(args[cur_arg], "track")) {
1629+
1630+
if (!*args[cur_arg + 1]) {
1631+
Alert("parsing [%s:%d]: 'track' expects [<proxy>/]<server> as argument.\n",
1632+
file, linenum);
1633+
return -1;
1634+
}
1635+
1636+
newsrv->trackit = strdup(args[cur_arg + 1]);
1637+
1638+
cur_arg += 2;
1639+
}
16281640
else if (!strcmp(args[cur_arg], "check")) {
16291641
global.maxsock++;
16301642
do_check = 1;
@@ -1684,13 +1696,19 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int inv)
16841696
return -1;
16851697
}
16861698
else {
1687-
Alert("parsing [%s:%d] : server %s only supports options 'backup', 'cookie', 'redir', 'check', 'inter', 'fastinter', 'downinter', 'rise', 'fall', 'addr', 'port', 'source', 'minconn', 'maxconn', 'maxqueue', 'slowstart' and 'weight'.\n",
1699+
Alert("parsing [%s:%d] : server %s only supports options 'backup', 'cookie', 'redir', 'check', 'track', 'inter', 'fastinter', 'downinter', 'rise', 'fall', 'addr', 'port', 'source', 'minconn', 'maxconn', 'maxqueue', 'slowstart' and 'weight'.\n",
16881700
file, linenum, newsrv->id);
16891701
return -1;
16901702
}
16911703
}
16921704

16931705
if (do_check) {
1706+
if (newsrv->trackit) {
1707+
Alert("parsing [%s:%d]: unable to enable checks and tracking at the same time!\n",
1708+
file, linenum);
1709+
return -1;
1710+
}
1711+
16941712
if (!newsrv->check_port && newsrv->check_addr.sin_port)
16951713
newsrv->check_port = newsrv->check_addr.sin_port;
16961714

@@ -2913,6 +2931,7 @@ int readcfgfile(const char *file)
29132931
/*
29142932
* If this server supports a maxconn parameter, it needs a dedicated
29152933
* tasks to fill the emptied slots when a connection leaves.
2934+
* Also, resolve deferred tracking dependency if needed.
29162935
*/
29172936
newsrv = curproxy->srv;
29182937
while (newsrv != NULL) {
@@ -2950,6 +2969,65 @@ int readcfgfile(const char *file)
29502969
tv_eternity(&t->expire);
29512970
task_queue(t);
29522971
}
2972+
2973+
if (newsrv->trackit) {
2974+
struct proxy *px;
2975+
struct server *srv;
2976+
char *pname, *sname;
2977+
2978+
pname = newsrv->trackit;
2979+
sname = strrchr(pname, '/');
2980+
2981+
if (sname)
2982+
*sname++ = '\0';
2983+
else {
2984+
sname = pname;
2985+
pname = NULL;
2986+
}
2987+
2988+
if (pname) {
2989+
px = findproxy(pname, curproxy->mode, PR_CAP_BE);
2990+
if (!px) {
2991+
Alert("parsing %s, %s '%s', server '%s': unable to find required proxy '%s' for tracking.\n",
2992+
file, proxy_type_str(curproxy), curproxy->id,
2993+
newsrv->id, pname);
2994+
return -1;
2995+
}
2996+
} else
2997+
px = curproxy;
2998+
2999+
srv = findserver(px, sname);
3000+
if (!srv) {
3001+
Alert("parsing %s, %s '%s', server '%s': unable to find required server '%s' for tracking.\n",
3002+
file, proxy_type_str(curproxy), curproxy->id,
3003+
newsrv->id, sname);
3004+
return -1;
3005+
}
3006+
3007+
if (!(srv->state & SRV_CHECKED)) {
3008+
Alert("parsing %s, %s '%s', server '%s': unable to use %s/%s for "
3009+
"tracing as it does not have checks enabled.\n",
3010+
file, proxy_type_str(curproxy), curproxy->id,
3011+
newsrv->id, px->id, srv->id);
3012+
return -1;
3013+
}
3014+
3015+
if (curproxy != px &&
3016+
(curproxy->options & PR_O_DISABLE404) != (px->options & PR_O_DISABLE404)) {
3017+
Alert("parsing %s, %s '%s', server '%s': unable to use %s/%s for"
3018+
"tracing: disable-on-404 option inconsistency.\n",
3019+
file, proxy_type_str(curproxy), curproxy->id,
3020+
newsrv->id, px->id, srv->id);
3021+
return -1;
3022+
}
3023+
3024+
newsrv->tracked = srv;
3025+
newsrv->tracknext = srv->tracknext;
3026+
srv->tracknext = newsrv;
3027+
3028+
free(newsrv->trackit);
3029+
}
3030+
29533031
newsrv = newsrv->next;
29543032
}
29553033

0 commit comments

Comments
 (0)