X-Git-Url: http://git.lttng.org./?a=blobdiff_plain;f=liblttng-ust%2Flttng-ust-comm.c;h=08e6299ce3a5bd7793e4ddf04c556e9d04e2e7f8;hb=382cbd153bc0240b75d1bece7564c900599534b4;hp=378ca21cfc71f354a282fe4a9a521cf77319ef02;hpb=1556a5495c92bdd99e57faa87e21eb0b6f95c3a2;p=lttng-ust.git diff --git a/liblttng-ust/lttng-ust-comm.c b/liblttng-ust/lttng-ust-comm.c index 378ca21c..08e6299c 100644 --- a/liblttng-ust/lttng-ust-comm.c +++ b/liblttng-ust/lttng-ust-comm.c @@ -20,6 +20,7 @@ */ #define _LGPL_SOURCE +#define _GNU_SOURCE #include #include #include @@ -51,7 +52,10 @@ #include "lttng-tracer-core.h" #include "compat.h" #include "../libringbuffer/tlsfixup.h" -#include "lttng-ust-baddr.h" +#include "lttng-ust-statedump.h" +#include "clock.h" +#include "../libringbuffer/getcpu.h" +#include "getenv.h" /* * Has lttng ust comm constructor been called ? @@ -110,8 +114,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 +150,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 +178,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 +191,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"); + } } /* @@ -304,6 +329,24 @@ extern void lttng_ring_buffer_client_discard_exit(void); extern void lttng_ring_buffer_client_discard_rt_exit(void); extern void lttng_ring_buffer_metadata_client_exit(void); +ssize_t lttng_ust_read(int fd, void *buf, size_t len) +{ + ssize_t ret; + size_t copied = 0, to_copy = len; + + do { + ret = read(fd, buf + copied, to_copy); + if (ret > 0) { + copied += ret; + to_copy -= ret; + } + } while ((ret > 0 && to_copy > 0) + || (ret < 0 && errno == EINTR)); + if (ret > 0) { + ret = copied; + } + return ret; +} /* * Returns the HOME directory path. Caller MUST NOT free(3) the returned * pointer. @@ -313,11 +356,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"); } /* @@ -399,7 +442,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) @@ -422,7 +465,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) @@ -445,7 +488,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 += @@ -454,6 +498,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; } @@ -549,13 +594,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) { @@ -616,12 +661,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; @@ -681,12 +726,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) { @@ -727,11 +772,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; @@ -752,7 +797,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, @@ -772,7 +817,6 @@ int handle_message(struct sock_info *sock_info, break; } -end: lur.handle = lum->handle; lur.cmd = lum->cmd; lur.ret_val = ret; @@ -1114,8 +1158,6 @@ error: static void wait_for_sessiond(struct sock_info *sock_info) { - int ret; - if (ust_lock()) { goto quit; } @@ -1131,23 +1173,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: @@ -1366,7 +1417,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: @@ -1444,7 +1501,9 @@ void __attribute__((constructor)) lttng_ust_init(void) */ init_usterr(); init_tracepoint(); - lttng_ust_baddr_statedump_init(); + lttng_ust_clock_init(); + lttng_ust_getcpu_init(); + lttng_ust_statedump_init(); lttng_ring_buffer_metadata_client_init(); lttng_ring_buffer_client_overwrite_init(); lttng_ring_buffer_client_overwrite_rt_init(); @@ -1546,9 +1605,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 @@ -1565,7 +1622,7 @@ void lttng_ust_cleanup(int exiting) lttng_ring_buffer_client_overwrite_rt_exit(); lttng_ring_buffer_client_overwrite_exit(); lttng_ring_buffer_metadata_client_exit(); - lttng_ust_baddr_statedump_destroy(); + lttng_ust_statedump_destroy(); exit_tracepoint(); if (!exiting) { /* Reinitialize values for fork */