Fix: validate that session, host and basepath are legal
[lttng-tools.git] / src / common / trace-chunk.c
index 26c7ce07d3486be1a4101920f100653dc2e19b03..a183fbeb0ff18d6aa969d984685228c0691cc46e 100644 (file)
@@ -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:
@@ -806,11 +827,20 @@ void lttng_trace_chunk_move_to_completed(struct lttng_trace_chunk *trace_chunk)
                        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
@@ -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.030787 seconds and 4 git commands to generate.