MINOR: stktable: use {show,set,clear} table with ptr
This patchs adds support for optional ptr (0xffff form) instead of key argument to match against existing sticktable entries, ie: if the key is empty or cannot be matched on the cli due to incompatible characters. Lookup is performed using a linear search so it will be slower than key search which relies on eb tree lookup. Example: set table mytable key mykey data.gpc0 1 show table mytable > 0x7fbd00032bd8: key=mykey use=0 exp=86373242 shard=0 gpc0=1 clear table mytable ptr 0x7fbd00032bd8 This patchs depends on: - "MINOR: stktable: add table_process_entry helper function" It should solve GH #2118
This commit is contained in:
parent
6ee3923c52
commit
9b2717e7bb
|
@ -385,6 +385,40 @@ struct stksess *stktable_lookup_key(struct stktable *t, struct stktable_key *key
|
||||||
return ts;
|
return ts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Looks in table <t> for a sticky session matching ptr <ptr>.
|
||||||
|
* Returns pointer on requested sticky session or NULL if none was found.
|
||||||
|
* The refcount of the found entry is increased and this function
|
||||||
|
* is protected using the table lock
|
||||||
|
*/
|
||||||
|
struct stksess *stktable_lookup_ptr(struct stktable *t, void *ptr)
|
||||||
|
{
|
||||||
|
struct stksess *ts = NULL;
|
||||||
|
struct ebmb_node *eb;
|
||||||
|
|
||||||
|
HA_RWLOCK_RDLOCK(STK_TABLE_LOCK, &t->lock);
|
||||||
|
/* linear search is performed, this could be optimized by adding
|
||||||
|
* an eb node dedicated to ptr lookups into stksess struct to
|
||||||
|
* leverage eb_lookup function instead.
|
||||||
|
*/
|
||||||
|
eb = ebmb_first(&t->keys);
|
||||||
|
while (eb) {
|
||||||
|
struct stksess *cur;
|
||||||
|
|
||||||
|
cur = ebmb_entry(eb, struct stksess, key);
|
||||||
|
if (cur == ptr) {
|
||||||
|
ts = cur;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
eb = ebmb_next(eb);
|
||||||
|
}
|
||||||
|
if (ts)
|
||||||
|
HA_ATOMIC_INC(&ts->ref_cnt);
|
||||||
|
HA_RWLOCK_RDUNLOCK(STK_TABLE_LOCK, &t->lock);
|
||||||
|
|
||||||
|
return ts;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Looks in table <t> for a sticky session with same key as <ts>.
|
* Looks in table <t> for a sticky session with same key as <ts>.
|
||||||
* Returns pointer on requested sticky session or NULL if none was found.
|
* Returns pointer on requested sticky session or NULL if none was found.
|
||||||
|
@ -5080,6 +5114,32 @@ static int table_process_entry_per_key(struct appctx *appctx, char **args)
|
||||||
return table_process_entry(appctx, ts, args);
|
return table_process_entry(appctx, ts, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Processes a single table entry matching a specific ptr passed in argument.
|
||||||
|
* returns 0 if wants to be called again, 1 if has ended processing.
|
||||||
|
*/
|
||||||
|
static int table_process_entry_per_ptr(struct appctx *appctx, char **args)
|
||||||
|
{
|
||||||
|
struct show_table_ctx *ctx = appctx->svcctx;
|
||||||
|
struct stktable *t = ctx->target;
|
||||||
|
long long int ptr;
|
||||||
|
char *error;
|
||||||
|
struct stksess *ts;
|
||||||
|
|
||||||
|
if (!*args[4] || args[4][0] != '0' || args[4][1] != 'x')
|
||||||
|
return cli_err(appctx, "Pointer expected (0xffff notation)\n");
|
||||||
|
|
||||||
|
/* Convert argument to integer value */
|
||||||
|
ptr = strtoll(args[4], &error, 16);
|
||||||
|
if (*error != '\0')
|
||||||
|
return cli_err(appctx, "Malformed ptr.\n");
|
||||||
|
|
||||||
|
ts = stktable_lookup_ptr(t, (void *)ptr);
|
||||||
|
if (!ts)
|
||||||
|
return cli_err(appctx, "No entry can be found matching ptr.\n");
|
||||||
|
|
||||||
|
return table_process_entry(appctx, ts, args);
|
||||||
|
}
|
||||||
|
|
||||||
/* Prepares the appctx fields with the data-based filters from the command line.
|
/* Prepares the appctx fields with the data-based filters from the command line.
|
||||||
* Returns 0 if the dump can proceed, 1 if has ended processing.
|
* Returns 0 if the dump can proceed, 1 if has ended processing.
|
||||||
*/
|
*/
|
||||||
|
@ -5145,6 +5205,8 @@ static int cli_parse_table_req(char **args, char *payload, struct appctx *appctx
|
||||||
|
|
||||||
if (strcmp(args[3], "key") == 0)
|
if (strcmp(args[3], "key") == 0)
|
||||||
return table_process_entry_per_key(appctx, args);
|
return table_process_entry_per_key(appctx, args);
|
||||||
|
if (strcmp(args[3], "ptr") == 0)
|
||||||
|
return table_process_entry_per_ptr(appctx, args);
|
||||||
else if (strncmp(args[3], "data.", 5) == 0)
|
else if (strncmp(args[3], "data.", 5) == 0)
|
||||||
return table_prepare_data_request(appctx, args);
|
return table_prepare_data_request(appctx, args);
|
||||||
else if (*args[3])
|
else if (*args[3])
|
||||||
|
@ -5155,11 +5217,11 @@ static int cli_parse_table_req(char **args, char *payload, struct appctx *appctx
|
||||||
err_args:
|
err_args:
|
||||||
switch (ctx->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> or key <key> or ptr <ptr>\n");
|
||||||
case STK_CLI_ACT_CLR:
|
case STK_CLI_ACT_CLR:
|
||||||
return cli_err(appctx, "Required arguments: <table> \"data.<store_data_type>\" <operator> <value> or <table> key <key>\n");
|
return cli_err(appctx, "Required arguments: <table> \"data.<store_data_type>\" <operator> <value> or <table> key <key> or <table> ptr <ptr>\n");
|
||||||
case STK_CLI_ACT_SET:
|
case STK_CLI_ACT_SET:
|
||||||
return cli_err(appctx, "Required arguments: <table> key <key> [data.<store_data_type> <value>]*\n");
|
return cli_err(appctx, "Required arguments: <table> key <key> [data.<store_data_type> <value>]* or <table> ptr <ptr> [data.<store_data_type> <value>]*\n");
|
||||||
default:
|
default:
|
||||||
return cli_err(appctx, "Unknown action\n");
|
return cli_err(appctx, "Unknown action\n");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue