MINOR: lb: infrastructure for declarative initialization

This creates an ops structure for the various callbacks into the LB
algorithms, and defines those ops structure for each algorithm. A new
proxy_init callback is added for the initialization functions called
from proxy_finalize(). Since one of them needs to return an int in case
of an error, we change all the others to also return an int so we have a
uniform type.

No functional changes.
This commit is contained in:
Maxime Henrion 2026-04-27 14:26:18 -04:00 committed by Olivier Houchard
parent 5ddba59a02
commit 16a4de0d5c
13 changed files with 100 additions and 12 deletions

View File

@ -150,6 +150,24 @@ struct lbprm_per_tgrp {
struct lb_fwrr_per_tgrp fwrr;
};
};
/* Call backs for some LB actions. Any of them may be NULL (thus should be ignored).
* Those marked "srvlock" will need to be called with the server lock held.
* The other ones might take it themselves if needed.
*/
struct lb_ops {
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 */
void (*set_server_status_down)(struct server *); /* to be called after status changes to DOWN // srvlock */
void (*server_take_conn)(struct server *); /* to be called when connection is assigned */
void (*server_drop_conn)(struct server *); /* to be called when connection is dropped */
void (*server_requeue)(struct server *); /* function used to place the server where it must be */
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. */
};
/* LB parameters for all algorithms */
struct lbprm {
union { /* LB parameters depending on the algo type */
@ -179,6 +197,7 @@ struct lbprm {
struct mt_list lb_free_list; /* LB tree elements available */
__decl_thread(HA_RWLOCK_T lock);
struct server *fbck; /* first backup server when !PR_O_USE_ALL_BK, or NULL */
const struct lb_ops *ops; /* algo-specific operations; NULL = no LB algo selected */
/* Call backs for some actions. Any of them may be NULL (thus should be ignored).
* Those marked "srvlock" will need to be called with the server lock held.

View File

@ -23,6 +23,7 @@
#define _HAPROXY_LB_CHASH_H
#include <haproxy/api.h>
#include <haproxy/backend-t.h>
#include <haproxy/lb_chash-t.h>
struct proxy;
@ -31,6 +32,8 @@ int chash_init_server_tree(struct proxy *p);
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 */
/*

View File

@ -23,12 +23,15 @@
#define _HAPROXY_LB_FAS_H
#include <haproxy/api.h>
#include <haproxy/backend-t.h>
#include <haproxy/lb_fas-t.h>
#include <haproxy/proxy-t.h>
#include <haproxy/server-t.h>
struct server *fas_get_next_server(struct proxy *p, struct server *srvtoavoid);
void fas_init_server_tree(struct proxy *p);
int fas_init_server_tree(struct proxy *p);
extern const struct lb_ops lb_fas_ops;
#endif /* _HAPROXY_LB_FAS_H */

View File

@ -23,12 +23,15 @@
#define _HAPROXY_LB_FWLC_H
#include <haproxy/api.h>
#include <haproxy/backend-t.h>
#include <haproxy/lb_fwlc-t.h>
#include <haproxy/proxy-t.h>
#include <haproxy/server-t.h>
struct server *fwlc_get_next_server(struct proxy *p, struct server *srvtoavoid);
void fwlc_init_server_tree(struct proxy *p);
int fwlc_init_server_tree(struct proxy *p);
extern const struct lb_ops lb_fwlc_ops;
#endif /* _HAPROXY_LB_FWLC_H */

View File

@ -23,13 +23,16 @@
#define _HAPROXY_LB_FWRR_H
#include <haproxy/api.h>
#include <haproxy/backend-t.h>
#include <haproxy/lb_fwrr-t.h>
#include <haproxy/proxy-t.h>
#include <haproxy/server-t.h>
void fwrr_init_server_groups(struct proxy *p);
int fwrr_init_server_groups(struct proxy *p);
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 */
/*

View File

@ -23,14 +23,17 @@
#define _HAPROXY_LB_MAP_H
#include <haproxy/api.h>
#include <haproxy/backend-t.h>
#include <haproxy/proxy-t.h>
#include <haproxy/server-t.h>
void recalc_server_map(struct proxy *px);
void init_server_map(struct proxy *p);
int init_server_map(struct proxy *p);
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 */
/*

View File

@ -23,11 +23,14 @@
#define _HAPROXY_LB_SS_H
#include <haproxy/api.h>
#include <haproxy/backend-t.h>
#include <haproxy/proxy-t.h>
#include <haproxy/server-t.h>
void recalc_server_ss(struct proxy *px);
void init_server_ss(struct proxy *px);
int init_server_ss(struct proxy *px);
struct server *ss_get_server(struct proxy *px);
extern const struct lb_ops lb_ss_ops;
#endif /* _HAPROXY_LB_SS_H */

View File

@ -626,3 +626,12 @@ int chash_init_server_tree(struct proxy *p)
}
return 0;
}
const struct lb_ops lb_chash_ops = {
.proxy_init = chash_init_server_tree,
.set_server_status_up = chash_set_server_status_up,
.set_server_status_down = chash_set_server_status_down,
.update_server_eweight = chash_update_server_weight,
.server_init = chash_server_init,
.server_deinit = chash_server_deinit,
};

View File

@ -255,7 +255,7 @@ static void fas_update_server_weight(struct server *srv)
* weighted least-conns. It also sets p->lbprm.wdiv to the eweight to
* uweight ratio. Both active and backup groups are initialized.
*/
void fas_init_server_tree(struct proxy *p)
int fas_init_server_tree(struct proxy *p)
{
struct server *srv;
struct eb_root init_head = EB_ROOT;
@ -285,6 +285,7 @@ void fas_init_server_tree(struct proxy *p)
srv->lb_tree = (srv->flags & SRV_F_BACKUP) ? &p->lbprm.fas.bck : &p->lbprm.fas.act;
fas_queue_srv(srv);
}
return 0;
}
/* Return next server from the FS tree in backend <p>. If the tree is empty,
@ -339,6 +340,14 @@ struct server *fas_get_next_server(struct proxy *p, struct server *srvtoavoid)
return srv;
}
const struct lb_ops lb_fas_ops = {
.proxy_init = fas_init_server_tree,
.set_server_status_up = fas_set_server_status_up,
.set_server_status_down = fas_set_server_status_down,
.update_server_eweight = fas_update_server_weight,
.server_take_conn = fas_srv_reposition,
.server_drop_conn = fas_srv_reposition,
};
/*
* Local variables:

View File

@ -709,7 +709,7 @@ static void fwlc_update_server_weight(struct server *srv)
* weighted least-conns. It also sets p->lbprm.wdiv to the eweight to
* uweight ratio. Both active and backup groups are initialized.
*/
void fwlc_init_server_tree(struct proxy *p)
int fwlc_init_server_tree(struct proxy *p)
{
struct server *srv;
struct eb_root init_head = EB_ROOT;
@ -744,6 +744,7 @@ void fwlc_init_server_tree(struct proxy *p)
srv->lb_tree = (srv->flags & SRV_F_BACKUP) ? &p->lbprm.fwlc.bck : &p->lbprm.fwlc.act;
fwlc_queue_srv(srv, srv->next_eweight);
}
return 0;
}
/* Return next server from the FWLC tree in backend <p>. If the tree is empty,
@ -886,6 +887,17 @@ redo:
return srv;
}
const struct lb_ops lb_fwlc_ops = {
.proxy_init = fwlc_init_server_tree,
.set_server_status_up = fwlc_set_server_status_up,
.set_server_status_down = fwlc_set_server_status_down,
.update_server_eweight = fwlc_update_server_weight,
.server_take_conn = fwlc_srv_reposition,
.server_drop_conn = fwlc_srv_reposition,
.server_requeue = fwlc_srv_reposition,
.server_deinit = fwlc_server_deinit,
.proxy_deinit = fwlc_proxy_deinit,
};
/*
* Local variables:

View File

@ -293,7 +293,7 @@ static inline void fwrr_queue_by_weight(struct eb_root *root, struct server *s,
* weighted round-robin. It also sets p->lbprm.wdiv to the eweight to uweight
* ratio. Both active and backup groups are initialized.
*/
void fwrr_init_server_groups(struct proxy *p)
int fwrr_init_server_groups(struct proxy *p)
{
struct server *srv;
struct eb_root init_head = EB_ROOT;
@ -357,6 +357,7 @@ void fwrr_init_server_groups(struct proxy *p)
srv, i + 1);
}
}
return 0;
}
/* simply removes a server from a weight tree.
@ -671,6 +672,13 @@ struct server *fwrr_get_next_server(struct proxy *p, struct server *srvtoavoid)
return srv;
}
const struct lb_ops lb_fwrr_ops = {
.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,
};
/*
* Local variables:
* c-indent-level: 8

View File

@ -137,7 +137,7 @@ void recalc_server_map(struct proxy *px)
* weights if applicable. It should be called only once per proxy, at config
* time.
*/
void init_server_map(struct proxy *p)
int init_server_map(struct proxy *p)
{
struct server *srv;
int pgcd;
@ -148,7 +148,7 @@ void init_server_map(struct proxy *p)
p->lbprm.update_server_eweight = NULL;
if (!p->srv)
return;
return 0;
/* We will factor the weights to reduce the table,
* using Euclide's largest common divisor algorithm.
@ -201,6 +201,7 @@ void init_server_map(struct proxy *p)
recount_servers(p);
update_backend_weight(p);
recalc_server_map(p);
return 0;
}
/*
@ -272,6 +273,11 @@ struct server *map_get_server_hash(struct proxy *px, unsigned int hash)
return srv;
}
const struct lb_ops lb_map_ops = {
.proxy_init = init_server_map,
.set_server_status_up = map_set_server_status_up,
.set_server_status_down = map_set_server_status_down,
};
/*
* Local variables:

View File

@ -143,7 +143,7 @@ void recalc_server_ss(struct proxy *px)
/* This function is responsible for preparing sticky LB algorithm.
* It should be called only once per proxy, at config time.
*/
void init_server_ss(struct proxy *p)
int init_server_ss(struct proxy *p)
{
struct server *srv;
@ -152,7 +152,7 @@ void init_server_ss(struct proxy *p)
p->lbprm.update_server_eweight = NULL;
if (!p->srv)
return;
return 0;
for (srv = p->srv; srv; srv = srv->next) {
srv->next_eweight = 1; /* ignore weights, all servers have the same weight */
@ -163,6 +163,7 @@ void init_server_ss(struct proxy *p)
recount_servers(p);
update_backend_weight(p);
recalc_server_ss(p);
return 0;
}
/*
@ -181,3 +182,9 @@ struct server *ss_get_server(struct proxy *px)
HA_RWLOCK_RDUNLOCK(LBPRM_LOCK, &px->lbprm.lock);
return srv;
}
const struct lb_ops lb_ss_ops = {
.proxy_init = init_server_ss,
.set_server_status_up = ss_set_server_status_up,
.set_server_status_down = ss_set_server_status_down,
};