notification-thread: add `GET_TRIGGER` command
authorFrancis Deslauriers <francis.deslauriers@efficios.com>
Mon, 8 Mar 2021 22:19:51 +0000 (17:19 -0500)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Sun, 18 Apr 2021 23:28:57 +0000 (19:28 -0400)
Signed-off-by: Francis Deslauriers <francis.deslauriers@efficios.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
Change-Id: Ifc94ea894999b9da796aa4fda0d929d237e12d3e

src/bin/lttng-sessiond/notification-thread-commands.c
src/bin/lttng-sessiond/notification-thread-commands.h
src/bin/lttng-sessiond/notification-thread-events.c

index b1b33343ba5da6ec663a981d944e70f9256861c6..7f031e7427688e903df292ff0a7da7a1176dc023 100644 (file)
@@ -382,6 +382,32 @@ int notification_thread_client_communication_update(
        return run_command_no_wait(handle, &cmd);
 }
 
+enum lttng_error_code notification_thread_command_get_trigger(
+               struct notification_thread_handle *handle,
+               const struct lttng_trigger *trigger,
+               struct lttng_trigger **real_trigger)
+{
+       int ret;
+       enum lttng_error_code ret_code;
+       struct notification_thread_command cmd = {};
+
+       init_notification_thread_command(&cmd);
+
+       cmd.type = NOTIFICATION_COMMAND_TYPE_GET_TRIGGER;
+       cmd.parameters.get_trigger.trigger = trigger;
+       ret = run_command_wait(handle, &cmd);
+       if (ret) {
+               ret_code = LTTNG_ERR_UNK;
+               goto end;
+       }
+
+       ret_code = cmd.reply_code;
+       *real_trigger = cmd.reply.get_trigger.trigger;
+
+end:
+       return ret_code;
+}
+
 /*
  * Takes ownership of the payload if present.
  */
index 50751a94d1ed4dc3c6cf6f2a4c68e55d6d4abf12..882959a29d0cc2c571e70e49d78552997ae71531 100644 (file)
@@ -32,6 +32,7 @@ enum notification_thread_command_type {
        NOTIFICATION_COMMAND_TYPE_LIST_TRIGGERS,
        NOTIFICATION_COMMAND_TYPE_QUIT,
        NOTIFICATION_COMMAND_TYPE_CLIENT_COMMUNICATION_UPDATE,
+       NOTIFICATION_COMMAND_TYPE_GET_TRIGGER,
 };
 
 struct notification_thread_command {
@@ -89,12 +90,19 @@ struct notification_thread_command {
                        enum client_transmission_status status;
                } client_communication_update;
 
+               struct {
+                       const struct lttng_trigger *trigger;
+               } get_trigger;
+
        } parameters;
 
        union {
                struct {
                        struct lttng_triggers *triggers;
                } list_triggers;
+               struct {
+                       struct lttng_trigger *trigger;
+               } get_trigger;
        } reply;
        /* lttng_waiter on which to wait for command reply (optional). */
        struct lttng_waiter reply_waiter;
@@ -166,4 +174,9 @@ enum lttng_error_code notification_thread_command_remove_tracer_event_source(
 void notification_thread_command_quit(
                struct notification_thread_handle *handle);
 
+enum lttng_error_code notification_thread_command_get_trigger(
+               struct notification_thread_handle *handle,
+               const struct lttng_trigger *trigger,
+               struct lttng_trigger **real_trigger);
+
 #endif /* NOTIFICATION_THREAD_COMMANDS_H */
index ec4d56bce7d9ec78c6c6926e256e376f59b6297a..28e553f44875c59c74f28fc29d1dbd9adf102e54 100644 (file)
@@ -353,6 +353,8 @@ const char *notification_command_type_str(
                return "REMOVE_TRACER_EVENT_SOURCE";
        case NOTIFICATION_COMMAND_TYPE_LIST_TRIGGERS:
                return "LIST_TRIGGERS";
+       case NOTIFICATION_COMMAND_TYPE_GET_TRIGGER:
+               return "GET_TRIGGER";
        case NOTIFICATION_COMMAND_TYPE_QUIT:
                return "QUIT";
        case NOTIFICATION_COMMAND_TYPE_CLIENT_COMMUNICATION_UPDATE:
@@ -2280,6 +2282,69 @@ end:
        return ret;
 }
 
+static inline void get_trigger_info_for_log(const struct lttng_trigger *trigger,
+               const char **trigger_name,
+               uid_t *trigger_owner_uid)
+{
+       enum lttng_trigger_status trigger_status;
+
+       trigger_status = lttng_trigger_get_name(trigger, trigger_name);
+       switch (trigger_status) {
+       case LTTNG_TRIGGER_STATUS_OK:
+               break;
+       case LTTNG_TRIGGER_STATUS_UNSET:
+               *trigger_name = "(unset)";
+               break;
+       default:
+               abort();
+       }
+
+       trigger_status = lttng_trigger_get_owner_uid(trigger,
+                       trigger_owner_uid);
+       assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
+}
+
+static int handle_notification_thread_command_get_trigger(
+               struct notification_thread_state *state,
+               const struct lttng_trigger *trigger,
+               struct lttng_trigger **registered_trigger,
+               enum lttng_error_code *_cmd_result)
+{
+       int ret = -1;
+       struct cds_lfht_iter iter;
+       struct lttng_trigger_ht_element *trigger_ht_element;
+       enum lttng_error_code cmd_result = LTTNG_ERR_TRIGGER_NOT_FOUND;
+       const char *trigger_name;
+       uid_t trigger_owner_uid;
+
+       rcu_read_lock();
+
+       cds_lfht_for_each_entry(
+                       state->triggers_ht, &iter, trigger_ht_element, node) {
+               if (lttng_trigger_is_equal(
+                                   trigger, trigger_ht_element->trigger)) {
+                       /* Take one reference on the return trigger. */
+                       *registered_trigger = trigger_ht_element->trigger;
+                       lttng_trigger_get(*registered_trigger);
+                       ret = 0;
+                       cmd_result = LTTNG_OK;
+                       goto end;
+               }
+       }
+
+       /* Not a fatal error if the trigger is not found. */
+       get_trigger_info_for_log(trigger, &trigger_name, &trigger_owner_uid);
+       ERR("Failed to retrieve registered version of trigger: trigger name = '%s', trigger owner uid = %d",
+                       trigger_name, (int) trigger_owner_uid);
+
+       ret = 0;
+
+end:
+       rcu_read_unlock();
+       *_cmd_result = cmd_result;
+       return ret;
+}
+
 static
 bool condition_is_supported(struct lttng_condition *condition)
 {
@@ -3138,6 +3203,16 @@ int handle_notification_thread_command(
                cmd->reply_code = LTTNG_OK;
                ret = 1;
                goto end;
+       case NOTIFICATION_COMMAND_TYPE_GET_TRIGGER:
+       {
+               struct lttng_trigger *trigger = NULL;
+
+               ret = handle_notification_thread_command_get_trigger(state,
+                               cmd->parameters.get_trigger.trigger, &trigger,
+                               &cmd->reply_code);
+               cmd->reply.get_trigger.trigger = trigger;
+               break;
+       }
        case NOTIFICATION_COMMAND_TYPE_CLIENT_COMMUNICATION_UPDATE:
        {
                const enum client_transmission_status client_status =
This page took 0.028547 seconds and 4 git commands to generate.