sessiond: lttng: Add command to check kernel tracer status
[lttng-tools.git] / src / bin / lttng / commands / enable_channels.cpp
index d62aa8656c51a84b395bda2f461e3b98b632a8ea..1638d0d446b88108aa2d96e595f622a2831e6298 100644 (file)
@@ -6,6 +6,18 @@
  */
 
 #define _LGPL_SOURCE
+#include "../command.hpp"
+#include "../utils.hpp"
+
+#include <common/mi-lttng.hpp>
+#include <common/sessiond-comm/sessiond-comm.hpp>
+#include <common/lttng-kernel.hpp>
+#include <common/utils.hpp>
+
+#include <lttng/domain-internal.hpp>
+
+#include <ctype.h>
+#include <inttypes.h>
 #include <popt.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <unistd.h>
-#include <inttypes.h>
-#include <ctype.h>
-
-#include <common/sessiond-comm/sessiond-comm.h>
-#include <common/utils.h>
-#include <common/mi-lttng.h>
-
-#include <lttng/domain-internal.h>
-
-#include "../command.h"
-#include "../utils.h"
-
 
 static struct lttng_channel chan_opts;
-static char *opt_channels;
 static int opt_kernel;
 static char *opt_session_name;
 static int opt_userspace;
@@ -49,7 +48,7 @@ static struct mi_writer *writer;
 #ifdef LTTNG_EMBED_HELP
 static const char help_msg[] =
 #include <lttng-enable-channel.1.h>
