Fix: trace chunk reported unknown before close command execution
[lttng-tools.git] / src / bin / lttng-relayd / main.c
index 453bf6d20fa5625f04d76a3da2eacd87702c62db..5b32341cd9ff4cb2647caa3557536326188dcf47 100644 (file)
@@ -40,6 +40,7 @@
 #include <urcu/rculist.h>
 #include <unistd.h>
 #include <fcntl.h>
+#include <strings.h>
 
 #include <lttng/lttng.h>
 #include <common/common.h>
@@ -1156,21 +1157,24 @@ send_reply:
                }
        } else {
                const uint32_t output_path_length =
-                               strlen(session->output_path) + 1;
+                               session ? strlen(session->output_path) + 1 : 0;
 
                reply.output_path_length = htobe32(output_path_length);
-               ret = lttng_dynamic_buffer_append(&reply_payload, &reply,
-                               sizeof(reply));
+               ret = lttng_dynamic_buffer_append(
+                               &reply_payload, &reply, sizeof(reply));
                if (ret) {
                        ERR("Failed to append \"create session\" command reply header to payload buffer");
                        goto end;
                }
 
-               ret = lttng_dynamic_buffer_append(&reply_payload,
-                               session->output_path, output_path_length);
-               if (ret) {
-                       ERR("Failed to append \"create session\" command reply path to payload buffer");
-                       goto end;
+               if (output_path_length) {
+                       ret = lttng_dynamic_buffer_append(&reply_payload,
+                                       session->output_path,
+                                       output_path_length);
+                       if (ret) {
+                               ERR("Failed to append \"create session\" command reply path to payload buffer");
+                               goto end;
+                       }
                }
        }
 
@@ -2278,6 +2282,7 @@ static int relay_rotate_session_streams(
        }
 
        reply_code = LTTNG_OK;
+       ret = 0;
 end:
        if (stream) {
                stream_put(stream);
@@ -2291,8 +2296,6 @@ end:
                                send_ret);
                ret = -1;
        }
-
-       ret = 0;
 end_no_reply:
        lttng_trace_chunk_put(next_trace_chunk);
        return ret;
@@ -2385,13 +2388,6 @@ static int relay_create_trace_chunk(const struct lttcomm_relayd_hdr *recv_hdr,
                }
        }
 
-       ret = session_init_output_directory_handle(
-                       conn->session, &session_output);
-       if (ret) {
-               reply_code = LTTNG_ERR_CREATE_DIR_FAIL;
-               goto end;
-       }
-
        chunk_status = lttng_trace_chunk_set_credentials_current_user(chunk);
        if (chunk_status != LTTNG_TRACE_CHUNK_STATUS_OK) {
                reply_code = LTTNG_ERR_UNK;
@@ -2399,7 +2395,14 @@ static int relay_create_trace_chunk(const struct lttcomm_relayd_hdr *recv_hdr,
                goto end;
        }
 
+       ret = session_init_output_directory_handle(
+                       conn->session, &session_output);
+       if (ret) {
+               reply_code = LTTNG_ERR_CREATE_DIR_FAIL;
+               goto end;
+       }
        chunk_status = lttng_trace_chunk_set_as_owner(chunk, &session_output);
+       lttng_directory_handle_fini(&session_output);
        if (chunk_status != LTTNG_TRACE_CHUNK_STATUS_OK) {
                reply_code = LTTNG_ERR_UNK;
                ret = -1;
@@ -2455,7 +2458,6 @@ end:
 end_no_reply:
        lttng_trace_chunk_put(chunk);
        lttng_trace_chunk_put(published_chunk);
-       lttng_directory_handle_fini(&session_output);
        return ret;
 }
 
@@ -2466,7 +2468,7 @@ static int relay_close_trace_chunk(const struct lttcomm_relayd_hdr *recv_hdr,
                struct relay_connection *conn,
                const struct lttng_buffer_view *payload)
 {
-       int ret = 0;
+       int ret = 0, buf_ret;
        ssize_t send_ret;
        struct relay_session *session = conn->session;
        struct lttcomm_relayd_close_trace_chunk *msg;
@@ -2627,17 +2629,17 @@ end_unlock_session:
 end:
        reply.generic.ret_code = htobe32((uint32_t) reply_code);
        reply.path_length = htobe32((uint32_t) path_length);
-       ret = lttng_dynamic_buffer_append(
+       buf_ret = lttng_dynamic_buffer_append(
                        &reply_payload, &reply, sizeof(reply));
-       if (ret) {
+       if (buf_ret) {
                ERR("Failed to append \"close trace chunk\" command reply header to payload buffer");
                goto end_no_reply;
        }
 
        if (reply_code == LTTNG_OK) {
-               ret = lttng_dynamic_buffer_append(&reply_payload,
+               buf_ret = lttng_dynamic_buffer_append(&reply_payload,
                                closed_trace_chunk_path, path_length);
-               if (ret) {
+               if (buf_ret) {
                        ERR("Failed to append \"close trace chunk\" command reply path to payload buffer");
                        goto end_no_reply;
                }
@@ -2672,8 +2674,8 @@ static int relay_trace_chunk_exists(const struct lttcomm_relayd_hdr *recv_hdr,
        struct lttcomm_relayd_trace_chunk_exists *msg;
        struct lttcomm_relayd_trace_chunk_exists_reply reply = {};
        struct lttng_buffer_view header_view;
-       struct lttng_trace_chunk *chunk = NULL;
        uint64_t chunk_id;
+       bool chunk_exists;
 
        if (!session || !conn->version_check_done) {
                ERR("Trying to close a trace chunk before version check");
@@ -2698,25 +2700,29 @@ static int relay_trace_chunk_exists(const struct lttcomm_relayd_hdr *recv_hdr,
        msg = (typeof(msg)) header_view.data;
        chunk_id = be64toh(msg->chunk_id);
 
-       chunk = sessiond_trace_chunk_registry_get_chunk(
+       ret = sessiond_trace_chunk_registry_chunk_exists(
                        sessiond_trace_chunk_registry,
                        conn->session->sessiond_uuid,
                        conn->session->id,
-                       chunk_id);
-
-       reply = (typeof(reply)) {
-               .generic.ret_code = htobe32((uint32_t) LTTNG_OK),
-               .trace_chunk_exists = !!chunk,
+                       chunk_id, &chunk_exists);
+       /*
+        * If ret is not 0, send the reply and report the error to the caller.
+        * It is a protocol (or internal) error and the session/connection
+        * should be torn down.
+        */
+       reply = (typeof(reply)){
+               .generic.ret_code = htobe32((uint32_t)
+                       (ret == 0 ? LTTNG_OK : LTTNG_ERR_INVALID_PROTOCOL)),
+               .trace_chunk_exists = ret == 0 ? chunk_exists : 0,
        };
-       send_ret = conn->sock->ops->sendmsg(conn->sock,
-                       &reply, sizeof(reply), 0);
+       send_ret = conn->sock->ops->sendmsg(
+                       conn->sock, &reply, sizeof(reply), 0);
        if (send_ret < (ssize_t) sizeof(reply)) {
                ERR("Failed to send \"create trace chunk\" command reply (ret = %zd)",
                                send_ret);
                ret = -1;
        }
 end_no_reply:
-       lttng_trace_chunk_put(chunk);
        return ret;
 }
 
This page took 0.026797 seconds and 5 git commands to generate.