* David Goulet ([email protected]) wrote:
> From: Julien Desfossez <[email protected]>
> 
> 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 <[email protected]>
> Signed-off-by: David Goulet <[email protected]>
> ---
>  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
> [email protected]
> http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev

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

_______________________________________________
lttng-dev mailing list
[email protected]
http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev

Reply via email to