* Return 0 on success, -1 on error.
*/
static
-int create_rotate_index_file(struct relay_stream *stream)
+int create_rotate_index_file(struct relay_stream *stream,
+ const char *stream_path)
{
int ret;
uint32_t major, minor;
}
major = stream->trace->session->major;
minor = stream->trace->session->minor;
- stream->index_file = lttng_index_file_create(stream->path_name,
+ stream->index_file = lttng_index_file_create(stream_path,
stream->channel_name,
-1, -1, stream->tracefile_size,
tracefile_array_get_file_index_head(stream->tfa),
/* Rotate also the index if the stream is not a metadata stream. */
if (!stream->is_metadata) {
- ret = create_rotate_index_file(stream);
+ ret = create_rotate_index_file(stream, stream->path_name);
if (ret < 0) {
ERR("Failed to rotate index file");
goto end;
goto end;
}
- ret = create_rotate_index_file(stream);
+ ret = create_rotate_index_file(stream, stream->path_name);
if (ret < 0) {
ERR("Rotate stream index file");
goto end;
* Update the trace path (just the folder, the stream name does not
* change).
*/
- free(stream->path_name);
+ free(stream->prev_path_name);
+ stream->prev_path_name = stream->path_name;
stream->path_name = create_output_path(new_path_view.data);
if (!stream->path_name) {
ERR("Failed to create a new output path");
}
if (rotate_index || !stream->index_file) {
- ret = create_rotate_index_file(stream);
+ const char *stream_path;
+
+ /*
+ * The data connection creates the stream's first index file.
+ *
+ * This can happen _after_ a ROTATE_STREAM command. In
+ * other words, the data of the first packet of this stream
+ * can be received after a ROTATE_STREAM command.
+ *
+ * The ROTATE_STREAM command changes the stream's path_name
+ * to point to the "next" chunk. If a rotation is pending for
+ * this stream, as indicated by "rotate_at_seq_num != -1ULL",
+ * it means that we are still receiving data that belongs in the
+ * stream's former path.
+ *
+ * In this very specific case, we must ensure that the index
+ * file is created in the streams's former path,
+ * "prev_path_name".
+ *
+ * All other rotations beyond the first one are not affected
+ * by this problem since the actual rotation operation creates
+ * the new chunk's index file.
+ */
+ stream_path = stream->rotate_at_seq_num == -1ULL ?
+ stream->path_name:
+ stream->prev_path_name;
+
+ ret = create_rotate_index_file(stream, stream_path);
if (ret < 0) {
ERR("Failed to rotate index");
/* Put self-ref for this index due to error. */
struct lttng_index_file *index_file;
char *path_name;
+ /*
+ * prev_path_name is only used for session rotation support.
+ * It is essentially used to work around the fact that index
+ * files are always created from the 'data' connection.
+ *
+ * Hence, it is possible to receive a ROTATE_STREAM command
+ * which affects the stream's path_name before the creation of
+ * an index file. In this situation, the index file of the
+ * 'previous' chunk would be created in the new destination folder.
+ *
+ * It would then be unlinked when the actual index of the new chunk
+ * is created.
+ */
+ char *prev_path_name;
char *channel_name;
/* On-disk circular buffer of tracefiles. */
* create and open have refcount of 1. Use put to decrement the
* refcount. Destroys when reaching 0. Use "get" to increment refcount.
*/
-struct lttng_index_file *lttng_index_file_create(char *path_name,
+struct lttng_index_file *lttng_index_file_create(const char *path_name,
char *stream_name, int uid, int gid, uint64_t size,
uint64_t count, uint32_t major, uint32_t minor);
struct lttng_index_file *lttng_index_file_open(const char *path_name,