提交 0f9c2666 编写于 作者: R Rich Felker

handle loss of syslog socket connection

when traditional syslogd implementations are restarted, the old server
socket ceases to exist and a new unix socket with the same pathname is
created. when this happens, the default destination address associated
with the client socket via connect is no longer valid, and attempts to
send produce errors. this happens despite the socket being datagram
type, and is in contrast to the behavior that would be seen with an IP
datagram (UDP) socket.

in order to avoid a situation where the application is unable to send
further syslog messages without calling closelog, this patch makes
syslog attempt to reconnect the socket when send returns an error
indicating a lost connection.

additionally, initial failure to connect the socket no longer results
in the socket being closed. this ensures that an application which
calls openlog to reserve the socket file descriptor will not run into
a situation where transient connection failure (e.g. due to syslogd
restart) prevents fd reservation. however, applications which may be
unable to connect the socket later (e.g. due to chroot, restricted
permissions, seccomp, etc.) will still fail to log if the syslog
socket cannot be connected at openlog time or if it has to be
reconnected later.
上级 11894f6d
......@@ -48,12 +48,8 @@ void closelog(void)
static void __openlog()
{
int fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
if (fd < 0) return;
if (connect(fd, (void *)&log_addr, sizeof log_addr) < 0)
close(fd);
else
log_fd = fd;
log_fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
if (log_fd >= 0) connect(log_fd, (void *)&log_addr, sizeof log_addr);
}
void openlog(const char *ident, int opt, int facility)
......@@ -78,6 +74,11 @@ void openlog(const char *ident, int opt, int facility)
pthread_setcancelstate(cs, 0);
}
static int is_lost_conn(int e)
{
return e==ECONNREFUSED || e==ECONNRESET || e==ENOTCONN || e==EPIPE;
}
static void _vsyslog(int priority, const char *message, va_list ap)
{
char timebuf[16];
......@@ -107,7 +108,10 @@ static void _vsyslog(int priority, const char *message, va_list ap)
if (l2 >= sizeof buf - l) l = sizeof buf - 1;
else l += l2;
if (buf[l-1] != '\n') buf[l++] = '\n';
if (send(log_fd, buf, l, 0) < 0 && (log_opt & LOG_CONS)) {
if (send(log_fd, buf, l, 0) < 0 && (!is_lost_conn(errno)
|| connect(log_fd, (void *)&log_addr, sizeof log_addr) < 0
|| send(log_fd, buf, l, 0) < 0)
&& (log_opt & LOG_CONS)) {
fd = open("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
if (fd >= 0) {
dprintf(fd, "%.*s", l-hlen, buf+hlen);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册