BUG/MEDIUM: checks: Avoid having an associated server for email checks.
When using a check to send email, avoid having an associated server, so that we don't modify the server state if we fail to send an email. Also revert back to initialize the check status to HCHK_STATUS_INI, now that set_server_check_status() stops early if there's no server, we shouldn't get in a mail loop anymore. This should be backported to 1.9.
This commit is contained in:
parent
c98aa1f182
commit
0923fa4200
32
src/checks.c
32
src/checks.c
@ -236,6 +236,11 @@ static void set_server_check_status(struct check *check, short status, const cha
|
|||||||
if (check->result == CHK_RES_NEUTRAL)
|
if (check->result == CHK_RES_NEUTRAL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/* If the check was really just sending a mail, it won't have an
|
||||||
|
* associated server, so we're done now.
|
||||||
|
*/
|
||||||
|
if (!s)
|
||||||
|
return;
|
||||||
report = 0;
|
report = 0;
|
||||||
|
|
||||||
switch (check->result) {
|
switch (check->result) {
|
||||||
@ -681,6 +686,7 @@ static void chk_report_conn_err(struct check *check, int errno_bck, int expired)
|
|||||||
* might be due to a server IP change.
|
* might be due to a server IP change.
|
||||||
* Let's trigger a DNS resolution if none are currently running.
|
* Let's trigger a DNS resolution if none are currently running.
|
||||||
*/
|
*/
|
||||||
|
if (check->server)
|
||||||
dns_trigger_resolution(check->server->dns_requester);
|
dns_trigger_resolution(check->server->dns_requester);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -711,13 +717,20 @@ static struct task *event_srv_chk_io(struct task *t, void *ctx, unsigned short s
|
|||||||
{
|
{
|
||||||
struct check *check = ctx;
|
struct check *check = ctx;
|
||||||
struct conn_stream *cs = check->cs;
|
struct conn_stream *cs = check->cs;
|
||||||
|
struct email_alertq *q = container_of(check, typeof(*q), check);
|
||||||
|
|
||||||
if (!(check->wait_list.events & SUB_RETRY_SEND))
|
if (!(check->wait_list.events & SUB_RETRY_SEND))
|
||||||
wake_srv_chk(cs);
|
wake_srv_chk(cs);
|
||||||
if (!(check->wait_list.events & SUB_RETRY_RECV)) {
|
if (!(check->wait_list.events & SUB_RETRY_RECV)) {
|
||||||
|
if (check->server)
|
||||||
HA_SPIN_LOCK(SERVER_LOCK, &check->server->lock);
|
HA_SPIN_LOCK(SERVER_LOCK, &check->server->lock);
|
||||||
|
else
|
||||||
|
HA_SPIN_LOCK(EMAIL_ALERTS_LOCK, &q->lock);
|
||||||
__event_srv_chk_r(cs);
|
__event_srv_chk_r(cs);
|
||||||
|
if (check->server)
|
||||||
HA_SPIN_UNLOCK(SERVER_LOCK, &check->server->lock);
|
HA_SPIN_UNLOCK(SERVER_LOCK, &check->server->lock);
|
||||||
|
else
|
||||||
|
HA_SPIN_UNLOCK(EMAIL_ALERTS_LOCK, &q->lock);
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -1394,9 +1407,13 @@ static int wake_srv_chk(struct conn_stream *cs)
|
|||||||
{
|
{
|
||||||
struct connection *conn = cs->conn;
|
struct connection *conn = cs->conn;
|
||||||
struct check *check = cs->data;
|
struct check *check = cs->data;
|
||||||
|
struct email_alertq *q = container_of(check, typeof(*q), check);
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
|
if (check->server)
|
||||||
HA_SPIN_LOCK(SERVER_LOCK, &check->server->lock);
|
HA_SPIN_LOCK(SERVER_LOCK, &check->server->lock);
|
||||||
|
else
|
||||||
|
HA_SPIN_LOCK(EMAIL_ALERTS_LOCK, &q->lock);
|
||||||
|
|
||||||
/* we may have to make progress on the TCP checks */
|
/* we may have to make progress on the TCP checks */
|
||||||
if (check->type == PR_O2_TCPCHK_CHK) {
|
if (check->type == PR_O2_TCPCHK_CHK) {
|
||||||
@ -1433,7 +1450,10 @@ static int wake_srv_chk(struct conn_stream *cs)
|
|||||||
ret = -1;
|
ret = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (check->server)
|
||||||
HA_SPIN_UNLOCK(SERVER_LOCK, &check->server->lock);
|
HA_SPIN_UNLOCK(SERVER_LOCK, &check->server->lock);
|
||||||
|
else
|
||||||
|
HA_SPIN_UNLOCK(EMAIL_ALERTS_LOCK, &q->lock);
|
||||||
|
|
||||||
/* if a connection got replaced, we must absolutely prevent the connection
|
/* if a connection got replaced, we must absolutely prevent the connection
|
||||||
* handler from touching its fd, and perform the FD polling updates ourselves
|
* handler from touching its fd, and perform the FD polling updates ourselves
|
||||||
@ -2131,6 +2151,7 @@ static struct task *process_chk_conn(struct task *t, void *context, unsigned sho
|
|||||||
int ret;
|
int ret;
|
||||||
int expired = tick_is_expired(t->expire, now_ms);
|
int expired = tick_is_expired(t->expire, now_ms);
|
||||||
|
|
||||||
|
if (check->server)
|
||||||
HA_SPIN_LOCK(SERVER_LOCK, &check->server->lock);
|
HA_SPIN_LOCK(SERVER_LOCK, &check->server->lock);
|
||||||
if (!(check->state & CHK_ST_INPROGRESS)) {
|
if (!(check->state & CHK_ST_INPROGRESS)) {
|
||||||
/* no check currently running */
|
/* no check currently running */
|
||||||
@ -2257,6 +2278,7 @@ static struct task *process_chk_conn(struct task *t, void *context, unsigned sho
|
|||||||
conn = NULL;
|
conn = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (check->server) {
|
||||||
if (check->result == CHK_RES_FAILED) {
|
if (check->result == CHK_RES_FAILED) {
|
||||||
/* a failure or timeout detected */
|
/* a failure or timeout detected */
|
||||||
check_notify_failure(check);
|
check_notify_failure(check);
|
||||||
@ -2269,9 +2291,11 @@ static struct task *process_chk_conn(struct task *t, void *context, unsigned sho
|
|||||||
/* a success was detected */
|
/* a success was detected */
|
||||||
check_notify_success(check);
|
check_notify_success(check);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
task_set_affinity(t, MAX_THREADS_MASK);
|
task_set_affinity(t, MAX_THREADS_MASK);
|
||||||
check->state &= ~CHK_ST_INPROGRESS;
|
check->state &= ~CHK_ST_INPROGRESS;
|
||||||
|
|
||||||
|
if (check->server) {
|
||||||
rv = 0;
|
rv = 0;
|
||||||
if (global.spread_checks > 0) {
|
if (global.spread_checks > 0) {
|
||||||
rv = srv_getinter(check) * global.spread_checks / 100;
|
rv = srv_getinter(check) * global.spread_checks / 100;
|
||||||
@ -2279,11 +2303,13 @@ static struct task *process_chk_conn(struct task *t, void *context, unsigned sho
|
|||||||
}
|
}
|
||||||
t->expire = tick_add(now_ms, MS_TO_TICKS(srv_getinter(check) + rv));
|
t->expire = tick_add(now_ms, MS_TO_TICKS(srv_getinter(check) + rv));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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(check->inter));
|
t->expire = tick_add(t->expire, MS_TO_TICKS(check->inter));
|
||||||
out_unlock:
|
out_unlock:
|
||||||
|
if (check->server)
|
||||||
HA_SPIN_UNLOCK(SERVER_LOCK, &check->server->lock);
|
HA_SPIN_UNLOCK(SERVER_LOCK, &check->server->lock);
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
@ -2760,7 +2786,7 @@ static int tcpcheck_main(struct check *check)
|
|||||||
conn = cs->conn;
|
conn = cs->conn;
|
||||||
/* Maybe there were an older connection we were waiting on */
|
/* Maybe there were an older connection we were waiting on */
|
||||||
check->wait_list.events = 0;
|
check->wait_list.events = 0;
|
||||||
conn->target = &s->obj_type;
|
conn->target = s ? &s->obj_type : &proxy->obj_type;
|
||||||
|
|
||||||
/* no client address */
|
/* no client address */
|
||||||
clear_addr(&conn->addr.from);
|
clear_addr(&conn->addr.from);
|
||||||
@ -3173,9 +3199,8 @@ static struct task *process_email_alert(struct task *t, void *context, unsigned
|
|||||||
alert = LIST_NEXT(&q->email_alerts, typeof(alert), list);
|
alert = LIST_NEXT(&q->email_alerts, typeof(alert), list);
|
||||||
LIST_DEL(&alert->list);
|
LIST_DEL(&alert->list);
|
||||||
t->expire = now_ms;
|
t->expire = now_ms;
|
||||||
check->server = alert->srv;
|
|
||||||
check->tcpcheck_rules = &alert->tcpcheck_rules;
|
check->tcpcheck_rules = &alert->tcpcheck_rules;
|
||||||
check->status = HCHK_STATUS_UNKNOWN; // the UNKNOWN status is used to exit set_server_check_status(.) early
|
check->status = HCHK_STATUS_INI;
|
||||||
check->state |= CHK_ST_ENABLED;
|
check->state |= CHK_ST_ENABLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3230,7 +3255,6 @@ int init_email_alert(struct mailers *mls, struct proxy *p, char **err)
|
|||||||
check->xprt = mailer->xprt;
|
check->xprt = mailer->xprt;
|
||||||
check->addr = mailer->addr;
|
check->addr = mailer->addr;
|
||||||
check->port = get_host_port(&mailer->addr);
|
check->port = get_host_port(&mailer->addr);
|
||||||
//check->server = s;
|
|
||||||
|
|
||||||
if ((t = task_new(MAX_THREADS_MASK)) == NULL) {
|
if ((t = task_new(MAX_THREADS_MASK)) == NULL) {
|
||||||
memprintf(err, "out of memory while allocating mailer alerts task");
|
memprintf(err, "out of memory while allocating mailer alerts task");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user