#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
+#include <dlfcn.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.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." LTTNG_UST_LIBRARY_VERSION_MAJOR
+
/*
* Has lttng ust comm constructor been called ?
*/
}
static
-void get_blocking_retry_timeout(void)
+void get_allow_blocking(void)
{
- const char *str_blocking_retry_timeout =
- lttng_getenv("LTTNG_UST_BLOCKING_RETRY_TIMEOUT");
-
- if (str_blocking_retry_timeout) {
- long timeout = strtol(str_blocking_retry_timeout, NULL, 10);
-
- if (timeout < 0)
- timeout = -1;
- if (timeout > INT_MAX) {
- WARN("Saturating %s value from %ld to %d\n",
- "LTTNG_UST_BLOCKING_RETRY_TIMEOUT",
- timeout, INT_MAX);
- timeout = INT_MAX;
- }
- DBG("%s environment variable value is %ld",
- "LTTNG_UST_BLOCKING_RETRY_TIMEOUT",
- timeout);
- lttng_ust_ringbuffer_set_retry_timeout(timeout);
+ 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();
}
}
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,
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();
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);
sock_info->notify_socket = -1;
}
- if (ust_lock()) {
- goto quit;
- }
/*
* Register. We need to perform both connect and sending
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();
/*
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();
/*
pthread_attr_t thread_attr;
int timeout_mode;
int ret;
+ void *handle;
if (uatomic_xchg(&initialized, 1) == 1)
return;
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
timeout_mode = get_constructor_timeout(&constructor_timeout);
- get_blocking_retry_timeout();
+ get_allow_blocking();
ret = sem_init(&constructor_wait, 0, 0);
if (ret) {
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)
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);
}
{
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);