mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-01-19 20:20:45 +00:00
MINOR: server/event_hdl: add support for SERVER_ADD and SERVER_DEL events
Basic support for ADD and DEL server events are added through this commit: SERVER_ADD is published on dynamic server addition through cli. SERVER_DEL is published on dynamic server deletion through cli. This work depends on: "MINOR: event_hdl: add event handler base api" "MINOR: server: add srv->rid (revision id) value"
This commit is contained in:
parent
745ce8e8ad
commit
129ecf441f
@ -40,6 +40,7 @@
|
||||
#include <haproxy/stats-t.h>
|
||||
#include <haproxy/task-t.h>
|
||||
#include <haproxy/thread-t.h>
|
||||
#include <haproxy/event_hdl-t.h>
|
||||
|
||||
|
||||
/* server states. Only SRV_ST_STOPPED indicates a down server. */
|
||||
@ -403,6 +404,8 @@ struct server {
|
||||
} op_st_chg; /* operational status change's reason */
|
||||
char adm_st_chg_cause[48]; /* administrative status change's cause */
|
||||
|
||||
event_hdl_sub_list e_subs; /* event_hdl: server's subscribers list (atomically updated) */
|
||||
|
||||
/* warning, these structs are huge, keep them at the bottom */
|
||||
struct conn_src conn_src; /* connection source settings */
|
||||
struct sockaddr_storage addr; /* the address to connect to, doesn't include the port */
|
||||
@ -411,6 +414,35 @@ struct server {
|
||||
EXTRA_COUNTERS(extra_counters);
|
||||
};
|
||||
|
||||
/* data provided to EVENT_HDL_SUB_SERVER handlers through event_hdl facility */
|
||||
struct event_hdl_cb_data_server {
|
||||
/* provided by:
|
||||
* EVENT_HDL_SUB_SERVER_ADD
|
||||
* EVENT_HDL_SUB_SERVER_DOWN
|
||||
*/
|
||||
struct {
|
||||
/* safe data can be safely used from both
|
||||
* sync and async handlers
|
||||
* data consistency is guaranteed
|
||||
*/
|
||||
char name[64]; /* server name/id */
|
||||
char proxy_name[64]; /* id of proxy the server belongs to */
|
||||
int puid; /* proxy-unique server ID */
|
||||
int rid; /* server id revision */
|
||||
unsigned int flags; /* server flags */
|
||||
} safe;
|
||||
struct {
|
||||
/* unsafe data may only be used from sync handlers:
|
||||
* in async mode, data consistency cannot be guaranteed
|
||||
* and unsafe data may already be stale, thus using
|
||||
* it is highly discouraged because it
|
||||
* could lead to undefined behavior (UAF, null dereference...)
|
||||
*/
|
||||
struct server *ptr; /* server live ptr */
|
||||
/* lock hints */
|
||||
uint8_t thread_isolate; /* 1 = thread_isolate is on, no locking required */
|
||||
} unsafe;
|
||||
};
|
||||
|
||||
/* Storage structure to load server-state lines from a flat file into
|
||||
* an ebtree, for faster processing
|
||||
|
40
src/server.c
40
src/server.c
@ -47,6 +47,7 @@
|
||||
#include <haproxy/time.h>
|
||||
#include <haproxy/tools.h>
|
||||
#include <haproxy/xxhash.h>
|
||||
#include <haproxy/event_hdl.h>
|
||||
|
||||
|
||||
static void srv_update_status(struct server *s);
|
||||
@ -132,6 +133,33 @@ int srv_getinter(const struct check *check)
|
||||
return (check->fastinter)?(check->fastinter):(check->inter);
|
||||
}
|
||||
|
||||
/*
|
||||
* Use this to publish EVENT_HDL_SUB_SERVER family type event
|
||||
* from srv facility
|
||||
* Event will be published in both global subscription list and
|
||||
* server dedicated subscription list
|
||||
* server ptr must be valid
|
||||
*/
|
||||
static inline void srv_event_hdl_publish(struct event_hdl_sub_type event, struct server *srv, uint8_t thread_isolate)
|
||||
{
|
||||
struct event_hdl_cb_data_server cb_data;
|
||||
|
||||
/* safe data assignments */
|
||||
cb_data.safe.puid = srv->puid;
|
||||
cb_data.safe.rid = srv->rid;
|
||||
cb_data.safe.flags = srv->flags;
|
||||
snprintf(cb_data.safe.name, sizeof(cb_data.safe.name), "%s", srv->id);
|
||||
if (srv->proxy)
|
||||
snprintf(cb_data.safe.proxy_name, sizeof(cb_data.safe.proxy_name), "%s", srv->proxy->id);
|
||||
/* unsafe data assignments */
|
||||
cb_data.unsafe.ptr = srv;
|
||||
cb_data.unsafe.thread_isolate = thread_isolate;
|
||||
/* publish in server dedicated sub list */
|
||||
event_hdl_publish(&srv->e_subs, event, EVENT_HDL_CB_DATA(&cb_data));
|
||||
/* publish in global subscription list */
|
||||
event_hdl_publish(NULL, event, EVENT_HDL_CB_DATA(&cb_data));
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that we did not get a hash collision.
|
||||
* Unlikely, but it can happen. The server's proxy must be at least
|
||||
@ -2337,6 +2365,7 @@ struct server *new_server(struct proxy *proxy)
|
||||
LIST_APPEND(&servers_list, &srv->global_list);
|
||||
LIST_INIT(&srv->srv_rec_item);
|
||||
LIST_INIT(&srv->ip_rec_item);
|
||||
event_hdl_sub_list_init(&srv->e_subs);
|
||||
|
||||
srv->next_state = SRV_ST_RUNNING; /* early server setup */
|
||||
srv->last_change = now.tv_sec;
|
||||
@ -2419,6 +2448,7 @@ struct server *srv_drop(struct server *srv)
|
||||
HA_SPIN_DESTROY(&srv->lock);
|
||||
|
||||
LIST_DELETE(&srv->global_list);
|
||||
event_hdl_sub_list_destroy(&srv->e_subs);
|
||||
|
||||
EXTRA_COUNTERS_FREE(srv->extra_counters);
|
||||
|
||||
@ -4893,6 +4923,11 @@ static int cli_parse_add_server(char **args, char *payload, struct appctx *appct
|
||||
*/
|
||||
srv->rid = (srv_id_reuse_cnt) ? (srv_id_reuse_cnt / 2) : 0;
|
||||
|
||||
/* adding server cannot fail when we reach this:
|
||||
* publishing EVENT_HDL_SUB_SERVER_ADD
|
||||
*/
|
||||
srv_event_hdl_publish(EVENT_HDL_SUB_SERVER_ADD, srv, 1);
|
||||
|
||||
thread_release();
|
||||
|
||||
/* Start the check task. The server must be fully initialized.
|
||||
@ -5020,6 +5055,11 @@ static int cli_parse_delete_server(char **args, char *payload, struct appctx *ap
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* removing cannot fail anymore when we reach this:
|
||||
* publishing EVENT_HDL_SUB_SERVER_DEL
|
||||
*/
|
||||
srv_event_hdl_publish(EVENT_HDL_SUB_SERVER_DEL, srv, 1);
|
||||
|
||||
/* remove srv from tracking list */
|
||||
if (srv->track)
|
||||
release_server_track(srv);
|
||||
|
Loading…
Reference in New Issue
Block a user