-;
+       ;
 #endif
 
 enum {
@@ -75,26 +74,26 @@ const char *output_splice = "splice";
 
 static struct poptOption long_options[] = {
        /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
-       {"help",           'h', POPT_ARG_NONE, 0, OPT_HELP, 0, 0},
-       {"session",        's', POPT_ARG_STRING, &opt_session_name, 0, 0, 0},
-       {"kernel",         'k', POPT_ARG_VAL, &opt_kernel, 1, 0, 0},
-       {"userspace",      'u', POPT_ARG_NONE, 0, OPT_USERSPACE, 0, 0},
-       {"discard",        0,   POPT_ARG_NONE, 0, OPT_DISCARD, 0, 0},
-       {"overwrite",      0,   POPT_ARG_NONE, 0, OPT_OVERWRITE, 0, 0},
-       {"subbuf-size",    0,   POPT_ARG_STRING, 0, OPT_SUBBUF_SIZE, 0, 0},
-       {"num-subbuf",     0,   POPT_ARG_INT, 0, OPT_NUM_SUBBUF, 0, 0},
-       {"switch-timer",   0,   POPT_ARG_INT, 0, OPT_SWITCH_TIMER, 0, 0},
-       {"monitor-timer",  0,   POPT_ARG_INT, 0, OPT_MONITOR_TIMER, 0, 0},
-       {"read-timer",     0,   POPT_ARG_INT, 0, OPT_READ_TIMER, 0, 0},
-       {"list-options",   0, POPT_ARG_NONE, NULL, OPT_LIST_OPTIONS, NULL, NULL},
-       {"output",         0,   POPT_ARG_STRING, &opt_output, 0, 0, 0},
-       {"buffers-uid",    0,   POPT_ARG_VAL, &opt_buffer_uid, 1, 0, 0},
-       {"buffers-pid",    0,   POPT_ARG_VAL, &opt_buffer_pid, 1, 0, 0},
-       {"buffers-global", 0,   POPT_ARG_VAL, &opt_buffer_global, 1, 0, 0},
-       {"tracefile-size", 'C',   POPT_ARG_INT, 0, OPT_TRACEFILE_SIZE, 0, 0},
-       {"tracefile-count", 'W',   POPT_ARG_INT, 0, OPT_TRACEFILE_COUNT, 0, 0},
-       {"blocking-timeout",     0,   POPT_ARG_INT, 0, OPT_BLOCKING_TIMEOUT, 0, 0},
-       {0, 0, 0, 0, 0, 0, 0}
+       { "help", 'h', POPT_ARG_NONE, nullptr, OPT_HELP, nullptr, nullptr },
+       { "session", 's', POPT_ARG_STRING, &opt_session_name, 0, nullptr, nullptr },
+       { "kernel", 'k', POPT_ARG_VAL, &opt_kernel, 1, nullptr, nullptr },
+       { "userspace", 'u', POPT_ARG_NONE, nullptr, OPT_USERSPACE, nullptr, nullptr },
+       { "discard", 0, POPT_ARG_NONE, nullptr, OPT_DISCARD, nullptr, nullptr },
+       { "overwrite", 0, POPT_ARG_NONE, nullptr, OPT_OVERWRITE, nullptr, nullptr },
+       { "subbuf-size", 0, POPT_ARG_STRING, nullptr, OPT_SUBBUF_SIZE, nullptr, nullptr },
+       { "num-subbuf", 0, POPT_ARG_INT, nullptr, OPT_NUM_SUBBUF, nullptr, nullptr },
+       { "switch-timer", 0, POPT_ARG_INT, nullptr, OPT_SWITCH_TIMER, nullptr, nullptr },
+       { "monitor-timer", 0, POPT_ARG_INT, nullptr, OPT_MONITOR_TIMER, nullptr, nullptr },
+       { "read-timer", 0, POPT_ARG_INT, nullptr, OPT_READ_TIMER, nullptr, nullptr },
+       { "list-options", 0, POPT_ARG_NONE, nullptr, OPT_LIST_OPTIONS, nullptr, nullptr },
+       { "output", 0, POPT_ARG_STRING, &opt_output, 0, nullptr, nullptr },
+       { "buffers-uid", 0, POPT_ARG_VAL, &opt_buffer_uid, 1, nullptr, nullptr },
+       { "buffers-pid", 0, POPT_ARG_VAL, &opt_buffer_pid, 1, nullptr, nullptr },
+       { "buffers-global", 0, POPT_ARG_VAL, &opt_buffer_global, 1, nullptr, nullptr },
+       { "tracefile-size", 'C', POPT_ARG_INT, nullptr, OPT_TRACEFILE_SIZE, nullptr, nullptr },
+       { "tracefile-count", 'W', POPT_ARG_INT, nullptr, OPT_TRACEFILE_COUNT, nullptr, nullptr },
+       { "blocking-timeout", 0, POPT_ARG_INT, nullptr, OPT_BLOCKING_TIMEOUT, nullptr, nullptr },
+       { nullptr, 0, 0, nullptr, 0, nullptr, nullptr }
 };
 
 /*
@@ -139,10 +138,11 @@ static void set_default_attr(struct lttng_domain *dom)
 /*
  * Adding channel using the lttng API.
  */
-static int enable_channel(char *session_name)
+static int enable_channel(char *session_name, char *channel_list)
 {
-       struct lttng_channel *channel = NULL;
+       struct lttng_channel *channel = nullptr;
        int ret = CMD_SUCCESS, warn = 0, error = 0, success = 0;
+       enum lttng_kernel_tracer_status kernel_tracer_status;
        char *channel_name;
        struct lttng_domain dom;
 
@@ -187,15 +187,16 @@ static int enable_channel(char *session_name)
 
        if (chan_opts.attr.tracefile_size == 0 && chan_opts.attr.tracefile_count) {
                ERR("Missing option --tracefile-size. "
-                               "A file count without a size won't do anything.");
+                   "A file count without a size won't do anything.");
                ret = CMD_ERROR;
                goto error;
        }
 
        if ((chan_opts.attr.tracefile_size > 0) &&
-                       (chan_opts.attr.tracefile_size < chan_opts.attr.subbuf_size)) {
+           (chan_opts.attr.tracefile_size < chan_opts.attr.subbuf_size)) {
                WARN("Tracefile size rounded up from (%" PRIu64 ") to subbuffer size (%" PRIu64 ")",
-                               chan_opts.attr.tracefile_size, chan_opts.attr.subbuf_size);
+                    chan_opts.attr.tracefile_size,
+                    chan_opts.attr.subbuf_size);
                chan_opts.attr.tracefile_size = chan_opts.attr.subbuf_size;
        }
 
