Use config.h to define SONAME major number
[lttng-ust.git] / liblttng-ust / lttng-ust-comm.c
index 7cd6a227d66c3bede0f7e244a02038c2c8de668b..eab2d8eb3b026435b3999d81a6b35f8509b61144 100644 (file)
@@ -27,6 +27,7 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/wait.h>
+#include <dlfcn.h>
 #include <fcntl.h>
 #include <unistd.h>
 #include <errno.h>
@@ -35,6 +36,7 @@
 #include <time.h>
 #include <assert.h>
 #include <signal.h>
+#include <limits.h>
 #include <urcu/uatomic.h>
 #include <urcu/futex.h>
 #include <urcu/compiler.h>
 #include "tracepoint-internal.h"
 #include "lttng-tracer-core.h"
 #include "compat.h"
-#include "../libringbuffer/tlsfixup.h"
+#include "../libringbuffer/rb-init.h"
 #include "lttng-ust-statedump.h"
 #include "clock.h"
 #include "../libringbuffer/getcpu.h"
 #include "getenv.h"
 
+/* Concatenate lttng ust shared library name with its major version number. */
+#define LTTNG_UST_LIB_SO_NAME "liblttng-ust.so." __ust_stringify(CONFIG_LTTNG_UST_LIBRARY_VERSION_MAJOR)
+
 /*
  * Has lttng ust comm constructor been called ?
  */
@@ -365,11 +370,11 @@ const char *get_lttng_home_dir(void)
 {
        const char *val;
 
-       val = (const char *) lttng_secure_getenv("LTTNG_HOME");
+       val = (const char *) lttng_getenv("LTTNG_HOME");
        if (val != NULL) {
                return val;
        }
-       return (const char *) lttng_secure_getenv("HOME");
+       return (const char *) lttng_getenv("HOME");
 }
 
 /*
@@ -470,7 +475,7 @@ long get_timeout(void)
        long constructor_delay_ms = LTTNG_UST_DEFAULT_CONSTRUCTOR_TIMEOUT_MS;
 
        if (!got_timeout_env) {
-               str_timeout = getenv("LTTNG_UST_REGISTER_TIMEOUT");
+               str_timeout = lttng_getenv("LTTNG_UST_REGISTER_TIMEOUT");
                got_timeout_env = 1;
        }
        if (str_timeout)
@@ -533,6 +538,19 @@ int get_constructor_timeout(struct timespec *constructor_timeout)
        return 1;
 }
 
+static
+void get_allow_blocking(void)
+{
+       const char *str_allow_blocking =
+               lttng_getenv("LTTNG_UST_ALLOW_BLOCKING");
+
+       if (str_allow_blocking) {
+               DBG("%s environment variable is set",
+                       "LTTNG_UST_ALLOW_BLOCKING");
+               lttng_ust_ringbuffer_set_allow_blocking();
+       }
+}
+
 static
 int register_to_sessiond(int socket, enum ustctl_socket_type type)
 {
@@ -1247,7 +1265,18 @@ char *get_map_shm(struct sock_info *sock_info)
                lttng_ust_unlock_fd_tracker();
                goto error;
        }
-       lttng_ust_add_fd_to_tracker(wait_shm_fd);
+
+       ret = lttng_ust_add_fd_to_tracker(wait_shm_fd);
+       if (ret < 0) {
+               ret = close(wait_shm_fd);
+               if (!ret) {
+                       PERROR("Error closing fd");
+               }
+               lttng_ust_unlock_fd_tracker();
+               goto error;
+       }
+
+       wait_shm_fd = ret;
        lttng_ust_unlock_fd_tracker();
 
        wait_shm_mmap = mmap(NULL, page_size, PROT_READ,
@@ -1339,7 +1368,7 @@ static
 void *ust_listener_thread(void *arg)
 {
        struct sock_info *sock_info = arg;
-       int sock, ret, prev_connect_failed = 0, has_waited = 0;
+       int sock, ret, prev_connect_failed = 0, has_waited = 0, fd;
        long timeout;
 
        lttng_ust_fixup_tls();
@@ -1371,6 +1400,10 @@ restart:
                prev_connect_failed = 0;
        }
 
+       if (ust_lock()) {
+               goto quit;
+       }
+
        if (sock_info->socket != -1) {
                /* FD tracker is updated by ustcomm_close_unix_sock() */
                ret = ustcomm_close_unix_sock(sock_info->socket);
@@ -1390,9 +1423,6 @@ restart:
                sock_info->notify_socket = -1;
        }
 
-       if (ust_lock()) {
-               goto quit;
-       }
 
        /*
         * Register. We need to perform both connect and sending
@@ -1419,9 +1449,21 @@ restart:
                ust_unlock();
                goto restart;
        }
-       lttng_ust_add_fd_to_tracker(ret);
-       lttng_ust_unlock_fd_tracker();
+       fd = ret;
+       ret = lttng_ust_add_fd_to_tracker(fd);
+       if (ret < 0) {
+               ret = close(fd);
+               if (ret) {
+                       PERROR("close on sock_info->socket");
+               }
+               ret = -1;
+               lttng_ust_unlock_fd_tracker();
+               ust_unlock();
+               goto quit;
+       }
+
        sock_info->socket = ret;
+       lttng_ust_unlock_fd_tracker();
 
        ust_unlock();
        /*
@@ -1490,9 +1532,22 @@ restart:
                ust_unlock();
                goto restart;
        }
-       lttng_ust_add_fd_to_tracker(ret);
-       lttng_ust_unlock_fd_tracker();
+
+       fd = ret;
+       ret = lttng_ust_add_fd_to_tracker(fd);
+       if (ret < 0) {
+               ret = close(fd);
+               if (ret) {
+                       PERROR("close on sock_info->notify_socket");
+               }
+               ret = -1;
+               lttng_ust_unlock_fd_tracker();
+               ust_unlock();
+               goto quit;
+       }
+
        sock_info->notify_socket = ret;
+       lttng_ust_unlock_fd_tracker();
 
        ust_unlock();
        /*
@@ -1634,6 +1689,7 @@ void __attribute__((constructor)) lttng_ust_init(void)
        pthread_attr_t thread_attr;
        int timeout_mode;
        int ret;
+       void *handle;
 
        if (uatomic_xchg(&initialized, 1) == 1)
                return;
@@ -1647,6 +1703,26 @@ void __attribute__((constructor)) lttng_ust_init(void)
 
        lttng_ust_loaded = 1;
 
+       /*
+        * We need to ensure that the liblttng-ust library is not unloaded to avoid
+        * the unloading of code used by the ust_listener_threads as we can not
+        * reliably know when they exited. To do that, manually load
+        * liblttng-ust.so to increment the dynamic loader's internal refcount for
+        * this library so it never becomes zero, thus never gets unloaded from the
+        * address space of the process. Since we are already running in the
+        * constructor of the LTTNG_UST_LIB_SO_NAME library, calling dlopen will
+        * simply increment the refcount and no additionnal work is needed by the
+        * dynamic loader as the shared library is already loaded in the address
+        * space. As a safe guard, we use the RTLD_NODELETE flag to prevent
+        * unloading of the UST library if its refcount becomes zero (which should
+        * never happen). Do the return value check but discard the handle at the
+        * end of the function as it's not needed.
+        */
+       handle = dlopen(LTTNG_UST_LIB_SO_NAME, RTLD_LAZY | RTLD_NODELETE);
+       if (!handle) {
+               ERR("dlopen of liblttng-ust shared library (%s).", LTTNG_UST_LIB_SO_NAME);
+       }
+
        /*
         * We want precise control over the order in which we construct
         * our sub-libraries vs starting to receive commands from
@@ -1654,6 +1730,7 @@ void __attribute__((constructor)) lttng_ust_init(void)
         * sessiond before the init functions are completed).
         */
        init_usterr();
+       lttng_ust_getenv_init();        /* Needs init_usterr() to be completed. */
        init_tracepoint();
        lttng_ust_init_fd_tracker();
        lttng_ust_clock_init();
@@ -1672,6 +1749,8 @@ void __attribute__((constructor)) lttng_ust_init(void)
 
        timeout_mode = get_constructor_timeout(&constructor_timeout);
 
+       get_allow_blocking();
+
        ret = sem_init(&constructor_wait, 0, 0);
        if (ret) {
                PERROR("sem_init");
@@ -1890,7 +1969,7 @@ void ust_before_fork(sigset_t *save_sigset)
        pthread_mutex_lock(&ust_fork_mutex);
 
        ust_lock_nocheck();
-       rcu_bp_before_fork();
+       urcu_bp_before_fork();
 }
 
 static void ust_after_fork_common(sigset_t *restore_sigset)
@@ -1914,7 +1993,7 @@ void ust_after_fork_parent(sigset_t *restore_sigset)
        if (URCU_TLS(lttng_ust_nest_count))
                return;
        DBG("process %d", getpid());
-       rcu_bp_after_fork_parent();
+       urcu_bp_after_fork_parent();
        /* Release mutexes and reenable signals */
        ust_after_fork_common(restore_sigset);
 }
@@ -1932,10 +2011,12 @@ void ust_after_fork_child(sigset_t *restore_sigset)
 {
        if (URCU_TLS(lttng_ust_nest_count))
                return;
+       lttng_context_vpid_reset();
        lttng_context_vtid_reset();
+       lttng_context_procname_reset();
        DBG("process %d", getpid());
        /* Release urcu mutexes */
-       rcu_bp_after_fork_child();
+       urcu_bp_after_fork_child();
        lttng_ust_cleanup(0);
        /* Release mutexes and reenable signals */
        ust_after_fork_common(restore_sigset);
This page took 0.026006 seconds and 4 git commands to generate.