mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-06 23:27:04 +02:00
MEDIUM: check: implement check deletion for dynamic servers
Implement a mechanism to free a started check on runtime for dynamic servers. A new function check_purge is created for this. The check task will be marked for deletion and scheduled to properly close connection elements and free the task/tasklet/buf_wait elements. This function will be useful to delete a dynamic server wich checks.
This commit is contained in:
parent
d6b7080cec
commit
b33a0abc0b
@ -53,6 +53,7 @@ enum chk_result {
|
|||||||
#define CHK_ST_IN_ALLOC 0x0040 /* check blocked waiting for input buffer allocation */
|
#define CHK_ST_IN_ALLOC 0x0040 /* check blocked waiting for input buffer allocation */
|
||||||
#define CHK_ST_OUT_ALLOC 0x0080 /* check blocked waiting for output buffer allocation */
|
#define CHK_ST_OUT_ALLOC 0x0080 /* check blocked waiting for output buffer allocation */
|
||||||
#define CHK_ST_CLOSE_CONN 0x0100 /* check is waiting that the connection gets closed */
|
#define CHK_ST_CLOSE_CONN 0x0100 /* check is waiting that the connection gets closed */
|
||||||
|
#define CHK_ST_PURGE 0x0200 /* check must be freed */
|
||||||
|
|
||||||
/* check status */
|
/* check status */
|
||||||
enum healthcheck_status {
|
enum healthcheck_status {
|
||||||
|
@ -79,6 +79,7 @@ struct buffer *check_get_buf(struct check *check, struct buffer *bptr);
|
|||||||
void check_release_buf(struct check *check, struct buffer *bptr);
|
void check_release_buf(struct check *check, struct buffer *bptr);
|
||||||
const char *init_check(struct check *check, int type);
|
const char *init_check(struct check *check, int type);
|
||||||
void free_check(struct check *check);
|
void free_check(struct check *check);
|
||||||
|
void check_purge(struct check *check);
|
||||||
|
|
||||||
int init_srv_check(struct server *srv);
|
int init_srv_check(struct server *srv);
|
||||||
int init_srv_agent_check(struct server *srv);
|
int init_srv_agent_check(struct server *srv);
|
||||||
|
43
src/check.c
43
src/check.c
@ -1102,7 +1102,10 @@ struct task *process_chk_conn(struct task *t, void *context, unsigned int state)
|
|||||||
if (check->server)
|
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 (unlikely(check->state & CHK_ST_PURGE)) {
|
||||||
|
TRACE_STATE("health-check state to purge", CHK_EV_TASK_WAKE, check);
|
||||||
|
}
|
||||||
|
else if (!(check->state & (CHK_ST_INPROGRESS))) {
|
||||||
/* no check currently running */
|
/* no check currently running */
|
||||||
if (!expired) /* woke up too early */ {
|
if (!expired) /* woke up too early */ {
|
||||||
TRACE_STATE("health-check wake up too early", CHK_EV_TASK_WAKE, check);
|
TRACE_STATE("health-check wake up too early", CHK_EV_TASK_WAKE, check);
|
||||||
@ -1139,7 +1142,7 @@ struct task *process_chk_conn(struct task *t, void *context, unsigned int state)
|
|||||||
* First, let's check whether there was an uncaught error,
|
* First, let's check whether there was an uncaught error,
|
||||||
* which can happen on connect timeout or error.
|
* which can happen on connect timeout or error.
|
||||||
*/
|
*/
|
||||||
if (check->result == CHK_RES_UNKNOWN) {
|
if (check->result == CHK_RES_UNKNOWN && likely(!(check->state & CHK_ST_PURGE))) {
|
||||||
/* Here the connection must be defined. Otherwise the
|
/* Here the connection must be defined. Otherwise the
|
||||||
* error would have already been detected
|
* error would have already been detected
|
||||||
*/
|
*/
|
||||||
@ -1197,7 +1200,7 @@ struct task *process_chk_conn(struct task *t, void *context, unsigned int state)
|
|||||||
check->sess = NULL;
|
check->sess = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (check->server) {
|
if (check->server && likely(!(check->state & CHK_ST_PURGE))) {
|
||||||
if (check->result == CHK_RES_FAILED) {
|
if (check->result == CHK_RES_FAILED) {
|
||||||
/* a failure or timeout detected */
|
/* a failure or timeout detected */
|
||||||
TRACE_DEVEL("report failure", CHK_EV_TASK_WAKE|CHK_EV_HCHK_END|CHK_EV_HCHK_ERR, check);
|
TRACE_DEVEL("report failure", CHK_EV_TASK_WAKE|CHK_EV_HCHK_END|CHK_EV_HCHK_ERR, check);
|
||||||
@ -1236,6 +1239,23 @@ struct task *process_chk_conn(struct task *t, void *context, unsigned int state)
|
|||||||
HA_SPIN_UNLOCK(SERVER_LOCK, &check->server->lock);
|
HA_SPIN_UNLOCK(SERVER_LOCK, &check->server->lock);
|
||||||
|
|
||||||
TRACE_LEAVE(CHK_EV_TASK_WAKE, check);
|
TRACE_LEAVE(CHK_EV_TASK_WAKE, check);
|
||||||
|
|
||||||
|
/* Free the check if set to PURGE. After this, the check instance may be
|
||||||
|
* freed via the free_server invocation, so it must not be accessed
|
||||||
|
* after this point.
|
||||||
|
*/
|
||||||
|
if (unlikely(check->state & CHK_ST_PURGE)) {
|
||||||
|
/* buf_wait */
|
||||||
|
LIST_DELETE(&check->buf_wait.list);
|
||||||
|
/* tasklet */
|
||||||
|
pool_free(pool_head_tasklet, check->wait_list.tasklet);
|
||||||
|
/* task */
|
||||||
|
task_destroy(check->task);
|
||||||
|
t = NULL;
|
||||||
|
|
||||||
|
free_server(check->server);
|
||||||
|
}
|
||||||
|
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1314,6 +1334,11 @@ const char *init_check(struct check *check, int type)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Liberates the resources allocated for a check.
|
||||||
|
*
|
||||||
|
* This function must only be used at startup when it is known that the check
|
||||||
|
* has never been executed.
|
||||||
|
*/
|
||||||
void free_check(struct check *check)
|
void free_check(struct check *check)
|
||||||
{
|
{
|
||||||
task_destroy(check->task);
|
task_destroy(check->task);
|
||||||
@ -1329,6 +1354,18 @@ void free_check(struct check *check)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This function must be used in order to free a started check. The check will
|
||||||
|
* be scheduled for a next execution in order to properly close and free all
|
||||||
|
* check elements.
|
||||||
|
*
|
||||||
|
* Non thread-safe.
|
||||||
|
*/
|
||||||
|
void check_purge(struct check *check)
|
||||||
|
{
|
||||||
|
check->state = CHK_ST_PURGE;
|
||||||
|
task_wakeup(check->task, TASK_WOKEN_OTHER);
|
||||||
|
}
|
||||||
|
|
||||||
/* manages a server health-check. Returns the time the task accepts to wait, or
|
/* manages a server health-check. Returns the time the task accepts to wait, or
|
||||||
* TIME_ETERNITY for infinity.
|
* TIME_ETERNITY for infinity.
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user