X-Git-Url: http://git.liburcu.org/?a=blobdiff_plain;f=liblttng-ust%2Flttng-ust-comm.c;h=fbdee7d3af8ea0d8d122ab3e4b3bb8a251ccc9a0;hb=549df04044855ca170838fe2f7d92b523445be65;hp=3a3e1d2827c82ea48ef6a79c1b89293ffbfce5b9;hpb=4770bd47f35d74dd6825169bd2548d65df0217ae;p=lttng-ust.git diff --git a/liblttng-ust/lttng-ust-comm.c b/liblttng-ust/lttng-ust-comm.c index 3a3e1d28..fbdee7d3 100644 --- a/liblttng-ust/lttng-ust-comm.c +++ b/liblttng-ust/lttng-ust-comm.c @@ -52,6 +52,7 @@ #include "compat.h" #include "../libringbuffer/tlsfixup.h" #include "lttng-ust-baddr.h" +#include "getenv.h" /* * Has lttng ust comm constructor been called ? @@ -110,8 +111,15 @@ static int lttng_ust_comm_should_quit; int ust_lock(void) { sigset_t sig_all_blocked, orig_mask; - int ret; + int ret, oldstate; + ret = pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate); + if (ret) { + ERR("pthread_setcancelstate: %s", strerror(ret)); + } + if (oldstate != PTHREAD_CANCEL_ENABLE) { + ERR("pthread_setcancelstate: unexpected oldstate"); + } sigfillset(&sig_all_blocked); ret = pthread_sigmask(SIG_SETMASK, &sig_all_blocked, &orig_mask); if (ret) { @@ -139,8 +147,15 @@ int ust_lock(void) void ust_lock_nocheck(void) { sigset_t sig_all_blocked, orig_mask; - int ret; + int ret, oldstate; + ret = pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate); + if (ret) { + ERR("pthread_setcancelstate: %s", strerror(ret)); + } + if (oldstate != PTHREAD_CANCEL_ENABLE) { + ERR("pthread_setcancelstate: unexpected oldstate"); + } sigfillset(&sig_all_blocked); ret = pthread_sigmask(SIG_SETMASK, &sig_all_blocked, &orig_mask); if (ret) { @@ -160,7 +175,7 @@ void ust_lock_nocheck(void) void ust_unlock(void) { sigset_t sig_all_blocked, orig_mask; - int ret; + int ret, oldstate; sigfillset(&sig_all_blocked); ret = pthread_sigmask(SIG_SETMASK, &sig_all_blocked, &orig_mask); @@ -173,6 +188,13 @@ void ust_unlock(void) if (ret) { ERR("pthread_sigmask: %s", strerror(ret)); } + ret = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate); + if (ret) { + ERR("pthread_setcancelstate: %s", strerror(ret)); + } + if (oldstate != PTHREAD_CANCEL_DISABLE) { + ERR("pthread_setcancelstate: unexpected oldstate"); + } } /* @@ -313,11 +335,11 @@ const char *get_lttng_home_dir(void) { const char *val; - val = (const char *) getenv("LTTNG_HOME"); + val = (const char *) lttng_secure_getenv("LTTNG_HOME"); if (val != NULL) { return val; } - return (const char *) getenv("HOME"); + return (const char *) lttng_secure_getenv("HOME"); } /* @@ -335,6 +357,16 @@ void lttng_fixup_ust_mutex_nest_tls(void) asm volatile ("" : : "m" (URCU_TLS(ust_mutex_nest))); } +/* + * Fixup urcu bp TLS. + */ +static +void lttng_fixup_urcu_bp_tls(void) +{ + rcu_read_lock(); + rcu_read_unlock(); +} + int lttng_get_notify_socket(void *owner) { struct sock_info *info = owner; @@ -389,7 +421,7 @@ int setup_local_apps(void) /* * Get notify_sock timeout, in ms. - * -1: don't wait. 0: wait forever. >0: timeout, in ms. + * -1: wait forever. 0: don't wait. >0: timeout, in ms. */ static long get_timeout(void) @@ -412,7 +444,7 @@ long get_notify_sock_timeout(void) } /* - * Return values: -1: don't wait. 0: wait forever. 1: timeout wait. + * Return values: -1: wait forever. 0: don't wait. 1: timeout wait. */ static int get_constructor_timeout(struct timespec *constructor_timeout) @@ -435,7 +467,8 @@ int get_constructor_timeout(struct timespec *constructor_timeout) */ ret = clock_gettime(CLOCK_REALTIME, constructor_timeout); if (ret) { - return -1; + /* Don't wait. */ + return 0; } constructor_timeout->tv_sec += constructor_delay_ms / 1000UL; constructor_timeout->tv_nsec += @@ -444,6 +477,7 @@ int get_constructor_timeout(struct timespec *constructor_timeout) constructor_timeout->tv_sec++; constructor_timeout->tv_nsec -= 1000000000UL; } + /* Timeout wait (constructor_delay_ms). */ return 1; } @@ -518,8 +552,8 @@ void handle_pending_statedump(struct sock_info *sock_info) int ctor_passed = sock_info->constructor_sem_posted; if (ctor_passed && sock_info->statedump_pending) { - pthread_mutex_lock(&ust_fork_mutex); sock_info->statedump_pending = 0; + pthread_mutex_lock(&ust_fork_mutex); lttng_handle_pending_statedump(sock_info); pthread_mutex_unlock(&ust_fork_mutex); } @@ -539,13 +573,13 @@ int handle_message(struct sock_info *sock_info, if (ust_lock()) { ret = -LTTNG_UST_ERR_EXITING; - goto end; + goto error; } ops = objd_ops(lum->handle); if (!ops) { ret = -ENOENT; - goto end; + goto error; } switch (lum->cmd) { @@ -606,12 +640,12 @@ int handle_message(struct sock_info *sock_info, } ret = len; free(bytecode); - goto end; + goto error; } else { DBG("incorrect filter data message size: %zd", len); ret = -EINVAL; free(bytecode); - goto end; + goto error; } } bytecode->bc.len = lum->u.filter.data_size; @@ -671,12 +705,12 @@ int handle_message(struct sock_info *sock_info, } ret = len; free(node); - goto end; + goto error; } else { DBG("Incorrect exclusion data message size: %zd", len); ret = -EINVAL; free(node); - goto end; + goto error; } } if (ops->cmd) { @@ -717,11 +751,11 @@ int handle_message(struct sock_info *sock_info, goto error; } ret = len; - goto end; + goto error; } else { DBG("incorrect channel data message size: %zd", len); ret = -EINVAL; - goto end; + goto error; } } args.channel.chan_data = chan_data; @@ -742,7 +776,7 @@ int handle_message(struct sock_info *sock_info, &args.stream.shm_fd, &args.stream.wakeup_fd); if (ret) { - goto end; + goto error; } if (ops->cmd) ret = ops->cmd(lum->handle, lum->cmd, @@ -762,7 +796,6 @@ int handle_message(struct sock_info *sock_info, break; } -end: lur.handle = lum->handle; lur.cmd = lum->cmd; lur.ret_val = ret; @@ -1104,8 +1137,6 @@ error: static void wait_for_sessiond(struct sock_info *sock_info) { - int ret; - if (ust_lock()) { goto quit; } @@ -1121,23 +1152,32 @@ void wait_for_sessiond(struct sock_info *sock_info) DBG("Waiting for %s apps sessiond", sock_info->name); /* Wait for futex wakeup */ - if (uatomic_read((int32_t *) sock_info->wait_shm_mmap) == 0) { - ret = futex_async((int32_t *) sock_info->wait_shm_mmap, - FUTEX_WAIT, 0, NULL, NULL, 0); - if (ret < 0) { - if (errno == EFAULT) { - wait_poll_fallback = 1; - DBG( + if (uatomic_read((int32_t *) sock_info->wait_shm_mmap)) + goto end_wait; + + while (futex_async((int32_t *) sock_info->wait_shm_mmap, + FUTEX_WAIT, 0, NULL, NULL, 0)) { + switch (errno) { + case EWOULDBLOCK: + /* Value already changed. */ + goto end_wait; + case EINTR: + /* Retry if interrupted by signal. */ + break; /* Get out of switch. */ + case EFAULT: + wait_poll_fallback = 1; + DBG( "Linux kernels 2.6.33 to 3.0 (with the exception of stable versions) " "do not support FUTEX_WAKE on read-only memory mappings correctly. " "Please upgrade your kernel " "(fix is commit 9ea71503a8ed9184d2d0b8ccc4d269d05f7940ae in Linux kernel " "mainline). LTTng-UST will use polling mode fallback."); - if (ust_debug()) - PERROR("futex"); - } + if (ust_debug()) + PERROR("futex"); + goto end_wait; } } +end_wait: return; quit: @@ -1356,7 +1396,13 @@ restart: print_cmd(lum.cmd, lum.handle); ret = handle_message(sock_info, sock, &lum); if (ret) { - ERR("Error handling message for %s socket", sock_info->name); + ERR("Error handling message for %s socket", + sock_info->name); + /* + * Close socket if protocol error is + * detected. + */ + goto end; } continue; default: @@ -1419,6 +1465,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(); @@ -1535,9 +1582,7 @@ static void lttng_ust_cleanup(int exiting) { cleanup_sock_info(&global_apps, exiting); - if (local_apps.allowed) { - cleanup_sock_info(&local_apps, exiting); - } + cleanup_sock_info(&local_apps, exiting); /* * The teardown in this function all affect data structures * accessed under the UST lock by the listener thread. This