X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fbin%2Flttng%2Fcommands%2Fenable_events.c;h=af6abbe6e6b4e93bc5950dfd000a9d0236e9cfb7;hp=6ea3c919f1dc8806cb2de0e4515d81a0e06d34f2;hb=d5dd17fd22066461e22eae8f77062cb3b9b111bc;hpb=c2063d0b0b102191bc656fabdab8a23ed570e9ba diff --git a/src/bin/lttng/commands/enable_events.c b/src/bin/lttng/commands/enable_events.c index 6ea3c919f..af6abbe6e 100644 --- a/src/bin/lttng/commands/enable_events.c +++ b/src/bin/lttng/commands/enable_events.c @@ -336,6 +336,94 @@ const char *print_raw_channel_name(const char *name) return 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. */ @@ -345,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)); @@ -378,6 +468,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); @@ -409,8 +505,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: @@ -469,8 +575,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: @@ -577,6 +683,28 @@ static int enable_events(char *session_name) goto error; } + 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--) { + 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); @@ -605,7 +733,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) { @@ -632,8 +762,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: @@ -668,6 +798,13 @@ error: } lttng_destroy_handle(handle); + if (exclusion_list != NULL) { + while (exclusion_count--) { + free(exclusion_list[exclusion_count]); + } + free(exclusion_list); + } + return ret; }