@@ -207,14 +208,16 @@ static int enable_channel(char *session_name)
                        chan_opts.attr.output = LTTNG_EVENT_SPLICE;
                } else {
                        ERR("Unknown output type %s. Possible values are: %s, %s\n",
-                                       opt_output, output_mmap, output_splice);
+                           opt_output,
+                           output_mmap,
+                           output_splice);
                        ret = CMD_ERROR;
                        goto error;
                }
        }
 
        handle = lttng_create_handle(session_name, &dom);
-       if (handle == NULL) {
+       if (handle == nullptr) {
                ret = -1;
                goto error;
        }
@@ -230,14 +233,14 @@ static int enable_channel(char *session_name)
        }
 
        /* Strip channel list (format: chan1,chan2,...) */
-       channel_name = strtok(opt_channels, ",");
-       while (channel_name != NULL) {
+       channel_name = strtok(channel_list, ",");
+       while (channel_name != nullptr) {
                void *extended_ptr;
 
                /* Validate channel name's length */
                if (strlen(channel_name) >= sizeof(chan_opts.name)) {
                        ERR("Channel name is too long (max. %zu characters)",
-                                       sizeof(chan_opts.name) - 1);
+                           sizeof(chan_opts.name) - 1);
                        error = 1;
                        goto skip_enable;
                }
@@ -261,7 +264,7 @@ static int enable_channel(char *session_name)
                channel->attr.extended.ptr = extended_ptr;
                if (opt_monitor_timer.set) {
                        ret = lttng_channel_set_monitor_timer_interval(channel,
-                                       opt_monitor_timer.interval);
+                                                                      opt_monitor_timer.interval);
                        if (ret) {
                                ERR("Failed to set the channel's monitor timer interval");
                                error = 1;
@@ -270,7 +273,7 @@ static int enable_channel(char *session_name)
                }
                if (opt_blocking_timeout.set) {
                        ret = lttng_channel_set_blocking_timeout(channel,
-                                       opt_blocking_timeout.value);
+                                                                opt_blocking_timeout.value);
                        if (ret) {
                                ERR("Failed to set the channel's blocking timeout");
                                error = 1;
@@ -287,30 +290,73 @@ static int enable_channel(char *session_name)
                        case LTTNG_ERR_KERN_CHAN_EXIST:
                        case LTTNG_ERR_UST_CHAN_EXIST:
                        case LTTNG_ERR_CHAN_EXIST:
-                               WARN("Channel %s: %s (session %s)", channel_name,
-                                               lttng_strerror(ret), session_name);
+                               WARN("Channel %s: %s (session %s)",
+                                    channel_name,
+                                    lttng_strerror(ret),
+                                    session_name);
                                warn = 1;
                                break;
                        case LTTNG_ERR_INVALID_CHANNEL_NAME:
                                ERR("Invalid channel name: \"%s\". "
                                    "Channel names may not start with '.', and "
-                                   "may not contain '/'.", channel_name);
+                                   "may not contain '/'.",
+                                   channel_name);
                                error = 1;
                                break;
                        default:
-                               ERR("Channel %s: %s (session %s)", channel_name,
-                                               lttng_strerror(ret), session_name);
+                               ERR("Channel %s: %s (session %s)",
+                                   channel_name,
+                                   lttng_strerror(ret),
+                                   session_name);
                                error = 1;
                                break;
                        }
+                       /*
+                        * Ask the sessiond for the more details on the status of the kernel tracer.
+                        */
+                       ret = lttng_get_kernel_tracer_status(&kernel_tracer_status);
+                       if (ret < 0) {
+                               ERR("Failed to get kernel tracer status: %s", lttng_strerror(ret));
+                       } else {
+                               switch (kernel_tracer_status) {
+                               case LTTNG_KERNEL_TRACER_STATUS_INITIALIZED:
+                                       break;
+                               case LTTNG_KERNEL_TRACER_STATUS_ERR_MODULES_UNKNOWN:
+                                       MSG("\tKernel module loading failed");
+                                       break;
+                               case LTTNG_KERNEL_TRACER_STATUS_ERR_MODULES_MISSING:
+                                       MSG("\tMissing one or more required kernel modules");
+                                       break;
+                               case LTTNG_KERNEL_TRACER_STATUS_ERR_MODULES_SIGNATURE:
+                                       MSG("\tKernel module signature error prevented loading of one or more required kernel modules");
+                                       break;
+                               case LTTNG_KERNEL_TRACER_STATUS_ERR_NEED_ROOT:
+                                       MSG("\tlttng-sessiond isn't running as root");
+                                       break;
+                               case LTTNG_KERNEL_TRACER_STATUS_ERR_NOTIFIER:
+                                       MSG("\tFailed to setup notifiers");
+                                       break;
+                               case LTTNG_KERNEL_TRACER_STATUS_ERR_OPEN_PROC_LTTNG:
+                                       MSG("\tlttng-sessiond failed to open proc lttng");
+                                       break;
+                               case LTTNG_KERNEL_TRACER_STATUS_ERR_VERSION_MISMATCH:
+                                       MSG("\tVersion mismatch between kernel tracer and kernel tracer ABI");
+                                       break;
+                               default:
+                                       MSG("\tUnknown kernel tracer status (%d)", kernel_tracer_status);
+                                       break;
+                               }
+                               MSG("\tConsult lttng-sessiond logs for more information");
+                       }
                } else {
                        MSG("%s channel %s enabled for session %s",
-                                       lttng_domain_type_str(dom.type),
-                                       channel_name, session_name);
+                           lttng_domain_type_str(dom.type),
+                           channel_name,
+                           session_name);
                        success = 1;
                }
 
-skip_enable:
+       skip_enable:
                if (lttng_opt_mi) {
                        /* Mi print the channel element and leave it open */
                        ret = mi_lttng_channel(writer, channel, 1);
@@ -320,8 +366,8 @@ skip_enable:
                        }
 
                        /* Individual Success ? */
-                       ret = mi_lttng_writer_write_element_bool(writer,
-                                       mi_lttng_element_command_success, success);
+                       ret = mi_lttng_writer_write_element_bool(
+                               writer, mi_lttng_element_command_success, success);
                        if (ret) {
                                ret = CMD_ERROR;
                                goto error;
@@ -336,9 +382,9 @@ skip_enable:
                }
 
                /* Next channel */
-               channel_name = strtok(NULL, ",");
+               channel_name = strtok(nullptr, ",");
                lttng_channel_destroy(channel);
