Expose monitor timer interval to lttngctl and client
authorJérémie Galarneau <jeremie.galarneau@efficios.com>
Fri, 5 May 2017 03:53:50 +0000 (23:53 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Fri, 5 May 2017 13:32:33 +0000 (09:32 -0400)
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
13 files changed:
include/lttng/channel.h
src/bin/lttng-sessiond/cmd.c
src/bin/lttng/commands/enable_channels.c
src/bin/lttng/commands/list.c
src/common/config/config-session-abi.h
src/common/config/session-config.c
src/common/consumer/consumer-testpoint.h
src/common/consumer/consumer.c
src/common/consumer/consumer.h
src/common/kernel-ctl/kernel-ioctl.h
src/common/mi-lttng-3.0.xsd
src/common/mi-lttng.c
src/lib/lttng-ctl/lttng-ctl.c

index 732074c3ae99d8c137483cd792e62e4dbafd2da4..e20ed4f4fce981cff071482817ca5108677df026 100644 (file)
@@ -68,6 +68,14 @@ struct lttng_channel {
        char padding[LTTNG_CHANNEL_PADDING1];
 };
 
+/*
+ */
+extern struct lttng_channel *lttng_channel_create(struct lttng_domain *domain);
+
+/*
+ */
+extern void lttng_channel_destroy(struct lttng_channel *channel);
+
 /*
  * List the channel(s) of a session.
  *
@@ -124,6 +132,12 @@ extern int lttng_channel_get_discarded_event_count(struct lttng_channel *chan,
 extern int lttng_channel_get_lost_packet_count(struct lttng_channel *chan,
                uint64_t *lost_packets);
 
+extern int lttng_channel_get_monitor_timer_interval(struct lttng_channel *chan,
+               uint64_t *monitor_timer_interval);
+
+extern int lttng_channel_set_monitor_timer_interval(struct lttng_channel *chan,
+               uint64_t monitor_timer_interval);
+
 #ifdef __cplusplus
 }
 #endif
index 5e146931e5e31d848d99232068c9c4c8b59aca5a..7b9647436ac82e059fdc61aa7216ddbbe9ca9dfc 100644 (file)
@@ -245,7 +245,7 @@ end:
  */
 static void list_lttng_channels(enum lttng_domain_type domain,
                struct ltt_session *session, struct lttng_channel *channels,
-               struct lttcomm_channel_extended *chan_exts)
+               struct lttng_channel_extended *chan_exts)
 {
        int i = 0, ret;
        struct ltt_kernel_channel *kchan;
@@ -259,6 +259,10 @@ static void list_lttng_channels(enum lttng_domain_type domain,
                        cds_list_for_each_entry(kchan,
                                        &session->kernel_session->channel_list.head, list) {
                                uint64_t discarded_events, lost_packets;
+                               struct lttng_channel_extended *extended;
+
+                               extended = (struct lttng_channel_extended *)
+                                               kchan->channel->attr.extended.ptr;
 
                                ret = get_kernel_runtime_stats(session, kchan,
                                                &discarded_events, &lost_packets);
@@ -271,6 +275,8 @@ static void list_lttng_channels(enum lttng_domain_type domain,
                                chan_exts[i].discarded_events =
                                                discarded_events;
                                chan_exts[i].lost_packets = lost_packets;
+                               chan_exts[i].monitor_timer_interval =
+                                               extended->monitor_timer_interval;
                                i++;
                        }
                }
@@ -323,6 +329,8 @@ static void list_lttng_channels(enum lttng_domain_type domain,
                        }
                        chan_exts[i].discarded_events = discarded_events;
                        chan_exts[i].lost_packets = lost_packets;
+                       chan_exts[i].monitor_timer_interval =
+                                       uchan->monitor_timer_interval;
                        i++;
                }
                rcu_read_unlock();
@@ -1681,7 +1689,7 @@ int cmd_add_context(struct ltt_session *session, enum lttng_domain_type domain,
                                free(attr);
                                goto error;
                        }
-                       free(attr);
+                       channel_attr_destroy(attr);
                        chan_ust_created = 1;
                }
 
@@ -2179,7 +2187,7 @@ error:
        free(filter_expression);
        free(filter);
        free(exclusion);
-       free(attr);
+       channel_attr_destroy(attr);
        rcu_read_unlock();
        return ret;
 }
