+/*
+ * 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;
+}
+