Package: unbound Version: 1.4.17-3 Severity: important Dear Maintainer, *** Please consider answering these questions, where appropriate ***
* What led up to the situation? I have a need for verbose logging on a server with intensive traffic (2000q/s), and of course need log rotation (on a hourly basis). We actually have 1G of logs building up every 2 hours. * What exactly did you do (or not do) that was effective (or ineffective)? I am using a custom logfile (logfile: "/var/log/unbound/query.log"), with verbose logging (verbosity: 2), and no syslog (use-syslog: no), and I set up logrotate to run "unbound-control log_reopen" as postrotate script. * What was the outcome of this action? Randomly, upon rotating, or just after, a segfault occurs, or the process just dies. I filed a bug report with the upstream developper, who fixed it in the latest SVN trunk. https://www.nlnetlabs.nl/bugs-script/show_bug.cgi?id=593 The fixed file is as follows : http://unbound.nlnetlabs.nl/svn/trunk/util/log.c Given this is valid for the latest SVN trunk, but not relevant for version 1.4.17, I backported the relevant bits into my own patch. *** End of the template - remove these lines *** -- System Information: Debian Release: 7.5 APT prefers stable APT policy: (500, 'stable') Architecture: i386 (i686) Kernel: Linux 3.2.0-4-686-pae (SMP w/1 CPU core) Locale: LANG=C, LC_CTYPE=C (charmap=ANSI_X3.4-1968) Shell: /bin/sh linked to /bin/bash Versions of packages unbound depends on: ii adduser 3.113+nmu3 ii libc6 2.13-38+deb7u1 ii libevent-2.0-5 2.0.19-stable-3 ii libgcc1 1:4.7.2-5 ii libldns1 1.6.13-1 ii libpython2.7 2.7.3-6+deb7u2 ii libssl1.0.0 1.0.1e-2+deb7u11 ii openssl 1.0.1e-2+deb7u11 ii unbound-anchor 1.4.17-3 unbound recommends no packages. unbound suggests no packages. -- Configuration Files: /etc/unbound/unbound.conf changed [not included] -- no debconf information
--- util/log.c.orig 2014-07-04 18:16:38.206490000 +0900 +++ util/log.c 2014-07-04 18:18:22.403506000 +0900 @@ -66,6 +66,10 @@ static int key_created = 0; /** pthread key for thread ids in logfile */ static ub_thread_key_t logkey; +#ifndef THREADS_DISABLED +/** pthread mutex to protect FILE* */ +static lock_quick_t log_lock; +#endif /** the identity of this executable/process */ static const char* ident="unbound"; #if defined(HAVE_SYSLOG_H) || defined(UB_ON_WINDOWS) @@ -84,14 +88,19 @@ if(!key_created) { key_created = 1; ub_thread_key_create(&logkey, NULL); + lock_quick_init(&log_lock); } + lock_quick_lock(&log_lock); if(logfile #if defined(HAVE_SYSLOG_H) || defined(UB_ON_WINDOWS) || logging_to_syslog #endif - ) - verbose(VERB_QUERY, "switching log to %s", - use_syslog?"syslog":(filename&&filename[0]?filename:"stderr")); + ) { + lock_quick_unlock(&log_lock); /* verbose() needs the lock */ + verbose(VERB_QUERY, "switching log to %s", + use_syslog?"syslog":(filename&&filename[0]?filename:"stderr")); + lock_quick_lock(&log_lock); + } if(logfile && logfile != stderr) fclose(logfile); #ifdef HAVE_SYSLOG_H @@ -104,6 +113,7 @@ * chroot and no longer be able to access dev/log and so on */ openlog(ident, LOG_NDELAY, LOG_DAEMON); logging_to_syslog = 1; + lock_quick_unlock(&log_lock); return; } #elif defined(UB_ON_WINDOWS) @@ -112,11 +122,13 @@ } if(use_syslog) { logging_to_syslog = 1; + lock_quick_unlock(&log_lock); return; } #endif /* HAVE_SYSLOG_H */ if(!filename || !filename[0]) { logfile = stderr; + lock_quick_unlock(&log_lock); return; } /* open the file for logging */ @@ -125,6 +137,7 @@ filename += strlen(chrootdir); f = fopen(filename, "a"); if(!f) { + lock_quick_unlock(&log_lock); log_err("Could not open logfile %s: %s", filename, strerror(errno)); return; @@ -134,11 +147,14 @@ setvbuf(f, NULL, (int)_IOLBF, 0); #endif logfile = f; + lock_quick_unlock(&log_lock); } void log_file(FILE *f) { + lock_quick_lock(&log_lock); logfile = f; + lock_quick_unlock(&log_lock); } void log_thread_set(int* num) @@ -207,7 +223,11 @@ return; } #endif /* HAVE_SYSLOG_H */ - if(!logfile) return; + lock_quick_lock(&log_lock); + if(!logfile) { + lock_quick_unlock(&log_lock); + return; + } if(log_now) now = (time_t)*log_now; else now = (time_t)time(NULL); @@ -225,6 +245,7 @@ /* line buffering does not work on windows */ fflush(logfile); #endif + lock_quick_unlock(&log_lock); } /**