X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Flogger.c;h=d4d964d1bbfd440c268d57b4578a0920071e2e0a;hp=e7c2be01e0f247e16e0ac8e0805fe2afa7f8dfcf;hb=54165a39391980defef3bf3356041aac960f64af;hpb=9c5c00f9fe36d630e20fb6f424fc4fce09df3c14 diff --git a/src/logger.c b/src/logger.c index e7c2be01e..d4d964d1b 100644 --- a/src/logger.c +++ b/src/logger.c @@ -36,6 +36,7 @@ #include "log.h" #include "list.h" #include "sd-daemon.h" +#include "tcpwrap.h" #define STREAM_BUFFER 2048 #define STREAMS_MAX 256 @@ -89,7 +90,7 @@ struct Stream { LIST_FIELDS(Stream, stream); }; -static int stream_log(Stream *s, char *p, usec_t timestamp) { +static int stream_log(Stream *s, char *p, usec_t ts) { char header_priority[16], header_time[64], header_pid[16]; struct iovec iovec[5]; @@ -134,7 +135,7 @@ static int stream_log(Stream *s, char *p, usec_t timestamp) { time_t t; struct tm *tm; - t = (time_t) (timestamp / USEC_PER_SEC); + t = (time_t) (ts / USEC_PER_SEC); if (!(tm = localtime(&t))) return -EINVAL; @@ -142,7 +143,7 @@ static int stream_log(Stream *s, char *p, usec_t timestamp) { return -EINVAL; } - snprintf(header_pid, sizeof(header_pid), "[%llu]: ", (unsigned long long) s->pid); + snprintf(header_pid, sizeof(header_pid), "[%lu]: ", (unsigned long) s->pid); char_array_0(header_pid); zero(iovec); @@ -177,7 +178,7 @@ static int stream_log(Stream *s, char *p, usec_t timestamp) { return 0; } -static int stream_line(Stream *s, char *p, usec_t timestamp) { +static int stream_line(Stream *s, char *p, usec_t ts) { int r; assert(s); @@ -236,13 +237,13 @@ static int stream_line(Stream *s, char *p, usec_t timestamp) { return 0; case STREAM_RUNNING: - return stream_log(s, p, timestamp); + return stream_log(s, p, ts); } assert_not_reached("Unknown stream state"); } -static int stream_scan(Stream *s, usec_t timestamp) { +static int stream_scan(Stream *s, usec_t ts) { char *p; size_t remaining; int r = 0; @@ -259,7 +260,7 @@ static int stream_scan(Stream *s, usec_t timestamp) { *newline = 0; - if ((r = stream_line(s, p, timestamp)) >= 0) { + if ((r = stream_line(s, p, ts)) >= 0) { remaining -= newline-p+1; p = newline+1; } @@ -273,7 +274,7 @@ static int stream_scan(Stream *s, usec_t timestamp) { return r; } -static int stream_process(Stream *s, usec_t timestamp) { +static int stream_process(Stream *s, usec_t ts) { ssize_t l; int r; assert(s); @@ -292,7 +293,7 @@ static int stream_process(Stream *s, usec_t timestamp) { return 0; s->length += l; - r = stream_scan(s, timestamp); + r = stream_scan(s, ts); if (r < 0) return r; @@ -340,6 +341,11 @@ static int stream_new(Server *s, int server_fd) { return 0; } + if (!socket_tcpwrap(fd, "systemd-logger")) { + close_nointr_nofail(fd); + return 0; + } + if (!(stream = new0(Stream, 1))) { close_nointr_nofail(fd); return -ENOMEM; @@ -424,11 +430,25 @@ static int server_init(Server *s, unsigned n_sockets) { for (i = 0; i < n_sockets; i++) { struct epoll_event ev; + int fd; + + fd = SD_LISTEN_FDS_START+i; + + if ((r = sd_is_socket(fd, AF_UNSPEC, SOCK_STREAM, 1)) < 0) { + log_error("Failed to determine file descriptor type: %s", strerror(-r)); + goto fail; + } + + if (!r) { + log_error("Wrong file descriptor type."); + r = -EINVAL; + goto fail; + } zero(ev); ev.events = EPOLLIN; - ev.data.ptr = UINT_TO_PTR(SD_LISTEN_FDS_START+i); - if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, SD_LISTEN_FDS_START+i, &ev) < 0) { + ev.data.ptr = UINT_TO_PTR(fd); + if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0) { r = -errno; log_error("Failed to add server fd to epoll object: %s", strerror(errno)); goto fail; @@ -453,7 +473,7 @@ static int server_init(Server *s, unsigned n_sockets) { /* /dev/kmsg logging is strictly optional */ if ((s->kmsg_fd = open("/dev/kmsg", O_WRONLY|O_NOCTTY|O_CLOEXEC)) < 0) - log_debug("Failed to open /dev/kmsg for logging, disabling kernel log buffer support: %s", strerror(errno)); + log_warning("Failed to open /dev/kmsg for logging, disabling kernel log buffer support: %s", strerror(errno)); return 0; @@ -487,10 +507,10 @@ static int process_event(Server *s, struct epoll_event *ev) { } } else { - usec_t timestamp; + usec_t ts; Stream *stream = ev->data.ptr; - timestamp = now(CLOCK_REALTIME); + ts = now(CLOCK_REALTIME); if (!(ev->events & EPOLLIN)) { log_info("Got invalid event from epoll. (2)"); @@ -498,7 +518,7 @@ static int process_event(Server *s, struct epoll_event *ev) { return 0; } - if ((r = stream_process(stream, timestamp)) <= 0) { + if ((r = stream_process(stream, ts)) <= 0) { if (r < 0) log_info("Got error on stream: %s", strerror(-r)); @@ -515,10 +535,20 @@ int main(int argc, char *argv[]) { Server server; int r = 3, n; + if (getppid() != 1) { + log_error("This program should be invoked by init only."); + return 1; + } + + if (argc > 1) { + log_error("This program does not take arguments."); + return 1; + } + log_set_target(LOG_TARGET_SYSLOG_OR_KMSG); log_parse_environment(); - log_info("systemd-logger running as pid %llu", (unsigned long long) getpid()); + log_info("systemd-logger running as pid %lu", (unsigned long) getpid()); if ((n = sd_listen_fds(true)) < 0) { log_error("Failed to read listening file descriptors from environment: %s", strerror(-r)); @@ -533,6 +563,10 @@ int main(int argc, char *argv[]) { if (server_init(&server, (unsigned) n) < 0) return 3; + sd_notify(false, + "READY=1\n" + "STATUS=Processing requests..."); + for (;;) { struct epoll_event event; int k; @@ -557,9 +591,12 @@ int main(int argc, char *argv[]) { r = 0; fail: + sd_notify(false, + "STATUS=Shutting down..."); + server_done(&server); - log_info("systemd-logger stopped as pid %llu", (unsigned long long) getpid()); + log_info("systemd-logger stopped as pid %lu", (unsigned long) getpid()); return r; }