diff --git a/doc/management.txt b/doc/management.txt index 7abfc85fb..4b01ddcb4 100644 --- a/doc/management.txt +++ b/doc/management.txt @@ -1470,6 +1470,11 @@ add server / [args]* init-addr method. This means that no resolution will be undertaken if a FQDN is specified as an address, even if the server creation will be validated. + A dynamic server may use the "track" keyword to follow the check status of + another server from the configuration. However, it is not possible to track + another dynamic server. This is to ensure that the tracking chain is kept + consistent even in the case of dynamic servers deletion. + Here is the list of the currently supported keywords : - allow-0rtt @@ -1507,6 +1512,7 @@ add server / [args]* - ssl-min-ver - tfo - tls-tickets + - track - usesrc - verify - verifyhost diff --git a/src/server.c b/src/server.c index 664e2f4ec..5fa394666 100644 --- a/src/server.c +++ b/src/server.c @@ -1678,7 +1678,7 @@ static struct srv_kw_list srv_kws = { "ALL", { }, { { "source", srv_parse_source, -1, 1, 1 }, /* Set the source address to be used to connect to the server */ { "stick", srv_parse_stick, 0, 1, 0 }, /* Enable stick-table persistence */ { "tfo", srv_parse_tfo, 0, 1, 1 }, /* enable TCP Fast Open of server */ - { "track", srv_parse_track, 1, 1, 0 }, /* Set the current state of the server, tracking another one */ + { "track", srv_parse_track, 1, 1, 1 }, /* Set the current state of the server, tracking another one */ { "socks4", srv_parse_socks4, 1, 1, 0 }, /* Set the socks4 proxy of the server*/ { "usesrc", srv_parse_usesrc, 0, 1, 1 }, /* safe-guard against usesrc without preceding keyword */ { "weight", srv_parse_weight, 1, 1, 1 }, /* Set the load-balancing weight */ @@ -2228,6 +2228,31 @@ void free_server(struct server *srv) srv = NULL; } +/* Remove a server from a tracking list if is tracking another + * server. No special care is taken if is tracked itself by another one : + * this situation should be avoided by the caller. + * + * Not thread-safe. + */ +static void release_server_track(struct server *srv) +{ + struct server *strack = srv->track; + struct server **base; + + if (!strack) + return; + + for (base = &strack->trackers; *base; base = &((*base)->tracknext)) { + if (*base == srv) { + *base = srv->tracknext; + return; + } + } + + /* srv not found on the tracking list, this should never happen */ + BUG_ON(!*base); +} + /* * Parse as much as possible such a range string argument: low[-high] * Set and values so that they may be reused by this loop @@ -4503,6 +4528,11 @@ static int cli_parse_add_server(char **args, char *payload, struct appctx *appct } } + if (srv->trackit) { + if (srv_apply_track(srv, be)) + goto out; + } + /* Attach the server to the end of the proxy linked list. Note that this * operation is not thread-safe so this is executed under thread * isolation. @@ -4564,8 +4594,11 @@ out: if (!usermsgs_empty()) cli_err(appctx, usermsgs_str()); - if (srv) + if (srv) { + release_server_track(srv); free_server(srv); + } + return 1; } @@ -4650,6 +4683,10 @@ static int cli_parse_delete_server(char **args, char *payload, struct appctx *ap goto out; } + /* remove srv from tracking list */ + if (srv->track) + release_server_track(srv); + /* TODO remove server for check list once 'check' will be implemented for * dynamic servers */