X-Git-Url: http://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fnotification-thread-events.c;h=a1af9c53526367018c774447837e352f2f349353;hp=b47a79528c329026870ed9afe4815b72da2be3fe;hb=513676343b23fd9743291679cff46756238bf360;hpb=242388e491e4219f967ee424d7bf02035a313e6f diff --git a/src/bin/lttng-sessiond/notification-thread-events.c b/src/bin/lttng-sessiond/notification-thread-events.c index b47a79528..a1af9c535 100644 --- a/src/bin/lttng-sessiond/notification-thread-events.c +++ b/src/bin/lttng-sessiond/notification-thread-events.c @@ -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) { @@ -2232,9 +2287,14 @@ int handle_notification_thread_command_register_trigger( uid_t object_uid; gid_t object_gid; enum action_executor_status executor_status; + const uint64_t trigger_tracer_token = + state->trigger_id.next_tracer_token++; rcu_read_lock(); + /* 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( @@ -2473,6 +2533,8 @@ int handle_notification_thread_command_register_trigger( end: *cmd_result = LTTNG_OK; + DBG("Registered trigger: name = `%s`, tracer token = %" PRIu64, + trigger_name, trigger_tracer_token); error_put_client_list: notification_client_list_put(client_list); @@ -2536,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; } @@ -2553,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, @@ -2651,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; @@ -4092,6 +4164,12 @@ 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.