From ecc48a904cc7c419fd1400afaa9ccb93be490cdd Mon Sep 17 00:00:00 2001 From: Julien Desfossez Date: Sun, 28 Jul 2013 18:03:47 -0400 Subject: [PATCH] Live timer set up Add a new option to create to enable the live_timer being --live at session creation. A new API call is added also to create as session in live mode like the snapshot feature. This timer is responsible to check all streams of a live session and make sure the viewer receives periodic updates even for low-throughput channels. Signed-off-by: Julien Desfossez Signed-off-by: David Goulet --- include/lttng/lttng.h | 18 ++++++- src/bin/lttng-sessiond/channel.c | 5 ++ src/bin/lttng-sessiond/cmd.c | 24 +++++++++- src/bin/lttng-sessiond/cmd.h | 2 +- src/bin/lttng-sessiond/consumer.c | 6 ++- src/bin/lttng-sessiond/consumer.h | 4 +- src/bin/lttng-sessiond/kernel-consumer.c | 5 +- src/bin/lttng-sessiond/kernel.c | 4 +- src/bin/lttng-sessiond/main.c | 44 +++++++++++++++++- src/bin/lttng-sessiond/session.h | 4 ++ src/bin/lttng-sessiond/trace-ust.h | 1 + src/bin/lttng-sessiond/ust-app.c | 1 + src/bin/lttng-sessiond/ust-app.h | 1 + src/bin/lttng-sessiond/ust-consumer.c | 1 + src/bin/lttng/commands/create.c | 49 +++++++++++++++++++- src/common/consumer.c | 4 +- src/common/consumer.h | 6 ++- src/common/defaults.h | 4 ++ src/common/kernel-consumer/kernel-consumer.c | 3 +- src/common/sessiond-comm/sessiond-comm.h | 8 ++++ src/common/ust-consumer/ust-consumer.c | 8 ++-- src/lib/lttng-ctl/lttng-ctl.c | 45 ++++++++++++++++++ 22 files changed, 228 insertions(+), 19 deletions(-) diff --git a/include/lttng/lttng.h b/include/lttng/lttng.h index 4ffffd84f..b029d58e3 100644 --- a/include/lttng/lttng.h +++ b/include/lttng/lttng.h @@ -281,7 +281,7 @@ struct lttng_event_field { * * The structures should be initialized to zero before use. */ -#define LTTNG_CHANNEL_ATTR_PADDING1 LTTNG_SYMBOL_NAME_LEN + 16 +#define LTTNG_CHANNEL_ATTR_PADDING1 LTTNG_SYMBOL_NAME_LEN + 12 struct lttng_channel_attr { int overwrite; /* 1: overwrite, 0: discard */ uint64_t subbuf_size; /* bytes */ @@ -292,6 +292,8 @@ struct lttng_channel_attr { /* LTTng 2.1 padding limit */ uint64_t tracefile_size; /* bytes */ uint64_t tracefile_count; /* number of tracefiles */ + /* LTTng 2.3 padding limit */ + unsigned int live_timer_interval; /* usec */ char padding[LTTNG_CHANNEL_ATTR_PADDING1]; }; @@ -333,6 +335,7 @@ struct lttng_session { char path[PATH_MAX]; uint32_t enabled; /* enabled/started: 1, disabled/stopped: 0 */ uint32_t snapshot_mode; + unsigned int live_timer_interval; /* usec */ char padding[LTTNG_SESSION_PADDING1]; }; @@ -406,6 +409,19 @@ extern int lttng_create_session(const char *name, const char *url); extern int lttng_create_session_snapshot(const char *name, const char *snapshot_url); +/* + * Create a session exclusively used for live reading. + * + * In this mode, the switch-timer parameter is forced for each UST channel, a + * live-switch-timer is enabled for kernel channels, manually setting + * switch-timer is forbidden. Synchronization beacons are sent to the relayd, + * indexes are sent and metadata is checked for each packet. + * + * Returns LTTNG_OK on success or a negative error code. + */ +extern int lttng_create_session_live(const char *name, const char *url, + unsigned int timer_interval); + /* * Destroy a tracing session. * diff --git a/src/bin/lttng-sessiond/channel.c b/src/bin/lttng-sessiond/channel.c index 984576edc..817100ff4 100644 --- a/src/bin/lttng-sessiond/channel.c +++ b/src/bin/lttng-sessiond/channel.c @@ -65,6 +65,7 @@ struct lttng_channel *channel_new_default_attr(int dom, chan->attr.output = DEFAULT_KERNEL_CHANNEL_OUTPUT; chan->attr.switch_timer_interval = DEFAULT_KERNEL_CHANNEL_SWITCH_TIMER; chan->attr.read_timer_interval = DEFAULT_KERNEL_CHANNEL_READ_TIMER; + chan->attr.live_timer_interval = DEFAULT_KERNEL_CHANNEL_LIVE_TIMER; break; case LTTNG_DOMAIN_UST: switch (type) { @@ -76,6 +77,8 @@ struct lttng_channel *channel_new_default_attr(int dom, DEFAULT_UST_UID_CHANNEL_SWITCH_TIMER; chan->attr.read_timer_interval = DEFAULT_UST_UID_CHANNEL_READ_TIMER; + chan->attr.live_timer_interval = + DEFAULT_UST_UID_CHANNEL_LIVE_TIMER; break; case LTTNG_BUFFER_PER_PID: default: @@ -86,6 +89,8 @@ struct lttng_channel *channel_new_default_attr(int dom, DEFAULT_UST_PID_CHANNEL_SWITCH_TIMER; chan->attr.read_timer_interval = DEFAULT_UST_PID_CHANNEL_READ_TIMER; + chan->attr.live_timer_interval = + DEFAULT_UST_UID_CHANNEL_LIVE_TIMER; break; } break; diff --git a/src/bin/lttng-sessiond/cmd.c b/src/bin/lttng-sessiond/cmd.c index e5b2b7e3c..bed8f830d 100644 --- a/src/bin/lttng-sessiond/cmd.c +++ b/src/bin/lttng-sessiond/cmd.c @@ -850,6 +850,25 @@ int cmd_enable_channel(struct ltt_session *session, rcu_read_lock(); + /* + * Don't try to enable a channel if the session has been started at + * some point in time before. The tracer does not allow it. + */ + if (session->started) { + ret = LTTNG_ERR_TRACE_ALREADY_STARTED; + goto error; + } + + /* + * If the session is a live session, remove the switch timer, the + * live timer does the same thing but sends also synchronisation + * beacons for inactive streams. + */ + if (session->live_timer > 0) { + attr->attr.live_timer_interval = session->live_timer; + attr->attr.switch_timer_interval = 0; + } + switch (domain->type) { case LTTNG_DOMAIN_KERNEL: { @@ -1764,7 +1783,7 @@ error: * Command LTTNG_CREATE_SESSION processed by the client thread. */ int cmd_create_session_uri(char *name, struct lttng_uri *uris, - size_t nb_uri, lttng_sock_cred *creds) + size_t nb_uri, lttng_sock_cred *creds, unsigned int live_timer) { int ret; struct ltt_session *session; @@ -1802,6 +1821,7 @@ int cmd_create_session_uri(char *name, struct lttng_uri *uris, session = session_find_by_name(name); assert(session); + session->live_timer = live_timer; /* Create default consumer output for the session not yet created. */ session->consumer = consumer_create_output(CONSUMER_DST_LOCAL); if (session->consumer == NULL) { @@ -1848,7 +1868,7 @@ int cmd_create_session_snapshot(char *name, struct lttng_uri *uris, * Create session in no output mode with URIs set to NULL. The uris we've * received are for a default snapshot output if one. */ - ret = cmd_create_session_uri(name, NULL, 0, creds); + ret = cmd_create_session_uri(name, NULL, 0, creds, -1); if (ret != LTTNG_OK) { goto error; } diff --git a/src/bin/lttng-sessiond/cmd.h b/src/bin/lttng-sessiond/cmd.h index 830d8216a..6502a58a6 100644 --- a/src/bin/lttng-sessiond/cmd.h +++ b/src/bin/lttng-sessiond/cmd.h @@ -29,7 +29,7 @@ void cmd_init(void); /* Session commands */ int cmd_create_session_uri(char *name, struct lttng_uri *uris, - size_t nb_uri, lttng_sock_cred *creds); + size_t nb_uri, lttng_sock_cred *creds, unsigned int live_timer); int cmd_create_session_snapshot(char *name, struct lttng_uri *uris, size_t nb_uri, lttng_sock_cred *creds); int cmd_destroy_session(struct ltt_session *session, int wpipe); diff --git a/src/bin/lttng-sessiond/consumer.c b/src/bin/lttng-sessiond/consumer.c index 8f05476a7..befc5d6dc 100644 --- a/src/bin/lttng-sessiond/consumer.c +++ b/src/bin/lttng-sessiond/consumer.c @@ -781,6 +781,7 @@ void consumer_init_ask_channel_comm_msg(struct lttcomm_consumer_msg *msg, int overwrite, unsigned int switch_timer_interval, unsigned int read_timer_interval, + unsigned int live_timer_interval, int output, int type, uint64_t session_id, @@ -809,6 +810,7 @@ void consumer_init_ask_channel_comm_msg(struct lttcomm_consumer_msg *msg, msg->u.ask_channel.overwrite = overwrite; msg->u.ask_channel.switch_timer_interval = switch_timer_interval; msg->u.ask_channel.read_timer_interval = read_timer_interval; + msg->u.ask_channel.live_timer_interval = live_timer_interval; msg->u.ask_channel.output = output; msg->u.ask_channel.type = type; msg->u.ask_channel.session_id = session_id; @@ -852,7 +854,8 @@ void consumer_init_channel_comm_msg(struct lttcomm_consumer_msg *msg, int type, uint64_t tracefile_size, uint64_t tracefile_count, - unsigned int monitor) + unsigned int monitor, + unsigned int live_timer_interval) { assert(msg); @@ -872,6 +875,7 @@ void consumer_init_channel_comm_msg(struct lttcomm_consumer_msg *msg, msg->u.channel.tracefile_size = tracefile_size; msg->u.channel.tracefile_count = tracefile_count; msg->u.channel.monitor = monitor; + msg->u.channel.live_timer_interval = live_timer_interval; strncpy(msg->u.channel.pathname, pathname, sizeof(msg->u.channel.pathname)); diff --git a/src/bin/lttng-sessiond/consumer.h b/src/bin/lttng-sessiond/consumer.h index 27da4e38c..5b4372221 100644 --- a/src/bin/lttng-sessiond/consumer.h +++ b/src/bin/lttng-sessiond/consumer.h @@ -220,6 +220,7 @@ void consumer_init_ask_channel_comm_msg(struct lttcomm_consumer_msg *msg, int overwrite, unsigned int switch_timer_interval, unsigned int read_timer_interval, + unsigned int live_timer_interval, int output, int type, uint64_t session_id, @@ -255,7 +256,8 @@ void consumer_init_channel_comm_msg(struct lttcomm_consumer_msg *msg, int type, uint64_t tracefile_size, uint64_t tracefile_count, - unsigned int monitor); + unsigned int monitor, + unsigned int live_timer_interval); int consumer_is_data_pending(uint64_t session_id, struct consumer_output *consumer); int consumer_close_metadata(struct consumer_socket *socket, diff --git a/src/bin/lttng-sessiond/kernel-consumer.c b/src/bin/lttng-sessiond/kernel-consumer.c index 225e25856..de8fddb97 100644 --- a/src/bin/lttng-sessiond/kernel-consumer.c +++ b/src/bin/lttng-sessiond/kernel-consumer.c @@ -123,7 +123,8 @@ int kernel_consumer_add_channel(struct consumer_socket *sock, CONSUMER_CHANNEL_TYPE_DATA, channel->channel->attr.tracefile_size, channel->channel->attr.tracefile_count, - monitor); + monitor, + channel->channel->attr.live_timer_interval); health_code_update(); @@ -184,7 +185,7 @@ int kernel_consumer_add_metadata(struct consumer_socket *sock, DEFAULT_KERNEL_CHANNEL_OUTPUT, CONSUMER_CHANNEL_TYPE_METADATA, 0, 0, - monitor); + monitor, 0); health_code_update(); diff --git a/src/bin/lttng-sessiond/kernel.c b/src/bin/lttng-sessiond/kernel.c index 5eda07758..123be4be5 100644 --- a/src/bin/lttng-sessiond/kernel.c +++ b/src/bin/lttng-sessiond/kernel.c @@ -136,11 +136,11 @@ int kernel_create_channel(struct ltt_kernel_session *session, goto error; } - DBG3("Kernel create channel %s with attr: %d, %" PRIu64 ", %" PRIu64 ", %u, %u, %d", + DBG3("Kernel create channel %s with attr: %d, %" PRIu64 ", %" PRIu64 ", %u, %u, %d, %d", chan->name, lkc->channel->attr.overwrite, lkc->channel->attr.subbuf_size, lkc->channel->attr.num_subbuf, lkc->channel->attr.switch_timer_interval, lkc->channel->attr.read_timer_interval, - lkc->channel->attr.output); + lkc->channel->attr.live_timer_interval, lkc->channel->attr.output); /* Kernel tracer channel creation */ ret = kernctl_create_channel(session->fd, &lkc->channel->attr); diff --git a/src/bin/lttng-sessiond/main.c b/src/bin/lttng-sessiond/main.c index b665deaac..b3832e19c 100644 --- a/src/bin/lttng-sessiond/main.c +++ b/src/bin/lttng-sessiond/main.c @@ -2468,6 +2468,7 @@ static int create_ust_session(struct ltt_session *session, lus->gid = session->gid; lus->output_traces = session->output_traces; lus->snapshot_mode = session->snapshot_mode; + lus->live_timer_interval = session->live_timer; session->ust_session = lus; /* Copy session output to the newly created UST session */ @@ -2582,6 +2583,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx, int sock, switch (cmd_ctx->lsm->cmd_type) { case LTTNG_CREATE_SESSION: case LTTNG_CREATE_SESSION_SNAPSHOT: + case LTTNG_CREATE_SESSION_LIVE: case LTTNG_DESTROY_SESSION: case LTTNG_LIST_SESSIONS: case LTTNG_LIST_DOMAINS: @@ -2645,6 +2647,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx, int sock, switch (cmd_ctx->lsm->cmd_type) { case LTTNG_CREATE_SESSION: case LTTNG_CREATE_SESSION_SNAPSHOT: + case LTTNG_CREATE_SESSION_LIVE: case LTTNG_CALIBRATE: case LTTNG_LIST_SESSIONS: case LTTNG_LIST_TRACEPOINTS: @@ -3089,7 +3092,7 @@ skip_domain: } ret = cmd_create_session_uri(cmd_ctx->lsm->session.name, uris, nb_uri, - &cmd_ctx->creds); + &cmd_ctx->creds, 0); free(uris); @@ -3379,6 +3382,45 @@ skip_domain: free(uris); break; } + case LTTNG_CREATE_SESSION_LIVE: + { + size_t nb_uri, len; + struct lttng_uri *uris = NULL; + + nb_uri = cmd_ctx->lsm->u.uri.size; + len = nb_uri * sizeof(struct lttng_uri); + + if (nb_uri > 0) { + uris = zmalloc(len); + if (uris == NULL) { + ret = LTTNG_ERR_FATAL; + goto error; + } + + /* Receive variable len data */ + DBG("Waiting for %zu URIs from client ...", nb_uri); + ret = lttcomm_recv_unix_sock(sock, uris, len); + if (ret <= 0) { + DBG("No URIs received from client... continuing"); + *sock_error = 1; + ret = LTTNG_ERR_SESSION_FAIL; + free(uris); + goto error; + } + + if (nb_uri == 1 && uris[0].dtype != LTTNG_DST_PATH) { + DBG("Creating session with ONE network URI is a bad call"); + ret = LTTNG_ERR_SESSION_FAIL; + free(uris); + goto error; + } + } + + ret = cmd_create_session_uri(cmd_ctx->lsm->session.name, uris, + nb_uri, &cmd_ctx->creds, cmd_ctx->lsm->u.session_live.timer_interval); + free(uris); + break; + } default: ret = LTTNG_ERR_UND; break; diff --git a/src/bin/lttng-sessiond/session.h b/src/bin/lttng-sessiond/session.h index 0fd2fb16a..2bd2fd0ba 100644 --- a/src/bin/lttng-sessiond/session.h +++ b/src/bin/lttng-sessiond/session.h @@ -99,6 +99,10 @@ struct ltt_session { * snapshot purposes. */ unsigned int snapshot_mode; + /* + * Timer set when the session is created for live reading. + */ + int live_timer; }; /* Prototypes */ diff --git a/src/bin/lttng-sessiond/trace-ust.h b/src/bin/lttng-sessiond/trace-ust.h index 1c37b3f0f..aa6ac408f 100644 --- a/src/bin/lttng-sessiond/trace-ust.h +++ b/src/bin/lttng-sessiond/trace-ust.h @@ -111,6 +111,7 @@ struct ltt_ust_session { unsigned int output_traces; unsigned int snapshot_mode; unsigned int has_non_default_channel; + unsigned int live_timer_interval; /* usec */ }; /* diff --git a/src/bin/lttng-sessiond/ust-app.c b/src/bin/lttng-sessiond/ust-app.c index 7a3423068..916cd8828 100644 --- a/src/bin/lttng-sessiond/ust-app.c +++ b/src/bin/lttng-sessiond/ust-app.c @@ -1504,6 +1504,7 @@ static void shadow_copy_session(struct ust_app_session *ua_sess, /* There is only one consumer object per session possible. */ ua_sess->consumer = usess->consumer; ua_sess->output_traces = usess->output_traces; + ua_sess->live_timer_interval = usess->live_timer_interval; switch (ua_sess->buffer_type) { case LTTNG_BUFFER_PER_PID: diff --git a/src/bin/lttng-sessiond/ust-app.h b/src/bin/lttng-sessiond/ust-app.h index fd5e93fe9..edec8d496 100644 --- a/src/bin/lttng-sessiond/ust-app.h +++ b/src/bin/lttng-sessiond/ust-app.h @@ -207,6 +207,7 @@ struct ust_app_session { struct rcu_head rcu_head; /* If the channel's streams have to be outputed or not. */ unsigned int output_traces; + unsigned int live_timer_interval; /* usec */ }; /* diff --git a/src/bin/lttng-sessiond/ust-consumer.c b/src/bin/lttng-sessiond/ust-consumer.c index 78f29f497..308798eb1 100644 --- a/src/bin/lttng-sessiond/ust-consumer.c +++ b/src/bin/lttng-sessiond/ust-consumer.c @@ -147,6 +147,7 @@ static int ask_channel_creation(struct ust_app_session *ua_sess, ua_chan->attr.overwrite, ua_chan->attr.switch_timer_interval, ua_chan->attr.read_timer_interval, + ua_sess->live_timer_interval, (int) ua_chan->attr.output, (int) ua_chan->attr.type, ua_sess->tracing_id, diff --git a/src/bin/lttng/commands/create.c b/src/bin/lttng/commands/create.c index 23a969672..d234c06a4 100644 --- a/src/bin/lttng/commands/create.c +++ b/src/bin/lttng/commands/create.c @@ -17,6 +17,7 @@ #define _GNU_SOURCE #include +#include #include #include #include @@ -43,11 +44,13 @@ static char *opt_data_url; static int opt_no_consumer; static int opt_no_output; static int opt_snapshot; +static unsigned int opt_live_timer; static int opt_disable_consumer; enum { OPT_HELP = 1, OPT_LIST_OPTIONS, + OPT_LIVE_TIMER, }; static struct poptOption long_options[] = { @@ -62,6 +65,7 @@ static struct poptOption long_options[] = { {"no-consumer", 0, POPT_ARG_VAL, &opt_no_consumer, 1, 0, 0}, {"disable-consumer", 0, POPT_ARG_VAL, &opt_disable_consumer, 1, 0, 0}, {"snapshot", 0, POPT_ARG_VAL, &opt_snapshot, 1, 0, 0}, + {"live", 0, POPT_ARG_INT, 0, OPT_LIVE_TIMER, 0, 0}, {0, 0, 0, 0, 0, 0, 0} }; @@ -70,7 +74,7 @@ static struct poptOption long_options[] = { * why this declaration exists and used ONLY in for this command. */ extern int _lttng_create_session_ext(const char *name, const char *url, - const char *datetime); + const char *datetime, int live_timer); /* * usage @@ -91,6 +95,11 @@ static void usage(FILE *ofp) fprintf(ofp, " if one, as the default snapshot output.\n"); fprintf(ofp, " Every channel will be set in overwrite mode\n"); fprintf(ofp, " and with mmap output (splice not supported).\n"); + fprintf(ofp, " --live USEC Set the session in live-reading mode.\n"); + fprintf(ofp, " The delay parameter in micro-seconds is the\n"); + fprintf(ofp, " maximum time the user can wait for the data\n"); + fprintf(ofp, " to be flushed. Requires a network URL (-U or -C/-D)\n"); + fprintf(ofp, " and a lttng-relayd listening.\n"); fprintf(ofp, "\n"); fprintf(ofp, "Extended Options:\n"); fprintf(ofp, "\n"); @@ -334,6 +343,18 @@ static int create_session(void) goto error; } + if ((opt_live_timer && !opt_url) && (opt_live_timer && !opt_data_url)) { + ERR("You need a network URL (-U or -C/-D) to use live tracing."); + ret = CMD_ERROR; + goto error; + } + + if (opt_snapshot && opt_live_timer) { + ERR("Snapshot and live modes are mutually exclusive."); + ret = CMD_ERROR; + goto error; + } + if (opt_snapshot) { /* No output by default. */ const char *snapshot_url = NULL; @@ -345,8 +366,10 @@ static int create_session(void) snapshot_url = url; } ret = lttng_create_session_snapshot(session_name, snapshot_url); + } else if (opt_live_timer) { + ret = lttng_create_session_live(session_name, url, opt_live_timer); } else { - ret = _lttng_create_session_ext(session_name, url, datetime); + ret = _lttng_create_session_ext(session_name, url, datetime, -1); } if (ret < 0) { /* Don't set ret so lttng can interpret the sessiond error. */ @@ -414,6 +437,7 @@ error: int cmd_create(int argc, const char **argv) { int opt, ret = CMD_SUCCESS; + char *opt_arg = NULL; static poptContext pc; pc = poptGetContext(NULL, argc, argv, long_options, 0); @@ -427,6 +451,27 @@ int cmd_create(int argc, const char **argv) case OPT_LIST_OPTIONS: list_cmd_options(stdout, long_options); goto end; + case OPT_LIVE_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 --live parameter: %s", opt_arg); + ret = CMD_ERROR; + goto end; + } + if (v != (uint32_t) v) { + ERR("32-bit overflow in --live parameter: %s", opt_arg); + ret = CMD_ERROR; + goto end; + } + opt_live_timer = (uint32_t) v; + DBG("Session live timer interval set to %d", opt_live_timer); + break; + } default: usage(stderr); ret = CMD_UNDEFINED; diff --git a/src/common/consumer.c b/src/common/consumer.c index 2c2b79cf0..0661f1264 100644 --- a/src/common/consumer.c +++ b/src/common/consumer.c @@ -839,7 +839,8 @@ struct lttng_consumer_channel *consumer_allocate_channel(uint64_t key, uint64_t tracefile_size, uint64_t tracefile_count, uint64_t session_id_per_pid, - unsigned int monitor) + unsigned int monitor, + unsigned int live_timer_interval) { struct lttng_consumer_channel *channel; @@ -860,6 +861,7 @@ struct lttng_consumer_channel *consumer_allocate_channel(uint64_t key, channel->tracefile_size = tracefile_size; channel->tracefile_count = tracefile_count; channel->monitor = monitor; + channel->live_timer_interval = live_timer_interval; pthread_mutex_init(&channel->lock, NULL); pthread_mutex_init(&channel->timer_lock, NULL); diff --git a/src/common/consumer.h b/src/common/consumer.h index 4831ce898..6eb5b61bb 100644 --- a/src/common/consumer.h +++ b/src/common/consumer.h @@ -197,6 +197,9 @@ struct lttng_consumer_channel { * This is nested OUTSIDE consumer_relayd_sock_pair lock. */ pthread_mutex_t timer_lock; + + /* Timer value in usec for live streaming. */ + unsigned int live_timer_interval; }; /* @@ -564,7 +567,8 @@ struct lttng_consumer_channel *consumer_allocate_channel(uint64_t key, uint64_t tracefile_size, uint64_t tracefile_count, uint64_t session_id_per_pid, - unsigned int monitor); + unsigned int monitor, + unsigned int live_timer_interval); void consumer_del_stream(struct lttng_consumer_stream *stream, struct lttng_ht *ht); void consumer_del_metadata_stream(struct lttng_consumer_stream *stream, diff --git a/src/common/defaults.h b/src/common/defaults.h index d1e4adfcd..7a3d59c9f 100644 --- a/src/common/defaults.h +++ b/src/common/defaults.h @@ -125,6 +125,7 @@ /* Must always be a power of 2 */ #define _DEFAULT_CHANNEL_SUBBUF_NUM 4 #define _DEFAULT_CHANNEL_SWITCH_TIMER 0 /* usec */ +#define _DEFAULT_CHANNEL_LIVE_TIMER 0 /* usec */ #define _DEFAULT_CHANNEL_READ_TIMER 200000 /* usec */ #define _DEFAULT_CHANNEL_OUTPUT LTTNG_EVENT_MMAP @@ -149,6 +150,7 @@ #define DEFAULT_KERNEL_CHANNEL_OUTPUT LTTNG_EVENT_SPLICE #define DEFAULT_KERNEL_CHANNEL_SWITCH_TIMER _DEFAULT_CHANNEL_SWITCH_TIMER #define DEFAULT_KERNEL_CHANNEL_READ_TIMER _DEFAULT_CHANNEL_READ_TIMER +#define DEFAULT_KERNEL_CHANNEL_LIVE_TIMER _DEFAULT_CHANNEL_LIVE_TIMER /* User space defaults */ @@ -164,6 +166,8 @@ /* Timers in usec. */ #define DEFAULT_UST_PID_CHANNEL_SWITCH_TIMER _DEFAULT_CHANNEL_SWITCH_TIMER #define DEFAULT_UST_UID_CHANNEL_SWITCH_TIMER _DEFAULT_CHANNEL_SWITCH_TIMER +#define DEFAULT_UST_PID_CHANNEL_LIVE_TIMER _DEFAULT_CHANNEL_LIVE_TIMER +#define DEFAULT_UST_UID_CHANNEL_LIVE_TIMER _DEFAULT_CHANNEL_LIVE_TIMER #define DEFAULT_UST_PID_CHANNEL_READ_TIMER 0 /* usec */ #define DEFAULT_UST_UID_CHANNEL_READ_TIMER 0 /* usec */ diff --git a/src/common/kernel-consumer/kernel-consumer.c b/src/common/kernel-consumer/kernel-consumer.c index 09ccda329..eaccce3d0 100644 --- a/src/common/kernel-consumer/kernel-consumer.c +++ b/src/common/kernel-consumer/kernel-consumer.c @@ -462,7 +462,8 @@ int lttng_kconsumer_recv_cmd(struct lttng_consumer_local_data *ctx, msg.u.channel.relayd_id, msg.u.channel.output, msg.u.channel.tracefile_size, msg.u.channel.tracefile_count, 0, - msg.u.channel.monitor); + msg.u.channel.monitor, + msg.u.channel.live_timer_interval); if (new_channel == NULL) { lttng_consumer_send_error(ctx, LTTCOMM_CONSUMERD_OUTFD_ERROR); goto end_nosignal; diff --git a/src/common/sessiond-comm/sessiond-comm.h b/src/common/sessiond-comm/sessiond-comm.h index b98e4f747..cf6262e6a 100644 --- a/src/common/sessiond-comm/sessiond-comm.h +++ b/src/common/sessiond-comm/sessiond-comm.h @@ -88,6 +88,7 @@ enum lttcomm_sessiond_command { LTTNG_SNAPSHOT_LIST_OUTPUT = 27, LTTNG_SNAPSHOT_RECORD = 28, LTTNG_CREATE_SESSION_SNAPSHOT = 29, + LTTNG_CREATE_SESSION_LIVE = 30, }; enum lttcomm_relayd_command { @@ -255,6 +256,10 @@ struct lttcomm_session_msg { uint32_t wait; struct lttng_snapshot_output output; } LTTNG_PACKED snapshot_record; + struct { + uint32_t nb_uri; + unsigned int timer_interval; /* usec */ + } LTTNG_PACKED session_live; } u; } LTTNG_PACKED; @@ -324,6 +329,8 @@ struct lttcomm_consumer_msg { uint32_t tracefile_count; /* number of tracefiles */ /* If the channel's streams have to be monitored or not. */ uint32_t monitor; + /* timer to check the streams usage in live mode (usec). */ + unsigned int live_timer_interval; } LTTNG_PACKED channel; /* Only used by Kernel. */ struct { uint64_t stream_key; @@ -352,6 +359,7 @@ struct lttcomm_consumer_msg { int32_t overwrite; /* 1: overwrite, 0: discard */ uint32_t switch_timer_interval; /* usec */ uint32_t read_timer_interval; /* usec */ + unsigned int live_timer_interval; /* usec */ int32_t output; /* splice, mmap */ int32_t type; /* metadata or per_cpu */ uint64_t session_id; /* Tracing session id */ diff --git a/src/common/ust-consumer/ust-consumer.c b/src/common/ust-consumer/ust-consumer.c index c794b93f8..f0147af4e 100644 --- a/src/common/ust-consumer/ust-consumer.c +++ b/src/common/ust-consumer/ust-consumer.c @@ -117,14 +117,15 @@ static struct lttng_consumer_channel *allocate_channel(uint64_t session_id, const char *pathname, const char *name, uid_t uid, gid_t gid, uint64_t relayd_id, uint64_t key, enum lttng_event_output output, uint64_t tracefile_size, uint64_t tracefile_count, - uint64_t session_id_per_pid, unsigned int monitor) + uint64_t session_id_per_pid, unsigned int monitor, + unsigned int live_timer_interval) { assert(pathname); assert(name); return consumer_allocate_channel(key, session_id, pathname, name, uid, gid, relayd_id, output, tracefile_size, - tracefile_count, session_id_per_pid, monitor); + tracefile_count, session_id_per_pid, monitor, live_timer_interval); } /* @@ -1194,7 +1195,8 @@ int lttng_ustconsumer_recv_cmd(struct lttng_consumer_local_data *ctx, msg.u.ask_channel.tracefile_size, msg.u.ask_channel.tracefile_count, msg.u.ask_channel.session_id_per_pid, - msg.u.ask_channel.monitor); + msg.u.ask_channel.monitor, + msg.u.ask_channel.live_timer_interval); if (!channel) { goto end_channel_error; } diff --git a/src/lib/lttng-ctl/lttng-ctl.c b/src/lib/lttng-ctl/lttng-ctl.c index daa4a7391..bff522201 100644 --- a/src/lib/lttng-ctl/lttng-ctl.c +++ b/src/lib/lttng-ctl/lttng-ctl.c @@ -1596,6 +1596,51 @@ int lttng_create_session_snapshot(const char *name, const char *snapshot_url) return ret; } +/* + * Create a session exclusively used for live. + * + * Returns LTTNG_OK on success or a negative error code. + */ +int lttng_create_session_live(const char *name, const char *url, + unsigned int timer_interval) +{ + int ret; + ssize_t size; + struct lttcomm_session_msg lsm; + struct lttng_uri *uris = NULL; + + if (name == NULL) { + return -LTTNG_ERR_INVALID; + } + + memset(&lsm, 0, sizeof(lsm)); + + lsm.cmd_type = LTTNG_CREATE_SESSION_LIVE; + lttng_ctl_copy_string(lsm.session.name, name, sizeof(lsm.session.name)); + + size = uri_parse_str_urls(url, NULL, &uris); + if (size < 0) { + ret = -LTTNG_ERR_INVALID; + goto end; + } + + /* file:// is not accepted for live session. */ + if (uris[0].dtype == LTTNG_DST_PATH) { + ret = -LTTNG_ERR_INVALID; + goto end; + } + + lsm.u.session_live.nb_uri = size; + lsm.u.session_live.timer_interval = timer_interval; + + ret = lttng_ctl_ask_sessiond_varlen(&lsm, uris, + sizeof(struct lttng_uri) * size, NULL); + +end: + free(uris); + return ret; +} + /* * lib constructor */ -- 2.34.1