BUG/MEDIUM: dns/server: fix incomatibility between SRV resolution and server state file
Server state file has no indication that a server is currently managed by a DNS SRV resolution. And thus, both feature (DNS SRV resolution and server state), when used together, does not provide the expected behavior: a smooth experience... This patch introduce the "SRV record name" in the server state file and loads and applies it if found and wherever required. This patch applies to haproxy-dev branch only. For backport, a specific patch is provided for 1.8.
This commit is contained in:
parent
233afc70ba
commit
6d0f38f00d
|
@ -2130,6 +2130,7 @@ show servers state [<backend>]
|
|||
configuration.
|
||||
srv_fqdn: Server FQDN.
|
||||
srv_port: Server port.
|
||||
srvrecord: DNS SRV record associated to this SRV.
|
||||
|
||||
show sess
|
||||
Dump all known sessions. Avoid doing this on slow connections as this can
|
||||
|
|
|
@ -126,10 +126,11 @@ enum srv_initaddr {
|
|||
"bk_f_forced_id " \
|
||||
"srv_f_forced_id " \
|
||||
"srv_fqdn " \
|
||||
"srv_port"
|
||||
"srv_port " \
|
||||
"srvrecord"
|
||||
|
||||
#define SRV_STATE_FILE_MAX_FIELDS 19
|
||||
#define SRV_STATE_FILE_NB_FIELDS_VERSION_1 18
|
||||
#define SRV_STATE_FILE_MAX_FIELDS 20
|
||||
#define SRV_STATE_FILE_NB_FIELDS_VERSION_1 19
|
||||
#define SRV_STATE_LINE_MAXLEN 512
|
||||
|
||||
/* server flags -- 32 bits */
|
||||
|
|
10
src/proxy.c
10
src/proxy.c
|
@ -1429,6 +1429,7 @@ static int dump_servers_state(struct stream_interface *si, struct buffer *buf)
|
|||
char srv_addr[INET6_ADDRSTRLEN + 1];
|
||||
time_t srv_time_since_last_change;
|
||||
int bk_f_forced_id, srv_f_forced_id;
|
||||
char *srvrecord;
|
||||
|
||||
/* we don't want to report any state if the backend is not enabled on this process */
|
||||
if (px->bind_proc && !(px->bind_proc & pid_bit))
|
||||
|
@ -1458,18 +1459,23 @@ static int dump_servers_state(struct stream_interface *si, struct buffer *buf)
|
|||
bk_f_forced_id = px->options & PR_O_FORCED_ID ? 1 : 0;
|
||||
srv_f_forced_id = srv->flags & SRV_F_FORCED_ID ? 1 : 0;
|
||||
|
||||
srvrecord = NULL;
|
||||
if (srv->srvrq && srv->srvrq->name)
|
||||
srvrecord = srv->srvrq->name;
|
||||
|
||||
chunk_appendf(buf,
|
||||
"%d %s "
|
||||
"%d %s %s "
|
||||
"%d %d %d %d %ld "
|
||||
"%d %d %d %d %d "
|
||||
"%d %d %s %u"
|
||||
"%d %d %s %u %s"
|
||||
"\n",
|
||||
px->uuid, px->id,
|
||||
srv->puid, srv->id, srv_addr,
|
||||
srv->cur_state, srv->cur_admin, srv->uweight, srv->iweight, (long int)srv_time_since_last_change,
|
||||
srv->check.status, srv->check.result, srv->check.health, srv->check.state, srv->agent.state,
|
||||
bk_f_forced_id, srv_f_forced_id, srv->hostname ? srv->hostname : "-", srv->svc_port);
|
||||
bk_f_forced_id, srv_f_forced_id, srv->hostname ? srv->hostname : "-", srv->svc_port,
|
||||
srvrecord ? srvrecord : "-");
|
||||
if (ci_putchk(si_ic(si), &trash) == -1) {
|
||||
si_applet_cant_put(si);
|
||||
return 0;
|
||||
|
|
52
src/server.c
52
src/server.c
|
@ -2758,6 +2758,7 @@ static void srv_update_state(struct server *srv, int version, char **params)
|
|||
const char *fqdn;
|
||||
const char *port_str;
|
||||
unsigned int port;
|
||||
char *srvrecord;
|
||||
|
||||
fqdn = NULL;
|
||||
port = 0;
|
||||
|
@ -2781,6 +2782,7 @@ static void srv_update_state(struct server *srv, int version, char **params)
|
|||
* srv_f_forced_id: params[12]
|
||||
* srv_fqdn: params[13]
|
||||
* srv_port: params[14]
|
||||
* srvrecord: params[15]
|
||||
*/
|
||||
|
||||
/* validating srv_op_state */
|
||||
|
@ -2913,6 +2915,13 @@ static void srv_update_state(struct server *srv, int version, char **params)
|
|||
}
|
||||
}
|
||||
|
||||
/* SRV record
|
||||
* NOTE: in HAProxy, SRV records must start with an underscore '_'
|
||||
*/
|
||||
srvrecord = params[15];
|
||||
if (srvrecord && *srvrecord != '_')
|
||||
srvrecord = NULL;
|
||||
|
||||
/* don't apply anything if one error has been detected */
|
||||
if (msg->data)
|
||||
goto out;
|
||||
|
@ -3045,6 +3054,48 @@ static void srv_update_state(struct server *srv, int version, char **params)
|
|||
}
|
||||
}
|
||||
}
|
||||
/* If all the conditions below are validated, this means
|
||||
* we're evaluating a server managed by SRV resolution
|
||||
*/
|
||||
else if (fqdn && !srv->hostname && srvrecord) {
|
||||
int res;
|
||||
|
||||
/* we can't apply previous state if SRV record has changed */
|
||||
if (srv->srvrq && strcmp(srv->srvrq->name, srvrecord) != 0) {
|
||||
chunk_appendf(msg, ", SRV record mismatch between configuration ('%s') and state file ('%s) for server '%s'. Previous state not applied", srv->srvrq->name, srvrecord, srv->id);
|
||||
HA_SPIN_UNLOCK(SERVER_LOCK, &srv->lock);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* create or find a SRV resolution for this srv record */
|
||||
if (srv->srvrq == NULL && (srv->srvrq = find_srvrq_by_name(srvrecord, srv->proxy)) == NULL)
|
||||
srv->srvrq = new_dns_srvrq(srv, srvrecord);
|
||||
if (srv->srvrq == NULL) {
|
||||
chunk_appendf(msg, ", can't create or find SRV resolution '%s' for server '%s'", srvrecord, srv->id);
|
||||
HA_SPIN_UNLOCK(SERVER_LOCK, &srv->lock);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* prepare DNS resolution for this server */
|
||||
res = srv_prepare_for_resolution(srv, fqdn);
|
||||
if (res == -1) {
|
||||
chunk_appendf(msg, ", can't allocate memory for DNS resolution for server '%s'", srv->id);
|
||||
HA_SPIN_UNLOCK(SERVER_LOCK, &srv->lock);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* configure check.port accordingly */
|
||||
if ((srv->check.state & CHK_ST_CONFIGURED) &&
|
||||
!(srv->flags & SRV_F_CHECKPORT))
|
||||
srv->check.port = port;
|
||||
|
||||
/* Unset SRV_F_MAPPORTS for SRV records.
|
||||
* SRV_F_MAPPORTS is unfortunately set by parse_server()
|
||||
* because no ports are provided in the configuration file.
|
||||
* This is because HAProxy will use the port found into the SRV record.
|
||||
*/
|
||||
srv->flags &= ~SRV_F_MAPPORTS;
|
||||
}
|
||||
|
||||
if (port_str)
|
||||
srv->svc_port = port;
|
||||
|
@ -3301,6 +3352,7 @@ void apply_server_state(void)
|
|||
* srv_f_forced_id: params[16] => srv_params[12]
|
||||
* srv_fqdn: params[17] => srv_params[13]
|
||||
* srv_port: params[18] => srv_params[14]
|
||||
* srvrecord: params[19] => srv_params[15]
|
||||
*/
|
||||
if (arg >= 4) {
|
||||
srv_params[srv_arg] = cur;
|
||||
|
|
Loading…
Reference in New Issue