X-Git-Url: http://git.efficios.com/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fcommon%2Fconsumer.c;h=b6e440a486fc5995f9a7caca0eac39631bf3340c;hp=5f87f4b5018fbec1a2de542797f46b4f6d17475f;hb=1624d5b7ba86633d36f3a5c86ea1df5d308c4360;hpb=6d5d85c79765744fcad6ba189a256784b825e7bf diff --git a/src/common/consumer.c b/src/common/consumer.c index 5f87f4b50..b6e440a48 100644 --- a/src/common/consumer.c +++ b/src/common/consumer.c @@ -828,7 +828,9 @@ struct lttng_consumer_channel *consumer_allocate_channel(uint64_t key, uid_t uid, gid_t gid, int relayd_id, - enum lttng_event_output output) + enum lttng_event_output output, + uint64_t tracefile_size, + uint64_t tracefile_count) { struct lttng_consumer_channel *channel; @@ -845,6 +847,8 @@ struct lttng_consumer_channel *consumer_allocate_channel(uint64_t key, channel->gid = gid; channel->relayd_id = relayd_id; channel->output = output; + channel->tracefile_size = tracefile_size; + channel->tracefile_count = tracefile_count; strncpy(channel->pathname, pathname, sizeof(channel->pathname)); channel->pathname[sizeof(channel->pathname) - 1] = '\0'; @@ -1283,6 +1287,93 @@ end: return ret; } +/* + * Create the tracefile on disk. + * + * Return 0 on success or else a negative value. + */ +int lttng_create_output_file(struct lttng_consumer_stream *stream) +{ + int ret; + char full_path[PATH_MAX]; + char *path_name_id = NULL; + char *path; + + assert(stream); + assert(stream->net_seq_idx == (uint64_t) -1ULL); + + ret = snprintf(full_path, sizeof(full_path), "%s/%s", + stream->chan->pathname, stream->name); + if (ret < 0) { + PERROR("snprintf create output file"); + goto error; + } + + /* + * If we split the trace in multiple files, we have to add the tracefile + * current count at the end of the tracefile name + */ + if (stream->chan->tracefile_size > 0) { + ret = asprintf(&path_name_id, "%s_%" PRIu64, full_path, + stream->tracefile_count_current); + if (ret < 0) { + PERROR("Allocating path name ID"); + goto error; + } + path = path_name_id; + } else { + path = full_path; + } + + ret = run_as_open(path, O_WRONLY | O_CREAT | O_TRUNC, + S_IRWXU | S_IRWXG | S_IRWXO, stream->uid, stream->gid); + if (ret < 0) { + PERROR("open stream path %s", path); + goto error_open; + } + stream->out_fd = ret; + stream->tracefile_size_current = 0; + +error_open: + free(path_name_id); +error: + return ret; +} + +/* + * Change the output tracefile according to the tracefile_size and + * tracefile_count parameters. The stream lock MUST be held before calling this + * function because we are modifying the stream status. + * + * Return 0 on success or else a negative value. + */ +static int rotate_output_file(struct lttng_consumer_stream *stream) +{ + int ret; + + assert(stream); + assert(stream->tracefile_size_current); + + ret = close(stream->out_fd); + if (ret < 0) { + PERROR("Closing tracefile"); + goto end; + } + + if (stream->chan->tracefile_count > 0) { + stream->tracefile_count_current = + (stream->tracefile_count_current + 1) % + stream->chan->tracefile_count; + } else { + stream->tracefile_count_current++; + } + + return lttng_create_output_file(stream); + +end: + return ret; +} + /* * Mmap the ring buffer, read it and write the data to the tracefile. This is a * core function for writing trace buffers to either the local filesystem or @@ -1390,6 +1481,21 @@ ssize_t lttng_consumer_on_read_subbuffer_mmap( } else { /* No streaming, we have to set the len with the full padding */ len += padding; + + /* + * Check if we need to change the tracefile before writing the packet. + */ + if (stream->chan->tracefile_size > 0 && + (stream->tracefile_size_current + len) > + stream->chan->tracefile_size) { + ret = rotate_output_file(stream); + if (ret < 0) { + ERR("Rotating output file"); + goto end; + } + outfd = stream->out_fd; + } + stream->tracefile_size_current += len; } while (len > 0) { @@ -1552,6 +1658,21 @@ ssize_t lttng_consumer_on_read_subbuffer_splice( } else { /* No streaming, we have to set the len with the full padding */ len += padding; + + /* + * Check if we need to change the tracefile before writing the packet. + */ + if (stream->chan->tracefile_size > 0 && + (stream->tracefile_size_current + len) > + stream->chan->tracefile_size) { + ret = rotate_output_file(stream); + if (ret < 0) { + ERR("Rotating output file"); + goto end; + } + outfd = stream->out_fd; + } + stream->tracefile_size_current += len; } while (len > 0) {