relayd: add remote trace chunk close command
[lttng-tools.git] / src / common / trace-chunk.c
index 451832fde245bbad1e35839f0a71e05f50454532..3f472b4353bc44aa8de15be627878640f96fca6c 100644 (file)
@@ -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;
@@ -800,8 +821,6 @@ 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 =
@@ -810,7 +829,16 @@ void lttng_trace_chunk_move_to_completed(struct lttng_trace_chunk *trace_chunk)
                        LTTNG_OPTIONAL_GET(trace_chunk->timestamp_close);
        LTTNG_OPTIONAL(struct lttng_directory_handle) archived_chunks_directory;
 
-       assert(trace_chunk->mode.is_set);
+       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.value == TRACE_CHUNK_MODE_OWNER);
        assert(!trace_chunk->name_overriden);
 
@@ -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)
 {
This page took 0.025593 seconds and 4 git commands to generate.