X-Git-Url: http://git.lttng.org/?a=blobdiff_plain;f=liblttng-ust%2Flttng-ust-comm.c;h=0cf5ecd9687536be5fc7794c4bfeb28ed135a11f;hb=101dace0dc164352c81cb347a7a0022aa84eabc6;hp=a84316a9358caeda6be0138a439c3828dd979b8e;hpb=8478887d1c753e281a584c0e8a3b63f34359ff76;p=lttng-ust.git diff --git a/liblttng-ust/lttng-ust-comm.c b/liblttng-ust/lttng-ust-comm.c index a84316a9..0cf5ecd9 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" @@ -364,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"); } /* @@ -396,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; @@ -449,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 @@ -458,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) @@ -469,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. */ @@ -513,6 +534,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) { @@ -936,6 +970,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"); @@ -966,13 +1015,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; } @@ -1213,17 +1255,39 @@ 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; + } + + 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, 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; @@ -1300,9 +1364,10 @@ 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(); /* * If available, add '-ust' to the end of this thread's * process name @@ -1331,7 +1396,12 @@ 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); if (ret) { ERR("Error closing %s ust cmd socket", @@ -1340,6 +1410,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", @@ -1348,6 +1419,7 @@ restart: sock_info->notify_socket = -1; } + /* * Register. We need to perform both connect and sending * registration message before doing the next connect otherwise @@ -1356,15 +1428,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. @@ -1374,8 +1445,28 @@ restart: ust_unlock(); goto restart; } + 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(); + /* + * 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; } @@ -1410,17 +1501,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. @@ -1430,7 +1528,32 @@ restart: ust_unlock(); goto restart; } + + 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(); + /* + * 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) { @@ -1454,10 +1577,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) { @@ -1575,12 +1694,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(); lttng_ust_loaded = 1; @@ -1591,7 +1705,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(); @@ -1608,6 +1724,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"); @@ -1811,6 +1929,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 */