From 1624d5b7ba86633d36f3a5c86ea1df5d308c4360 Mon Sep 17 00:00:00 2001 From: Julien Desfossez Date: Wed, 27 Mar 2013 13:27:55 -0400 Subject: [PATCH] On-disk multiple tracefiles circular buffer This patch introduces the tracefile_size and tracefile_count parameters to the enable-channel command and the API. This allows to split a stream into multiple tracefiles and limit the amount of trace data to keep on disk. The tracefiles are readable independently or with the others as long as the metadata file is present. For now only local traces are handled, relayd modifications coming soon. Signed-off-by: Julien Desfossez Signed-off-by: David Goulet --- doc/man/lttng.1 | 23 ++++ include/lttng/lttng.h | 5 +- src/bin/lttng-sessiond/channel.c | 10 ++ src/bin/lttng-sessiond/consumer.c | 12 +- src/bin/lttng-sessiond/consumer.h | 8 +- src/bin/lttng-sessiond/kernel-consumer.c | 9 +- src/bin/lttng-sessiond/kernel.c | 3 + src/bin/lttng-sessiond/trace-kernel.h | 2 + src/bin/lttng-sessiond/trace-ust.c | 4 + src/bin/lttng-sessiond/trace-ust.h | 2 + src/bin/lttng-sessiond/ust-app.c | 3 + src/bin/lttng-sessiond/ust-app.h | 2 + src/bin/lttng-sessiond/ust-consumer.c | 4 +- src/bin/lttng/commands/enable_channels.c | 34 +++++ src/common/consumer.c | 123 ++++++++++++++++++- src/common/consumer.h | 11 +- src/common/defaults.h | 8 ++ src/common/kernel-consumer/kernel-consumer.c | 21 +--- src/common/sessiond-comm/sessiond-comm.h | 4 + src/common/ust-consumer/ust-consumer.c | 39 ++---- src/lib/lttng-ctl/lttng-ctl.c | 4 + 21 files changed, 272 insertions(+), 59 deletions(-) diff --git a/doc/man/lttng.1 b/doc/man/lttng.1 index a8e02fafa..38a99ce63 100644 --- a/doc/man/lttng.1 +++ b/doc/man/lttng.1 @@ -345,6 +345,29 @@ same type. Use per PID buffer (\-u only). Each application has its own buffers. \-\-buffers-global Use shared buffer for the whole system (\-k only) +\-C, \-\-tracefile-size SIZE + Maximum size of of each tracefile within a stream (in bytes). +\-W, \-\-tracefile-count COUNT + Used in conjunction with \-C option, this will limit the number + of files created to the specified count. + +.B EXAMPLES: + +$ lttng enable-channel -C 4096 -W 32 chan1 +For each stream, the maximum size of a trace file will be 4096 bytes divided +over a \fBmaximum\fP of 32 different files. The file count is appended after +the stream number as seen in the following example. The last trace file is +smaller than 4096 since it was not completely filled. + + ~/lttng-traces/[...]/chan1_0_0 (4096) + ~/lttng-traces/[...]/chan1_0_1 (4096) + ~/lttng-traces/[...]/chan1_0_2 (3245) + ~/lttng-traces/[...]/chan1_1_0 (4096) + ... + +$ lttng enable-channel -C 4096 +This will create trace files of 4096 bytes and will create new ones as long as +there is data available. .fi .IP diff --git a/include/lttng/lttng.h b/include/lttng/lttng.h index 8566deabe..ee348df85 100644 --- a/include/lttng/lttng.h +++ b/include/lttng/lttng.h @@ -277,7 +277,7 @@ struct lttng_event_field { * * The structures should be initialized to zero before use. */ -#define LTTNG_CHANNEL_ATTR_PADDING1 LTTNG_SYMBOL_NAME_LEN + 32 +#define LTTNG_CHANNEL_ATTR_PADDING1 LTTNG_SYMBOL_NAME_LEN + 16 struct lttng_channel_attr { int overwrite; /* 1: overwrite, 0: discard */ uint64_t subbuf_size; /* bytes */ @@ -285,6 +285,9 @@ struct lttng_channel_attr { unsigned int switch_timer_interval; /* usec */ unsigned int read_timer_interval; /* usec */ enum lttng_event_output output; /* splice, mmap */ + /* LTTng 2.1 padding limit */ + uint64_t tracefile_size; /* bytes */ + uint64_t tracefile_count; /* number of tracefiles */ char padding[LTTNG_CHANNEL_ATTR_PADDING1]; }; diff --git a/src/bin/lttng-sessiond/channel.c b/src/bin/lttng-sessiond/channel.c index 6c7422b29..1621bc626 100644 --- a/src/bin/lttng-sessiond/channel.c +++ b/src/bin/lttng-sessiond/channel.c @@ -272,6 +272,16 @@ int channel_ust_create(struct ltt_ust_session *usess, goto error; } + /* + * The tracefile_size should not be < to the subbuf_size, otherwise + * we won't be able to write the packets on disk + */ + if ((attr->attr.tracefile_size > 0) && + (attr->attr.tracefile_size < attr->attr.subbuf_size)) { + ret = LTTNG_ERR_INVALID; + goto error; + } + /* Create UST channel */ uchan = trace_ust_create_channel(attr, usess->pathname); if (uchan == NULL) { diff --git a/src/bin/lttng-sessiond/consumer.c b/src/bin/lttng-sessiond/consumer.c index f0fb2dc00..f803f7b05 100644 --- a/src/bin/lttng-sessiond/consumer.c +++ b/src/bin/lttng-sessiond/consumer.c @@ -663,7 +663,9 @@ void consumer_init_ask_channel_comm_msg(struct lttcomm_consumer_msg *msg, uint64_t relayd_id, uint64_t key, unsigned char *uuid, - uint32_t chan_id) + uint32_t chan_id, + uint64_t tracefile_size, + uint64_t tracefile_count) { assert(msg); @@ -684,6 +686,8 @@ void consumer_init_ask_channel_comm_msg(struct lttcomm_consumer_msg *msg, msg->u.ask_channel.relayd_id = relayd_id; msg->u.ask_channel.key = key; msg->u.ask_channel.chan_id = chan_id; + msg->u.ask_channel.tracefile_size = tracefile_size; + msg->u.ask_channel.tracefile_count = tracefile_count; memcpy(msg->u.ask_channel.uuid, uuid, sizeof(msg->u.ask_channel.uuid)); @@ -709,7 +713,9 @@ void consumer_init_channel_comm_msg(struct lttcomm_consumer_msg *msg, const char *name, unsigned int nb_init_streams, enum lttng_event_output output, - int type) + int type, + uint64_t tracefile_size, + uint64_t tracefile_count) { assert(msg); @@ -726,6 +732,8 @@ void consumer_init_channel_comm_msg(struct lttcomm_consumer_msg *msg, msg->u.channel.nb_init_streams = nb_init_streams; msg->u.channel.output = output; msg->u.channel.type = type; + msg->u.channel.tracefile_size = tracefile_size; + msg->u.channel.tracefile_count = tracefile_count; 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 b767589d9..798eaa265 100644 --- a/src/bin/lttng-sessiond/consumer.h +++ b/src/bin/lttng-sessiond/consumer.h @@ -200,7 +200,9 @@ void consumer_init_ask_channel_comm_msg(struct lttcomm_consumer_msg *msg, uint64_t relayd_id, uint64_t key, unsigned char *uuid, - uint32_t chan_id); + uint32_t chan_id, + uint64_t tracefile_size, + uint64_t tracefile_count); void consumer_init_stream_comm_msg(struct lttcomm_consumer_msg *msg, enum lttng_consumer_command cmd, uint64_t channel_key, @@ -217,7 +219,9 @@ void consumer_init_channel_comm_msg(struct lttcomm_consumer_msg *msg, const char *name, unsigned int nb_init_streams, enum lttng_event_output output, - int type); + int type, + uint64_t tracefile_size, + uint64_t tracefile_count); 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 3368da6c1..05e30e49c 100644 --- a/src/bin/lttng-sessiond/kernel-consumer.c +++ b/src/bin/lttng-sessiond/kernel-consumer.c @@ -94,7 +94,9 @@ int kernel_consumer_add_channel(struct consumer_socket *sock, channel->channel->name, channel->stream_count, channel->channel->attr.output, - CONSUMER_CHANNEL_TYPE_DATA); + CONSUMER_CHANNEL_TYPE_DATA, + channel->channel->attr.tracefile_size, + channel->channel->attr.tracefile_count); health_code_update(); @@ -174,7 +176,8 @@ int kernel_consumer_add_metadata(struct consumer_socket *sock, DEFAULT_METADATA_NAME, 1, DEFAULT_KERNEL_CHANNEL_OUTPUT, - CONSUMER_CHANNEL_TYPE_METADATA); + CONSUMER_CHANNEL_TYPE_METADATA, + 0, 0); health_code_update(); @@ -190,7 +193,7 @@ int kernel_consumer_add_metadata(struct consumer_socket *sock, LTTNG_CONSUMER_ADD_STREAM, session->metadata->fd, session->metadata_stream_fd, - 0); /* CPU: 0 for metadata. */ + 0); /* CPU: 0 for metadata. */ health_code_update(); diff --git a/src/bin/lttng-sessiond/kernel.c b/src/bin/lttng-sessiond/kernel.c index d3a645375..951941132 100644 --- a/src/bin/lttng-sessiond/kernel.c +++ b/src/bin/lttng-sessiond/kernel.c @@ -536,6 +536,9 @@ int kernel_open_channel_stream(struct ltt_kernel_channel *channel) PERROR("fcntl session fd"); } + lks->tracefile_size = channel->channel->attr.tracefile_size; + lks->tracefile_count = channel->channel->attr.tracefile_count; + /* Add stream to channe stream list */ cds_list_add(&lks->list, &channel->stream_list.head); channel->stream_count++; diff --git a/src/bin/lttng-sessiond/trace-kernel.h b/src/bin/lttng-sessiond/trace-kernel.h index 66ca8dbde..87807d989 100644 --- a/src/bin/lttng-sessiond/trace-kernel.h +++ b/src/bin/lttng-sessiond/trace-kernel.h @@ -82,6 +82,8 @@ struct ltt_kernel_stream { int cpu; /* Format is %s_%d respectively channel name and CPU number. */ char name[DEFAULT_STREAM_NAME_LEN]; + uint64_t tracefile_size; + uint64_t tracefile_count; struct cds_list_head list; }; diff --git a/src/bin/lttng-sessiond/trace-ust.c b/src/bin/lttng-sessiond/trace-ust.c index 8f15a1576..cd8ff1053 100644 --- a/src/bin/lttng-sessiond/trace-ust.c +++ b/src/bin/lttng-sessiond/trace-ust.c @@ -293,6 +293,10 @@ struct ltt_ust_channel *trace_ust_create_channel(struct lttng_channel *chan, luc->events = lttng_ht_new(0, LTTNG_HT_TYPE_STRING); luc->ctx = lttng_ht_new(0, LTTNG_HT_TYPE_ULONG); + /* On-disk circular buffer parameters */ + luc->tracefile_size = chan->attr.tracefile_size; + luc->tracefile_count = chan->attr.tracefile_count; + DBG2("Trace UST channel %s created", luc->name); error: diff --git a/src/bin/lttng-sessiond/trace-ust.h b/src/bin/lttng-sessiond/trace-ust.h index 87fe412d6..92d6aaaf4 100644 --- a/src/bin/lttng-sessiond/trace-ust.h +++ b/src/bin/lttng-sessiond/trace-ust.h @@ -59,6 +59,8 @@ struct ltt_ust_channel { struct lttng_ht *ctx; struct lttng_ht *events; struct lttng_ht_node_str node; + uint64_t tracefile_size; + uint64_t tracefile_count; }; /* UST Metadata */ diff --git a/src/bin/lttng-sessiond/ust-app.c b/src/bin/lttng-sessiond/ust-app.c index fdcad1c30..4c9d227af 100644 --- a/src/bin/lttng-sessiond/ust-app.c +++ b/src/bin/lttng-sessiond/ust-app.c @@ -1298,6 +1298,9 @@ static void shadow_copy_channel(struct ust_app_channel *ua_chan, strncpy(ua_chan->name, uchan->name, sizeof(ua_chan->name)); ua_chan->name[sizeof(ua_chan->name) - 1] = '\0'; + ua_chan->tracefile_size = uchan->tracefile_size; + ua_chan->tracefile_count = uchan->tracefile_count; + /* Copy event attributes since the layout is different. */ ua_chan->attr.subbuf_size = uchan->attr.subbuf_size; ua_chan->attr.num_subbuf = uchan->attr.num_subbuf; diff --git a/src/bin/lttng-sessiond/ust-app.h b/src/bin/lttng-sessiond/ust-app.h index 82694a722..e0aa17a7f 100644 --- a/src/bin/lttng-sessiond/ust-app.h +++ b/src/bin/lttng-sessiond/ust-app.h @@ -143,6 +143,8 @@ struct ust_app_channel { struct ust_app_session *session; struct lttng_ht *ctx; struct lttng_ht *events; + uint64_t tracefile_size; + uint64_t tracefile_count; /* * Node indexed by channel name in the channels' hash table of a session. */ diff --git a/src/bin/lttng-sessiond/ust-consumer.c b/src/bin/lttng-sessiond/ust-consumer.c index 7f01de9ea..93c1f7135 100644 --- a/src/bin/lttng-sessiond/ust-consumer.c +++ b/src/bin/lttng-sessiond/ust-consumer.c @@ -155,7 +155,9 @@ static int ask_channel_creation(struct ust_app_session *ua_sess, consumer->net_seq_index, ua_chan->key, registry->uuid, - chan_id); + chan_id, + ua_chan->tracefile_size, + ua_chan->tracefile_count); health_code_update(); diff --git a/src/bin/lttng/commands/enable_channels.c b/src/bin/lttng/commands/enable_channels.c index 02a31800a..d026af433 100644 --- a/src/bin/lttng/commands/enable_channels.c +++ b/src/bin/lttng/commands/enable_channels.c @@ -49,6 +49,8 @@ enum { OPT_READ_TIMER, OPT_USERSPACE, OPT_LIST_OPTIONS, + OPT_TRACEFILE_SIZE, + OPT_TRACEFILE_COUNT, }; static struct lttng_handle *handle; @@ -73,6 +75,8 @@ static struct poptOption long_options[] = { {"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}, {0, 0, 0, 0, 0, 0, 0} }; @@ -115,6 +119,11 @@ static void usage(FILE *ofp) fprintf(ofp, " --buffers-uid Use per UID buffer (-u only)\n"); fprintf(ofp, " --buffers-pid Use per PID buffer (-u only)\n"); fprintf(ofp, " --buffers-global Use shared buffer for the whole system (-k only)\n"); + fprintf(ofp, " -C, --tracefile-size SIZE\n"); + fprintf(ofp, " Maximum size of of each tracefile within a stream (in bytes).\n"); + fprintf(ofp, " -W, --tracefile-count COUNT\n"); + fprintf(ofp, " Used in conjunction with -C option, this will limit the number\n"); + fprintf(ofp, " of files created to the specified count.\n"); fprintf(ofp, "\n"); } @@ -147,6 +156,12 @@ static void set_default_attr(struct lttng_domain *dom) if (chan.attr.output == -1) { chan.attr.output = default_attr.output; } + if (chan.attr.tracefile_count == -1) { + chan.attr.tracefile_count = default_attr.tracefile_count; + } + if (chan.attr.tracefile_size == -1) { + chan.attr.tracefile_size = default_attr.tracefile_size; + } } /* @@ -179,6 +194,15 @@ static int enable_channel(char *session_name) set_default_attr(&dom); + if ((chan.attr.tracefile_size > 0) && + (chan.attr.tracefile_size < chan.attr.subbuf_size)) { + ERR("Tracefile_size must be greater than or equal to subbuf_size " + "(%" PRIu64 " < %" PRIu64 ")", + chan.attr.tracefile_size, chan.attr.subbuf_size); + ret = CMD_ERROR; + goto error; + } + /* Setting channel output */ if (opt_output) { if (!strncmp(output_mmap, opt_output, strlen(output_mmap))) { @@ -307,6 +331,16 @@ int cmd_enable_channels(int argc, const char **argv) case OPT_USERSPACE: opt_userspace = 1; break; + case OPT_TRACEFILE_SIZE: + chan.attr.tracefile_size = atoll(poptGetOptArg(pc)); + DBG("Maximum tracefile size set to %" PRIu64, + chan.attr.tracefile_size); + break; + case OPT_TRACEFILE_COUNT: + chan.attr.tracefile_count = atoll(poptGetOptArg(pc)); + DBG("Maximum tracefile count set to %" PRIu64, + chan.attr.tracefile_count); + break; case OPT_LIST_OPTIONS: list_cmd_options(stdout, long_options); goto end; diff --git a/src/common/consumer.c b/src/common/consumer.c index 5f87f4b50..b6e440a48 100644 --- a/src/common/consumer.c +++ b/src/common/consumer.c @@ -828,7 +828,9 @@ struct lttng_consumer_channel *consumer_allocate_channel(uint64_t key, uid_t uid, gid_t gid, int relayd_id, - enum lttng_event_output output) + enum lttng_event_output output, + uint64_t tracefile_size, + uint64_t tracefile_count) { struct lttng_consumer_channel *channel; @@ -845,6 +847,8 @@ struct lttng_consumer_channel *consumer_allocate_channel(uint64_t key, channel->gid = gid; channel->relayd_id = relayd_id; channel->output = output; + channel->tracefile_size = tracefile_size; + channel->tracefile_count = tracefile_count; strncpy(channel->pathname, pathname, sizeof(channel->pathname)); channel->pathname[sizeof(channel->pathname) - 1] = '\0'; @@ -1283,6 +1287,93 @@ end: return ret; } +/* + * Create the tracefile on disk. + * + * Return 0 on success or else a negative value. + */ +int lttng_create_output_file(struct lttng_consumer_stream *stream) +{ + int ret; + char full_path[PATH_MAX]; + char *path_name_id = NULL; + char *path; + + assert(stream); + assert(stream->net_seq_idx == (uint64_t) -1ULL); + + ret = snprintf(full_path, sizeof(full_path), "%s/%s", + stream->chan->pathname, stream->name); + if (ret < 0) { + PERROR("snprintf create output file"); + goto error; + } + + /* + * If we split the trace in multiple files, we have to add the tracefile + * current count at the end of the tracefile name + */ + if (stream->chan->tracefile_size > 0) { + ret = asprintf(&path_name_id, "%s_%" PRIu64, full_path, + stream->tracefile_count_current); + if (ret < 0) { + PERROR("Allocating path name ID"); + goto error; + } + path = path_name_id; + } else { + path = full_path; + } + + ret = run_as_open(path, O_WRONLY | O_CREAT | O_TRUNC, + S_IRWXU | S_IRWXG | S_IRWXO, stream->uid, stream->gid); + if (ret < 0) { + PERROR("open stream path %s", path); + goto error_open; + } + stream->out_fd = ret; + stream->tracefile_size_current = 0; + +error_open: + free(path_name_id); +error: + return ret; +} + +/* + * Change the output tracefile according to the tracefile_size and + * tracefile_count parameters. The stream lock MUST be held before calling this + * function because we are modifying the stream status. + * + * Return 0 on success or else a negative value. + */ +static int rotate_output_file(struct lttng_consumer_stream *stream) +{ + int ret; + + assert(stream); + assert(stream->tracefile_size_current); + + ret = close(stream->out_fd); + if (ret < 0) { + PERROR("Closing tracefile"); + goto end; + } + + if (stream->chan->tracefile_count > 0) { + stream->tracefile_count_current = + (stream->tracefile_count_current + 1) % + stream->chan->tracefile_count; + } else { + stream->tracefile_count_current++; + } + + return lttng_create_output_file(stream); + +end: + return ret; +} + /* * Mmap the ring buffer, read it and write the data to the tracefile. This is a * core function for writing trace buffers to either the local filesystem or @@ -1390,6 +1481,21 @@ ssize_t lttng_consumer_on_read_subbuffer_mmap( } else { /* No streaming, we have to set the len with the full padding */ len += padding; + + /* + * Check if we need to change the tracefile before writing the packet. + */ + if (stream->chan->tracefile_size > 0 && + (stream->tracefile_size_current + len) > + stream->chan->tracefile_size) { + ret = rotate_output_file(stream); + if (ret < 0) { + ERR("Rotating output file"); + goto end; + } + outfd = stream->out_fd; + } + stream->tracefile_size_current += len; } while (len > 0) { @@ -1552,6 +1658,21 @@ ssize_t lttng_consumer_on_read_subbuffer_splice( } else { /* No streaming, we have to set the len with the full padding */ len += padding; + + /* + * Check if we need to change the tracefile before writing the packet. + */ + if (stream->chan->tracefile_size > 0 && + (stream->tracefile_size_current + len) > + stream->chan->tracefile_size) { + ret = rotate_output_file(stream); + if (ret < 0) { + ERR("Rotating output file"); + goto end; + } + outfd = stream->out_fd; + } + stream->tracefile_size_current += len; } while (len > 0) { diff --git a/src/common/consumer.h b/src/common/consumer.h index 46387522e..6fd4e2e5c 100644 --- a/src/common/consumer.h +++ b/src/common/consumer.h @@ -146,6 +146,9 @@ struct lttng_consumer_channel { /* For metadata periodical flush */ int switch_timer_enabled; timer_t switch_timer; + /* On-disk circular buffer */ + uint64_t tracefile_size; + uint64_t tracefile_count; }; /* @@ -233,6 +236,9 @@ struct lttng_consumer_stream { /* Internal state of libustctl. */ struct ustctl_consumer_stream *ustream; struct cds_list_head send_node; + /* On-disk circular buffer */ + uint64_t tracefile_size_current; + uint64_t tracefile_count_current; }; /* @@ -460,7 +466,9 @@ struct lttng_consumer_channel *consumer_allocate_channel(uint64_t key, uid_t uid, gid_t gid, int relayd_id, - enum lttng_event_output output); + enum lttng_event_output output, + uint64_t tracefile_size, + uint64_t tracefile_count); void consumer_del_stream(struct lttng_consumer_stream *stream, struct lttng_ht *ht); void consumer_del_metadata_stream(struct lttng_consumer_stream *stream, @@ -486,6 +494,7 @@ struct lttng_consumer_local_data *lttng_consumer_create( int (*recv_stream)(struct lttng_consumer_stream *stream), int (*update_stream)(int sessiond_key, uint32_t state)); void lttng_consumer_destroy(struct lttng_consumer_local_data *ctx); +int lttng_create_output_file(struct lttng_consumer_stream *stream); ssize_t lttng_consumer_on_read_subbuffer_mmap( struct lttng_consumer_local_data *ctx, struct lttng_consumer_stream *stream, unsigned long len, diff --git a/src/common/defaults.h b/src/common/defaults.h index 94a2a3587..fb6a975dd 100644 --- a/src/common/defaults.h +++ b/src/common/defaults.h @@ -136,6 +136,10 @@ #define DEFAULT_KERNEL_CHANNEL_SUBBUF_NUM DEFAULT_CHANNEL_SUBBUF_NUM /* See lttng-kernel.h enum lttng_kernel_output for channel output */ #define DEFAULT_KERNEL_CHANNEL_OUTPUT LTTNG_EVENT_SPLICE +/* By default, unlimited tracefile size */ +#define DEFAULT_KERNEL_CHANNEL_TRACEFILE_SIZE 0 +/* By default, unlimited tracefile count */ +#define DEFAULT_KERNEL_CHANNEL_TRACEFILE_COUNT 0 #define DEFAULT_KERNEL_CHANNEL_SWITCH_TIMER \ DEFAULT_CHANNEL_SWITCH_TIMER @@ -149,6 +153,10 @@ #define DEFAULT_UST_CHANNEL_SUBBUF_NUM DEFAULT_CHANNEL_SUBBUF_NUM /* See lttng-ust.h enum lttng_ust_output */ #define DEFAULT_UST_CHANNEL_OUTPUT LTTNG_EVENT_MMAP +/* By default, unlimited tracefile size */ +#define DEFAULT_UST_CHANNEL_TRACEFILE_SIZE 0 +/* By default, unlimited tracefile count */ +#define DEFAULT_UST_CHANNEL_TRACEFILE_COUNT 0 #define DEFAULT_UST_CHANNEL_SWITCH_TIMER \ DEFAULT_CHANNEL_SWITCH_TIMER diff --git a/src/common/kernel-consumer/kernel-consumer.c b/src/common/kernel-consumer/kernel-consumer.c index 0de73443e..385af875a 100644 --- a/src/common/kernel-consumer/kernel-consumer.c +++ b/src/common/kernel-consumer/kernel-consumer.c @@ -132,7 +132,9 @@ int lttng_kconsumer_recv_cmd(struct lttng_consumer_local_data *ctx, new_channel = consumer_allocate_channel(msg.u.channel.channel_key, msg.u.channel.session_id, msg.u.channel.pathname, msg.u.channel.name, msg.u.channel.uid, msg.u.channel.gid, - msg.u.channel.relayd_id, msg.u.channel.output); + msg.u.channel.relayd_id, msg.u.channel.output, + msg.u.channel.tracefile_size, + msg.u.channel.tracefile_count); if (new_channel == NULL) { lttng_consumer_send_error(ctx, LTTCOMM_CONSUMERD_OUTFD_ERROR); goto end_nosignal; @@ -501,28 +503,15 @@ end: int lttng_kconsumer_on_recv_stream(struct lttng_consumer_stream *stream) { int ret; - char full_path[PATH_MAX]; assert(stream); - ret = snprintf(full_path, sizeof(full_path), "%s/%s", - stream->chan->pathname, stream->name); + ret = lttng_create_output_file(stream); if (ret < 0) { - PERROR("snprintf on_recv_stream"); + ERR("Creating output file"); goto error; } - /* Opening the tracefile in write mode */ - if (stream->net_seq_idx == (uint64_t) -1ULL) { - ret = run_as_open(full_path, O_WRONLY | O_CREAT | O_TRUNC, - S_IRWXU|S_IRWXG|S_IRWXO, stream->uid, stream->gid); - if (ret < 0) { - PERROR("open kernel stream path %s", full_path); - goto error; - } - stream->out_fd = ret; - } - if (stream->output == LTTNG_EVENT_MMAP) { /* get the len of the mmap region */ unsigned long mmap_len; diff --git a/src/common/sessiond-comm/sessiond-comm.h b/src/common/sessiond-comm/sessiond-comm.h index 63d4eda07..5980ddfca 100644 --- a/src/common/sessiond-comm/sessiond-comm.h +++ b/src/common/sessiond-comm/sessiond-comm.h @@ -291,6 +291,8 @@ struct lttcomm_consumer_msg { /* Use splice or mmap to consume this fd */ enum lttng_event_output output; int type; /* Per cpu or metadata. */ + uint64_t tracefile_size; /* bytes */ + uint32_t tracefile_count; /* number of tracefiles */ } LTTNG_PACKED channel; /* Only used by Kernel. */ struct { uint64_t stream_key; @@ -328,6 +330,8 @@ struct lttcomm_consumer_msg { uint64_t key; /* Unique channel key. */ unsigned char uuid[UUID_STR_LEN]; /* uuid for ust tracer. */ uint32_t chan_id; /* Channel ID on the tracer side. */ + uint64_t tracefile_size; /* bytes */ + uint32_t tracefile_count; /* number of tracefiles */ } LTTNG_PACKED ask_channel; struct { uint64_t key; diff --git a/src/common/ust-consumer/ust-consumer.c b/src/common/ust-consumer/ust-consumer.c index 431b94626..b558988dc 100644 --- a/src/common/ust-consumer/ust-consumer.c +++ b/src/common/ust-consumer/ust-consumer.c @@ -112,13 +112,14 @@ error: */ static struct lttng_consumer_channel *allocate_channel(uint64_t session_id, const char *pathname, const char *name, uid_t uid, gid_t gid, - int relayd_id, uint64_t key, enum lttng_event_output output) + int relayd_id, uint64_t key, enum lttng_event_output output, + uint64_t tracefile_size, uint64_t tracefile_count) { assert(pathname); assert(name); return consumer_allocate_channel(key, session_id, pathname, name, uid, gid, - relayd_id, output); + relayd_id, output, tracefile_size, tracefile_count); } /* @@ -848,7 +849,9 @@ int lttng_ustconsumer_recv_cmd(struct lttng_consumer_local_data *ctx, msg.u.ask_channel.pathname, msg.u.ask_channel.name, msg.u.ask_channel.uid, msg.u.ask_channel.gid, msg.u.ask_channel.relayd_id, msg.u.ask_channel.key, - (enum lttng_event_output) msg.u.ask_channel.output); + (enum lttng_event_output) msg.u.ask_channel.output, + msg.u.ask_channel.tracefile_size, + msg.u.ask_channel.tracefile_count); if (!channel) { goto end_channel_error; } @@ -1283,35 +1286,7 @@ end: */ int lttng_ustconsumer_on_recv_stream(struct lttng_consumer_stream *stream) { - int ret; - char full_path[PATH_MAX]; - - /* Opening the tracefile in write mode */ - if (stream->net_seq_idx != (uint64_t) -1ULL) { - goto end; - } - - ret = snprintf(full_path, sizeof(full_path), "%s/%s", - stream->chan->pathname, stream->name); - if (ret < 0) { - PERROR("snprintf on_recv_stream"); - goto error; - } - - ret = run_as_open(full_path, O_WRONLY | O_CREAT | O_TRUNC, - S_IRWXU | S_IRWXG | S_IRWXO, stream->uid, stream->gid); - if (ret < 0) { - PERROR("open stream path %s", full_path); - goto error; - } - stream->out_fd = ret; - -end: - /* we return 0 to let the library handle the FD internally */ - return 0; - -error: - return ret; + return lttng_create_output_file(stream); } /* diff --git a/src/lib/lttng-ctl/lttng-ctl.c b/src/lib/lttng-ctl/lttng-ctl.c index 8f63bf3e8..f2a61072b 100644 --- a/src/lib/lttng-ctl/lttng-ctl.c +++ b/src/lib/lttng-ctl/lttng-ctl.c @@ -1360,6 +1360,8 @@ 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; + attr->tracefile_size = DEFAULT_KERNEL_CHANNEL_TRACEFILE_SIZE; + attr->tracefile_count = DEFAULT_KERNEL_CHANNEL_TRACEFILE_COUNT; break; case LTTNG_DOMAIN_UST: #if 0 @@ -1374,6 +1376,8 @@ void lttng_channel_set_default_attr(struct lttng_domain *domain, attr->subbuf_size = default_get_ust_channel_subbuf_size(); attr->num_subbuf = DEFAULT_UST_CHANNEL_SUBBUF_NUM; attr->output = DEFAULT_UST_CHANNEL_OUTPUT; + attr->tracefile_size = DEFAULT_UST_CHANNEL_TRACEFILE_SIZE; + attr->tracefile_count = DEFAULT_UST_CHANNEL_TRACEFILE_COUNT; break; default: /* Default behavior: leave set to 0. */ -- 2.34.1