Fix: failure to launch agent thread is not reported
authorJérémie Galarneau <jeremie.galarneau@efficios.com>
Mon, 23 Apr 2018 23:03:16 +0000 (19:03 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Wed, 25 Apr 2018 16:08:02 +0000 (12:08 -0400)
A session daemon may fail to launch its agent thread. In such
a case, the tracing of agent domains fails silently as events
never get enabled through the agent.

The problem that was reported was caused by a second session
daemon being already bound on the agent TCP socket port, which
prevented the launch of the agent thread.

While in this situation tracing is still not possible, the user
will at least get an error indicating as such when enabling
an event in those domains.

Reported-by: Deborah Barnard <starfallprojects@gmail.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
include/lttng/lttng-error.h
src/bin/lttng-sessiond/agent-thread.c
src/bin/lttng-sessiond/agent-thread.h
src/bin/lttng-sessiond/cmd.c
src/bin/lttng-sessiond/main.c
src/common/error.c

index db6fe73c27741c2b269063519adda358bd91fea9..69fecaac4c4f03e5aa68cc64000a7f924b482729 100644 (file)
@@ -145,6 +145,7 @@ enum lttng_error_code {
        LTTNG_ERR_REGEN_STATEDUMP_FAIL   = 122, /* Failed to regenerate the state dump */
        LTTNG_ERR_REGEN_STATEDUMP_NOMEM  = 123, /* Failed to regenerate the state dump, not enough memory */
        LTTNG_ERR_NOT_SNAPSHOT_SESSION   = 124, /* Session is not in snapshot mode. */
+       LTTNG_ERR_AGENT_TRACING_DISABLED = 139, /* Agent tracing disabled. */
 
        /* MUST be last element */
        LTTNG_ERR_NR,                           /* Last element */
index 4d53d6e09286a8d4968b38ac458ba80e64077705..bc1fac69965582bb91233e64417d99f9e7feab93 100644 (file)
@@ -32,6 +32,8 @@
 #include "session.h"
 #include "utils.h"
 
+static int agent_tracing_enabled = -1;
+
 /*
  * Note that there is not port here. It's set after this URI is parsed so we
  * can let the user define a custom one. However, localhost is ALWAYS the
@@ -223,6 +225,15 @@ error:
        return ret;
 }
 
+bool agent_tracing_is_enabled(void)
+{
+       int enabled;
+
+       enabled = uatomic_read(&agent_tracing_enabled);
+       assert(enabled != -1);
+       return enabled == 1;
+}
+
 /*
  * This thread manage application notify communication.
  */
@@ -248,6 +259,12 @@ void *agent_thread_manage_registration(void *data)
        }
 
        reg_sock = init_tcp_socket();
+       uatomic_set(&agent_tracing_enabled, !!reg_sock);
+
+       /*
+        * Signal that the agent thread is ready. The command thread
+        * may start to query whether or not agent tracing is enabled.
+        */
        sessiond_notify_ready();
        if (!reg_sock) {
                goto error_tcp_socket;
@@ -348,6 +365,7 @@ restart:
        }
 
 exit:
+       uatomic_set(&agent_tracing_enabled, 0);
        /* Whatever happens, try to delete it and exit. */
        (void) lttng_poll_del(&events, reg_sock->fd);
 error:
index 0a0b3682fecf327f037f12fb176a3333e3111e45..6bdfdcd5ea274041a1bf0e243aadc04077b7e6ab 100644 (file)
  * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
+#include <stdbool.h>
+
 #ifndef LTTNG_SESSIOND_AGENT_THREAD_H
 #define LTTNG_SESSIOND_AGENT_THREAD_H
 
 #ifdef HAVE_LIBLTTNG_UST_CTL
 
 void *agent_thread_manage_registration(void *data);
+bool agent_tracing_is_enabled(void);
 
 #else /* HAVE_LIBLTTNG_UST_CTL */
 
@@ -29,6 +32,11 @@ void *agent_thread_manage_registration(void *data)
 {
        return NULL;
 }
+static inline
+bool agent_tracing_is_enabled(void)
+{
+       return false;
+}
 
 #endif /* HAVE_LIBLTTNG_UST_CTL */
 
index bb46093e2586f4f458d60ad2584f7c97d264c0d3..cf30b8ebfbf88feda7cfa84617bf4ff4dae79b25 100644 (file)
@@ -41,6 +41,7 @@
 #include "syscall.h"
 #include "agent.h"
 #include "buffer-registry.h"
+#include "agent-thread.h"
 
 #include "cmd.h"
 
@@ -1344,6 +1345,21 @@ int cmd_enable_channel(struct ltt_session *session,
                attr->attr.switch_timer_interval = 0;
        }
 
+       /* Check for feature support */
+       switch (domain->type) {
+       case LTTNG_DOMAIN_JUL:
+       case LTTNG_DOMAIN_LOG4J:
+       case LTTNG_DOMAIN_PYTHON:
+               if (!agent_tracing_is_enabled()) {
+                       DBG("Attempted to enable a channel in an agent domain but the agent thread is not running");
+                       ret = LTTNG_ERR_AGENT_TRACING_DISABLED;
+                       goto error;
+               }
+               break;
+       default:
+               break;
+       }
+
        switch (domain->type) {
        case LTTNG_DOMAIN_KERNEL:
        {
@@ -2077,6 +2093,12 @@ static int _cmd_enable_event(struct ltt_session *session,
 
                assert(usess);
 
+               if (!agent_tracing_is_enabled()) {
+                       DBG("Attempted to enable an event in an agent domain but the agent thread is not running");
+                       ret = LTTNG_ERR_AGENT_TRACING_DISABLED;
+                       goto error;
+               }
+
                agt = trace_ust_find_agent(usess, domain->type);
                if (!agt) {
                        agt = agent_create(domain->type);
index b4d82f3bfce4ce748e0d697d54b9161340304c0c..cd2f07b60e8f0e6cce6556dab502a161cf351157 100644 (file)
@@ -4376,12 +4376,41 @@ static void *thread_manage_clients(void *data)
        }
 
        sessiond_notify_ready();
+
        ret = sem_post(&load_info->message_thread_ready);
        if (ret) {
                PERROR("sem_post message_thread_ready");
                goto error;
        }
 
+       /*
+        * Wait until all support threads are initialized before accepting
+        * commands.
+        */
+       while (uatomic_read(&lttng_sessiond_ready) != 0) {
+               fd_set read_fds;
+               struct timeval timeout;
+
+               FD_ZERO(&read_fds);
+               FD_SET(thread_quit_pipe[0], &read_fds);
+               memset(&timeout, 0, sizeof(timeout));
+               timeout.tv_usec = 1000;
+
+               /*
+                * If a support thread failed to launch, it may signal that
+                * we must exit and the sessiond would never be marked as
+                * "ready".
+                *
+                * The timeout is set to 1ms, which serves as a way to
+                * pace down this check.
+                */
+               ret = select(thread_quit_pipe[0] + 1, &read_fds, NULL, NULL,
+                               &timeout);
+               if (ret > 0 || (ret < 0 && errno != EINTR)) {
+                       goto exit;
+               }
+       }
+
        /* This testpoint is after we signal readiness to the parent. */
        if (testpoint(sessiond_thread_manage_clients)) {
                goto error;
index ba50d27601d42ffb6602309b065e8814b1aace85..b6d2ff42f687fb7fae99cdeceec2cdce281a42e2 100644 (file)
@@ -186,6 +186,7 @@ static const char *error_string_array[] = {
        [ ERROR_INDEX(LTTNG_ERR_REGEN_STATEDUMP_FAIL) ] = "Failed to regenerate the state dump",
        [ ERROR_INDEX(LTTNG_ERR_REGEN_STATEDUMP_NOMEM) ] = "Failed to regenerate the state dump, not enough memory",
        [ ERROR_INDEX(LTTNG_ERR_NOT_SNAPSHOT_SESSION) ] = "Snapshot command can't be applied to a non-snapshot session",
+       [ ERROR_INDEX(LTTNG_ERR_AGENT_TRACING_DISABLED) ] = "Session daemon agent tracing is disabled",
 
        /* Last element */
        [ ERROR_INDEX(LTTNG_ERR_NR) ] = "Unknown error code"
This page took 0.032588 seconds and 4 git commands to generate.