Subject: bin/28753: syslogd disables remote logging on non-fatal errors
To: None <gnats-admin@netbsd.org, netbsd-bugs@netbsd.org>
From: None <mjl@emsi.priv.at>
List: netbsd-bugs
Date: 12/22/2004 15:24:00
>Number:         28753
>Category:       bin
>Synopsis:       syslogd disables remote logging on non-fatal errors
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Wed Dec 22 15:24:00 +0000 2004
>Originator:     Martin J. Laubach
>Release:        NetBSD 2.0_RC4
>Organization:
>Environment:
System: NetBSD asparagus.emsi.priv.at 2.0_RC4 NetBSD 2.0_RC4 (ASPARAGUS) #1: Sun Oct 10 23:46:50 CEST 2004 mjl@asparagus.emsi.priv.at:/home/users/mjl/netbsd/cvs/src/sys20/arch/i386/compile/ASPARAGUS i386
Architecture: i386
Machine: i386
>Description:

  This appeared on the OpenBSD bug list. From superficial code
inspection, it seems we indeed have the same problem.

  The retry stuff in the patch doesn't look too good to me, but
that's a detail.


 > >Number:         4044
 > >Category:       user
 > >Synopsis:       syslogd disables remote logging on non-fatal errors
 
 > >Description:
 > 	syslogd permanently disables logging to a remote host whenever
 > 	sendto(2) fails, even on presumably temporary error conditions
 > 	(e.g. if destination host is down and arp cache did time out).
 
 > >Fix:
 > Ignore EHOSTDOWN and EHOSTUNREACH. This is actually similar to what
 > FreeBSD does, but avoids calling logerror() in the non-fatal error
 > path (which might trigger a loop).
 
 I have a similar patch in my tree as I ran into this problem as well.
 This patch also ignores ENETDOWN and adds a short delayed loop for
 ENOBUFS.
 
 Index: syslogd.c
 ===================================================================
 RCS file: /cvs/src/usr.sbin/syslogd/syslogd.c,v
 retrieving revision 1.84
 diff -u -p -r1.84 syslogd.c
 --- syslogd.c	14 Sep 2004 23:37:06 -0000	1.84
 +++ syslogd.c	15 Sep 2004 14:06:18 -0000
 @@ -790,7 +790,7 @@ fprintlog(struct filed *f, int flags, ch
  {
  	struct iovec iov[6];
  	struct iovec *v;
 -	int l;
 +	int l, resend, retry = 0;
  	char line[MAXLINE + 1], repbuf[80], greetings[500];
  
  	v = iov;
 @@ -851,12 +851,28 @@ fprintlog(struct filed *f, int flags, ch
  		    f->f_prevpri, (char *)iov[0].iov_base,
  		    (char *)iov[4].iov_base)) >= sizeof(line) || l == -1)
  			l = strlen(line);
 -		if (sendto(pfd[PFD_INET].fd, line, l, 0,
 -		    (struct sockaddr *)&f->f_un.f_forw.f_addr,
 -		    f->f_un.f_forw.f_addr.ss_len) != l) {
 -			f->f_type = F_UNUSED;
 -			logerror("sendto");
 -		}
 +		do {
 +			resend = 0;
 +			if (sendto(pfd[PFD_INET].fd, line, l, 0,
 +			    (struct sockaddr *)&f->f_un.f_forw.f_addr,
 +			    f->f_un.f_forw.f_addr.ss_len) != l) {
 +				switch (errno) {
 +				case ENOBUFS:
 +					resend = 1;
 +					usleep(10000);
 +					break;
 +				case EHOSTDOWN:
 +				case EHOSTUNREACH:
 +				case ENETDOWN:
 +					/* silently dropped */
 +					break;
 +				default:
 +					f->f_type = F_UNUSED;
 +					logerror("sendto");
 +					break;
 +				}
 +			}
 +		} while (resend && ++retry < 100);
  		break;
  
  	case F_CONSOLE:



>How-To-Repeat:
>Fix: