Fix: perform statedump before replying to sessiond
[lttng-ust.git] / liblttng-ust / lttng-ust-comm.c
index 2ada5065f995a30fb517cc7c13331256b13a2fc1..38e66dc25926d64407d6fb48013849fc331c1198 100644 (file)
@@ -388,6 +388,16 @@ void lttng_fixup_urcu_bp_tls(void)
        rcu_read_unlock();
 }
 
+void lttng_ust_fixup_tls(void)
+{
+       lttng_fixup_urcu_bp_tls();
+       lttng_fixup_ringbuffer_tls();
+       lttng_fixup_vtid_tls();
+       lttng_fixup_nest_count_tls();
+       lttng_fixup_procname_tls();
+       lttng_fixup_ust_mutex_nest_tls();
+}
+
 int lttng_get_notify_socket(void *owner)
 {
        struct sock_info *info = owner;
@@ -441,7 +451,7 @@ int setup_local_apps(void)
 }
 
 /*
- * Get notify_sock timeout, in ms.
+ * Get socket timeout, in ms.
  * -1: wait forever. 0: don't wait. >0: timeout, in ms.
  */
 static
@@ -461,12 +471,20 @@ long get_timeout(void)
        return constructor_delay_ms;
 }
 
+/* Timeout for notify socket send and recv. */
 static
 long get_notify_sock_timeout(void)
 {
        return get_timeout();
 }
 
+/* Timeout for connecting to cmd and notify sockets. */
+static
+long get_connect_sock_timeout(void)
+{
+       return get_timeout();
+}
+
 /*
  * Return values: -1: wait forever. 0: don't wait. 1: timeout wait.
  */
