X-Git-Url: http://git.efficios.com/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fbin%2Flttng%2Fcommands%2Fenable_channels.c;h=214c8a3621660c8cf83cbd31edf26e7b7c06aebc;hp=fa8513e72320c1f835af634fed3f14dbca5d18d8;hb=7010c0332387eea98b52f301458d481f151840a6;hpb=cf0bcb51ea857687a353d2851e572dba6cc63cb0 diff --git a/src/bin/lttng/commands/enable_channels.c b/src/bin/lttng/commands/enable_channels.c index fa8513e72..214c8a362 100644 --- a/src/bin/lttng/commands/enable_channels.c +++ b/src/bin/lttng/commands/enable_channels.c @@ -46,11 +46,21 @@ static int opt_buffer_pid; static int opt_buffer_global; static struct { bool set; - uint32_t interval; + uint64_t interval; } opt_monitor_timer; +static struct { + bool set; + int64_t value; +} opt_blocking_timeout; static struct mi_writer *writer; +#ifdef LTTNG_EMBED_HELP +static const char help_msg[] = +#include +; +#endif + enum { OPT_HELP = 1, OPT_DISCARD, @@ -64,6 +74,7 @@ enum { OPT_LIST_OPTIONS, OPT_TRACEFILE_SIZE, OPT_TRACEFILE_COUNT, + OPT_BLOCKING_TIMEOUT, }; static struct lttng_handle *handle; @@ -91,6 +102,7 @@ static struct poptOption long_options[] = { {"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} }; @@ -102,6 +114,8 @@ static void set_default_attr(struct lttng_domain *dom) { struct lttng_channel_attr default_attr; + memset(&default_attr, 0, sizeof(default_attr)); + /* Set attributes */ lttng_channel_set_default_attr(dom, &default_attr); @@ -143,6 +157,15 @@ static int enable_channel(char *session_name) memset(&dom, 0, sizeof(dom)); + /* Validate options. */ + if (opt_kernel) { + if (opt_blocking_timeout.set) { + ERR("Retry timeout option not supported for kernel domain (-k)"); + ret = CMD_ERROR; + goto error; + } + } + /* Create lttng domain */ if (opt_kernel) { dom.type = LTTNG_DOMAIN_KERNEL; @@ -254,6 +277,15 @@ static int enable_channel(char *session_name) goto error; } } + if (opt_blocking_timeout.set) { + ret = lttng_channel_set_blocking_timeout(channel, + opt_blocking_timeout.value); + if (ret) { + ERR("Failed to set the channel's blocking timeout"); + error = 1; + goto error; + } + } DBG("Enabling channel %s", channel_name); @@ -368,6 +400,7 @@ int cmd_enable_channels(int argc, const char **argv) static poptContext pc; char *session_name = NULL; char *opt_arg = NULL; + const char *leftover = NULL; init_channel_config(); @@ -502,24 +535,70 @@ int cmd_enable_channels(int argc, const char **argv) } case OPT_MONITOR_TIMER: { - unsigned long v; + uint64_t v; errno = 0; opt_arg = poptGetOptArg(pc); - v = strtoul(opt_arg, NULL, 0); - if (errno != 0 || !isdigit(opt_arg[0])) { - ERR("Wrong value in --monitor-timer parameter: %s", opt_arg); + + if (utils_parse_time_suffix(opt_arg, &v) < 0) { + ERR("Wrong value for --monitor-timer parameter: %s", opt_arg); ret = CMD_ERROR; goto end; } - if (v != (uint32_t) v) { - ERR("32-bit overflow in --monitor-timer parameter: %s", opt_arg); + 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); + break; + } + case OPT_BLOCKING_TIMEOUT: + { + uint64_t v; + long long v_msec; + + errno = 0; + opt_arg = poptGetOptArg(pc); + + if (strcmp(opt_arg, "inf") == 0) { + opt_blocking_timeout.value = (int64_t) -1; + opt_blocking_timeout.set = true; + DBG("Channel blocking timeout set to infinity"); + break; + } + + if (utils_parse_time_suffix(opt_arg, &v) < 0) { + ERR("Wrong value for --blocking-timeout parameter: %s", opt_arg); ret = CMD_ERROR; goto end; } - opt_monitor_timer.interval = (uint32_t) v; - opt_monitor_timer.set = true; - DBG("Channel monitor timer interval set to %d", opt_monitor_timer.interval); + + /* + * While LTTng-UST and LTTng-tools will accept a + * blocking timeout expressed in µs, the current + * tracer implementation relies on poll() which + * takes an "int timeout" parameter expressed in + * msec. + * + * Since the error reporting from the tracer is + * not precise, we perform this check here to + * provide a helpful error message in case of + * overflow. + * + * The setter (liblttng-ctl) also performs an + * equivalent check. + */ + v_msec = v / 1000; + if (v_msec != (int32_t) v_msec) { + ERR("32-bit milliseconds overflow in --blocking-timeout parameter: %s", opt_arg); + ret = CMD_ERROR; + goto end; + } + + 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, + opt_blocking_timeout.value == 0 ? + " (non-blocking)" : ""); break; } case OPT_USERSPACE: @@ -572,6 +651,14 @@ int cmd_enable_channels(int argc, const char **argv) goto end; } + if (chan_opts.attr.overwrite == 1 && opt_blocking_timeout.set && + opt_blocking_timeout.value != 0) { + ERR("You cannot specify --overwrite and --blocking-timeout=N, " + "where N is different than 0"); + ret = CMD_ERROR; + goto end; + } + /* Mi check */ if (lttng_opt_mi) { writer = mi_lttng_writer_create(fileno(stdout), lttng_opt_mi); @@ -605,6 +692,14 @@ int cmd_enable_channels(int argc, const char **argv) goto mi_closing; } + leftover = poptGetArg(pc); + if (leftover) { + ERR("Unknown argument: %s", leftover); + ret = CMD_ERROR; + success = 0; + goto mi_closing; + } + if (!opt_session_name) { session_name = get_session_name(); if (session_name == NULL) {