From owner-freebsd-bugs@FreeBSD.ORG Tue Oct 5 22:00:51 2004 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 0A17016A4D1 for ; Tue, 5 Oct 2004 22:00:51 +0000 (GMT) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id 4F5EB43D5A for ; Tue, 5 Oct 2004 22:00:50 +0000 (GMT) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.12.11/8.12.11) with ESMTP id i95M0nQH027281 for ; Tue, 5 Oct 2004 22:00:49 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.12.11/8.12.11/Submit) id i95M0mal027280; Tue, 5 Oct 2004 22:00:48 GMT (envelope-from gnats) Resent-Date: Tue, 5 Oct 2004 22:00:48 GMT Resent-Message-Id: <200410052200.i95M0mal027280@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Chris Gabe Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id D6BFB16A4CF for ; Tue, 5 Oct 2004 21:50:27 +0000 (GMT) Received: from mail.borderware.com (mail.borderware.com [207.236.65.231]) by mx1.FreeBSD.org (Postfix) with ESMTP id 5BC1A43D49 for ; Tue, 5 Oct 2004 21:50:23 +0000 (GMT) (envelope-from chris@borderware.com) Message-Id: <20041005215018.931B3ABB5@santana.borderware.com> Date: Tue, 5 Oct 2004 17:50:18 -0400 (EDT) From: Chris Gabe To: FreeBSD-gnats-submit@FreeBSD.org X-Send-Pr-Version: 3.113 Subject: bin/72366: syslog overflow fix X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list Reply-To: Chris Gabe List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 05 Oct 2004 22:00:51 -0000 >Number: 72366 >Category: bin >Synopsis: syslog overflow fix >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Tue Oct 05 22:00:48 GMT 2004 >Closed-Date: >Last-Modified: >Originator: Chris Gabe >Release: FreeBSD 5.3 (or later) >Organization: Borderware Technologies Inc >Environment: System: FreeBSD 5.3 >Description: When data is sent rapidly, locally, using syslog, some lines get quietly lost. >How-To-Repeat: Create a program that just syslogs argv[2] in a loop of (atoi(argv[1])) count to /var/log/messages Run a few copies with arguments 10000000 aaaaaaaaaaaaaaaaaa so syslog is extremely busy. Then invoke with arguments 1000 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb Count how many lines get to the file, using grep bbbb messages | wc. They won't all get there every time. >Fix: OpenBSD 3.2 had a fix in two parts. The main one is below, in libc, lib/libc/gen/syslog.c. Beware that it's the second send() attempt that is changed, not the one just like it a few lines above: if (send(LogFile, tbuf, cnt, 0) >= 0) return; /* * If the send() failed, the odds are syslogd was restarted. * Make one (only) attempt to reconnect to /dev/log. */ disconnectlog(); connectlog(); < if (send(LogFile, tbuf, cnt, 0) >= 0) < return; --- > do { > usleep(1); > if (send(LogFile, tbuf, cnt, 0) >= 0) > return; > } while (errno == ENOBUFS); Unless syslogd is really being misused, this results in no discernable performance difference, in our experience. The second part is not mandatory but often avoids sleeping in the above code. It is in syslogd, usr.sbin/syslogd/syslogd.c main(), < socklen_t len; --- > socklen_t len, slen; 479a480,487 (beware these numbers are quite different in 5.3) for (i = 0; i < nfunix; i++) { (void)unlink(funixn[i]); memset(&sunx, 0, sizeof(sunx)); sunx.sun_family = AF_UNIX; (void)strlcpy(sunx.sun_path, funixn[i], sizeof(sunx.sun_path)); funix[i] = socket(AF_UNIX, SOCK_DGRAM, 0); if (funix[i] < 0 || bind(funix[i], (struct sockaddr *)&sunx, SUN_LEN(&sunx)) < 0 || chmod(funixn[i], 0666) < 0) { (void)snprintf(line, sizeof line, "cannot create %s", funixn[i]); logerror(line); dprintf("cannot create %s (%d)\n", funixn[i], errno); if (i == 0) die(0); } > if (getsockopt(funix[i], SOL_SOCKET, SO_RCVBUF, &len, > &slen) == 0) { > len *= 2; > (void)setsockopt(funix[i], SOL_SOCKET, SO_RCVBUF, &len, > slen); > } >Release-Note: >Audit-Trail: >Unformatted: