Mirror of the lttng-dev mailing list
 help / color / mirror / Atom feed
* [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