@@ -591,6 +609,7 @@ int handle_message(struct sock_info *sock_info,
        const struct lttng_ust_objd_ops *ops;
        struct ustcomm_ust_reply lur;
        union ust_args args;
+       char ctxstr[LTTNG_UST_SYM_NAME_LEN];    /* App context string. */
        ssize_t len;
 
        memset(&lur, 0, sizeof(lur));
@@ -810,6 +829,64 @@ int handle_message(struct sock_info *sock_info,
                        ret = -ENOSYS;
                break;
        }
+       case LTTNG_UST_CONTEXT:
+               switch (lum->u.context.ctx) {
+               case LTTNG_UST_CONTEXT_APP_CONTEXT:
+               {
+                       char *p;
+                       size_t ctxlen, recvlen;
+
+                       ctxlen = strlen("$app.") + lum->u.context.u.app_ctx.provider_name_len - 1
+                                       + strlen(":") + lum->u.context.u.app_ctx.ctx_name_len;
+                       if (ctxlen >= LTTNG_UST_SYM_NAME_LEN) {
+                               ERR("Application context string length size is too large: %zu bytes",
+                                       ctxlen);
+                               ret = -EINVAL;
+                               goto error;
+                       }
+                       strcpy(ctxstr, "$app.");
+                       p = &ctxstr[strlen("$app.")];
+                       recvlen = ctxlen - strlen("$app.");
+                       len = ustcomm_recv_unix_sock(sock, p, recvlen);
+                       switch (len) {
+                       case 0: /* orderly shutdown */
+                               ret = 0;
+                               goto error;
+                       default:
+                               if (len == recvlen) {
+                                       DBG("app context data received");
+                                       break;
+                               } else if (len < 0) {
+                                       DBG("Receive failed from lttng-sessiond with errno %d", (int) -len);
+                                       if (len == -ECONNRESET) {
+                                               ERR("%s remote end closed connection", sock_info->name);
+                                               ret = len;
+                                               goto error;
+                                       }
+                                       ret = len;
+                                       goto error;
+                               } else {
+                                       DBG("incorrect app context data message size: %zd", len);
+                                       ret = -EINVAL;
+                                       goto error;
+                               }
+                       }
+                       /* Put : between provider and ctxname. */
+                       p[lum->u.context.u.app_ctx.provider_name_len - 1] = ':';
+                       args.app_context.ctxname = ctxstr;
+                       break;
+               }
+               default:
+                       break;
+               }
+               if (ops->cmd) {
+                       ret = ops->cmd(lum->handle, lum->cmd,
+                                       (unsigned long) &lum->u,
+                                       &args, sock_info);
+               } else {
+                       ret = -ENOSYS;
+               }
+               break;
        default:
                if (ops->cmd)
                        ret = ops->cmd(lum->handle, lum->cmd,
@@ -869,6 +946,21 @@ int handle_message(struct sock_info *sock_info,
                }
        }
        DBG("Return value: %d", lur.ret_val);
+
+       ust_unlock();
+
+       /*
+        * Performed delayed statedump operations outside of the UST
+        * lock. We need to take the dynamic loader lock before we take
+        * the UST lock internally within handle_pending_statedump().
+         */
+       handle_pending_statedump(sock_info);
+
+       if (ust_lock()) {
+               ret = -LTTNG_UST_ERR_EXITING;
+               goto error;
+       }
+
        ret = send_reply(sock, &lur);
        if (ret < 0) {
                DBG("error sending reply");
@@ -899,13 +991,6 @@ int handle_message(struct sock_info *sock_info,
 error:
        ust_unlock();
 
-       /*
-        * Performed delayed statedump operations outside of the UST
-        * lock. We need to take the dynamic loader lock before we take
-        * the UST lock internally within handle_pending_statedump().
-         */
-       handle_pending_statedump(sock_info);
-
        return ret;
 }
 
@@ -1236,6 +1321,8 @@ void *ust_listener_thread(void *arg)
        int sock, ret, prev_connect_failed = 0, has_waited = 0;
        long timeout;
 
+       lttng_ust_fixup_tls();
+
        /* Restart trying to connect to the session daemon */
 restart:
        if (prev_connect_failed) {
@@ -1280,7 +1367,8 @@ restart:
         * first connect registration message.
         */
        /* Connect cmd socket */
-       ret = ustcomm_connect_unix_sock(sock_info->sock_path);
+       ret = ustcomm_connect_unix_sock(sock_info->sock_path,
+               get_connect_sock_timeout());
        if (ret < 0) {
                DBG("Info: sessiond not accepting connections to %s apps socket", sock_info->name);
                prev_connect_failed = 1;
@@ -1336,7 +1424,8 @@ restart:
        ust_unlock();
 
        /* Connect notify socket */
-       ret = ustcomm_connect_unix_sock(sock_info->sock_path);
+       ret = ustcomm_connect_unix_sock(sock_info->sock_path,
+               get_connect_sock_timeout());
        if (ret < 0) {
                DBG("Info: sessiond not accepting connections to %s apps socket", sock_info->name);
                prev_connect_failed = 1;
@@ -1499,12 +1588,7 @@ void __attribute__((constructor)) lttng_ust_init(void)
         * to be the dynamic linker mutex) and ust_lock, taken within
         * the ust lock.
         */
-       lttng_fixup_urcu_bp_tls();
-       lttng_fixup_ringbuffer_tls();
-       lttng_fixup_vtid_tls();
-       lttng_fixup_nest_count_tls();
-       lttng_fixup_procname_tls();
-       lttng_fixup_ust_mutex_nest_tls();
+       lttng_ust_fixup_tls();
 
        /*
         * We want precise control over the order in which we construct
@@ -1523,7 +1607,6 @@ void __attribute__((constructor)) lttng_ust_init(void)
        lttng_ring_buffer_client_discard_init();
        lttng_ring_buffer_client_discard_rt_init();
        lttng_perf_counter_init();
-       lttng_context_init();
        /*
         * Invoke ust malloc wrapper init before starting other threads.
         */
@@ -1532,7 +1615,9 @@ void __attribute__((constructor)) lttng_ust_init(void)
        timeout_mode = get_constructor_timeout(&constructor_timeout);
 
        ret = sem_init(&constructor_wait, 0, 0);
-       assert(!ret);
+       if (ret) {
+               PERROR("sem_init");
+       }
 
        ret = setup_local_apps();
        if (ret) {
@@ -1597,17 +1682,34 @@ void __attribute__((constructor)) lttng_ust_init(void)
                        ret = sem_timedwait(&constructor_wait,
                                        &constructor_timeout);
                } while (ret < 0 && errno == EINTR);
-               if (ret < 0 && errno == ETIMEDOUT) {
-                       ERR("Timed out waiting for lttng-sessiond");
-               } else {
-                       assert(!ret);
+               if (ret < 0) {
+                       switch (errno) {
+                       case ETIMEDOUT:
+                               ERR("Timed out waiting for lttng-sessiond");
+                               break;
+                       case EINVAL:
+                               PERROR("sem_timedwait");
+                               break;
+                       default:
+                               ERR("Unexpected error \"%s\" returned by sem_timedwait",
+                                       strerror(errno));
+                       }
                }
                break;
        case -1:/* wait forever */
                do {
                        ret = sem_wait(&constructor_wait);
                } while (ret < 0 && errno == EINTR);
-               assert(!ret);
+               if (ret < 0) {
+                       switch (errno) {
+                       case EINVAL:
+                               PERROR("sem_wait");
+                               break;
+                       default:
+                               ERR("Unexpected error \"%s\" returned by sem_wait",
+                                       strerror(errno));
+                       }
+               }
                break;
        case 0: /* no timeout */
                break;
@@ -1619,6 +1721,7 @@ void lttng_ust_cleanup(int exiting)
 {
        cleanup_sock_info(&global_apps, exiting);
        cleanup_sock_info(&local_apps, exiting);
+       local_apps.allowed = 0;
        /*
         * The teardown in this function all affect data structures
         * accessed under the UST lock by the listener thread. This
@@ -1628,7 +1731,6 @@ void lttng_ust_cleanup(int exiting)
         */
        lttng_ust_abi_exit();
        lttng_ust_events_exit();
-       lttng_context_exit();
        lttng_perf_counter_exit();
        lttng_ring_buffer_client_discard_rt_exit();
        lttng_ring_buffer_client_discard_exit();
@@ -1715,6 +1817,9 @@ void ust_before_fork(sigset_t *save_sigset)
        sigset_t all_sigs;
        int ret;
 
+       /* Fixup lttng-ust TLS. */
+       lttng_ust_fixup_tls();
+
        if (URCU_TLS(lttng_ust_nest_count))
                return;
        /* Disable signals */
@@ -1769,11 +1874,11 @@ void ust_after_fork_child(sigset_t *restore_sigset)
 {
        if (URCU_TLS(lttng_ust_nest_count))
                return;
+       lttng_context_vtid_reset();
        DBG("process %d", getpid());
        /* Release urcu mutexes */
        rcu_bp_after_fork_child();
        lttng_ust_cleanup(0);
-       lttng_context_vtid_reset();
        /* Release mutexes and reenable signals */
        ust_after_fork_common(restore_sigset);
        lttng_ust_init();
This page took 0.026341 seconds and 4 git commands to generate.