+LTTNG_HIDDEN
+struct lttng_trace_chunk *lttng_trace_chunk_copy(
+ struct lttng_trace_chunk *source_chunk)
+{
+ struct lttng_trace_chunk *new_chunk = lttng_trace_chunk_allocate();
+
+ if (!new_chunk) {
+ goto end;
+ }
+
+ pthread_mutex_lock(&source_chunk->lock);
+ /*
+ * A new chunk is always a user; it shall create no new trace
+ * subdirectories.
+ */
+ new_chunk->mode = (typeof(new_chunk->mode)) {
+ .is_set = true,
+ .value = TRACE_CHUNK_MODE_USER,
+ };
+ /*
+ * top_level_directories is not copied as it is never used
+ * by _user_ mode chunks.
+ */
+ /* The new chunk is not part of a registry (yet, at least). */
+ new_chunk->in_registry_element = false;
+ new_chunk->name_overridden = source_chunk->name_overridden;
+ if (source_chunk->name) {
+ new_chunk->name = strdup(source_chunk->name);
+ if (!new_chunk->name) {
+ ERR("Failed to copy source trace chunk name in %s()",
+ __FUNCTION__);
+ goto error_unlock;
+ }
+ }
+ new_chunk->id = source_chunk->id;
+ new_chunk->timestamp_creation = source_chunk->timestamp_creation;
+ new_chunk->timestamp_close = source_chunk->timestamp_close;
+ new_chunk->credentials = source_chunk->credentials;
+ if (source_chunk->session_output_directory) {
+ const bool reference_acquired = lttng_directory_handle_get(
+ source_chunk->session_output_directory);
+
+ assert(reference_acquired);
+ new_chunk->session_output_directory =
+ source_chunk->session_output_directory;
+ }
+ if (source_chunk->chunk_directory) {
+ const bool reference_acquired = lttng_directory_handle_get(
+ source_chunk->chunk_directory);
+
+ assert(reference_acquired);
+ new_chunk->chunk_directory = source_chunk->chunk_directory;
+ }
+ new_chunk->close_command = source_chunk->close_command;
+ pthread_mutex_unlock(&source_chunk->lock);
+end:
+ return new_chunk;
+error_unlock:
+ pthread_mutex_unlock(&source_chunk->lock);
+ lttng_trace_chunk_put(new_chunk);
+ return NULL;
+}
+