* [lttng-dev] [PATCH lttng-tools 20/28] Send enable-event commands with exclusion data
@ 2013-11-07 10:21 JP Ikaheimonen
2013-11-07 10:22 ` [lttng-dev] [PATCH lttng-tools 21/28] Collate lttng_enable_event* code JP Ikaheimonen
` (7 more replies)
0 siblings, 8 replies; 9+ messages in thread
From: JP Ikaheimonen @ 2013-11-07 10:21 UTC (permalink / raw)
Create new function lttng_enable_event_with_exclusions().
This function deals with the various permutations of data that are
possible to accompany the enable-event command:
- all events / some events
- no filter / a filter
- no exclusions / some exclusions
The function generates the appropriate command structures and data
and sends it to the session.
Signed-off-by: JP Ikaheimonen <jp_ikaheimonen at mentor.com>
---
include/lttng/lttng.h | 17 ++++
src/lib/lttng-ctl/lttng-ctl.c | 208 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 225 insertions(+)
diff --git a/include/lttng/lttng.h b/include/lttng/lttng.h
index 0307536..255f7c4 100644
--- a/include/lttng/lttng.h
+++ b/include/lttng/lttng.h
@@ -573,6 +573,23 @@ extern int lttng_enable_event_with_filter(struct lttng_handle *handle,
const char *filter_expression);
/*
+ * Create or enable an event with a filter and/or exclusions.
+ *
+ * If the event you are trying to enable does not exist, it will be created,
+ * else it is enabled.
+ * If ev is NULL, all events are enabled with the filter and exclusion options.
+ * If channel_name is NULL, the default channel is used (channel0) and created
+ * if not found.
+ * If filter_expression is NULL, an event without associated filter is
+ * created.
+ * If exclusion count is zero, the event will be created without exclusions.
+ */
+extern int lttng_enable_event_with_exclusions(struct lttng_handle *handle,
+ struct lttng_event *event, const char *channel_name,
+ const char *filter_expression,
+ int exclusion_count, char **exclusion_names);
+
+/*
* Create or enable a channel.
*
* The chan and handle params can not be NULL.
diff --git a/src/lib/lttng-ctl/lttng-ctl.c b/src/lib/lttng-ctl/lttng-ctl.c
index 83a46a4..21173ca 100644
--- a/src/lib/lttng-ctl/lttng-ctl.c
+++ b/src/lib/lttng-ctl/lttng-ctl.c
@@ -855,6 +855,214 @@ alloc_error:
}
/*
+ * Enable event(s) for a channel, possibly with exclusions and a filter.
+ * If no event name is specified, all events are enabled.
+ * If no channel name is specified, the default name is used.
+ * If filter expression is not NULL, the filter is set for the event.
+ * If exclusion count is not zero, the exclusions are set for the event.
+ * Returns size of returned session payload data or a negative error code.
+ */
+int lttng_enable_event_with_exclusions(struct lttng_handle *handle,
+ struct lttng_event *ev, const char *channel_name,
+ const char *filter_expression,
+ int exclusion_count, char **exclusion_list)
+{
+ struct lttcomm_session_msg lsm;
+ char *varlen_data;
+ int ret = 0;
+ struct filter_parser_ctx *ctx = NULL;
+ FILE *fmem = NULL;
+
+ if (handle == NULL || ev == NULL) {
+ return -LTTNG_ERR_INVALID;
+ }
+
+ /* Empty filter string will always be rejected by the parser
+ * anyway, so treat this corner-case early to eliminate
+ * lttng_fmemopen error for 0-byte allocation.
+ */
+ if (filter_expression && filter_expression[0] == '\0') {
+ return -LTTNG_ERR_INVALID;
+ }
+
+ memset(&lsm, 0, sizeof(lsm));
+
+ /* If no channel name, send empty string. */
+ if (channel_name == NULL) {
+ lttng_ctl_copy_string(lsm.u.enable.channel_name, "",
+ sizeof(lsm.u.enable.channel_name));
+ } else {
+ lttng_ctl_copy_string(lsm.u.enable.channel_name, channel_name,
+ sizeof(lsm.u.enable.channel_name));
+ }
+
+ lttng_ctl_copy_lttng_domain(&lsm.domain, &handle->domain);
+
+ /* figure out correct command type, based on if we have a filter or exclusions */
+ if (exclusion_count == 0) {
+ if (filter_expression == NULL) {
+ if (ev->name[0] != '\0') {
+ lsm.cmd_type = LTTNG_ENABLE_EVENT;
+ } else {
+ lsm.cmd_type = LTTNG_ENABLE_ALL_EVENT;
+ }
+ } else {
+ lsm.cmd_type = LTTNG_ENABLE_EVENT_WITH_FILTER;
+ }
+ } else {
+ lsm.cmd_type = LTTNG_ENABLE_EVENT_WITH_EXCLUSION;
+ }
+
+ memcpy(&lsm.u.enable.event, ev, sizeof(lsm.u.enable.event));
+
+ lttng_ctl_copy_string(lsm.session.name, handle->session_name,
+ sizeof(lsm.session.name));
+ lsm.u.enable.exclusion_count = exclusion_count;
+ lsm.u.enable.bytecode_len = 0;
+
+ if (exclusion_count == 0 && filter_expression == NULL) {
+ ret = lttng_ctl_ask_sessiond(&lsm, NULL);
+ return ret;
+ }
+
+ /*
+ * We have either a filter or some exclusions, so we need to set up
+ * a variable-length memory block from where to send the data
+ */
+
+ /* Parse filter expression */
+ if (filter_expression != NULL) {
+
+ /*
+ * casting const to non-const, as the underlying function will
+ * use it in read-only mode.
+ */
+ fmem = lttng_fmemopen((void *) filter_expression,
+ strlen(filter_expression), "r");
+ if (!fmem) {
+ fprintf(stderr, "Error opening memory as stream\n");
+ return -LTTNG_ERR_FILTER_NOMEM;
+ }
+ ctx = filter_parser_ctx_alloc(fmem);
+ if (!ctx) {
+ fprintf(stderr, "Error allocating parser\n");
+ ret = -LTTNG_ERR_FILTER_NOMEM;
+ goto filter_alloc_error;
+ }
+ ret = filter_parser_ctx_append_ast(ctx);
+ if (ret) {
+ fprintf(stderr, "Parse error\n");
+ ret = -LTTNG_ERR_FILTER_INVAL;
+ goto parse_error;
+ }
+ ret = filter_visitor_set_parent(ctx);
+ if (ret) {
+ fprintf(stderr, "Set parent error\n");
+ ret = -LTTNG_ERR_FILTER_INVAL;
+ goto parse_error;
+ }
+ if (print_xml) {
+ ret = filter_visitor_print_xml(ctx, stdout, 0);
+ if (ret) {
+ fflush(stdout);
+ fprintf(stderr, "XML print error\n");
+ ret = -LTTNG_ERR_FILTER_INVAL;
+ goto parse_error;
+ }
+ }
+
+ dbg_printf("Generating IR... ");
+ fflush(stdout);
+ ret = filter_visitor_ir_generate(ctx);
+ if (ret) {
+ fprintf(stderr, "Generate IR error\n");
+ ret = -LTTNG_ERR_FILTER_INVAL;
+ goto parse_error;
+ }
+ dbg_printf("done\n");
+
+ dbg_printf("Validating IR... ");
+ fflush(stdout);
+ ret = filter_visitor_ir_check_binary_op_nesting(ctx);
+ if (ret) {
+ ret = -LTTNG_ERR_FILTER_INVAL;
+ goto parse_error;
+ }
+ dbg_printf("done\n");
+
+ dbg_printf("Generating bytecode... ");
+ fflush(stdout);
+ ret = filter_visitor_bytecode_generate(ctx);
+ if (ret) {
+ fprintf(stderr, "Generate bytecode error\n");
+ ret = -LTTNG_ERR_FILTER_INVAL;
+ goto parse_error;
+ }
+ dbg_printf("done\n");
+ dbg_printf("Size of bytecode generated: %u bytes.\n",
+ bytecode_get_len(&ctx->bytecode->b));
+
+ lsm.u.enable.bytecode_len = sizeof(ctx->bytecode->b)
+ + bytecode_get_len(&ctx->bytecode->b);
+ }
+
+ /* Allocate variable length data */
+ if (lsm.u.enable.exclusion_count != 0) {
+ varlen_data = zmalloc(lsm.u.enable.bytecode_len
+ + LTTNG_SYMBOL_NAME_LEN * exclusion_count);
+ if (!varlen_data) {
+ ret = -LTTNG_ERR_EXCLUSION_NOMEM;
+ goto varlen_alloc_error;
+ }
+ /* Put exclusion names first in the data */
+ while (exclusion_count--) {
+ strncpy(varlen_data + LTTNG_SYMBOL_NAME_LEN * exclusion_count,
+ *(exclusion_list + exclusion_count),
+ LTTNG_SYMBOL_NAME_LEN);
+ }
+ /* Add filter bytecode next */
+ if (lsm.u.enable.bytecode_len != 0) {
+ memcpy(varlen_data + LTTNG_SYMBOL_NAME_LEN * lsm.u.enable.exclusion_count,
+ &ctx->bytecode->b,
+ lsm.u.enable.bytecode_len);
+ }
+ } else {
+ /* no exclusions - use the already allocated filter bytecode */
+ varlen_data = (char *)(&ctx->bytecode->b);
+ }
+
+ ret = lttng_ctl_ask_sessiond_varlen(&lsm, varlen_data,
+ LTTNG_SYMBOL_NAME_LEN * lsm.u.enable.exclusion_count
+ + lsm.u.enable.bytecode_len,
+ NULL);
+
+ if (lsm.u.enable.exclusion_count != 0) {
+ free(varlen_data);
+ }
+
+varlen_alloc_error:
+ if (filter_expression) {
+ filter_bytecode_free(ctx);
+ filter_ir_free(ctx);
+ filter_parser_ctx_free(ctx);
+ if (fclose(fmem) != 0) {
+ perror("fclose");
+ }
+ }
+ return ret;
+
+parse_error:
+ filter_bytecode_free(ctx);
+ filter_ir_free(ctx);
+ filter_parser_ctx_free(ctx);
+filter_alloc_error:
+ if (fclose(fmem) != 0) {
+ perror("fclose");
+ }
+ return ret;
+}
+
+/*
* Disable event(s) of a channel and domain.
* If no event name is specified, all events are disabled.
* If no channel name is specified, the default 'channel0' is used.
--
1.8.1.2
^ permalink raw reply [flat|nested] 9+ messages in thread
* [lttng-dev] [PATCH lttng-tools 21/28] Collate lttng_enable_event* code
2013-11-07 10:21 [lttng-dev] [PATCH lttng-tools 20/28] Send enable-event commands with exclusion data JP Ikaheimonen
@ 2013-11-07 10:22 ` JP Ikaheimonen
2013-11-07 10:22 ` [lttng-dev] [PATCH lttng-tools 22/28] Add -exclude option to enable-event command JP Ikaheimonen
` (6 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: JP Ikaheimonen @ 2013-11-07 10:22 UTC (permalink / raw)
Because the function lttng_enable_event_with_exclusions() can also
handle the duties of lttng_enable_event and lttng_enable_event_with_filter
as special cases, there's no need to have the same code duplicated in
each function. Let the other two functions fall the generic function
lttng_enable_event_with_exclusions() instead.
Signed-off-by: JP Ikaheimonen <jp_ikaheimonen at mentor.com>
---
src/lib/lttng-ctl/lttng-ctl.c | 171 +-----------------------------------------
1 file changed, 4 insertions(+), 167 deletions(-)
diff --git a/src/lib/lttng-ctl/lttng-ctl.c b/src/lib/lttng-ctl/lttng-ctl.c
index 21173ca..9a21605 100644
--- a/src/lib/lttng-ctl/lttng-ctl.c
+++ b/src/lib/lttng-ctl/lttng-ctl.c
@@ -673,36 +673,8 @@ int lttng_add_context(struct lttng_handle *handle,
int lttng_enable_event(struct lttng_handle *handle,
struct lttng_event *ev, const char *channel_name)
{
- struct lttcomm_session_msg lsm;
-
- if (handle == NULL || ev == NULL) {
- return -LTTNG_ERR_INVALID;
- }
-
- memset(&lsm, 0, sizeof(lsm));
-
- /* If no channel name, send empty string. */
- if (channel_name == NULL) {
- lttng_ctl_copy_string(lsm.u.enable.channel_name, "",
- sizeof(lsm.u.enable.channel_name));
- } else {
- lttng_ctl_copy_string(lsm.u.enable.channel_name, channel_name,
- sizeof(lsm.u.enable.channel_name));
- }
-
- lttng_ctl_copy_lttng_domain(&lsm.domain, &handle->domain);
-
- if (ev->name[0] != '\0') {
- lsm.cmd_type = LTTNG_ENABLE_EVENT;
- } else {
- lsm.cmd_type = LTTNG_ENABLE_ALL_EVENT;
- }
- memcpy(&lsm.u.enable.event, ev, sizeof(lsm.u.enable.event));
-
- lttng_ctl_copy_string(lsm.session.name, handle->session_name,
- sizeof(lsm.session.name));
-
- return lttng_ctl_ask_sessiond(&lsm, NULL);
+ return lttng_enable_event_with_exclusions(handle, ev, channel_name,
+ NULL, 0, NULL);
}
/*
@@ -715,143 +687,8 @@ int lttng_enable_event_with_filter(struct lttng_handle *handle,
struct lttng_event *event, const char *channel_name,
const char *filter_expression)
{
- struct lttcomm_session_msg lsm;
- struct filter_parser_ctx *ctx;
- FILE *fmem;
- int ret = 0;
-
- if (!filter_expression) {
- /*
- * Fall back to normal event enabling if no filter
- * specified.
- */
- return lttng_enable_event(handle, event, channel_name);
- }
-
- /*
- * Empty filter string will always be rejected by the parser
- * anyway, so treat this corner-case early to eliminate
- * lttng_fmemopen error for 0-byte allocation.
- */
- if (handle == NULL || filter_expression[0] == '\0') {
- return -LTTNG_ERR_INVALID;
- }
-
- /*
- * casting const to non-const, as the underlying function will
- * use it in read-only mode.
- */
- fmem = lttng_fmemopen((void *) filter_expression,
- strlen(filter_expression), "r");
- if (!fmem) {
- fprintf(stderr, "Error opening memory as stream\n");
- return -LTTNG_ERR_FILTER_NOMEM;
- }
- ctx = filter_parser_ctx_alloc(fmem);
- if (!ctx) {
- fprintf(stderr, "Error allocating parser\n");
- ret = -LTTNG_ERR_FILTER_NOMEM;
- goto alloc_error;
- }
- ret = filter_parser_ctx_append_ast(ctx);
- if (ret) {
- fprintf(stderr, "Parse error\n");
- ret = -LTTNG_ERR_FILTER_INVAL;
- goto parse_error;
- }
- ret = filter_visitor_set_parent(ctx);
- if (ret) {
- fprintf(stderr, "Set parent error\n");
- ret = -LTTNG_ERR_FILTER_INVAL;
- goto parse_error;
- }
- if (print_xml) {
- ret = filter_visitor_print_xml(ctx, stdout, 0);
- if (ret) {
- fflush(stdout);
- fprintf(stderr, "XML print error\n");
- ret = -LTTNG_ERR_FILTER_INVAL;
- goto parse_error;
- }
- }
-
- dbg_printf("Generating IR... ");
- fflush(stdout);
- ret = filter_visitor_ir_generate(ctx);
- if (ret) {
- fprintf(stderr, "Generate IR error\n");
- ret = -LTTNG_ERR_FILTER_INVAL;
- goto parse_error;
- }
- dbg_printf("done\n");
-
- dbg_printf("Validating IR... ");
- fflush(stdout);
- ret = filter_visitor_ir_check_binary_op_nesting(ctx);
- if (ret) {
- ret = -LTTNG_ERR_FILTER_INVAL;
- goto parse_error;
- }
- dbg_printf("done\n");
-
- dbg_printf("Generating bytecode... ");
- fflush(stdout);
- ret = filter_visitor_bytecode_generate(ctx);
- if (ret) {
- fprintf(stderr, "Generate bytecode error\n");
- ret = -LTTNG_ERR_FILTER_INVAL;
- goto parse_error;
- }
- dbg_printf("done\n");
- dbg_printf("Size of bytecode generated: %u bytes.\n",
- bytecode_get_len(&ctx->bytecode->b));
-
- memset(&lsm, 0, sizeof(lsm));
-
- lsm.cmd_type = LTTNG_ENABLE_EVENT_WITH_FILTER;
-
- /* If no channel name, send empty string. */
- if (channel_name == NULL) {
- lttng_ctl_copy_string(lsm.u.enable.channel_name, "",
- sizeof(lsm.u.enable.channel_name));
- } else {
- lttng_ctl_copy_string(lsm.u.enable.channel_name, channel_name,
- sizeof(lsm.u.enable.channel_name));
- }
-
- /* Copy event name */
- if (event) {
- memcpy(&lsm.u.enable.event, event, sizeof(lsm.u.enable.event));
- }
-
- lsm.u.enable.bytecode_len = sizeof(ctx->bytecode->b)
- + bytecode_get_len(&ctx->bytecode->b);
-
- lttng_ctl_copy_lttng_domain(&lsm.domain, &handle->domain);
-
- lttng_ctl_copy_string(lsm.session.name, handle->session_name,
- sizeof(lsm.session.name));
-
- ret = lttng_ctl_ask_sessiond_varlen(&lsm, &ctx->bytecode->b,
- lsm.u.enable.bytecode_len, NULL);
-
- filter_bytecode_free(ctx);
- filter_ir_free(ctx);
- filter_parser_ctx_free(ctx);
- if (fclose(fmem) != 0) {
- perror("fclose");
- }
- return ret;
-
-parse_error:
- filter_bytecode_free(ctx);
- filter_ir_free(ctx);
- filter_parser_ctx_free(ctx);
-alloc_error:
- if (fclose(fmem) != 0) {
- perror("fclose");
- }
- return ret;
+ return lttng_enable_event_with_exclusions(handle, event, channel_name,
+ filter_expression, 0, NULL);
}
/*
--
1.8.1.2
^ permalink raw reply [flat|nested] 9+ messages in thread
* [lttng-dev] [PATCH lttng-tools 22/28] Add -exclude option to enable-event command
2013-11-07 10:21 [lttng-dev] [PATCH lttng-tools 20/28] Send enable-event commands with exclusion data JP Ikaheimonen
2013-11-07 10:22 ` [lttng-dev] [PATCH lttng-tools 21/28] Collate lttng_enable_event* code JP Ikaheimonen
@ 2013-11-07 10:22 ` JP Ikaheimonen
2013-11-07 10:22 ` [lttng-dev] [PATCH lttng-tools 23/28] Add usage for --exclude option JP Ikaheimonen
` (5 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: JP Ikaheimonen @ 2013-11-07 10:22 UTC (permalink / raw)
Add new option --exclude (shortcut -x) for enable-event command.
Signed-off-by: JP Ikaheimonen <jp_ikaheimonen at mentor.com>
---
src/bin/lttng/commands/enable_events.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/src/bin/lttng/commands/enable_events.c b/src/bin/lttng/commands/enable_events.c
index a7b70c3..c3feefd 100644
--- a/src/bin/lttng/commands/enable_events.c
+++ b/src/bin/lttng/commands/enable_events.c
@@ -43,6 +43,7 @@ static char *opt_function;
static char *opt_function_entry_symbol;
static char *opt_channel_name;
static char *opt_filter;
+static char *opt_exclude;
#if 0
/* Not implemented yet */
static char *opt_cmd_name;
@@ -61,6 +62,7 @@ enum {
OPT_LOGLEVEL_ONLY,
OPT_LIST_OPTIONS,
OPT_FILTER,
+ OPT_EXCLUDE,
};
static struct lttng_handle *handle;
@@ -89,6 +91,7 @@ static struct poptOption long_options[] = {
{"loglevel-only", 0, POPT_ARG_STRING, 0, OPT_LOGLEVEL_ONLY, 0, 0},
{"list-options", 0, POPT_ARG_NONE, NULL, OPT_LIST_OPTIONS, NULL, NULL},
{"filter", 'f', POPT_ARG_STRING, &opt_filter, OPT_FILTER, 0, 0},
+ {"exclude", 'x', POPT_ARG_STRING, &opt_exclude, OPT_EXCLUDE, 0, 0},
{0, 0, 0, 0, 0, 0, 0}
};
@@ -718,6 +721,8 @@ int cmd_enable_events(int argc, const char **argv)
goto end;
case OPT_FILTER:
break;
+ case OPT_EXCLUDE:
+ break;
default:
usage(stderr);
ret = CMD_UNDEFINED;
--
1.8.1.2
^ permalink raw reply [flat|nested] 9+ messages in thread
* [lttng-dev] [PATCH lttng-tools 23/28] Add usage for --exclude option
2013-11-07 10:21 [lttng-dev] [PATCH lttng-tools 20/28] Send enable-event commands with exclusion data JP Ikaheimonen
2013-11-07 10:22 ` [lttng-dev] [PATCH lttng-tools 21/28] Collate lttng_enable_event* code JP Ikaheimonen
2013-11-07 10:22 ` [lttng-dev] [PATCH lttng-tools 22/28] Add -exclude option to enable-event command JP Ikaheimonen
@ 2013-11-07 10:22 ` JP Ikaheimonen
2013-11-07 10:22 ` [lttng-dev] [PATCH lttng-tools 24/28] Add a function to check for legal exclusions JP Ikaheimonen
` (4 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: JP Ikaheimonen @ 2013-11-07 10:22 UTC (permalink / raw)
Signed-off-by: JP Ikaheimonen <jp_ikaheimonen at mentor.com>
---
src/bin/lttng/commands/enable_events.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/src/bin/lttng/commands/enable_events.c b/src/bin/lttng/commands/enable_events.c
index c3feefd..a363c3e 100644
--- a/src/bin/lttng/commands/enable_events.c
+++ b/src/bin/lttng/commands/enable_events.c
@@ -195,6 +195,12 @@ static void usage(FILE *ofp)
fprintf(ofp, " '$ctx.procname == \"demo*\"'\n");
fprintf(ofp, " '$ctx.vpid >= 4433 && $ctx.vpid < 4455'\n");
fprintf(ofp, " '$ctx.vtid == 1234'\n");
+ fprintf(ofp, " -x, --exclude LIST\n");
+ fprintf(ofp, " Add exclusions to UST tracepoints:\n");
+ fprintf(ofp, " Events that match any of the items\n");
+ fprintf(ofp, " in the comma-separated LIST are not\n");
+ fprintf(ofp, " enabled, even if they match a wildcard\n");
+ fprintf(ofp, " definition of the event.\n");
fprintf(ofp, "\n");
}
--
1.8.1.2
^ permalink raw reply [flat|nested] 9+ messages in thread
* [lttng-dev] [PATCH lttng-tools 24/28] Add a function to check for legal exclusions
2013-11-07 10:21 [lttng-dev] [PATCH lttng-tools 20/28] Send enable-event commands with exclusion data JP Ikaheimonen
` (2 preceding siblings ...)
2013-11-07 10:22 ` [lttng-dev] [PATCH lttng-tools 23/28] Add usage for --exclude option JP Ikaheimonen
@ 2013-11-07 10:22 ` JP Ikaheimonen
2013-11-07 10:22 ` [lttng-dev] [PATCH lttng-tools 25/28] Parse exclusions and forward them to the control handler JP Ikaheimonen
` (3 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: JP Ikaheimonen @ 2013-11-07 10:22 UTC (permalink / raw)
Add a function check_exclusion_subsets() that checks the event name
against a given list of exclusion names. Report warnings and/or errors
if an exclusion is not a proper subset of the event.
Return a newly allocated list of newly allocated exclusion name strings,
the count of items in that list, and an error code.
Signed-off-by: JP Ikaheimonen <jp_ikaheimonen at mentor.com>
---
src/bin/lttng/commands/enable_events.c | 88 ++++++++++++++++++++++++++++++++++
1 file changed, 88 insertions(+)
diff --git a/src/bin/lttng/commands/enable_events.c b/src/bin/lttng/commands/enable_events.c
index a363c3e..f88f53f 100644
--- a/src/bin/lttng/commands/enable_events.c
+++ b/src/bin/lttng/commands/enable_events.c
@@ -337,6 +337,94 @@ const char *print_raw_channel_name(const char *name)
}
/*
+ * Compare list of exclusions against an event name.
+ * Return a list of legal exclusion names.
+ * Produce an error or a warning about others (depending on the situation)
+ */
+static
+int check_exclusion_subsets(const char *event_name,
+ const char *exclusions,
+ int *exclusion_count_ptr,
+ char ***exclusion_list_ptr)
+{
+ const char *excluder_ptr;
+ const char *event_ptr;
+ const char *next_excluder;
+ int excluder_length;
+ int exclusion_count = 0;
+ char **exclusion_list = NULL;
+ int ret = CMD_SUCCESS;
+
+ if (event_name[strlen(event_name) - 1] != '*') {
+ ERR("Event %s: Excluders can only be used with wildcarded events", event_name);
+ goto error;
+ }
+
+ next_excluder = exclusions;
+ while (*next_excluder != 0) {
+ event_ptr = event_name;
+ excluder_ptr = next_excluder;
+ excluder_length = strcspn(next_excluder, ",");
+
+ /* Scan both the excluder and the event letter by letter */
+ while (1) {
+ char e, x;
+
+ e = *event_ptr;
+ x = *excluder_ptr;
+
+ if (x == '*') {
+ /* Event is a subset of the excluder */
+ ERR("Event %s: %.*s excludes all events from %s",
+ event_name,
+ excluder_length,
+ next_excluder,
+ event_name);
+ goto error;
+ }
+ if (e == '*') {
+ /* Excluder is a proper subset of event */
+ exclusion_count++;
+ exclusion_list = realloc(exclusion_list, sizeof(char **) * exclusion_count);
+ exclusion_list[exclusion_count - 1] = strndup(next_excluder, excluder_length);
+
+ break;
+ }
+ if (x != e) {
+ /* Excluder and event sets have no common elements */
+ WARN("Event %s: %.*s does not exclude any events from %s",
+ event_name,
+ excluder_length,
+ next_excluder,
+ event_name);
+ break;
+ }
+ excluder_ptr++;
+ event_ptr++;
+ }
+ /* next excluder */
+ next_excluder += excluder_length;
+ if (*next_excluder == ',') {
+ next_excluder++;
+ }
+ }
+ goto end;
+error:
+ while (exclusion_count--) {
+ free(exclusion_list[exclusion_count]);
+ }
+ if (exclusion_list != NULL) {
+ free(exclusion_list);
+ }
+ exclusion_list = NULL;
+ exclusion_count = 0;
+ ret = CMD_ERROR;
+end:
+ *exclusion_count_ptr = exclusion_count;
+ *exclusion_list_ptr = exclusion_list;
+ return ret;
+}
+/*
* Enabling event using the lttng API.
*/
static int enable_events(char *session_name)
--
1.8.1.2
^ permalink raw reply [flat|nested] 9+ messages in thread
* [lttng-dev] [PATCH lttng-tools 25/28] Parse exclusions and forward them to the control handler
2013-11-07 10:21 [lttng-dev] [PATCH lttng-tools 20/28] Send enable-event commands with exclusion data JP Ikaheimonen
` (3 preceding siblings ...)
2013-11-07 10:22 ` [lttng-dev] [PATCH lttng-tools 24/28] Add a function to check for legal exclusions JP Ikaheimonen
@ 2013-11-07 10:22 ` JP Ikaheimonen
2013-11-07 10:22 ` [lttng-dev] [PATCH lttng-tools 26/28] Detect and report exclusion option errors JP Ikaheimonen
` (2 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: JP Ikaheimonen @ 2013-11-07 10:22 UTC (permalink / raw)
For the enable-event command, parse the given exclusions,
and send them to the control handler.
Signed-off-by: JP Ikaheimonen <jp_ikaheimonen at mentor.com>
---
src/bin/lttng/commands/enable_events.c | 50 ++++++++++++++++++++++++++++++----
1 file changed, 44 insertions(+), 6 deletions(-)
diff --git a/src/bin/lttng/commands/enable_events.c b/src/bin/lttng/commands/enable_events.c
index f88f53f..90ecdda 100644
--- a/src/bin/lttng/commands/enable_events.c
+++ b/src/bin/lttng/commands/enable_events.c
@@ -433,6 +433,8 @@ static int enable_events(char *session_name)
char *event_name, *channel_name = NULL;
struct lttng_event ev;
struct lttng_domain dom;
+ int exclusion_count = 0;
+ char **exclusion_list = NULL;
memset(&ev, 0, sizeof(ev));
memset(&dom, 0, sizeof(dom));
@@ -494,8 +496,18 @@ static int enable_events(char *session_name)
}
}
+ if (opt_exclude) {
+ ret = check_exclusion_subsets("*", opt_exclude,
+ &exclusion_count, &exclusion_list);
+ if (ret == CMD_ERROR) {
+ goto error;
+ }
+ }
if (!opt_filter) {
- ret = lttng_enable_event(handle, &ev, channel_name);
+ ret = lttng_enable_event_with_exclusions(handle,
+ &ev, channel_name,
+ NULL,
+ exclusion_count, exclusion_list);
if (ret < 0) {
switch (-ret) {
case LTTNG_ERR_KERN_EVENT_EXIST:
@@ -555,8 +567,8 @@ static int enable_events(char *session_name)
}
}
if (opt_filter) {
- ret = lttng_enable_event_with_filter(handle, &ev, channel_name,
- opt_filter);
+ ret = lttng_enable_event_with_exclusions(handle, &ev, channel_name,
+ opt_filter, exclusion_count, exclusion_list);
if (ret < 0) {
switch (-ret) {
case LTTNG_ERR_FILTER_EXIST:
@@ -669,6 +681,23 @@ static int enable_events(char *session_name)
goto error;
}
+ if (opt_exclude) {
+ /* Free previously allocated items */
+ if (exclusion_list != NULL) {
+ while (exclusion_count--) {
+ free(exclusion_list[exclusion_count]);
+ }
+ free(exclusion_list);
+ exclusion_list = NULL;
+ }
+ /* Check for proper subsets */
+ ret = check_exclusion_subsets(event_name, opt_exclude,
+ &exclusion_count, &exclusion_list);
+ if (ret == CMD_ERROR) {
+ goto error;
+ }
+ }
+
ev.loglevel_type = opt_loglevel_type;
if (opt_loglevel) {
ev.loglevel = loglevel_str_to_value(opt_loglevel);
@@ -697,7 +726,9 @@ static int enable_events(char *session_name)
}
if (!opt_filter) {
- ret = lttng_enable_event(handle, &ev, channel_name);
+ ret = lttng_enable_event_with_exclusions(handle,
+ &ev, channel_name,
+ NULL, exclusion_count, exclusion_list);
if (ret < 0) {
/* Turn ret to positive value to handle the positive error code */
switch (-ret) {
@@ -724,8 +755,8 @@ static int enable_events(char *session_name)
}
if (opt_filter) {
- ret = lttng_enable_event_with_filter(handle, &ev, channel_name,
- opt_filter);
+ ret = lttng_enable_event_with_exclusions(handle, &ev, channel_name,
+ opt_filter, exclusion_count, exclusion_list);
if (ret < 0) {
switch (-ret) {
case LTTNG_ERR_FILTER_EXIST:
@@ -760,6 +791,13 @@ error:
}
lttng_destroy_handle(handle);
+ if (exclusion_list != NULL) {
+ while (exclusion_count--) {
+ free(exclusion_list[exclusion_count]);
+ }
+ free(exclusion_list);
+ }
+
return ret;
}
--
1.8.1.2
^ permalink raw reply [flat|nested] 9+ messages in thread
* [lttng-dev] [PATCH lttng-tools 26/28] Detect and report exclusion option errors
2013-11-07 10:21 [lttng-dev] [PATCH lttng-tools 20/28] Send enable-event commands with exclusion data JP Ikaheimonen
` (4 preceding siblings ...)
2013-11-07 10:22 ` [lttng-dev] [PATCH lttng-tools 25/28] Parse exclusions and forward them to the control handler JP Ikaheimonen
@ 2013-11-07 10:22 ` JP Ikaheimonen
2013-11-07 10:22 ` [lttng-dev] [PATCH lttng-tools 27/28] Add exclusion names to diagnostic printouts JP Ikaheimonen
2013-11-07 10:22 ` [lttng-dev] [PATCH lttng-tools 28/28] When listing events, show exclusions if they exist JP Ikaheimonen
7 siblings, 0 replies; 9+ messages in thread
From: JP Ikaheimonen @ 2013-11-07 10:22 UTC (permalink / raw)
Signed-off-by: JP Ikaheimonen <jp_ikaheimonen at mentor.com>
---
src/bin/lttng/commands/enable_events.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/src/bin/lttng/commands/enable_events.c b/src/bin/lttng/commands/enable_events.c
index 90ecdda..7009df7 100644
--- a/src/bin/lttng/commands/enable_events.c
+++ b/src/bin/lttng/commands/enable_events.c
@@ -465,6 +465,12 @@ static int enable_events(char *session_name)
goto error;
}
+ if (opt_kernel && opt_exclude) {
+ ERR("Event name exclusions are not yet implemented for kernel events");
+ ret = CMD_ERROR;
+ goto error;
+ }
+
channel_name = opt_channel_name;
handle = lttng_create_handle(session_name, &dom);
@@ -682,6 +688,11 @@ static int enable_events(char *session_name)
}
if (opt_exclude) {
+ if (opt_event_type != LTTNG_EVENT_ALL && opt_event_type != LTTNG_EVENT_TRACEPOINT) {
+ ERR("Exclusion option can only be used with tracepoint events");
+ ret = CMD_ERROR;
+ goto error;
+ }
/* Free previously allocated items */
if (exclusion_list != NULL) {
while (exclusion_count--) {
--
1.8.1.2
^ permalink raw reply [flat|nested] 9+ messages in thread
* [lttng-dev] [PATCH lttng-tools 27/28] Add exclusion names to diagnostic printouts
2013-11-07 10:21 [lttng-dev] [PATCH lttng-tools 20/28] Send enable-event commands with exclusion data JP Ikaheimonen
` (5 preceding siblings ...)
2013-11-07 10:22 ` [lttng-dev] [PATCH lttng-tools 26/28] Detect and report exclusion option errors JP Ikaheimonen
@ 2013-11-07 10:22 ` JP Ikaheimonen
2013-11-07 10:22 ` [lttng-dev] [PATCH lttng-tools 28/28] When listing events, show exclusions if they exist JP Ikaheimonen
7 siblings, 0 replies; 9+ messages in thread
From: JP Ikaheimonen @ 2013-11-07 10:22 UTC (permalink / raw)
Signed-off-by: JP Ikaheimonen <jp_ikaheimonen at mentor.com>
---
src/bin/lttng/commands/enable_events.c | 82 +++++++++++++++++++++++++++++-----
1 file changed, 71 insertions(+), 11 deletions(-)
diff --git a/src/bin/lttng/commands/enable_events.c b/src/bin/lttng/commands/enable_events.c
index 7009df7..42cd022 100644
--- a/src/bin/lttng/commands/enable_events.c
+++ b/src/bin/lttng/commands/enable_events.c
@@ -337,6 +337,39 @@ const char *print_raw_channel_name(const char *name)
}
/*
+ * Return allocated string for pretty-printing exclusion names.
+ */
+static
+char *print_exclusions(int count, char **names)
+{
+ int length = 0;
+ int i;
+ const char *preamble = " excluding ";
+ char *ret;
+
+ if (count == 0) {
+ return strdup("");
+ }
+
+ /* calculate total required length */
+ for (i = 0; i < count; i++) {
+ length += strlen(names[i]) + 1;
+ }
+
+ /* add length of preamble + one for NUL - one for last (missing) comma */
+ length += strlen(preamble);
+ ret = malloc(length);
+ strcpy(ret, preamble);
+ for (i = 0; i < count; i++) {
+ strcat(ret, names[i]);
+ if (i != count - 1) {
+ strcat(ret, ",");
+ }
+ }
+ return ret;
+}
+
+/*
* Compare list of exclusions against an event name.
* Return a list of legal exclusion names.
* Produce an error or a warning about others (depending on the situation)
@@ -535,15 +568,20 @@ static int enable_events(char *session_name)
switch (opt_event_type) {
case LTTNG_EVENT_TRACEPOINT:
if (opt_loglevel) {
- MSG("All %s tracepoints are enabled in channel %s for loglevel %s",
+ char *exclusion_string = print_exclusions(exclusion_count, exclusion_list);
+ MSG("All %s tracepoints%s are enabled in channel %s for loglevel %s",
get_domain_str(dom.type),
+ exclusion_string,
print_channel_name(channel_name),
opt_loglevel);
+ free(exclusion_string);
} else {
- MSG("All %s tracepoints are enabled in channel %s",
+ char *exclusion_string = print_exclusions(exclusion_count, exclusion_list);
+ MSG("All %s tracepoints%s are enabled in channel %s",
get_domain_str(dom.type),
+ exclusion_string,
print_channel_name(channel_name));
-
+ free(exclusion_string);
}
break;
case LTTNG_EVENT_SYSCALL:
@@ -554,14 +592,20 @@ static int enable_events(char *session_name)
break;
case LTTNG_EVENT_ALL:
if (opt_loglevel) {
- MSG("All %s events are enabled in channel %s for loglevel %s",
+ char *exclusion_string = print_exclusions(exclusion_count, exclusion_list);
+ MSG("All %s events%s are enabled in channel %s for loglevel %s",
get_domain_str(dom.type),
+ exclusion_string,
print_channel_name(channel_name),
opt_loglevel);
+ free(exclusion_string);
} else {
- MSG("All %s events are enabled in channel %s",
+ char *exclusion_string = print_exclusions(exclusion_count, exclusion_list);
+ MSG("All %s events%s are enabled in channel %s",
get_domain_str(dom.type),
+ exclusion_string,
print_channel_name(channel_name));
+ free(exclusion_string);
}
break;
default:
@@ -737,19 +781,24 @@ static int enable_events(char *session_name)
}
if (!opt_filter) {
+ char *exclusion_string;
+
ret = lttng_enable_event_with_exclusions(handle,
&ev, channel_name,
NULL, exclusion_count, exclusion_list);
+ exclusion_string = print_exclusions(exclusion_count, exclusion_list);
if (ret < 0) {
/* Turn ret to positive value to handle the positive error code */
switch (-ret) {
case LTTNG_ERR_KERN_EVENT_EXIST:
- WARN("Kernel event %s already enabled (channel %s, session %s)",
+ WARN("Kernel event %s%s already enabled (channel %s, session %s)",
event_name,
+ exclusion_string,
print_channel_name(channel_name), session_name);
break;
default:
- ERR("Event %s: %s (channel %s, session %s)", event_name,
+ ERR("Event %s%s: %s (channel %s, session %s)", event_name,
+ exclusion_string,
lttng_strerror(ret),
ret == -LTTNG_ERR_NEED_CHANNEL_NAME
? print_raw_channel_name(channel_name)
@@ -759,25 +808,33 @@ static int enable_events(char *session_name)
}
warn = 1;
} else {
- MSG("%s event %s created in channel %s",
+ MSG("%s event %s%s created in channel %s",
get_domain_str(dom.type), event_name,
+ exclusion_string,
print_channel_name(channel_name));
}
+ free(exclusion_string);
}
if (opt_filter) {
+ char *exclusion_string;
+
ret = lttng_enable_event_with_exclusions(handle, &ev, channel_name,
opt_filter, exclusion_count, exclusion_list);
+ exclusion_string = print_exclusions(exclusion_count, exclusion_list);
+
if (ret < 0) {
switch (-ret) {
case LTTNG_ERR_FILTER_EXIST:
- WARN("Filter on event %s is already enabled"
+ WARN("Filter on event %s%s is already enabled"
" (channel %s, session %s)",
event_name,
+ exclusion_string,
print_channel_name(channel_name), session_name);
break;
default:
- ERR("Event %s: %s (channel %s, session %s, filter \'%s\')", ev.name,
+ ERR("Event %s%s: %s (channel %s, session %s, filter \'%s\')", ev.name,
+ exclusion_string,
lttng_strerror(ret),
ret == -LTTNG_ERR_NEED_CHANNEL_NAME
? print_raw_channel_name(channel_name)
@@ -787,8 +844,11 @@ static int enable_events(char *session_name)
}
goto error;
} else {
- MSG("Filter '%s' successfully set", opt_filter);
+ MSG("Event %s%s: Filter '%s' successfully set",
+ event_name, exclusion_string,
+ opt_filter);
}
+ free(exclusion_string);
}
/* Next event */
--
1.8.1.2
^ permalink raw reply [flat|nested] 9+ messages in thread
* [lttng-dev] [PATCH lttng-tools 28/28] When listing events, show exclusions if they exist
2013-11-07 10:21 [lttng-dev] [PATCH lttng-tools 20/28] Send enable-event commands with exclusion data JP Ikaheimonen
` (6 preceding siblings ...)
2013-11-07 10:22 ` [lttng-dev] [PATCH lttng-tools 27/28] Add exclusion names to diagnostic printouts JP Ikaheimonen
@ 2013-11-07 10:22 ` JP Ikaheimonen
7 siblings, 0 replies; 9+ messages in thread
From: JP Ikaheimonen @ 2013-11-07 10:22 UTC (permalink / raw)
Add "[has exclusions]" to the printout of an event, if that
event has exclusions added.
Signed-off-by: JP Ikaheimonen <jp_ikaheimonen at mentor.com>
---
include/lttng/lttng.h | 3 ++-
src/bin/lttng-sessiond/cmd.c | 3 +++
src/bin/lttng/commands/list.c | 15 +++++++++++++--
3 files changed, 18 insertions(+), 3 deletions(-)
diff --git a/include/lttng/lttng.h b/include/lttng/lttng.h
index 255f7c4..85fdfaa 100644
--- a/include/lttng/lttng.h
+++ b/include/lttng/lttng.h
@@ -226,7 +226,7 @@ struct lttng_event_function_attr {
*
* The structures should be initialized to zero before use.
*/
-#define LTTNG_EVENT_PADDING1 15
+#define LTTNG_EVENT_PADDING1 14
#define LTTNG_EVENT_PADDING2 LTTNG_SYMBOL_NAME_LEN + 32
struct lttng_event {
enum lttng_event_type type;
@@ -238,6 +238,7 @@ struct lttng_event {
int32_t enabled; /* Does not apply: -1 */
pid_t pid;
unsigned char filter; /* filter enabled ? */
+ unsigned char exclusion; /* exclusions added ? */
char padding[LTTNG_EVENT_PADDING1];
diff --git a/src/bin/lttng-sessiond/cmd.c b/src/bin/lttng-sessiond/cmd.c
index 69dfda6..d00bf1e 100644
--- a/src/bin/lttng-sessiond/cmd.c
+++ b/src/bin/lttng-sessiond/cmd.c
@@ -305,6 +305,9 @@ static int list_lttng_ust_global_events(char *channel_name,
if (uevent->filter) {
tmp[i].filter = 1;
}
+ if (uevent->exclusion) {
+ tmp[i].exclusion = 1;
+ }
i++;
}
diff --git a/src/bin/lttng/commands/list.c b/src/bin/lttng/commands/list.c
index bca06e7..6a54279 100644
--- a/src/bin/lttng/commands/list.c
+++ b/src/bin/lttng/commands/list.c
@@ -168,6 +168,15 @@ const char *filter_string(int value)
}
}
+static
+const char *exclusion_string(int value)
+{
+ switch (value) {
+ case 1: return " [has exclusions]";
+ default: return "";
+ }
+}
+
static const char *loglevel_string(int value)
{
switch (value) {
@@ -217,18 +226,20 @@ static void print_events(struct lttng_event *event)
case LTTNG_EVENT_TRACEPOINT:
{
if (event->loglevel != -1) {
- MSG("%s%s (loglevel: %s (%d)) (type: tracepoint)%s%s",
+ MSG("%s%s (loglevel: %s (%d)) (type: tracepoint)%s%s%s",
indent6,
event->name,
loglevel_string(event->loglevel),
event->loglevel,
enabled_string(event->enabled),
+ exclusion_string(event->exclusion),
filter_string(event->filter));
} else {
- MSG("%s%s (type: tracepoint)%s%s",
+ MSG("%s%s (type: tracepoint)%s%s%s",
indent6,
event->name,
enabled_string(event->enabled),
+ exclusion_string(event->exclusion),
filter_string(event->filter));
}
break;
--
1.8.1.2
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2013-11-07 10:22 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-11-07 10:21 [lttng-dev] [PATCH lttng-tools 20/28] Send enable-event commands with exclusion data JP Ikaheimonen
2013-11-07 10:22 ` [lttng-dev] [PATCH lttng-tools 21/28] Collate lttng_enable_event* code JP Ikaheimonen
2013-11-07 10:22 ` [lttng-dev] [PATCH lttng-tools 22/28] Add -exclude option to enable-event command JP Ikaheimonen
2013-11-07 10:22 ` [lttng-dev] [PATCH lttng-tools 23/28] Add usage for --exclude option JP Ikaheimonen
2013-11-07 10:22 ` [lttng-dev] [PATCH lttng-tools 24/28] Add a function to check for legal exclusions JP Ikaheimonen
2013-11-07 10:22 ` [lttng-dev] [PATCH lttng-tools 25/28] Parse exclusions and forward them to the control handler JP Ikaheimonen
2013-11-07 10:22 ` [lttng-dev] [PATCH lttng-tools 26/28] Detect and report exclusion option errors JP Ikaheimonen
2013-11-07 10:22 ` [lttng-dev] [PATCH lttng-tools 27/28] Add exclusion names to diagnostic printouts JP Ikaheimonen
2013-11-07 10:22 ` [lttng-dev] [PATCH lttng-tools 28/28] When listing events, show exclusions if they exist JP Ikaheimonen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox