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 */
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.
#define _HAPROXY_LB_CHASH_H
#include <haproxy/api.h>
+#include <haproxy/backend-t.h>
#include <haproxy/lb_chash-t.h>
struct proxy;
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 */
/*
#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 */
#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 */
#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 */
/*
#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 */
/*
#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 */
}
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,
+};
* 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;
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,
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:
* 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;
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,
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:
* 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;
srv, i + 1);
}
}
+ return 0;
}
/* simply removes a server from a weight tree.
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
* 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;
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.
recount_servers(p);
update_backend_weight(p);
recalc_server_map(p);
+ return 0;
}
/*
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:
/* 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;
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 */
recount_servers(p);
update_backend_weight(p);
recalc_server_ss(p);
+ return 0;
}
/*
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,
+};