X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;ds=sidebyside;f=libust%2Flttng-ust-comm.c;h=7971168c638b2d14fdf0864ec3bb6a0b35ec840e;hb=35ec2526b0bd16c7ee9884fda90b8e761e75425d;hp=93f48940edb9a162f205686b066f1f9eb9bbc4e9;hpb=33bbeb90d8a4fbad6e9ec6cdfe8f8ac007b5896f;p=lttng-ust.git diff --git a/libust/lttng-ust-comm.c b/libust/lttng-ust-comm.c index 93f48940..7971168c 100644 --- a/libust/lttng-ust-comm.c +++ b/libust/lttng-ust-comm.c @@ -19,6 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#define _LGPL_SOURCE #include #include #include @@ -35,8 +36,10 @@ #include #include #include +#include #include +#include #include #include #include @@ -117,6 +120,8 @@ struct sock_info local_apps = { .socket = -1, }; +static int wait_poll_fallback; + extern void ltt_ring_buffer_client_overwrite_init(void); extern void ltt_ring_buffer_client_discard_init(void); extern void ltt_ring_buffer_metadata_client_init(void); @@ -213,6 +218,9 @@ int handle_register_done(struct sock_info *sock_info) if (sock_info->constructor_sem_posted) return 0; sock_info->constructor_sem_posted = 1; + if (uatomic_read(&sem_count) <= 0) { + return 0; + } ret = uatomic_add_return(&sem_count, -1); if (ret == 0) { ret = sem_post(&constructor_wait); @@ -228,6 +236,7 @@ int handle_message(struct sock_info *sock_info, int ret = 0; const struct objd_ops *ops; struct lttcomm_ust_reply lur; + int shm_fd, wait_fd; ust_lock(); @@ -273,10 +282,53 @@ end: if (ret >= 0) { lur.ret_code = LTTCOMM_OK; } else { - lur.ret_code = LTTCOMM_SESSION_FAIL; + //lur.ret_code = LTTCOMM_SESSION_FAIL; + lur.ret_code = ret; + } + switch (lum->cmd) { + case LTTNG_UST_STREAM: + /* + * Special-case reply to send stream info. + * Use lum.u output. + */ + lur.u.stream.memory_map_size = lum->u.stream.memory_map_size; + shm_fd = lum->u.stream.shm_fd; + wait_fd = lum->u.stream.wait_fd; + break; + case LTTNG_UST_METADATA: + case LTTNG_UST_CHANNEL: + lur.u.channel.memory_map_size = lum->u.channel.memory_map_size; + shm_fd = lum->u.channel.shm_fd; + wait_fd = lum->u.channel.wait_fd; + break; } ret = send_reply(sock, &lur); + if (ret < 0) { + perror("error sending reply"); + goto error; + } + if ((lum->cmd == LTTNG_UST_STREAM + || lum->cmd == LTTNG_UST_CHANNEL + || lum->cmd == LTTNG_UST_METADATA) + && lur.ret_code == LTTCOMM_OK) { + /* we also need to send the file descriptors. */ + ret = lttcomm_send_fds_unix_sock(sock, + &shm_fd, &shm_fd, + 1, sizeof(int)); + if (ret < 0) { + perror("send shm_fd"); + goto error; + } + ret = lttcomm_send_fds_unix_sock(sock, + &wait_fd, &wait_fd, + 1, sizeof(int)); + if (ret < 0) { + perror("send wait_fd"); + goto error; + } + } +error: ust_unlock(); return ret; } @@ -477,10 +529,15 @@ error: static void wait_for_sessiond(struct sock_info *sock_info) { + int ret; + ust_lock(); if (lttng_ust_comm_should_quit) { goto quit; } + if (wait_poll_fallback) { + goto error; + } if (!sock_info->wait_shm_mmap) { sock_info->wait_shm_mmap = get_map_shm(sock_info); if (!sock_info->wait_shm_mmap) @@ -489,9 +546,23 @@ void wait_for_sessiond(struct sock_info *sock_info) ust_unlock(); DBG("Waiting for %s apps sessiond", sock_info->name); - /* Wait for futex wakeup TODO */ - sleep(5); - + /* 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; + ERR( +"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."); + } + PERROR("futex"); + } + } return; quit: @@ -500,8 +571,6 @@ quit: error: ust_unlock(); - /* Error handling: fallback on a 5 seconds sleep. */ - sleep(5); return; } @@ -516,10 +585,25 @@ static void *ust_listener_thread(void *arg) { struct sock_info *sock_info = arg; - int sock, ret; + int sock, ret, prev_connect_failed = 0, has_waited = 0; /* Restart trying to connect to the session daemon */ restart: + if (prev_connect_failed) { + /* Wait for sessiond availability with pipe */ + wait_for_sessiond(sock_info); + if (has_waited) { + has_waited = 0; + /* + * Sleep for 5 seconds before retrying after a + * sequence of failure / wait / failure. This + * deals with a killed or broken session daemon. + */ + sleep(5); + } + has_waited = 1; + prev_connect_failed = 0; + } ust_lock(); if (lttng_ust_comm_should_quit) { @@ -539,6 +623,7 @@ restart: ret = lttcomm_connect_unix_sock(sock_info->sock_path); if (ret < 0) { ERR("Error connecting to %s apps socket", sock_info->name); + prev_connect_failed = 1; /* * If we cannot find the sessiond daemon, don't delay * constructor execution. @@ -546,9 +631,6 @@ restart: ret = handle_register_done(sock_info); assert(!ret); ust_unlock(); - - /* Wait for sessiond availability with pipe */ - wait_for_sessiond(sock_info); goto restart; } @@ -560,7 +642,7 @@ restart: */ if (sock_info->root_handle == -1) { ret = lttng_abi_create_root_handle(); - if (ret) { + if (ret < 0) { ERR("Error creating root handle"); ust_unlock(); goto quit; @@ -571,6 +653,7 @@ restart: ret = register_app_to_sessiond(sock); if (ret < 0) { ERR("Error registering to %s apps socket", sock_info->name); + prev_connect_failed = 1; /* * If we cannot register to the sessiond daemon, don't * delay constructor execution. @@ -578,7 +661,6 @@ restart: ret = handle_register_done(sock_info); assert(!ret); ust_unlock(); - wait_for_sessiond(sock_info); goto restart; } ust_unlock(); @@ -843,6 +925,7 @@ void ust_after_fork_child(ust_fork_info_t *fork_info) /* 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(fork_info); lttng_ust_init();