X-Git-Url: http://git.efficios.com/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fcommon%2Ftrace-chunk.c;h=c549f46b33c855334814355ef8a6e37f6cacadf2;hp=aadb40f6f68383a174304cc912c2beb2880a86fd;hb=0e2d816a62eccd0d159ec254e87ff80a7e6cf1bb;hpb=3ff5c5db220d92baf64280ba54713fcafe76142e diff --git a/src/common/trace-chunk.c b/src/common/trace-chunk.c index aadb40f6f..c549f46b3 100644 --- a/src/common/trace-chunk.c +++ b/src/common/trace-chunk.c @@ -78,6 +78,11 @@ struct lttng_trace_chunk { * Only used by _owner_ mode chunks. */ struct lttng_dynamic_pointer_array top_level_directories; + /* + * All files contained within the trace chunk. + * Array of paths (char *). + */ + struct lttng_dynamic_pointer_array files; /* Is contained within an lttng_trace_chunk_registry_element? */ bool in_registry_element; bool name_overridden; @@ -111,6 +116,10 @@ static const char *close_command_names[] = { [LTTNG_TRACE_CHUNK_COMMAND_TYPE_MOVE_TO_COMPLETED] = "move to completed chunk folder", + [LTTNG_TRACE_CHUNK_COMMAND_TYPE_NO_OPERATION] = + "no operation", + [LTTNG_TRACE_CHUNK_COMMAND_TYPE_DELETE] = + "delete", }; static const @@ -216,6 +225,7 @@ void lttng_trace_chunk_init(struct lttng_trace_chunk *chunk) urcu_ref_init(&chunk->ref); pthread_mutex_init(&chunk->lock, NULL); lttng_dynamic_pointer_array_init(&chunk->top_level_directories, free); + lttng_dynamic_pointer_array_init(&chunk->files, free); } static @@ -233,6 +243,7 @@ void lttng_trace_chunk_fini(struct lttng_trace_chunk *chunk) free(chunk->name); chunk->name = NULL; lttng_dynamic_pointer_array_reset(&chunk->top_level_directories); + lttng_dynamic_pointer_array_reset(&chunk->files); pthread_mutex_destroy(&chunk->lock); } @@ -472,6 +483,17 @@ end: return status; } +LTTNG_HIDDEN +bool lttng_trace_chunk_get_name_overridden(struct lttng_trace_chunk *chunk) +{ + bool name_overridden; + + pthread_mutex_lock(&chunk->lock); + name_overridden = chunk->name_overridden; + pthread_mutex_unlock(&chunk->lock); + return name_overridden; +} + static bool is_valid_chunk_name(const char *name) { @@ -813,6 +835,80 @@ end: return status; } +/* + * TODO: Implement O(1) lookup. + */ +static +bool lttng_trace_chunk_find_file(struct lttng_trace_chunk *chunk, + const char *path, size_t *index) +{ + size_t i, count; + + count = lttng_dynamic_pointer_array_get_count(&chunk->files); + for (i = 0; i < count; i++) { + const char *iter_path = + lttng_dynamic_pointer_array_get_pointer( + &chunk->files, i); + if (!strcmp(iter_path, path)) { + if (index) { + *index = i; + } + return true; + } + } + return false; +} + +static +enum lttng_trace_chunk_status lttng_trace_chunk_add_file( + struct lttng_trace_chunk *chunk, + const char *path) +{ + char *copy; + int ret; + enum lttng_trace_chunk_status status = LTTNG_TRACE_CHUNK_STATUS_OK; + + if (lttng_trace_chunk_find_file(chunk, path, NULL)) { + return LTTNG_TRACE_CHUNK_STATUS_OK; + } + DBG("Adding new file \"%s\" to trace chunk \"%s\"", + path, chunk->name ? : "(unnamed)"); + copy = strdup(path); + if (!copy) { + PERROR("Failed to copy path"); + status = LTTNG_TRACE_CHUNK_STATUS_ERROR; + goto end; + } + ret = lttng_dynamic_pointer_array_add_pointer( + &chunk->files, copy); + if (ret) { + ERR("Allocation failure while adding file to a trace chunk"); + free(copy); + status = LTTNG_TRACE_CHUNK_STATUS_ERROR; + goto end; + } +end: + return status; +} + +static +void lttng_trace_chunk_remove_file( + struct lttng_trace_chunk *chunk, + const char *path) +{ + size_t index; + bool found; + int ret; + + found = lttng_trace_chunk_find_file(chunk, path, &index); + if (!found) { + return; + } + ret = lttng_dynamic_pointer_array_remove_pointer( + &chunk->files, index); + assert(!ret); +} + LTTNG_HIDDEN enum lttng_trace_chunk_status lttng_trace_chunk_open_file( struct lttng_trace_chunk *chunk, const char *file_path, @@ -839,6 +935,10 @@ enum lttng_trace_chunk_status lttng_trace_chunk_open_file( status = LTTNG_TRACE_CHUNK_STATUS_ERROR; goto end; } + status = lttng_trace_chunk_add_file(chunk, file_path); + if (status != LTTNG_TRACE_CHUNK_STATUS_OK) { + goto end; + } ret = lttng_directory_handle_open_file_as_user( chunk->chunk_directory, file_path, flags, mode, chunk->credentials.value.use_current_user ? @@ -851,6 +951,7 @@ enum lttng_trace_chunk_status lttng_trace_chunk_open_file( file_path, flags, (int) mode); status = LTTNG_TRACE_CHUNK_STATUS_ERROR; } + lttng_trace_chunk_remove_file(chunk, file_path); goto end; } *out_fd = ret; @@ -892,6 +993,7 @@ int lttng_trace_chunk_unlink_file(struct lttng_trace_chunk *chunk, status = LTTNG_TRACE_CHUNK_STATUS_ERROR; goto end; } + lttng_trace_chunk_remove_file(chunk, file_path); end: pthread_mutex_unlock(&chunk->lock); return status; @@ -1078,7 +1180,15 @@ enum lttng_trace_chunk_status lttng_trace_chunk_set_close_command( DBG("Setting trace chunk close command to \"%s\"", close_command_names[close_command]); } - LTTNG_OPTIONAL_SET(&chunk->close_command, close_command); + /* + * Unset close command for no-op for backward compatibility with relayd + * 2.11. + */ + if (close_command != LTTNG_TRACE_CHUNK_COMMAND_TYPE_NO_OPERATION) { + LTTNG_OPTIONAL_SET(&chunk->close_command, close_command); + } else { + LTTNG_OPTIONAL_UNSET(&chunk->close_command); + } pthread_mutex_unlock(&chunk->lock); end: return status; @@ -1091,6 +1201,10 @@ const char *lttng_trace_chunk_command_type_get_name( switch (command) { case LTTNG_TRACE_CHUNK_COMMAND_TYPE_MOVE_TO_COMPLETED: return "move to completed trace chunk folder"; + case LTTNG_TRACE_CHUNK_COMMAND_TYPE_NO_OPERATION: + return "no operation"; + case LTTNG_TRACE_CHUNK_COMMAND_TYPE_DELETE: + return "delete"; default: abort(); }