Fix: sessiond: no rotation performed from null chunk to new chunk
[lttng-tools.git] / src / bin / lttng-sessiond / agent-thread.c
index b238656812c69390b2d7e16ee841d7830cd3ba03..575f6aee934a504ddb6248d4e87610d622d0959c 100644 (file)
 #include "lttng-sessiond.h"
 #include "session.h"
 #include "utils.h"
+#include "thread.h"
+
+struct thread_notifiers {
+       struct lttng_pipe *quit_pipe;
+       sem_t ready;
+};
 
 static int agent_tracing_enabled = -1;
 
@@ -59,6 +65,10 @@ static void update_agent_app(struct agent_app *app)
 
        session_lock_list();
        cds_list_for_each_entry_safe(session, stmp, &list->head, list) {
+               if (!session_get(session)) {
+                       continue;
+               }
+
                session_lock(session);
                if (session->ust_session) {
                        struct agent *agt;
@@ -71,6 +81,7 @@ static void update_agent_app(struct agent_app *app)
                        rcu_read_unlock();
                }
                session_unlock(session);
+               session_put(session);
        }
        session_unlock_list();
 }
@@ -287,15 +298,33 @@ static int write_agent_port(uint16_t port)
                        config.agent_port_file_path.value);
 }
 
+static
+void mark_thread_as_ready(struct thread_notifiers *notifiers)
+{
+       DBG("Marking agent management thread as ready");
+       sem_post(&notifiers->ready);
+}
+
+static
+void wait_until_thread_is_ready(struct thread_notifiers *notifiers)
+{
+       DBG("Waiting for agent management thread to be ready");
+       sem_wait(&notifiers->ready);
+       DBG("Agent management thread is ready");
+}
+
 /*
  * This thread manage application notify communication.
  */
-void *agent_thread_manage_registration(void *data)
+static void *thread_agent_management(void *data)
 {
        int i, ret, pollfd;
        uint32_t revents, nb_fd;
        struct lttng_poll_event events;
        struct lttcomm_sock *reg_sock;
+       struct thread_notifiers *notifiers = data;
+       const int quit_pipe_read_fd = lttng_pipe_get_readfd(
+                       notifiers->quit_pipe);
 
        DBG("[agent-thread] Manage agent application registration.");
 
@@ -305,13 +334,18 @@ void *agent_thread_manage_registration(void *data)
        /* Agent initialization call MUST be called before starting the thread. */
        assert(agent_apps_ht_by_sock);
 
-       /* Create pollset with size 2, quit pipe and socket. */
-       ret = sessiond_set_thread_pollset(&events, 2);
+       /* Create pollset with size 2, quit pipe and registration socket. */
+       ret = lttng_poll_create(&events, 2, LTTNG_CLOEXEC);
        if (ret < 0) {
-               sessiond_notify_ready();
                goto error_poll_create;
        }
 
+       ret = lttng_poll_add(&events, quit_pipe_read_fd,
+                       LPOLLIN | LPOLLERR);
+       if (ret < 0) {
+               goto error_tcp_socket;
+       }
+
        reg_sock = init_tcp_socket();
        if (reg_sock) {
                uint16_t port;
@@ -322,12 +356,12 @@ void *agent_thread_manage_registration(void *data)
                if (ret) {
                        ERR("[agent-thread] Failed to create agent port file: agent tracing will be unavailable");
                        /* Don't prevent the launch of the sessiond on error. */
-                       sessiond_notify_ready();
+                       mark_thread_as_ready(notifiers);
                        goto error;
                }
        } else {
                /* Don't prevent the launch of the sessiond on error. */
-               sessiond_notify_ready();
+               mark_thread_as_ready(notifiers);
                goto error_tcp_socket;
        }
 
@@ -336,7 +370,7 @@ void *agent_thread_manage_registration(void *data)
         * may start to query whether or not agent tracing is enabled.
         */
        uatomic_set(&agent_tracing_enabled, 1);
-       sessiond_notify_ready();
+       mark_thread_as_ready(notifiers);
 
        /* Add TCP socket to poll set. */
        ret = lttng_poll_add(&events, reg_sock->fd,
@@ -370,14 +404,8 @@ restart:
                        revents = LTTNG_POLL_GETEV(&events, i);
                        pollfd = LTTNG_POLL_GETFD(&events, i);
 
-                       if (!revents) {
-                               /* No activity for this FD (poll implementation). */
-                               continue;
-                       }
-
                        /* Thread quit pipe has been closed. Killing thread. */
-                       ret = sessiond_check_thread_quit_pipe(pollfd, revents);
-                       if (ret) {
+                       if (pollfd == quit_pipe_read_fd) {
                                goto exit;
                        }
 
@@ -441,9 +469,57 @@ error_tcp_socket:
        lttng_poll_clean(&events);
 error_poll_create:
        uatomic_set(&agent_tracing_enabled, 0);
-       DBG("[agent-thread] is cleaning up and stopping.");
-
+       DBG("[agent-thread] Cleaning up and stopping.");
        rcu_thread_offline();
        rcu_unregister_thread();
        return NULL;
 }
+
+static bool shutdown_agent_management_thread(void *data)
+{
+       struct thread_notifiers *notifiers = data;
+       const int write_fd = lttng_pipe_get_writefd(notifiers->quit_pipe);
+
+       return notify_thread_pipe(write_fd) == 1;
+}
+
+static void cleanup_agent_management_thread(void *data)
+{
+       struct thread_notifiers *notifiers = data;
+
+       lttng_pipe_destroy(notifiers->quit_pipe);
+       sem_destroy(&notifiers->ready);
+       free(notifiers);
+}
+
+bool launch_agent_management_thread(void)
+{
+       struct thread_notifiers *notifiers;
+       struct lttng_thread *thread;
+
+       notifiers = zmalloc(sizeof(*notifiers));
+       if (!notifiers) {
+               goto error_alloc;
+       }
+
+       sem_init(&notifiers->ready, 0, 0);
+       notifiers->quit_pipe = lttng_pipe_open(FD_CLOEXEC);
+       if (!notifiers->quit_pipe) {
+               goto error;
+       }
+       thread = lttng_thread_create("Agent management",
+                       thread_agent_management,
+                       shutdown_agent_management_thread,
+                       cleanup_agent_management_thread,
+                       notifiers);
+       if (!thread) {
+               goto error;
+       }
+       wait_until_thread_is_ready(notifiers);
+       lttng_thread_put(thread);
+       return true;
+error:
+       cleanup_agent_management_thread(notifiers);
+error_alloc:
+       return false;
+}
This page took 0.026018 seconds and 4 git commands to generate.