-               channel = NULL;
+               channel = nullptr;
        }
 
        if (lttng_opt_mi) {
@@ -373,14 +419,14 @@ error:
 /*
  * Default value for channel configuration.
  */
-static void init_channel_config(void)
+static void init_channel_config()
 {
        /*
         * Put -1 everywhere so we can identify those set by the command line and
         * those needed to be set by the default values.
         */
        memset(&chan_opts.attr, -1, sizeof(chan_opts.attr));
-       chan_opts.attr.extended.ptr = NULL;
+       chan_opts.attr.extended.ptr = nullptr;
 }
 
 /*
@@ -390,13 +436,15 @@ int cmd_enable_channels(int argc, const char **argv)
 {
        int opt, ret = CMD_SUCCESS, command_ret = CMD_SUCCESS, success = 1;
        static poptContext pc;
-       char *session_name = NULL;
-       char *opt_arg = NULL;
-       const char *leftover = NULL;
+       char *session_name = nullptr;
+       char *channel_list = nullptr;
+       char *opt_arg = nullptr;
+       const char *arg_channel_list = nullptr;
+       const char *leftover = nullptr;
 
        init_channel_config();
 
-       pc = poptGetContext(NULL, argc, argv, long_options, 0);
+       pc = poptGetContext(nullptr, argc, argv, long_options, 0);
        poptReadDefaultConfig(pc, 0);
 
        while ((opt = poptGetNextOpt(pc)) != -1) {
@@ -419,7 +467,8 @@ int cmd_enable_channels(int argc, const char **argv)
 
                        /* Parse the size */
                        opt_arg = poptGetOptArg(pc);
-                       if (utils_parse_size_suffix(opt_arg, &chan_opts.attr.subbuf_size) < 0 || !chan_opts.attr.subbuf_size) {
+                       if (utils_parse_size_suffix(opt_arg, &chan_opts.attr.subbuf_size) < 0 ||
+                           !chan_opts.attr.subbuf_size) {
                                ERR("Wrong value in --subbuf-size parameter: %s", opt_arg);
                                ret = CMD_ERROR;
                                goto end;
@@ -430,19 +479,22 @@ int cmd_enable_channels(int argc, const char **argv)
                        rounded_size = 1ULL << order;
                        if (rounded_size < chan_opts.attr.subbuf_size) {
                                ERR("The subbuf size (%" PRIu64 ") is rounded and overflows!",
-                                               chan_opts.attr.subbuf_size);
+                                   chan_opts.attr.subbuf_size);
                                ret = CMD_ERROR;
                                goto end;
                        }
 
                        if (rounded_size != chan_opts.attr.subbuf_size) {
-                               WARN("The subbuf size (%" PRIu64 ") is rounded to the next power of 2 (%" PRIu64 ")",
-                                               chan_opts.attr.subbuf_size, rounded_size);
+                               WARN("The subbuf size (%" PRIu64
+                                    ") is rounded to the next power of 2 (%" PRIu64 ")",
+                                    chan_opts.attr.subbuf_size,
+                                    rounded_size);
                                chan_opts.attr.subbuf_size = rounded_size;
                        }
 
                        /* Should now be power of 2 */
-                       LTTNG_ASSERT(!((chan_opts.attr.subbuf_size - 1) & chan_opts.attr.subbuf_size));
+                       LTTNG_ASSERT(
+                               !((chan_opts.attr.subbuf_size - 1) & chan_opts.attr.subbuf_size));
 
                        DBG("Channel subbuf size set to %" PRIu64, chan_opts.attr.subbuf_size);
                        break;
@@ -454,7 +506,7 @@ int cmd_enable_channels(int argc, const char **argv)
 
                        errno = 0;
                        opt_arg = poptGetOptArg(pc);
-                       chan_opts.attr.num_subbuf = strtoull(opt_arg, NULL, 0);
+                       chan_opts.attr.num_subbuf = strtoull(opt_arg, nullptr, 0);
                        if (errno != 0 || !chan_opts.attr.num_subbuf || !isdigit(opt_arg[0])) {
                                ERR("Wrong value in --num-subbuf parameter: %s", opt_arg);
                                ret = CMD_ERROR;
@@ -465,20 +517,24 @@ int cmd_enable_channels(int argc, const char **argv)
                        LTTNG_ASSERT(order >= 0);
                        rounded_size = 1ULL << order;
                        if (rounded_size < chan_opts.attr.num_subbuf) {
-                               ERR("The number of subbuffers (%" PRIu64 ") is rounded and overflows!",
-                                               chan_opts.attr.num_subbuf);
+                               ERR("The number of subbuffers (%" PRIu64
+                                   ") is rounded and overflows!",
+                                   chan_opts.attr.num_subbuf);
                                ret = CMD_ERROR;
                                goto end;
                        }
 
                        if (rounded_size != chan_opts.attr.num_subbuf) {
-                               WARN("The number of subbuffers (%" PRIu64 ") is rounded to the next power of 2 (%" PRIu64 ")",
-                                               chan_opts.attr.num_subbuf, rounded_size);
+                               WARN("The number of subbuffers (%" PRIu64
+                                    ") is rounded to the next power of 2 (%" PRIu64 ")",
+                                    chan_opts.attr.num_subbuf,
+                                    rounded_size);
                                chan_opts.attr.num_subbuf = rounded_size;
                        }
 
                        /* Should now be power of 2 */
-                       LTTNG_ASSERT(!((chan_opts.attr.num_subbuf - 1) & chan_opts.attr.num_subbuf));
+                       LTTNG_ASSERT(
+                               !((chan_opts.attr.num_subbuf - 1) & chan_opts.attr.num_subbuf));
 
                        DBG("Channel subbuf num set to %" PRIu64, chan_opts.attr.num_subbuf);
                        break;
@@ -503,8 +559,8 @@ int cmd_enable_channels(int argc, const char **argv)
                        }
                        chan_opts.attr.switch_timer_interval = (uint32_t) v;
                        DBG("Channel switch timer interval set to %d %s",
-                                       chan_opts.attr.switch_timer_interval,
-                                       USEC_UNIT);
+                           chan_opts.attr.switch_timer_interval,
+                           USEC_UNIT);
                        break;
                }
                case OPT_READ_TIMER:
