X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=liblttng-ust%2Flttng-ust-comm.c;h=67438117408715cff1e009123d392544dcb9bd96;hb=e63683c765cba41c0b140e283d2eb03523e4c57e;hp=5e738b06cf6eee5b539f4f507ba97817525a8fbf;hpb=e37047b693079a1136cc467f6ea9b8090ce58d10;p=lttng-ust.git diff --git a/liblttng-ust/lttng-ust-comm.c b/liblttng-ust/lttng-ust-comm.c index 5e738b06..67438117 100644 --- a/liblttng-ust/lttng-ust-comm.c +++ b/liblttng-ust/lttng-ust-comm.c @@ -78,6 +78,12 @@ static sem_t constructor_wait; */ static int sem_count = { 2 }; +/* + * Counting nesting within lttng-ust. Used to ensure that calling fork() + * from liblttng-ust does not execute the pre/post fork handlers. + */ +static int __thread lttng_ust_nest_count; + /* * Info about socket and associated listener thread. */ @@ -130,6 +136,15 @@ extern void ltt_ring_buffer_client_overwrite_exit(void); extern void ltt_ring_buffer_client_discard_exit(void); extern void ltt_ring_buffer_metadata_client_exit(void); +/* + * Force a read (imply TLS fixup for dlopen) of TLS variables. + */ +static +void lttng_fixup_nest_count_tls(void) +{ + asm volatile ("" : : "m" (lttng_ust_nest_count)); +} + static int setup_local_apps(void) { @@ -469,7 +484,9 @@ int get_wait_shm(struct sock_info *sock_info, size_t mmap_size) * If the open failed because the file did not exist, try * creating it ourself. */ + lttng_ust_nest_count++; pid = fork(); + lttng_ust_nest_count--; if (pid > 0) { int status; @@ -838,6 +855,7 @@ void __attribute__((constructor)) lttng_ust_init(void) { struct timespec constructor_timeout; sigset_t sig_all_blocked, orig_parent_mask; + pthread_attr_t thread_attr; int timeout_mode; int ret; @@ -852,6 +870,7 @@ void __attribute__((constructor)) lttng_ust_init(void) lttng_fixup_event_tls(); lttng_fixup_ringbuffer_tls(); lttng_fixup_vtid_tls(); + lttng_fixup_nest_count_tls(); /* * We want precise control over the order in which we construct @@ -886,13 +905,22 @@ void __attribute__((constructor)) lttng_ust_init(void) ERR("pthread_sigmask: %s", strerror(ret)); } - ret = pthread_create(&global_apps.ust_listener, NULL, + ret = pthread_attr_init(&thread_attr); + if (ret) { + ERR("pthread_attr_init: %s", strerror(ret)); + } + ret = pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED); + if (ret) { + ERR("pthread_attr_setdetachstate: %s", strerror(ret)); + } + + ret = pthread_create(&global_apps.ust_listener, &thread_attr, ust_listener_thread, &global_apps); if (ret) { ERR("pthread_create global: %s", strerror(ret)); } if (local_apps.allowed) { - ret = pthread_create(&local_apps.ust_listener, NULL, + ret = pthread_create(&local_apps.ust_listener, &thread_attr, ust_listener_thread, &local_apps); if (ret) { ERR("pthread_create local: %s", strerror(ret)); @@ -900,6 +928,10 @@ void __attribute__((constructor)) lttng_ust_init(void) } else { handle_register_done(&local_apps); } + ret = pthread_attr_destroy(&thread_attr); + if (ret) { + ERR("pthread_attr_destroy: %s", strerror(ret)); + } /* Restore original signal mask in parent */ ret = pthread_sigmask(SIG_SETMASK, &orig_parent_mask, NULL); @@ -1019,6 +1051,8 @@ void ust_before_fork(sigset_t *save_sigset) sigset_t all_sigs; int ret; + if (lttng_ust_nest_count) + return; /* Disable signals */ sigfillset(&all_sigs); ret = sigprocmask(SIG_BLOCK, &all_sigs, save_sigset); @@ -1044,6 +1078,8 @@ static void ust_after_fork_common(sigset_t *restore_sigset) void ust_after_fork_parent(sigset_t *restore_sigset) { + if (lttng_ust_nest_count) + return; DBG("process %d", getpid()); rcu_bp_after_fork_parent(); /* Release mutexes and reenable signals */ @@ -1061,6 +1097,8 @@ void ust_after_fork_parent(sigset_t *restore_sigset) */ void ust_after_fork_child(sigset_t *restore_sigset) { + if (lttng_ust_nest_count) + return; DBG("process %d", getpid()); /* Release urcu mutexes */ rcu_bp_after_fork_child();