X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fclient.c;h=00b5ec7e4ab7bb4db6a67c0c32855d2e77236162;hp=3ccc29efceaf335a71ce0bc3c5d705aaefd90619;hb=b5ef16855f9c69315d9530730200890dbbebad24;hpb=9124c6304bba12b0d4424b4071a25a34445ff4da diff --git a/src/bin/lttng-sessiond/client.c b/src/bin/lttng-sessiond/client.c index 3ccc29efc..00b5ec7e4 100644 --- a/src/bin/lttng-sessiond/client.c +++ b/src/bin/lttng-sessiond/client.c @@ -43,6 +43,7 @@ #include "utils.h" #include "manage-consumer.h" #include "clear.h" +#include "agent-thread.h" static bool is_root; @@ -694,6 +695,78 @@ error: return ret; } +static enum lttng_error_code receive_lttng_trigger(struct command_ctx *cmd_ctx, + int sock, + int *sock_error, + struct lttng_trigger **_trigger) +{ + int ret; + size_t trigger_len; + ssize_t sock_recv_len; + enum lttng_error_code ret_code; + struct lttng_payload trigger_payload; + struct lttng_trigger *trigger = NULL; + + lttng_payload_init(&trigger_payload); + trigger_len = (size_t) cmd_ctx->lsm.u.trigger.length; + ret = lttng_dynamic_buffer_set_size( + &trigger_payload.buffer, trigger_len); + if (ret) { + ret_code = LTTNG_ERR_NOMEM; + goto end; + } + + sock_recv_len = lttcomm_recv_unix_sock( + sock, trigger_payload.buffer.data, trigger_len); + if (sock_recv_len < 0 || sock_recv_len != trigger_len) { + ERR("Failed to receive trigger 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, &trigger_payload); + if (sock_recv_len > 0 && + sock_recv_len != cmd_ctx->lsm.fd_count * sizeof(int)) { + ERR("Failed to receive all file descriptors for trigger 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 trigger 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 trigger. */ + { + struct lttng_payload_view view = + lttng_payload_view_from_payload( + &trigger_payload, 0, -1); + + if (lttng_trigger_create_from_payload(&view, &trigger) != + trigger_len) { + ERR("Invalid trigger received as part of command payload"); + ret_code = LTTNG_ERR_INVALID_TRIGGER; + lttng_trigger_put(trigger); + goto end; + } + } + + *_trigger = trigger; + ret_code = LTTNG_OK; + +end: + return ret_code; +} + /* * Version of setup_lttng_msg() without command header. */ @@ -773,7 +846,9 @@ static int process_client_msg(struct command_ctx *cmd_ctx, int *sock, bool need_domain; bool need_consumerd; - DBG("Processing client command %d", cmd_ctx->lsm.cmd_type); + DBG("Processing client command '%s\' (%d)", + lttcomm_sessiond_command_str(cmd_ctx->lsm.cmd_type), + cmd_ctx->lsm.cmd_type); assert(!rcu_read_ongoing()); @@ -1005,6 +1080,11 @@ static int process_client_msg(struct command_ctx *cmd_ctx, int *sock, case LTTNG_DOMAIN_JUL: case LTTNG_DOMAIN_LOG4J: case LTTNG_DOMAIN_PYTHON: + if (!agent_tracing_is_enabled()) { + ret = LTTNG_ERR_AGENT_TRACING_DISABLED; + goto error; + } + /* Fallthrough */ case LTTNG_DOMAIN_UST: { if (!ust_app_supported()) { @@ -2055,9 +2135,14 @@ error_add_context: } case LTTNG_REGISTER_TRIGGER: { + struct lttng_trigger *payload_trigger; struct lttng_trigger *return_trigger; - size_t original_payload_size; - size_t payload_size; + size_t original_reply_payload_size; + size_t reply_payload_size; + const struct lttng_credentials cmd_creds = { + .uid = LTTNG_OPTIONAL_INIT_VALUE(cmd_ctx->creds.uid), + .gid = LTTNG_OPTIONAL_INIT_VALUE(cmd_ctx->creds.gid), + }; ret = setup_empty_lttng_msg(cmd_ctx); if (ret) { @@ -2065,37 +2150,55 @@ error_add_context: goto setup_error; } - original_payload_size = cmd_ctx->reply_payload.buffer.size; + ret = receive_lttng_trigger( + cmd_ctx, *sock, sock_error, &payload_trigger); + if (ret != LTTNG_OK) { + goto error; + } + + original_reply_payload_size = cmd_ctx->reply_payload.buffer.size; - ret = cmd_register_trigger(cmd_ctx, *sock, + ret = cmd_register_trigger(&cmd_creds, payload_trigger, notification_thread_handle, &return_trigger); if (ret != LTTNG_OK) { + lttng_trigger_put(payload_trigger); goto error; } ret = lttng_trigger_serialize(return_trigger, &cmd_ctx->reply_payload); + lttng_trigger_put(payload_trigger); + lttng_trigger_put(return_trigger); if (ret) { ERR("Failed to serialize trigger in reply to \"register trigger\" command"); ret = LTTNG_ERR_NOMEM; - lttng_trigger_destroy(return_trigger); goto error; } - lttng_trigger_destroy(return_trigger); - return_trigger = NULL; - - payload_size = cmd_ctx->reply_payload.buffer.size - - original_payload_size; + reply_payload_size = cmd_ctx->reply_payload.buffer.size - + original_reply_payload_size; - update_lttng_msg(cmd_ctx, 0, payload_size); + update_lttng_msg(cmd_ctx, 0, reply_payload_size); ret = LTTNG_OK; break; } case LTTNG_UNREGISTER_TRIGGER: { - ret = cmd_unregister_trigger(cmd_ctx, *sock, + struct lttng_trigger *payload_trigger; + const struct lttng_credentials cmd_creds = { + .uid = LTTNG_OPTIONAL_INIT_VALUE(cmd_ctx->creds.uid), + .gid = LTTNG_OPTIONAL_INIT_VALUE(cmd_ctx->creds.gid), + }; + + ret = receive_lttng_trigger( + cmd_ctx, *sock, sock_error, &payload_trigger); + if (ret != LTTNG_OK) { + goto error; + } + + ret = cmd_unregister_trigger(&cmd_creds, payload_trigger, notification_thread_handle); + lttng_trigger_put(payload_trigger); break; } case LTTNG_ROTATE_SESSION: @@ -2514,6 +2617,11 @@ static void *thread_manage_clients(void *data) continue; } + if (ret < LTTNG_OK || ret >= LTTNG_ERR_NR) { + WARN("Command returned an invalid status code, returning unknown error: command type = %d, ret = %d", cmd_ctx.lsm.cmd_type, ret); + ret = LTTNG_ERR_UNK; + } + cmd_completion_handler = cmd_pop_completion_handler(); if (cmd_completion_handler) { enum lttng_error_code completion_code; @@ -2535,8 +2643,7 @@ static void *thread_manage_clients(void *data) struct lttcomm_lttng_msg *llm = (typeof( llm)) cmd_ctx.reply_payload.buffer.data; - assert(cmd_ctx.reply_payload.buffer.size >= - sizeof(llm)); + assert(cmd_ctx.reply_payload.buffer.size >= sizeof(*llm)); assert(cmd_ctx.lttng_msg_size == cmd_ctx.reply_payload.buffer.size); llm->fd_count = lttng_payload_view_get_fd_handle_count(&view);