From: Jérémie Galarneau Date: Tue, 26 Jan 2021 23:15:15 +0000 (-0500) Subject: sessiond: unregister triggers during clean-up on shutdown X-Git-Tag: v2.13.0-rc1~365 X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=commitdiff_plain;h=b69a1b4064e50db1192d79fd92305182cfc5829e sessiond: unregister triggers during clean-up on shutdown Triggers should be unregistered on sessiond clean-up. This allows the kernel and user space tracer control code to assume that all event notifiers have already been destroyed on tear-down and that any remaining event notifier is the result of a leak. Moreover, it simplifies the tear down as it is simply handled in the way a regular trigger unregistration would be. Signed-off-by: Jérémie Galarneau Change-Id: Ie821c5162c2fbe9c3d6705f464224c50ae9df1c8 --- diff --git a/src/bin/lttng-sessiond/kernel.c b/src/bin/lttng-sessiond/kernel.c index 4bb8045e7..3216ffcf5 100644 --- a/src/bin/lttng-sessiond/kernel.c +++ b/src/bin/lttng-sessiond/kernel.c @@ -2065,20 +2065,9 @@ error: LTTNG_HIDDEN void cleanup_kernel_tracer(void) { - int ret; - struct cds_lfht_iter iter; - struct ltt_kernel_event_notifier_rule *rule = NULL; - - rcu_read_lock(); - cds_lfht_for_each_entry(kernel_token_to_event_notifier_rule_ht, &iter, rule, ht_node) { - kernel_disable_event_notifier_rule(rule); - trace_kernel_destroy_event_notifier_rule(rule); - } - rcu_read_unlock(); - DBG2("Closing kernel event notifier group notification file descriptor"); if (kernel_tracer_event_notifier_group_notification_fd >= 0) { - ret = notification_thread_command_remove_tracer_event_source( + int ret = notification_thread_command_remove_tracer_event_source( notification_thread_handle, kernel_tracer_event_notifier_group_notification_fd); if (ret != LTTNG_OK) { @@ -2095,13 +2084,15 @@ void cleanup_kernel_tracer(void) } if (kernel_token_to_event_notifier_rule_ht) { - ret = cds_lfht_destroy(kernel_token_to_event_notifier_rule_ht, NULL); + const int ret = cds_lfht_destroy( + kernel_token_to_event_notifier_rule_ht, NULL); assert(ret == 0); } DBG2("Closing kernel event notifier group file descriptor"); if (kernel_tracer_event_notifier_group_fd >= 0) { - ret = close(kernel_tracer_event_notifier_group_fd); + const int ret = close(kernel_tracer_event_notifier_group_fd); + if (ret) { PERROR("Failed to close kernel event notifier group file descriptor: fd = %d", kernel_tracer_event_notifier_group_fd); @@ -2112,7 +2103,8 @@ void cleanup_kernel_tracer(void) DBG2("Closing kernel fd"); if (kernel_tracer_fd >= 0) { - ret = close(kernel_tracer_fd); + const int ret = close(kernel_tracer_fd); + if (ret) { PERROR("Failed to close kernel tracer file descriptor: fd = %d", kernel_tracer_fd); diff --git a/src/bin/lttng-sessiond/main.c b/src/bin/lttng-sessiond/main.c index e646a6de5..9f8c9a332 100644 --- a/src/bin/lttng-sessiond/main.c +++ b/src/bin/lttng-sessiond/main.c @@ -1254,6 +1254,63 @@ static void destroy_all_sessions_and_wait(void) DBG("Destruction of all sessions completed"); } +static void unregister_all_triggers(void) +{ + enum lttng_error_code ret_code; + enum lttng_trigger_status trigger_status; + struct lttng_triggers *triggers = NULL; + unsigned int trigger_count, i; + const struct lttng_credentials creds = { + .uid = LTTNG_OPTIONAL_INIT_VALUE(0), + }; + + DBG("Unregistering all triggers"); + + /* + * List all triggers as "root" since we wish to unregister all triggers. + */ + ret_code = notification_thread_command_list_triggers( + notification_thread_handle, creds.uid.value, &triggers); + if (ret_code != LTTNG_OK) { + ERR("Failed to list triggers while unregistering all triggers"); + goto end; + } + + trigger_status = lttng_triggers_get_count(triggers, &trigger_count); + assert(trigger_status == LTTNG_TRIGGER_STATUS_OK); + + for (i = 0; i < trigger_count; i++) { + enum lttng_error_code ret_code; + uid_t trigger_owner; + const char *trigger_name; + const struct lttng_trigger *trigger = + lttng_triggers_get_at_index(triggers, i); + + assert(trigger); + + trigger_status = lttng_trigger_get_owner_uid( + trigger, &trigger_owner); + assert(trigger_status == LTTNG_TRIGGER_STATUS_OK); + + trigger_status = lttng_trigger_get_name(trigger, &trigger_name); + assert(trigger_status == LTTNG_TRIGGER_STATUS_OK); + + DBG("Unregistering trigger: trigger owner uid = %d, trigger name = '%s'", + (int) trigger_owner, trigger_name); + + ret_code = cmd_unregister_trigger( + &creds, trigger, notification_thread_handle); + if (ret_code != LTTNG_OK) { + ERR("Failed to unregister trigger: trigger owner uid = %d, trigger name = '%s', error: '%s'", + (int) trigger_owner, trigger_name, + lttng_strerror(-ret_code)); + /* Continue to unregister the remaining triggers. */ + } + } +end: + lttng_triggers_destroy(triggers); +} + static int run_as_worker_post_fork_cleanup(void *data) { struct sessiond_config *sessiond_config = data; @@ -1772,6 +1829,13 @@ stop_threads: destroy_all_sessions_and_wait(); + /* + * At this point no new trigger can be registered (no sessions are + * running/rotating) and clients can't connect to the session daemon + * anymore. Unregister all triggers. + */ + unregister_all_triggers(); + if (register_apps_thread) { lttng_thread_shutdown(register_apps_thread); lttng_thread_put(register_apps_thread); diff --git a/src/bin/lttng-sessiond/ust-app.c b/src/bin/lttng-sessiond/ust-app.c index 3a899775d..a1891d805 100644 --- a/src/bin/lttng-sessiond/ust-app.c +++ b/src/bin/lttng-sessiond/ust-app.c @@ -4314,16 +4314,12 @@ void ust_app_clean_list(void) if (ust_app_ht_by_notify_sock) { cds_lfht_for_each_entry(ust_app_ht_by_notify_sock->ht, &iter.iter, app, notify_sock_n.node) { - struct cds_lfht_node *node; - struct ust_app *app; - - node = cds_lfht_iter_get_node(&iter.iter); - if (!node) { - continue; - } + /* + * Assert that all notifiers are gone as all triggers + * are unregistered prior to this clean-up. + */ + assert(lttng_ht_get_count(app->token_to_event_notifier_rule_ht) == 0); - app = container_of(node, struct ust_app, - notify_sock_n.node); ust_app_notify_sock_unregister(app->notify_sock); } }