Signed-off-by: Nenad Merdanovic <nmer...@haproxy.com> --- doc/configuration.txt | 6 ++++++ include/proto/backend.h | 13 +++++++++++++ src/backend.c | 25 +++++++++++++++++++++++++ 3 files changed, 44 insertions(+)
diff --git a/doc/configuration.txt b/doc/configuration.txt index e88bfd6..a79c4f3 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -12530,6 +12530,12 @@ mul(<value>) This prefix is followed by a name. The separator is a '.'. The name may only contain characters 'a-z', 'A-Z', '0-9', '.' and '_'. +nbsrv + Takes an input value of type string, interprets it as a backend name and + returns the number of usable servers in that backend. Can be used in places + where we want to look up a backend from a dynamic name, like a result of a + map lookup. + neg Takes the input value of type signed integer, computes the opposite value, and returns the remainder as an signed integer. 0 is identity. This operator diff --git a/include/proto/backend.h b/include/proto/backend.h index 105807b..39a7f3d 100644 --- a/include/proto/backend.h +++ b/include/proto/backend.h @@ -46,6 +46,19 @@ struct server *get_server_sh(struct proxy *px, const char *addr, int len); struct server *get_server_uh(struct proxy *px, char *uri, int uri_len); int be_lastsession(const struct proxy *be); +/* Returns number of usable servers in backend */ +static inline int be_usable_srv(struct proxy *be) +{ + if (be->state == PR_STSTOPPED) + return 0; + else if (be->srv_act) + return be->srv_act; + else if (be->lbprm.fbck) + return 1; + else + return be->srv_bck; +} + /* set the time of last session on the backend */ static void inline be_set_sess_last(struct proxy *be) { diff --git a/src/backend.c b/src/backend.c index c9bc3ed..5e2b8fc 100644 --- a/src/backend.c +++ b/src/backend.c @@ -1821,6 +1821,24 @@ smp_fetch_srv_sess_rate(const struct arg *args, struct sample *smp, const char * return 1; } +static int sample_conv_nbsrv(const struct arg *args, struct sample *smp, void *private) +{ + + struct proxy *px; + + if (!smp_make_safe(smp)) + return 0; + + px = proxy_find_by_name(smp->data.u.str.str, PR_CAP_BE, 0); + if (!px) + return 0; + + smp->data.type = SMP_T_SINT; + smp->data.u.sint = be_usable_srv(px); + + return 1; +} + /* Note: must not be declared <const> as its list will be overwritten. * Please take care of keeping this list alphabetically sorted. @@ -1841,6 +1859,12 @@ static struct sample_fetch_kw_list smp_kws = {ILH, { { /* END */ }, }}; +/* Note: must not be declared <const> as its list will be overwritten */ +static struct sample_conv_kw_list sample_conv_kws = {ILH, { + { "nbsrv", sample_conv_nbsrv, 0, NULL, SMP_T_STR, SMP_T_SINT }, + { /* END */ }, +}}; + /* Note: must not be declared <const> as its list will be overwritten. * Please take care of keeping this list alphabetically sorted. @@ -1854,6 +1878,7 @@ __attribute__((constructor)) static void __backend_init(void) { sample_register_fetches(&smp_kws); + sample_register_convs(&sample_conv_kws); acl_register_keywords(&acl_kws); } -- 2.9.3