summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorglebius <glebius@FreeBSD.org>2004-10-08 21:15:21 +0000
committerglebius <glebius@FreeBSD.org>2004-10-08 21:15:21 +0000
commitbaf8b008c9797313952f6650a2ebba43acf7b99d (patch)
tree7b46a2c5e1f7848286882520558e9d94e59502b0
parentea65b8bd5739b4d56feb36bf95dc8d8864ee3f87 (diff)
downloadFreeBSD-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.c26
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
OpenPOWER on IntegriCloud