X-Git-Url: http://git.lttng.org/?a=blobdiff_plain;f=liblttng-ust%2Flttng-ust-comm.c;h=43728ff47613d2d2fb0b8e092268ea1c60243f79;hb=6f626d284c2bb02ae8980da6e8053e191d604286;hp=cc9b6b5e1e8706a1b941de1b0d09ea37dddaffd3;hpb=2315088b93f925c5cccee865ccb8f6bc542e52dc;p=lttng-ust.git diff --git a/liblttng-ust/lttng-ust-comm.c b/liblttng-ust/lttng-ust-comm.c index cc9b6b5e..43728ff4 100644 --- a/liblttng-ust/lttng-ust-comm.c +++ b/liblttng-ust/lttng-ust-comm.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -46,12 +47,13 @@ #include #include #include +#include #include #include #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" @@ -106,6 +108,14 @@ static pthread_mutex_t ust_fork_mutex = PTHREAD_MUTEX_INITIALIZER; /* Should the ust comm thread quit ? */ static int lttng_ust_comm_should_quit; +/* + * This variable can be tested by applications to check whether + * lttng-ust is loaded. They simply have to define their own + * "lttng_ust_loaded" weak symbol, and test it. It is set to 1 by the + * library constructor. + */ +int lttng_ust_loaded __attribute__((weak)); + /* * Return 0 on success, -1 if should quit. * The lock is taken in both cases. @@ -356,11 +366,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"); } /* @@ -388,6 +398,17 @@ 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(); + lttng_ust_fixup_fd_tracker_tls(); +} + int lttng_get_notify_socket(void *owner) { struct sock_info *info = owner; @@ -441,7 +462,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 @@ -450,7 +471,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) @@ -461,12 +482,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. */ @@ -505,6 +534,30 @@ int get_constructor_timeout(struct timespec *constructor_timeout) return 1; } +static +void get_blocking_retry_timeout(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); + } +} + static int register_to_sessiond(int socket, enum ustctl_socket_type type) { @@ -928,6 +981,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"); @@ -958,13 +1026,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; } @@ -1205,17 +1266,28 @@ char *get_map_shm(struct sock_info *sock_info) goto error; } + lttng_ust_lock_fd_tracker(); wait_shm_fd = get_wait_shm(sock_info, page_size); if (wait_shm_fd < 0) { + lttng_ust_unlock_fd_tracker(); goto error; } + lttng_ust_add_fd_to_tracker(wait_shm_fd); + lttng_ust_unlock_fd_tracker(); + wait_shm_mmap = mmap(NULL, page_size, PROT_READ, MAP_SHARED, wait_shm_fd, 0); + /* close shm fd immediately after taking the mmap reference */ + lttng_ust_lock_fd_tracker(); ret = close(wait_shm_fd); - if (ret) { + if (!ret) { + lttng_ust_delete_fd_from_tracker(wait_shm_fd); + } else { PERROR("Error closing fd"); } + lttng_ust_unlock_fd_tracker(); + if (wait_shm_mmap == MAP_FAILED) { DBG("mmap error (can be caused by race with sessiond). Fallback to poll mode."); goto error; @@ -1295,6 +1367,7 @@ void *ust_listener_thread(void *arg) int sock, ret, prev_connect_failed = 0, has_waited = 0; long timeout; + lttng_ust_fixup_tls(); /* * If available, add '-ust' to the end of this thread's * process name @@ -1324,6 +1397,7 @@ restart: } if (sock_info->socket != -1) { + /* FD tracker is updated by ustcomm_close_unix_sock() */ ret = ustcomm_close_unix_sock(sock_info->socket); if (ret) { ERR("Error closing %s ust cmd socket", @@ -1332,6 +1406,7 @@ restart: sock_info->socket = -1; } if (sock_info->notify_socket != -1) { + /* FD tracker is updated by ustcomm_close_unix_sock() */ ret = ustcomm_close_unix_sock(sock_info->notify_socket); if (ret) { ERR("Error closing %s ust notify socket", @@ -1340,6 +1415,10 @@ restart: sock_info->notify_socket = -1; } + if (ust_lock()) { + goto quit; + } + /* * Register. We need to perform both connect and sending * registration message before doing the next connect otherwise @@ -1348,15 +1427,14 @@ restart: * first connect registration message. */ /* Connect cmd socket */ - ret = ustcomm_connect_unix_sock(sock_info->sock_path); + lttng_ust_lock_fd_tracker(); + ret = ustcomm_connect_unix_sock(sock_info->sock_path, + get_connect_sock_timeout()); if (ret < 0) { + lttng_ust_unlock_fd_tracker(); DBG("Info: sessiond not accepting connections to %s apps socket", sock_info->name); prev_connect_failed = 1; - if (ust_lock()) { - goto quit; - } - /* * If we cannot find the sessiond daemon, don't delay * constructor execution. @@ -1366,8 +1444,16 @@ restart: ust_unlock(); goto restart; } + lttng_ust_add_fd_to_tracker(ret); + lttng_ust_unlock_fd_tracker(); sock_info->socket = ret; + ust_unlock(); + /* + * Unlock/relock ust lock because connect is blocking (with + * timeout). Don't delay constructors on the ust lock for too + * long. + */ if (ust_lock()) { goto quit; } @@ -1402,17 +1488,24 @@ restart: } ust_unlock(); + /* + * Unlock/relock ust lock because connect is blocking (with + * timeout). Don't delay constructors on the ust lock for too + * long. + */ + if (ust_lock()) { + goto quit; + } /* Connect notify socket */ - ret = ustcomm_connect_unix_sock(sock_info->sock_path); + lttng_ust_lock_fd_tracker(); + ret = ustcomm_connect_unix_sock(sock_info->sock_path, + get_connect_sock_timeout()); if (ret < 0) { + lttng_ust_unlock_fd_tracker(); DBG("Info: sessiond not accepting connections to %s apps socket", sock_info->name); prev_connect_failed = 1; - if (ust_lock()) { - goto quit; - } - /* * If we cannot find the sessiond daemon, don't delay * constructor execution. @@ -1422,8 +1515,20 @@ restart: ust_unlock(); goto restart; } + lttng_ust_add_fd_to_tracker(ret); + lttng_ust_unlock_fd_tracker(); sock_info->notify_socket = ret; + ust_unlock(); + /* + * Unlock/relock ust lock because connect is blocking (with + * timeout). Don't delay constructors on the ust lock for too + * long. + */ + if (ust_lock()) { + goto quit; + } + timeout = get_notify_sock_timeout(); if (timeout >= 0) { /* @@ -1446,10 +1551,6 @@ restart: WARN("Unsupported timeout value %ld", timeout); } - if (ust_lock()) { - goto quit; - } - ret = register_to_sessiond(sock_info->notify_socket, USTCTL_SOCKET_NOTIFY); if (ret < 0) { @@ -1547,13 +1648,6 @@ void lttng_ust_malloc_wrapper_init(void) { } -static -void init_ust_env(void) -{ - if (putenv("LTTNG_UST_LOADED=1")) - DBG("Error setting LTTNG_UST_LOADED environment variable"); -} - /* * sessiond monitoring thread: monitor presence of global and per-user * sessiond by polling the application common named pipe. @@ -1574,14 +1668,9 @@ 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(); - init_ust_env(); + lttng_ust_loaded = 1; /* * We want precise control over the order in which we construct @@ -1590,7 +1679,9 @@ 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(); lttng_ust_getcpu_init(); lttng_ust_statedump_init(); @@ -1607,6 +1698,8 @@ void __attribute__((constructor)) lttng_ust_init(void) timeout_mode = get_constructor_timeout(&constructor_timeout); + get_blocking_retry_timeout(); + ret = sem_init(&constructor_wait, 0, 0); if (ret) { PERROR("sem_init"); @@ -1714,6 +1807,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 @@ -1809,6 +1903,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 */ @@ -1863,11 +1960,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();