X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=src%2Fcommon%2Ftrace-chunk.c;h=a183fbeb0ff18d6aa969d984685228c0691cc46e;hb=913a542b6eabb29468ab09a1503ed454427679f2;hp=451832fde245bbad1e35839f0a71e05f50454532;hpb=93bed9fe8f48c11b7bb1224db36d82404cea080d;p=lttng-tools.git diff --git a/src/common/trace-chunk.c b/src/common/trace-chunk.c index 451832fde..a183fbeb0 100644 --- a/src/common/trace-chunk.c +++ b/src/common/trace-chunk.c @@ -77,7 +77,7 @@ struct lttng_trace_chunk { struct lttng_dynamic_pointer_array top_level_directories; /* Is contained within an lttng_trace_chunk_registry_element? */ bool in_registry_element; - bool name_overriden; + bool name_overridden; char *name; /* An unset id means the chunk is anonymous. */ LTTNG_OPTIONAL(uint64_t) id; @@ -381,13 +381,13 @@ end: LTTNG_HIDDEN enum lttng_trace_chunk_status lttng_trace_chunk_get_name( struct lttng_trace_chunk *chunk, const char **name, - bool *name_overriden) + bool *name_overridden) { enum lttng_trace_chunk_status status = LTTNG_TRACE_CHUNK_STATUS_OK; pthread_mutex_lock(&chunk->lock); - if (name_overriden) { - *name_overriden = chunk->name_overriden; + if (name_overridden) { + *name_overridden = chunk->name_overridden; } if (!chunk->name) { status = LTTNG_TRACE_CHUNK_STATUS_NONE; @@ -399,6 +399,27 @@ end: return status; } +static +bool is_valid_chunk_name(const char *name) +{ + size_t len; + + if (!name) { + return false; + } + + len = strnlen(name, LTTNG_NAME_MAX); + if (len == 0 || len == LTTNG_NAME_MAX) { + return false; + } + + if (strchr(name, '/') || strchr(name, '.')) { + return false; + } + + return true; +} + LTTNG_HIDDEN enum lttng_trace_chunk_status lttng_trace_chunk_override_name( struct lttng_trace_chunk *chunk, const char *name) @@ -407,7 +428,7 @@ enum lttng_trace_chunk_status lttng_trace_chunk_override_name( char *new_name; enum lttng_trace_chunk_status status = LTTNG_TRACE_CHUNK_STATUS_OK; - if (!name || !*name || strnlen(name, LTTNG_NAME_MAX) == LTTNG_NAME_MAX) { + if (!is_valid_chunk_name(name)) { ERR("Attempted to set an invalid name on a trace chunk: name = %s", name ? : "NULL"); status = LTTNG_TRACE_CHUNK_STATUS_INVALID_ARGUMENT; @@ -429,7 +450,7 @@ enum lttng_trace_chunk_status lttng_trace_chunk_override_name( } free(chunk->name); chunk->name = new_name; - chunk->name_overriden = true; + chunk->name_overridden = true; end_unlock: pthread_mutex_unlock(&chunk->lock); end: @@ -800,19 +821,26 @@ void lttng_trace_chunk_move_to_completed(struct lttng_trace_chunk *trace_chunk) int ret; char *directory_to_rename = NULL; bool free_directory_to_rename = false; - const int session_dirfd = - trace_chunk->session_output_directory.value.dirfd; char *archived_chunk_name = NULL; const uint64_t chunk_id = LTTNG_OPTIONAL_GET(trace_chunk->id); const time_t creation_timestamp = LTTNG_OPTIONAL_GET(trace_chunk->timestamp_creation); const time_t close_timestamp = LTTNG_OPTIONAL_GET(trace_chunk->timestamp_close); - LTTNG_OPTIONAL(struct lttng_directory_handle) archived_chunks_directory; + LTTNG_OPTIONAL(struct lttng_directory_handle) archived_chunks_directory = {}; + + if (!trace_chunk->mode.is_set || + trace_chunk->mode.value != TRACE_CHUNK_MODE_OWNER || + !trace_chunk->session_output_directory.is_set) { + /* + * This command doesn't need to run if the output is remote + * or if the trace chunk is not owned by this process. + */ + goto end; + } - assert(trace_chunk->mode.is_set); assert(trace_chunk->mode.value == TRACE_CHUNK_MODE_OWNER); - assert(!trace_chunk->name_overriden); + assert(!trace_chunk->name_overridden); /* * The fist trace chunk of a session is directly output to the @@ -845,17 +873,18 @@ void lttng_trace_chunk_move_to_completed(struct lttng_trace_chunk *trace_chunk) } for (i = 0; i < count; i++) { - const int temp_dirfd = temporary_rename_directory.dirfd; const char *top_level_name = lttng_dynamic_pointer_array_get_pointer( &trace_chunk->top_level_directories, i); - /* - * FIXME replace renamat() use by directory handle - * wrapper for non-POSIX 2008 systems. - */ - ret = renameat(session_dirfd, top_level_name, - temp_dirfd, top_level_name); + ret = lttng_directory_handle_rename_as_user( + &trace_chunk->session_output_directory.value, + top_level_name, + &temporary_rename_directory, + top_level_name, + LTTNG_OPTIONAL_GET(trace_chunk->credentials).use_current_user ? + NULL : + &trace_chunk->credentials.value.user); if (ret) { PERROR("Failed to move \"%s\" to temporary trace chunk rename directory", top_level_name); @@ -906,13 +935,14 @@ void lttng_trace_chunk_move_to_completed(struct lttng_trace_chunk *trace_chunk) } archived_chunks_directory.is_set = true; - /* - * FIXME replace renamat() use by directory handle - * wrapper for non-POSIX 2008 systems. - */ - ret = renameat(session_dirfd, directory_to_rename, - archived_chunks_directory.value.dirfd, - archived_chunk_name); + ret = lttng_directory_handle_rename_as_user( + &trace_chunk->session_output_directory.value, + directory_to_rename, + &archived_chunks_directory.value, + archived_chunk_name, + LTTNG_OPTIONAL_GET(trace_chunk->credentials).use_current_user ? + NULL : + &trace_chunk->credentials.value.user); if (ret) { PERROR("Failed to rename folder \"%s\" to \"%s\"", directory_to_rename, archived_chunk_name); @@ -928,6 +958,24 @@ end: } } +LTTNG_HIDDEN +enum lttng_trace_chunk_status lttng_trace_chunk_get_close_command( + struct lttng_trace_chunk *chunk, + enum lttng_trace_chunk_command_type *command_type) +{ + enum lttng_trace_chunk_status status = LTTNG_TRACE_CHUNK_STATUS_OK; + + pthread_mutex_lock(&chunk->lock); + if (chunk->close_command.is_set) { + *command_type = chunk->close_command.value; + status = LTTNG_TRACE_CHUNK_STATUS_OK; + } else { + status = LTTNG_TRACE_CHUNK_STATUS_NONE; + } + pthread_mutex_unlock(&chunk->lock); + return status; +} + LTTNG_HIDDEN enum lttng_trace_chunk_status lttng_trace_chunk_set_close_command( struct lttng_trace_chunk *chunk, @@ -956,6 +1004,18 @@ end_unlock: return status; } +LTTNG_HIDDEN +const char *lttng_trace_chunk_command_type_get_name( + enum lttng_trace_chunk_command_type command) +{ + switch (command) { + case LTTNG_TRACE_CHUNK_COMMAND_TYPE_MOVE_TO_COMPLETED: + return "move to completed trace chunk folder"; + default: + abort(); + } +} + LTTNG_HIDDEN bool lttng_trace_chunk_get(struct lttng_trace_chunk *chunk) {