X-Git-Url: https://git.liburcu.org/?a=blobdiff_plain;f=src%2Fbin%2Flttng%2Fcommands%2Fenable_events.cpp;h=c0d9e0166df0e4366687a4765bb167a567ab2e42;hb=77878c17ea0ac9508c21899bd38da1f971d52f5f;hp=e6f6274fb140c9b2b56c7db3f1b78703b09acc51;hpb=8884bbc1ce31fa2fc4085a430c4f253e1dd95f14;p=lttng-tools.git diff --git a/src/bin/lttng/commands/enable_events.cpp b/src/bin/lttng/commands/enable_events.cpp index e6f6274fb..c0d9e0166 100644 --- a/src/bin/lttng/commands/enable_events.cpp +++ b/src/bin/lttng/commands/enable_events.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -16,11 +17,14 @@ #include #include #include +#include #include #include +#include #include #include #include +#include /* Mi dependancy */ #include "../command.hpp" @@ -47,6 +51,7 @@ void _mi_lttng_writer_deleter_func(mi_writer *writer) using mi_writer_uptr = std::unique_ptr< mi_writer, lttng::memory::create_deleter_class::deleter>; +using event_rule_patterns = std::vector; int opt_event_type; const char *opt_loglevel; @@ -291,11 +296,11 @@ char *print_exclusions(const struct lttng_dynamic_pointer_array *exclusions) return ret; } -int check_exclusion_subsets(const char *event_name, const char *exclusion) +int check_exclusion_subsets(const char *pattern, const char *exclusion) { bool warn = false; int ret = 0; - const char *e = event_name; + const char *e = pattern; const char *x = exclusion; /* Scan both the excluder and the event letter by letter */ @@ -313,10 +318,7 @@ int check_exclusion_subsets(const char *event_name, const char *exclusion) if (*x == '*') { /* Event is a subset of the excluder */ - ERR("Event %s: %s excludes all events from %s", - event_name, - exclusion, - event_name); + ERR("Event %s: %s excludes all events from %s", pattern, exclusion, pattern); goto error; } @@ -346,15 +348,15 @@ error: end: if (warn) { WARN("Event %s: %s does not exclude any events from %s", - event_name, + pattern, exclusion, - event_name); + pattern); } return ret; } -int create_exclusion_list_and_validate(const char *event_name, +int create_exclusion_list_and_validate(const char *pattern, const char *exclusions_arg, struct lttng_dynamic_pointer_array *exclusions) { @@ -366,7 +368,7 @@ int create_exclusion_list_and_validate(const char *event_name, goto error; } - if (validate_exclusion_list(event_name, exclusions) != 0) { + if (validate_exclusion_list(pattern, exclusions) != 0) { goto error; } @@ -401,11 +403,11 @@ void warn_on_truncated_exclusion_names(const struct lttng_dynamic_pointer_array * Enabling event using the lttng API. * Note: in case of error only the last error code will be return. */ -int enable_events(char *session_name, char *event_list) +int enable_events(const std::string& session_name, const event_rule_patterns& patterns) { int ret = CMD_SUCCESS, command_ret = CMD_SUCCESS; int error_holder = CMD_SUCCESS, warn = 0, error = 0, success = 1; - char *event_name, *channel_name = nullptr; + char *channel_name = nullptr; struct lttng_event *ev; struct lttng_domain dom = {}; struct lttng_dynamic_pointer_array exclusions; @@ -494,7 +496,7 @@ int enable_events(char *session_name, char *event_list) channel_name = opt_channel_name; - handle = lttng_create_handle(session_name, &dom); + handle = lttng_create_handle(session_name.c_str(), &dom); if (handle == nullptr) { ret = -1; goto error; @@ -510,304 +512,17 @@ int enable_events(char *session_name, char *event_list) } } - if (opt_enable_all) { - /* Default setup for enable all */ - if (opt_kernel) { - ev->type = (lttng_event_type) opt_event_type; - strcpy(ev->name, "*"); - /* kernel loglevels not implemented */ - ev->loglevel_type = LTTNG_EVENT_LOGLEVEL_ALL; - } else { - ev->type = LTTNG_EVENT_TRACEPOINT; - strcpy(ev->name, "*"); - ev->loglevel_type = (lttng_loglevel_type) opt_loglevel_type; - if (opt_loglevel) { - int name_search_ret; - - LTTNG_ASSERT(opt_userspace || opt_jul || opt_log4j || opt_python); - - if (opt_userspace) { - enum lttng_loglevel loglevel; - - name_search_ret = - loglevel_name_to_value(opt_loglevel, &loglevel); - ev->loglevel = (int) loglevel; - } else if (opt_jul) { - enum lttng_loglevel_jul loglevel; - - name_search_ret = - loglevel_jul_name_to_value(opt_loglevel, &loglevel); - ev->loglevel = (int) loglevel; - } else if (opt_log4j) { - enum lttng_loglevel_log4j loglevel; - - name_search_ret = loglevel_log4j_name_to_value(opt_loglevel, - &loglevel); - ev->loglevel = (int) loglevel; - } else { - /* python domain. */ - enum lttng_loglevel_python loglevel; - - name_search_ret = loglevel_python_name_to_value( - opt_loglevel, &loglevel); - ev->loglevel = (int) loglevel; - } - - if (name_search_ret == -1) { - ERR("Unknown loglevel %s", opt_loglevel); - ret = -LTTNG_ERR_INVALID; - goto error; - } - } else { - LTTNG_ASSERT(opt_userspace || opt_jul || opt_log4j || opt_python); - if (opt_userspace) { - ev->loglevel = -1; - } else if (opt_jul) { - ev->loglevel = LTTNG_LOGLEVEL_JUL_ALL; - } else if (opt_log4j) { - ev->loglevel = LTTNG_LOGLEVEL_LOG4J_ALL; - } else if (opt_python) { - ev->loglevel = LTTNG_LOGLEVEL_PYTHON_DEBUG; - } - } - } - - if (opt_exclude) { - ret = create_exclusion_list_and_validate("*", opt_exclude, &exclusions); - if (ret) { - ret = CMD_ERROR; - goto error; - } - - ev->exclusion = 1; - warn_on_truncated_exclusion_names(&exclusions, &warn); - } - if (!opt_filter) { - ret = lttng_enable_event_with_exclusions( - handle, - ev, - channel_name, - nullptr, - lttng_dynamic_pointer_array_get_count(&exclusions), - (char **) exclusions.array.buffer.data); - if (ret < 0) { - switch (-ret) { - case LTTNG_ERR_KERN_EVENT_EXIST: - WARN("Kernel events already enabled (channel %s, session %s)", - print_channel_name(channel_name), - session_name); - warn = 1; - break; - case LTTNG_ERR_TRACE_ALREADY_STARTED: - { - const char *msg = - "The command tried to enable an event in a new domain for a session that has already been started once."; - ERR("Events: %s (channel %s, session %s)", - msg, - print_channel_name(channel_name), - session_name); - error = 1; - break; - } - default: - ERR("Events: %s (channel %s, session %s)", - lttng_strerror(ret), - ret == -LTTNG_ERR_NEED_CHANNEL_NAME ? - print_raw_channel_name(channel_name) : - print_channel_name(channel_name), - session_name); - error = 1; - break; - } - goto end; - } - - switch (opt_event_type) { - case LTTNG_EVENT_TRACEPOINT: - if (opt_loglevel && dom.type != LTTNG_DOMAIN_KERNEL) { - char *exclusion_string = print_exclusions(&exclusions); - - if (!exclusion_string) { - PERROR("Cannot allocate exclusion_string"); - error = 1; - goto end; - } - MSG("All %s tracepoints%s are enabled in channel %s for loglevel %s", - lttng_domain_type_str(dom.type), - exclusion_string, - print_channel_name(channel_name), - opt_loglevel); - free(exclusion_string); - } else { - char *exclusion_string = print_exclusions(&exclusions); - - if (!exclusion_string) { - PERROR("Cannot allocate exclusion_string"); - error = 1; - goto end; - } - MSG("All %s tracepoints%s are enabled in channel %s", - lttng_domain_type_str(dom.type), - exclusion_string, - print_channel_name(channel_name)); - free(exclusion_string); - } - break; - case LTTNG_EVENT_SYSCALL: - if (opt_kernel) { - MSG("All %s system calls are enabled in channel %s", - lttng_domain_type_str(dom.type), - print_channel_name(channel_name)); - } - break; - case LTTNG_EVENT_ALL: - if (opt_loglevel && dom.type != LTTNG_DOMAIN_KERNEL) { - char *exclusion_string = print_exclusions(&exclusions); - - if (!exclusion_string) { - PERROR("Cannot allocate exclusion_string"); - error = 1; - goto end; - } - MSG("All %s events%s are enabled in channel %s for loglevel %s", - lttng_domain_type_str(dom.type), - exclusion_string, - print_channel_name(channel_name), - opt_loglevel); - free(exclusion_string); - } else { - char *exclusion_string = print_exclusions(&exclusions); - - if (!exclusion_string) { - PERROR("Cannot allocate exclusion_string"); - error = 1; - goto end; - } - MSG("All %s events%s are enabled in channel %s", - lttng_domain_type_str(dom.type), - exclusion_string, - print_channel_name(channel_name)); - free(exclusion_string); - } - break; - default: - /* - * We should not be here since lttng_enable_event should have - * failed on the event type. - */ - goto error; - } - } - - if (opt_filter) { - command_ret = lttng_enable_event_with_exclusions( - handle, - ev, - channel_name, - opt_filter, - lttng_dynamic_pointer_array_get_count(&exclusions), - (char **) exclusions.array.buffer.data); - if (command_ret < 0) { - switch (-command_ret) { - case LTTNG_ERR_FILTER_EXIST: - WARN("Filter on all events is already enabled" - " (channel %s, session %s)", - print_channel_name(channel_name), - session_name); - warn = 1; - break; - case LTTNG_ERR_TRACE_ALREADY_STARTED: - { - const char *msg = - "The command tried to enable an event in a new domain for a session that has already been started once."; - ERR("All events: %s (channel %s, session %s, filter \'%s\')", - msg, - print_channel_name(channel_name), - session_name, - opt_filter); - error = 1; - break; - } - default: - ERR("All events: %s (channel %s, session %s, filter \'%s\')", - lttng_strerror(command_ret), - command_ret == -LTTNG_ERR_NEED_CHANNEL_NAME ? - print_raw_channel_name(channel_name) : - print_channel_name(channel_name), - session_name, - opt_filter); - error = 1; - break; - } - error_holder = command_ret; - } else { - ev->filter = 1; - MSG("Filter '%s' successfully set", opt_filter); - } - } - - if (lttng_opt_mi) { - /* The wildcard * is used for kernel and ust domain to - * represent ALL. We copy * in event name to force the wildcard use - * for kernel domain - * - * Note: this is strictly for semantic and printing while in - * machine interface mode. - */ - strcpy(ev->name, "*"); - - /* If we reach here the events are enabled */ - if (!error && !warn) { - ev->enabled = 1; - } else { - ev->enabled = 0; - success = 0; - } - ret = mi_lttng_event(writer.get(), ev, 1, handle->domain.type); - if (ret) { - ret = CMD_ERROR; - goto error; - } - - /* print exclusion */ - ret = mi_print_exclusion(&exclusions); - if (ret) { - ret = CMD_ERROR; - goto error; - } - - /* Success ? */ - ret = mi_lttng_writer_write_element_bool( - writer.get(), mi_lttng_element_command_success, success); - if (ret) { - ret = CMD_ERROR; - goto error; - } - - /* Close event element */ - ret = mi_lttng_writer_close_element(writer.get()); - if (ret) { - ret = CMD_ERROR; - goto error; - } - } - - goto end; - } - - /* Strip event list */ - event_name = strtok(event_list, ","); - while (event_name != nullptr) { + for (const auto& pattern : patterns) { /* Copy name and type of the event */ - strncpy(ev->name, event_name, LTTNG_SYMBOL_NAME_LEN); + strncpy(ev->name, pattern.c_str(), LTTNG_SYMBOL_NAME_LEN); ev->name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0'; ev->type = (lttng_event_type) opt_event_type; /* Kernel tracer action */ if (opt_kernel) { - DBG("Enabling kernel event %s for channel %s", - event_name, - print_channel_name(channel_name)); + DBG_FMT("Enabling kernel event: pattern=`{}`, channel_name=`{}`", + pattern, + print_channel_name(channel_name)); switch (opt_event_type) { case LTTNG_EVENT_ALL: /* Enable tracepoints and syscalls */ @@ -877,7 +592,7 @@ int enable_events(char *session_name, char *event_list) ev->loglevel_type = LTTNG_EVENT_LOGLEVEL_ALL; } else if (opt_userspace) { /* User-space tracer action */ DBG("Enabling UST event %s for channel %s, loglevel %s", - event_name, + pattern.c_str(), print_channel_name(channel_name), opt_loglevel ?: ""); @@ -887,7 +602,7 @@ int enable_events(char *session_name, char *event_list) case LTTNG_EVENT_TRACEPOINT: /* Copy name and type of the event */ ev->type = LTTNG_EVENT_TRACEPOINT; - strncpy(ev->name, event_name, LTTNG_SYMBOL_NAME_LEN); + strncpy(ev->name, pattern.c_str(), LTTNG_SYMBOL_NAME_LEN); ev->name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0'; break; case LTTNG_EVENT_PROBE: @@ -911,7 +626,7 @@ int enable_events(char *session_name, char *event_list) /* Free previously allocated items. */ lttng_dynamic_pointer_array_reset(&exclusions); ret = create_exclusion_list_and_validate( - event_name, opt_exclude, &exclusions); + pattern.c_str(), opt_exclude, &exclusions); if (ret) { ret = CMD_ERROR; goto error; @@ -984,7 +699,7 @@ int enable_events(char *session_name, char *event_list) } } ev->type = LTTNG_EVENT_TRACEPOINT; - strncpy(ev->name, event_name, LTTNG_SYMBOL_NAME_LEN); + strncpy(ev->name, pattern.c_str(), LTTNG_SYMBOL_NAME_LEN); ev->name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0'; } else { abort(); @@ -1011,10 +726,10 @@ int enable_events(char *session_name, char *event_list) switch (-command_ret) { case LTTNG_ERR_KERN_EVENT_EXIST: WARN("Kernel event %s%s already enabled (channel %s, session %s)", - event_name, + pattern.c_str(), exclusion_string, print_channel_name(channel_name), - session_name); + session_name.c_str()); warn = 1; break; case LTTNG_ERR_TRACE_ALREADY_STARTED: @@ -1022,30 +737,30 @@ int enable_events(char *session_name, char *event_list) const char *msg = "The command tried to enable an event in a new domain for a session that has already been started once."; ERR("Event %s%s: %s (channel %s, session %s)", - event_name, + pattern.c_str(), exclusion_string, msg, print_channel_name(channel_name), - session_name); + session_name.c_str()); error = 1; break; } case LTTNG_ERR_SDT_PROBE_SEMAPHORE: ERR("SDT probes %s guarded by semaphores are not supported (channel %s, session %s)", - event_name, + pattern.c_str(), print_channel_name(channel_name), - session_name); + session_name.c_str()); error = 1; break; default: ERR("Event %s%s: %s (channel %s, session %s)", - event_name, + pattern.c_str(), exclusion_string, lttng_strerror(command_ret), command_ret == -LTTNG_ERR_NEED_CHANNEL_NAME ? print_raw_channel_name(channel_name) : print_channel_name(channel_name), - session_name); + session_name.c_str()); error = 1; break; } @@ -1056,7 +771,7 @@ int enable_events(char *session_name, char *event_list) case LTTNG_DOMAIN_UST: MSG("%s event %s%s created in channel %s", lttng_domain_type_str(dom.type), - event_name, + pattern.c_str(), exclusion_string, print_channel_name(channel_name)); break; @@ -1069,7 +784,7 @@ int enable_events(char *session_name, char *event_list) */ MSG("%s event %s%s enabled", lttng_domain_type_str(dom.type), - event_name, + pattern.c_str(), exclusion_string); break; default: @@ -1103,10 +818,10 @@ int enable_events(char *session_name, char *event_list) case LTTNG_ERR_FILTER_EXIST: WARN("Filter on event %s%s is already enabled" " (channel %s, session %s)", - event_name, + pattern.c_str(), exclusion_string, print_channel_name(channel_name), - session_name); + session_name.c_str()); warn = 1; break; case LTTNG_ERR_TRACE_ALREADY_STARTED: @@ -1118,7 +833,7 @@ int enable_events(char *session_name, char *event_list) exclusion_string, msg, print_channel_name(channel_name), - session_name, + session_name.c_str(), opt_filter); error = 1; break; @@ -1131,7 +846,7 @@ int enable_events(char *session_name, char *event_list) command_ret == -LTTNG_ERR_NEED_CHANNEL_NAME ? print_raw_channel_name(channel_name) : print_channel_name(channel_name), - session_name, + session_name.c_str(), opt_filter); error = 1; break; @@ -1140,7 +855,7 @@ int enable_events(char *session_name, char *event_list) } else { MSG("Event %s%s: Filter '%s' successfully set", - event_name, + pattern.c_str(), exclusion_string, opt_filter); } @@ -1184,8 +899,6 @@ int enable_events(char *session_name, char *event_list) } } - /* Next event */ - event_name = strtok(nullptr, ","); /* Reset warn, error and success */ success = 1; } @@ -1220,16 +933,21 @@ error: return ret; } +void _poptContextFree_deleter_func(poptContext ctx) +{ + poptFreeContext(ctx); +} + } /* namespace */ -int validate_exclusion_list(const char *event_name, +int validate_exclusion_list(const char *pattern, const struct lttng_dynamic_pointer_array *exclusions) { int ret; /* Event name must be a valid globbing pattern to allow exclusions. */ - if (!strutils_is_star_glob_pattern(event_name)) { - ERR("Event %s: Exclusions can only be used with a globbing pattern", event_name); + if (!strutils_is_star_glob_pattern(pattern)) { + ERR("Event %s: Exclusions can only be used with a globbing pattern", pattern); goto error; } @@ -1238,7 +956,7 @@ int validate_exclusion_list(const char *event_name, * then we can validate the individual exclusions. Otherwise * all exclusions are passed to the session daemon. */ - if (strutils_is_star_at_the_end_only_glob_pattern(event_name)) { + if (strutils_is_star_at_the_end_only_glob_pattern(pattern)) { size_t i, num_exclusions; num_exclusions = lttng_dynamic_pointer_array_get_count(exclusions); @@ -1250,7 +968,7 @@ int validate_exclusion_list(const char *event_name, if (!strutils_is_star_glob_pattern(exclusion) || strutils_is_star_at_the_end_only_glob_pattern(exclusion)) { - ret = check_exclusion_subsets(event_name, exclusion); + ret = check_exclusion_subsets(pattern, exclusion); if (ret) { goto error; } @@ -1274,24 +992,24 @@ end: int cmd_enable_events(int argc, const char **argv) { int opt, ret = CMD_SUCCESS, command_ret = CMD_SUCCESS, success = 1; - static poptContext pc; - char *session_name = nullptr; - char *event_list = nullptr; + std::string session_name; const char *arg_event_list = nullptr; const char *leftover = nullptr; int event_type = -1; + event_rule_patterns patterns; - pc = poptGetContext(nullptr, argc, argv, long_options, 0); - poptReadDefaultConfig(pc, 0); + auto pc = lttng::make_unique_wrapper( + poptGetContext(nullptr, argc, argv, long_options, 0)); + poptReadDefaultConfig(pc.get(), 0); /* Default event type */ opt_event_type = LTTNG_EVENT_ALL; - while ((opt = poptGetNextOpt(pc)) != -1) { + while ((opt = poptGetNextOpt(pc.get())) != -1) { switch (opt) { case OPT_HELP: SHOW_HELP(); - goto end; + return CMD_SUCCESS; case OPT_TRACEPOINT: opt_event_type = LTTNG_EVENT_TRACEPOINT; break; @@ -1312,22 +1030,21 @@ int cmd_enable_events(int argc, const char **argv) break; case OPT_LOGLEVEL: opt_loglevel_type = LTTNG_EVENT_LOGLEVEL_RANGE; - opt_loglevel = poptGetOptArg(pc); + opt_loglevel = poptGetOptArg(pc.get()); break; case OPT_LOGLEVEL_ONLY: opt_loglevel_type = LTTNG_EVENT_LOGLEVEL_SINGLE; - opt_loglevel = poptGetOptArg(pc); + opt_loglevel = poptGetOptArg(pc.get()); break; case OPT_LIST_OPTIONS: list_cmd_options(stdout, long_options); - goto end; + return CMD_SUCCESS; case OPT_FILTER: break; case OPT_EXCLUDE: break; default: - ret = CMD_UNDEFINED; - goto end; + return CMD_UNDEFINED; } /* Validate event type. Multiple event type are not supported. */ @@ -1336,8 +1053,7 @@ int cmd_enable_events(int argc, const char **argv) } else { if (event_type != opt_event_type) { ERR("Multiple event type not supported."); - ret = CMD_ERROR; - goto end; + return CMD_ERROR; } } } @@ -1345,109 +1061,101 @@ int cmd_enable_events(int argc, const char **argv) ret = print_missing_or_multiple_domains( opt_kernel + opt_userspace + opt_jul + opt_log4j + opt_python, true); if (ret) { - ret = CMD_ERROR; - goto end; + return CMD_ERROR; } /* Mi check */ if (lttng_opt_mi) { writer = mi_writer_uptr(mi_lttng_writer_create(fileno(stdout), lttng_opt_mi)); if (!writer) { - ret = -LTTNG_ERR_NOMEM; - goto end; + LTTNG_THROW_ERROR(lttng::format( + "Failed to create MI writer: format_code={}", lttng_opt_mi)); } /* Open command element */ ret = mi_lttng_writer_command_open(writer.get(), mi_lttng_element_command_enable_event); if (ret) { - ret = CMD_ERROR; - goto end; + LTTNG_THROW_ERROR(lttng::format( + "Failed to open MI command element: command_name=`{}`", + mi_lttng_element_command_enable_event)); } /* Open output element */ ret = mi_lttng_writer_open_element(writer.get(), mi_lttng_element_command_output); if (ret) { - ret = CMD_ERROR; - goto end; + LTTNG_THROW_ERROR( + lttng::format("Failed to open MI element: element_name=`{}`", + mi_lttng_element_command_output)); } } - arg_event_list = poptGetArg(pc); + /* Close the MI command context when leaving the function, no matter the result. */ + const auto close_mi_on_exit = lttng::make_scope_exit([&success]() noexcept { + if (!lttng_opt_mi) { + return; + } + + /* Close output element. */ + if (mi_lttng_writer_close_element(writer.get())) { + ERR_FMT("Failed to close MI output element"); + return; + } + + if (mi_lttng_writer_write_element_bool( + writer.get(), mi_lttng_element_command_success, success)) { + ERR_FMT("Failed to write MI element: element_name=`{}`, value={}", + mi_lttng_element_command_success, + success); + return; + } + + /* Command element close. */ + if (mi_lttng_writer_command_close(writer.get())) { + ERR_FMT("Failed to close MI command element"); + return; + } + }); + + arg_event_list = poptGetArg(pc.get()); if (arg_event_list == nullptr && opt_enable_all == 0) { ERR("Missing event name(s)."); - ret = CMD_ERROR; - goto end; + return CMD_ERROR; } - if (opt_enable_all == 0) { - event_list = strdup(arg_event_list); - if (event_list == nullptr) { - PERROR("Failed to copy event name(s)"); - ret = CMD_ERROR; - goto end; + if (opt_enable_all) { + patterns.emplace_back("*"); + } else { + std::stringstream event_list_arg_stream(arg_event_list); + + for (std::string line; std::getline(event_list_arg_stream, line, ',');) { + patterns.emplace_back(std::move(line)); } } - leftover = poptGetArg(pc); + leftover = poptGetArg(pc.get()); if (leftover) { ERR("Unknown argument: %s", leftover); - ret = CMD_ERROR; - goto end; + return CMD_ERROR; } if (!opt_session_name) { - session_name = get_session_name(); - if (session_name == nullptr) { - command_ret = CMD_ERROR; - success = 0; - goto mi_closing; + const auto rc_file_session_name = + lttng::make_unique_wrapper(get_session_name()); + + if (!rc_file_session_name) { + return CMD_ERROR; } + + session_name = rc_file_session_name.get(); } else { session_name = opt_session_name; } - command_ret = enable_events(session_name, event_list); + command_ret = enable_events(session_name, patterns); if (command_ret) { - success = 0; - goto mi_closing; - } - -mi_closing: - /* Mi closing */ - if (lttng_opt_mi) { - /* Close output element */ - ret = mi_lttng_writer_close_element(writer.get()); - if (ret) { - ret = CMD_ERROR; - goto end; - } - - ret = mi_lttng_writer_write_element_bool( - writer.get(), mi_lttng_element_command_success, success); - if (ret) { - ret = CMD_ERROR; - goto end; - } - - /* Command element close */ - ret = mi_lttng_writer_command_close(writer.get()); - if (ret) { - ret = CMD_ERROR; - goto end; - } - } - -end: - if (opt_session_name == nullptr) { - free(session_name); + return CMD_ERROR; } - free(event_list); - - /* Overwrite ret if an error occurred in enable_events */ - ret = command_ret ? command_ret : ret; - - poptFreeContext(pc); - return ret; + return CMD_SUCCESS; }