@@ -527,8 +583,8 @@ int cmd_enable_channels(int argc, const char **argv)
                        }
                        chan_opts.attr.read_timer_interval = (uint32_t) v;
                        DBG("Channel read timer interval set to %d %s",
-                                       chan_opts.attr.read_timer_interval,
-                                       USEC_UNIT);
+                           chan_opts.attr.read_timer_interval,
+                           USEC_UNIT);
                        break;
                }
                case OPT_MONITOR_TIMER:
@@ -546,8 +602,8 @@ int cmd_enable_channels(int argc, const char **argv)
                        opt_monitor_timer.interval = (uint64_t) v;
                        opt_monitor_timer.set = true;
                        DBG("Channel monitor timer interval set to %" PRIu64 " %s",
-                                       opt_monitor_timer.interval,
-                                       USEC_UNIT);
+                           opt_monitor_timer.interval,
+                           USEC_UNIT);
                        break;
                }
                case OPT_BLOCKING_TIMEOUT:
@@ -588,7 +644,8 @@ int cmd_enable_channels(int argc, const char **argv)
                         */
                        v_msec = v / 1000;
                        if (v_msec != (int32_t) v_msec) {
-                               ERR("32-bit milliseconds overflow in --blocking-timeout parameter: %s", opt_arg);
+                               ERR("32-bit milliseconds overflow in --blocking-timeout parameter: %s",
+                                   opt_arg);
                                ret = CMD_ERROR;
                                goto end;
                        }
@@ -596,10 +653,9 @@ int cmd_enable_channels(int argc, const char **argv)
                        opt_blocking_timeout.value = (int64_t) v;
                        opt_blocking_timeout.set = true;
                        DBG("Channel blocking timeout set to %" PRId64 " %s%s",
-                                       opt_blocking_timeout.value,
-                                       USEC_UNIT,
-                                       opt_blocking_timeout.value == 0 ?
-                                               " (non-blocking)" : "");
+                           opt_blocking_timeout.value,
+                           USEC_UNIT,
+                           opt_blocking_timeout.value == 0 ? " (non-blocking)" : "");
                        break;
                }
                case OPT_USERSPACE:
@@ -613,7 +669,7 @@ int cmd_enable_channels(int argc, const char **argv)
                                goto end;
                        }
                        DBG("Maximum tracefile size set to %" PRIu64,
-                                       chan_opts.attr.tracefile_size);
+                           chan_opts.attr.tracefile_size);
                        break;
                case OPT_TRACEFILE_COUNT:
                {
@@ -621,7 +677,7 @@ int cmd_enable_channels(int argc, const char **argv)
 
                        errno = 0;
                        opt_arg = poptGetOptArg(pc);
-                       v = strtoul(opt_arg, NULL, 0);
+                       v = strtoul(opt_arg, nullptr, 0);
                        if (errno != 0 || !isdigit(opt_arg[0])) {
                                ERR("Wrong value in --tracefile-count parameter: %s", opt_arg);
                                ret = CMD_ERROR;
@@ -634,7 +690,7 @@ int cmd_enable_channels(int argc, const char **argv)
                        }
                        chan_opts.attr.tracefile_count = (uint32_t) v;
                        DBG("Maximum tracefile count set to %" PRIu64,
-                                       chan_opts.attr.tracefile_count);
+                           chan_opts.attr.tracefile_count);
                        break;
                }
                case OPT_LIST_OPTIONS:
