Implement path filter
* basic_filters.c (parse_path_filter, run_path_filter, free_path_filter): New functions. * filter.c (filter_types): Add path filter type. (set_filter_priv_data): New function. * filter.h (set_filter_priv_data, expression_add_filter_and): Add declarations. (DECL_FILTER): Add path filter declaration. * filter_action.c (inject_path_tracing): New function. (filtering_parse_finish): Use it. * filter_expression.c (add_variable_token, add_operator_token, expression_add_filter_and): New functions. * pathtrace.c (storepath): Duplicate path.
This commit is contained in:
parent
dfc18a8a98
commit
59b2dbbdbd
@ -375,3 +375,33 @@ free_fd_filter(void *priv_data)
|
|||||||
free_number_set_array(set, 1);
|
free_number_set_array(set, 1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
parse_path_filter(const char *path)
|
||||||
|
{
|
||||||
|
struct path_set *set = xcalloc(1, sizeof(struct path_set));
|
||||||
|
|
||||||
|
pathtrace_select_set(path, set);
|
||||||
|
return set;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
run_path_filter(struct tcb *tcp, void *priv_data)
|
||||||
|
{
|
||||||
|
struct path_set *set = priv_data;
|
||||||
|
|
||||||
|
return pathtrace_match_set(tcp, set);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
free_path_filter(void *priv_data)
|
||||||
|
{
|
||||||
|
struct path_set *set = priv_data;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for (i = 0; i < set->num_selected; ++i)
|
||||||
|
free((char *) set->paths_selected[i]);
|
||||||
|
free(set->paths_selected);
|
||||||
|
free(set);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
8
filter.c
8
filter.c
@ -41,6 +41,7 @@ static const struct filter_type {
|
|||||||
} filter_types[] = {
|
} filter_types[] = {
|
||||||
FILTER_TYPE(syscall),
|
FILTER_TYPE(syscall),
|
||||||
FILTER_TYPE(fd),
|
FILTER_TYPE(fd),
|
||||||
|
FILTER_TYPE(path),
|
||||||
};
|
};
|
||||||
#undef FILTER_TYPE
|
#undef FILTER_TYPE
|
||||||
|
|
||||||
@ -120,3 +121,10 @@ set_filters_qualify_mode(struct filter **filters, unsigned int *nfilters,
|
|||||||
*filters = xreallocarray(*filters, filters_left, sizeof(struct filter));
|
*filters = xreallocarray(*filters, filters_left, sizeof(struct filter));
|
||||||
*nfilters = filters_left;
|
*nfilters = filters_left;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
set_filter_priv_data(struct filter *filter, void *priv_data)
|
||||||
|
{
|
||||||
|
if (filter)
|
||||||
|
filter->priv_data = priv_data;
|
||||||
|
}
|
||||||
|
3
filter.h
3
filter.h
@ -56,6 +56,7 @@ void run_filters(struct tcb *, struct filter *, unsigned int, bool *);
|
|||||||
void free_filter(struct filter *);
|
void free_filter(struct filter *);
|
||||||
void set_filters_qualify_mode(struct filter **, unsigned int *nfilters,
|
void set_filters_qualify_mode(struct filter **, unsigned int *nfilters,
|
||||||
unsigned int filters_left);
|
unsigned int filters_left);
|
||||||
|
void set_filter_priv_data(struct filter *, void *);
|
||||||
|
|
||||||
/* filter action api */
|
/* filter action api */
|
||||||
struct filter *create_filter(struct filter_action *, const char *name);
|
struct filter *create_filter(struct filter_action *, const char *name);
|
||||||
@ -67,6 +68,7 @@ void set_filter_action_priv_data(struct filter_action *, void *);
|
|||||||
struct bool_expression *create_expression();
|
struct bool_expression *create_expression();
|
||||||
bool run_expression(struct bool_expression *, bool *, unsigned int);
|
bool run_expression(struct bool_expression *, bool *, unsigned int);
|
||||||
void set_expression_qualify_mode(struct bool_expression *, unsigned int);
|
void set_expression_qualify_mode(struct bool_expression *, unsigned int);
|
||||||
|
void expression_add_filter_and(struct bool_expression *, unsigned int);
|
||||||
|
|
||||||
#define DECL_FILTER(name) \
|
#define DECL_FILTER(name) \
|
||||||
extern void * \
|
extern void * \
|
||||||
@ -79,6 +81,7 @@ free_ ## name ## _filter(void *) \
|
|||||||
|
|
||||||
DECL_FILTER(syscall);
|
DECL_FILTER(syscall);
|
||||||
DECL_FILTER(fd);
|
DECL_FILTER(fd);
|
||||||
|
DECL_FILTER(path);
|
||||||
#undef DECL_FILTER
|
#undef DECL_FILTER
|
||||||
|
|
||||||
#define DECL_FILTER_ACTION(name) \
|
#define DECL_FILTER_ACTION(name) \
|
||||||
|
@ -86,12 +86,30 @@ compare_action_priority(const void *a, const void *b)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
inject_path_tracing(void)
|
||||||
|
{
|
||||||
|
struct filter_action *action = find_or_add_action("trace");
|
||||||
|
struct filter *path_filter;
|
||||||
|
|
||||||
|
if (!action->nfilters)
|
||||||
|
qualify("trace=all");
|
||||||
|
path_filter = add_filter_to_array(&action->filters, &action->nfilters,
|
||||||
|
"path");
|
||||||
|
set_filter_priv_data(path_filter, &global_path_set);
|
||||||
|
expression_add_filter_and(action->expr, action->nfilters - 1);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
filtering_parsing_finish(void)
|
filtering_parsing_finish(void)
|
||||||
{
|
{
|
||||||
unsigned int maxfilters = 0;
|
unsigned int maxfilters = 0;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
|
/* Inject path filter into trace action. */
|
||||||
|
if (tracing_paths)
|
||||||
|
inject_path_tracing();
|
||||||
|
|
||||||
/* Sort actions by priority */
|
/* Sort actions by priority */
|
||||||
if (nfilter_actions == 0)
|
if (nfilter_actions == 0)
|
||||||
return;
|
return;
|
||||||
|
@ -69,6 +69,32 @@ reallocate_expression(struct bool_expression *const expr,
|
|||||||
expr->ntokens = new_ntokens;
|
expr->ntokens = new_ntokens;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
add_variable_token(struct bool_expression *expr, unsigned int id)
|
||||||
|
{
|
||||||
|
struct expression_token token;
|
||||||
|
token.type = TOK_VARIABLE;
|
||||||
|
token.data.variable_id = id;
|
||||||
|
reallocate_expression(expr, expr->ntokens + 1);
|
||||||
|
expr->tokens[expr->ntokens - 1] = token;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
add_operator_token(struct bool_expression *expr, int op) {
|
||||||
|
struct expression_token token;
|
||||||
|
token.type = TOK_OPERATOR;
|
||||||
|
token.data.operator_id = op;
|
||||||
|
reallocate_expression(expr, expr->ntokens + 1);
|
||||||
|
expr->tokens[expr->ntokens - 1] = token;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
expression_add_filter_and(struct bool_expression *expr, unsigned int filter_id)
|
||||||
|
{
|
||||||
|
add_variable_token(expr, filter_id);
|
||||||
|
add_operator_token(expr, OP_AND);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
set_expression_qualify_mode(struct bool_expression *expr,
|
set_expression_qualify_mode(struct bool_expression *expr,
|
||||||
unsigned int filters_left)
|
unsigned int filters_left)
|
||||||
|
@ -90,7 +90,7 @@ storepath(const char *path, struct path_set *set)
|
|||||||
xgrowarray(set->paths_selected, &set->size,
|
xgrowarray(set->paths_selected, &set->size,
|
||||||
sizeof(set->paths_selected[0]));
|
sizeof(set->paths_selected[0]));
|
||||||
|
|
||||||
set->paths_selected[set->num_selected++] = path;
|
set->paths_selected[set->num_selected++] = xstrdup(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user