/*
- * Copyright (C) 2011 - Julien Desfossez <julien.desfossez@polymtl.ca>
- * Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
- * Copyright (C) 2013 - David Goulet <dgoulet@efficios.com>
+ * Copyright (C) 2011 Julien Desfossez <julien.desfossez@polymtl.ca>
+ * Copyright (C) 2011 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ * Copyright (C) 2013 David Goulet <dgoulet@efficios.com>
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License, version 2 only, as
- * published by the Free Software Foundation.
+ * SPDX-License-Identifier: GPL-2.0-only
*
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 51
- * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define _LGPL_SOURCE
stream->index_file = NULL;
}
+ lttng_trace_chunk_put(stream->trace_chunk);
+ stream->trace_chunk = NULL;
+
/* Check and cleanup relayd if needed. */
rcu_read_lock();
relayd = consumer_find_relayd(stream->net_seq_idx);
}
/* Free stream within a RCU call. */
+ lttng_trace_chunk_put(stream->trace_chunk);
+ stream->trace_chunk = NULL;
consumer_stream_free(stream);
}
rcu_read_unlock();
return ret;
}
+
+int consumer_stream_create_output_files(struct lttng_consumer_stream *stream,
+ bool create_index)
+{
+ int ret;
+ enum lttng_trace_chunk_status chunk_status;
+ const int flags = O_WRONLY | O_CREAT | O_TRUNC;
+ const mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
+ char stream_path[LTTNG_PATH_MAX];
+
+ ASSERT_LOCKED(stream->lock);
+ assert(stream->trace_chunk);
+
+ ret = utils_stream_file_path(stream->chan->pathname, stream->name,
+ stream->chan->tracefile_size,
+ stream->tracefile_count_current, NULL,
+ stream_path, sizeof(stream_path));
+ if (ret < 0) {
+ goto end;
+ }
+
+ if (stream->out_fd >= 0) {
+ ret = close(stream->out_fd);
+ if (ret < 0) {
+ PERROR("Failed to close stream file \"%s\"",
+ stream->name);
+ goto end;
+ }
+ stream->out_fd = -1;
+ }
+
+ DBG("Opening stream output file \"%s\"", stream_path);
+ chunk_status = lttng_trace_chunk_open_file(stream->trace_chunk, stream_path,
+ flags, mode, &stream->out_fd, false);
+ if (chunk_status != LTTNG_TRACE_CHUNK_STATUS_OK) {
+ ERR("Failed to open stream file \"%s\"", stream->name);
+ ret = -1;
+ goto end;
+ }
+
+ if (!stream->metadata_flag && (create_index || stream->index_file)) {
+ if (stream->index_file) {
+ lttng_index_file_put(stream->index_file);
+ }
+ chunk_status = lttng_index_file_create_from_trace_chunk(
+ stream->trace_chunk,
+ stream->chan->pathname,
+ stream->name,
+ stream->chan->tracefile_size,
+ stream->tracefile_count_current,
+ CTF_INDEX_MAJOR, CTF_INDEX_MINOR,
+ false, &stream->index_file);
+ if (chunk_status != LTTNG_TRACE_CHUNK_STATUS_OK) {
+ ret = -1;
+ goto end;
+ }
+ }
+
+ /* Reset current size because we just perform a rotation. */
+ stream->tracefile_size_current = 0;
+ stream->out_fd_offset = 0;
+end:
+ return ret;
+}
+
+int consumer_stream_rotate_output_files(struct lttng_consumer_stream *stream)
+{
+ int ret;
+
+ stream->tracefile_count_current++;
+ if (stream->chan->tracefile_count > 0) {
+ stream->tracefile_count_current %=
+ stream->chan->tracefile_count;
+ }
+
+ DBG("Rotating output files of stream \"%s\"", stream->name);
+ ret = consumer_stream_create_output_files(stream, true);
+ if (ret) {
+ goto end;
+ }
+
+end:
+ return ret;
+}
+
+bool consumer_stream_is_deleted(struct lttng_consumer_stream *stream)
+{
+ /*
+ * This function does not take a const stream since
+ * cds_lfht_is_node_deleted was not const before liburcu 0.12.
+ */
+ assert(stream);
+ return cds_lfht_is_node_deleted(&stream->node.node);
+}