From: Jérémie Galarneau Date: Tue, 20 Apr 2021 04:43:22 +0000 (-0400) Subject: sessiond: add support for anonymous triggers X-Git-Tag: v2.13.0-rc1~30 X-Git-Url: https://git.lttng.org./?a=commitdiff_plain;h=0efb2ad7fc448283184e43d6fb0915febae45384;p=lttng-tools.git sessiond: add support for anonymous triggers Signed-off-by: Jérémie Galarneau Change-Id: I5b7fb29700af7ac7b633e5d73fb29f99f55ebfe8 --- diff --git a/src/bin/lttng-sessiond/action-executor.c b/src/bin/lttng-sessiond/action-executor.c index aa55782e2..9a89865a9 100644 --- a/src/bin/lttng-sessiond/action-executor.c +++ b/src/bin/lttng-sessiond/action-executor.c @@ -206,7 +206,16 @@ static const char *get_trigger_name(const struct lttng_trigger *trigger) enum lttng_trigger_status trigger_status; trigger_status = lttng_trigger_get_name(trigger, &trigger_name); - assert(trigger_status == LTTNG_TRIGGER_STATUS_OK); + switch (trigger_status) { + case LTTNG_TRIGGER_STATUS_OK: + break; + case LTTNG_TRIGGER_STATUS_UNSET: + trigger_name = "(anonymous)"; + break; + default: + trigger_name = "(failed to get name)"; + break; + } return trigger_name; } @@ -772,17 +781,7 @@ static void *action_executor_thread(void *_data) uid_t trigger_owner_uid; enum lttng_trigger_status trigger_status; - trigger_status = lttng_trigger_get_name( - work_item->trigger, &trigger_name); - switch (trigger_status) { - case LTTNG_TRIGGER_STATUS_OK: - break; - case LTTNG_TRIGGER_STATUS_UNSET: - trigger_name = "(unset)"; - break; - default: - abort(); - } + trigger_name = get_trigger_name(work_item->trigger); trigger_status = lttng_trigger_get_owner_uid( work_item->trigger, &trigger_owner_uid); diff --git a/src/bin/lttng-sessiond/client.c b/src/bin/lttng-sessiond/client.c index 6943a776e..c10b9bc87 100644 --- a/src/bin/lttng-sessiond/client.c +++ b/src/bin/lttng-sessiond/client.c @@ -2247,6 +2247,7 @@ error_add_context: original_reply_payload_size = cmd_ctx->reply_payload.buffer.size; ret = cmd_register_trigger(&cmd_creds, payload_trigger, + cmd_ctx->lsm.u.trigger.is_trigger_anonymous, the_notification_thread_handle, &return_trigger); if (ret != LTTNG_OK) { diff --git a/src/bin/lttng-sessiond/cmd.c b/src/bin/lttng-sessiond/cmd.c index 45bf3b78f..f0d5c571d 100644 --- a/src/bin/lttng-sessiond/cmd.c +++ b/src/bin/lttng-sessiond/cmd.c @@ -4320,8 +4320,7 @@ enum lttng_error_code synchronize_tracer_notifier_register( trigger_status = lttng_trigger_get_name(trigger, &trigger_name); trigger_name = trigger_status == LTTNG_TRIGGER_STATUS_OK ? - trigger_name : - "(unnamed)"; + trigger_name : "(anonymous)"; session_lock_list(); switch (trigger_domain) { @@ -4386,6 +4385,7 @@ end_unlock_session_list: enum lttng_error_code cmd_register_trigger(const struct lttng_credentials *cmd_creds, struct lttng_trigger *trigger, + bool is_trigger_anonymous, struct notification_thread_handle *notification_thread, struct lttng_trigger **return_trigger) { @@ -4396,7 +4396,7 @@ enum lttng_error_code cmd_register_trigger(const struct lttng_credentials *cmd_c trigger_status = lttng_trigger_get_name(trigger, &trigger_name); trigger_name = trigger_status == LTTNG_TRIGGER_STATUS_OK ? - trigger_name : "(unnamed)"; + trigger_name : "(anonymous)"; trigger_status = lttng_trigger_get_owner_uid( trigger, &trigger_owner); @@ -4444,8 +4444,8 @@ enum lttng_error_code cmd_register_trigger(const struct lttng_credentials *cmd_c * it is safe to use without any locking as its properties are * immutable. */ - ret_code = notification_thread_command_register_trigger(notification_thread, - trigger); + ret_code = notification_thread_command_register_trigger( + notification_thread, trigger, is_trigger_anonymous); if (ret_code != LTTNG_OK) { DBG("Failed to register trigger to notification thread: trigger name = '%s', trigger owner uid = %d, error code = %d", trigger_name, (int) trigger_owner, ret_code); @@ -4454,7 +4454,7 @@ enum lttng_error_code cmd_register_trigger(const struct lttng_credentials *cmd_c trigger_status = lttng_trigger_get_name(trigger, &trigger_name); trigger_name = trigger_status == LTTNG_TRIGGER_STATUS_OK ? - trigger_name : "(unnamed)"; + trigger_name : "(anonymous)"; /* * Synchronize tracers if the trigger adds an event notifier. @@ -4556,7 +4556,7 @@ enum lttng_error_code cmd_unregister_trigger(const struct lttng_credentials *cmd struct lttng_trigger *sessiond_trigger = NULL; trigger_status = lttng_trigger_get_name(trigger, &trigger_name); - trigger_name = trigger_status == LTTNG_TRIGGER_STATUS_OK ? trigger_name : "(unnamed)"; + trigger_name = trigger_status == LTTNG_TRIGGER_STATUS_OK ? trigger_name : "(anonymous)"; trigger_status = lttng_trigger_get_owner_uid(trigger, &trigger_owner); assert(trigger_status == LTTNG_TRIGGER_STATUS_OK); @@ -4702,7 +4702,7 @@ enum lttng_error_code cmd_execute_error_query(const struct lttng_credentials *cm trigger_status = lttng_trigger_get_name(matching_trigger, &trigger_name); trigger_name = trigger_status == LTTNG_TRIGGER_STATUS_OK ? - trigger_name : "(unnamed)"; + trigger_name : "(anonymous)"; trigger_status = lttng_trigger_get_owner_uid(matching_trigger, &trigger_owner); assert(trigger_status == LTTNG_TRIGGER_STATUS_OK); diff --git a/src/bin/lttng-sessiond/cmd.h b/src/bin/lttng-sessiond/cmd.h index 9aa13ff22..33cac66ff 100644 --- a/src/bin/lttng-sessiond/cmd.h +++ b/src/bin/lttng-sessiond/cmd.h @@ -144,6 +144,7 @@ int cmd_regenerate_statedump(struct ltt_session *session); enum lttng_error_code cmd_register_trigger( const struct lttng_credentials *cmd_creds, struct lttng_trigger *trigger, + bool is_anonymous_trigger, struct notification_thread_handle *notification_thread_handle, struct lttng_trigger **return_trigger); enum lttng_error_code cmd_unregister_trigger( diff --git a/src/bin/lttng-sessiond/event-notifier-error-accounting.c b/src/bin/lttng-sessiond/event-notifier-error-accounting.c index 61ba6981e..aac685467 100644 --- a/src/bin/lttng-sessiond/event-notifier-error-accounting.c +++ b/src/bin/lttng-sessiond/event-notifier-error-accounting.c @@ -78,7 +78,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(); diff --git a/src/bin/lttng-sessiond/event.c b/src/bin/lttng-sessiond/event.c index 50d8fd028..60aa2cde8 100644 --- a/src/bin/lttng-sessiond/event.c +++ b/src/bin/lttng-sessiond/event.c @@ -592,7 +592,7 @@ int trigger_agent_enable(const struct lttng_trigger *trigger, struct agent *agt) t_status = lttng_trigger_get_name(trigger, &trigger_name); if (t_status != LTTNG_TRIGGER_STATUS_OK) { - trigger_name = "(unnamed)"; + trigger_name = "(anonymous)"; } t_status = lttng_trigger_get_owner_uid(trigger, &trigger_owner_uid); diff --git a/src/bin/lttng-sessiond/main.c b/src/bin/lttng-sessiond/main.c index 05566d5f8..02e18a22c 100644 --- a/src/bin/lttng-sessiond/main.c +++ b/src/bin/lttng-sessiond/main.c @@ -1363,7 +1363,8 @@ static void unregister_all_triggers(void) assert(trigger_status == LTTNG_TRIGGER_STATUS_OK); trigger_status = lttng_trigger_get_name(trigger, &trigger_name); - assert(trigger_status == LTTNG_TRIGGER_STATUS_OK); + trigger_name = trigger_status == LTTNG_TRIGGER_STATUS_OK ? + trigger_name : "(anonymous)"; DBG("Unregistering trigger: trigger owner uid = %d, trigger name = '%s'", (int) trigger_owner, trigger_name); diff --git a/src/bin/lttng-sessiond/notification-thread-commands.c b/src/bin/lttng-sessiond/notification-thread-commands.c index 7f031e742..89eb37bb1 100644 --- a/src/bin/lttng-sessiond/notification-thread-commands.c +++ b/src/bin/lttng-sessiond/notification-thread-commands.c @@ -111,7 +111,8 @@ error: enum lttng_error_code notification_thread_command_register_trigger( struct notification_thread_handle *handle, - struct lttng_trigger *trigger) + struct lttng_trigger *trigger, + bool is_trigger_anonymous) { int ret; enum lttng_error_code ret_code; @@ -123,6 +124,8 @@ enum lttng_error_code notification_thread_command_register_trigger( cmd.type = NOTIFICATION_COMMAND_TYPE_REGISTER_TRIGGER; lttng_trigger_get(trigger); cmd.parameters.register_trigger.trigger = trigger; + cmd.parameters.register_trigger.is_trigger_anonymous = + is_trigger_anonymous; ret = run_command_wait(handle, &cmd); if (ret) { diff --git a/src/bin/lttng-sessiond/notification-thread-commands.h b/src/bin/lttng-sessiond/notification-thread-commands.h index 882959a29..0aa7a80c3 100644 --- a/src/bin/lttng-sessiond/notification-thread-commands.h +++ b/src/bin/lttng-sessiond/notification-thread-commands.h @@ -43,6 +43,7 @@ struct notification_thread_command { /* Register trigger. */ struct { struct lttng_trigger *trigger; + bool is_trigger_anonymous; } register_trigger; /* Unregister trigger. */ struct { @@ -112,7 +113,8 @@ struct notification_thread_command { enum lttng_error_code notification_thread_command_register_trigger( struct notification_thread_handle *handle, - struct lttng_trigger *trigger); + struct lttng_trigger *trigger, + bool is_anonymous_trigger); enum lttng_error_code notification_thread_command_unregister_trigger( struct notification_thread_handle *handle, diff --git a/src/bin/lttng-sessiond/notification-thread-events.c b/src/bin/lttng-sessiond/notification-thread-events.c index 9e4ad7cb8..178b80fa2 100644 --- a/src/bin/lttng-sessiond/notification-thread-events.c +++ b/src/bin/lttng-sessiond/notification-thread-events.c @@ -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; } @@ -2253,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(); @@ -2635,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; @@ -2657,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); @@ -3091,6 +3108,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: @@ -4537,11 +4555,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; @@ -4566,9 +4582,6 @@ 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_event_rule_matches_get_capture_descriptor_count( lttng_trigger_get_const_condition(element->trigger), &capture_count) != LTTNG_CONDITION_STATUS_OK) { diff --git a/src/bin/lttng-sessiond/rotate.c b/src/bin/lttng-sessiond/rotate.c index 097da860a..ec0aa6668 100644 --- a/src/bin/lttng-sessiond/rotate.c +++ b/src/bin/lttng-sessiond/rotate.c @@ -104,7 +104,8 @@ int subscribe_session_consumed_size_rotation(struct ltt_session *session, uint64 } ret = notification_thread_command_register_trigger( - notification_thread_handle, session->rotate_trigger); + notification_thread_handle, session->rotate_trigger, + true); if (ret < 0 && ret != -LTTNG_ERR_TRIGGER_EXISTS) { ERR("Register trigger, %s", lttng_strerror(ret)); ret = -1; diff --git a/src/bin/lttng-sessiond/trigger-error-query.c b/src/bin/lttng-sessiond/trigger-error-query.c index 54aeb4149..4c464004d 100644 --- a/src/bin/lttng-sessiond/trigger-error-query.c +++ b/src/bin/lttng-sessiond/trigger-error-query.c @@ -24,7 +24,7 @@ enum lttng_trigger_status lttng_trigger_add_error_results( status = lttng_trigger_get_name(trigger, &trigger_name); trigger_name = status == LTTNG_TRIGGER_STATUS_OK ? - trigger_name : "(unnamed)"; + trigger_name : "(anonymous)"; status = lttng_trigger_get_owner_uid(trigger, &trigger_owner); assert(status == LTTNG_TRIGGER_STATUS_OK); @@ -80,7 +80,7 @@ enum lttng_trigger_status lttng_trigger_add_action_error_query_results( status = lttng_trigger_get_name(trigger, &trigger_name); trigger_name = status == LTTNG_TRIGGER_STATUS_OK ? - trigger_name : "(unnamed)"; + trigger_name : "(anonymous)"; status = lttng_trigger_get_owner_uid(trigger, &trigger_owner); assert(status == LTTNG_TRIGGER_STATUS_OK); diff --git a/src/bin/lttng/commands/list_triggers.c b/src/bin/lttng/commands/list_triggers.c index b497d4f4d..bb90e7b6e 100644 --- a/src/bin/lttng/commands/list_triggers.c +++ b/src/bin/lttng/commands/list_triggers.c @@ -556,6 +556,9 @@ void print_action_errors(const struct lttng_trigger *trigger, assert(query); trigger_status = lttng_trigger_get_name(trigger, &trigger_name); + /* + * Anonymous triggers are not listed; this would be an internal error. + */ assert(trigger_status == LTTNG_TRIGGER_STATUS_OK); trigger_status = lttng_trigger_get_owner_uid(trigger, &trigger_uid); @@ -812,7 +815,9 @@ void print_trigger_errors(const struct lttng_trigger *trigger) lttng_error_query_trigger_create(trigger); assert(query); - + /* + * Anonymous triggers are not listed; this would be an internal error. + */ trigger_status = lttng_trigger_get_name(trigger, &trigger_name); assert(trigger_status == LTTNG_TRIGGER_STATUS_OK); @@ -893,7 +898,15 @@ void print_one_trigger(const struct lttng_trigger *trigger) const char *name; uid_t trigger_uid; + /* + * Anonymous triggers are not listed since they can't be specified nor + * referenced through the CLI. + */ trigger_status = lttng_trigger_get_name(trigger, &name); + if (trigger_status == LTTNG_TRIGGER_STATUS_UNSET) { + goto end; + } + assert(trigger_status == LTTNG_TRIGGER_STATUS_OK); trigger_status = lttng_trigger_get_owner_uid(trigger, &trigger_uid); @@ -949,6 +962,8 @@ void print_one_trigger(const struct lttng_trigger *trigger) } print_trigger_errors(trigger); +end: + return; } static @@ -959,6 +974,7 @@ int compare_triggers_by_name(const void *a, const void *b) const char *name_a, *name_b; enum lttng_trigger_status trigger_status; + /* Anonymous triggers are not reachable here. */ trigger_status = lttng_trigger_get_name(trigger_a, &name_a); assert(trigger_status == LTTNG_TRIGGER_STATUS_OK); @@ -1032,9 +1048,24 @@ int cmd_list_triggers(int argc, const char **argv) } for (i = 0; i < num_triggers; i++) { - const int add_ret = lttng_dynamic_pointer_array_add_pointer( - &sorted_triggers, - (void *) lttng_triggers_get_at_index(triggers, i)); + int add_ret; + const char *unused_name; + const struct lttng_trigger *trigger = + lttng_triggers_get_at_index(triggers, i); + + trigger_status = lttng_trigger_get_name(trigger, &unused_name); + switch (trigger_status) { + case LTTNG_TRIGGER_STATUS_OK: + break; + case LTTNG_TRIGGER_STATUS_UNSET: + /* Don't list anonymous triggers. */ + continue; + default: + abort(); + } + + add_ret = lttng_dynamic_pointer_array_add_pointer( + &sorted_triggers, (void *) trigger); if (add_ret) { ERR("Failed to allocate array of struct lttng_trigger *."); diff --git a/src/bin/lttng/commands/remove_trigger.c b/src/bin/lttng/commands/remove_trigger.c index 401b59742..f923cdd4b 100644 --- a/src/bin/lttng/commands/remove_trigger.c +++ b/src/bin/lttng/commands/remove_trigger.c @@ -151,7 +151,15 @@ int cmd_remove_trigger(int argc, const char **argv) trigger = lttng_triggers_get_at_index(triggers, i); trigger_status = lttng_trigger_get_name(trigger, &trigger_name); - assert(trigger_status == LTTNG_TRIGGER_STATUS_OK); + switch (trigger_status) { + case LTTNG_TRIGGER_STATUS_OK: + break; + case LTTNG_TRIGGER_STATUS_UNSET: + /* Don't compare against anonymous triggers. */ + continue; + default: + abort(); + } trigger_status = lttng_trigger_get_owner_uid( trigger, &trigger_uid); diff --git a/src/common/sessiond-comm/sessiond-comm.h b/src/common/sessiond-comm/sessiond-comm.h index d24d2f580..7b3e0f509 100644 --- a/src/common/sessiond-comm/sessiond-comm.h +++ b/src/common/sessiond-comm/sessiond-comm.h @@ -486,6 +486,7 @@ struct lttcomm_session_msg { } LTTNG_PACKED process_attr_tracker_set_tracking_policy; struct { uint32_t length; + uint8_t is_trigger_anonymous; } LTTNG_PACKED trigger; struct { uint32_t length; diff --git a/src/common/trigger.c b/src/common/trigger.c index a86295069..5c48609ea 100644 --- a/src/common/trigger.c +++ b/src/common/trigger.c @@ -346,7 +346,12 @@ LTTNG_HIDDEN bool lttng_trigger_is_equal( const struct lttng_trigger *a, const struct lttng_trigger *b) { - if (strcmp(a->name, b->name) != 0) { + if (!!a->name != !!b->name) { + /* Both must be either anonymous or named. */ + return false; + } + + if (a->name && strcmp(a->name, b->name) != 0) { return false; } diff --git a/tests/regression/tools/notification/notification.c b/tests/regression/tools/notification/notification.c index ce6f56332..c097c1026 100644 --- a/tests/regression/tools/notification/notification.c +++ b/tests/regression/tools/notification/notification.c @@ -590,7 +590,13 @@ static const char *get_notification_trigger_name( } trigger_status = lttng_trigger_get_name(trigger, &trigger_name); - if (trigger_status != LTTNG_TRIGGER_STATUS_OK) { + switch (trigger_status) { + case LTTNG_TRIGGER_STATUS_OK: + break; + case LTTNG_TRIGGER_STATUS_UNSET: + trigger_name = "(anonymous)"; + break; + default: fail("Failed to get name from notification's trigger"); goto end; } diff --git a/tests/regression/tools/trigger/utils/notification-client.c b/tests/regression/tools/trigger/utils/notification-client.c index ac572bfc6..98c00d6f7 100644 --- a/tests/regression/tools/trigger/utils/notification-client.c +++ b/tests/regression/tools/trigger/utils/notification-client.c @@ -62,6 +62,7 @@ static bool action_list_contains_notify( return false; } +/* Only expects named triggers. */ static bool is_trigger_name(const char *expected_trigger_name, struct lttng_notification *notification) {