Re: [PATCH] BUG/MEDIUM: stick-tables: Decrement ref_cnt in table_* converters

2018-05-28 Thread Willy Tarreau
Hi Daniel,

On Sun, May 27, 2018 at 12:31:54PM -0400, Daniel Corbett wrote:
> I have attached the latest patch with these changes.

Now merged, thank you!

willy



Re: [PATCH] BUG/MEDIUM: stick-tables: Decrement ref_cnt in table_* converters

2018-05-27 Thread Daniel Corbett

Hello Willy,


On 05/24/2018 04:16 PM, Willy Tarreau wrote:


Interesting one! However it's not correct, it doesn't decrement the
refcount on the return 0 path so the problem remains when a data
type is looked up in a table where it is not stored. For example :


Nice catch.  Thanks for pointing this out.


Given that all functions seem to be written the same way, I suggest
that we change the end and invert the !ptr condition to centralize
the release call. It would give this above :

 ptr = stktable_data_ptr(t, ts, STKTABLE_DT_CONN_CUR);
 if (ptr)
smp->data.u.sint = stktable_data_cast(ptr, conn_cur);
 stktable_release(t, ts);
 return !!ptr;

Could you please rework your patch to do this so that I can merge it ?



I have attached the latest patch with these changes.

Thanks,
-- Daniel


>From e47065ac6cc7478d21cfa00c5c45a0ae7cd412bf Mon Sep 17 00:00:00 2001
From: Daniel Corbett 
Date: Sun, 27 May 2018 09:47:12 -0400
Subject: [PATCH] BUG/MEDIUM: stick-tables: Decrement ref_cnt in table_*
 converters

When using table_* converters ref_cnt was incremented
and never decremented causing entries to not expire.

The root cause appears to be that stktable_lookup_key()
was called within all sample_conv_table_* functions which was
incrementing ref_cnt and not decrementing after completion.

Added stktable_release() to the end of each sample_conv_table_*
function and reworked the end logic to ensure that ref_cnt is
always decremented after use.

This should be backported to 1.8
---
 src/stick_table.c | 170 +++---
 1 file changed, 86 insertions(+), 84 deletions(-)

diff --git a/src/stick_table.c b/src/stick_table.c
index fcc6fe6..101a4e2 100644
--- a/src/stick_table.c
+++ b/src/stick_table.c
@@ -875,6 +875,7 @@ static int sample_conv_in_table(const struct arg *arg_p, struct sample *smp, voi
 	smp->data.type = SMP_T_BOOL;
 	smp->data.u.sint = !!ts;
 	smp->flags = SMP_F_VOL_TEST;
+	stktable_release(t, ts);
 	return 1;
 }
 
@@ -907,12 +908,12 @@ static int sample_conv_table_bytes_in_rate(const struct arg *arg_p, struct sampl
 		return 1;
 
 	ptr = stktable_data_ptr(t, ts, STKTABLE_DT_BYTES_IN_RATE);
-	if (!ptr)
-		return 0; /* parameter not stored */
+	if (ptr)
+		smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, bytes_in_rate),
+   t->data_arg[STKTABLE_DT_BYTES_IN_RATE].u);
 
-	smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, bytes_in_rate),
-	   t->data_arg[STKTABLE_DT_BYTES_IN_RATE].u);
-	return 1;
+	stktable_release(t, ts);
+	return !!ptr;
 }
 
 /* Casts sample  to the type of the table specified in arg(0), and looks
@@ -944,11 +945,11 @@ static int sample_conv_table_conn_cnt(const struct arg *arg_p, struct sample *sm
 		return 1;
 
 	ptr = stktable_data_ptr(t, ts, STKTABLE_DT_CONN_CNT);
-	if (!ptr)
-		return 0; /* parameter not stored */
+	if (ptr)
+		smp->data.u.sint = stktable_data_cast(ptr, conn_cnt);
 
-	smp->data.u.sint = stktable_data_cast(ptr, conn_cnt);
-	return 1;
+	stktable_release(t, ts);
+	return !!ptr;
 }
 
 /* Casts sample  to the type of the table specified in arg(0), and looks
@@ -980,11 +981,11 @@ static int sample_conv_table_conn_cur(const struct arg *arg_p, struct sample *sm
 		return 1;
 
 	ptr = stktable_data_ptr(t, ts, STKTABLE_DT_CONN_CUR);
-	if (!ptr)
-		return 0; /* parameter not stored */
+	if (ptr)
+		smp->data.u.sint = stktable_data_cast(ptr, conn_cur);
 
