Fix: Lock FD tracker across fork
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Fri, 4 Oct 2019 14:07:03 +0000 (10:07 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Mon, 7 Oct 2019 16:00:47 +0000 (12:00 -0400)
If fork() is performed while other threads are holding the fd tracker
lock, it will stay in locked state in the child process and eventually
cause a deadlock.

One way to solve this is to hold the fd tracker lock across fork(), in
the same way we do for the ust_lock. This ensures no other threads are
holding that lock in the parent, and therefore provides a consistent
lock state in the child.

Fixes: #1199
Fixes: #1200
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
liblttng-ust-comm/lttng-ust-fd-tracker.c
liblttng-ust/lttng-ust-comm.c

index 1bc186bf08453f870001446ebf17dbb0e2ab2054..282895911c65569c6a5050bb859b9e73383c1a5a 100644 (file)
@@ -61,6 +61,9 @@
  * Protect the lttng_fd_set. Nests within the ust_lock, and therefore
  * within the libc dl lock. Therefore, we need to fixup the TLS before
  * nesting into this lock.
+ *
+ * The ust_safe_guard_fd_mutex nests within the ust_mutex. This mutex
+ * is also held across fork.
  */
 static pthread_mutex_t ust_safe_guard_fd_mutex = PTHREAD_MUTEX_INITIALIZER;
 /*
index e392e460cca2dada53036fc622adbc8b3cf87355..47ba36e5c9f1d9f1871c267469049708a7dd1e1e 100644 (file)
@@ -86,6 +86,8 @@ static int initialized;
  *
  * ust_lock nests within the dynamic loader lock (within glibc) because
  * it is taken within the library constructor.
+ *
+ * The ust fd tracker lock nests within the ust_mutex.
  */
 static pthread_mutex_t ust_mutex = PTHREAD_MUTEX_INITIALIZER;
 
@@ -2065,6 +2067,7 @@ void ust_before_fork(sigset_t *save_sigset)
 
        ust_lock_nocheck();
        urcu_bp_before_fork();
+       lttng_ust_lock_fd_tracker();
 }
 
 static void ust_after_fork_common(sigset_t *restore_sigset)
@@ -2072,6 +2075,7 @@ static void ust_after_fork_common(sigset_t *restore_sigset)
        int ret;
 
        DBG("process %d", getpid());
+       lttng_ust_unlock_fd_tracker();
        ust_unlock();
 
        pthread_mutex_unlock(&ust_fork_mutex);
This page took 0.026098 seconds and 4 git commands to generate.