From: Aurelien DARRAGON Date: Mon, 13 Jan 2025 15:09:56 +0000 (+0100) Subject: MEDIUM: stktable: split src-based key smp_fetch_sc functions X-Git-Tag: v3.2-dev4~30 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=22229a41a294d6ba2a406ab8e8cd28a464dc4018;p=thirdparty%2Fhaproxy.git MEDIUM: stktable: split src-based key smp_fetch_sc functions In this patch we split several sample fetch functions that are leveraged by the "src-" fetches such as smp_fetch_sc_inc_gpc(). Indeed, for all of them, we add an intermediate helper function that takes a stkctr pointer as parameter and performs the logic, leaving the lookup part in the calling function. Before this patch existing functions were doing the lookup + the fetch logic. Thanks to this patch it will become easier to add generic converters taking lookup key as input. List of targeted functions: - smp_fetch_sc_inc_gpc() - smp_fetch_sc_inc_gpc0() - smp_fetch_sc_inc_gpc1() - smp_fetch_sc_clr_gpc() - smp_fetch_sc_clr_gpc0() - smp_fetch_sc_clr_gpc1() - smp_fetch_sc_conn_cnt() - smp_fetch_sc_conn_rate() - smp_fetch_sc_updt_conn_cnt() - smp_fetch_sc_conn_curr() - smp_fetch_sc_glitch_cnt() - smp_fetch_sc_glitch_rate() - smp_fetch_sc_sess_cnt() - smp_fetch_sc_sess_rate() - smp_fetch_sc_http_req_cnt() - smp_fetch_sc_http_req_rate() - smp_fetch_sc_http_err_cnt() - smp_fetch_sc_http_err_rate() - smp_fetch_sc_http_fail_cnt() - smp_fetch_sc_http_fail_rate() - smp_fetch_sc_kbytes_in() - smp_fetch_sc_bytes_in_rate() - smp_fetch_kbytes_out() - smp_fetch_sc_gpc1_rate() - smp_fetch_sc_gpc0_rate() - smp_fetch_sc_gpc_rate() - smp_fetch_sc_get_gpc1() - smp_fetch_sc_get_gpc0() - smp_fetch_sc_get_gpc() - smp_fetch_sc_get_gpt0() - smp_fetch_sc_get_gpt() - smp_fetch_sc_bytes_out_rate() Please note that this patch doesn't render any good using "git show" or "git diff". For all the functions listed above, a new helper function was defined right above it, with the same name without "_sc". These new functions perform the fetch part, while the original ones (with "_sc") now simply perform the lookup and then leverage the corresponding fetch helper. --- diff --git a/src/stick_table.c b/src/stick_table.c index 85c8f4b54..9d7af8eee 100644 --- a/src/stick_table.c +++ b/src/stick_table.c @@ -3725,6 +3725,34 @@ smp_fetch_sc_tracked(const struct arg *args, struct sample *smp, const char *kw, return 1; } +static int smp_fetch_get_gpt(struct stkctr *stkctr, struct sample *smp, unsigned int idx, int decrefcnt) +{ + smp->flags = SMP_F_VOL_TEST; + smp->data.type = SMP_T_SINT; + smp->data.u.sint = 0; + + if (stkctr_entry(stkctr)) { + void *ptr; + + ptr = stktable_data_ptr_idx(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GPT, idx); + if (!ptr) { + if (decrefcnt) + stktable_release(stkctr->table, stkctr_entry(stkctr)); + return 0; /* parameter not stored */ + } + + HA_RWLOCK_RDLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock); + + smp->data.u.sint = stktable_data_cast(ptr, std_t_uint); + + HA_RWLOCK_RDUNLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock); + + if (decrefcnt) + stktable_release(stkctr->table, stkctr_entry(stkctr)); + } + return 1; +} + /* set to the General Purpose Tag of index set as first arg * to value from the stream's tracked frontend counters or from the src. * Supports being called as "sc_get_gpt(,[,])" or @@ -3744,6 +3772,11 @@ smp_fetch_sc_get_gpt(const struct arg *args, struct sample *smp, const char *kw, if (!stkctr) return 0; + return smp_fetch_get_gpt(stkctr, smp, idx, (stkctr == &tmpstkctr) ? 1 : 0); +} + +static int smp_fetch_get_gpt0(struct stkctr *stkctr, struct sample *smp, int decrefcnt) +{ smp->flags = SMP_F_VOL_TEST; smp->data.type = SMP_T_SINT; smp->data.u.sint = 0; @@ -3751,9 +3784,12 @@ smp_fetch_sc_get_gpt(const struct arg *args, struct sample *smp, const char *kw, if (stkctr_entry(stkctr)) { void *ptr; - ptr = stktable_data_ptr_idx(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GPT, idx); + ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GPT0); + if (!ptr) + ptr = stktable_data_ptr_idx(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GPT, 0); + if (!ptr) { - if (stkctr == &tmpstkctr) + if (decrefcnt) stktable_release(stkctr->table, stkctr_entry(stkctr)); return 0; /* parameter not stored */ } @@ -3764,7 +3800,7 @@ smp_fetch_sc_get_gpt(const struct arg *args, struct sample *smp, const char *kw, HA_RWLOCK_RDUNLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock); - if (stkctr == &tmpstkctr) + if (decrefcnt) stktable_release(stkctr->table, stkctr_entry(stkctr)); } return 1; @@ -3785,19 +3821,21 @@ smp_fetch_sc_get_gpt0(const struct arg *args, struct sample *smp, const char *kw if (!stkctr) return 0; + return smp_fetch_get_gpt0(stkctr, smp, (stkctr == &tmpstkctr) ? 1 : 0); +} + +static int smp_fetch_get_gpc(struct stkctr *stkctr, struct sample *smp, unsigned int idx, int decrefcnt) +{ smp->flags = SMP_F_VOL_TEST; smp->data.type = SMP_T_SINT; smp->data.u.sint = 0; - if (stkctr_entry(stkctr)) { + if (stkctr_entry(stkctr) != NULL) { void *ptr; - ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GPT0); - if (!ptr) - ptr = stktable_data_ptr_idx(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GPT, 0); - + ptr = stktable_data_ptr_idx(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GPC, idx); if (!ptr) { - if (stkctr == &tmpstkctr) + if (decrefcnt) stktable_release(stkctr->table, stkctr_entry(stkctr)); return 0; /* parameter not stored */ } @@ -3808,7 +3846,7 @@ smp_fetch_sc_get_gpt0(const struct arg *args, struct sample *smp, const char *kw HA_RWLOCK_RDUNLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock); - if (stkctr == &tmpstkctr) + if (decrefcnt) stktable_release(stkctr->table, stkctr_entry(stkctr)); } return 1; @@ -3833,6 +3871,11 @@ smp_fetch_sc_get_gpc(const struct arg *args, struct sample *smp, const char *kw, if (!stkctr) return 0; + return smp_fetch_get_gpc(stkctr, smp, idx, (stkctr == &tmpstkctr) ? 1 : 0); +} + +static int smp_fetch_get_gpc0(struct stkctr *stkctr, struct sample *smp, int decrefcnt) +{ smp->flags = SMP_F_VOL_TEST; smp->data.type = SMP_T_SINT; smp->data.u.sint = 0; @@ -3840,9 +3883,14 @@ smp_fetch_sc_get_gpc(const struct arg *args, struct sample *smp, const char *kw, if (stkctr_entry(stkctr) != NULL) { void *ptr; - ptr = stktable_data_ptr_idx(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GPC, idx); + ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GPC0); if (!ptr) { - if (stkctr == &tmpstkctr) + /* fallback on the gpc array */ + ptr = stktable_data_ptr_idx(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GPC, 0); + } + + if (!ptr) { + if (decrefcnt) stktable_release(stkctr->table, stkctr_entry(stkctr)); return 0; /* parameter not stored */ } @@ -3853,7 +3901,7 @@ smp_fetch_sc_get_gpc(const struct arg *args, struct sample *smp, const char *kw, HA_RWLOCK_RDUNLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock); - if (stkctr == &tmpstkctr) + if (decrefcnt) stktable_release(stkctr->table, stkctr_entry(stkctr)); } return 1; @@ -3874,6 +3922,11 @@ smp_fetch_sc_get_gpc0(const struct arg *args, struct sample *smp, const char *kw if (!stkctr) return 0; + return smp_fetch_get_gpc0(stkctr, smp, (stkctr == &tmpstkctr) ? 1 : 0); +} + +static int smp_fetch_get_gpc1(struct stkctr *stkctr, struct sample *smp, int decrefcnt) +{ smp->flags = SMP_F_VOL_TEST; smp->data.type = SMP_T_SINT; smp->data.u.sint = 0; @@ -3881,14 +3934,14 @@ smp_fetch_sc_get_gpc0(const struct arg *args, struct sample *smp, const char *kw if (stkctr_entry(stkctr) != NULL) { void *ptr; - ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GPC0); + ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GPC1); if (!ptr) { /* fallback on the gpc array */ - ptr = stktable_data_ptr_idx(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GPC, 0); + ptr = stktable_data_ptr_idx(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GPC, 1); } if (!ptr) { - if (stkctr == &tmpstkctr) + if (decrefcnt) stktable_release(stkctr->table, stkctr_entry(stkctr)); return 0; /* parameter not stored */ } @@ -3899,7 +3952,7 @@ smp_fetch_sc_get_gpc0(const struct arg *args, struct sample *smp, const char *kw HA_RWLOCK_RDUNLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock); - if (stkctr == &tmpstkctr) + if (decrefcnt) stktable_release(stkctr->table, stkctr_entry(stkctr)); } return 1; @@ -3920,32 +3973,32 @@ smp_fetch_sc_get_gpc1(const struct arg *args, struct sample *smp, const char *kw if (!stkctr) return 0; + return smp_fetch_get_gpc1(stkctr, smp, (stkctr == &tmpstkctr) ? 1 : 0); +} + +static int smp_fetch_gpc_rate(struct stkctr *stkctr, struct sample *smp, unsigned int idx, int decrefcnt) +{ smp->flags = SMP_F_VOL_TEST; smp->data.type = SMP_T_SINT; smp->data.u.sint = 0; - if (stkctr_entry(stkctr) != NULL) { void *ptr; - ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GPC1); - if (!ptr) { - /* fallback on the gpc array */ - ptr = stktable_data_ptr_idx(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GPC, 1); - } - + ptr = stktable_data_ptr_idx(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GPC_RATE, idx); if (!ptr) { - if (stkctr == &tmpstkctr) + if (decrefcnt) stktable_release(stkctr->table, stkctr_entry(stkctr)); return 0; /* parameter not stored */ } HA_RWLOCK_RDLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock); - smp->data.u.sint = stktable_data_cast(ptr, std_t_uint); + smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, std_t_frqp), + stkctr->table->data_arg[STKTABLE_DT_GPC_RATE].u); HA_RWLOCK_RDUNLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock); - if (stkctr == &tmpstkctr) + if (decrefcnt) stktable_release(stkctr->table, stkctr_entry(stkctr)); } return 1; @@ -3970,48 +4023,13 @@ smp_fetch_sc_gpc_rate(const struct arg *args, struct sample *smp, const char *kw if (!stkctr) return 0; - smp->flags = SMP_F_VOL_TEST; - smp->data.type = SMP_T_SINT; - smp->data.u.sint = 0; - if (stkctr_entry(stkctr) != NULL) { - void *ptr; - - ptr = stktable_data_ptr_idx(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GPC_RATE, idx); - if (!ptr) { - if (stkctr == &tmpstkctr) - stktable_release(stkctr->table, stkctr_entry(stkctr)); - return 0; /* parameter not stored */ - } - - HA_RWLOCK_RDLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock); - - smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, std_t_frqp), - stkctr->table->data_arg[STKTABLE_DT_GPC_RATE].u); - - HA_RWLOCK_RDUNLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock); - - if (stkctr == &tmpstkctr) - stktable_release(stkctr->table, stkctr_entry(stkctr)); - } - return 1; + return smp_fetch_gpc_rate(stkctr, smp, idx, (stkctr == &tmpstkctr) ? 1 : 0); } -/* set to the General Purpose Counter 0's event rate from the stream's - * tracked frontend counters or from the src. - * Supports being called as "sc[0-9]_gpc0_rate" or "src_gpc0_rate" only. - * Value zero is returned if the key is new. - */ -static int -smp_fetch_sc_gpc0_rate(const struct arg *args, struct sample *smp, const char *kw, void *private) +static int smp_fetch_gpc0_rate(struct stkctr *stkctr, struct sample *smp, int decrefcnt) { - struct stkctr tmpstkctr; - struct stkctr *stkctr; unsigned int period; - stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw, &tmpstkctr); - if (!stkctr) - return 0; - smp->flags = SMP_F_VOL_TEST; smp->data.type = SMP_T_SINT; smp->data.u.sint = 0; @@ -4030,7 +4048,7 @@ smp_fetch_sc_gpc0_rate(const struct arg *args, struct sample *smp, const char *k } if (!ptr) { - if (stkctr == &tmpstkctr) + if (decrefcnt) stktable_release(stkctr->table, stkctr_entry(stkctr)); return 0; /* parameter not stored */ } @@ -4041,28 +4059,34 @@ smp_fetch_sc_gpc0_rate(const struct arg *args, struct sample *smp, const char *k HA_RWLOCK_RDUNLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock); - if (stkctr == &tmpstkctr) + if (decrefcnt) stktable_release(stkctr->table, stkctr_entry(stkctr)); } return 1; } -/* set to the General Purpose Counter 1's event rate from the stream's +/* set to the General Purpose Counter 0's event rate from the stream's * tracked frontend counters or from the src. - * Supports being called as "sc[0-9]_gpc1_rate" or "src_gpc1_rate" only. + * Supports being called as "sc[0-9]_gpc0_rate" or "src_gpc0_rate" only. * Value zero is returned if the key is new. */ static int -smp_fetch_sc_gpc1_rate(const struct arg *args, struct sample *smp, const char *kw, void *private) +smp_fetch_sc_gpc0_rate(const struct arg *args, struct sample *smp, const char *kw, void *private) { struct stkctr tmpstkctr; struct stkctr *stkctr; - unsigned int period; stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw, &tmpstkctr); if (!stkctr) return 0; + return smp_fetch_gpc0_rate(stkctr, smp, (stkctr == &tmpstkctr) ? 1 : 0); +} + +static int smp_fetch_gpc1_rate(struct stkctr *stkctr, struct sample *smp, int decrefcnt) +{ + unsigned int period; + smp->flags = SMP_F_VOL_TEST; smp->data.type = SMP_T_SINT; smp->data.u.sint = 0; @@ -4081,7 +4105,7 @@ smp_fetch_sc_gpc1_rate(const struct arg *args, struct sample *smp, const char *k } if (!ptr) { - if (stkctr == &tmpstkctr) + if (decrefcnt) stktable_release(stkctr->table, stkctr_entry(stkctr)); return 0; /* parameter not stored */ } @@ -4092,37 +4116,36 @@ smp_fetch_sc_gpc1_rate(const struct arg *args, struct sample *smp, const char *k HA_RWLOCK_RDUNLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock); - if (stkctr == &tmpstkctr) + if (decrefcnt) stktable_release(stkctr->table, stkctr_entry(stkctr)); } return 1; } -/* Increment the GPC[args(0)] value from the stream's tracked - * frontend counters and return it into temp integer. - * Supports being called as "sc_inc_gpc(,[,
])" - * or "src_inc_gpc([,
])" only. +/* set to the General Purpose Counter 1's event rate from the stream's + * tracked frontend counters or from the src. + * Supports being called as "sc[0-9]_gpc1_rate" or "src_gpc1_rate" only. + * Value zero is returned if the key is new. */ static int -smp_fetch_sc_inc_gpc(const struct arg *args, struct sample *smp, const char *kw, void *private) +smp_fetch_sc_gpc1_rate(const struct arg *args, struct sample *smp, const char *kw, void *private) { struct stkctr tmpstkctr; struct stkctr *stkctr; - unsigned int idx; - - idx = args[0].data.sint; - stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args + 1, kw, &tmpstkctr); + stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw, &tmpstkctr); if (!stkctr) return 0; + return smp_fetch_gpc1_rate(stkctr, smp, (stkctr == &tmpstkctr) ? 1 : 0); +} + +static int smp_fetch_inc_gpc(struct stkctr *stkctr, struct sample *smp, unsigned int idx, int decrefcnt) +{ smp->flags = SMP_F_VOL_TEST; smp->data.type = SMP_T_SINT; smp->data.u.sint = 0; - if (!stkctr_entry(stkctr)) - stkctr = smp_create_src_stkctr(smp->sess, smp->strm, args + 1, kw, &tmpstkctr); - if (stkctr && stkctr_entry(stkctr)) { void *ptr1,*ptr2; @@ -4147,36 +4170,47 @@ smp_fetch_sc_inc_gpc(const struct arg *args, struct sample *smp, const char *kw, HA_RWLOCK_WRUNLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock); /* If data was modified, we need to touch to re-schedule sync */ - stktable_touch_local(stkctr->table, stkctr_entry(stkctr), (stkctr == &tmpstkctr) ? 1 : 0); + stktable_touch_local(stkctr->table, stkctr_entry(stkctr), decrefcnt); } - else if (stkctr == &tmpstkctr) + else if (decrefcnt) stktable_release(stkctr->table, stkctr_entry(stkctr)); } return 1; } -/* Increment the General Purpose Counter 0 value from the stream's tracked +/* Increment the GPC[args(0)] value from the stream's tracked * frontend counters and return it into temp integer. - * Supports being called as "sc[0-9]_inc_gpc0" or "src_inc_gpc0" only. + * Supports being called as "sc_inc_gpc(,[,
])" + * or "src_inc_gpc([,
])" only. */ static int -smp_fetch_sc_inc_gpc0(const struct arg *args, struct sample *smp, const char *kw, void *private) +smp_fetch_sc_inc_gpc(const struct arg *args, struct sample *smp, const char *kw, void *private) { struct stkctr tmpstkctr; struct stkctr *stkctr; - unsigned int period = 0; + unsigned int idx; - stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw, &tmpstkctr); + idx = args[0].data.sint; + + stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args + 1, kw, &tmpstkctr); if (!stkctr) return 0; + if (!stkctr_entry(stkctr)) + stkctr = smp_create_src_stkctr(smp->sess, smp->strm, args + 1, kw, &tmpstkctr); + + return smp_fetch_inc_gpc(stkctr, smp, idx, (stkctr == &tmpstkctr) ? 1 : 0); +} + + +static int smp_fetch_inc_gpc0(struct stkctr *stkctr, struct sample *smp, int decrefcnt) +{ + unsigned int period = 0; + smp->flags = SMP_F_VOL_TEST; smp->data.type = SMP_T_SINT; smp->data.u.sint = 0; - if (!stkctr_entry(stkctr)) - stkctr = smp_create_src_stkctr(smp->sess, smp->strm, args, kw, &tmpstkctr); - if (stkctr && stkctr_entry(stkctr)) { void *ptr1,*ptr2; @@ -4216,36 +4250,42 @@ smp_fetch_sc_inc_gpc0(const struct arg *args, struct sample *smp, const char *kw HA_RWLOCK_WRUNLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock); /* If data was modified, we need to touch to re-schedule sync */ - stktable_touch_local(stkctr->table, stkctr_entry(stkctr), (stkctr == &tmpstkctr) ? 1 : 0); + stktable_touch_local(stkctr->table, stkctr_entry(stkctr), decrefcnt); } - else if (stkctr == &tmpstkctr) + else if (decrefcnt) stktable_release(stkctr->table, stkctr_entry(stkctr)); } return 1; } -/* Increment the General Purpose Counter 1 value from the stream's tracked +/* Increment the General Purpose Counter 0 value from the stream's tracked * frontend counters and return it into temp integer. - * Supports being called as "sc[0-9]_inc_gpc1" or "src_inc_gpc1" only. + * Supports being called as "sc[0-9]_inc_gpc0" or "src_inc_gpc0" only. */ static int -smp_fetch_sc_inc_gpc1(const struct arg *args, struct sample *smp, const char *kw, void *private) +smp_fetch_sc_inc_gpc0(const struct arg *args, struct sample *smp, const char *kw, void *private) { struct stkctr tmpstkctr; struct stkctr *stkctr; - unsigned int period = 0; stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw, &tmpstkctr); if (!stkctr) return 0; + if (!stkctr_entry(stkctr)) + stkctr = smp_create_src_stkctr(smp->sess, smp->strm, args, kw, &tmpstkctr); + + return smp_fetch_inc_gpc0(stkctr, smp, (stkctr == &tmpstkctr) ? 1 : 0); +} + +static int smp_fetch_inc_gpc1(struct stkctr *stkctr, struct sample *smp, int decrefcnt) +{ + unsigned int period = 0; + smp->flags = SMP_F_VOL_TEST; smp->data.type = SMP_T_SINT; smp->data.u.sint = 0; - if (!stkctr_entry(stkctr)) - stkctr = smp_create_src_stkctr(smp->sess, smp->strm, args, kw, &tmpstkctr); - if (stkctr && stkctr_entry(stkctr)) { void *ptr1,*ptr2; @@ -4285,14 +4325,63 @@ smp_fetch_sc_inc_gpc1(const struct arg *args, struct sample *smp, const char *kw HA_RWLOCK_WRUNLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock); /* If data was modified, we need to touch to re-schedule sync */ - stktable_touch_local(stkctr->table, stkctr_entry(stkctr), (stkctr == &tmpstkctr) ? 1 : 0); + stktable_touch_local(stkctr->table, stkctr_entry(stkctr), (decrefcnt) ? 1 : 0); } - else if (stkctr == &tmpstkctr) + else if (decrefcnt) stktable_release(stkctr->table, stkctr_entry(stkctr)); } return 1; } +/* Increment the General Purpose Counter 1 value from the stream's tracked + * frontend counters and return it into temp integer. + * Supports being called as "sc[0-9]_inc_gpc1" or "src_inc_gpc1" only. + */ +static int +smp_fetch_sc_inc_gpc1(const struct arg *args, struct sample *smp, const char *kw, void *private) +{ + struct stkctr tmpstkctr; + struct stkctr *stkctr; + + stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw, &tmpstkctr); + if (!stkctr) + return 0; + + if (!stkctr_entry(stkctr)) + stkctr = smp_create_src_stkctr(smp->sess, smp->strm, args, kw, &tmpstkctr); + + return smp_fetch_inc_gpc1(stkctr, smp, (stkctr == &tmpstkctr) ? 1 : 0); +} + +static int smp_fetch_clr_gpc(struct stkctr *stkctr, struct sample *smp, unsigned int idx, int decrefcnt) +{ + smp->flags = SMP_F_VOL_TEST; + smp->data.type = SMP_T_SINT; + smp->data.u.sint = 0; + + if (stkctr && stkctr_entry(stkctr)) { + void *ptr; + + ptr = stktable_data_ptr_idx(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GPC, idx); + if (!ptr) { + if (decrefcnt) + stktable_release(stkctr->table, stkctr_entry(stkctr)); + return 0; /* parameter not stored */ + } + + HA_RWLOCK_WRLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock); + + smp->data.u.sint = stktable_data_cast(ptr, std_t_uint); + stktable_data_cast(ptr, std_t_uint) = 0; + + HA_RWLOCK_WRUNLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock); + + /* If data was modified, we need to touch to re-schedule sync */ + stktable_touch_local(stkctr->table, stkctr_entry(stkctr), decrefcnt); + } + return 1; +} + /* Clear the GPC[args(0)] value from the stream's tracked * frontend counters and return its previous value into temp integer. * Supports being called as "sc_clr_gpc(,[,
])" @@ -4311,19 +4400,29 @@ smp_fetch_sc_clr_gpc(const struct arg *args, struct sample *smp, const char *kw, if (!stkctr) return 0; + if (!stkctr_entry(stkctr)) + stkctr = smp_create_src_stkctr(smp->sess, smp->strm, args, kw, &tmpstkctr); + + return smp_fetch_clr_gpc(stkctr, smp, idx, (stkctr == &tmpstkctr) ? 1 : 0); +} + +static int smp_fetch_clr_gpc0(struct stkctr *stkctr, struct sample *smp, int decrefcnt) +{ smp->flags = SMP_F_VOL_TEST; smp->data.type = SMP_T_SINT; smp->data.u.sint = 0; - if (!stkctr_entry(stkctr)) - stkctr = smp_create_src_stkctr(smp->sess, smp->strm, args, kw, &tmpstkctr); - if (stkctr && stkctr_entry(stkctr)) { void *ptr; - ptr = stktable_data_ptr_idx(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GPC, idx); + ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GPC0); if (!ptr) { - if (stkctr == &tmpstkctr) + /* fallback on the gpc array */ + ptr = stktable_data_ptr_idx(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GPC, 0); + } + + if (!ptr) { + if (decrefcnt) stktable_release(stkctr->table, stkctr_entry(stkctr)); return 0; /* parameter not stored */ } @@ -4336,7 +4435,7 @@ smp_fetch_sc_clr_gpc(const struct arg *args, struct sample *smp, const char *kw, HA_RWLOCK_WRUNLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock); /* If data was modified, we need to touch to re-schedule sync */ - stktable_touch_local(stkctr->table, stkctr_entry(stkctr), (stkctr == &tmpstkctr) ? 1 : 0); + stktable_touch_local(stkctr->table, stkctr_entry(stkctr), decrefcnt); } return 1; } @@ -4355,24 +4454,29 @@ smp_fetch_sc_clr_gpc0(const struct arg *args, struct sample *smp, const char *kw if (!stkctr) return 0; + if (!stkctr_entry(stkctr)) + stkctr = smp_create_src_stkctr(smp->sess, smp->strm, args, kw, &tmpstkctr); + + return smp_fetch_clr_gpc0(stkctr, smp, (stkctr == &tmpstkctr) ? 1 : 0); +} + +static int smp_fetch_clr_gpc1(struct stkctr *stkctr, struct sample *smp, int decrefcnt) +{ smp->flags = SMP_F_VOL_TEST; smp->data.type = SMP_T_SINT; smp->data.u.sint = 0; - if (!stkctr_entry(stkctr)) - stkctr = smp_create_src_stkctr(smp->sess, smp->strm, args, kw, &tmpstkctr); - if (stkctr && stkctr_entry(stkctr)) { void *ptr; - ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GPC0); + ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GPC1); if (!ptr) { /* fallback on the gpc array */ - ptr = stktable_data_ptr_idx(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GPC, 0); + ptr = stktable_data_ptr_idx(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GPC, 1); } if (!ptr) { - if (stkctr == &tmpstkctr) + if (decrefcnt) stktable_release(stkctr->table, stkctr_entry(stkctr)); return 0; /* parameter not stored */ } @@ -4385,7 +4489,7 @@ smp_fetch_sc_clr_gpc0(const struct arg *args, struct sample *smp, const char *kw HA_RWLOCK_WRUNLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock); /* If data was modified, we need to touch to re-schedule sync */ - stktable_touch_local(stkctr->table, stkctr_entry(stkctr), (stkctr == &tmpstkctr) ? 1 : 0); + stktable_touch_local(stkctr->table, stkctr_entry(stkctr), decrefcnt); } return 1; } @@ -4404,37 +4508,37 @@ smp_fetch_sc_clr_gpc1(const struct arg *args, struct sample *smp, const char *kw if (!stkctr) return 0; - smp->flags = SMP_F_VOL_TEST; - smp->data.type = SMP_T_SINT; - smp->data.u.sint = 0; - if (!stkctr_entry(stkctr)) stkctr = smp_create_src_stkctr(smp->sess, smp->strm, args, kw, &tmpstkctr); - if (stkctr && stkctr_entry(stkctr)) { + return smp_fetch_clr_gpc1(stkctr, smp, (stkctr == &tmpstkctr) ? 1 : 0); +} + +static int smp_fetch_conn_cnt(struct stkctr *stkctr, struct sample *smp, int decrefcnt) +{ + smp->flags = SMP_F_VOL_TEST; + smp->data.type = SMP_T_SINT; + smp->data.u.sint = 0; + if (stkctr_entry(stkctr) != NULL) { void *ptr; - ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GPC1); - if (!ptr) { - /* fallback on the gpc array */ - ptr = stktable_data_ptr_idx(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GPC, 1); - } - + ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_CONN_CNT); if (!ptr) { - if (stkctr == &tmpstkctr) + if (decrefcnt) stktable_release(stkctr->table, stkctr_entry(stkctr)); return 0; /* parameter not stored */ } - HA_RWLOCK_WRLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock); + HA_RWLOCK_RDLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock); smp->data.u.sint = stktable_data_cast(ptr, std_t_uint); - stktable_data_cast(ptr, std_t_uint) = 0; - HA_RWLOCK_WRUNLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock); + HA_RWLOCK_RDUNLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock); + + if (decrefcnt) + stktable_release(stkctr->table, stkctr_entry(stkctr)); + - /* If data was modified, we need to touch to re-schedule sync */ - stktable_touch_local(stkctr->table, stkctr_entry(stkctr), (stkctr == &tmpstkctr) ? 1 : 0); } return 1; } @@ -4453,29 +4557,33 @@ smp_fetch_sc_conn_cnt(const struct arg *args, struct sample *smp, const char *kw if (!stkctr) return 0; + return smp_fetch_conn_cnt(stkctr, smp, (stkctr == &tmpstkctr) ? 1 : 0); +} + +static int smp_fetch_conn_rate(struct stkctr *stkctr, struct sample *smp, int decrefcnt) +{ smp->flags = SMP_F_VOL_TEST; smp->data.type = SMP_T_SINT; smp->data.u.sint = 0; if (stkctr_entry(stkctr) != NULL) { void *ptr; - ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_CONN_CNT); + ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_CONN_RATE); if (!ptr) { - if (stkctr == &tmpstkctr) + if (decrefcnt) stktable_release(stkctr->table, stkctr_entry(stkctr)); return 0; /* parameter not stored */ } HA_RWLOCK_RDLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock); - smp->data.u.sint = stktable_data_cast(ptr, std_t_uint); + smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, std_t_frqp), + stkctr->table->data_arg[STKTABLE_DT_CONN_RATE].u); HA_RWLOCK_RDUNLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock); - if (stkctr == &tmpstkctr) + if (decrefcnt) stktable_release(stkctr->table, stkctr_entry(stkctr)); - - } return 1; } @@ -4494,29 +4602,34 @@ smp_fetch_sc_conn_rate(const struct arg *args, struct sample *smp, const char *k if (!stkctr) return 0; - smp->flags = SMP_F_VOL_TEST; + return smp_fetch_conn_rate(stkctr, smp, (stkctr == &tmpstkctr) ? 1 : 0); +} + +static int smp_fetch_updt_conn_cnt(struct stkctr *stkctr, struct sample *smp) +{ + void *ptr; + + if (!stkctr_entry(stkctr)) + return 0; /* not found */ + + ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_CONN_CNT); + if (!ptr) { + return 0; /* parameter not stored in this table */ + } + smp->data.type = SMP_T_SINT; - smp->data.u.sint = 0; - if (stkctr_entry(stkctr) != NULL) { - void *ptr; - ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_CONN_RATE); - if (!ptr) { - if (stkctr == &tmpstkctr) - stktable_release(stkctr->table, stkctr_entry(stkctr)); - return 0; /* parameter not stored */ - } + HA_RWLOCK_WRLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock); - HA_RWLOCK_RDLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock); + smp->data.u.sint = ++stktable_data_cast(ptr, std_t_uint); - smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, std_t_frqp), - stkctr->table->data_arg[STKTABLE_DT_CONN_RATE].u); + HA_RWLOCK_WRUNLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock); - HA_RWLOCK_RDUNLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock); + smp->flags = SMP_F_VOL_TEST; - if (stkctr == &tmpstkctr) - stktable_release(stkctr->table, stkctr_entry(stkctr)); - } + stktable_touch_local(stkctr->table, stkctr_entry(stkctr), 1); + + /* Touch was previously performed by stktable_update_key */ return 1; } @@ -4529,8 +4642,7 @@ smp_fetch_src_updt_conn_cnt(const struct arg *args, struct sample *smp, const ch { struct connection *conn = objt_conn(smp->sess->origin); struct stksess *ts; - void *ptr; - struct stktable *t; + struct stkctr tmpstkctr; if (!conn) return 0; @@ -4539,30 +4651,41 @@ smp_fetch_src_updt_conn_cnt(const struct arg *args, struct sample *smp, const ch if (!smp_fetch_src || !smp_fetch_src(empty_arg_list, smp, "src", NULL)) return 0; - t = args->data.t; + tmpstkctr.table = args->data.t; - if ((ts = smp_fetch_stksess(t, smp, 1)) == NULL) + if ((ts = smp_fetch_stksess(args->data.t, smp, 1)) == NULL) /* entry does not exist and could not be created */ return 0; - ptr = stktable_data_ptr(t, ts, STKTABLE_DT_CONN_CNT); - if (!ptr) { - return 0; /* parameter not stored in this table */ - } + stkctr_set_entry(&tmpstkctr, ts); - smp->data.type = SMP_T_SINT; + return smp_fetch_updt_conn_cnt(&tmpstkctr, smp); +} - HA_RWLOCK_WRLOCK(STK_SESS_LOCK, &ts->lock); +static int smp_fetch_conn_cur(struct stkctr *stkctr, struct sample *smp, int decrefcnt) +{ + smp->flags = SMP_F_VOL_TEST; + smp->data.type = SMP_T_SINT; + smp->data.u.sint = 0; + if (stkctr_entry(stkctr) != NULL) { + void *ptr; - smp->data.u.sint = ++stktable_data_cast(ptr, std_t_uint); + ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_CONN_CUR); + if (!ptr) { + if (decrefcnt) + stktable_release(stkctr->table, stkctr_entry(stkctr)); + return 0; /* parameter not stored */ + } - HA_RWLOCK_WRUNLOCK(STK_SESS_LOCK, &ts->lock); + HA_RWLOCK_RDLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock); - smp->flags = SMP_F_VOL_TEST; + smp->data.u.sint = stktable_data_cast(ptr, std_t_uint); - stktable_touch_local(t, ts, 1); + HA_RWLOCK_RDUNLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock); - /* Touch was previously performed by stktable_update_key */ + if (decrefcnt) + stktable_release(stkctr->table, stkctr_entry(stkctr)); + } return 1; } @@ -4580,15 +4703,20 @@ smp_fetch_sc_conn_cur(const struct arg *args, struct sample *smp, const char *kw if (!stkctr) return 0; + return smp_fetch_conn_cur(stkctr, smp, (stkctr == &tmpstkctr) ? 1 : 0); +} + +static int smp_fetch_glitch_cnt(struct stkctr *stkctr, struct sample *smp, int decrefcnt) +{ smp->flags = SMP_F_VOL_TEST; smp->data.type = SMP_T_SINT; smp->data.u.sint = 0; if (stkctr_entry(stkctr) != NULL) { void *ptr; - ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_CONN_CUR); + ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GLITCH_CNT); if (!ptr) { - if (stkctr == &tmpstkctr) + if (decrefcnt) stktable_release(stkctr->table, stkctr_entry(stkctr)); return 0; /* parameter not stored */ } @@ -4599,7 +4727,7 @@ smp_fetch_sc_conn_cur(const struct arg *args, struct sample *smp, const char *kw HA_RWLOCK_RDUNLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock); - if (stkctr == &tmpstkctr) + if (decrefcnt) stktable_release(stkctr->table, stkctr_entry(stkctr)); } return 1; @@ -4619,26 +4747,32 @@ smp_fetch_sc_glitch_cnt(const struct arg *args, struct sample *smp, const char * if (!stkctr) return 0; + return smp_fetch_glitch_cnt(stkctr, smp, (stkctr == &tmpstkctr) ? 1 : 0); +} + +static int smp_fetch_glitch_rate(struct stkctr *stkctr, struct sample *smp, int decrefcnt) +{ smp->flags = SMP_F_VOL_TEST; smp->data.type = SMP_T_SINT; smp->data.u.sint = 0; if (stkctr_entry(stkctr) != NULL) { void *ptr; - ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GLITCH_CNT); + ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GLITCH_RATE); if (!ptr) { - if (stkctr == &tmpstkctr) + if (decrefcnt) stktable_release(stkctr->table, stkctr_entry(stkctr)); return 0; /* parameter not stored */ } HA_RWLOCK_RDLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock); - smp->data.u.sint = stktable_data_cast(ptr, std_t_uint); + smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, std_t_frqp), + stkctr->table->data_arg[STKTABLE_DT_GLITCH_RATE].u); HA_RWLOCK_RDUNLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock); - if (stkctr == &tmpstkctr) + if (decrefcnt) stktable_release(stkctr->table, stkctr_entry(stkctr)); } return 1; @@ -4658,27 +4792,31 @@ smp_fetch_sc_glitch_rate(const struct arg *args, struct sample *smp, const char if (!stkctr) return 0; + return smp_fetch_glitch_rate(stkctr, smp, (stkctr == &tmpstkctr) ? 1 : 0); +} + +static int smp_fetch_sess_cnt(struct stkctr *stkctr, struct sample *smp, int decrefcnt) +{ smp->flags = SMP_F_VOL_TEST; smp->data.type = SMP_T_SINT; smp->data.u.sint = 0; if (stkctr_entry(stkctr) != NULL) { void *ptr; - ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GLITCH_RATE); + ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_SESS_CNT); if (!ptr) { - if (stkctr == &tmpstkctr) + if (decrefcnt) stktable_release(stkctr->table, stkctr_entry(stkctr)); return 0; /* parameter not stored */ } HA_RWLOCK_RDLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock); - smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, std_t_frqp), - stkctr->table->data_arg[STKTABLE_DT_GLITCH_RATE].u); + smp->data.u.sint = stktable_data_cast(ptr, std_t_uint); HA_RWLOCK_RDUNLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock); - if (stkctr == &tmpstkctr) + if (decrefcnt) stktable_release(stkctr->table, stkctr_entry(stkctr)); } return 1; @@ -4698,26 +4836,32 @@ smp_fetch_sc_sess_cnt(const struct arg *args, struct sample *smp, const char *kw if (!stkctr) return 0; + return smp_fetch_sess_cnt(stkctr, smp, (stkctr == &tmpstkctr) ? 1 : 0); +} + +static int smp_fetch_sess_rate(struct stkctr *stkctr, struct sample *smp, int decrefcnt) +{ smp->flags = SMP_F_VOL_TEST; smp->data.type = SMP_T_SINT; smp->data.u.sint = 0; if (stkctr_entry(stkctr) != NULL) { void *ptr; - ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_SESS_CNT); + ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_SESS_RATE); if (!ptr) { - if (stkctr == &tmpstkctr) + if (decrefcnt) stktable_release(stkctr->table, stkctr_entry(stkctr)); return 0; /* parameter not stored */ } HA_RWLOCK_RDLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock); - smp->data.u.sint = stktable_data_cast(ptr, std_t_uint); + smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, std_t_frqp), + stkctr->table->data_arg[STKTABLE_DT_SESS_RATE].u); HA_RWLOCK_RDUNLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock); - if (stkctr == &tmpstkctr) + if (decrefcnt) stktable_release(stkctr->table, stkctr_entry(stkctr)); } return 1; @@ -4736,27 +4880,31 @@ smp_fetch_sc_sess_rate(const struct arg *args, struct sample *smp, const char *k if (!stkctr) return 0; + return smp_fetch_sess_rate(stkctr, smp, (stkctr == &tmpstkctr) ? 1 : 0); +} + +static int smp_fetch_http_req_cnt(struct stkctr *stkctr, struct sample *smp, int decrefcnt) +{ smp->flags = SMP_F_VOL_TEST; smp->data.type = SMP_T_SINT; smp->data.u.sint = 0; if (stkctr_entry(stkctr) != NULL) { void *ptr; - ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_SESS_RATE); + ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_HTTP_REQ_CNT); if (!ptr) { - if (stkctr == &tmpstkctr) + if (decrefcnt) stktable_release(stkctr->table, stkctr_entry(stkctr)); return 0; /* parameter not stored */ } HA_RWLOCK_RDLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock); - smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, std_t_frqp), - stkctr->table->data_arg[STKTABLE_DT_SESS_RATE].u); + smp->data.u.sint = stktable_data_cast(ptr, std_t_uint); HA_RWLOCK_RDUNLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock); - if (stkctr == &tmpstkctr) + if (decrefcnt) stktable_release(stkctr->table, stkctr_entry(stkctr)); } return 1; @@ -4776,26 +4924,32 @@ smp_fetch_sc_http_req_cnt(const struct arg *args, struct sample *smp, const char if (!stkctr) return 0; + return smp_fetch_http_req_cnt(stkctr, smp, (stkctr == &tmpstkctr) ? 1 : 0); +} + +static int smp_fetch_http_req_rate(struct stkctr *stkctr, struct sample *smp, int decrefcnt) +{ smp->flags = SMP_F_VOL_TEST; smp->data.type = SMP_T_SINT; smp->data.u.sint = 0; if (stkctr_entry(stkctr) != NULL) { void *ptr; - ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_HTTP_REQ_CNT); + ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_HTTP_REQ_RATE); if (!ptr) { - if (stkctr == &tmpstkctr) + if (decrefcnt) stktable_release(stkctr->table, stkctr_entry(stkctr)); return 0; /* parameter not stored */ } HA_RWLOCK_RDLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock); - smp->data.u.sint = stktable_data_cast(ptr, std_t_uint); + smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, std_t_frqp), + stkctr->table->data_arg[STKTABLE_DT_HTTP_REQ_RATE].u); HA_RWLOCK_RDUNLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock); - if (stkctr == &tmpstkctr) + if (decrefcnt) stktable_release(stkctr->table, stkctr_entry(stkctr)); } return 1; @@ -4815,27 +4969,31 @@ smp_fetch_sc_http_req_rate(const struct arg *args, struct sample *smp, const cha if (!stkctr) return 0; + return smp_fetch_http_req_rate(stkctr, smp, (stkctr == &tmpstkctr) ? 1 : 0); +} + +static int smp_fetch_http_err_cnt(struct stkctr *stkctr, struct sample *smp, int decrefcnt) +{ smp->flags = SMP_F_VOL_TEST; smp->data.type = SMP_T_SINT; smp->data.u.sint = 0; if (stkctr_entry(stkctr) != NULL) { void *ptr; - ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_HTTP_REQ_RATE); + ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_HTTP_ERR_CNT); if (!ptr) { - if (stkctr == &tmpstkctr) + if (decrefcnt) stktable_release(stkctr->table, stkctr_entry(stkctr)); return 0; /* parameter not stored */ } HA_RWLOCK_RDLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock); - smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, std_t_frqp), - stkctr->table->data_arg[STKTABLE_DT_HTTP_REQ_RATE].u); + smp->data.u.sint = stktable_data_cast(ptr, std_t_uint); HA_RWLOCK_RDUNLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock); - if (stkctr == &tmpstkctr) + if (decrefcnt) stktable_release(stkctr->table, stkctr_entry(stkctr)); } return 1; @@ -4855,26 +5013,32 @@ smp_fetch_sc_http_err_cnt(const struct arg *args, struct sample *smp, const char if (!stkctr) return 0; + return smp_fetch_http_err_cnt(stkctr, smp, (stkctr == &tmpstkctr) ? 1 : 0); +} + +static int smp_fetch_http_err_rate(struct stkctr *stkctr, struct sample *smp, int decrefcnt) +{ smp->flags = SMP_F_VOL_TEST; smp->data.type = SMP_T_SINT; smp->data.u.sint = 0; if (stkctr_entry(stkctr) != NULL) { void *ptr; - ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_HTTP_ERR_CNT); + ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_HTTP_ERR_RATE); if (!ptr) { - if (stkctr == &tmpstkctr) + if (decrefcnt) stktable_release(stkctr->table, stkctr_entry(stkctr)); return 0; /* parameter not stored */ } HA_RWLOCK_RDLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock); - smp->data.u.sint = stktable_data_cast(ptr, std_t_uint); + smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, std_t_frqp), + stkctr->table->data_arg[STKTABLE_DT_HTTP_ERR_RATE].u); HA_RWLOCK_RDUNLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock); - if (stkctr == &tmpstkctr) + if (decrefcnt) stktable_release(stkctr->table, stkctr_entry(stkctr)); } return 1; @@ -4894,27 +5058,31 @@ smp_fetch_sc_http_err_rate(const struct arg *args, struct sample *smp, const cha if (!stkctr) return 0; + return smp_fetch_http_err_rate(stkctr, smp, (stkctr == &tmpstkctr) ? 1 : 0); +} + +static int smp_fetch_http_fail_cnt(struct stkctr *stkctr, struct sample *smp, int decrefcnt) +{ smp->flags = SMP_F_VOL_TEST; smp->data.type = SMP_T_SINT; smp->data.u.sint = 0; if (stkctr_entry(stkctr) != NULL) { void *ptr; - ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_HTTP_ERR_RATE); + ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_HTTP_FAIL_CNT); if (!ptr) { - if (stkctr == &tmpstkctr) + if (decrefcnt) stktable_release(stkctr->table, stkctr_entry(stkctr)); return 0; /* parameter not stored */ } HA_RWLOCK_RDLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock); - smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, std_t_frqp), - stkctr->table->data_arg[STKTABLE_DT_HTTP_ERR_RATE].u); + smp->data.u.sint = stktable_data_cast(ptr, std_t_uint); HA_RWLOCK_RDUNLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock); - if (stkctr == &tmpstkctr) + if (decrefcnt) stktable_release(stkctr->table, stkctr_entry(stkctr)); } return 1; @@ -4934,29 +5102,36 @@ smp_fetch_sc_http_fail_cnt(const struct arg *args, struct sample *smp, const cha if (!stkctr) return 0; + return smp_fetch_http_fail_cnt(stkctr, smp, (stkctr == &tmpstkctr) ? 1 : 0); +} + +static int smp_fetch_http_fail_rate(struct stkctr *stkctr, struct sample *smp, int decrefcnt) +{ smp->flags = SMP_F_VOL_TEST; smp->data.type = SMP_T_SINT; smp->data.u.sint = 0; if (stkctr_entry(stkctr) != NULL) { void *ptr; - ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_HTTP_FAIL_CNT); + ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_HTTP_FAIL_RATE); if (!ptr) { - if (stkctr == &tmpstkctr) + if (decrefcnt) stktable_release(stkctr->table, stkctr_entry(stkctr)); return 0; /* parameter not stored */ } HA_RWLOCK_RDLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock); - smp->data.u.sint = stktable_data_cast(ptr, std_t_uint); + smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, std_t_frqp), + stkctr->table->data_arg[STKTABLE_DT_HTTP_FAIL_RATE].u); HA_RWLOCK_RDUNLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock); - if (stkctr == &tmpstkctr) + if (decrefcnt) stktable_release(stkctr->table, stkctr_entry(stkctr)); } return 1; + } /* set to the HTTP response failure rate from the stream's tracked frontend @@ -4973,27 +5148,31 @@ smp_fetch_sc_http_fail_rate(const struct arg *args, struct sample *smp, const ch if (!stkctr) return 0; + return smp_fetch_http_fail_rate(stkctr, smp, (stkctr == &tmpstkctr) ? 1 : 0); +} + +static int smp_fetch_kbytes_in(struct stkctr *stkctr, struct sample *smp, int decrefcnt) +{ smp->flags = SMP_F_VOL_TEST; smp->data.type = SMP_T_SINT; smp->data.u.sint = 0; if (stkctr_entry(stkctr) != NULL) { void *ptr; - ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_HTTP_FAIL_RATE); + ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_BYTES_IN_CNT); if (!ptr) { - if (stkctr == &tmpstkctr) + if (decrefcnt) stktable_release(stkctr->table, stkctr_entry(stkctr)); return 0; /* parameter not stored */ } HA_RWLOCK_RDLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock); - smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, std_t_frqp), - stkctr->table->data_arg[STKTABLE_DT_HTTP_FAIL_RATE].u); + smp->data.u.sint = stktable_data_cast(ptr, std_t_ull) >> 10; HA_RWLOCK_RDUNLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock); - if (stkctr == &tmpstkctr) + if (decrefcnt) stktable_release(stkctr->table, stkctr_entry(stkctr)); } return 1; @@ -5013,26 +5192,32 @@ smp_fetch_sc_kbytes_in(const struct arg *args, struct sample *smp, const char *k if (!stkctr) return 0; + return smp_fetch_kbytes_in(stkctr, smp, (stkctr == &tmpstkctr) ? 1 : 0); +} + +static int smp_fetch_bytes_in_rate(struct stkctr *stkctr, struct sample *smp, int decrefcnt) +{ smp->flags = SMP_F_VOL_TEST; smp->data.type = SMP_T_SINT; smp->data.u.sint = 0; if (stkctr_entry(stkctr) != NULL) { void *ptr; - ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_BYTES_IN_CNT); + ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_BYTES_IN_RATE); if (!ptr) { - if (stkctr == &tmpstkctr) + if (decrefcnt) stktable_release(stkctr->table, stkctr_entry(stkctr)); return 0; /* parameter not stored */ } HA_RWLOCK_RDLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock); - smp->data.u.sint = stktable_data_cast(ptr, std_t_ull) >> 10; + smp->data.u.sint = (uint64_t)read_freq_ctr_period(&stktable_data_cast(ptr, std_t_frqp), + stkctr->table->data_arg[STKTABLE_DT_BYTES_IN_RATE].u) * stkctr->table->brates_factor; HA_RWLOCK_RDUNLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock); - if (stkctr == &tmpstkctr) + if (decrefcnt) stktable_release(stkctr->table, stkctr_entry(stkctr)); } return 1; @@ -5052,27 +5237,31 @@ smp_fetch_sc_bytes_in_rate(const struct arg *args, struct sample *smp, const cha if (!stkctr) return 0; + return smp_fetch_bytes_in_rate(stkctr, smp, (stkctr == &tmpstkctr) ? 1 : 0); +} + +static int smp_fetch_kbytes_out(struct stkctr *stkctr, struct sample *smp, int decrefcnt) +{ smp->flags = SMP_F_VOL_TEST; smp->data.type = SMP_T_SINT; smp->data.u.sint = 0; if (stkctr_entry(stkctr) != NULL) { void *ptr; - ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_BYTES_IN_RATE); + ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_BYTES_OUT_CNT); if (!ptr) { - if (stkctr == &tmpstkctr) + if (decrefcnt) stktable_release(stkctr->table, stkctr_entry(stkctr)); return 0; /* parameter not stored */ } HA_RWLOCK_RDLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock); - smp->data.u.sint = (uint64_t)read_freq_ctr_period(&stktable_data_cast(ptr, std_t_frqp), - stkctr->table->data_arg[STKTABLE_DT_BYTES_IN_RATE].u) * stkctr->table->brates_factor; + smp->data.u.sint = stktable_data_cast(ptr, std_t_ull) >> 10; HA_RWLOCK_RDUNLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock); - if (stkctr == &tmpstkctr) + if (decrefcnt) stktable_release(stkctr->table, stkctr_entry(stkctr)); } return 1; @@ -5092,29 +5281,7 @@ smp_fetch_sc_kbytes_out(const struct arg *args, struct sample *smp, const char * if (!stkctr) return 0; - smp->flags = SMP_F_VOL_TEST; - smp->data.type = SMP_T_SINT; - smp->data.u.sint = 0; - if (stkctr_entry(stkctr) != NULL) { - void *ptr; - - ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_BYTES_OUT_CNT); - if (!ptr) { - if (stkctr == &tmpstkctr) - stktable_release(stkctr->table, stkctr_entry(stkctr)); - return 0; /* parameter not stored */ - } - - HA_RWLOCK_RDLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock); - - smp->data.u.sint = stktable_data_cast(ptr, std_t_ull) >> 10; - - HA_RWLOCK_RDUNLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock); - - if (stkctr == &tmpstkctr) - stktable_release(stkctr->table, stkctr_entry(stkctr)); - } - return 1; + return smp_fetch_kbytes_out(stkctr, smp, (stkctr == &tmpstkctr) ? 1 : 0); } /* set to the key associated to the stream's tracked entry. @@ -5143,20 +5310,8 @@ smp_fetch_sc_key(const struct arg *args, struct sample *smp, const char *kw, voi return 0; /* nothing currently tracked */ } -/* set to the data rate sent to clients in bytes/s, as found in the - * stream's tracked frontend counters. Supports being called as - * "sc[0-9]_bytes_out_rate" or "src_bytes_out_rate" only. - */ -static int -smp_fetch_sc_bytes_out_rate(const struct arg *args, struct sample *smp, const char *kw, void *private) +static int smp_fetch_bytes_out_rate(struct stkctr *stkctr, struct sample *smp, int decrefcnt) { - struct stkctr tmpstkctr; - struct stkctr *stkctr; - - stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw, &tmpstkctr); - if (!stkctr) - return 0; - smp->flags = SMP_F_VOL_TEST; smp->data.type = SMP_T_SINT; smp->data.u.sint = 0; @@ -5165,7 +5320,7 @@ smp_fetch_sc_bytes_out_rate(const struct arg *args, struct sample *smp, const ch ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_BYTES_OUT_RATE); if (!ptr) { - if (stkctr == &tmpstkctr) + if (decrefcnt) stktable_release(stkctr->table, stkctr_entry(stkctr)); return 0; /* parameter not stored */ } @@ -5177,12 +5332,29 @@ smp_fetch_sc_bytes_out_rate(const struct arg *args, struct sample *smp, const ch HA_RWLOCK_RDUNLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock); - if (stkctr == &tmpstkctr) + if (decrefcnt) stktable_release(stkctr->table, stkctr_entry(stkctr)); } return 1; } +/* set to the data rate sent to clients in bytes/s, as found in the + * stream's tracked frontend counters. Supports being called as + * "sc[0-9]_bytes_out_rate" or "src_bytes_out_rate" only. + */ +static int +smp_fetch_sc_bytes_out_rate(const struct arg *args, struct sample *smp, const char *kw, void *private) +{ + struct stkctr tmpstkctr; + struct stkctr *stkctr; + + stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw, &tmpstkctr); + if (!stkctr) + return 0; + + return smp_fetch_bytes_out_rate(stkctr, smp, (stkctr == &tmpstkctr) ? 1 : 0); +} + /* set to the number of active trackers on the SC entry in the stream's * tracked frontend counters. Supports being called as "sc[0-9]_trackers" only. */