mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-03-11 05:48:41 +00:00
MINOR: server: add srv->rid (revision id) value
With current design, we could not distinguish between previously existing deleted server and a new server reusing the deleted server name/id. This can cause some confusion when auditing stats/events/logs, because the new server will look similar to the old one. To address this, we're adding a new value in server structure: rid rid (revision id) value is an unsigned 32bits value that is set upon server creation. Value is derived from a global counter that starts at 0 and is incremented each time one or multiple server deletions are followed by a server addition (meaning that old name/id reuse could occur). Thanks to this revision id, it is now easy to tell whether the server we're looking at is the same as before or if it has been deleted and re-added in the meantime. (combining server name/id + server revision id yields a process-wide unique identifier)
This commit is contained in:
parent
7f59d68fe2
commit
61e3894dfe
@ -264,6 +264,7 @@ struct server {
|
||||
int slowstart; /* slowstart time in seconds (ms in the conf) */
|
||||
|
||||
char *id; /* just for identification */
|
||||
uint32_t rid; /* revision: if id has been reused for a new server, rid won't match */
|
||||
unsigned iweight,uweight, cur_eweight; /* initial weight, user-specified weight, and effective weight */
|
||||
unsigned wscore; /* weight score, used during srv map computation */
|
||||
unsigned next_eweight; /* next pending eweight to commit */
|
||||
|
42
src/server.c
42
src/server.c
@ -72,6 +72,31 @@ struct eb_root idle_conn_srv = EB_ROOT;
|
||||
struct task *idle_conn_task __read_mostly = NULL;
|
||||
struct list servers_list = LIST_HEAD_INIT(servers_list);
|
||||
|
||||
/* SERVER DELETE(n)->ADD global tracker:
|
||||
* This is meant to provide srv->rid (revision id) value.
|
||||
* Revision id allows to differentiate between a previously existing
|
||||
* deleted server and a new server reusing deleted server name/id.
|
||||
*
|
||||
* start value is 0 (even value)
|
||||
* LSB is used to specify that one or multiple srv delete in a row
|
||||
* were performed.
|
||||
* When adding a new server, increment by 1 if current
|
||||
* value is odd (odd = LSB set),
|
||||
* because adding a new server after one or
|
||||
* multiple deletions means we could potentially be reusing old names:
|
||||
* Increase the revision id to prevent mixups between old and new names.
|
||||
*
|
||||
* srv->rid is calculated from cnt even values only.
|
||||
* sizeof(srv_id_reuse_cnt) must be twice sizeof(srv->rid)
|
||||
*
|
||||
* Wraparound is expected and should not cause issues
|
||||
* (with current design we allow up to 4 billion unique revisions)
|
||||
*
|
||||
* Counter is only used under thread_isolate (cli_add/cli_del),
|
||||
* no need for atomic ops.
|
||||
*/
|
||||
static uint64_t srv_id_reuse_cnt = 0;
|
||||
|
||||
/* The server names dictionary */
|
||||
struct dict server_key_dict = {
|
||||
.name = "server keys",
|
||||
@ -2635,6 +2660,9 @@ static int _srv_parse_init(struct server **srv, char **args, int *cur_arg,
|
||||
else
|
||||
newsrv->tmpl_info.prefix = strdup(args[1]);
|
||||
|
||||
/* revision defaults to 0 */
|
||||
newsrv->rid = 0;
|
||||
|
||||
/* several ways to check the port component :
|
||||
* - IP => port=+0, relative (IPv4 only)
|
||||
* - IP: => port=+0, relative
|
||||
@ -4854,6 +4882,17 @@ static int cli_parse_add_server(char **args, char *payload, struct appctx *appct
|
||||
if (srv->addr_node.key)
|
||||
ebis_insert(&be->used_server_addr, &srv->addr_node);
|
||||
|
||||
/* check if LSB bit (odd bit) is set for reuse_cnt */
|
||||
if (srv_id_reuse_cnt & 1) {
|
||||
/* cnt must be increased */
|
||||
srv_id_reuse_cnt++;
|
||||
}
|
||||
/* srv_id_reuse_cnt is always even at this stage, divide by 2 to
|
||||
* save some space
|
||||
* (sizeof(srv->rid) is half of sizeof(srv_id_reuse_cnt))
|
||||
*/
|
||||
srv->rid = (srv_id_reuse_cnt) ? (srv_id_reuse_cnt / 2) : 0;
|
||||
|
||||
thread_release();
|
||||
|
||||
/* Start the check task. The server must be fully initialized.
|
||||
@ -5022,6 +5061,9 @@ static int cli_parse_delete_server(char **args, char *payload, struct appctx *ap
|
||||
/* remove srv from idle_node tree for idle conn cleanup */
|
||||
eb32_delete(&srv->idle_node);
|
||||
|
||||
/* set LSB bit (odd bit) for reuse_cnt */
|
||||
srv_id_reuse_cnt |= 1;
|
||||
|
||||
thread_release();
|
||||
|
||||
ha_notice("Server deleted.\n");
|
||||
|
Loading…
Reference in New Issue
Block a user