Fix: liblttng-ctl comm: lttng_channel is not packed
[lttng-tools.git] / src / bin / lttng-sessiond / client.c
index c9ff2ec70fa635ff6de188ef12bd70361be6e512..bdc5680ee662c18c8f6e19641264bc8fbd4160b2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 David Goulet <david.goulet@polymtl.ca>
+ * Copyright (C) 2011 EfficiOS Inc.
  * Copyright (C) 2011 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
  * Copyright (C) 2013 Jérémie Galarneau <jeremie.galarneau@efficios.com>
  *
@@ -9,20 +9,19 @@
 
 #include "common/buffer-view.h"
 #include "common/compat/socket.h"
-#include "common/dynamic-buffer.h"
 #include "common/dynamic-array.h"
-#include "common/payload.h"
-#include "common/payload-view.h"
+#include "common/dynamic-buffer.h"
 #include "common/fd-handle.h"
-#include "common/sessiond-comm/sessiond-comm.h"
-#include "common/payload.h"
 #include "common/payload-view.h"
+#include "common/payload.h"
+#include "common/sessiond-comm/sessiond-comm.h"
 #include "lttng/lttng-error.h"
 #include "lttng/tracker.h"
 #include <common/compat/getenv.h>
 #include <common/tracker.h>
 #include <common/unix.h>
 #include <common/utils.h>
+#include <lttng/error-query-internal.h>
 #include <lttng/event-internal.h>
 #include <lttng/session-descriptor-internal.h>
 #include <lttng/session-internal.h>
 #include <pthread.h>
 #include <signal.h>
 #include <stddef.h>
+#include <stdint.h>
 #include <sys/stat.h>
 #include <unistd.h>
 
+#include "agent-thread.h"
+#include "clear.h"
 #include "client.h"
-#include "lttng-sessiond.h"
 #include "cmd.h"
+#include "health-sessiond.h"
 #include "kernel.h"
+#include "lttng-sessiond.h"
+#include "manage-consumer.h"
 #include "save.h"
-#include "health-sessiond.h"
 #include "testpoint.h"
 #include "utils.h"
-#include "manage-consumer.h"
-#include "clear.h"
-#include "agent-thread.h"
 
 static bool is_root;
 
