trace-chunk: implement no-op and delete release commands
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Thu, 12 Dec 2019 18:05:15 +0000 (13:05 -0500)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Thu, 19 Dec 2019 23:42:37 +0000 (18:42 -0500)
The delete release command is used by clear. The no-op command is used
for implicit session rotations launched by the destroy command.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Change-Id: I49ea666ff77d3e5f6ac4b25977313ea18e10be62
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
src/common/trace-chunk-registry.h
src/common/trace-chunk.c

index afe942ba913d46d19f32f3ca1dc1d175a8fabad3..b04609c32bbe55c8a519fc79b8ee0ed5ea9e1c5f 100644 (file)
@@ -107,6 +107,6 @@ lttng_trace_chunk_registry_find_anonymous_chunk(
 
 LTTNG_HIDDEN
 unsigned int lttng_trace_chunk_registry_put_each_chunk(
-               struct lttng_trace_chunk_registry *registry);
+               const struct lttng_trace_chunk_registry *registry);
 
 #endif /* LTTNG_TRACE_CHUNK_REGISTRY_H */
index 266a02ee68e3933ea2533c70572c714098c4df45..cd81909ffc70ee6a36e464ae2d134e2dfbdd9cc9 100644 (file)
@@ -60,6 +60,12 @@ typedef int (*chunk_command)(struct lttng_trace_chunk *trace_chunk);
 /* Move a completed trace chunk to the 'completed' trace archive folder. */
 static
 int lttng_trace_chunk_move_to_completed_post_release(struct lttng_trace_chunk *trace_chunk);
+/* Empty callback. */
+static
+int lttng_trace_chunk_no_operation(struct lttng_trace_chunk *trace_chunk);
+/* Unlink old chunk files. */
+static
+int lttng_trace_chunk_delete_post_release(struct lttng_trace_chunk *trace_chunk);
 static
 enum lttng_trace_chunk_status lttng_trace_chunk_rename_path_no_lock(
                struct lttng_trace_chunk *chunk, const char *path);
@@ -135,6 +141,10 @@ static const
 chunk_command close_command_post_release_funcs[] = {
        [LTTNG_TRACE_CHUNK_COMMAND_TYPE_MOVE_TO_COMPLETED] =
                        lttng_trace_chunk_move_to_completed_post_release,
+       [LTTNG_TRACE_CHUNK_COMMAND_TYPE_NO_OPERATION] =
+                       lttng_trace_chunk_no_operation,
+       [LTTNG_TRACE_CHUNK_COMMAND_TYPE_DELETE] =
+                       lttng_trace_chunk_delete_post_release,
 };
 
 static
@@ -1398,6 +1408,117 @@ end:
        return ret;
 }
 
+static
+int lttng_trace_chunk_no_operation(struct lttng_trace_chunk *trace_chunk)
+{
+       return 0;
+}
+
+static
+int lttng_trace_chunk_delete_post_release_user(
+               struct lttng_trace_chunk *trace_chunk)
+{
+       int ret = 0;
+
+       DBG("Trace chunk \"delete\" close command post-release (User)");
+
+       /* Unlink all files. */
+       while (lttng_dynamic_pointer_array_get_count(&trace_chunk->files) != 0) {
+               enum lttng_trace_chunk_status status;
+               const char *path;
+
+               /* Remove first. */
+               path = lttng_dynamic_pointer_array_get_pointer(
+                               &trace_chunk->files, 0);
+               DBG("Unlink file: %s", path);
+               status = lttng_trace_chunk_unlink_file(trace_chunk, path);
+               if (status != LTTNG_TRACE_CHUNK_STATUS_OK) {
+                       ERR("Error unlinking file '%s' when deleting chunk", path);
+                       ret = -1;
+                       goto end;
+               }
+       }
+end:
+       return ret;
+}
+
+static
+int lttng_trace_chunk_delete_post_release_owner(
+               struct lttng_trace_chunk *trace_chunk)
+{
+       enum lttng_trace_chunk_status status;
+       size_t i, count;
+       int ret = 0;
+
+       ret = lttng_trace_chunk_delete_post_release_user(trace_chunk);
+       if (ret) {
+               goto end;
+       }
+
+       DBG("Trace chunk \"delete\" close command post-release (Owner)");
+
+       assert(trace_chunk->session_output_directory);
+       assert(trace_chunk->chunk_directory);
+
+       /* Remove empty directories. */
+       count = lttng_dynamic_pointer_array_get_count(
+                       &trace_chunk->top_level_directories);
+
+       for (i = 0; i < count; i++) {
+               const char *top_level_name =
+                               lttng_dynamic_pointer_array_get_pointer(
+                                       &trace_chunk->top_level_directories, i);
+
+               status = lttng_trace_chunk_remove_subdirectory_recursive(trace_chunk, top_level_name);
+               if (status != LTTNG_TRACE_CHUNK_STATUS_OK) {
+                       ERR("Error recursively removing subdirectory '%s' file when deleting chunk",
+                                       top_level_name);
+                       ret = -1;
+                       break;
+               }
+       }
+       if (!ret) {
+               lttng_directory_handle_put(trace_chunk->chunk_directory);
+               trace_chunk->chunk_directory = NULL;
+
+               if (trace_chunk->path && trace_chunk->path[0] != '\0') {
+                       status = lttng_directory_handle_remove_subdirectory(
+                                       trace_chunk->session_output_directory,
+                                       trace_chunk->path);
+                       if (status != LTTNG_TRACE_CHUNK_STATUS_OK) {
+                               ERR("Error removing subdirectory '%s' file when deleting chunk",
+                                       trace_chunk->path);
+                               ret = -1;
+                       }
+               }
+       }
+       free(trace_chunk->path);
+       trace_chunk->path = NULL;
+end:
+       return ret;
+}
+
+/*
+ * For local files, session and consumer daemons all run the delete hook. The
+ * consumer daemons have the list of files to unlink, and technically the
+ * session daemon is the owner of the chunk. Unlink all files owned by each
+ * consumer daemon.
+ */
+static
+int lttng_trace_chunk_delete_post_release(
+               struct lttng_trace_chunk *trace_chunk)
+{
+       if (!trace_chunk->chunk_directory) {
+               return 0;
+       }
+
+       if (trace_chunk->mode.value == TRACE_CHUNK_MODE_OWNER) {
+               return lttng_trace_chunk_delete_post_release_owner(trace_chunk);
+       } else {
+               return lttng_trace_chunk_delete_post_release_user(trace_chunk);
+       }
+}
+
 LTTNG_HIDDEN
 enum lttng_trace_chunk_status lttng_trace_chunk_get_close_command(
                struct lttng_trace_chunk *chunk,
@@ -1787,8 +1908,9 @@ lttng_trace_chunk_registry_find_anonymous_chunk(
                        session_id, NULL);
 }
 
+LTTNG_HIDDEN
 unsigned int lttng_trace_chunk_registry_put_each_chunk(
-               struct lttng_trace_chunk_registry *registry)
+               const struct lttng_trace_chunk_registry *registry)
 {
        struct cds_lfht_iter iter;
        struct lttng_trace_chunk_registry_element *chunk_element;
This page took 0.028793 seconds and 4 git commands to generate.