-	smp->data.u.sint = stktable_data_cast(ptr, conn_cur);
-	return 1;
+	stktable_release(t, ts);
+	return !!ptr;
 }
 
 /* Casts sample  to the type of the table specified in arg(0), and looks
@@ -1016,12 +1017,12 @@ static int sample_conv_table_conn_rate(const struct arg *arg_p, struct sample *s
 		return 1;
 
 	ptr = stktable_data_ptr(t, ts, STKTABLE_DT_CONN_RATE);
-	if (!ptr)
-		return 0; /* parameter not stored */
+	if (ptr)
+		smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, conn_rate),
+   t->data_arg[STKTABLE_DT_CONN_RATE].u);
 
-	smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, conn_rate),
-	   t->data_arg[STKTABLE_DT_CONN_RATE].u);
-	return 1;
+	stktable_release(t, ts);
+	return !!ptr;
 }
 
 /* Casts sample  to the type of the table specified in arg(0), and looks
@@ -1053,12 +1054,12 @@ static int sample_conv_table_bytes_out_rate(const struct arg *arg_p, struct samp
 		return 1;
 
 	ptr = stktable_data_ptr(t, ts, STKTABLE_DT_BYTES_OUT_RATE);
-	if (!ptr)
-		return 0; /* parameter not stored */
+	if (ptr)
+		smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, bytes_out_rate),
+   t->data_arg[STKTABLE_DT_BYTES_OUT_RATE].u);
 
-	smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, bytes_out_

Re: [PATCH] BUG/MEDIUM: stick-tables: Decrement ref_cnt in table_* converters

2018-05-24 Thread Willy Tarreau
Hi Daniel,

On Thu, May 17, 2018 at 02:05:28PM -0400, Daniel Corbett wrote:
> Hello,
> 
> When using table_* converters ref_cnt was incremented
> and never decremented causing entries to not expire.
> 
> The root cause appears to be that stktable_lookup_key()
> was called within all sample_conv_table_* functions which was
> incrementing ref_cnt and not decrementing after completion.
> 
> Added stktable_release() to the end of each sample_conv_table_*
> function.

Interesting one! However it's not correct, it doesn't decrement the
refcount on the return 0 path so the problem remains when a data
type is looked up in a table where it is not stored. For example :

ts = stktable_lookup_key(t, key);

  ## ref_cnt incremented here only if ts != NULL

smp->flags = SMP_F_VOL_TEST;
smp->data.type = SMP_T_SINT;
smp->data.u.sint = 0;

if (!ts) /* key not present */
return 1;

ptr = stktable_data_ptr(t, ts, STKTABLE_DT_CONN_CUR);
if (!ptr)

  ## here it's not decremented

return 0; /* parameter not stored */

smp->data.u.sint = stktable_data_cast(ptr, conn_cur);
  + stktable_release(t, ts);
return 1;

Given that all functions seem to be written the same way, I suggest
that we change the end and invert the !ptr condition to centralize
the release call. It would give this above :

ptr = stktable_data_ptr(t, ts, STKTABLE_DT_CONN_CUR);
if (ptr)
smp->data.u.sint = stktable_data_cast(ptr, conn_cur);
stktable_release(t, ts);
return !!ptr;

Could you please rework your patch to do this so that I can merge it ?

Thanks!
Willy



[PATCH] BUG/MEDIUM: stick-tables: Decrement ref_cnt in table_* converters

2018-05-17 Thread Daniel Corbett

Hello,

When using table_* converters ref_cnt was incremented
and never decremented causing entries to not expire.

The root cause appears to be that stktable_lookup_key()
was called within all sample_conv_table_* functions which was
incrementing ref_cnt and not decrementing after completion.

Added stktable_release() to the end of each sample_conv_table_*
function.

This should be backported to 1.8.


Thanks,
-- Daniel

>From 28530921746e62bb229880774a311bfebfcf7579 Mon Sep 17 00:00:00 2001
From: Daniel Corbett 
Date: Thu, 17 May 2018 13:17:54 -0400
Subject: [PATCH] BUG/MEDIUM: stick-tables: Decrement ref_cnt in table_*
 converters

When using table_* converters ref_cnt was incremented
and never decremented causing entries to not expire.

The root cause appears to be that stktable_lookup_key()
was called within all sample_conv_table_* functions which was
incrementing ref_cnt and not decrementing after completion.

Added stktable_release() to the end of each sample_conv_table_*
function.

This should be backported to 1.8
---
 src/stick_table.c | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/src/stick_table.c b/src/stick_table.c
