X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=liblttng-ust%2Flttng-ust-comm.c;h=e8c85304e798b446ecf17110cc9e3fd70464527f;hb=refs%2Fheads%2Fstable-2.2;hp=d91f4bd255a993fc1f8699a3deed4f1cf8a6dba9;hpb=ff0f57289ff0e6be25424081fabbbfc0e3b1b565;p=lttng-ust.git diff --git a/liblttng-ust/lttng-ust-comm.c b/liblttng-ust/lttng-ust-comm.c index d91f4bd2..e8c85304 100644 --- a/liblttng-ust/lttng-ust-comm.c +++ b/liblttng-ust/lttng-ust-comm.c @@ -178,10 +178,14 @@ static const char *str_timeout; static int got_timeout_env; extern void lttng_ring_buffer_client_overwrite_init(void); +extern void lttng_ring_buffer_client_overwrite_rt_init(void); extern void lttng_ring_buffer_client_discard_init(void); +extern void lttng_ring_buffer_client_discard_rt_init(void); extern void lttng_ring_buffer_metadata_client_init(void); extern void lttng_ring_buffer_client_overwrite_exit(void); +extern void lttng_ring_buffer_client_overwrite_rt_exit(void); 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); /* @@ -205,10 +209,12 @@ void print_cmd(int cmd, int handle) { const char *cmd_name = "Unknown"; - if (cmd_name_mapping[cmd]) { + if (cmd >= 0 && cmd < LTTNG_ARRAY_SIZE(cmd_name_mapping) + && cmd_name_mapping[cmd]) { cmd_name = cmd_name_mapping[cmd]; } - DBG("Message Received \"%s\", Handle \"%s\" (%d)", cmd_name, + DBG("Message Received \"%s\" (%d), Handle \"%s\" (%d)", + cmd_name, cmd, lttng_ust_obj_get_name(handle), handle); } @@ -439,6 +445,7 @@ int handle_message(struct sock_info *sock_info, goto error; } ret = len; + free(bytecode); goto end; } else { DBG("incorrect filter data message size: %zd", len); @@ -620,6 +627,25 @@ void cleanup_sock_info(struct sock_info *sock_info, int exiting) { int ret; + if (sock_info->root_handle != -1) { + ret = lttng_ust_objd_unref(sock_info->root_handle, 1); + if (ret) { + ERR("Error unref root handle"); + } + sock_info->root_handle = -1; + } + sock_info->constructor_sem_posted = 0; + + /* + * wait_shm_mmap, socket and notify socket are used by listener + * threads outside of the ust lock, so we cannot tear them down + * ourselves, because we cannot join on these threads. Leave + * responsibility of cleaning up these resources to the OS + * process exit. + */ + if (exiting) + return; + if (sock_info->socket != -1) { ret = ustcomm_close_unix_sock(sock_info->socket); if (ret) { @@ -634,21 +660,7 @@ void cleanup_sock_info(struct sock_info *sock_info, int exiting) } sock_info->notify_socket = -1; } - if (sock_info->root_handle != -1) { - ret = lttng_ust_objd_unref(sock_info->root_handle, 1); - if (ret) { - ERR("Error unref root handle"); - } - sock_info->root_handle = -1; - } - sock_info->constructor_sem_posted = 0; - /* - * wait_shm_mmap is used by listener threads outside of the - * ust lock, so we cannot tear it down ourselves, because we - * cannot join on these threads. Leave this task to the OS - * process exit. - */ - if (!exiting && sock_info->wait_shm_mmap) { + if (sock_info->wait_shm_mmap) { ret = munmap(sock_info->wait_shm_mmap, sysconf(_SC_PAGE_SIZE)); if (ret) { ERR("Error unmapping wait shm"); @@ -677,6 +689,30 @@ int get_wait_shm(struct sock_info *sock_info, size_t mmap_size) */ wait_shm_fd = shm_open(sock_info->wait_shm_path, O_RDONLY, 0); if (wait_shm_fd >= 0) { + int32_t tmp_read; + ssize_t len; + size_t bytes_read = 0; + + /* + * Try to read the fd. If unable to do so, try opening + * it in write mode. + */ + do { + len = read(wait_shm_fd, + &((char *) &tmp_read)[bytes_read], + sizeof(tmp_read) - bytes_read); + if (len > 0) { + bytes_read += len; + } + } while ((len < 0 && errno == EINTR) + || (len > 0 && bytes_read < sizeof(tmp_read))); + if (bytes_read != sizeof(tmp_read)) { + ret = close(wait_shm_fd); + if (ret) { + ERR("close wait_shm_fd"); + } + goto open_write; + } goto end; } else if (wait_shm_fd < 0 && errno != ENOENT) { /* @@ -687,9 +723,11 @@ int get_wait_shm(struct sock_info *sock_info, size_t mmap_size) ERR("Error opening shm %s", sock_info->wait_shm_path); goto end; } + +open_write: /* - * If the open failed because the file did not exist, try - * creating it ourself. + * If the open failed because the file did not exist, or because + * the file was not truncated yet, try creating it ourself. */ URCU_TLS(lttng_ust_nest_count)++; pid = fork(); @@ -884,8 +922,6 @@ void *ust_listener_thread(void *arg) { struct sock_info *sock_info = arg; int sock, ret, prev_connect_failed = 0, has_waited = 0; - int open_sock[2]; - int i; long timeout; /* Restart trying to connect to the session daemon */ @@ -905,11 +941,6 @@ restart: has_waited = 1; prev_connect_failed = 0; } - ust_lock(); - - if (lttng_ust_comm_should_quit) { - goto quit; - } if (sock_info->socket != -1) { ret = ustcomm_close_unix_sock(sock_info->socket); @@ -928,47 +959,40 @@ restart: sock_info->notify_socket = -1; } - /* Register */ - for (i = 0; i < 2; i++) { - ret = ustcomm_connect_unix_sock(sock_info->sock_path); - if (ret < 0) { - DBG("Info: sessiond not accepting connections to %s apps socket", sock_info->name); - prev_connect_failed = 1; - /* - * If we cannot find the sessiond daemon, don't delay - * constructor execution. - */ - ret = handle_register_done(sock_info); - assert(!ret); - ust_unlock(); - goto restart; - } - open_sock[i] = ret; - } + /* + * Register. We need to perform both connect and sending + * registration message before doing the next connect otherwise + * we may reach unix socket connect queue max limits and block + * on the 2nd connect while the session daemon is awaiting the + * first connect registration message. + */ + /* Connect cmd socket */ + ret = ustcomm_connect_unix_sock(sock_info->sock_path); + if (ret < 0) { + DBG("Info: sessiond not accepting connections to %s apps socket", sock_info->name); + prev_connect_failed = 1; - sock_info->socket = open_sock[0]; - sock_info->notify_socket = open_sock[1]; + ust_lock(); + + if (lttng_ust_comm_should_quit) { + goto quit; + } - timeout = get_notify_sock_timeout(); - if (timeout >= 0) { /* - * Give at least 10ms to sessiond to reply to - * notifications. + * If we cannot find the sessiond daemon, don't delay + * constructor execution. */ - if (timeout < 10) - timeout = 10; - ret = ustcomm_setsockopt_rcv_timeout(sock_info->notify_socket, - timeout); - if (ret < 0) { - WARN("Error setting socket receive timeout"); - } - ret = ustcomm_setsockopt_snd_timeout(sock_info->notify_socket, - timeout); - if (ret < 0) { - WARN("Error setting socket send timeout"); - } - } else if (timeout < -1) { - WARN("Unsuppoorted timeout value %ld", timeout); + ret = handle_register_done(sock_info); + assert(!ret); + ust_unlock(); + goto restart; + } + sock_info->socket = ret; + + ust_lock(); + + if (lttng_ust_comm_should_quit) { + goto quit; } /* @@ -999,6 +1023,60 @@ restart: ust_unlock(); goto restart; } + + ust_unlock(); + + /* Connect notify socket */ + ret = ustcomm_connect_unix_sock(sock_info->sock_path); + if (ret < 0) { + DBG("Info: sessiond not accepting connections to %s apps socket", sock_info->name); + prev_connect_failed = 1; + + ust_lock(); + + if (lttng_ust_comm_should_quit) { + goto quit; + } + + /* + * If we cannot find the sessiond daemon, don't delay + * constructor execution. + */ + ret = handle_register_done(sock_info); + assert(!ret); + ust_unlock(); + goto restart; + } + sock_info->notify_socket = ret; + + timeout = get_notify_sock_timeout(); + if (timeout >= 0) { + /* + * Give at least 10ms to sessiond to reply to + * notifications. + */ + if (timeout < 10) + timeout = 10; + ret = ustcomm_setsockopt_rcv_timeout(sock_info->notify_socket, + timeout); + if (ret < 0) { + WARN("Error setting socket receive timeout"); + } + ret = ustcomm_setsockopt_snd_timeout(sock_info->notify_socket, + timeout); + if (ret < 0) { + WARN("Error setting socket send timeout"); + } + } else if (timeout < -1) { + WARN("Unsupported timeout value %ld", timeout); + } + + ust_lock(); + + if (lttng_ust_comm_should_quit) { + goto quit; + } + ret = register_to_sessiond(sock_info->notify_socket, USTCTL_SOCKET_NOTIFY); if (ret < 0) { @@ -1116,7 +1194,10 @@ void __attribute__((constructor)) lttng_ust_init(void) init_tracepoint(); lttng_ring_buffer_metadata_client_init(); lttng_ring_buffer_client_overwrite_init(); + lttng_ring_buffer_client_overwrite_rt_init(); lttng_ring_buffer_client_discard_init(); + lttng_ring_buffer_client_discard_rt_init(); + lttng_context_init(); timeout_mode = get_constructor_timeout(&constructor_timeout); @@ -1219,7 +1300,10 @@ void lttng_ust_cleanup(int exiting) */ lttng_ust_abi_exit(); lttng_ust_events_exit(); + lttng_context_exit(); + lttng_ring_buffer_client_discard_rt_exit(); lttng_ring_buffer_client_discard_exit(); + lttng_ring_buffer_client_overwrite_rt_exit(); lttng_ring_buffer_client_overwrite_exit(); lttng_ring_buffer_metadata_client_exit(); exit_tracepoint();