@@ -2948,8 +2956,8 @@ ssize_t cmd_list_channels(enum lttng_domain_type domain,
 
        if (nb_chan > 0) {
                const size_t channel_size = sizeof(struct lttng_channel) +
-                       sizeof(struct lttcomm_channel_extended);
-               struct lttcomm_channel_extended *channel_exts;
+                       sizeof(struct lttng_channel_extended);
+               struct lttng_channel_extended *channel_exts;
 
                payload_size = nb_chan * channel_size;
                *channels = zmalloc(payload_size);
index 9a990030d5023ff38f0b984f1329f32e5feb849f..fa8513e72320c1f835af634fed3f14dbca5d18d8 100644 (file)
 #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;
-static struct lttng_channel chan;
 static char *opt_output;
 static int opt_buffer_uid;
 static int opt_buffer_pid;
 static int opt_buffer_global;
+static struct {
+       bool set;
+       uint32_t interval;
+} opt_monitor_timer;
 
 static struct mi_writer *writer;
 
@@ -54,6 +58,7 @@ enum {
        OPT_SUBBUF_SIZE,
        OPT_NUM_SUBBUF,
        OPT_SWITCH_TIMER,
+       OPT_MONITOR_TIMER,
        OPT_READ_TIMER,
        OPT_USERSPACE,
        OPT_LIST_OPTIONS,
@@ -77,6 +82,7 @@ static struct poptOption long_options[] = {
        {"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},
@@ -99,29 +105,29 @@ static void set_default_attr(struct lttng_domain *dom)
        /* Set attributes */
        lttng_channel_set_default_attr(dom, &default_attr);
 
-       if (chan.attr.overwrite == -1) {
-               chan.attr.overwrite = default_attr.overwrite;
+       if (chan_opts.attr.overwrite == -1) {
+               chan_opts.attr.overwrite = default_attr.overwrite;
        }
-       if (chan.attr.subbuf_size == -1) {
-               chan.attr.subbuf_size = default_attr.subbuf_size;
+       if (chan_opts.attr.subbuf_size == -1) {
+               chan_opts.attr.subbuf_size = default_attr.subbuf_size;
        }
-       if (chan.attr.num_subbuf == -1) {
-               chan.attr.num_subbuf = default_attr.num_subbuf;
+       if (chan_opts.attr.num_subbuf == -1) {
+               chan_opts.attr.num_subbuf = default_attr.num_subbuf;
        }
-       if (chan.attr.switch_timer_interval == -1) {
-               chan.attr.switch_timer_interval = default_attr.switch_timer_interval;
+       if (chan_opts.attr.switch_timer_interval == -1) {
+               chan_opts.attr.switch_timer_interval = default_attr.switch_timer_interval;
        }
-       if (chan.attr.read_timer_interval == -1) {
-               chan.attr.read_timer_interval = default_attr.read_timer_interval;
+       if (chan_opts.attr.read_timer_interval == -1) {
+               chan_opts.attr.read_timer_interval = default_attr.read_timer_interval;
        }
-       if ((int) chan.attr.output == -1) {
-               chan.attr.output = default_attr.output;
+       if ((int) chan_opts.attr.output == -1) {
+               chan_opts.attr.output = default_attr.output;
        }
-       if (chan.attr.tracefile_count == -1) {
-               chan.attr.tracefile_count = default_attr.tracefile_count;
+       if (chan_opts.attr.tracefile_count == -1) {
+               chan_opts.attr.tracefile_count = default_attr.tracefile_count;
        }
-       if (chan.attr.tracefile_size == -1) {
-               chan.attr.tracefile_size = default_attr.tracefile_size;
+       if (chan_opts.attr.tracefile_size == -1) {
+               chan_opts.attr.tracefile_size = default_attr.tracefile_size;
        }
 }
 
@@ -130,6 +136,7 @@ static void set_default_attr(struct lttng_domain *dom)
  */
 static int enable_channel(char *session_name)
 {
+       struct lttng_channel *channel = NULL;
        int ret = CMD_SUCCESS, warn = 0, error = 0, success = 0;
        char *channel_name;
        struct lttng_domain dom;
@@ -164,26 +171,26 @@ static int enable_channel(char *session_name)
 
        set_default_attr(&dom);
 
-       if (chan.attr.tracefile_size == 0 && chan.attr.tracefile_count) {
+       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.");
                ret = CMD_ERROR;
                goto error;
        }
 
-       if ((chan.attr.tracefile_size > 0) &&
-                       (chan.attr.tracefile_size < chan.attr.subbuf_size)) {
+       if ((chan_opts.attr.tracefile_size > 0) &&
+                       (chan_opts.attr.tracefile_size < chan_opts.attr.subbuf_size)) {
                WARN("Tracefile size rounded up from (%" PRIu64 ") to subbuffer size (%" PRIu64 ")",
-                               chan.attr.tracefile_size, chan.attr.subbuf_size);
-               chan.attr.tracefile_size = chan.attr.subbuf_size;
+                               chan_opts.attr.tracefile_size, chan_opts.attr.subbuf_size);
+               chan_opts.attr.tracefile_size = chan_opts.attr.subbuf_size;
        }
 
        /* Setting channel output */
        if (opt_output) {
                if (!strncmp(output_mmap, opt_output, strlen(output_mmap))) {
-                       chan.attr.output = LTTNG_EVENT_MMAP;
+                       chan_opts.attr.output = LTTNG_EVENT_MMAP;
                } else if (!strncmp(output_splice, opt_output, strlen(output_splice))) {
-                       chan.attr.output = LTTNG_EVENT_SPLICE;
+                       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);
@@ -211,20 +218,46 @@ static int enable_channel(char *session_name)
        /* Strip channel list (format: chan1,chan2,...) */
        channel_name = strtok(opt_channels, ",");
        while (channel_name != NULL) {
+               void *extended_ptr;
+
                /* Validate channel name's length */
                if (strlen(channel_name) >= NAME_MAX) {
                        ERR("Channel name is too long (max. %zu characters)",
-                                       sizeof(chan.name) - 1);
+                                       sizeof(chan_opts.name) - 1);
                        error = 1;
                        goto skip_enable;
                }
 
+               /*
+                * A dynamically-allocated channel is used in order to allow
+                * the configuration of extended attributes (post-2.9).
+                */
+               channel = lttng_channel_create(&dom);
+               if (!channel) {
+                       ERR("Unable to create channel object");
+                       error = 1;
+                       goto error;
+               }
+
                /* Copy channel name */
-               strcpy(chan.name, channel_name);
+               strcpy(channel->name, channel_name);
+               channel->enabled = 1;
+               extended_ptr = channel->attr.extended.ptr;
+               memcpy(&channel->attr, &chan_opts.attr, sizeof(chan_opts.attr));
+               channel->attr.extended.ptr = extended_ptr;
+               if (opt_monitor_timer.set) {
+                       ret = lttng_channel_set_monitor_timer_interval(channel,
+                                       opt_monitor_timer.interval);
+                       if (ret) {
+                               ERR("Failed to set the channel's monitor timer interval");
+                               error = 1;
+                               goto error;
+                       }
+               }
 
                DBG("Enabling channel %s", channel_name);
 
-               ret = lttng_enable_channel(handle, &chan);
+               ret = lttng_enable_channel(handle, channel);
                if (ret < 0) {
                        success = 0;
                        switch (-ret) {
@@ -256,7 +289,7 @@ static int enable_channel(char *session_name)
 skip_enable:
                if (lttng_opt_mi) {
                        /* Mi print the channel element and leave it open */
-                       ret = mi_lttng_channel(writer, &chan, 1);
+                       ret = mi_lttng_channel(writer, channel, 1);
                        if (ret) {
                                ret = CMD_ERROR;
                                goto error;
@@ -280,6 +313,8 @@ skip_enable:
 
                /* Next channel */
                channel_name = strtok(NULL, ",");
+               lttng_channel_destroy(channel);
+               channel = NULL;
        }
 
        if (lttng_opt_mi) {
@@ -294,6 +329,9 @@ skip_enable:
        ret = CMD_SUCCESS;
 
 error:
+       if (channel) {
+               lttng_channel_destroy(channel);
+       }
        /* If more important error happen bypass the warning */
        if (!ret && warn) {
                ret = CMD_WARNING;
@@ -317,8 +355,8 @@ static void init_channel_config(void)
         * 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.attr, -1, sizeof(chan.attr));
-       chan.attr.extended.ptr = NULL;
+       memset(&chan_opts.attr, -1, sizeof(chan_opts.attr));
+       chan_opts.attr.extended.ptr = NULL;
 }
 
 /*
@@ -342,11 +380,11 @@ int cmd_enable_channels(int argc, const char **argv)
                        SHOW_HELP();
                        goto end;
                case OPT_DISCARD:
-                       chan.attr.overwrite = 0;
+                       chan_opts.attr.overwrite = 0;
                        DBG("Channel set to discard");
                        break;
                case OPT_OVERWRITE:
-                       chan.attr.overwrite = 1;
+                       chan_opts.attr.overwrite = 1;
                        DBG("Channel set to overwrite");
                        break;
                case OPT_SUBBUF_SIZE:
@@ -356,32 +394,32 @@ int cmd_enable_channels(int argc, const char **argv)
 
                        /* Parse the size */
                        opt_arg = poptGetOptArg(pc);
-                       if (utils_parse_size_suffix(opt_arg, &chan.attr.subbuf_size) < 0 || !chan.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;
                        }
 
-                       order = get_count_order_u64(chan.attr.subbuf_size);
+                       order = get_count_order_u64(chan_opts.attr.subbuf_size);
                        assert(order >= 0);
                        rounded_size = 1ULL << order;
-                       if (rounded_size < chan.attr.subbuf_size) {
+                       if (rounded_size < chan_opts.attr.subbuf_size) {
                                ERR("The subbuf size (%" PRIu64 ") is rounded and overflows!",
-                                               chan.attr.subbuf_size);
+                                               chan_opts.attr.subbuf_size);
                                ret = CMD_ERROR;
                                goto end;
                        }
 
-                       if (rounded_size != chan.attr.subbuf_size) {
+                       if (rounded_size != chan_opts.attr.subbuf_size) {
                                WARN("The subbuf size (%" PRIu64 ") is rounded to the next power of 2 (%" PRIu64 ")",
-                                               chan.attr.subbuf_size, rounded_size);
-                               chan.attr.subbuf_size = rounded_size;
+                                               chan_opts.attr.subbuf_size, rounded_size);
+                               chan_opts.attr.subbuf_size = rounded_size;
                        }
 
                        /* Should now be power of 2 */
-                       assert(!((chan.attr.subbuf_size - 1) & chan.attr.subbuf_size));
+                       assert(!((chan_opts.attr.subbuf_size - 1) & chan_opts.attr.subbuf_size));
 
-                       DBG("Channel subbuf size set to %" PRIu64, chan.attr.subbuf_size);
+                       DBG("Channel subbuf size set to %" PRIu64, chan_opts.attr.subbuf_size);
                        break;
                }
                case OPT_NUM_SUBBUF:
@@ -391,33 +429,33 @@ int cmd_enable_channels(int argc, const char **argv)
 
                        errno = 0;
                        opt_arg = poptGetOptArg(pc);
-                       chan.attr.num_subbuf = strtoull(opt_arg, NULL, 0);
-                       if (errno != 0 || !chan.attr.num_subbuf || !isdigit(opt_arg[0])) {
+                       chan_opts.attr.num_subbuf = strtoull(opt_arg, NULL, 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;
                                goto end;
                        }
 
-                       order = get_count_order_u64(chan.attr.num_subbuf);
+                       order = get_count_order_u64(chan_opts.attr.num_subbuf);
                        assert(order >= 0);
                        rounded_size = 1ULL << order;
-                       if (rounded_size < chan.attr.num_subbuf) {
+                       if (rounded_size < chan_opts.attr.num_subbuf) {
                                ERR("The number of subbuffers (%" PRIu64 ") is rounded and overflows!",
-                                               chan.attr.num_subbuf);
+                                               chan_opts.attr.num_subbuf);
                                ret = CMD_ERROR;
                                goto end;
                        }
 
-                       if (rounded_size != chan.attr.num_subbuf) {
+                       if (rounded_size != chan_opts.attr.num_subbuf) {
                                WARN("The number of subbuffers (%" PRIu64 ") is rounded to the next power of 2 (%" PRIu64 ")",
-                                               chan.attr.num_subbuf, rounded_size);
-                               chan.attr.num_subbuf = rounded_size;
+                                               chan_opts.attr.num_subbuf, rounded_size);
+                               chan_opts.attr.num_subbuf = rounded_size;
                        }
 
                        /* Should now be power of 2 */
-                       assert(!((chan.attr.num_subbuf - 1) & chan.attr.num_subbuf));
+                       assert(!((chan_opts.attr.num_subbuf - 1) & chan_opts.attr.num_subbuf));
 
-                       DBG("Channel subbuf num set to %" PRIu64, chan.attr.num_subbuf);
+                       DBG("Channel subbuf num set to %" PRIu64, chan_opts.attr.num_subbuf);
                        break;
                }
                case OPT_SWITCH_TIMER:
@@ -437,8 +475,8 @@ int cmd_enable_channels(int argc, const char **argv)
                                ret = CMD_ERROR;
                                goto end;
                        }
-                       chan.attr.switch_timer_interval = (uint32_t) v;
-                       DBG("Channel switch timer interval set to %d", chan.attr.switch_timer_interval);
+                       chan_opts.attr.switch_timer_interval = (uint32_t) v;
+                       DBG("Channel switch timer interval set to %d", chan_opts.attr.switch_timer_interval);
                        break;
                }
                case OPT_READ_TIMER:
@@ -458,8 +496,30 @@ int cmd_enable_channels(int argc, const char **argv)
                                ret = CMD_ERROR;
                                goto end;
                        }
-                       chan.attr.read_timer_interval = (uint32_t) v;
-                       DBG("Channel read timer interval set to %d", chan.attr.read_timer_interval);
+                       chan_opts.attr.read_timer_interval = (uint32_t) v;
+                       DBG("Channel read timer interval set to %d", chan_opts.attr.read_timer_interval);
+                       break;
+               }
+               case OPT_MONITOR_TIMER:
+               {
+                       unsigned long 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);
+                               ret = CMD_ERROR;
+                               goto end;
+                       }
+                       if (v != (uint32_t) v) {
+                               ERR("32-bit overflow in --monitor-timer 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);
                        break;
                }
                case OPT_USERSPACE:
@@ -467,13 +527,13 @@ int cmd_enable_channels(int argc, const char **argv)
                        break;
                case OPT_TRACEFILE_SIZE:
                        opt_arg = poptGetOptArg(pc);
-                       if (utils_parse_size_suffix(opt_arg, &chan.attr.tracefile_size) < 0) {
+                       if (utils_parse_size_suffix(opt_arg, &chan_opts.attr.tracefile_size) < 0) {
                                ERR("Wrong value in --tracefile-size parameter: %s", opt_arg);
                                ret = CMD_ERROR;
                                goto end;
                        }
                        DBG("Maximum tracefile size set to %" PRIu64,
-                                       chan.attr.tracefile_size);
+                                       chan_opts.attr.tracefile_size);
                        break;
                case OPT_TRACEFILE_COUNT:
                {
@@ -492,9 +552,9 @@ int cmd_enable_channels(int argc, const char **argv)
                                ret = CMD_ERROR;
                                goto end;
                        }
-                       chan.attr.tracefile_count = (uint32_t) v;
+                       chan_opts.attr.tracefile_count = (uint32_t) v;
                        DBG("Maximum tracefile count set to %" PRIu64,
-                                       chan.attr.tracefile_count);
+                                       chan_opts.attr.tracefile_count);
                        break;
                }
                case OPT_LIST_OPTIONS:
index 9aa28b57ae600de10898df918325f4589a716a0a..c1f91d13546fe5264f4dad3bb89689ee257fd5cd 100644 (file)
@@ -1166,7 +1166,7 @@ error:
 static void print_channel(struct lttng_channel *channel)
 {
        int ret;
-       uint64_t discarded_events, lost_packets;
+       uint64_t discarded_events, lost_packets, monitor_timer_interval;
 
        ret = lttng_channel_get_discarded_event_count(channel,
                        &discarded_events);
@@ -1182,6 +1182,13 @@ static void print_channel(struct lttng_channel *channel)
                return;
        }
 
+       ret = lttng_channel_get_monitor_timer_interval(channel,
+                       &monitor_timer_interval);
+       if (ret) {
+               ERR("Failed to retrieve monitor interval of channel");
+               return;
+       }
+
        MSG("- %s:%s\n", channel->name, enabled_string(channel->enabled));
 
        MSG("%sAttributes:", indent4);
@@ -1190,6 +1197,7 @@ static void print_channel(struct lttng_channel *channel)
        MSG("%snumber of subbuffers: %" PRIu64, indent6, channel->attr.num_subbuf);
        MSG("%sswitch timer interval: %u", indent6, channel->attr.switch_timer_interval);
        MSG("%sread timer interval: %u", indent6, channel->attr.read_timer_interval);
+       MSG("%smonitor timer interval: %" PRIu64, indent6, monitor_timer_interval);
        MSG("%strace file count: %" PRIu64, indent6, channel->attr.tracefile_count);
        MSG("%strace file size (bytes): %" PRIu64, indent6, channel->attr.tracefile_size);
        MSG("%sdiscarded events: %" PRIu64, indent6, discarded_events);
index 66d9cca73d4405084c264f215ed4b5247d411ca5..2faa354a0d05136d939dc83ae24abcd818e64269 100644 (file)
@@ -41,6 +41,7 @@ extern const char * const config_element_subbuf_size;
 extern const char * const config_element_num_subbuf;
 extern const char * const config_element_switch_timer_interval;
 extern const char * const config_element_read_timer_interval;
+extern const char * const config_element_monitor_timer_interval;
 extern const char * const config_element_output;
 extern const char * const config_element_output_type;
 extern const char * const config_element_tracefile_size;
index b2d7a6b5b149f6f0adb5f6e775d10bb383b901ac..69b62d7523b6cd286df13f6bddb918bba5f726ce 100644 (file)
@@ -91,6 +91,7 @@ const char * const config_element_subbuf_size = "subbuffer_size";
 const char * const config_element_num_subbuf = "subbuffer_count";
 const char * const config_element_switch_timer_interval = "switch_timer_interval";
 const char * const config_element_read_timer_interval = "read_timer_interval";
+const char * const config_element_monitor_timer_interval = "monitor_timer_interval";
 const char * const config_element_output = "output";
 const char * const config_element_output_type = "output_type";
 const char * const config_element_tracefile_size = "tracefile_size";
index e94ce57a2b86a0b59e92a3f3bcbe8d9c59491475..cb2634cd7d8a8d09dd5d110f3c0aa235f03ca527 100644 (file)
@@ -25,6 +25,7 @@
 TESTPOINT_DECL(consumerd_thread_channel);
 TESTPOINT_DECL(consumerd_thread_metadata);
 TESTPOINT_DECL(consumerd_thread_data);
+TESTPOINT_DECL(consumerd_thread_data_poll);
 TESTPOINT_DECL(consumerd_thread_sessiond);
 TESTPOINT_DECL(consumerd_thread_metadata_timer);
 
index 3b857dec3779bc82ce7e587c75448f5b4ac4c07f..b2feb3945c8a40f3c1476e4dba7d9b659b8f9f8b 100644 (file)
@@ -67,6 +67,8 @@ struct consumer_channel_msg {
        uint64_t key;                           /* del */
 };
 
+int data_consumption_paused;
+
 /*
  * Flag to inform the polling thread to quit when all fd hung up. Updated by
  * the consumer_thread_receive_fds when it notices that all fds has hung up.
@@ -2530,6 +2532,9 @@ void *consumer_thread_data_poll(void *data)
                /* poll on the array of fds */
        restart:
                DBG("polling on %d fd", nb_fd + 2);
+               if (testpoint(consumerd_thread_data_poll)) {
+                       goto end;
+               }
                health_poll_entry();
                num_rdy = poll(pollfd, nb_fd + 2, -1);
                health_poll_exit();
index 527331298c0440ece041d2a73a5296352aa8304b..6a38e50e55a0a5a9b8c3d6eea784a718379b594d 100644 (file)
@@ -161,6 +161,7 @@ struct lttng_consumer_channel {
 
        /* Metadata cache is metadata channel */
        struct consumer_metadata_cache *metadata_cache;
+
        /* For UST metadata periodical flush */
        int switch_timer_enabled;
        timer_t switch_timer;
@@ -601,6 +602,9 @@ struct lttng_consumer_global_data {
        struct lttng_ht *stream_per_chan_id_ht;
 };
 
+/* Flag used to temporarily pause data consumption from testpoints. */
+extern int data_consumption_paused;
+
 /*
  * Init consumer data structures.
  */
index 396c286812d2c99d46da83ee7b64c68b3a3960f9..cb2362053f59eaf9d77cb2e91bc3a71384ffde7c 100644 (file)
@@ -20,7 +20,7 @@
 #define _LTT_KERNEL_IOCTL_H
 
 #define LTTNG_MODULES_ABI_MAJOR_VERSION                2
-#define LTTNG_MODULES_ABI_MINOR_VERSION                2
+#define LTTNG_MODULES_ABI_MINOR_VERSION                3
 
 /* Get a snapshot of the current ring buffer producer and consumer positions */
 #define RING_BUFFER_SNAPSHOT                _IO(0xF6, 0x00)
index 33d24ebf071731e0c6f91728994e06cdfe7f7070..56b65a364d7c8a0110f124a58ab9860e8b7491f9 100644 (file)
@@ -362,6 +362,7 @@ THE SOFTWARE.
                        <xs:element name="live_timer_interval" type="tns:uint32_type" default="0" minOccurs="0" /> <!-- usec -->
                        <xs:element name="discarded_events" type="tns:uint64_type" default="0" minOccurs="0" />
                        <xs:element name="lost_packets" type="tns:uint64_type" default="0" minOccurs="0" />
+                       <xs:element name="monitor_timer_interval" type="tns:uint64_type" default="0" minOccurs="0" />
                </xs:all>
        </xs:complexType>
 
index e87e767c56a2a686929a7f752418cff5369b63dd..197add2d470518bf0e18f4f2ecc16320d8a88265 100644 (file)
@@ -862,7 +862,7 @@ int mi_lttng_channel_attr(struct mi_writer *writer,
        int ret = 0;
        struct lttng_channel *chan = caa_container_of(attr,
                        struct lttng_channel, attr);
-       uint64_t discarded_events, lost_packets;
+       uint64_t discarded_events, lost_packets, monitor_timer_interval;
 
        assert(attr);
 
@@ -876,6 +876,12 @@ int mi_lttng_channel_attr(struct mi_writer *writer,
                goto end;
        }
 
+       ret = lttng_channel_get_monitor_timer_interval(chan,
+                       &monitor_timer_interval);
+       if (ret) {
+               goto end;
+       }
+
        /* Opening Attributes */
        ret = mi_lttng_writer_open_element(writer, config_element_attributes);
        if (ret) {
@@ -922,6 +928,14 @@ int mi_lttng_channel_attr(struct mi_writer *writer,
                goto end;
        }
 
+       /* Monitor timer interval in usec */
+       ret = mi_lttng_writer_write_element_unsigned_int(writer,
+               config_element_monitor_timer_interval,
+               monitor_timer_interval);
+       if (ret) {
+               goto end;
+       }
+
        /* Event output */
        ret = mi_lttng_writer_write_element_string(writer,
                config_element_output_type,
index 4e1665f401a333719b7220638e43a80c95cee4a6..0f9378c2c5d82507df87d2b83a46a5d5f192d733 100644 (file)
@@ -1320,26 +1320,111 @@ int lttng_disable_event(struct lttng_handle *handle, const char *name,
        return lttng_disable_event_ext(handle, &ev, channel_name, NULL);
 }
 
+struct lttng_channel *lttng_channel_create(struct lttng_domain *domain)
+{
+       struct lttng_channel *channel = NULL;
+       struct lttng_channel_extended *extended = NULL;
+
+       if (!domain) {
+               goto error;
+       }
+
+       /* Validate domain. */
+       switch (domain->type) {
+       case LTTNG_DOMAIN_UST:
+               switch (domain->buf_type) {
+               case LTTNG_BUFFER_PER_UID:
+               case LTTNG_BUFFER_PER_PID:
+                       break;
+               default:
+                       goto error;
+               }
+               break;
+       case LTTNG_DOMAIN_KERNEL:
+               if (domain->buf_type != LTTNG_BUFFER_GLOBAL) {
+                       goto error;
+               }
+               break;
+       default:
+               goto error;
+       }
+
+       channel = zmalloc(sizeof(*channel));
+       if (!channel) {
+               goto error;
+       }
+
+       extended = zmalloc(sizeof(*extended));
+       if (!extended) {
+               goto error;
+       }
+
+       channel->attr.extended.ptr = extended;
+
+       lttng_channel_set_default_attr(domain, &channel->attr);
+       return channel;
+error:
+       free(channel);
+       free(extended);
+       return NULL;
+}
+
+void lttng_channel_destroy(struct lttng_channel *channel)
+{
+       if (!channel) {
+               return;
+       }
+
+       if (channel->attr.extended.ptr) {
+               free(channel->attr.extended.ptr);
+       }
+       free(channel);
+}
+
 /*
  * Enable channel per domain
  * Returns size of returned session payload data or a negative error code.
  */
 int lttng_enable_channel(struct lttng_handle *handle,
-               struct lttng_channel *chan)
+               struct lttng_channel *in_chan)
 {
        struct lttcomm_session_msg lsm;
 
        /* NULL arguments are forbidden. No default values. */
-       if (handle == NULL || chan == NULL) {
+       if (handle == NULL || in_chan == NULL) {
                return -LTTNG_ERR_INVALID;
        }
 
        memset(&lsm, 0, sizeof(lsm));
+       memcpy(&lsm.u.channel.chan, in_chan, sizeof(lsm.u.channel.chan));
+       lsm.u.channel.chan.attr.extended.ptr = NULL;
 
-       memcpy(&lsm.u.channel.chan, chan, sizeof(lsm.u.channel.chan));
+       if (!in_chan->attr.extended.ptr) {
+               struct lttng_channel *channel;
+               struct lttng_channel_extended *extended;
 
-       lsm.cmd_type = LTTNG_ENABLE_CHANNEL;
+               channel = lttng_channel_create(&handle->domain);
+               if (!channel) {
+                       return -LTTNG_ERR_NOMEM;
+               }
+
+               /*
+                * Create a new channel in order to use default extended
+                * attribute values.
+                */
+               extended = (struct lttng_channel_extended *)
+                               channel->attr.extended.ptr;
+               memcpy(&lsm.u.channel.extended, extended, sizeof(*extended));
+               lttng_channel_destroy(channel);
+       } else {
+               struct lttng_channel_extended *extended;
+
+               extended = (struct lttng_channel_extended *)
+                               in_chan->attr.extended.ptr;
+               memcpy(&lsm.u.channel.extended, extended, sizeof(*extended));
+       }
 
+       lsm.cmd_type = LTTNG_ENABLE_CHANNEL;
        lttng_ctl_copy_lttng_domain(&lsm.domain, &handle->domain);
 
        lttng_ctl_copy_string(lsm.session.name, handle->session_name,
@@ -1705,7 +1790,7 @@ int lttng_list_channels(struct lttng_handle *handle,
        int ret;
        size_t channel_count, i;
        const size_t channel_size = sizeof(struct lttng_channel) +
-                       sizeof(struct lttcomm_channel_extended);
+                       sizeof(struct lttng_channel_extended);
        struct lttcomm_session_msg lsm;
        void *extended_at;
 
@@ -1741,7 +1826,7 @@ int lttng_list_channels(struct lttng_handle *handle,
                struct lttng_channel *chan = &(*channels)[i];
 
                chan->attr.extended.ptr = extended_at;
-               extended_at += sizeof(struct lttcomm_channel_extended);
+               extended_at += sizeof(struct lttng_channel_extended);
        }
 
        ret = (int) channel_count;
@@ -1946,6 +2031,9 @@ int lttng_calibrate(struct lttng_handle *handle,
 void lttng_channel_set_default_attr(struct lttng_domain *domain,
                struct lttng_channel_attr *attr)
 {
+       struct lttng_channel_extended *extended =
+                       (struct lttng_channel_extended *) attr->extended.ptr;
+
        /* Safety check */
        if (attr == NULL || domain == NULL) {
                return;
@@ -1966,6 +2054,10 @@ void lttng_channel_set_default_attr(struct lttng_domain *domain,
                attr->subbuf_size = default_get_kernel_channel_subbuf_size();
                attr->num_subbuf = DEFAULT_KERNEL_CHANNEL_SUBBUF_NUM;
                attr->output = DEFAULT_KERNEL_CHANNEL_OUTPUT;
+               if (extended) {
+                       extended->monitor_timer_interval =
+                                       DEFAULT_KERNEL_CHANNEL_MONITOR_TIMER;
+               }
                break;
        case LTTNG_DOMAIN_UST:
                switch (domain->buf_type) {
@@ -1977,6 +2069,10 @@ void lttng_channel_set_default_attr(struct lttng_domain *domain,
                                        DEFAULT_UST_UID_CHANNEL_SWITCH_TIMER;
                        attr->read_timer_interval =
                                        DEFAULT_UST_UID_CHANNEL_READ_TIMER;
+                       if (extended) {
+                               extended->monitor_timer_interval =
+                                               DEFAULT_UST_UID_CHANNEL_MONITOR_TIMER;
+                       }
                        break;
                case LTTNG_BUFFER_PER_PID:
                default:
@@ -1987,19 +2083,25 @@ void lttng_channel_set_default_attr(struct lttng_domain *domain,
                                        DEFAULT_UST_PID_CHANNEL_SWITCH_TIMER;
                        attr->read_timer_interval =
                                        DEFAULT_UST_PID_CHANNEL_READ_TIMER;
+                       if (extended) {
+                               extended->monitor_timer_interval =
+                                               DEFAULT_UST_PID_CHANNEL_MONITOR_TIMER;
+                       }
                        break;
                }
        default:
                /* Default behavior: leave set to 0. */
                break;
        }
+
+       attr->extended.ptr = extended;
 }
 
 int lttng_channel_get_discarded_event_count(struct lttng_channel *channel,
                uint64_t *discarded_events)
 {
        int ret = 0;
-       struct lttcomm_channel_extended *chan_ext;
+       struct lttng_channel_extended *chan_ext;
 
        if (!channel || !discarded_events) {
                ret = -LTTNG_ERR_INVALID;
@@ -2025,7 +2127,7 @@ int lttng_channel_get_lost_packet_count(struct lttng_channel *channel,
                uint64_t *lost_packets)
 {
        int ret = 0;
-       struct lttcomm_channel_extended *chan_ext;
+       struct lttng_channel_extended *chan_ext;
 
        if (!channel || !lost_packets) {
                ret = -LTTNG_ERR_INVALID;
@@ -2047,6 +2149,44 @@ end:
        return ret;
 }
 
+int lttng_channel_get_monitor_timer_interval(struct lttng_channel *chan,
+               uint64_t *monitor_timer_interval)
+{
+       int ret = 0;
+
+       if (!chan || !monitor_timer_interval) {
+               ret = -LTTNG_ERR_INVALID;
+               goto end;
+       }
+
+       if (!chan->attr.extended.ptr) {
+               ret = -LTTNG_ERR_INVALID;
+               goto end;
+       }
+
+       *monitor_timer_interval = ((struct lttng_channel_extended *)
+                       chan->attr.extended.ptr)->monitor_timer_interval;
+end:
+       return ret;
+}
+
+int lttng_channel_set_monitor_timer_interval(struct lttng_channel *chan,
+               uint64_t monitor_timer_interval)
+{
+       int ret = 0;
+
+       if (!chan || !chan->attr.extended.ptr) {
+               ret = -LTTNG_ERR_INVALID;
+               goto end;
+       }
+
+       ((struct lttng_channel_extended *)
+                       chan->attr.extended.ptr)->monitor_timer_interval =
+                       monitor_timer_interval;
+end:
+       return ret;
+}
+
 /*
  * Check if session daemon is alive.
  *
This page took 0.079356 seconds and 5 git commands to generate.