index 3e44747..f1ad347 100644
--- a/src/stick_table.c
+++ b/src/stick_table.c
@@ -912,6 +912,7 @@ static int sample_conv_table_bytes_in_rate(const struct arg *arg_p, struct sampl
 
 	smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, bytes_in_rate),
 	   t->data_arg[STKTABLE_DT_BYTES_IN_RATE].u);
+	stktable_release(t, ts);
 	return 1;
 }
 
@@ -948,6 +949,7 @@ static int sample_conv_table_conn_cnt(const struct arg *arg_p, struct sample *sm
 		return 0; /* parameter not stored */
 
 	smp->data.u.sint = stktable_data_cast(ptr, conn_cnt);
+	stktable_release(t, ts);
 	return 1;
 }
 
@@ -984,6 +986,7 @@ static int sample_conv_table_conn_cur(const struct arg *arg_p, struct sample *sm
 		return 0; /* parameter not stored */
 
 	smp->data.u.sint = stktable_data_cast(ptr, conn_cur);
+	stktable_release(t, ts);
 	return 1;
 }
 
@@ -1021,6 +1024,7 @@ static int sample_conv_table_conn_rate(const struct arg *arg_p, struct sample *s
 
 	smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, conn_rate),
 	   t->data_arg[STKTABLE_DT_CONN_RATE].u);
+	stktable_release(t, ts);
 	return 1;
 }
 
@@ -1058,6 +1062,7 @@ static int sample_conv_table_bytes_out_rate(const struct arg *arg_p, struct samp
 
 	smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, bytes_out_rate),
 	   t->data_arg[STKTABLE_DT_BYTES_OUT_RATE].u);
+	stktable_release(t, ts);
 	return 1;
 }
 
@@ -1094,6 +1099,7 @@ static int sample_conv_table_gpt0(const struct arg *arg_p, struct sample *smp, v
 		return 0; /* parameter not stored */
 
 	smp->data.u.sint = stktable_data_cast(ptr, gpt0);
+	stktable_release(t, ts);
 	return 1;
 }
 
@@ -1130,6 +1136,7 @@ static int sample_conv_table_gpc0(const struct arg *arg_p, struct sample *smp, v
 		return 0; /* parameter not stored */
 
 	smp->data.u.sint = stktable_data_cast(ptr, gpc0);
+	stktable_release(t, ts);
 	return 1;
 }
 
@@ -1167,6 +1174,7 @@ static int sample_conv_table_gpc0_rate(const struct arg *arg_p, struct sample *s
 
 	smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, gpc0_rate),
 	  t->data_arg[STKTABLE_DT_GPC0_RATE].u);
+	stktable_release(t, ts);
 	return 1;
 }
 
@@ -1203,6 +1211,7 @@ static int sample_conv_table_gpc1(const struct arg *arg_p, struct sample *smp, v
 		return 0; /* parameter not stored */
 
 	smp->data.u.sint = stktable_data_cast(ptr, gpc1);
+	stktable_release(t, ts);
 	return 1;
 }
 
@@ -1240,6 +1249,7 @@ static int sample_conv_table_gpc1_rate(const struct arg *arg_p, struct sample *s
 
 	smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, gpc1_rate),
 	  t->data_arg[STKTABLE_DT_GPC1_RATE].u);
+	stktable_release(t, ts);
 	return 1;
 }
 
@@ -1276,6 +1286,7 @@ static int sample_conv_table_http_err_cnt(const struct arg *arg_p, struct sample
 		return 0; /* parameter not stored */
 
 	smp->data.u.sint = stktable_data_cast(ptr, http_err_cnt);
+	stktable_release(t, ts);
 	return 1;
 }
 
@@ -1313,6 +1324,7 @@ static int sample_conv_table_http_err_rate(const struct arg *arg_p, struct sampl
 
 	smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, http_err_rate),
 	   t->data_arg[STKTABLE_DT_HTTP_ERR_RATE].u);
+	stktable_release(t, ts);
 	return 1;
 }
 
@@ -1349,6 +1361,7 @@ static int sample_conv_table_http_req_cnt(const struct arg *arg_p, struct sample
 		return 0; /* parameter not stored */
 
 	smp->data.u.sint = stktable_data_cast(ptr, http_req_cnt);
+	stktable_release(t, ts);
 	return 1;
 }
 
@@ -1386,6 +1399,7 @@ static int sample_conv_table_http_req_rate(const struct arg *arg_p, struct sampl
 
 	smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, http_req_rate),