journald-stream.c revision d682b3a7e7c7c2941a4d3e193f1e330dbc9fae89
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering This file is part of systemd.
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering Copyright 2011 Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering systemd is free software; you can redistribute it and/or modify it
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering under the terms of the GNU Lesser General Public License as published by
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering (at your option) any later version.
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering systemd is distributed in the hope that it will be useful, but
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering Lesser General Public License for more details.
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering You should have received a copy of the GNU Lesser General Public License
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering LIST_FIELDS(StdoutStream, stdout_stream);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poetteringstatic int stdout_stream_log(StdoutStream *s, const char *p) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering struct iovec iovec[N_IOVEC_META_FIELDS + 5];
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering char *message = NULL, *syslog_priority = NULL, *syslog_facility = NULL, *syslog_identifier = NULL;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering unsigned n = 0;
ac50788b0f5aeee09e7d45db28ae8ab7f39cd52eZbigniew Jędrzejewski-Szmek syslog_parse_priority((char**) &p, &priority, false);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (s->forward_to_syslog || s->server->forward_to_syslog)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering server_forward_syslog(s->server, syslog_fixup_facility(priority), s->identifier, p, &s->ucred, NULL);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (s->forward_to_kmsg || s->server->forward_to_kmsg)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering server_forward_kmsg(s->server, priority, s->identifier, p, &s->ucred);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (s->forward_to_console || s->server->forward_to_console)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering server_forward_console(s->server, priority, s->identifier, p, &s->ucred);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering IOVEC_SET_STRING(iovec[n++], "_TRANSPORT=stdout");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (asprintf(&syslog_priority, "PRIORITY=%i", priority & LOG_PRIMASK) >= 0)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering IOVEC_SET_STRING(iovec[n++], syslog_priority);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (asprintf(&syslog_facility, "SYSLOG_FACILITY=%i", LOG_FAC(priority)) >= 0)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering IOVEC_SET_STRING(iovec[n++], syslog_facility);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering syslog_identifier = strappend("SYSLOG_IDENTIFIER=", s->identifier);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering IOVEC_SET_STRING(iovec[n++], syslog_identifier);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering label_len = strlen((char*) s->security_context);
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek server_dispatch_message(s->server, iovec, n, ELEMENTSOF(iovec), &s->ucred, NULL, label, label_len, s->unit_id, priority, 0);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poetteringstatic int stdout_stream_line(StdoutStream *s, char *p) {
41891700e02daf0cab9e86908c76ac6f411bbd57Lennart Poettering if (r < 0 || s->priority < 0 || s->priority > 999) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering log_warning("Failed to parse log priority line.");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering log_warning("Failed to parse level prefix line.");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering s->state = STDOUT_STREAM_FORWARD_TO_SYSLOG;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering log_warning("Failed to parse forward to syslog line.");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering s->state = STDOUT_STREAM_FORWARD_TO_KMSG;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering log_warning("Failed to parse copy to kmsg line.");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering s->state = STDOUT_STREAM_FORWARD_TO_CONSOLE;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering log_warning("Failed to parse copy to console line.");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering assert_not_reached("Unknown stream state");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poetteringstatic int stdout_stream_scan(StdoutStream *s, bool force_flush) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering else if (remaining >= sizeof(s->buffer) - 1) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poetteringint stdout_stream_process(StdoutStream *s) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering l = read(s->fd, s->buffer+s->length, sizeof(s->buffer)-1-s->length);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering log_warning("Failed to read from stream: %m");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poetteringvoid stdout_stream_free(StdoutStream *s) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering LIST_REMOVE(StdoutStream, stdout_stream, s->server->stdout_streams, s);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (s->fd >= 0) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering epoll_ctl(s->server->epoll_fd, EPOLL_CTL_DEL, s->fd, NULL);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering fd = accept4(s->stdout_fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering log_error("Failed to accept stdout connection: %m");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (s->n_stdout_streams >= STDOUT_STREAMS_MAX) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering log_warning("Too many stdout streams, refusing connection.");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &stream->ucred, &len) < 0) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering log_error("Failed to determine peer credentials: %m");
d682b3a7e7c7c2941a4d3e193f1e330dbc9fae89Lennart Poettering if (getpeercon(fd, &stream->security_context) < 0 && errno != ENOPROTOOPT)
d682b3a7e7c7c2941a4d3e193f1e330dbc9fae89Lennart Poettering log_error("Failed to determine peer security context: %m");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering log_error("Failed to shutdown writing side of socket: %m");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering log_error("Failed to add stream to event loop: %m");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering LIST_PREPEND(StdoutStream, stdout_stream, s->stdout_streams, stream);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poetteringint server_open_stdout_socket(Server *s) {
b92bea5d2a9481de69bb627a7b442a9f58fca43dZbigniew Jędrzejewski-Szmek .un.sun_path = "/run/systemd/journal/stdout",
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering s->stdout_fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering r = bind(s->stdout_fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path));
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (listen(s->stdout_fd, SOMAXCONN) < 0) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, s->stdout_fd, &ev) < 0) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering log_error("Failed to add stdout server fd to epoll object: %m");