Fix: sessiond: notification: find_tracer_event_source returns NULL
[lttng-tools.git] / src / bin / lttng-sessiond / notification-thread-events.c
index c7037a482bfcdeccf70e0159089467196b690a79..9e5ec509135bd6d2818b6d6635ea6cdd0acf82ea 100644 (file)
@@ -2110,95 +2110,115 @@ end:
 }
 
 static
-int handle_notification_thread_command_remove_tracer_event_source(
-               struct notification_thread_state *state,
-               int tracer_event_source_fd,
-               enum lttng_error_code *_cmd_result)
+struct notification_event_tracer_event_source_element *
+find_tracer_event_source_element(struct notification_thread_state *state,
+               int tracer_event_source_fd)
 {
-       int ret = 0;
-       bool found = false;
-       enum lttng_error_code cmd_result = LTTNG_OK;
-       struct notification_event_tracer_event_source_element *source_element = NULL, *tmp;
+       struct notification_event_tracer_event_source_element *source_element;
 
-       cds_list_for_each_entry_safe(source_element, tmp,
+       cds_list_for_each_entry(source_element,
                        &state->tracer_event_sources_list, node) {
-               if (source_element->fd != tracer_event_source_fd) {
-                       continue;
+               if (source_element->fd == tracer_event_source_fd) {
+                       goto end;
                }
-
-               DBG("Removed tracer event source from poll set: tracer_event_source_fd = %d, domain = '%s'",
-                               tracer_event_source_fd,
-                               lttng_domain_type_str(source_element->domain));
-               cds_list_del(&source_element->node);
-               found = true;
-               break;
        }
 
-       if (!found) {
-               /*
-                * This is temporarily allowed since the poll activity set is
-                * not properly cleaned-up for the moment. This is adressed in
-                * an upcoming fix.
-                */
-               source_element = NULL;
-               goto end;
-       }
+       source_element = NULL;
+end:
+       return source_element;
+}
 
-       if (!source_element->is_fd_in_poll_set) {
-               /* Skip the poll set removal. */
-               goto end;
-       }
+static
+int remove_tracer_event_source_from_pollset(
+               struct notification_thread_state *state,
+               struct notification_event_tracer_event_source_element *source_element)
+{
+       int ret = 0;
+
+       assert(source_element->is_fd_in_poll_set);
 
        DBG3("Removing tracer event source from poll set: tracer_event_source_fd = %d, domain = '%s'",
-                       tracer_event_source_fd,
+                       source_element->fd,
                        lttng_domain_type_str(source_element->domain));
 
        /* Removing the fd from the event poll set. */
-       ret = lttng_poll_del(&state->events, tracer_event_source_fd);
+       ret = lttng_poll_del(&state->events, source_element->fd);
        if (ret < 0) {
                ERR("Failed to remove tracer event source from poll set: tracer_event_source_fd = %d, domain = '%s'",
-                               tracer_event_source_fd,
+                               source_element->fd,
                                lttng_domain_type_str(source_element->domain));
-               cmd_result = LTTNG_ERR_FATAL;
+               ret = -1;
                goto end;
        }
 
        source_element->is_fd_in_poll_set = false;
 
-       ret = drain_event_notifier_notification_pipe(state, tracer_event_source_fd,
+       ret = drain_event_notifier_notification_pipe(state, source_element->fd,
                        source_element->domain);
        if (ret) {
                ERR("Error draining event notifier notification: tracer_event_source_fd = %d, domain = %s",
-                               tracer_event_source_fd,
+                               source_element->fd,
                                lttng_domain_type_str(source_element->domain));
-               cmd_result = LTTNG_ERR_FATAL;
+               ret = -1;
                goto end;
        }
 
-       /*
-        * The drain_event_notifier_notification_pipe() call might have read
-        * data from an fd that we received in event in the latest _poll_wait()
-        * call. Make sure the thread call poll_wait() again to ensure we have
-        * a clean state.
-        */
-       state->restart_poll = true;
-
 end:
-       free(source_element);
-       *_cmd_result = cmd_result;
        return ret;
 }
 
-int handle_notification_thread_remove_tracer_event_source_no_result(
+int handle_notification_thread_tracer_event_source_died(
                struct notification_thread_state *state,
                int tracer_event_source_fd)
 {
-       int ret;
-       enum lttng_error_code cmd_result;
+       int ret = 0;
+       struct notification_event_tracer_event_source_element *source_element;
+
+       source_element = find_tracer_event_source_element(state,
+                       tracer_event_source_fd);
+
+       assert(source_element);
+
+       ret = remove_tracer_event_source_from_pollset(state, source_element);
+       if (ret) {
+               ERR("Failed to remove dead tracer event source from poll set");
+       }
 
-       ret = handle_notification_thread_command_remove_tracer_event_source(
-                       state, tracer_event_source_fd, &cmd_result);
-       (void) cmd_result;
+       return ret;
+}
+
+static
+int handle_notification_thread_command_remove_tracer_event_source(
+               struct notification_thread_state *state,
+               int tracer_event_source_fd,
+               enum lttng_error_code *_cmd_result)
+{
+       int ret = 0;
+       enum lttng_error_code cmd_result = LTTNG_OK;
+       struct notification_event_tracer_event_source_element *source_element = NULL;
+
+       source_element = find_tracer_event_source_element(state,
+                       tracer_event_source_fd);
+
+       assert(source_element);
+
+       /* Remove the tracer source from the list. */
+       cds_list_del(&source_element->node);
+
+       if (!source_element->is_fd_in_poll_set) {
+               /* Skip the poll set removal. */
+               goto end;
+       }
+
+       ret = remove_tracer_event_source_from_pollset(state, source_element);
+       if (ret) {
+               ERR("Failed to remove tracer event source from poll set");
+               cmd_result = LTTNG_ERR_FATAL;
+       }
+
+end:
+       free(source_element);
+       *_cmd_result = cmd_result;
        return ret;
 }
 
@@ -3794,9 +3814,11 @@ int client_handle_message_handshake(struct notification_client *client,
                        &client->communication.inbound.creds);
        client->gid = LTTNG_SOCK_GET_GID_CRED(
                        &client->communication.inbound.creds);
-       DBG("Received handshake from client (uid = %u, gid = %u) with version %i.%i",
+       client->is_sessiond = LTTNG_SOCK_GET_PID_CRED(&client->communication.inbound.creds) == getpid();
+       DBG("Received handshake from client: uid = %u, gid = %u, protocol version = %i.%i, client is sessiond = %s",
                        client->uid, client->gid, (int) client->major,
-                       (int) client->minor);
+                       (int) client->minor,
+                       client->is_sessiond ? "true" : "false");
 
        if (handshake_client->major !=
                        LTTNG_NOTIFICATION_CHANNEL_VERSION_MAJOR) {
@@ -4394,6 +4416,14 @@ int notification_client_list_send_evaluation(
                        goto skip_client;
                }
 
+               if (lttng_trigger_is_hidden(trigger) && !client->is_sessiond) {
+                       /*
+                        * Notifications resulting from an hidden trigger are
+                        * only sent to the session daemon.
+                        */
+                       continue;
+               }
+
                if (source_object_creds) {
                        if (client->uid != lttng_credentials_get_uid(source_object_creds) &&
                                        client->gid != lttng_credentials_get_gid(source_object_creds) &&
This page took 0.026297 seconds and 4 git commands to generate.