X-Git-Url: http://git.lttng.org./?a=blobdiff_plain;f=liblttng-ust%2Flttng-ust-comm.c;h=2ada5065f995a30fb517cc7c13331256b13a2fc1;hb=5cf81d53e305c81517e48e0dc91620a916cdc0cc;hp=cc5188f6112cb744ddd45297973cef532201d9a6;hpb=5e1b7b8bac9f038e681906b269c1422611c6376d;p=lttng-ust.git diff --git a/liblttng-ust/lttng-ust-comm.c b/liblttng-ust/lttng-ust-comm.c index cc5188f6..2ada5065 100644 --- a/liblttng-ust/lttng-ust-comm.c +++ b/liblttng-ust/lttng-ust-comm.c @@ -52,9 +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 ? @@ -113,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) { @@ -142,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) { @@ -163,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); @@ -176,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"); + } } /* @@ -307,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. @@ -316,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"); } /* @@ -402,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) @@ -415,6 +455,9 @@ long get_timeout(void) } if (str_timeout) constructor_delay_ms = strtol(str_timeout, NULL, 10); + /* All negative values are considered as "-1". */ + if (constructor_delay_ms < -1) + constructor_delay_ms = -1; return constructor_delay_ms; } @@ -425,7 +468,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) @@ -448,7 +491,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 += @@ -457,6 +501,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; } @@ -552,13 +597,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) { @@ -619,12 +664,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; @@ -684,12 +729,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) { @@ -730,11 +775,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; @@ -755,7 +800,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, @@ -775,7 +820,6 @@ int handle_message(struct sock_info *sock_info, break; } -end: lur.handle = lum->handle; lur.cmd = lum->cmd; lur.ret_val = ret; @@ -907,7 +951,12 @@ void cleanup_sock_info(struct sock_info *sock_info, int exiting) long page_size; page_size = sysconf(_SC_PAGE_SIZE); - if (page_size > 0) { + if (page_size <= 0) { + if (!page_size) { + errno = EINVAL; + } + PERROR("Error in sysconf(_SC_PAGE_SIZE)"); + } else { ret = munmap(sock_info->wait_shm_mmap, page_size); if (ret) { ERR("Error unmapping wait shm"); @@ -1089,7 +1138,11 @@ char *get_map_shm(struct sock_info *sock_info) char *wait_shm_mmap; page_size = sysconf(_SC_PAGE_SIZE); - if (page_size < 0) { + if (page_size <= 0) { + if (!page_size) { + errno = EINVAL; + } + PERROR("Error in sysconf(_SC_PAGE_SIZE)"); goto error; } @@ -1117,8 +1170,6 @@ error: static void wait_for_sessiond(struct sock_info *sock_info) { - int ret; - if (ust_lock()) { goto quit; } @@ -1134,23 +1185,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: @@ -1189,8 +1249,9 @@ restart: * deals with a killed or broken session daemon. */ sleep(5); + } else { + has_waited = 1; } - has_waited = 1; prev_connect_failed = 0; } @@ -1369,7 +1430,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: @@ -1449,7 +1516,7 @@ void __attribute__((constructor)) lttng_ust_init(void) init_tracepoint(); lttng_ust_clock_init(); lttng_ust_getcpu_init(); - lttng_ust_baddr_statedump_init(); + lttng_ust_statedump_init(); lttng_ring_buffer_metadata_client_init(); lttng_ring_buffer_client_overwrite_init(); lttng_ring_buffer_client_overwrite_rt_init(); @@ -1551,9 +1618,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 @@ -1570,7 +1635,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 */