Fix: sessiond: acquire session list lock when updating event notifiers
authorJérémie Galarneau <jeremie.galarneau@efficios.com>
Thu, 4 Feb 2021 23:18:32 +0000 (18:18 -0500)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Thu, 4 Feb 2021 23:31:23 +0000 (18:31 -0500)
Registering triggers with an on-event hit condition affects event
notifiers, imposing a synchronization of enablers with the user space
tracers.

As noted in the comments of session.h, the session list lock protects
those updates and is, ultimately, ill-named. The comment is adjusted to
mention "tracer configurations" rather than "session configurations"
since event notifiers are not part of a session, making the comment
imprecise.

Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
Change-Id: Id1bcbcccbdeeafa91176ed3413ddddbcbab10ad2

src/bin/lttng-sessiond/cmd.c
src/bin/lttng-sessiond/session.h

index d8b0637534aec9d4f99dab23a6742b2cdb1a2c93..505645bf1ce1cb69c864fadb322a3d366e493944 100644 (file)
@@ -4317,7 +4317,7 @@ enum lttng_error_code cmd_register_trigger(const struct lttng_credentials *cmd_c
                struct lttng_trigger **return_trigger)
 {
        enum lttng_error_code ret_code;
-       bool must_update_event_notifier;
+       bool must_update_event_notifiers;
        const char *trigger_name;
        uid_t trigger_owner;
        enum lttng_trigger_status trigger_status;
@@ -4384,7 +4384,7 @@ enum lttng_error_code cmd_register_trigger(const struct lttng_credentials *cmd_c
        trigger_name = trigger_status == LTTNG_TRIGGER_STATUS_OK ?
                        trigger_name : "(unnamed)";
 
-       ret_code = trigger_modifies_event_notifier(trigger, &must_update_event_notifier);
+       ret_code = trigger_modifies_event_notifier(trigger, &must_update_event_notifiers);
        if (ret_code != LTTNG_OK) {
                ERR("Failed to determine if event modifies event notifiers: trigger name = '%s', trigger owner uid = %d, error code = %d",
                                trigger_name, (int) trigger_owner, ret_code);
@@ -4394,10 +4394,11 @@ enum lttng_error_code cmd_register_trigger(const struct lttng_credentials *cmd_c
        /*
         * Synchronize tracers if the trigger adds an event notifier.
         */
-       if (must_update_event_notifier) {
+       if (must_update_event_notifiers) {
                const enum lttng_domain_type trigger_domain =
                                lttng_trigger_get_underlying_domain_type_restriction(trigger);
 
+               session_lock_list();
                switch (trigger_domain) {
                case LTTNG_DOMAIN_KERNEL:
                {
@@ -4434,19 +4435,21 @@ enum lttng_error_code cmd_register_trigger(const struct lttng_credentials *cmd_c
                                agt = agent_create(trigger_domain);
                                if (!agt) {
                                        ret_code = LTTNG_ERR_NOMEM;
-                                       goto end;
+                                       goto end_unlock_session_list;
                                }
                                agent_add(agt, trigger_agents_ht_by_domain);
                        }
 
                        ret_code = trigger_agent_enable(trigger, agt);
                        if (ret_code != LTTNG_OK) {
-                               goto end;
+                               goto end_unlock_session_list;
                        }
 
                        break;
                }
                }
+
+               session_unlock_list();
        }
 
        /*
@@ -4462,6 +4465,9 @@ enum lttng_error_code cmd_register_trigger(const struct lttng_credentials *cmd_c
        trigger = NULL;
 end:
        return ret_code;
+end_unlock_session_list:
+       session_unlock_list();
+       return ret_code;
 }
 
 enum lttng_error_code cmd_unregister_trigger(const struct lttng_credentials *cmd_creds,
@@ -4469,7 +4475,7 @@ enum lttng_error_code cmd_unregister_trigger(const struct lttng_credentials *cmd
                struct notification_thread_handle *notification_thread)
 {
        enum lttng_error_code ret_code;
-       bool must_update_event_notifier;
+       bool must_update_event_notifiers;
        const char *trigger_name;
        uid_t trigger_owner;
        enum lttng_trigger_status trigger_status;
@@ -4501,7 +4507,7 @@ enum lttng_error_code cmd_unregister_trigger(const struct lttng_credentials *cmd
                }
        }
 
-       ret_code = trigger_modifies_event_notifier(trigger, &must_update_event_notifier);
+       ret_code = trigger_modifies_event_notifier(trigger, &must_update_event_notifiers);
        if (ret_code != LTTNG_OK) {
                ERR("Failed to determine if event modifies event notifiers: trigger name = '%s', trigger owner uid = %d, error code = %d",
                                trigger_name, (int) trigger_owner, ret_code);
@@ -4521,11 +4527,12 @@ enum lttng_error_code cmd_unregister_trigger(const struct lttng_credentials *cmd
         * the tracers from producing notifications associated with this
         * event notifier.
         */
-       if (must_update_event_notifier) {
+       if (must_update_event_notifiers) {
                const enum lttng_domain_type trigger_domain =
                                lttng_trigger_get_underlying_domain_type_restriction(
                                                trigger);
 
+               session_lock_list();
                switch (trigger_domain) {
                case LTTNG_DOMAIN_KERNEL:
                {
@@ -4548,24 +4555,28 @@ enum lttng_error_code cmd_unregister_trigger(const struct lttng_credentials *cmd
                                agt = agent_create(trigger_domain);
                                if (!agt) {
                                        ret_code = LTTNG_ERR_NOMEM;
-                                       goto end;
+                                       goto end_unlock_session_list;
                                }
                                agent_add(agt, trigger_agents_ht_by_domain);
                        }
 
                        ret_code = trigger_agent_disable(trigger, agt);
                        if (ret_code != LTTNG_OK) {
-                               goto end;
+                               goto end_unlock_session_list;
                        }
 
                        break;
                }
                }
+
+               session_unlock_list();
        }
 
 end:
        return ret_code;
-}
+end_unlock_session_list:
+       session_unlock_list();
+       return ret_code;}
 
 int cmd_list_triggers(struct command_ctx *cmd_ctx,
                struct notification_thread_handle *notification_thread,
index 9b790c1fe94df7911db72b2f9674eee7a089b138..5ff20ad412eea13c1cdde2e0aa4c6e9202d37399 100644 (file)
@@ -206,7 +206,7 @@ void session_unlock(struct ltt_session *session);
  * also used as a multi-session lock when synchronizing newly-registered
  * 'user space tracer' and 'agent' applications.
  *
- * In other words, it prevents session configurations from changing while they
+ * In other words, it prevents tracer configurations from changing while they
  * are being transmitted to the various applications.
  */
 void session_lock_list(void);
This page took 0.030023 seconds and 5 git commands to generate.