Only perform notification related unregistering when action is notify
[lttng-tools.git] / src / bin / lttng-sessiond / notification-thread-events.c
index 40450304297230b96cdf980afde1b516dc6c02c9..a1af9c53526367018c774447837e352f2f349353 100644 (file)
@@ -1984,6 +1984,61 @@ end:
        return ret;
 }
 
+static int handle_notification_thread_command_list_triggers(
+               struct notification_thread_handle *handle,
+               struct notification_thread_state *state,
+               uid_t client_uid,
+               struct lttng_triggers **triggers,
+               enum lttng_error_code *_cmd_result)
+{
+       int ret = 0;
+       enum lttng_error_code cmd_result = LTTNG_OK;
+       struct cds_lfht_iter iter;
+       struct lttng_trigger_ht_element *trigger_ht_element;
+       struct lttng_triggers *local_triggers = NULL;
+       const struct lttng_credentials *creds;
+
+       rcu_read_lock();
+
+       local_triggers = lttng_triggers_create();
+       if (!local_triggers) {
+               /* Not a fatal error. */
+               cmd_result = LTTNG_ERR_NOMEM;
+               goto end;
+       }
+
+       cds_lfht_for_each_entry(state->triggers_ht, &iter,
+                       trigger_ht_element, node) {
+               /*
+                * Only return the triggers to which the client has access.
+                * The root user has visibility over all triggers.
+                */
+               creds = lttng_trigger_get_credentials(trigger_ht_element->trigger);
+               if (client_uid != lttng_credentials_get_uid(creds) && client_uid != 0) {
+                       continue;
+               }
+
+               ret = lttng_triggers_add(local_triggers,
+                               trigger_ht_element->trigger);
+               if (ret < 0) {
+                       /* Not a fatal error. */
+                       ret = 0;
+                       cmd_result = LTTNG_ERR_NOMEM;
+                       goto end;
+               }
+       }
+
+       /* Transferring ownership to the caller. */
+       *triggers = local_triggers;
+       local_triggers = NULL;
+
+end:
+       rcu_read_unlock();
+       lttng_triggers_destroy(local_triggers);
+       *_cmd_result = cmd_result;
+       return ret;
+}
+
 static
 int condition_is_supported(struct lttng_condition *condition)
 {
@@ -2543,13 +2598,7 @@ int handle_notification_thread_command_unregister_trigger(
 
                cds_list_for_each_entry_safe(trigger_element, tmp,
                                &trigger_list->list, node) {
-                       const struct lttng_condition *current_condition =
-                                       lttng_trigger_get_const_condition(
-                                               trigger_element->trigger);
-
-                       assert(current_condition);
-                       if (!lttng_condition_is_equal(condition,
-                                       current_condition)) {
+                       if (!lttng_trigger_is_equal(trigger, trigger_element->trigger)) {
                                continue;
                        }
 
@@ -2560,17 +2609,19 @@ int handle_notification_thread_command_unregister_trigger(
                }
        }
 
-       /*
-        * Remove and release the client list from
-        * notification_trigger_clients_ht.
-        */
-       client_list = get_client_list_from_condition(state, condition);
-       assert(client_list);
+       if (is_trigger_action_notify(trigger)) {
+               /*
+                * Remove and release the client list from
+                * notification_trigger_clients_ht.
+                */
+               client_list = get_client_list_from_condition(state, condition);
+               assert(client_list);
 
-       /* Put new reference and the hashtable's reference. */
-       notification_client_list_put(client_list);
-       notification_client_list_put(client_list);
-       client_list = NULL;
+               /* Put new reference and the hashtable's reference. */
+               notification_client_list_put(client_list);
+               notification_client_list_put(client_list);
+               client_list = NULL;
+       }
 
        /* Remove trigger from triggers_ht. */
        trigger_ht_element = caa_container_of(triggers_ht_node,
@@ -2658,6 +2709,20 @@ int handle_notification_thread_command(
                                cmd->parameters.session_rotation.location,
                                &cmd->reply_code);
                break;
+       case NOTIFICATION_COMMAND_TYPE_LIST_TRIGGERS:
+       {
+               struct lttng_triggers *triggers = NULL;
+
+               ret = handle_notification_thread_command_list_triggers(
+                               handle,
+                               state,
+                               cmd->parameters.list_triggers.uid,
+                               &triggers,
+                               &cmd->reply_code);
+               cmd->reply.list_triggers.triggers = triggers;
+               ret = 0;
+               break;
+       }
        case NOTIFICATION_COMMAND_TYPE_QUIT:
                DBG("[notification-thread] Received quit command");
                cmd->reply_code = LTTNG_OK;
This page took 0.024079 seconds and 4 git commands to generate.