Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RFC] Kernel exclusion #8

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions instrumentation/events/lttng-module/lttng-test.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,22 @@ LTTNG_TRACEPOINT_EVENT(lttng_test_filter_event,
)
)

LTTNG_TRACEPOINT_EVENT(lttng_test_event_a,
TP_PROTO(int id),
TP_ARGS(id),
TP_FIELDS(
ctf_integer(int, id, id)
)
)

LTTNG_TRACEPOINT_EVENT(lttng_test_event_b,
TP_PROTO(int id),
TP_ARGS(id),
TP_FIELDS(
ctf_integer(int, id, id)
)
)

#endif /* LTTNG_TRACE_LTTNG_TEST_H */

/* This part must be outside protection */
Expand Down
12 changes: 12 additions & 0 deletions lttng-abi.c
Original file line number Diff line number Diff line change
Expand Up @@ -1462,6 +1462,18 @@ long lttng_event_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
(struct lttng_kernel_filter_bytecode __user *) arg);
}

}
case LTTNG_KERNEL_EXCLUSION:
switch (*evtype) {
case LTTNG_TYPE_EVENT:
return -EINVAL;
case LTTNG_TYPE_ENABLER:
{
enabler = file->private_data;
return lttng_enabler_attach_exclusion(enabler,
(struct lttng_kernel_event_exclusion __user *) arg);
}

}
default:
return -ENOIOCTLCMD;
Expand Down
7 changes: 7 additions & 0 deletions lttng-abi.h
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,12 @@ struct lttng_kernel_filter_bytecode {
uint64_t seqnum;
char data[0];
} __attribute__((packed));
#define LTTNG_KERNEL_EXCLUSION_PADDING 32
struct lttng_kernel_event_exclusion {
uint32_t count;
char padding[LTTNG_KERNEL_EXCLUSION_PADDING];
char names[LTTNG_KERNEL_SYM_NAME_LEN][0];
} __attribute__((packed));

