[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