Fix: sessiond: triggers: failure to insert trigger is fatal
[lttng-tools.git] / src / bin / lttng-sessiond / notification-thread-events.c
index 28e553f44875c59c74f28fc29d1dbd9adf102e54..c9c21bc7225df72ee21ad8a74d33f101dd878aca 100644 (file)
 #include <common/macros.h>
 #include <lttng/condition/condition.h>
 #include <lttng/action/action-internal.h>
-#include <lttng/action/group-internal.h>
+#include <lttng/action/list-internal.h>
 #include <lttng/domain-internal.h>
 #include <lttng/notification/notification-internal.h>
 #include <lttng/condition/condition-internal.h>
 #include <lttng/condition/buffer-usage-internal.h>
 #include <lttng/condition/session-consumed-size-internal.h>
 #include <lttng/condition/session-rotation-internal.h>
-#include <lttng/condition/on-event-internal.h>
+#include <lttng/condition/event-rule-matches-internal.h>
 #include <lttng/domain-internal.h>
 #include <lttng/notification/channel-internal.h>
 #include <lttng/trigger/trigger-internal.h>
@@ -373,7 +373,7 @@ int match_trigger_by_name_uid(struct cds_lfht_node *node,
                const void *key)
 {
        bool match = false;
-       const char *name;
+       const char *element_trigger_name;
        const char *key_name;
        enum lttng_trigger_status status;
        const struct lttng_credentials *key_creds;
@@ -385,14 +385,25 @@ int match_trigger_by_name_uid(struct cds_lfht_node *node,
                                struct lttng_trigger_ht_element,
                                node_by_name_uid);
 
-       status = lttng_trigger_get_name(trigger_ht_element->trigger, &name);
-       assert(status == LTTNG_TRIGGER_STATUS_OK);
+       status = lttng_trigger_get_name(trigger_ht_element->trigger,
+                       &element_trigger_name);
+       element_trigger_name = status == LTTNG_TRIGGER_STATUS_OK ?
+                       element_trigger_name : NULL;
 
        status = lttng_trigger_get_name(trigger_key, &key_name);
-       assert(status == LTTNG_TRIGGER_STATUS_OK);
+       key_name = status == LTTNG_TRIGGER_STATUS_OK ? key_name : NULL;
 
-       /* Compare the names. */
-       if (strcmp(name, key_name) != 0) {
+       /*
+        * Compare the names.
+        * Consider null names as not equal. This is to maintain backwards
+        * compatibility with pre-2.13 anonymous triggers. Multiples anonymous
+        * triggers are allowed for a given user.
+        */
+       if (!element_trigger_name || !key_name) {
+               goto end;
+       }
+
+       if (strcmp(element_trigger_name, key_name) != 0) {
                goto end;
        }
 
@@ -471,7 +482,7 @@ enum lttng_object_type get_condition_binding_object(
        case LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING:
        case LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED:
                return LTTNG_OBJECT_TYPE_SESSION;
-       case LTTNG_CONDITION_TYPE_ON_EVENT:
+       case LTTNG_CONDITION_TYPE_EVENT_RULE_MATCHES:
                return LTTNG_OBJECT_TYPE_NONE;
        default:
                return LTTNG_OBJECT_TYPE_UNKNOWN;
@@ -1953,9 +1964,9 @@ int handle_notification_thread_command_session_rotation(
                 * Ownership of `evaluation` transferred to the action executor
                 * no matter the result.
                 */
-               executor_status = action_executor_enqueue(state->executor,
-                               trigger, evaluation, &session_creds,
-                               client_list);
+               executor_status = action_executor_enqueue_trigger(
+                               state->executor, trigger, evaluation,
+                               &session_creds, client_list);
                evaluation = NULL;
                switch (executor_status) {
                case ACTION_EXECUTOR_STATUS_OK:
@@ -2174,40 +2185,6 @@ end:
        return ret;
 }
 
-static
-int condition_on_event_update_error_count(struct lttng_trigger *trigger)
-{
-       int ret = 0;
-       uint64_t error_count = 0;
-       struct lttng_condition *condition;
-       enum event_notifier_error_accounting_status status;
-
-       condition = lttng_trigger_get_condition(trigger);
-       assert(lttng_condition_get_type(condition) ==
-                       LTTNG_CONDITION_TYPE_ON_EVENT);
-
-       status = event_notifier_error_accounting_get_count(trigger, &error_count);
-       if (status != EVENT_NOTIFIER_ERROR_ACCOUNTING_STATUS_OK) {
-               uid_t trigger_owner_uid;
-               const char *trigger_name;
-               const enum lttng_trigger_status trigger_status =
-                               lttng_trigger_get_owner_uid(
-                                               trigger, &trigger_owner_uid);
-
-               assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
-               if (lttng_trigger_get_name(trigger, &trigger_name) != LTTNG_TRIGGER_STATUS_OK) {
-                       trigger_name = "(unnamed)";
-               }
-
-               ERR("Failed to get event notifier error count of trigger for update: trigger owner = %d, trigger name = '%s'",
-                               trigger_owner_uid, trigger_name);
-               ret = -1;
-       }
-
-       lttng_condition_on_event_set_error_count(condition, error_count);
-       return ret;
-}
-
 int handle_notification_thread_remove_tracer_event_source_no_result(
                struct notification_thread_state *state,
                int tracer_event_source_fd)
@@ -2255,12 +2232,6 @@ static int handle_notification_thread_command_list_triggers(
                        continue;
                }
 
-               if (lttng_trigger_needs_tracer_notifier(trigger_ht_element->trigger)) {
-                       ret = condition_on_event_update_error_count(
-                                       trigger_ht_element->trigger);
-                       assert(!ret);
-               }
-
                ret = lttng_triggers_add(local_triggers,
                                trigger_ht_element->trigger);
                if (ret < 0) {
@@ -2293,7 +2264,7 @@ static inline void get_trigger_info_for_log(const struct lttng_trigger *trigger,
        case LTTNG_TRIGGER_STATUS_OK:
                break;
        case LTTNG_TRIGGER_STATUS_UNSET:
-               *trigger_name = "(unset)";
+               *trigger_name = "(anonymous)";
                break;
        default:
                abort();
@@ -2334,7 +2305,7 @@ static int handle_notification_thread_command_get_trigger(
 
        /* Not a fatal error if the trigger is not found. */
        get_trigger_info_for_log(trigger, &trigger_name, &trigger_owner_uid);
-       ERR("Failed to retrieve registered version of trigger: trigger name = '%s', trigger owner uid = %d",
+       DBG("Failed to retrieve registered version of trigger: trigger name = '%s', trigger owner uid = %d",
                        trigger_name, (int) trigger_owner_uid);
 
        ret = 0;
@@ -2376,12 +2347,12 @@ bool condition_is_supported(struct lttng_condition *condition)
                is_supported = kernel_supports_ring_buffer_snapshot_sample_positions() == 1;
                break;
        }
-       case LTTNG_CONDITION_TYPE_ON_EVENT:
+       case LTTNG_CONDITION_TYPE_EVENT_RULE_MATCHES:
        {
                const struct lttng_event_rule *event_rule;
                enum lttng_domain_type domain;
                const enum lttng_condition_status status =
-                               lttng_condition_on_event_get_rule(
+                               lttng_condition_event_rule_matches_get_rule(
                                                condition, &event_rule);
 
                assert(status == LTTNG_CONDITION_STATUS_OK);
@@ -2520,12 +2491,12 @@ bool is_trigger_action_notify(const struct lttng_trigger *trigger)
                goto end;
        }
 
-       action_status = lttng_action_group_get_count(action, &count);
+       action_status = lttng_action_list_get_count(action, &count);
        assert(action_status == LTTNG_ACTION_STATUS_OK);
 
        for (i = 0; i < count; i++) {
                const struct lttng_action *inner_action =
-                               lttng_action_group_get_at_index(
+                               lttng_action_list_get_at_index(
                                                action, i);
 
                action_type = lttng_action_get_type(inner_action);
@@ -2642,7 +2613,7 @@ enum lttng_error_code setup_tracer_notifier(
                goto error_remove_ht_element;
        }
 
-       lttng_condition_on_event_set_error_counter_index(
+       lttng_condition_event_rule_matches_set_error_counter_index(
                        condition, error_counter_index);
 
        ret = LTTNG_OK;
@@ -2675,6 +2646,7 @@ static
 int handle_notification_thread_command_register_trigger(
                struct notification_thread_state *state,
                struct lttng_trigger *trigger,
+               bool is_trigger_anonymous,
                enum lttng_error_code *cmd_result)
 {
        int ret = 0;
@@ -2697,22 +2669,27 @@ int handle_notification_thread_command_register_trigger(
        /* Set the trigger's tracer token. */
        lttng_trigger_set_tracer_token(trigger, trigger_tracer_token);
 
-       if (lttng_trigger_get_name(trigger, &trigger_name) ==
-                       LTTNG_TRIGGER_STATUS_UNSET) {
-               const enum lttng_error_code ret_code = generate_trigger_name(
-                               state, trigger, &trigger_name);
+       if (!is_trigger_anonymous) {
+               if (lttng_trigger_get_name(trigger, &trigger_name) ==
+                               LTTNG_TRIGGER_STATUS_UNSET) {
+                       const enum lttng_error_code ret_code =
+                                       generate_trigger_name(state, trigger,
+                                                       &trigger_name);
 
-               if (ret_code != LTTNG_OK) {
-                       /* Fatal error. */
-                       ret = -1;
-                       *cmd_result = ret_code;
+                       if (ret_code != LTTNG_OK) {
+                               /* Fatal error. */
+                               ret = -1;
+                               *cmd_result = ret_code;
+                               goto error;
+                       }
+               } else if (trigger_name_taken(state, trigger)) {
+                       /* Not a fatal error. */
+                       *cmd_result = LTTNG_ERR_TRIGGER_EXISTS;
+                       ret = 0;
                        goto error;
                }
-       } else if (trigger_name_taken(state, trigger)) {
-               /* Not a fatal error. */
-               *cmd_result = LTTNG_ERR_TRIGGER_EXISTS;
-               ret = 0;
-               goto error;
+       } else {
+               trigger_name = "(anonymous)";
        }
 
        condition = lttng_trigger_get_condition(trigger);
@@ -2752,9 +2729,8 @@ int handle_notification_thread_command_register_trigger(
                        trigger,
                        &trigger_ht_element->node_by_name_uid);
        if (node != &trigger_ht_element->node_by_name_uid) {
-               /* Not a fatal error, simply report it to the client. */
-               cds_lfht_del(state->triggers_ht, &trigger_ht_element->node);
-               *cmd_result = LTTNG_ERR_TRIGGER_EXISTS;
+               /* Internal error: add to triggers_ht should have failed. */
+               ret = -1;
                goto error_free_ht_element;
        }
 
@@ -2917,8 +2893,8 @@ int handle_notification_thread_command_register_trigger(
         * Ownership of `evaluation` transferred to the action executor
         * no matter the result.
         */
-       executor_status = action_executor_enqueue(state->executor, trigger,
-                       evaluation, &object_creds, client_list);
+       executor_status = action_executor_enqueue_trigger(state->executor,
+                       trigger, evaluation, &object_creds, client_list);
        evaluation = NULL;
        switch (executor_status) {
        case ACTION_EXECUTOR_STATUS_OK:
@@ -3049,9 +3025,6 @@ int handle_notification_thread_command_unregister_trigger(
        trigger_ht_element = caa_container_of(triggers_ht_node,
                        struct lttng_trigger_ht_element, node);
 
-       /* From this point, consider the trigger unregistered no matter what. */
-       lttng_trigger_set_as_unregistered(trigger_ht_element->trigger);
-
        /* Remove trigger from channel_triggers_ht. */
        cds_lfht_for_each_entry(state->channel_triggers_ht, &iter, trigger_list,
                        channel_triggers_ht_node) {
@@ -3134,6 +3107,7 @@ int handle_notification_thread_command(
        case NOTIFICATION_COMMAND_TYPE_REGISTER_TRIGGER:
                ret = handle_notification_thread_command_register_trigger(state,
                                cmd->parameters.register_trigger.trigger,
+                               cmd->parameters.register_trigger.is_trigger_anonymous,
                                &cmd->reply_code);
                break;
        case NOTIFICATION_COMMAND_TYPE_UNREGISTER_TRIGGER:
@@ -4580,11 +4554,9 @@ int dispatch_one_event_notifier_notification(struct notification_thread_state *s
        struct cds_lfht_node *node;
        struct cds_lfht_iter iter;
        struct notification_trigger_tokens_ht_element *element;
-       enum lttng_trigger_status trigger_status;
        struct lttng_evaluation *evaluation = NULL;
        enum action_executor_status executor_status;
        struct notification_client_list *client_list = NULL;
-       const char *trigger_name;
        int ret;
        unsigned int capture_count = 0;
 
@@ -4609,10 +4581,7 @@ int dispatch_one_event_notifier_notification(struct notification_thread_state *s
                        struct notification_trigger_tokens_ht_element,
                        node);
 
-       trigger_status = lttng_trigger_get_name(element->trigger, &trigger_name);
-       assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
-
-       if (lttng_condition_on_event_get_capture_descriptor_count(
+       if (lttng_condition_event_rule_matches_get_capture_descriptor_count(
                            lttng_trigger_get_const_condition(element->trigger),
                            &capture_count) != LTTNG_CONDITION_STATUS_OK) {
                ERR("Failed to get capture count");
@@ -4626,10 +4595,10 @@ int dispatch_one_event_notifier_notification(struct notification_thread_state *s
                goto end;
        }
 
-       evaluation = lttng_evaluation_on_event_create(
+       evaluation = lttng_evaluation_event_rule_matches_create(
                        container_of(lttng_trigger_get_const_condition(
                                                     element->trigger),
-                                       struct lttng_condition_on_event,
+                                       struct lttng_condition_event_rule_matches,
                                        parent),
                        notification->capture_buffer,
                        notification->capture_buf_size, false);
@@ -4641,7 +4610,7 @@ int dispatch_one_event_notifier_notification(struct notification_thread_state *s
        }
        client_list = get_client_list_from_condition(state,
                        lttng_trigger_get_const_condition(element->trigger));
-       executor_status = action_executor_enqueue(state->executor,
+       executor_status = action_executor_enqueue_trigger(state->executor,
                        element->trigger, evaluation, NULL, client_list);
        switch (executor_status) {
        case ACTION_EXECUTOR_STATUS_OK:
@@ -4924,9 +4893,9 @@ int handle_notification_thread_channel_sample(
                 * Ownership of `evaluation` transferred to the action executor
                 * no matter the result.
                 */
-               executor_status = action_executor_enqueue(state->executor,
-                               trigger, evaluation, &channel_creds,
-                               client_list);
+               executor_status = action_executor_enqueue_trigger(
+                               state->executor, trigger, evaluation,
+                               &channel_creds, client_list);
                evaluation = NULL;
                switch (executor_status) {
                case ACTION_EXECUTOR_STATUS_OK:
This page took 0.028753 seconds and 4 git commands to generate.