Save/load: support session trace format
[lttng-tools.git] / src / bin / lttng-sessiond / cmd.cpp
index 214085c55a29bd11c4f548db101eb64e6c488989..94edb6368637eb625497819ac27eff4e5d246221 100644 (file)
@@ -951,7 +951,9 @@ static lttng_error_code send_consumer_relayd_sockets(const ltt_session& session,
                consumer->relay_major_version = control_sock->major;
                consumer->relay_minor_version = control_sock->minor;
 
-               ret = relayd_get_configuration(control_sock, 0, result_flags, nullptr);
+               ret = relayd_get_configuration(control_sock,
+                               LTTCOMM_RELAYD_CONFIGURATION_QUERY_FLAG_SUPPORTED_TRACE_FORMAT,
+                               result_flags, &supported_trace_format);
                if (ret < 0) {
                        ERR("Unable to get relayd configuration");
                        status = LTTNG_ERR_RELAYD_CONNECT_FAIL;
@@ -6063,6 +6065,132 @@ end:
        return ret;
 }
 
+enum lttng_error_code cmd_execute_trace_format_support_query(
+               struct command_ctx& cmd_ctx, int sock, int& sock_error)
+{
+       int ret;
+       enum lttng_error_code ret_code;
+       struct lttng_payload query_payload;
+       size_t payload_len, offset = 0;
+       ssize_t sock_recv_len, consumed;
+
+       lttng::trace_format_descriptor::uptr trace_format;
+
+       lttng_payload_init(&query_payload);
+
+       /* Receive the payload */
+       payload_len = (size_t) cmd_ctx.lsm.u.trace_format_support_query.trace_format_length +
+                       cmd_ctx.lsm.u.trace_format_support_query.type_payload_length;
+       ret = lttng_dynamic_buffer_set_size(&query_payload.buffer, payload_len);
+       if (ret) {
+               ret_code = LTTNG_ERR_NOMEM;
+       }
+
+       sock_recv_len = lttcomm_recv_unix_sock(sock, query_payload.buffer.data, payload_len);
+       if (sock_recv_len < 0 || sock_recv_len != payload_len) {
+               ERR("Failed to receive error query in command payload");
+               sock_error = 1;
+               ret_code = LTTNG_ERR_INVALID_PROTOCOL;
+               goto end;
+       }
+
+       /* Receive fds, if any. */
+       if (cmd_ctx.lsm.fd_count > 0) {
+               sock_recv_len = lttcomm_recv_payload_fds_unix_sock(
+                               sock, cmd_ctx.lsm.fd_count, &query_payload);
+               if (sock_recv_len > 0 && sock_recv_len != cmd_ctx.lsm.fd_count * sizeof(int)) {
+                       ERR("Failed to receive all file descriptors for error query in command payload: expected fd count = %u, ret = %d",
+                                       cmd_ctx.lsm.fd_count, (int) ret);
+                       ret_code = LTTNG_ERR_INVALID_PROTOCOL;
+                       sock_error = 1;
+                       goto end;
+               } else if (sock_recv_len <= 0) {
+                       ERR("Failed to receive file descriptors for error query in command payload: expected fd count = %u, ret = %d",
+                                       cmd_ctx.lsm.fd_count, (int) ret);
+                       ret_code = LTTNG_ERR_FATAL;
+                       sock_error = 1;
+                       goto end;
+               }
+       }
+
+       /* Deserialize trace_format_descriptor. */
+       {
+               struct lttng_payload_view view =
+                               lttng_payload_view_from_payload(&query_payload, offset, -1);
+               if (!lttng_payload_view_is_valid(&view)) {
+                       ret = LTTNG_ERR_INVALID_PROTOCOL;
+                       goto end;
+               }
+
+               consumed = lttng::trace_format_descriptor::create_from_payload(&view, trace_format);
+
+               if (consumed != cmd_ctx.lsm.u.trace_format_support_query.trace_format_length) {
+                       ERR("Invalid trace format descriptor received as part of command payload");
+                       ret_code = LTTNG_ERR_INVALID_PROTOCOL;
+                       goto end;
+               }
+               offset += consumed;
+       }
+
+       switch (cmd_ctx.lsm.u.trace_format_support_query.query_type) {
+       case 0:
+       {
+               if (cmd_ctx.lsm.domain.type != LTTNG_DOMAIN_KERNEL) {
+                       /* UST supports all trace format*/
+                       ret_code = LTTNG_OK;
+                       goto end;
+               }
+               ret_code = kernel_domain_check_trace_format_requirements(*trace_format);
+               break;
+       }
+       case 1:
+       {
+               struct lttcomm_relayd_sock *relay_sock = nullptr;
+               struct lttng_uri uri;
+               uint64_t result_flags = 0;
+               uint64_t supported_trace_format = 0;
+               struct lttng_payload_view view = lttng_payload_view_from_payload(&query_payload,
+                               offset,
+                               cmd_ctx.lsm.u.trace_format_support_query.type_payload_length);
+               if (!lttng_payload_view_is_valid(&view)) {
+                       ret_code = LTTNG_ERR_INVALID_PROTOCOL;
+                       goto end;
+               }
+
+               memcpy(&uri, view.buffer.data, sizeof(uri));
+               ret_code = create_connect_relayd(&uri, &relay_sock);
+               if (ret_code != LTTNG_OK) {
+                       goto end;
+               }
+               LTTNG_ASSERT(sock);
+
+               ret_code = relayd_get_configuration(relay_sock,
+                               LTTCOMM_RELAYD_CONFIGURATION_QUERY_FLAG_SUPPORTED_TRACE_FORMAT,
+                               result_flags, &supported_trace_format);
+               if (ret_code != LTTNG_OK) {
+                       goto end;
+               }
+
+               if (!(supported_trace_format & trace_format->relayd_type())) {
+                       ERR("Relayd does not support the requested trace format");
+                       ret_code = LTTNG_ERR_TRACE_FORMAT_UNSUPPORTED_RELAY_DAEMON;
+                       goto end;
+               }
+
+               ret_code = LTTNG_OK;
+               break;
+       }
+       default:
+       {
+               ret_code = LTTNG_ERR_INVALID_PROTOCOL;
+               break;
+       }
+       }
+end:
+       lttng_payload_reset(&query_payload);
+       return ret_code;
+}
+
 /* Wait for a given path to be removed before continuing. */
 static enum lttng_error_code wait_on_path(void *path_data)
 {
This page took 0.027902 seconds and 5 git commands to generate.