sessiond: implement EXECUTE_ERROR_QUERY command
authorJérémie Galarneau <jeremie.galarneau@efficios.com>
Thu, 15 Apr 2021 17:11:09 +0000 (13:11 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Sun, 18 Apr 2021 23:28:57 +0000 (19:28 -0400)
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
Change-Id: I3404e85e18b0b4e5d51b620c3a082736d3190066

17 files changed:
include/lttng/action/action-internal.h
include/lttng/error-query-internal.h
include/lttng/trigger/trigger-internal.h
src/bin/lttng-sessiond/Makefile.am
src/bin/lttng-sessiond/client.c
src/bin/lttng-sessiond/cmd.c
src/bin/lttng-sessiond/cmd.h
src/bin/lttng-sessiond/trigger-error-query.c [new file with mode: 0644]
src/common/actions/action.c
src/common/actions/group.c
src/common/actions/notify.c
src/common/actions/rotate-session.c
src/common/actions/snapshot-session.c
src/common/actions/start-session.c
src/common/actions/stop-session.c
src/common/error-query.c
tests/unit/Makefile.am

index 12029e42f5d9ade44dde8f68eef6399eb2a48719..55e34163b1cb14749bd6451c51605cf766da5d51 100644 (file)
@@ -8,12 +8,13 @@
 #ifndef LTTNG_ACTION_INTERNAL_H
 #define LTTNG_ACTION_INTERNAL_H
 
-#include <lttng/action/action.h>
-#include <common/macros.h>
 #include <common/buffer-view.h>
 #include <common/dynamic-buffer.h>
+#include <common/macros.h>
 #include <common/payload-view.h>
 #include <common/payload.h>
+#include <lttng/lttng.h>
+#include <pthread.h>
 #include <stdbool.h>
 #include <sys/types.h>
 #include <urcu/ref.h>
@@ -31,6 +32,9 @@ typedef ssize_t (*action_create_from_payload_cb)(
                struct lttng_action **action);
 typedef const struct lttng_rate_policy *(*action_get_rate_policy_cb)(
                const struct lttng_action *action);
+typedef enum lttng_action_status (*action_add_error_query_results_cb)(
+               const struct lttng_action *action,
+               struct lttng_error_query_results *results);
 
 struct lttng_action {
        struct urcu_ref ref;
@@ -40,6 +44,7 @@ struct lttng_action {
        action_equal_cb equal;
        action_destroy_cb destroy;
        action_get_rate_policy_cb get_rate_policy;
+       action_add_error_query_results_cb add_error_query_results;
 
        /* Internal use only. */
 
@@ -52,8 +57,10 @@ struct lttng_action {
        uint64_t execution_counter;
        /*
         * The number of time the action execution failed.
+        * An unsigned long is used to use a type which makes atomic
+        * operations possible.
         */
-       uint64_t execution_failure_counter;
+       unsigned long execution_failure_counter;
 };
 
 struct lttng_action_comm {
@@ -68,7 +75,8 @@ void lttng_action_init(struct lttng_action *action,
                action_serialize_cb serialize,
                action_equal_cb equal,
                action_destroy_cb destroy,
-               action_get_rate_policy_cb get_rate_policy);
+               action_get_rate_policy_cb get_rate_policy,
+               action_add_error_query_results_cb add_error_query_results);
 
 LTTNG_HIDDEN
 bool lttng_action_validate(struct lttng_action *action);
@@ -106,4 +114,19 @@ void lttng_action_increase_execution_failure_count(struct lttng_action *action);
 LTTNG_HIDDEN
 bool lttng_action_should_execute(const struct lttng_action *action);
 
+LTTNG_HIDDEN
+enum lttng_action_status lttng_action_add_error_query_results(
+               const struct lttng_action *action,
+               struct lttng_error_query_results *results);
+
+/*
+ * For use by the various lttng_action implementation. Implements the default
+ * behavior to the generic error "execution failure counter" that all actions
+ * (except group, which passes-through) provide.
+ */
+LTTNG_HIDDEN
+enum lttng_action_status lttng_action_generic_add_error_query_results(
+               const struct lttng_action *action,
+               struct lttng_error_query_results *results);
+
 #endif /* LTTNG_ACTION_INTERNAL_H */
index 24216f964308eb805402baf079929fca583e009a..b5578d44d57b466a7032baa0042e028318cf4b54 100644 (file)
@@ -33,9 +33,9 @@ const struct lttng_trigger *lttng_error_query_action_borrow_trigger_target(
                const struct lttng_error_query *query);
 
 LTTNG_HIDDEN
-const struct lttng_action *lttng_error_query_action_borrow_action_target(
+struct lttng_action *lttng_error_query_action_borrow_action_target(
                const struct lttng_error_query *query,
-               const struct lttng_trigger *trigger);
+               struct lttng_trigger *trigger);
 
 LTTNG_HIDDEN
 int lttng_error_query_serialize(const struct lttng_error_query *query,
index f16b68d00fd88412af0e649e02aef3447b434c11..5bab4c7634c9a096a0819085cd49ccef063fdd8d 100644 (file)
@@ -12,7 +12,7 @@
 #include <common/dynamic-array.h>
 #include <common/macros.h>
 #include <common/optional.h>
-#include <lttng/trigger/trigger.h>
+#include <lttng/lttng.h>
 #include <pthread.h>
 #include <stdbool.h>
 #include <stdint.h>
@@ -226,4 +226,14 @@ void lttng_trigger_lock(struct lttng_trigger *trigger);
 LTTNG_HIDDEN
 void lttng_trigger_unlock(struct lttng_trigger *trigger);
 
+LTTNG_HIDDEN
+enum lttng_trigger_status lttng_trigger_add_error_results(
+               const struct lttng_trigger *trigger,
+               struct lttng_error_query_results *results);
+
+LTTNG_HIDDEN
+enum lttng_trigger_status lttng_trigger_add_action_error_query_results(
+               struct lttng_trigger *trigger,
+               struct lttng_error_query_results *results);
+
 #endif /* LTTNG_TRIGGER_INTERNAL_H */
index 8a299fab8e298b08b387e674fd9fd9a78f1dfc67..07aaa821ca19a9c4f83613ebca7dcb4505c14aa6 100644 (file)
@@ -56,7 +56,8 @@ lttng_sessiond_SOURCES = utils.c utils.h \
                        clear.c clear.h \
                        tracker.c tracker.h \
                        event-notifier-error-accounting.c event-notifier-error-accounting.h \
-                       action-executor.c action-executor.h
+                       action-executor.c action-executor.h\
+                       trigger-error-query.c
 
 lttng_sessiond_LDFLAGS = -rdynamic
 
index d83bee8e66441c8f6b9ddb08f8821ef83a468191..6943a776e56a91fe5ecf8cd35f10f8ae786257fb 100644 (file)
@@ -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 <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;
 
@@ -780,6 +779,77 @@ end:
        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;
+}
+
 /*
  * Version of setup_lttng_msg() without command header.
  */
@@ -890,6 +960,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:
@@ -900,6 +971,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:
@@ -949,6 +1021,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 */
@@ -970,6 +1043,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:
@@ -2356,6 +2430,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;
index c7745abf1485d37f2e651ec8d37490adbb6b85a9..3fab5af02e94d7194fca8033755cbb7abfb93f4e 100644 (file)
@@ -6,67 +6,69 @@
  *
  */
 
-#include "bin/lttng-sessiond/session.h"
+
 #define _LGPL_SOURCE
 #include <assert.h>
 #include <inttypes.h>
+#include <stdio.h>
+#include <sys/stat.h>
 #include <urcu/list.h>
 #include <urcu/uatomic.h>
-#include <sys/stat.h>
-#include <stdio.h>
 
-#include <common/defaults.h>
+#include <common/buffer-view.h>
 #include <common/common.h>
-#include <common/sessiond-comm/sessiond-comm.h>
-#include <common/relayd/relayd.h>
-#include <common/utils.h>
 #include <common/compat/string.h>
-#include <common/kernel-ctl/kernel-ctl.h>
+#include <common/defaults.h>
 #include <common/dynamic-buffer.h>
-#include <common/buffer-view.h>
-#include <common/payload.h>
+#include <common/kernel-ctl/kernel-ctl.h>
 #include <common/payload-view.h>
+#include <common/payload.h>
+#include <common/relayd/relayd.h>
+#include <common/sessiond-comm/sessiond-comm.h>
+#include <common/string-utils/string-utils.h>
 #include <common/trace-chunk.h>
-#include <lttng/location-internal.h>
-#include <lttng/trigger/trigger-internal.h>
-#include <lttng/condition/condition.h>
+#include <common/utils.h>
+#include <lttng/action/action-internal.h>
+#include <lttng/action/action.h>
+#include <lttng/channel-internal.h>
+#include <lttng/channel.h>
 #include <lttng/condition/condition-internal.h>
-#include <lttng/condition/on-event.h>
+#include <lttng/condition/condition.h>
 #include <lttng/condition/on-event-internal.h>
-#include <lttng/event-rule/event-rule.h>
+#include <lttng/condition/on-event.h>
+#include <lttng/error-query-internal.h>
 #include <lttng/event-rule/event-rule-internal.h>
-#include <lttng/action/action.h>
-#include <lttng/channel.h>
-#include <lttng/channel-internal.h>
-#include <lttng/rotate-internal.h>
+#include <lttng/event-rule/event-rule.h>
 #include <lttng/location-internal.h>
-#include <lttng/session-internal.h>
-#include <lttng/userspace-probe-internal.h>
-#include <lttng/session-descriptor-internal.h>
 #include <lttng/lttng-error.h>
+#include <lttng/rotate-internal.h>
+#include <lttng/session-descriptor-internal.h>
+#include <lttng/session-internal.h>
 #include <lttng/tracker.h>
-#include <common/string-utils/string-utils.h>
+#include <lttng/trigger/trigger-internal.h>
+#include <lttng/userspace-probe-internal.h>
 
+#include "agent-thread.h"
+#include "agent.h"
+#include "buffer-registry.h"
 #include "channel.h"
+#include "cmd.h"
 #include "consumer.h"
+#include "event-notifier-error-accounting.h"
 #include "event.h"
 #include "health-sessiond.h"
-#include "kernel.h"
 #include "kernel-consumer.h"
+#include "kernel.h"
 #include "lttng-sessiond.h"
-#include "utils.h"
 #include "lttng-syscall.h"
-#include "agent.h"
-#include "buffer-registry.h"
-#include "notification-thread.h"
 #include "notification-thread-commands.h"
+#include "notification-thread.h"
 #include "rotate.h"
 #include "rotation-thread.h"
+#include "session.h"
 #include "timer.h"
-#include "agent-thread.h"
 #include "tracker.h"
-
-#include "cmd.h"
+#include "utils.h"
 
 /* Sleep for 100ms between each check for the shm path's deletion. */
 #define SESSION_DESTROY_SHM_PATH_CHECK_DELAY_US 100000
@@ -4650,6 +4652,129 @@ end:
        lttng_triggers_destroy(triggers);
        return ret;
 }
+
+enum lttng_error_code cmd_execute_error_query(const struct lttng_credentials *cmd_creds,
+               const struct lttng_error_query *query,
+               struct lttng_error_query_results **_results,
+               struct notification_thread_handle *notification_thread)
+{
+       enum lttng_error_code ret_code;
+       const struct lttng_trigger *query_target_trigger;
+       struct lttng_action *query_target_action;
+       struct lttng_trigger *matching_trigger = NULL;
+       const char *trigger_name;
+       uid_t trigger_owner;
+       enum lttng_trigger_status trigger_status;
+       struct lttng_error_query_results *results = NULL;
+
+       switch (lttng_error_query_get_target_type(query)) {
+       case LTTNG_ERROR_QUERY_TARGET_TYPE_TRIGGER:
+               query_target_trigger = lttng_error_query_trigger_borrow_target(query);
+               break;
+       case LTTNG_ERROR_QUERY_TARGET_TYPE_ACTION:
+               query_target_trigger = lttng_error_query_action_borrow_trigger_target(
+                               query);
+               break;
+       default:
+               abort();
+       }
+
+       assert(query_target_trigger);
+
+       ret_code = notification_thread_command_get_trigger(notification_thread,
+                       query_target_trigger, &matching_trigger);
+       if (ret_code != LTTNG_OK) {
+               goto end;
+       }
+
+       /* No longer needed. */
+       query_target_trigger = NULL;
+
+       if (lttng_error_query_get_target_type(query) ==
+                       LTTNG_ERROR_QUERY_TARGET_TYPE_ACTION) {
+               /* Get the sessiond-side version of the target action. */
+               query_target_action =
+                               lttng_error_query_action_borrow_action_target(
+                                               query, matching_trigger);
+       }
+
+       trigger_status = lttng_trigger_get_name(matching_trigger, &trigger_name);
+       trigger_name = trigger_status == LTTNG_TRIGGER_STATUS_OK ?
+                       trigger_name : "(unnamed)";
+       trigger_status = lttng_trigger_get_owner_uid(matching_trigger,
+                       &trigger_owner);
+       assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
+
+       results = lttng_error_query_results_create();
+       if (!results) {
+               ret_code = LTTNG_ERR_NOMEM;
+               goto end;
+       }
+
+       DBG("Running \"execute error query\" command: trigger name = '%s', trigger owner uid = %d, command creds uid = %d",
+                       trigger_name, (int) trigger_owner,
+                       (int) lttng_credentials_get_uid(cmd_creds));
+
+       /*
+        * Validate the trigger credentials against the command credentials.
+        * Only the root user can target a trigger with non-matching
+        * credentials.
+        */
+       if (!lttng_credentials_is_equal_uid(
+                       lttng_trigger_get_credentials(matching_trigger),
+                       cmd_creds)) {
+               if (lttng_credentials_get_uid(cmd_creds) != 0) {
+                       ERR("Trigger credentials do not match the command credentials: trigger name = '%s', trigger owner uid = %d, command creds uid = %d",
+                                       trigger_name, (int) trigger_owner,
+                                       (int) lttng_credentials_get_uid(cmd_creds));
+                       ret_code = LTTNG_ERR_INVALID_TRIGGER;
+                       goto end;
+               }
+       }
+
+       switch (lttng_error_query_get_target_type(query)) {
+       case LTTNG_ERROR_QUERY_TARGET_TYPE_TRIGGER:
+               trigger_status = lttng_trigger_add_error_results(
+                               matching_trigger, results);
+
+               switch (trigger_status) {
+               case LTTNG_TRIGGER_STATUS_OK:
+                       break;
+               default:
+                       ret_code = LTTNG_ERR_UNK;
+                       goto end;
+               }
+
+               break;
+       case LTTNG_ERROR_QUERY_TARGET_TYPE_ACTION:
+       {
+               const enum lttng_action_status action_status =
+                               lttng_action_add_error_query_results(
+                                               query_target_action, results);
+
+               switch (action_status) {
+               case LTTNG_ACTION_STATUS_OK:
+                       break;
+               default:
+                       ret_code = LTTNG_ERR_UNK;
+                       goto end;
+               }
+
+               break;
+       }
+       default:
+               break;
+       }
+
+       *_results = results;
+       results = NULL;
+       ret_code = LTTNG_OK;
+end:
+       lttng_trigger_put(matching_trigger);
+       lttng_error_query_results_destroy(results);
+       return ret_code;
+}
+
 /*
  * Send relayd sockets from snapshot output to consumer. Ignore request if the
  * snapshot output is *not* set with a remote destination.
index dcda2365dd0a134d3075c4f1a81af3bf25cdefec..9aa13ff2220eb751c8455960ca55dafdc6a3f871 100644 (file)
@@ -154,6 +154,10 @@ enum lttng_error_code cmd_unregister_trigger(
 int cmd_list_triggers(struct command_ctx *cmd_ctx,
                struct notification_thread_handle *notification_thread_handle,
                struct lttng_triggers **return_triggers);
+enum lttng_error_code cmd_execute_error_query(const struct lttng_credentials *cmd_creds,
+               const struct lttng_error_query *query,
+               struct lttng_error_query_results **_results,
+               struct notification_thread_handle *notification_thread);
 
 int cmd_rotate_session(struct ltt_session *session,
                struct lttng_rotate_session_return *rotate_return,
diff --git a/src/bin/lttng-sessiond/trigger-error-query.c b/src/bin/lttng-sessiond/trigger-error-query.c
new file mode 100644 (file)
index 0000000..bc8e7f6
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2021 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-only
+ *
+ */
+
+#include "event-notifier-error-accounting.h"
+#include <lttng/error-query-internal.h>
+#include <lttng/trigger/trigger-internal.h>
+#include <lttng/action/action-internal.h>
+
+LTTNG_HIDDEN
+enum lttng_trigger_status lttng_trigger_add_error_results(
+               const struct lttng_trigger *trigger,
+               struct lttng_error_query_results *results)
+{
+       enum lttng_trigger_status status;
+       uint64_t discarded_tracer_messages_count;
+       enum event_notifier_error_accounting_status error_accounting_status;
+       struct lttng_error_query_result *discarded_tracer_messages_counter = NULL;
+       const char *trigger_name;
+       uid_t trigger_owner;
+
+       status = lttng_trigger_get_name(trigger, &trigger_name);
+       trigger_name = status == LTTNG_TRIGGER_STATUS_OK ?
+                       trigger_name : "(unnamed)";
+       status = lttng_trigger_get_owner_uid(trigger,
+                       &trigger_owner);
+       assert(status == LTTNG_TRIGGER_STATUS_OK);
+
+       error_accounting_status = event_notifier_error_accounting_get_count(
+                       trigger, &discarded_tracer_messages_count);
+       if (error_accounting_status != EVENT_NOTIFIER_ERROR_ACCOUNTING_STATUS_OK) {
+               ERR("Failed to retrieve tracer discarded messages count for triger: triggger name = '%s', trigger owner uid = %d",
+                               trigger_name, (int) trigger_owner);
+               status = LTTNG_TRIGGER_STATUS_ERROR;
+               goto end;
+       }
+
+       discarded_tracer_messages_counter = lttng_error_query_result_counter_create(
+                       "discarded tracer messages",
+                       "Count of messages discarded by the tracer due to a communication error with the session daemon",
+                       discarded_tracer_messages_count);
+       if (!discarded_tracer_messages_counter) {
+               status = LTTNG_TRIGGER_STATUS_ERROR;
+               goto end;
+       }
+
+       if (lttng_error_query_results_add_result(
+                           results, discarded_tracer_messages_counter)) {
+               status = LTTNG_TRIGGER_STATUS_ERROR;
+               goto end;
+       }
+
+       /* Ownership transferred to the results. */
+       discarded_tracer_messages_counter = NULL;
+
+       status = LTTNG_TRIGGER_STATUS_OK;
+end:
+       lttng_error_query_result_destroy(discarded_tracer_messages_counter);
+       return status;
+}
+
+LTTNG_HIDDEN
+enum lttng_trigger_status lttng_trigger_add_action_error_query_results(
+               struct lttng_trigger *trigger,
+               struct lttng_error_query_results *results)
+{
+       enum lttng_trigger_status status;
+       const char *trigger_name;
+       uid_t trigger_owner;
+       enum lttng_action_status action_status;
+
+       status = lttng_trigger_get_name(trigger, &trigger_name);
+       trigger_name = status == LTTNG_TRIGGER_STATUS_OK ?
+                       trigger_name : "(unnamed)";
+       status = lttng_trigger_get_owner_uid(trigger,
+                       &trigger_owner);
+       assert(status == LTTNG_TRIGGER_STATUS_OK);
+
+       action_status = lttng_action_add_error_query_results(
+                       lttng_trigger_get_action(trigger), results);
+       switch (action_status) {
+       case LTTNG_ACTION_STATUS_OK:
+               status = LTTNG_TRIGGER_STATUS_OK;
+               goto end;
+       default:
+               status = LTTNG_TRIGGER_STATUS_ERROR;
+               goto end;
+       }
+
+       status = LTTNG_TRIGGER_STATUS_OK;
+end:
+       return status;
+}
index 64864a6273ae1fabac87cd8e6fd813831335f9d0..d4b9c09ebfab716f6a7d2becd13d2e953f1871c9 100644 (file)
@@ -15,6 +15,7 @@
 #include <lttng/action/snapshot-session-internal.h>
 #include <lttng/action/start-session-internal.h>
 #include <lttng/action/stop-session-internal.h>
+#include <lttng/error-query-internal.h>
 
 LTTNG_HIDDEN
 const char *lttng_action_type_string(enum lttng_action_type action_type)
@@ -51,7 +52,8 @@ void lttng_action_init(struct lttng_action *action,
                action_serialize_cb serialize,
                action_equal_cb equal,
                action_destroy_cb destroy,
-               action_get_rate_policy_cb get_rate_policy)
+               action_get_rate_policy_cb get_rate_policy,
+               action_add_error_query_results_cb add_error_query_results)
 {
        urcu_ref_init(&action->ref);
        action->type = type;
@@ -60,6 +62,7 @@ void lttng_action_init(struct lttng_action *action,
        action->equal = equal;
        action->destroy = destroy;
        action->get_rate_policy = get_rate_policy;
+       action->add_error_query_results = add_error_query_results;
 
        action->execution_request_counter = 0;
        action->execution_counter = 0;
@@ -265,7 +268,7 @@ void lttng_action_increase_execution_count(struct lttng_action *action)
 LTTNG_HIDDEN
 void lttng_action_increase_execution_failure_count(struct lttng_action *action)
 {
-       action->execution_failure_counter++;
+       uatomic_inc(&action->execution_failure_counter);
 }
 
 LTTNG_HIDDEN
@@ -290,3 +293,44 @@ bool lttng_action_should_execute(const struct lttng_action *action)
 end:
        return execute;
 }
+
+LTTNG_HIDDEN
+enum lttng_action_status lttng_action_add_error_query_results(
+               const struct lttng_action *action,
+               struct lttng_error_query_results *results)
+{
+       return action->add_error_query_results(action, results);
+}
+
+LTTNG_HIDDEN
+enum lttng_action_status lttng_action_generic_add_error_query_results(
+               const struct lttng_action *action,
+               struct lttng_error_query_results *results)
+{
+       enum lttng_action_status action_status;
+       struct lttng_error_query_result *error_counter = NULL;
+       const uint64_t execution_failure_counter =
+                       uatomic_read(&action->execution_failure_counter);
+
+       error_counter = lttng_error_query_result_counter_create(
+                       "total execution failures",
+                       "Aggregated count of errors encountered when executing the action",
+                       execution_failure_counter);
+       if (!error_counter) {
+               action_status = LTTNG_ACTION_STATUS_ERROR;
+               goto end;
+       }
+
+       if (lttng_error_query_results_add_result(
+                           results, error_counter)) {
+               action_status = LTTNG_ACTION_STATUS_ERROR;
+               goto end;
+       }
+
+       /* Ownership transferred to the results. */
+       error_counter = NULL;
+       action_status = LTTNG_ACTION_STATUS_OK;
+end:
+       lttng_error_query_result_destroy(error_counter);
+       return action_status;
+}
index afb832ee646a766b40142f87eae385eb178b7fa4..3effa871561c6fd97e03143a27a72083ffcb74a0 100644 (file)
@@ -250,6 +250,34 @@ end:
        return consumed_len;
 }
 
+static enum lttng_action_status lttng_action_group_add_error_query_results(
+               const struct lttng_action *action,
+               struct lttng_error_query_results *results)
+{
+       unsigned int i, count;
+       enum lttng_action_status action_status;
+       const struct lttng_action_group *group =
+                       container_of(action, typeof(*group), parent);
+
+       action_status = lttng_action_group_get_count(action, &count);
+       if (action_status != LTTNG_ACTION_STATUS_OK) {
+               goto end;
+       }
+
+       for (i = 0; i < count; i++) {
+               struct lttng_action *inner_action =
+                               lttng_action_group_borrow_mutable_at_index(action, i);
+
+               action_status = lttng_action_add_error_query_results(
+                               inner_action, results);
+               if (action_status != LTTNG_ACTION_STATUS_OK) {
+                       goto end;
+               }
+       }
+end:
+       return action_status;
+}
+
 struct lttng_action *lttng_action_group_create(void)
 {
        struct lttng_action_group *action_group;
@@ -267,7 +295,8 @@ struct lttng_action *lttng_action_group_create(void)
                        lttng_action_group_validate,
                        lttng_action_group_serialize,
                        lttng_action_group_is_equal, lttng_action_group_destroy,
-                       NULL);
+                       NULL,
+                       lttng_action_group_add_error_query_results);
 
        lttng_dynamic_pointer_array_init(&action_group->actions,
                        destroy_lttng_action_group_element);
