mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2026-05-14 17:56:09 +02:00
MINOR: lb: make LB initialization even more declarative
This lets lb_ops specify the conditions necessary to bind to this set of ops. The condition is expressed as a list of mask and match fields on the algorithm flags. This is then used in proxy_finalize() to locate the lb_ops corresponding to the current configuration, by iterating over the list of lb_ops structures. This list is implemented using the same mechanisms used for configuration keywords: an INITCALL1 macro to a registration function. This also moves the lookup and property flags into the lb_ops structure that were previously applied manually on a case by case basis.
This commit is contained in:
parent
731fc033dd
commit
87a4f6d47e
@ -156,6 +156,7 @@ struct lbprm_per_tgrp {
|
||||
* The other ones might take it themselves if needed.
|
||||
*/
|
||||
struct lb_ops {
|
||||
struct list link;
|
||||
int (*proxy_init)(struct proxy *); /* set up per-proxy LB state at config time; <0=fail */
|
||||
void (*update_server_eweight)(struct server *); /* to be called after eweight change // srvlock */
|
||||
void (*set_server_status_up)(struct server *); /* to be called after status changes to UP // srvlock */
|
||||
@ -166,6 +167,11 @@ struct lb_ops {
|
||||
void (*proxy_deinit)(struct proxy *); /* to be called when we're destroying the proxy */
|
||||
void (*server_deinit)(struct server *); /* to be called when we're destroying the server */
|
||||
int (*server_init)(struct server *); /* initialize a freshly added server (runtime); <0=fail. */
|
||||
uint32_t algo_prop; /* load balancing algorithm lookup and properties */
|
||||
struct {
|
||||
uint32_t mask;
|
||||
uint32_t match;
|
||||
} map[VAR_ARRAY];
|
||||
};
|
||||
|
||||
/* LB parameters for all algorithms */
|
||||
|
||||
@ -30,6 +30,10 @@
|
||||
#include <haproxy/stream-t.h>
|
||||
#include <haproxy/time.h>
|
||||
|
||||
extern struct list lb_ops_list;
|
||||
|
||||
void lb_ops_register(struct lb_ops *ops);
|
||||
|
||||
struct server *get_server_sh(struct proxy *px, const char *addr, int len, const struct server *avoid);
|
||||
struct server *get_server_uh(struct proxy *px, char *uri, int uri_len, const struct server *avoid);
|
||||
struct server *get_server_ph(struct proxy *px, const char *uri, int uri_len, const struct server *avoid);
|
||||
|
||||
@ -31,8 +31,6 @@ struct server;
|
||||
struct server *chash_get_next_server(struct proxy *p, struct server *srvtoavoid);
|
||||
struct server *chash_get_server_hash(struct proxy *p, unsigned int hash, const struct server *avoid);
|
||||
|
||||
extern const struct lb_ops lb_chash_ops;
|
||||
|
||||
#endif /* _HAPROXY_LB_CHASH_H */
|
||||
|
||||
/*
|
||||
|
||||
@ -30,8 +30,6 @@
|
||||
|
||||
struct server *fas_get_next_server(struct proxy *p, struct server *srvtoavoid);
|
||||
|
||||
extern const struct lb_ops lb_fas_ops;
|
||||
|
||||
#endif /* _HAPROXY_LB_FAS_H */
|
||||
|
||||
/*
|
||||
|
||||
@ -30,8 +30,6 @@
|
||||
|
||||
struct server *fwlc_get_next_server(struct proxy *p, struct server *srvtoavoid);
|
||||
|
||||
extern const struct lb_ops lb_fwlc_ops;
|
||||
|
||||
#endif /* _HAPROXY_LB_FWLC_H */
|
||||
|
||||
/*
|
||||
|
||||
@ -30,8 +30,6 @@
|
||||
|
||||
struct server *fwrr_get_next_server(struct proxy *p, struct server *srvtoavoid);
|
||||
|
||||
extern const struct lb_ops lb_fwrr_ops;
|
||||
|
||||
#endif /* _HAPROXY_LB_FWRR_H */
|
||||
|
||||
/*
|
||||
|
||||
@ -30,8 +30,6 @@
|
||||
struct server *map_get_server_rr(struct proxy *px, struct server *srvtoavoid);
|
||||
struct server *map_get_server_hash(struct proxy *px, unsigned int hash);
|
||||
|
||||
extern const struct lb_ops lb_map_ops;
|
||||
|
||||
#endif /* _HAPROXY_LB_MAP_H */
|
||||
|
||||
/*
|
||||
|
||||
@ -29,6 +29,4 @@
|
||||
|
||||
struct server *ss_get_server(struct proxy *px);
|
||||
|
||||
extern const struct lb_ops lb_ss_ops;
|
||||
|
||||
#endif /* _HAPROXY_LB_SS_H */
|
||||
|
||||
@ -64,6 +64,13 @@
|
||||
|
||||
#define TRACE_SOURCE &trace_strm
|
||||
|
||||
struct list lb_ops_list = LIST_HEAD_INIT(lb_ops_list);
|
||||
|
||||
void lb_ops_register(struct lb_ops *ops)
|
||||
{
|
||||
LIST_APPEND(&lb_ops_list, &ops->link);
|
||||
}
|
||||
|
||||
/* helper function to invoke the correct hash method */
|
||||
unsigned int gen_hash(const struct proxy* px, const char* key, unsigned long len)
|
||||
{
|
||||
|
||||
@ -619,7 +619,13 @@ static int chash_init_server_tree(struct proxy *p)
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct lb_ops lb_chash_ops = {
|
||||
static struct lb_ops lb_chash_ops = {ILH,
|
||||
.map = {
|
||||
{ .mask = BE_LB_KIND | BE_LB_PARM, .match = BE_LB_KIND_RR | BE_LB_RR_RANDOM },
|
||||
{ .mask = BE_LB_KIND | BE_LB_HASH_TYPE, .match = BE_LB_KIND_HI | BE_LB_HASH_CONS },
|
||||
{ 0, 0 }
|
||||
},
|
||||
.algo_prop = BE_LB_LKUP_CHTREE | BE_LB_PROP_DYN,
|
||||
.proxy_init = chash_init_server_tree,
|
||||
.set_server_status_up = chash_set_server_status_up,
|
||||
.set_server_status_down = chash_set_server_status_down,
|
||||
@ -627,3 +633,5 @@ const struct lb_ops lb_chash_ops = {
|
||||
.server_init = chash_server_init,
|
||||
.server_deinit = chash_server_deinit,
|
||||
};
|
||||
|
||||
INITCALL1(STG_REGISTER, lb_ops_register, &lb_chash_ops);
|
||||
|
||||
@ -334,7 +334,12 @@ struct server *fas_get_next_server(struct proxy *p, struct server *srvtoavoid)
|
||||
return srv;
|
||||
}
|
||||
|
||||
const struct lb_ops lb_fas_ops = {
|
||||
static struct lb_ops lb_fas_ops = {ILH,
|
||||
.map = {
|
||||
{ .mask = BE_LB_KIND | BE_LB_PARM, .match = BE_LB_KIND_CB | BE_LB_CB_FAS },
|
||||
{ 0, 0 }
|
||||
},
|
||||
.algo_prop = BE_LB_LKUP_FSTREE | BE_LB_PROP_DYN,
|
||||
.proxy_init = fas_init_server_tree,
|
||||
.set_server_status_up = fas_set_server_status_up,
|
||||
.set_server_status_down = fas_set_server_status_down,
|
||||
@ -343,6 +348,8 @@ const struct lb_ops lb_fas_ops = {
|
||||
.server_drop_conn = fas_srv_reposition,
|
||||
};
|
||||
|
||||
INITCALL1(STG_REGISTER, lb_ops_register, &lb_fas_ops);
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* c-indent-level: 8
|
||||
|
||||
@ -878,7 +878,12 @@ redo:
|
||||
return srv;
|
||||
}
|
||||
|
||||
const struct lb_ops lb_fwlc_ops = {
|
||||
static struct lb_ops lb_fwlc_ops = {ILH,
|
||||
.map = {
|
||||
{ .mask = BE_LB_KIND | BE_LB_PARM, .match = BE_LB_KIND_CB | BE_LB_CB_LC },
|
||||
{ 0, 0 }
|
||||
},
|
||||
.algo_prop = BE_LB_LKUP_LCTREE | BE_LB_PROP_DYN,
|
||||
.proxy_init = fwlc_init_server_tree,
|
||||
.set_server_status_up = fwlc_set_server_status_up,
|
||||
.set_server_status_down = fwlc_set_server_status_down,
|
||||
@ -890,6 +895,8 @@ const struct lb_ops lb_fwlc_ops = {
|
||||
.proxy_deinit = fwlc_proxy_deinit,
|
||||
};
|
||||
|
||||
INITCALL1(STG_REGISTER, lb_ops_register, &lb_fwlc_ops);
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* c-indent-level: 8
|
||||
|
||||
@ -668,13 +668,20 @@ struct server *fwrr_get_next_server(struct proxy *p, struct server *srvtoavoid)
|
||||
return srv;
|
||||
}
|
||||
|
||||
const struct lb_ops lb_fwrr_ops = {
|
||||
static struct lb_ops lb_fwrr_ops = {ILH,
|
||||
.map = {
|
||||
{ .mask = BE_LB_KIND | BE_LB_PARM, .match = BE_LB_KIND_RR | BE_LB_RR_DYN },
|
||||
{ 0, 0 }
|
||||
},
|
||||
.algo_prop = BE_LB_LKUP_RRTREE | BE_LB_PROP_DYN,
|
||||
.proxy_init = fwrr_init_server_groups,
|
||||
.set_server_status_up = fwrr_set_server_status_up,
|
||||
.set_server_status_down = fwrr_set_server_status_down,
|
||||
.update_server_eweight = fwrr_update_server_weight,
|
||||
};
|
||||
|
||||
INITCALL1(STG_REGISTER, lb_ops_register, &lb_fwrr_ops);
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* c-indent-level: 8
|
||||
|
||||
10
src/lb_map.c
10
src/lb_map.c
@ -269,12 +269,20 @@ struct server *map_get_server_hash(struct proxy *px, unsigned int hash)
|
||||
return srv;
|
||||
}
|
||||
|
||||
const struct lb_ops lb_map_ops = {
|
||||
static struct lb_ops lb_map_ops = {ILH,
|
||||
.map = {
|
||||
{ .mask = BE_LB_KIND | BE_LB_PARM, .match = BE_LB_KIND_RR | BE_LB_RR_STATIC },
|
||||
{ .mask = BE_LB_KIND | BE_LB_HASH_TYPE, .match = BE_LB_KIND_HI | BE_LB_HASH_MAP },
|
||||
{ 0, 0 }
|
||||
},
|
||||
.algo_prop = BE_LB_LKUP_MAP,
|
||||
.proxy_init = init_server_map,
|
||||
.set_server_status_up = map_set_server_status_up,
|
||||
.set_server_status_down = map_set_server_status_down,
|
||||
};
|
||||
|
||||
INITCALL1(STG_REGISTER, lb_ops_register, &lb_map_ops);
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* c-indent-level: 8
|
||||
|
||||
10
src/lb_ss.c
10
src/lb_ss.c
@ -21,6 +21,7 @@
|
||||
#include <haproxy/api.h>
|
||||
#include <haproxy/backend.h>
|
||||
#include <haproxy/lb_ss.h>
|
||||
#include <haproxy/list.h>
|
||||
#include <haproxy/server-t.h>
|
||||
|
||||
/* This function elects a new stick server for proxy px.
|
||||
@ -179,8 +180,15 @@ struct server *ss_get_server(struct proxy *px)
|
||||
return srv;
|
||||
}
|
||||
|
||||
const struct lb_ops lb_ss_ops = {
|
||||
static struct lb_ops lb_ss_ops = {ILH,
|
||||
.map = {
|
||||
{ .mask = BE_LB_KIND | BE_LB_PARM, .match = BE_LB_KIND_SA | BE_LB_SA_SS },
|
||||
{ 0, 0 }
|
||||
},
|
||||
.algo_prop = BE_LB_PROP_DYN,
|
||||
.proxy_init = init_server_ss,
|
||||
.set_server_status_up = ss_set_server_status_up,
|
||||
.set_server_status_down = ss_set_server_status_down,
|
||||
};
|
||||
|
||||
INITCALL1(STG_REGISTER, lb_ops_register, &lb_ss_ops);
|
||||
|
||||
53
src/proxy.c
53
src/proxy.c
@ -1648,6 +1648,7 @@ int proxy_finalize(struct proxy *px, int *err_code)
|
||||
struct server_rule *srule;
|
||||
struct sticking_rule *mrule;
|
||||
struct logger *tmplogger;
|
||||
struct lb_ops *ops;
|
||||
unsigned int next_id;
|
||||
int cfgerr = 0;
|
||||
char *err = NULL;
|
||||
@ -2611,49 +2612,23 @@ int proxy_finalize(struct proxy *px, int *err_code)
|
||||
*/
|
||||
|
||||
px->lbprm.algo &= ~(BE_LB_LKUP | BE_LB_PROP_DYN);
|
||||
switch (px->lbprm.algo & BE_LB_KIND) {
|
||||
case BE_LB_KIND_RR:
|
||||
if ((px->lbprm.algo & BE_LB_PARM) == BE_LB_RR_STATIC) {
|
||||
px->lbprm.algo |= BE_LB_LKUP_MAP;
|
||||
px->lbprm.ops = &lb_map_ops;
|
||||
} else if ((px->lbprm.algo & BE_LB_PARM) == BE_LB_RR_RANDOM) {
|
||||
px->lbprm.algo |= BE_LB_LKUP_CHTREE | BE_LB_PROP_DYN;
|
||||
px->lbprm.ops = &lb_chash_ops;
|
||||
} else {
|
||||
px->lbprm.algo |= BE_LB_LKUP_RRTREE | BE_LB_PROP_DYN;
|
||||
px->lbprm.ops = &lb_fwrr_ops;
|
||||
list_for_each_entry(ops, &lb_ops_list, link) {
|
||||
int i;
|
||||
for (i = 0; ops->map[i].match != 0; i++) {
|
||||
if ((px->lbprm.algo & ops->map[i].mask) == ops->map[i].match) {
|
||||
px->lbprm.ops = ops;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case BE_LB_KIND_CB:
|
||||
if ((px->lbprm.algo & BE_LB_PARM) == BE_LB_CB_LC) {
|
||||
px->lbprm.algo |= BE_LB_LKUP_LCTREE | BE_LB_PROP_DYN;
|
||||
px->lbprm.ops = &lb_fwlc_ops;
|
||||
} else {
|
||||
px->lbprm.algo |= BE_LB_LKUP_FSTREE | BE_LB_PROP_DYN;
|
||||
px->lbprm.ops = &lb_fas_ops;
|
||||
if (px->lbprm.ops) {
|
||||
px->lbprm.algo |= px->lbprm.ops->algo_prop;
|
||||
if (px->lbprm.ops->proxy_init && px->lbprm.ops->proxy_init(px) < 0)
|
||||
cfgerr++;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case BE_LB_KIND_HI:
|
||||
if ((px->lbprm.algo & BE_LB_HASH_TYPE) == BE_LB_HASH_CONS) {
|
||||
px->lbprm.algo |= BE_LB_LKUP_CHTREE | BE_LB_PROP_DYN;
|
||||
px->lbprm.ops = &lb_chash_ops;
|
||||
} else {
|
||||
px->lbprm.algo |= BE_LB_LKUP_MAP;
|
||||
px->lbprm.ops = &lb_map_ops;
|
||||
}
|
||||
break;
|
||||
case BE_LB_KIND_SA:
|
||||
if ((px->lbprm.algo & BE_LB_PARM) == BE_LB_SA_SS) {
|
||||
px->lbprm.algo |= BE_LB_PROP_DYN;
|
||||
px->lbprm.ops = &lb_ss_ops;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (px->lbprm.ops && px->lbprm.ops->proxy_init &&
|
||||
px->lbprm.ops->proxy_init(px) < 0)
|
||||
cfgerr++;
|
||||
|
||||
HA_RWLOCK_INIT(&px->lbprm.lock);
|
||||
|
||||
if (px->options & PR_O_LOGASAP)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user