@@ -776,6 +776,78 @@ static enum lttng_error_code receive_lttng_trigger(struct command_ctx *cmd_ctx,
        ret_code = LTTNG_OK;
 
 end:
+       lttng_payload_reset(&trigger_payload);
+       return ret_code;
+}
+
+static enum lttng_error_code receive_lttng_error_query(struct command_ctx *cmd_ctx,
+               int sock,
+               int *sock_error,
+               struct lttng_error_query **_query)
+{
+       int ret;
+       size_t query_len;
+       ssize_t sock_recv_len;
+       enum lttng_error_code ret_code;
+       struct lttng_payload query_payload;
+       struct lttng_error_query *query = NULL;
+
+       lttng_payload_init(&query_payload);
+       query_len = (size_t) cmd_ctx->lsm.u.error_query.length;
+       ret = lttng_dynamic_buffer_set_size(&query_payload.buffer, query_len);
+       if (ret) {
+               ret_code = LTTNG_ERR_NOMEM;
+               goto end;
+       }
+
+       sock_recv_len = lttcomm_recv_unix_sock(
+                       sock, query_payload.buffer.data, query_len);
+       if (sock_recv_len < 0 || sock_recv_len != query_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 error query. */
+       {
+               struct lttng_payload_view view =
+                               lttng_payload_view_from_payload(
+                                               &query_payload, 0, -1);
+
+               if (lttng_error_query_create_from_payload(&view, &query) !=
+                               query_len) {
+                       ERR("Invalid error query received as part of command payload");
+                       ret_code = LTTNG_ERR_INVALID_PROTOCOL;
+                       goto end;
+               }
+       }
+
+       *_query = query;
+       ret_code = LTTNG_OK;
+
+end:
+       lttng_payload_reset(&query_payload);
        return ret_code;
 }
 
@@ -889,6 +961,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx, int *sock,
        case LTTNG_SESSION_LIST_ROTATION_SCHEDULES:
        case LTTNG_CLEAR_SESSION:
        case LTTNG_LIST_TRIGGERS:
+       case LTTNG_EXECUTE_ERROR_QUERY:
                need_domain = false;
                break;
        default:
@@ -899,6 +972,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx, int *sock,
        switch (cmd_ctx->lsm.cmd_type) {
        case LTTNG_REGISTER_TRIGGER:
        case LTTNG_UNREGISTER_TRIGGER:
+       case LTTNG_EXECUTE_ERROR_QUERY:
                need_consumerd = false;
                break;
        default:
@@ -948,6 +1022,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx, int *sock,
        case LTTNG_ROTATION_GET_INFO:
        case LTTNG_REGISTER_TRIGGER:
        case LTTNG_LIST_TRIGGERS:
+       case LTTNG_EXECUTE_ERROR_QUERY:
                break;
        default:
                /* Setup lttng message with no payload */
@@ -969,6 +1044,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx, int *sock,
        case LTTNG_REGISTER_TRIGGER:
        case LTTNG_UNREGISTER_TRIGGER:
        case LTTNG_LIST_TRIGGERS:
+       case LTTNG_EXECUTE_ERROR_QUERY:
                need_tracing_session = false;
                break;
        default:
@@ -1360,12 +1436,8 @@ error_add_context:
        }
        case LTTNG_ENABLE_CHANNEL:
        {
-               cmd_ctx->lsm.u.channel.chan.attr.extended.ptr =
-                               (struct lttng_channel_extended *) &cmd_ctx->lsm.u.channel.extended;
-               ret = cmd_enable_channel(cmd_ctx->session,
-                               ALIGNED_CONST_PTR(cmd_ctx->lsm.domain),
-                               ALIGNED_CONST_PTR(cmd_ctx->lsm.u.channel.chan),
-                               the_kernel_poll_pipe[1]);
+               ret = cmd_enable_channel(
+                               cmd_ctx, *sock, the_kernel_poll_pipe[1]);
                break;
        }
        case LTTNG_PROCESS_ATTR_TRACKER_ADD_INCLUDE_VALUE:
@@ -1883,25 +1955,30 @@ error_add_context:
        }
        case LTTNG_LIST_CHANNELS:
        {
-               ssize_t payload_size;
-               struct lttng_channel *channels = NULL;
+               enum lttng_error_code ret_code;
+               size_t original_payload_size;
+               size_t payload_size;
+               const size_t command_header_size = sizeof(struct lttcomm_list_command_header);
 
-               payload_size = cmd_list_channels(cmd_ctx->lsm.domain.type,
-                               cmd_ctx->session, &channels);
-               if (payload_size < 0) {
-                       /* Return value is a negative lttng_error_code. */
-                       ret = -payload_size;
-                       goto error;
+               ret = setup_empty_lttng_msg(cmd_ctx);
+               if (ret) {
+                       ret = LTTNG_ERR_NOMEM;
+                       goto setup_error;
                }
 
-               ret = setup_lttng_msg_no_cmd_header(cmd_ctx, channels,
-                       payload_size);
-               free(channels);
+               original_payload_size = cmd_ctx->reply_payload.buffer.size;
 
-               if (ret < 0) {
-                       goto setup_error;
+               ret_code = cmd_list_channels(cmd_ctx->lsm.domain.type,
+                               cmd_ctx->session, &cmd_ctx->reply_payload);
+               if (ret_code != LTTNG_OK) {
+                       ret = (int) ret_code;
+                       goto error;
                }
 
+               payload_size = cmd_ctx->reply_payload.buffer.size -
+                               command_header_size - original_payload_size;
+               update_lttng_msg(cmd_ctx, command_header_size, payload_size);
+
                ret = LTTNG_OK;
                break;
        }
@@ -2172,6 +2249,7 @@ error_add_context:
                original_reply_payload_size = cmd_ctx->reply_payload.buffer.size;
 
                ret = cmd_register_trigger(&cmd_creds, payload_trigger,
+                               cmd_ctx->lsm.u.trigger.is_trigger_anonymous,
                                the_notification_thread_handle,
                                &return_trigger);
                if (ret != LTTNG_OK) {
@@ -2355,6 +2433,57 @@ error_add_context:
                ret = LTTNG_OK;
                break;
        }
+       case LTTNG_EXECUTE_ERROR_QUERY:
+       {
+               struct lttng_error_query *query;
+               const struct lttng_credentials cmd_creds = {
+                       .uid = LTTNG_OPTIONAL_INIT_VALUE(cmd_ctx->creds.uid),
+                       .gid = LTTNG_OPTIONAL_INIT_VALUE(cmd_ctx->creds.gid),
+               };
+               struct lttng_error_query_results *results = NULL;
+               size_t original_payload_size;
+               size_t payload_size;
+
+               ret = setup_empty_lttng_msg(cmd_ctx);
+               if (ret) {
+                       ret = LTTNG_ERR_NOMEM;
+                       goto setup_error;
+               }
+
+               original_payload_size = cmd_ctx->reply_payload.buffer.size;
+
+               ret = receive_lttng_error_query(
+                               cmd_ctx, *sock, sock_error, &query);
+               if (ret != LTTNG_OK) {
+                       goto error;
+               }
+
+               ret = cmd_execute_error_query(&cmd_creds, query, &results,
+                               the_notification_thread_handle);
+               lttng_error_query_destroy(query);
+               if (ret != LTTNG_OK) {
+                       goto error;
+               }
+
+               assert(results);
+               ret = lttng_error_query_results_serialize(
+                               results, &cmd_ctx->reply_payload);
+               lttng_error_query_results_destroy(results);
+               if (ret) {
+                       ERR("Failed to serialize error query result set in reply to `execute error query` command");
+                       ret = LTTNG_ERR_NOMEM;
+                       goto error;
+               }
+
+               payload_size = cmd_ctx->reply_payload.buffer.size -
+                       original_payload_size;
+
+               update_lttng_msg(cmd_ctx, 0, payload_size);
+
+               ret = LTTNG_OK;
+
+               break;
+       }
        default:
                ret = LTTNG_ERR_UND;
                break;
This page took 0.028826 seconds and 4 git commands to generate.