util: Handle serverLogMutex lock across forks 39/14239/8
authorKailas Zadbuke <kailashsz@in.ibm.com>
Wed, 3 Jun 2020 10:14:08 +0000 (15:14 +0530)
committerBenjamin Kaduk <kaduk@mit.edu>
Tue, 30 Jun 2020 04:49:21 +0000 (00:49 -0400)
If a process forks when another thread has serverLogMutex locked, the
child process inherits the locked serverLogMutex. This causes a deadlock
when code in the child process tries to lock serverLogMutex, since we
can never unlock serverLogMutex because the locking thread no longer
exists. This can happen in the salvageserver, since the salvageserver
locks serverLogMutex in different threads, and forks to handle salvage
jobs.

To avoid this deadlock, we register handlers using pthread_atfork()
so that the serverLogMutex will be held during the fork. The fork will
be blocked until the worker thread releases the serverLogMutex. Hence the
serverLogMutex will be held until the fork is complete and it will be
released in the parent and child threads.

Thanks to Yadavendra Yadav(yadayada@in.ibm.com) for working with me
on this issue.

Change-Id: I191c8272825c1667bb2150146e04b1dfe36a54e4
Reviewed-on: https://gerrit.openafs.org/14239
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>
Tested-by: BuildBot <buildbot@rampaginggeek.com>

src/util/serverLog.c

index 2ae8a6f..60e8517 100644 (file)
@@ -508,9 +508,24 @@ SetupLogSignals(void)
 
 #if defined(AFS_PTHREAD_ENV)
 static void
+LockServerLog(void)
+{
+    LOCK_SERVERLOG();
+}
+
+static void
+UnlockServerLog(void)
+{
+    UNLOCK_SERVERLOG();
+}
+
+static void
 InitServerLogMutex(void)
 {
     opr_Verify(pthread_mutex_init(&serverLogMutex, NULL) == 0);
+# ifndef AFS_NT40_ENV
+    opr_Verify(pthread_atfork(LockServerLog, UnlockServerLog, UnlockServerLog) == 0);
+# endif
 }
 #endif /* AFS_PTHREAD_ENV */