/* LTTng file descriptor ioctl */
#define LTTNG_KERNEL_SESSION _IO(0xF6, 0x45)
Expand Down Expand Up @@ -224,6 +230,7 @@ struct lttng_kernel_filter_bytecode {

/* Event FD ioctl */
#define LTTNG_KERNEL_FILTER _IO(0xF6, 0x90)
#define LTTNG_KERNEL_EXCLUSION _IO(0xF6, 0x91)

/* LTTng-specific ioctls for the lib ringbuffer */
/* returns the timestamp begin of the current sub-buffer */
Expand Down
102 changes: 100 additions & 2 deletions lttng-events.c
Original file line number Diff line number Diff line change
Expand Up @@ -1144,7 +1144,7 @@ int lttng_session_list_tracker_pids(struct lttng_session *session)
* Enabler management.
*/
static
int lttng_match_enabler_star_glob(const char *desc_name,
int lttng_match_event_pattern_star_glob(const char *desc_name,
const char *pattern)
{
if (!strutils_star_glob_match(pattern, LTTNG_SIZE_MAX,
Expand All @@ -1162,6 +1162,48 @@ int lttng_match_enabler_name(const char *desc_name,
return 1;
}

static
int lttng_match_enabler_exclusion(const char *desc_name,
struct lttng_enabler *enabler)
{
struct lttng_excluder_node *excluder;
/**
* Iterate over the list of excluders of this enabler. If the
* event matches with an excluder, return 'do not enable'
*/
list_for_each_entry(excluder, &enabler->excluder_head, node) {
int count;

for (count = 0; count < excluder->exclusion.count; count++) {
int len;
char *excluder_name;

excluder_name = (char *) (excluder->exclusion.names) +
(count * LTTNG_KERNEL_SYM_NAME_LEN);

len = strnlen(excluder_name, LTTNG_KERNEL_SYM_NAME_LEN);

if (len <= 0) {
continue;
}

/**
* If the event name matches with the exclusion,
* return 0 to signify that this event should _not_ be
* enabled
*/
if (lttng_match_event_pattern_star_glob(desc_name, excluder_name)) {
return 0;
}
}
}
/**
* If none of the exclusions match with the event name,
* return 1 to signify that this event should be enabled
*/
return 1;
}

static
int lttng_desc_match_enabler(const struct lttng_event_desc *desc,
struct lttng_enabler *enabler)
Expand Down Expand Up @@ -1194,7 +1236,17 @@ int lttng_desc_match_enabler(const struct lttng_event_desc *desc,
}
switch (enabler->type) {
case LTTNG_ENABLER_STAR_GLOB:
return lttng_match_enabler_star_glob(desc_name, enabler_name);
{
/**
* Return 'does not match' if the event name does not match with
* the enabler.
*/
if (!lttng_match_event_pattern_star_glob(desc_name, enabler_name)) {
return 0;
}

return lttng_match_enabler_exclusion(desc_name, enabler);
}
case LTTNG_ENABLER_NAME:
return lttng_match_enabler_name(desc_name, enabler_name);
default:
Expand Down Expand Up @@ -1386,6 +1438,7 @@ struct lttng_enabler *lttng_enabler_create(enum lttng_enabler_type type,
return NULL;
enabler->type = type;
INIT_LIST_HEAD(&enabler->filter_bytecode_head);
INIT_LIST_HEAD(&enabler->excluder_head);
memcpy(&enabler->event_param, event_param,
sizeof(enabler->event_param));
enabler->chan = chan;
Expand Down Expand Up @@ -1447,6 +1500,45 @@ int lttng_enabler_attach_bytecode(struct lttng_enabler *enabler,
return ret;
}

int lttng_enabler_attach_exclusion(struct lttng_enabler *enabler,
struct lttng_kernel_event_exclusion __user *exclusion)
{
struct lttng_excluder_node *excluder_node;
uint32_t exclusion_count;
int ret;

ret = get_user(exclusion_count, &exclusion->count);
if (ret) {
goto error;
}

excluder_node = kzalloc(sizeof(*excluder_node) +
(exclusion_count * LTTNG_KERNEL_SYM_NAME_LEN),
GFP_KERNEL);
if (!excluder_node) {
ret = -ENOMEM;
goto error;
}

ret = copy_from_user(&excluder_node->exclusion, exclusion,
sizeof(*exclusion) + (exclusion_count * LTTNG_KERNEL_SYM_NAME_LEN));
if (ret) {
goto error_free;
}

excluder_node->enabler = enabler;
excluder_node->exclusion.count = exclusion_count;

list_add_tail(&excluder_node->node, &enabler->excluder_head);
lttng_session_lazy_sync_enablers(enabler->chan->session);
return 0;

error_free:
kfree(excluder_node);
error:
return ret;
}

int lttng_enabler_attach_context(struct lttng_enabler *enabler,
struct lttng_kernel_context *context_param)
{
Expand All @@ -1457,13 +1549,19 @@ static
void lttng_enabler_destroy(struct lttng_enabler *enabler)
{
struct lttng_filter_bytecode_node *filter_node, *tmp_filter_node;
struct lttng_excluder_node *excluder_node, *tmp_excluder_node;

/* Destroy filter bytecode */
list_for_each_entry_safe(filter_node, tmp_filter_node,
&enabler->filter_bytecode_head, node) {
kfree(filter_node);
}

list_for_each_entry_safe(excluder_node, tmp_excluder_node,
&enabler->excluder_head, node) {
kfree(excluder_node);
}

/* Destroy contexts */
lttng_destroy_context(enabler->ctx);

Expand Down
12 changes: 12 additions & 0 deletions lttng-events.h
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,15 @@ struct lttng_filter_bytecode_node {
*/
struct lttng_kernel_filter_bytecode bc;
};
struct lttng_excluder_node {
struct list_head node;
struct lttng_enabler *enabler;
/*
* struct lttng_kernel_event_exclusion has var. sized array, must be
* last field.
*/
struct lttng_kernel_event_exclusion exclusion;
};

/*
* Filter return value masks.
Expand Down Expand Up @@ -340,6 +349,7 @@ struct lttng_enabler {
struct list_head node; /* per-session list of enablers */
/* head list of struct lttng_ust_filter_bytecode_node */
struct list_head filter_bytecode_head;
struct list_head excluder_head;

struct lttng_kernel_event event_param;
struct lttng_channel *chan;
Expand Down Expand Up @@ -655,6 +665,8 @@ static inline long lttng_channel_syscall_mask(struct lttng_channel *channel,
void lttng_filter_sync_state(struct lttng_bytecode_runtime *runtime);
int lttng_enabler_attach_bytecode(struct lttng_enabler *enabler,
struct lttng_kernel_filter_bytecode __user *bytecode);
int lttng_enabler_attach_exclusion(struct lttng_enabler *enabler,
struct lttng_kernel_event_exclusion __user *exclusion);
void lttng_enabler_event_link_bytecode(struct lttng_event *event,
struct lttng_enabler *enabler);

Expand Down
Loading