From: Lennart Poettering Date: Fri, 10 Sep 2010 15:11:11 +0000 (+0200) Subject: logger: support SOCK_STREAM /dev/log sockets as necessary for syslog-ng X-Git-Tag: v10~25 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b00bad36414ba3acd857f8c5f3dec12ba202363a;p=systemd logger: support SOCK_STREAM /dev/log sockets as necessary for syslog-ng --- diff --git a/fixme b/fixme index 422ec184..2e7cd3b1 100644 --- a/fixme +++ b/fixme @@ -86,6 +86,8 @@ * emergency.service should start default.target after C-d. +* support dbus introspection in mid-level object paths, i.e. in /org/freedesktop/systemd/units/. + External: * place /etc/inittab with explaining blurb. diff --git a/src/logger.c b/src/logger.c index 03a8ae8f..9d67ab6b 100644 --- a/src/logger.c +++ b/src/logger.c @@ -51,6 +51,8 @@ typedef struct Server { unsigned n_server_fd; + bool syslog_is_stream; + LIST_HEAD(Stream, streams); unsigned n_streams; } Server; @@ -172,14 +174,28 @@ static int stream_log(Stream *s, char *p, usec_t ts) { IOVEC_SET_STRING(iovec[3], header_pid); IOVEC_SET_STRING(iovec[4], p); + /* When using syslog via SOCK_STREAM seperate the messages by NUL chars */ + if (s->server->syslog_is_stream) + iovec[4].iov_len++; + zero(msghdr); msghdr.msg_iov = iovec; msghdr.msg_iovlen = ELEMENTSOF(iovec); msghdr.msg_control = &control; msghdr.msg_controllen = control.cmsghdr.cmsg_len; - if (sendmsg(s->server->syslog_fd, &msghdr, MSG_NOSIGNAL) < 0) - return -errno; + for (;;) { + ssize_t n; + + if ((n = sendmsg(s->server->syslog_fd, &msghdr, MSG_NOSIGNAL)) < 0) + return -errno; + + if (!s->server->syslog_is_stream || + (size_t) n >= IOVEC_TOTAL_SIZE(iovec, ELEMENTSOF(iovec))) + break; + + IOVEC_INCREMENT(iovec, ELEMENTSOF(iovec), n); + } } else if (s->target == STREAM_KMSG) { IOVEC_SET_STRING(iovec[1], s->process); @@ -479,22 +495,35 @@ static int server_init(Server *s, unsigned n_sockets) { } } - if ((s->syslog_fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0)) < 0) { - r = -errno; - log_error("Failed to create log fd: %m"); - goto fail; - } - zero(sa); sa.un.sun_family = AF_UNIX; strncpy(sa.un.sun_path, "/dev/log", sizeof(sa.un.sun_path)); - if (connect(s->syslog_fd, &sa.sa, sizeof(sa)) < 0) { + if ((s->syslog_fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0)) < 0) { r = -errno; - log_error("Failed to connect log socket to /dev/log: %m"); + log_error("Failed to create log fd: %m"); goto fail; } + if (connect(s->syslog_fd, &sa.sa, sizeof(sa)) < 0) { + close_nointr_nofail(s->syslog_fd); + + if ((s->syslog_fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0)) < 0) { + r = -errno; + log_error("Failed to create log fd: %m"); + goto fail; + } + + if (connect(s->syslog_fd, &sa.sa, sizeof(sa)) < 0) { + r = -errno; + log_error("Failed to connect log socket to /dev/log: %m"); + goto fail; + } + + s->syslog_is_stream = true; + } else + s->syslog_is_stream = false; + /* /dev/kmsg logging is strictly optional */ if ((s->kmsg_fd = open("/dev/kmsg", O_WRONLY|O_NOCTTY|O_CLOEXEC)) < 0) log_warning("Failed to open /dev/kmsg for logging, disabling kernel log buffer support: %m");