trigger: keep state of if a trigger is currently registered
[lttng-tools.git] / src / bin / lttng-sessiond / notification-thread-events.c
index ee20725dd318c3a167053d20b6da2fb03f8fed64..ec4d56bce7d9ec78c6c6926e256e376f59b6297a 100644 (file)
@@ -1089,6 +1089,7 @@ int notification_thread_client_subscribe(struct notification_client *client,
        struct notification_client_list *client_list = NULL;
        struct lttng_condition_list_element *condition_list_element = NULL;
        struct notification_client_list_element *client_list_element = NULL;
+       struct lttng_trigger_ht_element *trigger_ht_element;
        enum lttng_notification_channel_status status =
                        LTTNG_NOTIFICATION_CHANNEL_STATUS_OK;
 
@@ -1138,11 +1139,11 @@ int notification_thread_client_subscribe(struct notification_client *client,
         * at this point so that conditions that are already TRUE result
         * in a notification being sent out.
         *
-        * The client_list's trigger is used without locking the list itself.
-        * This is correct since the list doesn't own the trigger and the
-        * object is immutable.
+        * Note the iteration on all triggers which share an identical
+        * `condition` than the one to which the client is registering. This is
+        * done to ensure that the client receives a distinct notification for
+        * all triggers that have a `notify` action that have this condition.
         */
-       struct lttng_trigger_ht_element *trigger_ht_element;
        pthread_mutex_lock(&client_list->lock);
        cds_list_for_each_entry(trigger_ht_element,
                        &client_list->triggers_list, client_list_trigger_node) {
@@ -1151,6 +1152,7 @@ int notification_thread_client_subscribe(struct notification_client *client,
                        WARN("[notification-thread] Evaluation of a condition on client subscription failed, aborting.");
                        ret = -1;
                        free(client_list_element);
+                       pthread_mutex_unlock(&client_list->lock);
                        goto end;
                }
        }
@@ -2691,6 +2693,9 @@ int handle_notification_thread_command_register_trigger(
                goto error_free_ht_element;
        }
 
+       /* From this point consider the trigger registered. */
+       lttng_trigger_set_as_registered(trigger);
+
        /*
         * Some triggers might need a tracer notifier depending on its
         * condition and actions.
@@ -2890,6 +2895,11 @@ error_free_ht_element:
        }
 error:
        if (free_trigger) {
+               /*
+                * Other objects might have a reference to the trigger, mark it
+                * as unregistered.
+                */
+               lttng_trigger_set_as_unregistered(trigger);
                lttng_trigger_destroy(trigger);
        }
 end:
@@ -2971,6 +2981,12 @@ int handle_notification_thread_command_unregister_trigger(
                cmd_reply = LTTNG_OK;
        }
 
+       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) {
@@ -2993,9 +3009,6 @@ int handle_notification_thread_command_unregister_trigger(
                teardown_tracer_notifier(state, trigger);
        }
 
-       trigger_ht_element = caa_container_of(triggers_ht_node,
-                       struct lttng_trigger_ht_element, node);
-
        if (is_trigger_action_notify(trigger)) {
                /*
                 * Remove and release the client list from
@@ -4212,8 +4225,7 @@ int send_evaluation_to_clients(const struct lttng_trigger *trigger,
        };
 
        return notification_client_list_send_evaluation(client_list,
-                       lttng_trigger_get_const_condition(trigger), evaluation,
-                       lttng_trigger_get_credentials(trigger),
+                       trigger, evaluation,
                        &creds,
                        client_handle_transmission_status_wrapper, state);
 }
@@ -4254,9 +4266,8 @@ int send_evaluation_to_clients(const struct lttng_trigger *trigger,
 LTTNG_HIDDEN
 int notification_client_list_send_evaluation(
                struct notification_client_list *client_list,
-               const struct lttng_condition *condition,
+               const struct lttng_trigger *trigger,
                const struct lttng_evaluation *evaluation,
-               const struct lttng_credentials *trigger_creds,
                const struct lttng_credentials *source_object_creds,
                report_client_transmission_result_cb client_report,
                void *user_data)
@@ -4265,12 +4276,14 @@ int notification_client_list_send_evaluation(
        struct lttng_payload msg_payload;
        struct notification_client_list_element *client_list_element, *tmp;
        const struct lttng_notification notification = {
-               .condition = (struct lttng_condition *) condition,
+               .trigger = (struct lttng_trigger *) trigger,
                .evaluation = (struct lttng_evaluation *) evaluation,
        };
        struct lttng_notification_channel_message msg_header = {
                .type = (int8_t) LTTNG_NOTIFICATION_CHANNEL_MESSAGE_TYPE_NOTIFICATION,
        };
+       const struct lttng_credentials *trigger_creds =
+                       lttng_trigger_get_credentials(trigger);
 
        lttng_payload_init(&msg_payload);
 
@@ -4333,7 +4346,7 @@ int notification_client_list_send_evaluation(
                        }
                }
 
-               if (client->uid != lttng_credentials_get_uid(trigger_creds) && client->gid != lttng_credentials_get_gid(trigger_creds)) {
+               if (client->uid != lttng_credentials_get_uid(trigger_creds)) {
                        DBG("[notification-thread] Skipping client at it does not have the permission to receive notification for this trigger");
                        goto skip_client;
                }
@@ -4521,13 +4534,6 @@ int dispatch_one_event_notifier_notification(struct notification_thread_state *s
                        struct notification_trigger_tokens_ht_element,
                        node);
 
-       if (!lttng_trigger_should_fire(element->trigger)) {
-               ret = 0;
-               goto end_unlock;
-       }
-
-       lttng_trigger_fire(element->trigger);
-
        trigger_status = lttng_trigger_get_name(element->trigger, &trigger_name);
        assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
 
@@ -4550,7 +4556,6 @@ int dispatch_one_event_notifier_notification(struct notification_thread_state *s
                                                     element->trigger),
                                        struct lttng_condition_on_event,
                                        parent),
-                       trigger_name,
                        notification->capture_buffer,
                        notification->capture_buf_size, false);
 
@@ -4840,12 +4845,6 @@ int handle_notification_thread_channel_sample(
                        goto put_list;
                }
 
-               if (!lttng_trigger_should_fire(trigger)) {
-                       goto put_list;
-               }
-
-               lttng_trigger_fire(trigger);
-
                /*
                 * Ownership of `evaluation` transferred to the action executor
                 * no matter the result.
This page took 0.025869 seconds and 4 git commands to generate.