@@ -644,19 +700,23 @@ int cmd_enable_channels(int argc, const char **argv)
                        ret = CMD_UNDEFINED;
                        goto end;
                }
+
+               if (opt_arg) {
+                       free(opt_arg);
+                       opt_arg = nullptr;
+               }
        }
 
-       ret = print_missing_or_multiple_domains(
-                       opt_kernel + opt_userspace, false);
+       ret = print_missing_or_multiple_domains(opt_kernel + opt_userspace, false);
        if (ret) {
                ret = CMD_ERROR;
                goto end;
        }
 
        if (chan_opts.attr.overwrite == 1 && opt_blocking_timeout.set &&
-                       opt_blocking_timeout.value != 0) {
+           opt_blocking_timeout.value != 0) {
                ERR("You cannot specify --overwrite and --blocking-timeout=N, "
-                       "where N is different than 0");
+                   "where N is different than 0");
                ret = CMD_ERROR;
                goto end;
        }
@@ -671,24 +731,31 @@ int cmd_enable_channels(int argc, const char **argv)
 
                /* Open command element */
                ret = mi_lttng_writer_command_open(writer,
-                               mi_lttng_element_command_enable_channels);
+                                                  mi_lttng_element_command_enable_channels);
                if (ret) {
                        ret = CMD_ERROR;
                        goto end;
                }
 
                /* Open output element */
-               ret = mi_lttng_writer_open_element(writer,
-                               mi_lttng_element_command_output);
+               ret = mi_lttng_writer_open_element(writer, mi_lttng_element_command_output);
                if (ret) {
                        ret = CMD_ERROR;
                        goto end;
                }
        }
 
-       opt_channels = (char*) poptGetArg(pc);
-       if (opt_channels == NULL) {
-               ERR("Missing channel name.\n");
+       arg_channel_list = poptGetArg(pc);
+       if (arg_channel_list == nullptr) {
+               ERR("Missing channel name.");
+               ret = CMD_ERROR;
+               success = 0;
+               goto mi_closing;
+       }
+
+       channel_list = strdup(arg_channel_list);
+       if (channel_list == nullptr) {
+               PERROR("Failed to copy channel name");
                ret = CMD_ERROR;
                success = 0;
                goto mi_closing;
@@ -704,7 +771,7 @@ int cmd_enable_channels(int argc, const char **argv)
 
        if (!opt_session_name) {
                session_name = get_session_name();
-               if (session_name == NULL) {
+               if (session_name == nullptr) {
                        command_ret = CMD_ERROR;
                        success = 0;
                        goto mi_closing;
@@ -713,7 +780,7 @@ int cmd_enable_channels(int argc, const char **argv)
                session_name = opt_session_name;
        }
 
-       command_ret = enable_channel(session_name);
+       command_ret = enable_channel(session_name, channel_list);
        if (command_ret) {
                success = 0;
        }
@@ -728,8 +795,8 @@ mi_closing:
                }
 
                /* Success ? */
-               ret = mi_lttng_writer_write_element_bool(writer,
-                               mi_lttng_element_command_success, success);
+               ret = mi_lttng_writer_write_element_bool(
+                       writer, mi_lttng_element_command_success, success);
                if (ret) {
                        goto end;
                }
@@ -752,8 +819,11 @@ end:
                free(session_name);
        }
 
+       free(channel_list);
+
        /* Overwrite ret if an error occurred when enable_channel */
        ret = command_ret ? command_ret : ret;
        poptFreeContext(pc);
+       free(opt_arg);
        return ret;
 }
This page took 0.031483 seconds and 4 git commands to generate.