diff options
author | glebius <glebius@FreeBSD.org> | 2004-10-08 21:15:21 +0000 |
---|---|---|
committer | glebius <glebius@FreeBSD.org> | 2004-10-08 21:15:21 +0000 |
commit | baf8b008c9797313952f6650a2ebba43acf7b99d (patch) | |
tree | 7b46a2c5e1f7848286882520558e9d94e59502b0 | |
parent | ea65b8bd5739b4d56feb36bf95dc8d8864ee3f87 (diff) | |
download | FreeBSD-src-baf8b008c9797313952f6650a2ebba43acf7b99d.zip FreeBSD-src-baf8b008c9797313952f6650a2ebba43acf7b99d.tar.gz |
When send()ing to syslogd return ENOBUFS keep trying until success.
This fixes a case, when DoSed syslogd completely loses messages.
PR: bin/72366
Discussed with: dwmalone, millert@OpenBSD.org
Approved by: julian (mentor)
Obtained from: OpenBSD (rev. 1.17, 1.21 by millert)
MFC after: 3 months
-rw-r--r-- | lib/libc/gen/syslog.c | 26 |
1 files changed, 18 insertions, 8 deletions
diff --git a/lib/libc/gen/syslog.c b/lib/libc/gen/syslog.c index 2c16d73..5d3a90f 100644 --- a/lib/libc/gen/syslog.c +++ b/lib/libc/gen/syslog.c @@ -243,17 +243,27 @@ vsyslog(pri, fmt, ap) if (!opened) openlog(LogTag, LogStat | LOG_NDELAY, 0); connectlog(); - 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. + * If the send() failed, there are two likely scenarios: + * 1) syslogd was restarted + * 2) /var/run/log is out of socket buffer space + * We attempt to reconnect to /var/run/log to take care of + * case #1 and keep send()ing data to cover case #2 + * to give syslogd a chance to empty its socket buffer. */ - disconnectlog(); - connectlog(); - if (send(LogFile, tbuf, cnt, 0) >= 0) - return; + + if (send(LogFile, tbuf, cnt, 0) < 0) { + if (errno != ENOBUFS) { + disconnectlog(); + connectlog(); + } + do { + usleep(1); + if (send(LogFile, tbuf, cnt, 0) >= 0) + break; + } while (errno == ENOBUFS); + } /* * Output the message to the console; try not to block |