On-disk multiple tracefiles circular buffer
authorJulien Desfossez <jdesfossez@efficios.com>
Wed, 27 Mar 2013 17:27:55 +0000 (13:27 -0400)
committerDavid Goulet <dgoulet@efficios.com>
Thu, 28 Mar 2013 16:55:22 +0000 (12:55 -0400)
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@efficios.com>
Signed-off-by: David Goulet <dgoulet@efficios.com>
21 files changed:
doc/man/lttng.1
include/lttng/lttng.h
src/bin/lttng-sessiond/channel.c
src/bin/lttng-sessiond/consumer.c
src/bin/lttng-sessiond/consumer.h
src/bin/lttng-sessiond/kernel-consumer.c
src/bin/lttng-sessiond/kernel.c
src/bin/lttng-sessiond/trace-kernel.h
src/bin/lttng-sessiond/trace-ust.c
src/bin/lttng-sessiond/trace-ust.h
src/bin/lttng-sessiond/ust-app.c
src/bin/lttng-sessiond/ust-app.h
src/bin/lttng-sessiond/ust-consumer.c
src/bin/lttng/commands/enable_channels.c
src/common/consumer.c
src/common/consumer.h
src/common/defaults.h
src/common/kernel-consumer/kernel-consumer.c
src/common/sessiond-comm/sessiond-comm.h
src/common/ust-consumer/ust-consumer.c
src/lib/lttng-ctl/lttng-ctl.c

index a8e02fafa11718c70436559071d6069c9d3f4f82..38a99ce63bd19ea35cf2d059793d58907eb652ea 100644 (file)
@@ -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
index 8566deabe61d91dea58337e94bb74f5075c970e2..ee348df850adb0c4753201595ed2e404b1840a9e 100644 (file)
@@ -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];
 };
index 6c7422b292dcb3ffd21665468c0f15cc6a728180..1621bc626bba7d72b52098b8c1798ee859d80c70 100644 (file)
@@ -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) {
index f0fb2dc00f92967efdf7d22df4c7c61e98abd73b..f803f7b0553c19c0458d387ae8b03a73a1969417 100644 (file)
@@ -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));
index b767589d92c58a90f59dd799bc9994de09dee789..798eaa265679f960e93f4b334ce7cfc93c43e85c 100644 (file)
@@ -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,
index 3368da6c1ba8a5d6e2c89ac09d0679793fc04867..05e30e49cb0b9ff65e88534ae9cec25de2222693 100644 (file)
@@ -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();
 
index d3a64537546406a8a30bb161e244b45858897c78..95194113243dcf4dbf426e0dfaac19b192cd46ba 100644 (file)
@@ -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++;
index 66ca8dbdef5a9b8f5818855b6cb51c88820ef319..87807d989c12645946b03c4b9d01fb0feb7b42d5 100644 (file)
@@ -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;
 };
 
index 8f15a1576a68375277609e0ffd50642d0fd4eb3c..cd8ff1053caa7c6163fe7686288d071e5dedafc0 100644 (file)
@@ -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:
index 87fe412d6b862ed0c5eed27af988c55affbdabbd..92d6aaaf416d5af7c5c1f5184854c99d2c30fbf6 100644 (file)
@@ -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 */
index fdcad1c304ab0c717fb3f619b812de6d17433b31..4c9d227af008a285bd17d8732ed906803351f275 100644 (file)
@@ -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;
index 82694a722b976ebe494d44d88444512ecadc0aa6..e0aa17a7feb01f05ed3002347827f8451b6f0612 100644 (file)
@@ -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.
         */
index 7f01de9ea55516223a78fc885886aa774485f934..93c1f713562b016f7147ba16e402dae18ce88e0d 100644 (file)
@@ -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();
 
index 02a31800a8766cd04a57ed55765cb5636dae857e..d026af4337332ddfa08c05b3f912aa40085e9b18 100644 (file)
@@ -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;
index 5f87f4b5018fbec1a2de542797f46b4f6d17475f..b6e440a486fc5995f9a7caca0eac39631bf3340c 100644 (file)
@@ -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) {
index 46387522ec50c8a9509077f88a06213ef8c7c22e..6fd4e2e5ce5ae08160475b3d6ba02d4069ca95df 100644 (file)
@@ -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,
index 94a2a35870a423a21e31a7c096b93cef1fcea3e4..fb6a975ddabe8fb3e231fc49f5d8754855cfa775 100644 (file)
 #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
 #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
index 0de73443e1bee5c51549e608d20b1548cb007257..385af875a2d9b69aeeff6c58f5dcf8017338e16d 100644 (file)
@@ -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;
index 63d4eda078866b17342089aae7382e5aebf243a2..5980ddfcaccb0ea47e6854723262f7e4338e8fbd 100644 (file)
@@ -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;
index 431b94626736d042d92db89db0774e7e941cc3e7..b558988dcf1a2ba4fcf6b6cabdff46c7166bbf25 100644 (file)
@@ -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);
 }
 
 /*
index 8f63bf3e85e367285f9c599176040a4cd266dcd5..f2a61072b7971a44a2254bd600a1a7a85eb4a973 100644 (file)
@@ -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. */
This page took 0.039819 seconds and 5 git commands to generate.