mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-22 22:31:28 +02:00
CLEANUP: map/cli: take the "show map" 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. Many commands, including pure parsers, use this context but that's not a problem as it's designed to be used this way. Due to this, many lines are changed but that's in fact a replacement of "appctx->ctx.map" with "ctx->". Note that the code also uses st2 which deserves being addressed in separate commit.
This commit is contained in:
parent
0f154ed1ef
commit
0fcecc63c8
@ -149,13 +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 {
|
|
||||||
unsigned int display_flags;
|
|
||||||
struct pat_ref *ref;
|
|
||||||
struct bref bref; /* back-reference from the pat_ref_elt being dumped */
|
|
||||||
struct pattern_expr *expr;
|
|
||||||
struct buffer chunk;
|
|
||||||
} map;
|
|
||||||
struct {
|
struct {
|
||||||
struct hlua *hlua;
|
struct hlua *hlua;
|
||||||
struct task *task;
|
struct task *task;
|
||||||
|
317
src/map.c
317
src/map.c
@ -14,7 +14,7 @@
|
|||||||
#include <syslog.h>
|
#include <syslog.h>
|
||||||
|
|
||||||
#include <haproxy/api.h>
|
#include <haproxy/api.h>
|
||||||
#include <haproxy/applet-t.h>
|
#include <haproxy/applet.h>
|
||||||
#include <haproxy/arg.h>
|
#include <haproxy/arg.h>
|
||||||
#include <haproxy/cli.h>
|
#include <haproxy/cli.h>
|
||||||
#include <haproxy/conn_stream.h>
|
#include <haproxy/conn_stream.h>
|
||||||
@ -321,9 +321,23 @@ struct pattern_expr *pat_expr_get_next(struct pattern_expr *getnext, struct list
|
|||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* appctx context for the "{show|get|add|del|*} {map|acl}" commands. This is
|
||||||
|
* used even by commands that only have a parser and no I/O handler because
|
||||||
|
* it provides a unified way to manipulate some fields and will allow to
|
||||||
|
* expand some of them more easily later if needed.
|
||||||
|
*/
|
||||||
|
struct show_map_ctx {
|
||||||
|
struct pat_ref *ref;
|
||||||
|
struct bref bref; /* back-reference from the pat_ref_elt being dumped */
|
||||||
|
struct pattern_expr *expr;
|
||||||
|
struct buffer chunk;
|
||||||
|
unsigned int display_flags;
|
||||||
|
};
|
||||||
|
|
||||||
/* expects the current generation ID in appctx->cli.cli.i0 */
|
/* expects the current generation ID in appctx->cli.cli.i0 */
|
||||||
static int cli_io_handler_pat_list(struct appctx *appctx)
|
static int cli_io_handler_pat_list(struct appctx *appctx)
|
||||||
{
|
{
|
||||||
|
struct show_map_ctx *ctx = appctx->svcctx;
|
||||||
struct conn_stream *cs = appctx->owner;
|
struct conn_stream *cs = appctx->owner;
|
||||||
struct pat_ref_elt *elt;
|
struct pat_ref_elt *elt;
|
||||||
|
|
||||||
@ -332,12 +346,12 @@ static int cli_io_handler_pat_list(struct appctx *appctx)
|
|||||||
* reference to the last ref_elt being dumped.
|
* reference to the last ref_elt being dumped.
|
||||||
*/
|
*/
|
||||||
if (appctx->st2 == STAT_ST_LIST) {
|
if (appctx->st2 == STAT_ST_LIST) {
|
||||||
HA_SPIN_LOCK(PATREF_LOCK, &appctx->ctx.map.ref->lock);
|
HA_SPIN_LOCK(PATREF_LOCK, &ctx->ref->lock);
|
||||||
if (!LIST_ISEMPTY(&appctx->ctx.map.bref.users)) {
|
if (!LIST_ISEMPTY(&ctx->bref.users)) {
|
||||||
LIST_DELETE(&appctx->ctx.map.bref.users);
|
LIST_DELETE(&ctx->bref.users);
|
||||||
LIST_INIT(&appctx->ctx.map.bref.users);
|
LIST_INIT(&ctx->bref.users);
|
||||||
}
|
}
|
||||||
HA_SPIN_UNLOCK(PATREF_LOCK, &appctx->ctx.map.ref->lock);
|
HA_SPIN_UNLOCK(PATREF_LOCK, &ctx->ref->lock);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -349,19 +363,19 @@ static int cli_io_handler_pat_list(struct appctx *appctx)
|
|||||||
/* fall through */
|
/* fall through */
|
||||||
|
|
||||||
case STAT_ST_LIST:
|
case STAT_ST_LIST:
|
||||||
HA_SPIN_LOCK(PATREF_LOCK, &appctx->ctx.map.ref->lock);
|
HA_SPIN_LOCK(PATREF_LOCK, &ctx->ref->lock);
|
||||||
|
|
||||||
if (!LIST_ISEMPTY(&appctx->ctx.map.bref.users)) {
|
if (!LIST_ISEMPTY(&ctx->bref.users)) {
|
||||||
LIST_DELETE(&appctx->ctx.map.bref.users);
|
LIST_DELETE(&ctx->bref.users);
|
||||||
LIST_INIT(&appctx->ctx.map.bref.users);
|
LIST_INIT(&ctx->bref.users);
|
||||||
} else {
|
} else {
|
||||||
appctx->ctx.map.bref.ref = appctx->ctx.map.ref->head.n;
|
ctx->bref.ref = ctx->ref->head.n;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (appctx->ctx.map.bref.ref != &appctx->ctx.map.ref->head) {
|
while (ctx->bref.ref != &ctx->ref->head) {
|
||||||
chunk_reset(&trash);
|
chunk_reset(&trash);
|
||||||
|
|
||||||
elt = LIST_ELEM(appctx->ctx.map.bref.ref, struct pat_ref_elt *, list);
|
elt = LIST_ELEM(ctx->bref.ref, struct pat_ref_elt *, list);
|
||||||
|
|
||||||
if (elt->gen_id != appctx->ctx.cli.i0)
|
if (elt->gen_id != appctx->ctx.cli.i0)
|
||||||
goto skip;
|
goto skip;
|
||||||
@ -379,16 +393,16 @@ static int cli_io_handler_pat_list(struct appctx *appctx)
|
|||||||
/* let's try again later from this stream. We add ourselves into
|
/* let's try again later from this stream. We add ourselves into
|
||||||
* this stream's users so that it can remove us upon termination.
|
* this stream's users so that it can remove us upon termination.
|
||||||
*/
|
*/
|
||||||
LIST_APPEND(&elt->back_refs, &appctx->ctx.map.bref.users);
|
LIST_APPEND(&elt->back_refs, &ctx->bref.users);
|
||||||
HA_SPIN_UNLOCK(PATREF_LOCK, &appctx->ctx.map.ref->lock);
|
HA_SPIN_UNLOCK(PATREF_LOCK, &ctx->ref->lock);
|
||||||
cs_rx_room_blk(cs);
|
cs_rx_room_blk(cs);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
skip:
|
skip:
|
||||||
/* get next list entry and check the end of the list */
|
/* get next list entry and check the end of the list */
|
||||||
appctx->ctx.map.bref.ref = elt->list.n;
|
ctx->bref.ref = elt->list.n;
|
||||||
}
|
}
|
||||||
HA_SPIN_UNLOCK(PATREF_LOCK, &appctx->ctx.map.ref->lock);
|
HA_SPIN_UNLOCK(PATREF_LOCK, &ctx->ref->lock);
|
||||||
/* fall through */
|
/* fall through */
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -399,6 +413,7 @@ static int cli_io_handler_pat_list(struct appctx *appctx)
|
|||||||
|
|
||||||
static int cli_io_handler_pats_list(struct appctx *appctx)
|
static int cli_io_handler_pats_list(struct appctx *appctx)
|
||||||
{
|
{
|
||||||
|
struct show_map_ctx *ctx = appctx->svcctx;
|
||||||
struct conn_stream *cs = appctx->owner;
|
struct conn_stream *cs = appctx->owner;
|
||||||
|
|
||||||
switch (appctx->st2) {
|
switch (appctx->st2) {
|
||||||
@ -419,23 +434,23 @@ static int cli_io_handler_pats_list(struct appctx *appctx)
|
|||||||
* available field of this pointer is <list>. It is used with the function
|
* available field of this pointer is <list>. It is used with the function
|
||||||
* pat_list_get_next() for returning the first available entry
|
* pat_list_get_next() for returning the first available entry
|
||||||
*/
|
*/
|
||||||
appctx->ctx.map.ref = LIST_ELEM(&pattern_reference, struct pat_ref *, list);
|
ctx->ref = LIST_ELEM(&pattern_reference, struct pat_ref *, list);
|
||||||
appctx->ctx.map.ref = pat_list_get_next(appctx->ctx.map.ref, &pattern_reference,
|
ctx->ref = pat_list_get_next(ctx->ref, &pattern_reference,
|
||||||
appctx->ctx.map.display_flags);
|
ctx->display_flags);
|
||||||
appctx->st2 = STAT_ST_LIST;
|
appctx->st2 = STAT_ST_LIST;
|
||||||
/* fall through */
|
/* fall through */
|
||||||
|
|
||||||
case STAT_ST_LIST:
|
case STAT_ST_LIST:
|
||||||
while (appctx->ctx.map.ref) {
|
while (ctx->ref) {
|
||||||
chunk_reset(&trash);
|
chunk_reset(&trash);
|
||||||
|
|
||||||
/* Build messages. If the reference is used by another category than
|
/* Build messages. If the reference is used by another category than
|
||||||
* the listed categories, display the information in the message.
|
* the listed categories, display the information in the message.
|
||||||
*/
|
*/
|
||||||
chunk_appendf(&trash, "%d (%s) %s. curr_ver=%u next_ver=%u entry_cnt=%llu\n", appctx->ctx.map.ref->unique_id,
|
chunk_appendf(&trash, "%d (%s) %s. curr_ver=%u next_ver=%u entry_cnt=%llu\n", ctx->ref->unique_id,
|
||||||
appctx->ctx.map.ref->reference ? appctx->ctx.map.ref->reference : "",
|
ctx->ref->reference ? ctx->ref->reference : "",
|
||||||
appctx->ctx.map.ref->display, appctx->ctx.map.ref->curr_gen, appctx->ctx.map.ref->next_gen,
|
ctx->ref->display, ctx->ref->curr_gen, ctx->ref->next_gen,
|
||||||
appctx->ctx.map.ref->entry_cnt);
|
ctx->ref->entry_cnt);
|
||||||
|
|
||||||
if (ci_putchk(cs_ic(cs), &trash) == -1) {
|
if (ci_putchk(cs_ic(cs), &trash) == -1) {
|
||||||
/* let's try again later from this stream. We add ourselves into
|
/* let's try again later from this stream. We add ourselves into
|
||||||
@ -446,8 +461,8 @@ static int cli_io_handler_pats_list(struct appctx *appctx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* get next list entry and check the end of the list */
|
/* get next list entry and check the end of the list */
|
||||||
appctx->ctx.map.ref = pat_list_get_next(appctx->ctx.map.ref, &pattern_reference,
|
ctx->ref = pat_list_get_next(ctx->ref, &pattern_reference,
|
||||||
appctx->ctx.map.display_flags);
|
ctx->display_flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fall through */
|
/* fall through */
|
||||||
@ -461,6 +476,7 @@ static int cli_io_handler_pats_list(struct appctx *appctx)
|
|||||||
|
|
||||||
static int cli_io_handler_map_lookup(struct appctx *appctx)
|
static int cli_io_handler_map_lookup(struct appctx *appctx)
|
||||||
{
|
{
|
||||||
|
struct show_map_ctx *ctx = appctx->svcctx;
|
||||||
struct conn_stream *cs = appctx->owner;
|
struct conn_stream *cs = appctx->owner;
|
||||||
struct sample sample;
|
struct sample sample;
|
||||||
struct pattern *pat;
|
struct pattern *pat;
|
||||||
@ -469,48 +485,48 @@ static int cli_io_handler_map_lookup(struct appctx *appctx)
|
|||||||
switch (appctx->st2) {
|
switch (appctx->st2) {
|
||||||
case STAT_ST_INIT:
|
case STAT_ST_INIT:
|
||||||
/* Init to the first entry. The list cannot be change */
|
/* Init to the first entry. The list cannot be change */
|
||||||
appctx->ctx.map.expr = LIST_ELEM(&appctx->ctx.map.ref->pat, struct pattern_expr *, list);
|
ctx->expr = LIST_ELEM(&ctx->ref->pat, struct pattern_expr *, list);
|
||||||
appctx->ctx.map.expr = pat_expr_get_next(appctx->ctx.map.expr, &appctx->ctx.map.ref->pat);
|
ctx->expr = pat_expr_get_next(ctx->expr, &ctx->ref->pat);
|
||||||
appctx->st2 = STAT_ST_LIST;
|
appctx->st2 = STAT_ST_LIST;
|
||||||
/* fall through */
|
/* fall through */
|
||||||
|
|
||||||
case STAT_ST_LIST:
|
case STAT_ST_LIST:
|
||||||
HA_SPIN_LOCK(PATREF_LOCK, &appctx->ctx.map.ref->lock);
|
HA_SPIN_LOCK(PATREF_LOCK, &ctx->ref->lock);
|
||||||
/* for each lookup type */
|
/* for each lookup type */
|
||||||
while (appctx->ctx.map.expr) {
|
while (ctx->expr) {
|
||||||
/* initialise chunk to build new message */
|
/* initialise chunk to build new message */
|
||||||
chunk_reset(&trash);
|
chunk_reset(&trash);
|
||||||
|
|
||||||
/* execute pattern matching */
|
/* execute pattern matching */
|
||||||
sample.data.type = SMP_T_STR;
|
sample.data.type = SMP_T_STR;
|
||||||
sample.flags = SMP_F_CONST;
|
sample.flags = SMP_F_CONST;
|
||||||
sample.data.u.str.data = appctx->ctx.map.chunk.data;
|
sample.data.u.str.data = ctx->chunk.data;
|
||||||
sample.data.u.str.area = appctx->ctx.map.chunk.area;
|
sample.data.u.str.area = ctx->chunk.area;
|
||||||
|
|
||||||
if (appctx->ctx.map.expr->pat_head->match &&
|
if (ctx->expr->pat_head->match &&
|
||||||
sample_convert(&sample, appctx->ctx.map.expr->pat_head->expect_type))
|
sample_convert(&sample, ctx->expr->pat_head->expect_type))
|
||||||
pat = appctx->ctx.map.expr->pat_head->match(&sample, appctx->ctx.map.expr, 1);
|
pat = ctx->expr->pat_head->match(&sample, ctx->expr, 1);
|
||||||
else
|
else
|
||||||
pat = NULL;
|
pat = NULL;
|
||||||
|
|
||||||
/* build return message: set type of match */
|
/* build return message: set type of match */
|
||||||
for (match_method=0; match_method<PAT_MATCH_NUM; match_method++)
|
for (match_method=0; match_method<PAT_MATCH_NUM; match_method++)
|
||||||
if (appctx->ctx.map.expr->pat_head->match == pat_match_fcts[match_method])
|
if (ctx->expr->pat_head->match == pat_match_fcts[match_method])
|
||||||
break;
|
break;
|
||||||
if (match_method >= PAT_MATCH_NUM)
|
if (match_method >= PAT_MATCH_NUM)
|
||||||
chunk_appendf(&trash, "type=unknown(%p)", appctx->ctx.map.expr->pat_head->match);
|
chunk_appendf(&trash, "type=unknown(%p)", ctx->expr->pat_head->match);
|
||||||
else
|
else
|
||||||
chunk_appendf(&trash, "type=%s", pat_match_names[match_method]);
|
chunk_appendf(&trash, "type=%s", pat_match_names[match_method]);
|
||||||
|
|
||||||
/* case sensitive */
|
/* case sensitive */
|
||||||
if (appctx->ctx.map.expr->mflags & PAT_MF_IGNORE_CASE)
|
if (ctx->expr->mflags & PAT_MF_IGNORE_CASE)
|
||||||
chunk_appendf(&trash, ", case=insensitive");
|
chunk_appendf(&trash, ", case=insensitive");
|
||||||
else
|
else
|
||||||
chunk_appendf(&trash, ", case=sensitive");
|
chunk_appendf(&trash, ", case=sensitive");
|
||||||
|
|
||||||
/* Display no match, and set default value */
|
/* Display no match, and set default value */
|
||||||
if (!pat) {
|
if (!pat) {
|
||||||
if (appctx->ctx.map.display_flags == PAT_REF_MAP)
|
if (ctx->display_flags == PAT_REF_MAP)
|
||||||
chunk_appendf(&trash, ", found=no");
|
chunk_appendf(&trash, ", found=no");
|
||||||
else
|
else
|
||||||
chunk_appendf(&trash, ", match=no");
|
chunk_appendf(&trash, ", match=no");
|
||||||
@ -519,7 +535,7 @@ static int cli_io_handler_map_lookup(struct appctx *appctx)
|
|||||||
/* Display match and match info */
|
/* Display match and match info */
|
||||||
else {
|
else {
|
||||||
/* display match */
|
/* display match */
|
||||||
if (appctx->ctx.map.display_flags == PAT_REF_MAP)
|
if (ctx->display_flags == PAT_REF_MAP)
|
||||||
chunk_appendf(&trash, ", found=yes");
|
chunk_appendf(&trash, ", found=yes");
|
||||||
else
|
else
|
||||||
chunk_appendf(&trash, ", match=yes");
|
chunk_appendf(&trash, ", match=yes");
|
||||||
@ -531,7 +547,7 @@ static int cli_io_handler_map_lookup(struct appctx *appctx)
|
|||||||
chunk_appendf(&trash, ", idx=list");
|
chunk_appendf(&trash, ", idx=list");
|
||||||
|
|
||||||
/* display pattern */
|
/* display pattern */
|
||||||
if (appctx->ctx.map.display_flags == PAT_REF_MAP) {
|
if (ctx->display_flags == PAT_REF_MAP) {
|
||||||
if (pat->ref && pat->ref->pattern)
|
if (pat->ref && pat->ref->pattern)
|
||||||
chunk_appendf(&trash, ", key=\"%s\"", pat->ref->pattern);
|
chunk_appendf(&trash, ", key=\"%s\"", pat->ref->pattern);
|
||||||
else
|
else
|
||||||
@ -545,7 +561,7 @@ static int cli_io_handler_map_lookup(struct appctx *appctx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* display return value */
|
/* display return value */
|
||||||
if (appctx->ctx.map.display_flags == PAT_REF_MAP) {
|
if (ctx->display_flags == PAT_REF_MAP) {
|
||||||
if (pat->data && pat->ref && pat->ref->sample)
|
if (pat->data && pat->ref && pat->ref->sample)
|
||||||
chunk_appendf(&trash, ", value=\"%s\", type=\"%s\"", pat->ref->sample,
|
chunk_appendf(&trash, ", value=\"%s\", type=\"%s\"", pat->ref->sample,
|
||||||
smp_to_type[pat->data->type]);
|
smp_to_type[pat->data->type]);
|
||||||
@ -561,16 +577,16 @@ static int cli_io_handler_map_lookup(struct appctx *appctx)
|
|||||||
/* let's try again later from this stream. We add ourselves into
|
/* let's try again later from this stream. We add ourselves into
|
||||||
* this stream's users so that it can remove us upon termination.
|
* this stream's users so that it can remove us upon termination.
|
||||||
*/
|
*/
|
||||||
HA_SPIN_UNLOCK(PATREF_LOCK, &appctx->ctx.map.ref->lock);
|
HA_SPIN_UNLOCK(PATREF_LOCK, &ctx->ref->lock);
|
||||||
cs_rx_room_blk(cs);
|
cs_rx_room_blk(cs);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get next entry */
|
/* get next entry */
|
||||||
appctx->ctx.map.expr = pat_expr_get_next(appctx->ctx.map.expr,
|
ctx->expr = pat_expr_get_next(ctx->expr,
|
||||||
&appctx->ctx.map.ref->pat);
|
&ctx->ref->pat);
|
||||||
}
|
}
|
||||||
HA_SPIN_UNLOCK(PATREF_LOCK, &appctx->ctx.map.ref->lock);
|
HA_SPIN_UNLOCK(PATREF_LOCK, &ctx->ref->lock);
|
||||||
/* fall through */
|
/* fall through */
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -581,31 +597,35 @@ static int cli_io_handler_map_lookup(struct appctx *appctx)
|
|||||||
|
|
||||||
static void cli_release_mlook(struct appctx *appctx)
|
static void cli_release_mlook(struct appctx *appctx)
|
||||||
{
|
{
|
||||||
ha_free(&appctx->ctx.map.chunk.area);
|
struct show_map_ctx *ctx = appctx->svcctx;
|
||||||
|
|
||||||
|
ha_free(&ctx->chunk.area);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int cli_parse_get_map(char **args, char *payload, struct appctx *appctx, void *private)
|
static int cli_parse_get_map(char **args, char *payload, struct appctx *appctx, void *private)
|
||||||
{
|
{
|
||||||
|
struct show_map_ctx *ctx = applet_reserve_svcctx(appctx, sizeof(*ctx));
|
||||||
|
|
||||||
if (strcmp(args[1], "map") == 0 || strcmp(args[1], "acl") == 0) {
|
if (strcmp(args[1], "map") == 0 || strcmp(args[1], "acl") == 0) {
|
||||||
/* Set flags. */
|
/* Set flags. */
|
||||||
if (args[1][0] == 'm')
|
if (args[1][0] == 'm')
|
||||||
appctx->ctx.map.display_flags = PAT_REF_MAP;
|
ctx->display_flags = PAT_REF_MAP;
|
||||||
else
|
else
|
||||||
appctx->ctx.map.display_flags = PAT_REF_ACL;
|
ctx->display_flags = PAT_REF_ACL;
|
||||||
|
|
||||||
/* No parameter. */
|
/* No parameter. */
|
||||||
if (!*args[2] || !*args[3]) {
|
if (!*args[2] || !*args[3]) {
|
||||||
if (appctx->ctx.map.display_flags == PAT_REF_MAP)
|
if (ctx->display_flags == PAT_REF_MAP)
|
||||||
return cli_err(appctx, "Missing map identifier and/or key.\n");
|
return cli_err(appctx, "Missing map identifier and/or key.\n");
|
||||||
else
|
else
|
||||||
return cli_err(appctx, "Missing ACL identifier and/or key.\n");
|
return cli_err(appctx, "Missing ACL identifier and/or key.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* lookup into the maps */
|
/* lookup into the maps */
|
||||||
appctx->ctx.map.ref = pat_ref_lookup_ref(args[2]);
|
ctx->ref = pat_ref_lookup_ref(args[2]);
|
||||||
if (!appctx->ctx.map.ref) {
|
if (!ctx->ref) {
|
||||||
if (appctx->ctx.map.display_flags == PAT_REF_MAP)
|
if (ctx->display_flags == PAT_REF_MAP)
|
||||||
return cli_err(appctx, "Unknown map identifier. Please use #<id> or <file>.\n");
|
return cli_err(appctx, "Unknown map identifier. Please use #<id> or <file>.\n");
|
||||||
else
|
else
|
||||||
return cli_err(appctx, "Unknown ACL identifier. Please use #<id> or <file>.\n");
|
return cli_err(appctx, "Unknown ACL identifier. Please use #<id> or <file>.\n");
|
||||||
@ -615,10 +635,10 @@ static int cli_parse_get_map(char **args, char *payload, struct appctx *appctx,
|
|||||||
* it may be used over multiple iterations. It's released
|
* it may be used over multiple iterations. It's released
|
||||||
* at the end and upon abort anyway.
|
* at the end and upon abort anyway.
|
||||||
*/
|
*/
|
||||||
appctx->ctx.map.chunk.data = strlen(args[3]);
|
ctx->chunk.data = strlen(args[3]);
|
||||||
appctx->ctx.map.chunk.size = appctx->ctx.map.chunk.data + 1;
|
ctx->chunk.size = ctx->chunk.data + 1;
|
||||||
appctx->ctx.map.chunk.area = strdup(args[3]);
|
ctx->chunk.area = strdup(args[3]);
|
||||||
if (!appctx->ctx.map.chunk.area)
|
if (!ctx->chunk.area)
|
||||||
return cli_err(appctx, "Out of memory error.\n");
|
return cli_err(appctx, "Out of memory error.\n");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -628,6 +648,8 @@ static int cli_parse_get_map(char **args, char *payload, struct appctx *appctx,
|
|||||||
|
|
||||||
static int cli_parse_prepare_map(char **args, char *payload, struct appctx *appctx, void *private)
|
static int cli_parse_prepare_map(char **args, char *payload, struct appctx *appctx, void *private)
|
||||||
{
|
{
|
||||||
|
struct show_map_ctx *ctx = applet_reserve_svcctx(appctx, sizeof(*ctx));
|
||||||
|
|
||||||
if (strcmp(args[1], "map") == 0 ||
|
if (strcmp(args[1], "map") == 0 ||
|
||||||
strcmp(args[1], "acl") == 0) {
|
strcmp(args[1], "acl") == 0) {
|
||||||
uint next_gen;
|
uint next_gen;
|
||||||
@ -635,20 +657,20 @@ static int cli_parse_prepare_map(char **args, char *payload, struct appctx *appc
|
|||||||
|
|
||||||
/* Set ACL or MAP flags. */
|
/* Set ACL or MAP flags. */
|
||||||
if (args[1][0] == 'm')
|
if (args[1][0] == 'm')
|
||||||
appctx->ctx.map.display_flags = PAT_REF_MAP;
|
ctx->display_flags = PAT_REF_MAP;
|
||||||
else
|
else
|
||||||
appctx->ctx.map.display_flags = PAT_REF_ACL;
|
ctx->display_flags = PAT_REF_ACL;
|
||||||
|
|
||||||
/* lookup into the refs and check the map flag */
|
/* lookup into the refs and check the map flag */
|
||||||
appctx->ctx.map.ref = pat_ref_lookup_ref(args[2]);
|
ctx->ref = pat_ref_lookup_ref(args[2]);
|
||||||
if (!appctx->ctx.map.ref ||
|
if (!ctx->ref ||
|
||||||
!(appctx->ctx.map.ref->flags & appctx->ctx.map.display_flags)) {
|
!(ctx->ref->flags & ctx->display_flags)) {
|
||||||
if (appctx->ctx.map.display_flags == PAT_REF_MAP)
|
if (ctx->display_flags == PAT_REF_MAP)
|
||||||
return cli_err(appctx, "Unknown map identifier. Please use #<id> or <file>.\n");
|
return cli_err(appctx, "Unknown map identifier. Please use #<id> or <file>.\n");
|
||||||
else
|
else
|
||||||
return cli_err(appctx, "Unknown ACL identifier. Please use #<id> or <file>.\n");
|
return cli_err(appctx, "Unknown ACL identifier. Please use #<id> or <file>.\n");
|
||||||
}
|
}
|
||||||
next_gen = pat_ref_newgen(appctx->ctx.map.ref);
|
next_gen = pat_ref_newgen(ctx->ref);
|
||||||
return cli_dynmsg(appctx, LOG_INFO, memprintf(&msg, "New version created: %u\n", next_gen));
|
return cli_dynmsg(appctx, LOG_INFO, memprintf(&msg, "New version created: %u\n", next_gen));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -657,25 +679,29 @@ static int cli_parse_prepare_map(char **args, char *payload, struct appctx *appc
|
|||||||
|
|
||||||
static void cli_release_show_map(struct appctx *appctx)
|
static void cli_release_show_map(struct appctx *appctx)
|
||||||
{
|
{
|
||||||
|
struct show_map_ctx *ctx = appctx->svcctx;
|
||||||
|
|
||||||
if (appctx->st2 == STAT_ST_LIST) {
|
if (appctx->st2 == STAT_ST_LIST) {
|
||||||
HA_SPIN_LOCK(PATREF_LOCK, &appctx->ctx.map.ref->lock);
|
HA_SPIN_LOCK(PATREF_LOCK, &ctx->ref->lock);
|
||||||
if (!LIST_ISEMPTY(&appctx->ctx.map.bref.users))
|
if (!LIST_ISEMPTY(&ctx->bref.users))
|
||||||
LIST_DELETE(&appctx->ctx.map.bref.users);
|
LIST_DELETE(&ctx->bref.users);
|
||||||
HA_SPIN_UNLOCK(PATREF_LOCK, &appctx->ctx.map.ref->lock);
|
HA_SPIN_UNLOCK(PATREF_LOCK, &ctx->ref->lock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cli_parse_show_map(char **args, char *payload, struct appctx *appctx, void *private)
|
static int cli_parse_show_map(char **args, char *payload, struct appctx *appctx, void *private)
|
||||||
{
|
{
|
||||||
|
struct show_map_ctx *ctx = applet_reserve_svcctx(appctx, sizeof(*ctx));
|
||||||
|
|
||||||
if (strcmp(args[1], "map") == 0 ||
|
if (strcmp(args[1], "map") == 0 ||
|
||||||
strcmp(args[1], "acl") == 0) {
|
strcmp(args[1], "acl") == 0) {
|
||||||
const char *gen = NULL;
|
const char *gen = NULL;
|
||||||
|
|
||||||
/* Set ACL or MAP flags. */
|
/* Set ACL or MAP flags. */
|
||||||
if (args[1][0] == 'm')
|
if (args[1][0] == 'm')
|
||||||
appctx->ctx.map.display_flags = PAT_REF_MAP;
|
ctx->display_flags = PAT_REF_MAP;
|
||||||
else
|
else
|
||||||
appctx->ctx.map.display_flags = PAT_REF_ACL;
|
ctx->display_flags = PAT_REF_ACL;
|
||||||
|
|
||||||
/* no parameter: display all map available */
|
/* no parameter: display all map available */
|
||||||
if (!*args[2]) {
|
if (!*args[2]) {
|
||||||
@ -693,10 +719,10 @@ static int cli_parse_show_map(char **args, char *payload, struct appctx *appctx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* lookup into the refs and check the map flag */
|
/* lookup into the refs and check the map flag */
|
||||||
appctx->ctx.map.ref = pat_ref_lookup_ref(args[2]);
|
ctx->ref = pat_ref_lookup_ref(args[2]);
|
||||||
if (!appctx->ctx.map.ref ||
|
if (!ctx->ref ||
|
||||||
!(appctx->ctx.map.ref->flags & appctx->ctx.map.display_flags)) {
|
!(ctx->ref->flags & ctx->display_flags)) {
|
||||||
if (appctx->ctx.map.display_flags == PAT_REF_MAP)
|
if (ctx->display_flags == PAT_REF_MAP)
|
||||||
return cli_err(appctx, "Unknown map identifier. Please use #<id> or <file>.\n");
|
return cli_err(appctx, "Unknown map identifier. Please use #<id> or <file>.\n");
|
||||||
else
|
else
|
||||||
return cli_err(appctx, "Unknown ACL identifier. Please use #<id> or <file>.\n");
|
return cli_err(appctx, "Unknown ACL identifier. Please use #<id> or <file>.\n");
|
||||||
@ -706,9 +732,9 @@ static int cli_parse_show_map(char **args, char *payload, struct appctx *appctx,
|
|||||||
if (gen)
|
if (gen)
|
||||||
appctx->ctx.cli.i0 = str2uic(gen);
|
appctx->ctx.cli.i0 = str2uic(gen);
|
||||||
else
|
else
|
||||||
appctx->ctx.cli.i0 = appctx->ctx.map.ref->curr_gen;
|
appctx->ctx.cli.i0 = ctx->ref->curr_gen;
|
||||||
|
|
||||||
LIST_INIT(&appctx->ctx.map.bref.users);
|
LIST_INIT(&ctx->bref.users);
|
||||||
appctx->io_handler = cli_io_handler_pat_list;
|
appctx->io_handler = cli_io_handler_pat_list;
|
||||||
appctx->io_release = cli_release_show_map;
|
appctx->io_release = cli_release_show_map;
|
||||||
return 0;
|
return 0;
|
||||||
@ -719,19 +745,21 @@ static int cli_parse_show_map(char **args, char *payload, struct appctx *appctx,
|
|||||||
|
|
||||||
static int cli_parse_set_map(char **args, char *payload, struct appctx *appctx, void *private)
|
static int cli_parse_set_map(char **args, char *payload, struct appctx *appctx, void *private)
|
||||||
{
|
{
|
||||||
|
struct show_map_ctx *ctx = applet_reserve_svcctx(appctx, sizeof(*ctx));
|
||||||
|
|
||||||
if (strcmp(args[1], "map") == 0) {
|
if (strcmp(args[1], "map") == 0) {
|
||||||
char *err;
|
char *err;
|
||||||
|
|
||||||
/* Set flags. */
|
/* Set flags. */
|
||||||
appctx->ctx.map.display_flags = PAT_REF_MAP;
|
ctx->display_flags = PAT_REF_MAP;
|
||||||
|
|
||||||
/* Expect three parameters: map name, key and new value. */
|
/* Expect three parameters: map name, key and new value. */
|
||||||
if (!*args[2] || !*args[3] || !*args[4])
|
if (!*args[2] || !*args[3] || !*args[4])
|
||||||
return cli_err(appctx, "'set map' expects three parameters: map identifier, key and value.\n");
|
return cli_err(appctx, "'set map' expects three parameters: map identifier, key and value.\n");
|
||||||
|
|
||||||
/* Lookup the reference in the maps. */
|
/* Lookup the reference in the maps. */
|
||||||
appctx->ctx.map.ref = pat_ref_lookup_ref(args[2]);
|
ctx->ref = pat_ref_lookup_ref(args[2]);
|
||||||
if (!appctx->ctx.map.ref)
|
if (!ctx->ref)
|
||||||
return cli_err(appctx, "Unknown map identifier. Please use #<id> or <file>.\n");
|
return cli_err(appctx, "Unknown map identifier. Please use #<id> or <file>.\n");
|
||||||
|
|
||||||
/* If the entry identifier start with a '#', it is considered as
|
/* If the entry identifier start with a '#', it is considered as
|
||||||
@ -754,30 +782,30 @@ static int cli_parse_set_map(char **args, char *payload, struct appctx *appctx,
|
|||||||
|
|
||||||
/* Try to modify the entry. */
|
/* Try to modify the entry. */
|
||||||
err = NULL;
|
err = NULL;
|
||||||
HA_SPIN_LOCK(PATREF_LOCK, &appctx->ctx.map.ref->lock);
|
HA_SPIN_LOCK(PATREF_LOCK, &ctx->ref->lock);
|
||||||
if (!pat_ref_set_by_id(appctx->ctx.map.ref, ref, args[4], &err)) {
|
if (!pat_ref_set_by_id(ctx->ref, ref, args[4], &err)) {
|
||||||
HA_SPIN_UNLOCK(PATREF_LOCK, &appctx->ctx.map.ref->lock);
|
HA_SPIN_UNLOCK(PATREF_LOCK, &ctx->ref->lock);
|
||||||
if (err)
|
if (err)
|
||||||
return cli_dynerr(appctx, memprintf(&err, "%s.\n", err));
|
return cli_dynerr(appctx, memprintf(&err, "%s.\n", err));
|
||||||
else
|
else
|
||||||
return cli_err(appctx, "Failed to update an entry.\n");
|
return cli_err(appctx, "Failed to update an entry.\n");
|
||||||
}
|
}
|
||||||
HA_SPIN_UNLOCK(PATREF_LOCK, &appctx->ctx.map.ref->lock);
|
HA_SPIN_UNLOCK(PATREF_LOCK, &ctx->ref->lock);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Else, use the entry identifier as pattern
|
/* Else, use the entry identifier as pattern
|
||||||
* string, and update the value.
|
* string, and update the value.
|
||||||
*/
|
*/
|
||||||
err = NULL;
|
err = NULL;
|
||||||
HA_SPIN_LOCK(PATREF_LOCK, &appctx->ctx.map.ref->lock);
|
HA_SPIN_LOCK(PATREF_LOCK, &ctx->ref->lock);
|
||||||
if (!pat_ref_set(appctx->ctx.map.ref, args[3], args[4], &err)) {
|
if (!pat_ref_set(ctx->ref, args[3], args[4], &err)) {
|
||||||
HA_SPIN_UNLOCK(PATREF_LOCK, &appctx->ctx.map.ref->lock);
|
HA_SPIN_UNLOCK(PATREF_LOCK, &ctx->ref->lock);
|
||||||
if (err)
|
if (err)
|
||||||
return cli_dynerr(appctx, memprintf(&err, "%s.\n", err));
|
return cli_dynerr(appctx, memprintf(&err, "%s.\n", err));
|
||||||
else
|
else
|
||||||
return cli_err(appctx, "Failed to update an entry.\n");
|
return cli_err(appctx, "Failed to update an entry.\n");
|
||||||
}
|
}
|
||||||
HA_SPIN_UNLOCK(PATREF_LOCK, &appctx->ctx.map.ref->lock);
|
HA_SPIN_UNLOCK(PATREF_LOCK, &ctx->ref->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The set is done, send message. */
|
/* The set is done, send message. */
|
||||||
@ -789,6 +817,8 @@ static int cli_parse_set_map(char **args, char *payload, struct appctx *appctx,
|
|||||||
|
|
||||||
static int cli_parse_add_map(char **args, char *payload, struct appctx *appctx, void *private)
|
static int cli_parse_add_map(char **args, char *payload, struct appctx *appctx, void *private)
|
||||||
{
|
{
|
||||||
|
struct show_map_ctx *ctx = applet_reserve_svcctx(appctx, sizeof(*ctx));
|
||||||
|
|
||||||
if (strcmp(args[1], "map") == 0 ||
|
if (strcmp(args[1], "map") == 0 ||
|
||||||
strcmp(args[1], "acl") == 0) {
|
strcmp(args[1], "acl") == 0) {
|
||||||
const char *gen = NULL;
|
const char *gen = NULL;
|
||||||
@ -798,9 +828,9 @@ static int cli_parse_add_map(char **args, char *payload, struct appctx *appctx,
|
|||||||
|
|
||||||
/* Set flags. */
|
/* Set flags. */
|
||||||
if (args[1][0] == 'm')
|
if (args[1][0] == 'm')
|
||||||
appctx->ctx.map.display_flags = PAT_REF_MAP;
|
ctx->display_flags = PAT_REF_MAP;
|
||||||
else
|
else
|
||||||
appctx->ctx.map.display_flags = PAT_REF_ACL;
|
ctx->display_flags = PAT_REF_ACL;
|
||||||
|
|
||||||
/* For both "map" and "acl" we may have an optional generation
|
/* For both "map" and "acl" we may have an optional generation
|
||||||
* number specified using a "@" character before the pattern
|
* number specified using a "@" character before the pattern
|
||||||
@ -816,7 +846,7 @@ static int cli_parse_add_map(char **args, char *payload, struct appctx *appctx,
|
|||||||
* - one parameter if there is a payload
|
* - one parameter if there is a payload
|
||||||
* If it is "acl", we expect only two parameters
|
* If it is "acl", we expect only two parameters
|
||||||
*/
|
*/
|
||||||
if (appctx->ctx.map.display_flags == PAT_REF_MAP) {
|
if (ctx->display_flags == PAT_REF_MAP) {
|
||||||
if ((!payload && (!*args[2] || !*args[3] || !*args[4])) ||
|
if ((!payload && (!*args[2] || !*args[3] || !*args[4])) ||
|
||||||
(payload && !*args[2]))
|
(payload && !*args[2]))
|
||||||
return cli_err(appctx,
|
return cli_err(appctx,
|
||||||
@ -827,9 +857,9 @@ static int cli_parse_add_map(char **args, char *payload, struct appctx *appctx,
|
|||||||
return cli_err(appctx, "'add acl' expects two parameters: ACL identifier and pattern.\n");
|
return cli_err(appctx, "'add acl' expects two parameters: ACL identifier and pattern.\n");
|
||||||
|
|
||||||
/* Lookup for the reference. */
|
/* Lookup for the reference. */
|
||||||
appctx->ctx.map.ref = pat_ref_lookup_ref(args[2]);
|
ctx->ref = pat_ref_lookup_ref(args[2]);
|
||||||
if (!appctx->ctx.map.ref) {
|
if (!ctx->ref) {
|
||||||
if (appctx->ctx.map.display_flags == PAT_REF_MAP)
|
if (ctx->display_flags == PAT_REF_MAP)
|
||||||
return cli_err(appctx, "Unknown map identifier. Please use #<id> or <file>.\n");
|
return cli_err(appctx, "Unknown map identifier. Please use #<id> or <file>.\n");
|
||||||
else
|
else
|
||||||
return cli_err(appctx, "Unknown ACL identifier. Please use #<id> or <file>.\n");
|
return cli_err(appctx, "Unknown ACL identifier. Please use #<id> or <file>.\n");
|
||||||
@ -837,8 +867,8 @@ static int cli_parse_add_map(char **args, char *payload, struct appctx *appctx,
|
|||||||
|
|
||||||
if (gen) {
|
if (gen) {
|
||||||
genid = str2uic(gen);
|
genid = str2uic(gen);
|
||||||
if ((int)(genid - appctx->ctx.map.ref->next_gen) > 0) {
|
if ((int)(genid - ctx->ref->next_gen) > 0) {
|
||||||
if (appctx->ctx.map.display_flags == PAT_REF_MAP)
|
if (ctx->display_flags == PAT_REF_MAP)
|
||||||
return cli_err(appctx, "Version number in the future, please use 'prepare map' before.\n");
|
return cli_err(appctx, "Version number in the future, please use 'prepare map' before.\n");
|
||||||
else
|
else
|
||||||
return cli_err(appctx, "Version number in the future, please use 'prepare acl' before.\n");
|
return cli_err(appctx, "Version number in the future, please use 'prepare acl' before.\n");
|
||||||
@ -848,8 +878,8 @@ static int cli_parse_add_map(char **args, char *payload, struct appctx *appctx,
|
|||||||
/* The command "add acl" is prohibited if the reference
|
/* The command "add acl" is prohibited if the reference
|
||||||
* use samples.
|
* use samples.
|
||||||
*/
|
*/
|
||||||
if ((appctx->ctx.map.display_flags & PAT_REF_ACL) &&
|
if ((ctx->display_flags & PAT_REF_ACL) &&
|
||||||
(appctx->ctx.map.ref->flags & PAT_REF_SMP)) {
|
(ctx->ref->flags & PAT_REF_SMP)) {
|
||||||
return cli_err(appctx,
|
return cli_err(appctx,
|
||||||
"This ACL is shared with a map containing samples. "
|
"This ACL is shared with a map containing samples. "
|
||||||
"You must use the command 'add map' to add values.\n");
|
"You must use the command 'add map' to add values.\n");
|
||||||
@ -876,7 +906,7 @@ static int cli_parse_add_map(char **args, char *payload, struct appctx *appctx,
|
|||||||
l = strcspn(key, " \t");
|
l = strcspn(key, " \t");
|
||||||
payload += l;
|
payload += l;
|
||||||
|
|
||||||
if (!*payload && appctx->ctx.map.display_flags == PAT_REF_MAP)
|
if (!*payload && ctx->display_flags == PAT_REF_MAP)
|
||||||
return cli_dynerr(appctx, memprintf(&err, "Missing value for key '%s'.\n", key));
|
return cli_dynerr(appctx, memprintf(&err, "Missing value for key '%s'.\n", key));
|
||||||
|
|
||||||
key[l] = 0;
|
key[l] = 0;
|
||||||
@ -892,12 +922,12 @@ static int cli_parse_add_map(char **args, char *payload, struct appctx *appctx,
|
|||||||
value[l] = 0;
|
value[l] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (appctx->ctx.map.display_flags != PAT_REF_MAP)
|
if (ctx->display_flags != PAT_REF_MAP)
|
||||||
value = NULL;
|
value = NULL;
|
||||||
|
|
||||||
HA_SPIN_LOCK(PATREF_LOCK, &appctx->ctx.map.ref->lock);
|
HA_SPIN_LOCK(PATREF_LOCK, &ctx->ref->lock);
|
||||||
ret = !!pat_ref_load(appctx->ctx.map.ref, gen ? genid : appctx->ctx.map.ref->curr_gen, key, value, -1, &err);
|
ret = !!pat_ref_load(ctx->ref, gen ? genid : ctx->ref->curr_gen, key, value, -1, &err);
|
||||||
HA_SPIN_UNLOCK(PATREF_LOCK, &appctx->ctx.map.ref->lock);
|
HA_SPIN_UNLOCK(PATREF_LOCK, &ctx->ref->lock);
|
||||||
|
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
if (err)
|
if (err)
|
||||||
@ -917,23 +947,25 @@ static int cli_parse_add_map(char **args, char *payload, struct appctx *appctx,
|
|||||||
|
|
||||||
static int cli_parse_del_map(char **args, char *payload, struct appctx *appctx, void *private)
|
static int cli_parse_del_map(char **args, char *payload, struct appctx *appctx, void *private)
|
||||||
{
|
{
|
||||||
|
struct show_map_ctx *ctx = applet_reserve_svcctx(appctx, sizeof(*ctx));
|
||||||
|
|
||||||
if (args[1][0] == 'm')
|
if (args[1][0] == 'm')
|
||||||
appctx->ctx.map.display_flags = PAT_REF_MAP;
|
ctx->display_flags = PAT_REF_MAP;
|
||||||
else
|
else
|
||||||
appctx->ctx.map.display_flags = PAT_REF_ACL;
|
ctx->display_flags = PAT_REF_ACL;
|
||||||
|
|
||||||
/* Expect two parameters: map name and key. */
|
/* Expect two parameters: map name and key. */
|
||||||
if (!*args[2] || !*args[3]) {
|
if (!*args[2] || !*args[3]) {
|
||||||
if (appctx->ctx.map.display_flags == PAT_REF_MAP)
|
if (ctx->display_flags == PAT_REF_MAP)
|
||||||
return cli_err(appctx, "This command expects two parameters: map identifier and key.\n");
|
return cli_err(appctx, "This command expects two parameters: map identifier and key.\n");
|
||||||
else
|
else
|
||||||
return cli_err(appctx, "This command expects two parameters: ACL identifier and key.\n");
|
return cli_err(appctx, "This command expects two parameters: ACL identifier and key.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Lookup the reference in the maps. */
|
/* Lookup the reference in the maps. */
|
||||||
appctx->ctx.map.ref = pat_ref_lookup_ref(args[2]);
|
ctx->ref = pat_ref_lookup_ref(args[2]);
|
||||||
if (!appctx->ctx.map.ref ||
|
if (!ctx->ref ||
|
||||||
!(appctx->ctx.map.ref->flags & appctx->ctx.map.display_flags))
|
!(ctx->ref->flags & ctx->display_flags))
|
||||||
return cli_err(appctx, "Unknown map identifier. Please use #<id> or <file>.\n");
|
return cli_err(appctx, "Unknown map identifier. Please use #<id> or <file>.\n");
|
||||||
|
|
||||||
/* If the entry identifier start with a '#', it is considered as
|
/* If the entry identifier start with a '#', it is considered as
|
||||||
@ -955,25 +987,25 @@ static int cli_parse_del_map(char **args, char *payload, struct appctx *appctx,
|
|||||||
return cli_err(appctx, "Malformed identifier. Please use #<id> or <file>.\n");
|
return cli_err(appctx, "Malformed identifier. Please use #<id> or <file>.\n");
|
||||||
|
|
||||||
/* Try to delete the entry. */
|
/* Try to delete the entry. */
|
||||||
HA_SPIN_LOCK(PATREF_LOCK, &appctx->ctx.map.ref->lock);
|
HA_SPIN_LOCK(PATREF_LOCK, &ctx->ref->lock);
|
||||||
if (!pat_ref_delete_by_id(appctx->ctx.map.ref, ref)) {
|
if (!pat_ref_delete_by_id(ctx->ref, ref)) {
|
||||||
HA_SPIN_UNLOCK(PATREF_LOCK, &appctx->ctx.map.ref->lock);
|
HA_SPIN_UNLOCK(PATREF_LOCK, &ctx->ref->lock);
|
||||||
/* The entry is not found, send message. */
|
/* The entry is not found, send message. */
|
||||||
return cli_err(appctx, "Key not found.\n");
|
return cli_err(appctx, "Key not found.\n");
|
||||||
}
|
}
|
||||||
HA_SPIN_UNLOCK(PATREF_LOCK, &appctx->ctx.map.ref->lock);
|
HA_SPIN_UNLOCK(PATREF_LOCK, &ctx->ref->lock);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Else, use the entry identifier as pattern
|
/* Else, use the entry identifier as pattern
|
||||||
* string and try to delete the entry.
|
* string and try to delete the entry.
|
||||||
*/
|
*/
|
||||||
HA_SPIN_LOCK(PATREF_LOCK, &appctx->ctx.map.ref->lock);
|
HA_SPIN_LOCK(PATREF_LOCK, &ctx->ref->lock);
|
||||||
if (!pat_ref_delete(appctx->ctx.map.ref, args[3])) {
|
if (!pat_ref_delete(ctx->ref, args[3])) {
|
||||||
HA_SPIN_UNLOCK(PATREF_LOCK, &appctx->ctx.map.ref->lock);
|
HA_SPIN_UNLOCK(PATREF_LOCK, &ctx->ref->lock);
|
||||||
/* The entry is not found, send message. */
|
/* The entry is not found, send message. */
|
||||||
return cli_err(appctx, "Key not found.\n");
|
return cli_err(appctx, "Key not found.\n");
|
||||||
}
|
}
|
||||||
HA_SPIN_UNLOCK(PATREF_LOCK, &appctx->ctx.map.ref->lock);
|
HA_SPIN_UNLOCK(PATREF_LOCK, &ctx->ref->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The deletion is done, send message. */
|
/* The deletion is done, send message. */
|
||||||
@ -987,11 +1019,12 @@ static int cli_parse_del_map(char **args, char *payload, struct appctx *appctx,
|
|||||||
*/
|
*/
|
||||||
static int cli_io_handler_clear_map(struct appctx *appctx)
|
static int cli_io_handler_clear_map(struct appctx *appctx)
|
||||||
{
|
{
|
||||||
|
struct show_map_ctx *ctx = appctx->svcctx;
|
||||||
int finished;
|
int finished;
|
||||||
|
|
||||||
HA_SPIN_LOCK(PATREF_LOCK, &appctx->ctx.map.ref->lock);
|
HA_SPIN_LOCK(PATREF_LOCK, &ctx->ref->lock);
|
||||||
finished = pat_ref_purge_range(appctx->ctx.map.ref, appctx->ctx.cli.i0, appctx->ctx.cli.i1, 100);
|
finished = pat_ref_purge_range(ctx->ref, appctx->ctx.cli.i0, appctx->ctx.cli.i1, 100);
|
||||||
HA_SPIN_UNLOCK(PATREF_LOCK, &appctx->ctx.map.ref->lock);
|
HA_SPIN_UNLOCK(PATREF_LOCK, &ctx->ref->lock);
|
||||||
|
|
||||||
if (!finished) {
|
if (!finished) {
|
||||||
/* let's come back later */
|
/* let's come back later */
|
||||||
@ -1007,14 +1040,16 @@ static int cli_io_handler_clear_map(struct appctx *appctx)
|
|||||||
*/
|
*/
|
||||||
static int cli_parse_clear_map(char **args, char *payload, struct appctx *appctx, void *private)
|
static int cli_parse_clear_map(char **args, char *payload, struct appctx *appctx, void *private)
|
||||||
{
|
{
|
||||||
|
struct show_map_ctx *ctx = applet_reserve_svcctx(appctx, sizeof(*ctx));
|
||||||
|
|
||||||
if (strcmp(args[1], "map") == 0 || strcmp(args[1], "acl") == 0) {
|
if (strcmp(args[1], "map") == 0 || strcmp(args[1], "acl") == 0) {
|
||||||
const char *gen = NULL;
|
const char *gen = NULL;
|
||||||
|
|
||||||
/* Set ACL or MAP flags. */
|
/* Set ACL or MAP flags. */
|
||||||
if (args[1][0] == 'm')
|
if (args[1][0] == 'm')
|
||||||
appctx->ctx.map.display_flags = PAT_REF_MAP;
|
ctx->display_flags = PAT_REF_MAP;
|
||||||
else
|
else
|
||||||
appctx->ctx.map.display_flags = PAT_REF_ACL;
|
ctx->display_flags = PAT_REF_ACL;
|
||||||
|
|
||||||
/* For both "map" and "acl" we may have an optional generation
|
/* For both "map" and "acl" we may have an optional generation
|
||||||
* number specified using a "@" character before the pattern
|
* number specified using a "@" character before the pattern
|
||||||
@ -1027,17 +1062,17 @@ static int cli_parse_clear_map(char **args, char *payload, struct appctx *appctx
|
|||||||
|
|
||||||
/* no parameter */
|
/* no parameter */
|
||||||
if (!*args[2]) {
|
if (!*args[2]) {
|
||||||
if (appctx->ctx.map.display_flags == PAT_REF_MAP)
|
if (ctx->display_flags == PAT_REF_MAP)
|
||||||
return cli_err(appctx, "Missing map identifier.\n");
|
return cli_err(appctx, "Missing map identifier.\n");
|
||||||
else
|
else
|
||||||
return cli_err(appctx, "Missing ACL identifier.\n");
|
return cli_err(appctx, "Missing ACL identifier.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* lookup into the refs and check the map flag */
|
/* lookup into the refs and check the map flag */
|
||||||
appctx->ctx.map.ref = pat_ref_lookup_ref(args[2]);
|
ctx->ref = pat_ref_lookup_ref(args[2]);
|
||||||
if (!appctx->ctx.map.ref ||
|
if (!ctx->ref ||
|
||||||
!(appctx->ctx.map.ref->flags & appctx->ctx.map.display_flags)) {
|
!(ctx->ref->flags & ctx->display_flags)) {
|
||||||
if (appctx->ctx.map.display_flags == PAT_REF_MAP)
|
if (ctx->display_flags == PAT_REF_MAP)
|
||||||
return cli_err(appctx, "Unknown map identifier. Please use #<id> or <file>.\n");
|
return cli_err(appctx, "Unknown map identifier. Please use #<id> or <file>.\n");
|
||||||
else
|
else
|
||||||
return cli_err(appctx, "Unknown ACL identifier. Please use #<id> or <file>.\n");
|
return cli_err(appctx, "Unknown ACL identifier. Please use #<id> or <file>.\n");
|
||||||
@ -1047,7 +1082,7 @@ static int cli_parse_clear_map(char **args, char *payload, struct appctx *appctx
|
|||||||
if (gen)
|
if (gen)
|
||||||
appctx->ctx.cli.i1 = appctx->ctx.cli.i0 = str2uic(gen);
|
appctx->ctx.cli.i1 = appctx->ctx.cli.i0 = str2uic(gen);
|
||||||
else
|
else
|
||||||
appctx->ctx.cli.i1 = appctx->ctx.cli.i0 = appctx->ctx.map.ref->curr_gen;
|
appctx->ctx.cli.i1 = appctx->ctx.cli.i0 = ctx->ref->curr_gen;
|
||||||
|
|
||||||
/* delegate the clearing to the I/O handler which can yield */
|
/* delegate the clearing to the I/O handler which can yield */
|
||||||
return 0;
|
return 0;
|
||||||
@ -1061,6 +1096,8 @@ static int cli_parse_clear_map(char **args, char *payload, struct appctx *appctx
|
|||||||
*/
|
*/
|
||||||
static int cli_parse_commit_map(char **args, char *payload, struct appctx *appctx, void *private)
|
static int cli_parse_commit_map(char **args, char *payload, struct appctx *appctx, void *private)
|
||||||
{
|
{
|
||||||
|
struct show_map_ctx *ctx = applet_reserve_svcctx(appctx, sizeof(*ctx));
|
||||||
|
|
||||||
if (strcmp(args[1], "map") == 0 || strcmp(args[1], "acl") == 0) {
|
if (strcmp(args[1], "map") == 0 || strcmp(args[1], "acl") == 0) {
|
||||||
const char *gen = NULL;
|
const char *gen = NULL;
|
||||||
uint genid;
|
uint genid;
|
||||||
@ -1068,9 +1105,9 @@ static int cli_parse_commit_map(char **args, char *payload, struct appctx *appct
|
|||||||
|
|
||||||
/* Set ACL or MAP flags. */
|
/* Set ACL or MAP flags. */
|
||||||
if (args[1][0] == 'm')
|
if (args[1][0] == 'm')
|
||||||
appctx->ctx.map.display_flags = PAT_REF_MAP;
|
ctx->display_flags = PAT_REF_MAP;
|
||||||
else
|
else
|
||||||
appctx->ctx.map.display_flags = PAT_REF_ACL;
|
ctx->display_flags = PAT_REF_ACL;
|
||||||
|
|
||||||
if (*args[2] != '@')
|
if (*args[2] != '@')
|
||||||
return cli_err(appctx, "Missing version number.\n");
|
return cli_err(appctx, "Missing version number.\n");
|
||||||
@ -1086,29 +1123,29 @@ static int cli_parse_commit_map(char **args, char *payload, struct appctx *appct
|
|||||||
|
|
||||||
/* no parameter */
|
/* no parameter */
|
||||||
if (!*args[3]) {
|
if (!*args[3]) {
|
||||||
if (appctx->ctx.map.display_flags == PAT_REF_MAP)
|
if (ctx->display_flags == PAT_REF_MAP)
|
||||||
return cli_err(appctx, "Missing map identifier.\n");
|
return cli_err(appctx, "Missing map identifier.\n");
|
||||||
else
|
else
|
||||||
return cli_err(appctx, "Missing ACL identifier.\n");
|
return cli_err(appctx, "Missing ACL identifier.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* lookup into the refs and check the map flag */
|
/* lookup into the refs and check the map flag */
|
||||||
appctx->ctx.map.ref = pat_ref_lookup_ref(args[3]);
|
ctx->ref = pat_ref_lookup_ref(args[3]);
|
||||||
if (!appctx->ctx.map.ref ||
|
if (!ctx->ref ||
|
||||||
!(appctx->ctx.map.ref->flags & appctx->ctx.map.display_flags)) {
|
!(ctx->ref->flags & ctx->display_flags)) {
|
||||||
if (appctx->ctx.map.display_flags == PAT_REF_MAP)
|
if (ctx->display_flags == PAT_REF_MAP)
|
||||||
return cli_err(appctx, "Unknown map identifier. Please use #<id> or <file>.\n");
|
return cli_err(appctx, "Unknown map identifier. Please use #<id> or <file>.\n");
|
||||||
else
|
else
|
||||||
return cli_err(appctx, "Unknown ACL identifier. Please use #<id> or <file>.\n");
|
return cli_err(appctx, "Unknown ACL identifier. Please use #<id> or <file>.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
HA_SPIN_LOCK(PATREF_LOCK, &appctx->ctx.map.ref->lock);
|
HA_SPIN_LOCK(PATREF_LOCK, &ctx->ref->lock);
|
||||||
if (genid - (appctx->ctx.map.ref->curr_gen + 1) <
|
if (genid - (ctx->ref->curr_gen + 1) <
|
||||||
appctx->ctx.map.ref->next_gen - appctx->ctx.map.ref->curr_gen)
|
ctx->ref->next_gen - ctx->ref->curr_gen)
|
||||||
ret = pat_ref_commit(appctx->ctx.map.ref, genid);
|
ret = pat_ref_commit(ctx->ref, genid);
|
||||||
else
|
else
|
||||||
ret = 1;
|
ret = 1;
|
||||||
HA_SPIN_UNLOCK(PATREF_LOCK, &appctx->ctx.map.ref->lock);
|
HA_SPIN_UNLOCK(PATREF_LOCK, &ctx->ref->lock);
|
||||||
|
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
return cli_err(appctx, "Version number out of range.\n");
|
return cli_err(appctx, "Version number out of range.\n");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user