index 0ab88be44fe6397ab7351dc058a3057dfef2c8a2..646bffe9d3a63f7fb7acf8a7066d08555f6e5de9 100644 (file)
@@ -103,7 +103,8 @@ struct lttng_action *lttng_action_notify_create(void)
                        lttng_action_notify_serialize,
                        lttng_action_notify_is_equal,
                        lttng_action_notify_destroy,
-                       lttng_action_notify_internal_get_rate_policy);
+                       lttng_action_notify_internal_get_rate_policy,
+                       lttng_action_generic_add_error_query_results);
 
        notify->policy = policy;
        policy = NULL;
index 3d5a61709b791be6a531eeee7c82b18f677e3737..c8dadd1191fa095565cb97603bfb1c49f1199f89 100644 (file)
@@ -252,7 +252,8 @@ struct lttng_action *lttng_action_rotate_session_create(void)
                        lttng_action_rotate_session_serialize,
                        lttng_action_rotate_session_is_equal,
                        lttng_action_rotate_session_destroy,
-                       lttng_action_rotate_session_internal_get_rate_policy);
+                       lttng_action_rotate_session_internal_get_rate_policy,
+                       lttng_action_generic_add_error_query_results);
 
        status = lttng_action_rotate_session_set_rate_policy(action, policy);
        if (status != LTTNG_ACTION_STATUS_OK) {
index 239cf5e73fded4ebd25bb3785a6d6dea8897a633..776615003a1120073e90f1408c2383299433b94b 100644 (file)
@@ -395,7 +395,8 @@ struct lttng_action *lttng_action_snapshot_session_create(void)
                        lttng_action_snapshot_session_serialize,
                        lttng_action_snapshot_session_is_equal,
                        lttng_action_snapshot_session_destroy,
-                       lttng_action_snapshot_session_internal_get_rate_policy);
+                       lttng_action_snapshot_session_internal_get_rate_policy,
+                       lttng_action_generic_add_error_query_results);
 
        status = lttng_action_snapshot_session_set_rate_policy(action, policy);
        if (status != LTTNG_ACTION_STATUS_OK) {
index 8ed8068dd2f902f1f1ce17d5298a16c8ed69ee6b..e5cbac7267c0b74dd24817c8e68413cc51775bce 100644 (file)
@@ -255,7 +255,8 @@ struct lttng_action *lttng_action_start_session_create(void)
                        lttng_action_start_session_serialize,
                        lttng_action_start_session_is_equal,
                        lttng_action_start_session_destroy,
-                       lttng_action_start_session_internal_get_rate_policy);
+                       lttng_action_start_session_internal_get_rate_policy,
+                       lttng_action_generic_add_error_query_results);
 
        status = lttng_action_start_session_set_rate_policy(action, policy);
        if (status != LTTNG_ACTION_STATUS_OK) {
index 9f74bf88496efe26309c6d187b28e847c78fbadb..ec167d1eda6ed1955cdc7c1b5a38d2d3a47477ef 100644 (file)
@@ -255,7 +255,8 @@ struct lttng_action *lttng_action_stop_session_create(void)
                        lttng_action_stop_session_serialize,
                        lttng_action_stop_session_is_equal,
                        lttng_action_stop_session_destroy,
-                       lttng_action_stop_session_internal_get_rate_policy);
+                       lttng_action_stop_session_internal_get_rate_policy,
+                       lttng_action_generic_add_error_query_results);
 
        status = lttng_action_stop_session_set_rate_policy(action, policy);
        if (status != LTTNG_ACTION_STATUS_OK) {
index 17fd5ffae030cb3404803fafcd8a90eddef26ffe..d353c5a8ff090e5064114facb3c9d44e031ffe6f 100644 (file)
@@ -351,6 +351,7 @@ lttng_error_query_result_counter_create(
                goto error;
        }
 
+       counter->value = value;
        goto end;
 error:
        lttng_error_query_result_destroy(&counter->parent);
@@ -659,15 +660,15 @@ const struct lttng_trigger *lttng_error_query_action_borrow_trigger_target(
 }
 
 LTTNG_HIDDEN
-const struct lttng_action *lttng_error_query_action_borrow_action_target(
+struct lttng_action *lttng_error_query_action_borrow_action_target(
        const struct lttng_error_query *query,
-       const struct lttng_trigger *trigger)
+       struct lttng_trigger *trigger)
 {
-       const struct lttng_action *target_action = NULL;
+       struct lttng_action *target_action = NULL;
        const struct lttng_error_query_action *query_action =
                        container_of(query, typeof(*query_action), parent);
-       const struct lttng_action *trigger_action =
-                       lttng_trigger_get_const_action(trigger);
+       struct lttng_action *trigger_action =
+                       lttng_trigger_get_action(trigger);
 
        if (!query_action->action_index.is_set) {
                target_action = trigger_action;
@@ -678,7 +679,8 @@ const struct lttng_action *lttng_error_query_action_borrow_action_target(
                        goto end;
                }
 
-               target_action = lttng_action_group_get_at_index(trigger_action,
+               target_action = lttng_action_group_borrow_mutable_at_index(
+                               trigger_action,
                                LTTNG_OPTIONAL_GET(query_action->action_index));
        }
 
index 2a0f3c9fb6a6c231079a0b937ff439bc1a7894b8..401e89f25a5e7936eef74852077e38ea9789b791 100644 (file)
@@ -114,6 +114,7 @@ SESSIOND_OBJS = $(top_builddir)/src/bin/lttng-sessiond/buffer-registry.$(OBJEXT)
         $(top_builddir)/src/bin/lttng-sessiond/process-utils.$(OBJEXT) \
         $(top_builddir)/src/bin/lttng-sessiond/thread.$(OBJEXT) \
         $(top_builddir)/src/bin/lttng-sessiond/tracker.$(OBJEXT) \
+        $(top_builddir)/src/bin/lttng-sessiond/trigger-error-query.$(OBJEXT) \
         $(top_builddir)/src/common/libcommon.la \
         $(top_builddir)/src/common/testpoint/libtestpoint.la \
         $(top_builddir)/src/common/compat/libcompat.la \
This page took 0.03886 seconds and 4 git commands to generate.