SoW-2019-0002: Dynamic Snapshot
[lttng-tools.git] / src / bin / lttng-sessiond / agent-thread.c
index 9c98d30ab4e71accd303a442d41b45feeee212b6..3587fd4713312a7f85d0c577adaadc6852cff418 100644 (file)
@@ -1,18 +1,8 @@
 /*
- * Copyright (C) 2013 David Goulet <dgoulet@efficios.com>
+ * Copyright (C) 2013 David Goulet <dgoulet@efficios.com>
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License, version 2 only, as
- * published by the Free Software Foundation.
+ * SPDX-License-Identifier: GPL-2.0-only
  *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 51
- * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
 #define _LGPL_SOURCE
 #include "utils.h"
 #include "thread.h"
 
+struct thread_notifiers {
+       struct lttng_pipe *quit_pipe;
+       sem_t ready;
+};
+
 static int agent_tracing_enabled = -1;
 
 /*
@@ -54,6 +49,8 @@ static void update_agent_app(struct agent_app *app)
 {
        struct ltt_session *session, *stmp;
        struct ltt_session_list *list;
+       struct agent *trigger_agent;
+       struct lttng_ht_iter iter;
 
        list = session_get_list();
        assert(list);
@@ -79,6 +76,14 @@ static void update_agent_app(struct agent_app *app)
                session_put(session);
        }
        session_unlock_list();
+
+       /* Do we need more locking here? maybe against trigger add? */
+       rcu_read_lock();
+       cds_lfht_for_each_entry (trigger_agents_ht_by_domain->ht, &iter.iter,
+                       trigger_agent, node.node) {
+               agent_update(trigger_agent, app->sock->fd);
+       }
+       rcu_read_unlock();
 }
 
 /*
@@ -293,6 +298,21 @@ 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.
  */
@@ -302,8 +322,9 @@ static void *thread_agent_management(void *data)
        uint32_t revents, nb_fd;
        struct lttng_poll_event events;
        struct lttcomm_sock *reg_sock;
-       struct lttng_pipe *quit_pipe = data;
-       const int quit_pipe_read_fd = lttng_pipe_get_readfd(quit_pipe);
+       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.");
 
@@ -335,12 +356,12 @@ static void *thread_agent_management(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;
        }
 
@@ -349,7 +370,7 @@ static void *thread_agent_management(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,
@@ -383,11 +404,6 @@ 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. */
                        if (pollfd == quit_pipe_read_fd) {
                                goto exit;
@@ -461,40 +477,49 @@ error_poll_create:
 
 static bool shutdown_agent_management_thread(void *data)
 {
-       struct lttng_pipe *quit_pipe = data;
-       const int write_fd = lttng_pipe_get_writefd(quit_pipe);
+       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 lttng_pipe *quit_pipe = data;
+       struct thread_notifiers *notifiers = data;
 
-       lttng_pipe_destroy(quit_pipe);
+       lttng_pipe_destroy(notifiers->quit_pipe);
+       sem_destroy(&notifiers->ready);
+       free(notifiers);
 }
 
 bool launch_agent_management_thread(void)
 {
-       struct lttng_pipe *quit_pipe;
+       struct thread_notifiers *notifiers;
        struct lttng_thread *thread;
 
-       quit_pipe = lttng_pipe_open(FD_CLOEXEC);
-       if (!quit_pipe) {
+       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,
-                       quit_pipe);
+                       notifiers);
        if (!thread) {
                goto error;
        }
-
+       wait_until_thread_is_ready(notifiers);
        lttng_thread_put(thread);
        return true;
 error:
-       cleanup_agent_management_thread(quit_pipe);
+       cleanup_agent_management_thread(notifiers);
+error_alloc:
        return false;
 }
This page took 0.027614 seconds and 5 git commands to generate.