[lttng-dev] [PATCH lttng-tools] On-disk multiple tracefiles circular buffer

Mathieu Desnoyers mathieu.desnoyers at efficios.com
Wed Mar 27 15:38:51 EDT 2013


* David Goulet (dgoulet at efficios.com) wrote:
> From: Julien Desfossez <jdesfossez at efficios.com>
> 
> 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 <jdesfossez at efficios.com>
> Signed-off-by: David Goulet <dgoulet at efficios.com>
> ---
>  doc/man/lttng.1                              |    5 ++
>  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     |   33 +++++++
>  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, 253 insertions(+), 59 deletions(-)
> 
> diff --git a/doc/man/lttng.1 b/doc/man/lttng.1
> index 0a548f8..891e106 100644
> --- a/doc/man/lttng.1
> +++ b/doc/man/lttng.1
> @@ -345,6 +345,11 @@ 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 tracefiles per stream (in bytes)

of each tracefile within a stream

> +\-W, \-\-tracefile-count COUNT
> +        Number of tracefiles per stream

Can we beef up these descriptions so users can have a clue what this is
supposed to be used for ? An example would be good.

> +
>  .fi
>  
>  .IP
> diff --git a/include/lttng/lttng.h b/include/lttng/lttng.h
> index 8566dea..9fa5844 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 + 20
>  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 */
> +	uint32_t tracefile_count;                /* number of tracefiles */

why not uint64_t (same comment for all type use below) ?

>  
>  	char padding[LTTNG_CHANNEL_ATTR_PADDING1];
>  };
> diff --git a/src/bin/lttng-sessiond/channel.c b/src/bin/lttng-sessiond/channel.c
> index 6c7422b..1621bc6 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 f0fb2dc..c3f53be 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,
> +		uint32_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,
> +		uint32_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 b767589..c2631ba 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,
> +		uint32_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,
> +		uint32_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 3368da6..05e30e4 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 d3a6453..9519411 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 66ca8db..ea30827 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;
> +	uint32_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 8f15a15..cd8ff10 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 87fe412..588905a 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;
> +	uint32_t tracefile_count;
>  };
>  
>  /* UST Metadata */
> diff --git a/src/bin/lttng-sessiond/ust-app.c b/src/bin/lttng-sessiond/ust-app.c
> index fdcad1c..4c9d227 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 82694a7..b94603f 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;
> +	uint32_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 7f01de9..93c1f71 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 02a3180..d303bbd 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,10 @@ 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 tracefiles per stream (in bytes)\n");
> +	fprintf(ofp, "  -W, --tracefile-count COUNT\n");
> +	fprintf(ofp, "                           Number of tracefiles per stream to keep\n");

more info would be welcome, like the manpage.

>  	fprintf(ofp, "\n");
>  }
>  
> @@ -147,6 +155,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 +193,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 superior or equal to subbuf_size "

superior -> higher

Thanks,

Mathieu

> +				"(%" 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 +330,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 %" PRIu32,
> +					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 5f87f4b..0c59846 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,
> +		uint32_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';
> @@ -1284,6 +1288,93 @@ end:
>  }
>  
>  /*
> + * 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_%" PRIu32, 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
>   * the network.
> @@ -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 4638752..6a15b0c 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;
> +	uint32_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;
> +	uint32_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,
> +		uint32_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 94a2a35..fb6a975 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 0de7344..385af87 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 63d4eda..5980ddf 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 431b946..95b0f62 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, uint32_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 8f63bf3..f2a6107 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. */
> -- 
> 1.7.10.4
> 
> 
> _______________________________________________
> lttng-dev mailing list
> lttng-dev at lists.lttng.org
> http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev

-- 
Mathieu Desnoyers
EfficiOS Inc.
http://www.efficios.com



More information about the lttng-dev mailing list