mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2024-12-19 10:14:41 +00:00
CLEANUP: stick-table/cli: take the "show table" context definition out of the appctx
This makes use of the generic command context allocation so that the appctx doesn't have to declare a specific one anymore. The context is created during parsing. The code also uses st2 which deserves being addressed in separate commit.
This commit is contained in:
parent
0fd8f0e236
commit
3c69e08e96
@ -149,15 +149,6 @@ struct appctx {
|
|||||||
int iid, type, sid; /* proxy id, type and service id if bounding of stats is enabled */
|
int iid, type, sid; /* proxy id, type and service id if bounding of stats is enabled */
|
||||||
int st_code; /* the status code returned by an action */
|
int st_code; /* the status code returned by an action */
|
||||||
} stats;
|
} stats;
|
||||||
struct {
|
|
||||||
void *target; /* table we want to dump, or NULL for all */
|
|
||||||
struct stktable *t; /* table being currently dumped (first if NULL) */
|
|
||||||
struct stksess *entry; /* last entry we were trying to dump (or first if NULL) */
|
|
||||||
long long value[STKTABLE_FILTER_LEN]; /* value to compare against */
|
|
||||||
signed char data_type[STKTABLE_FILTER_LEN]; /* type of data to compare, or -1 if none */
|
|
||||||
signed char data_op[STKTABLE_FILTER_LEN]; /* operator (STD_OP_*) when data_type set */
|
|
||||||
char action; /* action on the table : one of STK_CLI_ACT_* */
|
|
||||||
} table;
|
|
||||||
struct {
|
struct {
|
||||||
unsigned int display_flags;
|
unsigned int display_flags;
|
||||||
struct pat_ref *ref;
|
struct pat_ref *ref;
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include <import/ebistree.h>
|
#include <import/ebistree.h>
|
||||||
|
|
||||||
#include <haproxy/api.h>
|
#include <haproxy/api.h>
|
||||||
|
#include <haproxy/applet.h>
|
||||||
#include <haproxy/arg.h>
|
#include <haproxy/arg.h>
|
||||||
#include <haproxy/cfgparse.h>
|
#include <haproxy/cfgparse.h>
|
||||||
#include <haproxy/cli.h>
|
#include <haproxy/cli.h>
|
||||||
@ -4386,6 +4387,16 @@ static int table_dump_entry_to_buffer(struct buffer *msg,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* appctx context used by the "show table" command */
|
||||||
|
struct show_table_ctx {
|
||||||
|
void *target; /* table we want to dump, or NULL for all */
|
||||||
|
struct stktable *t; /* table being currently dumped (first if NULL) */
|
||||||
|
struct stksess *entry; /* last entry we were trying to dump (or first if NULL) */
|
||||||
|
long long value[STKTABLE_FILTER_LEN]; /* value to compare against */
|
||||||
|
signed char data_type[STKTABLE_FILTER_LEN]; /* type of data to compare, or -1 if none */
|
||||||
|
signed char data_op[STKTABLE_FILTER_LEN]; /* operator (STD_OP_*) when data_type set */
|
||||||
|
char action; /* action on the table : one of STK_CLI_ACT_* */
|
||||||
|
};
|
||||||
|
|
||||||
/* Processes a single table entry matching a specific key passed in argument.
|
/* Processes a single table entry matching a specific key passed in argument.
|
||||||
* returns 0 if wants to be called again, 1 if has ended processing.
|
* returns 0 if wants to be called again, 1 if has ended processing.
|
||||||
@ -4393,7 +4404,8 @@ static int table_dump_entry_to_buffer(struct buffer *msg,
|
|||||||
static int table_process_entry_per_key(struct appctx *appctx, char **args)
|
static int table_process_entry_per_key(struct appctx *appctx, char **args)
|
||||||
{
|
{
|
||||||
struct conn_stream *cs = appctx->owner;
|
struct conn_stream *cs = appctx->owner;
|
||||||
struct stktable *t = appctx->ctx.table.target;
|
struct show_table_ctx *ctx = appctx->svcctx;
|
||||||
|
struct stktable *t = ctx->target;
|
||||||
struct stksess *ts;
|
struct stksess *ts;
|
||||||
uint32_t uint32_key;
|
uint32_t uint32_key;
|
||||||
unsigned char ip6_key[sizeof(struct in6_addr)];
|
unsigned char ip6_key[sizeof(struct in6_addr)];
|
||||||
@ -4436,7 +4448,7 @@ static int table_process_entry_per_key(struct appctx *appctx, char **args)
|
|||||||
static_table_key.key_len = strlen(args[4]);
|
static_table_key.key_len = strlen(args[4]);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
switch (appctx->ctx.table.action) {
|
switch (ctx->action) {
|
||||||
case STK_CLI_ACT_SHOW:
|
case STK_CLI_ACT_SHOW:
|
||||||
return cli_err(appctx, "Showing keys from tables of type other than ip, ipv6, string and integer is not supported\n");
|
return cli_err(appctx, "Showing keys from tables of type other than ip, ipv6, string and integer is not supported\n");
|
||||||
case STK_CLI_ACT_CLR:
|
case STK_CLI_ACT_CLR:
|
||||||
@ -4452,7 +4464,7 @@ static int table_process_entry_per_key(struct appctx *appctx, char **args)
|
|||||||
if (!cli_has_level(appctx, ACCESS_LVL_OPER))
|
if (!cli_has_level(appctx, ACCESS_LVL_OPER))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
switch (appctx->ctx.table.action) {
|
switch (ctx->action) {
|
||||||
case STK_CLI_ACT_SHOW:
|
case STK_CLI_ACT_SHOW:
|
||||||
ts = stktable_lookup_key(t, &static_table_key);
|
ts = stktable_lookup_key(t, &static_table_key);
|
||||||
if (!ts)
|
if (!ts)
|
||||||
@ -4564,28 +4576,29 @@ static int table_process_entry_per_key(struct appctx *appctx, char **args)
|
|||||||
*/
|
*/
|
||||||
static int table_prepare_data_request(struct appctx *appctx, char **args)
|
static int table_prepare_data_request(struct appctx *appctx, char **args)
|
||||||
{
|
{
|
||||||
|
struct show_table_ctx *ctx = appctx->svcctx;
|
||||||
int i;
|
int i;
|
||||||
char *err = NULL;
|
char *err = NULL;
|
||||||
|
|
||||||
if (appctx->ctx.table.action != STK_CLI_ACT_SHOW && appctx->ctx.table.action != STK_CLI_ACT_CLR)
|
if (ctx->action != STK_CLI_ACT_SHOW && ctx->action != STK_CLI_ACT_CLR)
|
||||||
return cli_err(appctx, "content-based lookup is only supported with the \"show\" and \"clear\" actions\n");
|
return cli_err(appctx, "content-based lookup is only supported with the \"show\" and \"clear\" actions\n");
|
||||||
|
|
||||||
for (i = 0; i < STKTABLE_FILTER_LEN; i++) {
|
for (i = 0; i < STKTABLE_FILTER_LEN; i++) {
|
||||||
if (i > 0 && !*args[3+3*i]) // number of filter entries can be less than STKTABLE_FILTER_LEN
|
if (i > 0 && !*args[3+3*i]) // number of filter entries can be less than STKTABLE_FILTER_LEN
|
||||||
break;
|
break;
|
||||||
/* condition on stored data value */
|
/* condition on stored data value */
|
||||||
appctx->ctx.table.data_type[i] = stktable_get_data_type(args[3+3*i] + 5);
|
ctx->data_type[i] = stktable_get_data_type(args[3+3*i] + 5);
|
||||||
if (appctx->ctx.table.data_type[i] < 0)
|
if (ctx->data_type[i] < 0)
|
||||||
return cli_dynerr(appctx, memprintf(&err, "Filter entry #%i: Unknown data type\n", i + 1));
|
return cli_dynerr(appctx, memprintf(&err, "Filter entry #%i: Unknown data type\n", i + 1));
|
||||||
|
|
||||||
if (!((struct stktable *)appctx->ctx.table.target)->data_ofs[appctx->ctx.table.data_type[i]])
|
if (!((struct stktable *)ctx->target)->data_ofs[ctx->data_type[i]])
|
||||||
return cli_dynerr(appctx, memprintf(&err, "Filter entry #%i: Data type not stored in this table\n", i + 1));
|
return cli_dynerr(appctx, memprintf(&err, "Filter entry #%i: Data type not stored in this table\n", i + 1));
|
||||||
|
|
||||||
appctx->ctx.table.data_op[i] = get_std_op(args[4+3*i]);
|
ctx->data_op[i] = get_std_op(args[4+3*i]);
|
||||||
if (appctx->ctx.table.data_op[i] < 0)
|
if (ctx->data_op[i] < 0)
|
||||||
return cli_dynerr(appctx, memprintf(&err, "Filter entry #%i: Require and operator among \"eq\", \"ne\", \"le\", \"ge\", \"lt\", \"gt\"\n", i + 1));
|
return cli_dynerr(appctx, memprintf(&err, "Filter entry #%i: Require and operator among \"eq\", \"ne\", \"le\", \"ge\", \"lt\", \"gt\"\n", i + 1));
|
||||||
|
|
||||||
if (!*args[5+3*i] || strl2llrc(args[5+3*i], strlen(args[5+3*i]), &appctx->ctx.table.value[i]) != 0)
|
if (!*args[5+3*i] || strl2llrc(args[5+3*i], strlen(args[5+3*i]), &ctx->value[i]) != 0)
|
||||||
return cli_dynerr(appctx, memprintf(&err, "Filter entry #%i: Require a valid integer value to compare against\n", i + 1));
|
return cli_dynerr(appctx, memprintf(&err, "Filter entry #%i: Require a valid integer value to compare against\n", i + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4600,21 +4613,22 @@ static int table_prepare_data_request(struct appctx *appctx, char **args)
|
|||||||
/* returns 0 if wants to be called, 1 if has ended processing */
|
/* returns 0 if wants to be called, 1 if has ended processing */
|
||||||
static int cli_parse_table_req(char **args, char *payload, struct appctx *appctx, void *private)
|
static int cli_parse_table_req(char **args, char *payload, struct appctx *appctx, void *private)
|
||||||
{
|
{
|
||||||
|
struct show_table_ctx *ctx = applet_reserve_svcctx(appctx, sizeof(*ctx));
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < STKTABLE_FILTER_LEN; i++)
|
for (i = 0; i < STKTABLE_FILTER_LEN; i++)
|
||||||
appctx->ctx.table.data_type[i] = -1;
|
ctx->data_type[i] = -1;
|
||||||
appctx->ctx.table.target = NULL;
|
ctx->target = NULL;
|
||||||
appctx->ctx.table.entry = NULL;
|
ctx->entry = NULL;
|
||||||
appctx->ctx.table.action = (long)private; // keyword argument, one of STK_CLI_ACT_*
|
ctx->action = (long)private; // keyword argument, one of STK_CLI_ACT_*
|
||||||
|
|
||||||
if (*args[2]) {
|
if (*args[2]) {
|
||||||
appctx->ctx.table.target = stktable_find_by_name(args[2]);
|
ctx->target = stktable_find_by_name(args[2]);
|
||||||
if (!appctx->ctx.table.target)
|
if (!ctx->target)
|
||||||
return cli_err(appctx, "No such table\n");
|
return cli_err(appctx, "No such table\n");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (appctx->ctx.table.action != STK_CLI_ACT_SHOW)
|
if (ctx->action != STK_CLI_ACT_SHOW)
|
||||||
goto err_args;
|
goto err_args;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -4629,7 +4643,7 @@ static int cli_parse_table_req(char **args, char *payload, struct appctx *appctx
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_args:
|
err_args:
|
||||||
switch (appctx->ctx.table.action) {
|
switch (ctx->action) {
|
||||||
case STK_CLI_ACT_SHOW:
|
case STK_CLI_ACT_SHOW:
|
||||||
return cli_err(appctx, "Optional argument only supports \"data.<store_data_type>\" <operator> <value> and key <key>\n");
|
return cli_err(appctx, "Optional argument only supports \"data.<store_data_type>\" <operator> <value> and key <key>\n");
|
||||||
case STK_CLI_ACT_CLR:
|
case STK_CLI_ACT_CLR:
|
||||||
@ -4647,11 +4661,12 @@ err_args:
|
|||||||
*/
|
*/
|
||||||
static int cli_io_handler_table(struct appctx *appctx)
|
static int cli_io_handler_table(struct appctx *appctx)
|
||||||
{
|
{
|
||||||
|
struct show_table_ctx *ctx = appctx->svcctx;
|
||||||
struct conn_stream *cs = appctx->owner;
|
struct conn_stream *cs = appctx->owner;
|
||||||
struct stream *s = __cs_strm(cs);
|
struct stream *s = __cs_strm(cs);
|
||||||
struct ebmb_node *eb;
|
struct ebmb_node *eb;
|
||||||
int skip_entry;
|
int skip_entry;
|
||||||
int show = appctx->ctx.table.action == STK_CLI_ACT_SHOW;
|
int show = ctx->action == STK_CLI_ACT_SHOW;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We have 3 possible states in appctx->st2 :
|
* We have 3 possible states in appctx->st2 :
|
||||||
@ -4668,7 +4683,7 @@ static int cli_io_handler_table(struct appctx *appctx)
|
|||||||
if (unlikely(cs_ic(cs)->flags & (CF_WRITE_ERROR|CF_SHUTW))) {
|
if (unlikely(cs_ic(cs)->flags & (CF_WRITE_ERROR|CF_SHUTW))) {
|
||||||
/* in case of abort, remove any refcount we might have set on an entry */
|
/* in case of abort, remove any refcount we might have set on an entry */
|
||||||
if (appctx->st2 == STAT_ST_LIST) {
|
if (appctx->st2 == STAT_ST_LIST) {
|
||||||
stksess_kill_if_expired(appctx->ctx.table.t, appctx->ctx.table.entry, 1);
|
stksess_kill_if_expired(ctx->t, ctx->entry, 1);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -4678,50 +4693,50 @@ static int cli_io_handler_table(struct appctx *appctx)
|
|||||||
while (appctx->st2 != STAT_ST_FIN) {
|
while (appctx->st2 != STAT_ST_FIN) {
|
||||||
switch (appctx->st2) {
|
switch (appctx->st2) {
|
||||||
case STAT_ST_INIT:
|
case STAT_ST_INIT:
|
||||||
appctx->ctx.table.t = appctx->ctx.table.target;
|
ctx->t = ctx->target;
|
||||||
if (!appctx->ctx.table.t)
|
if (!ctx->t)
|
||||||
appctx->ctx.table.t = stktables_list;
|
ctx->t = stktables_list;
|
||||||
|
|
||||||
appctx->ctx.table.entry = NULL;
|
ctx->entry = NULL;
|
||||||
appctx->st2 = STAT_ST_INFO;
|
appctx->st2 = STAT_ST_INFO;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STAT_ST_INFO:
|
case STAT_ST_INFO:
|
||||||
if (!appctx->ctx.table.t ||
|
if (!ctx->t ||
|
||||||
(appctx->ctx.table.target &&
|
(ctx->target &&
|
||||||
appctx->ctx.table.t != appctx->ctx.table.target)) {
|
ctx->t != ctx->target)) {
|
||||||
appctx->st2 = STAT_ST_END;
|
appctx->st2 = STAT_ST_END;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (appctx->ctx.table.t->size) {
|
if (ctx->t->size) {
|
||||||
if (show && !table_dump_head_to_buffer(&trash, cs, appctx->ctx.table.t, appctx->ctx.table.target))
|
if (show && !table_dump_head_to_buffer(&trash, cs, ctx->t, ctx->target))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (appctx->ctx.table.target &&
|
if (ctx->target &&
|
||||||
(strm_li(s)->bind_conf->level & ACCESS_LVL_MASK) >= ACCESS_LVL_OPER) {
|
(strm_li(s)->bind_conf->level & ACCESS_LVL_MASK) >= ACCESS_LVL_OPER) {
|
||||||
/* dump entries only if table explicitly requested */
|
/* dump entries only if table explicitly requested */
|
||||||
HA_SPIN_LOCK(STK_TABLE_LOCK, &appctx->ctx.table.t->lock);
|
HA_SPIN_LOCK(STK_TABLE_LOCK, &ctx->t->lock);
|
||||||
eb = ebmb_first(&appctx->ctx.table.t->keys);
|
eb = ebmb_first(&ctx->t->keys);
|
||||||
if (eb) {
|
if (eb) {
|
||||||
appctx->ctx.table.entry = ebmb_entry(eb, struct stksess, key);
|
ctx->entry = ebmb_entry(eb, struct stksess, key);
|
||||||
appctx->ctx.table.entry->ref_cnt++;
|
ctx->entry->ref_cnt++;
|
||||||
appctx->st2 = STAT_ST_LIST;
|
appctx->st2 = STAT_ST_LIST;
|
||||||
HA_SPIN_UNLOCK(STK_TABLE_LOCK, &appctx->ctx.table.t->lock);
|
HA_SPIN_UNLOCK(STK_TABLE_LOCK, &ctx->t->lock);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
HA_SPIN_UNLOCK(STK_TABLE_LOCK, &appctx->ctx.table.t->lock);
|
HA_SPIN_UNLOCK(STK_TABLE_LOCK, &ctx->t->lock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
appctx->ctx.table.t = appctx->ctx.table.t->next;
|
ctx->t = ctx->t->next;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STAT_ST_LIST:
|
case STAT_ST_LIST:
|
||||||
skip_entry = 0;
|
skip_entry = 0;
|
||||||
|
|
||||||
HA_RWLOCK_RDLOCK(STK_SESS_LOCK, &appctx->ctx.table.entry->lock);
|
HA_RWLOCK_RDLOCK(STK_SESS_LOCK, &ctx->entry->lock);
|
||||||
|
|
||||||
if (appctx->ctx.table.data_type[0] >= 0) {
|
if (ctx->data_type[0] >= 0) {
|
||||||
/* we're filtering on some data contents */
|
/* we're filtering on some data contents */
|
||||||
void *ptr;
|
void *ptr;
|
||||||
int dt, i;
|
int dt, i;
|
||||||
@ -4730,11 +4745,11 @@ static int cli_io_handler_table(struct appctx *appctx)
|
|||||||
|
|
||||||
|
|
||||||
for (i = 0; i < STKTABLE_FILTER_LEN; i++) {
|
for (i = 0; i < STKTABLE_FILTER_LEN; i++) {
|
||||||
if (appctx->ctx.table.data_type[i] == -1)
|
if (ctx->data_type[i] == -1)
|
||||||
break;
|
break;
|
||||||
dt = appctx->ctx.table.data_type[i];
|
dt = ctx->data_type[i];
|
||||||
ptr = stktable_data_ptr(appctx->ctx.table.t,
|
ptr = stktable_data_ptr(ctx->t,
|
||||||
appctx->ctx.table.entry,
|
ctx->entry,
|
||||||
dt);
|
dt);
|
||||||
|
|
||||||
data = 0;
|
data = 0;
|
||||||
@ -4750,12 +4765,12 @@ static int cli_io_handler_table(struct appctx *appctx)
|
|||||||
break;
|
break;
|
||||||
case STD_T_FRQP:
|
case STD_T_FRQP:
|
||||||
data = read_freq_ctr_period(&stktable_data_cast(ptr, std_t_frqp),
|
data = read_freq_ctr_period(&stktable_data_cast(ptr, std_t_frqp),
|
||||||
appctx->ctx.table.t->data_arg[dt].u);
|
ctx->t->data_arg[dt].u);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
op = appctx->ctx.table.data_op[i];
|
op = ctx->data_op[i];
|
||||||
value = appctx->ctx.table.value[i];
|
value = ctx->value[i];
|
||||||
|
|
||||||
/* skip the entry if the data does not match the test and the value */
|
/* skip the entry if the data does not match the test and the value */
|
||||||
if ((data < value &&
|
if ((data < value &&
|
||||||
@ -4771,38 +4786,38 @@ static int cli_io_handler_table(struct appctx *appctx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (show && !skip_entry &&
|
if (show && !skip_entry &&
|
||||||
!table_dump_entry_to_buffer(&trash, cs, appctx->ctx.table.t, appctx->ctx.table.entry)) {
|
!table_dump_entry_to_buffer(&trash, cs, ctx->t, ctx->entry)) {
|
||||||
HA_RWLOCK_RDUNLOCK(STK_SESS_LOCK, &appctx->ctx.table.entry->lock);
|
HA_RWLOCK_RDUNLOCK(STK_SESS_LOCK, &ctx->entry->lock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
HA_RWLOCK_RDUNLOCK(STK_SESS_LOCK, &appctx->ctx.table.entry->lock);
|
HA_RWLOCK_RDUNLOCK(STK_SESS_LOCK, &ctx->entry->lock);
|
||||||
|
|
||||||
HA_SPIN_LOCK(STK_TABLE_LOCK, &appctx->ctx.table.t->lock);
|
HA_SPIN_LOCK(STK_TABLE_LOCK, &ctx->t->lock);
|
||||||
appctx->ctx.table.entry->ref_cnt--;
|
ctx->entry->ref_cnt--;
|
||||||
|
|
||||||
eb = ebmb_next(&appctx->ctx.table.entry->key);
|
eb = ebmb_next(&ctx->entry->key);
|
||||||
if (eb) {
|
if (eb) {
|
||||||
struct stksess *old = appctx->ctx.table.entry;
|
struct stksess *old = ctx->entry;
|
||||||
appctx->ctx.table.entry = ebmb_entry(eb, struct stksess, key);
|
ctx->entry = ebmb_entry(eb, struct stksess, key);
|
||||||
if (show)
|
if (show)
|
||||||
__stksess_kill_if_expired(appctx->ctx.table.t, old);
|
__stksess_kill_if_expired(ctx->t, old);
|
||||||
else if (!skip_entry && !appctx->ctx.table.entry->ref_cnt)
|
else if (!skip_entry && !ctx->entry->ref_cnt)
|
||||||
__stksess_kill(appctx->ctx.table.t, old);
|
__stksess_kill(ctx->t, old);
|
||||||
appctx->ctx.table.entry->ref_cnt++;
|
ctx->entry->ref_cnt++;
|
||||||
HA_SPIN_UNLOCK(STK_TABLE_LOCK, &appctx->ctx.table.t->lock);
|
HA_SPIN_UNLOCK(STK_TABLE_LOCK, &ctx->t->lock);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (show)
|
if (show)
|
||||||
__stksess_kill_if_expired(appctx->ctx.table.t, appctx->ctx.table.entry);
|
__stksess_kill_if_expired(ctx->t, ctx->entry);
|
||||||
else if (!skip_entry && !appctx->ctx.table.entry->ref_cnt)
|
else if (!skip_entry && !ctx->entry->ref_cnt)
|
||||||
__stksess_kill(appctx->ctx.table.t, appctx->ctx.table.entry);
|
__stksess_kill(ctx->t, ctx->entry);
|
||||||
|
|
||||||
HA_SPIN_UNLOCK(STK_TABLE_LOCK, &appctx->ctx.table.t->lock);
|
HA_SPIN_UNLOCK(STK_TABLE_LOCK, &ctx->t->lock);
|
||||||
|
|
||||||
appctx->ctx.table.t = appctx->ctx.table.t->next;
|
ctx->t = ctx->t->next;
|
||||||
appctx->st2 = STAT_ST_INFO;
|
appctx->st2 = STAT_ST_INFO;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -4816,8 +4831,10 @@ static int cli_io_handler_table(struct appctx *appctx)
|
|||||||
|
|
||||||
static void cli_release_show_table(struct appctx *appctx)
|
static void cli_release_show_table(struct appctx *appctx)
|
||||||
{
|
{
|
||||||
|
struct show_table_ctx *ctx = appctx->svcctx;
|
||||||
|
|
||||||
if (appctx->st2 == STAT_ST_LIST) {
|
if (appctx->st2 == STAT_ST_LIST) {
|
||||||
stksess_kill_if_expired(appctx->ctx.table.t, appctx->ctx.table.entry, 1);
|
stksess_kill_if_expired(ctx->t, ctx->entry, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user