[syslog-ng] [Bug 193] syslog-ng 3.3.6 spins at 100% on FreeBSD
Lennert Buytenhek
buytenh at wantstofly.org
Tue Sep 4 05:45:28 CEST 2012
On Tue, Sep 04, 2012 at 05:43:28AM +0200, bugzilla at bugzilla.balabit.com wrote:
> --- Comment #9 from Lennert Buytenhek <buytenh at wantstofly.org> 2012-09-04 05:43:27 ---
> I have committed the fix to the ivykis master and stable-v0.30 branches.
> I'll release 0.30.3 by the end of this week or so if nothing else pops
> up before that time.
This is the fix I committed to stable-v0.30:
commit 84963e1987d38bd8c77dd74dcacdfe9344fc0fe8
Author: Lennert Buytenhek <buytenh at wantstofly.org>
Date: Mon Sep 3 19:01:27 2012 +0200
spinlock.h: Use PTHREAD_PROCESS_SHARED for pthread-backed spinlocks.
iv_signal maintains an AVL tree of registered signal interests,
which is protected from concurrent modifications as well as from
lookup versus modification races by a spinlock.
To be able to reset the disposition of each signal for which there
is an iv_signal object registered back to SIG_DFL in the child
process after fork(), we have to walk the AVL tree from the child
process, but this requires that the child sees a consistent version
of the AVL tree, and that requires that we don't add or remove signal
interests in one thread while calling fork() in another thread in
the parent process.
To guarantee the consistency of the AVL tree data structure across
fork() calls, iv_signal registers atfork handlers which lock the
spinlock in the parent process before the fork() happens, and unlock
the spinlock in both the parent process and the child process after
the fork() completes.
However, for this to work properly, the spinlock that iv_signal uses
must be initialized as a shared spinlock (PTHREAD_PROCESS_SHARED)
instead of as a process private spinlock (PTHREAD_PROCESS_PRIVATE) as
is done currently.
This trips up at least FreeBSD, as FreeBSD's libpthread apparently
has different implementations for process private spinlocks and shared
spinlocks, and trying to lock an unlocked process private spinlock in
a fork()ed child process causes the child to go into an infinite loop.
Fix this by having spinlock.h initialize pthread spinlocks as shared
spinlocks.
This was showing up as an issue on FreeBSD builds of syslog-ng.
Reported-by: Cy Schubert <cy at FreeBSD.org>
Tested-by: Gergely Nagy <algernon at balabit.hu>
Signed-off-by: Lennert Buytenhek <buytenh at wantstofly.org>
diff --git a/modules/spinlock.h b/modules/spinlock.h
index 1978317..6451f85 100644
--- a/modules/spinlock.h
+++ b/modules/spinlock.h
@@ -25,7 +25,7 @@
static inline void spin_init(spinlock_t *lock)
{
- pthread_spin_init(lock, PTHREAD_PROCESS_PRIVATE);
+ pthread_spin_init(lock, PTHREAD_PROCESS_SHARED);
}
static inline void spin_lock(spinlock_t *lock)
More information about the syslog-ng
mailing list