1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2011 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
26 #include <selinux/selinux.h>
29 #include "sd-daemon.h"
32 #include "alloc-util.h"
33 #include "dirent-util.h"
38 #include "journald-console.h"
39 #include "journald-kmsg.h"
40 #include "journald-server.h"
41 #include "journald-stream.h"
42 #include "journald-syslog.h"
43 #include "journald-wall.h"
45 #include "parse-util.h"
46 #include "selinux-util.h"
47 #include "socket-util.h"
48 #include "stdio-util.h"
49 #include "string-util.h"
50 #include "syslog-util.h"
52 #define STDOUT_STREAMS_MAX 4096
54 typedef enum StdoutStreamState
{
55 STDOUT_STREAM_IDENTIFIER
,
56 STDOUT_STREAM_UNIT_ID
,
57 STDOUT_STREAM_PRIORITY
,
58 STDOUT_STREAM_LEVEL_PREFIX
,
59 STDOUT_STREAM_FORWARD_TO_SYSLOG
,
60 STDOUT_STREAM_FORWARD_TO_KMSG
,
61 STDOUT_STREAM_FORWARD_TO_CONSOLE
,
67 StdoutStreamState state
;
77 bool forward_to_syslog
:1;
78 bool forward_to_kmsg
:1;
79 bool forward_to_console
:1;
82 bool in_notify_queue
:1;
84 char buffer
[LINE_MAX
+1];
87 sd_event_source
*event_source
;
91 LIST_FIELDS(StdoutStream
, stdout_stream
);
92 LIST_FIELDS(StdoutStream
, stdout_stream_notify_queue
);
95 void stdout_stream_free(StdoutStream
*s
) {
100 assert(s
->server
->n_stdout_streams
> 0);
101 s
->server
->n_stdout_streams
--;
102 LIST_REMOVE(stdout_stream
, s
->server
->stdout_streams
, s
);
104 if (s
->in_notify_queue
)
105 LIST_REMOVE(stdout_stream_notify_queue
, s
->server
->stdout_streams_notify_queue
, s
);
108 if (s
->event_source
) {
109 sd_event_source_set_enabled(s
->event_source
, SD_EVENT_OFF
);
110 s
->event_source
= sd_event_source_unref(s
->event_source
);
122 DEFINE_TRIVIAL_CLEANUP_FUNC(StdoutStream
*, stdout_stream_free
);
124 static void stdout_stream_destroy(StdoutStream
*s
) {
129 (void) unlink(s
->state_file
);
131 stdout_stream_free(s
);
134 static int stdout_stream_save(StdoutStream
*s
) {
135 _cleanup_free_
char *temp_path
= NULL
;
136 _cleanup_fclose_
FILE *f
= NULL
;
141 if (s
->state
!= STDOUT_STREAM_RUNNING
)
144 if (!s
->state_file
) {
147 r
= fstat(s
->fd
, &st
);
149 return log_warning_errno(errno
, "Failed to stat connected stream: %m");
151 /* We use device and inode numbers as identifier for the stream */
152 if (asprintf(&s
->state_file
, "/run/systemd/journal/streams/%lu:%lu", (unsigned long) st
.st_dev
, (unsigned long) st
.st_ino
) < 0)
156 mkdir_p("/run/systemd/journal/streams", 0755);
158 r
= fopen_temporary(s
->state_file
, &f
, &temp_path
);
163 "# This is private data. Do not parse\n"
166 "FORWARD_TO_SYSLOG=%i\n"
167 "FORWARD_TO_KMSG=%i\n"
168 "FORWARD_TO_CONSOLE=%i\n",
171 s
->forward_to_syslog
,
173 s
->forward_to_console
);
175 if (!isempty(s
->identifier
)) {
176 _cleanup_free_
char *escaped
;
178 escaped
= cescape(s
->identifier
);
184 fprintf(f
, "IDENTIFIER=%s\n", escaped
);
187 if (!isempty(s
->unit_id
)) {
188 _cleanup_free_
char *escaped
;
190 escaped
= cescape(s
->unit_id
);
196 fprintf(f
, "UNIT=%s\n", escaped
);
199 r
= fflush_and_check(f
);
203 if (rename(temp_path
, s
->state_file
) < 0) {
208 if (!s
->fdstore
&& !s
->in_notify_queue
) {
209 LIST_PREPEND(stdout_stream_notify_queue
, s
->server
->stdout_streams_notify_queue
, s
);
210 s
->in_notify_queue
= true;
212 if (s
->server
->notify_event_source
) {
213 r
= sd_event_source_set_enabled(s
->server
->notify_event_source
, SD_EVENT_ON
);
215 log_warning_errno(r
, "Failed to enable notify event source: %m");
222 (void) unlink(s
->state_file
);
225 (void) unlink(temp_path
);
227 return log_error_errno(r
, "Failed to save stream data %s: %m", s
->state_file
);
230 static int stdout_stream_log(StdoutStream
*s
, const char *p
) {
231 struct iovec iovec
[N_IOVEC_META_FIELDS
+ 5];
233 char syslog_priority
[] = "PRIORITY=\0";
234 char syslog_facility
[sizeof("SYSLOG_FACILITY=")-1 + DECIMAL_STR_MAX(int) + 1];
235 _cleanup_free_
char *message
= NULL
, *syslog_identifier
= NULL
;
245 priority
= s
->priority
;
248 syslog_parse_priority(&p
, &priority
, false);
250 if (s
->forward_to_syslog
|| s
->server
->forward_to_syslog
)
251 server_forward_syslog(s
->server
, syslog_fixup_facility(priority
), s
->identifier
, p
, &s
->ucred
, NULL
);
253 if (s
->forward_to_kmsg
|| s
->server
->forward_to_kmsg
)
254 server_forward_kmsg(s
->server
, priority
, s
->identifier
, p
, &s
->ucred
);
256 if (s
->forward_to_console
|| s
->server
->forward_to_console
)
257 server_forward_console(s
->server
, priority
, s
->identifier
, p
, &s
->ucred
);
259 if (s
->server
->forward_to_wall
)
260 server_forward_wall(s
->server
, priority
, s
->identifier
, p
, &s
->ucred
);
262 IOVEC_SET_STRING(iovec
[n
++], "_TRANSPORT=stdout");
264 syslog_priority
[strlen("PRIORITY=")] = '0' + LOG_PRI(priority
);
265 IOVEC_SET_STRING(iovec
[n
++], syslog_priority
);
267 if (priority
& LOG_FACMASK
) {
268 xsprintf(syslog_facility
, "SYSLOG_FACILITY=%i", LOG_FAC(priority
));
269 IOVEC_SET_STRING(iovec
[n
++], syslog_facility
);
273 syslog_identifier
= strappend("SYSLOG_IDENTIFIER=", s
->identifier
);
274 if (syslog_identifier
)
275 IOVEC_SET_STRING(iovec
[n
++], syslog_identifier
);
278 message
= strappend("MESSAGE=", p
);
280 IOVEC_SET_STRING(iovec
[n
++], message
);
282 label_len
= s
->label
? strlen(s
->label
) : 0;
283 server_dispatch_message(s
->server
, iovec
, n
, ELEMENTSOF(iovec
), &s
->ucred
, NULL
, s
->label
, label_len
, s
->unit_id
, priority
, 0);
287 static int stdout_stream_line(StdoutStream
*s
, char *p
) {
297 case STDOUT_STREAM_IDENTIFIER
:
299 s
->identifier
= NULL
;
301 s
->identifier
= strdup(p
);
306 s
->state
= STDOUT_STREAM_UNIT_ID
;
309 case STDOUT_STREAM_UNIT_ID
:
310 if (s
->ucred
.uid
== 0) {
314 s
->unit_id
= strdup(p
);
320 s
->state
= STDOUT_STREAM_PRIORITY
;
323 case STDOUT_STREAM_PRIORITY
:
324 r
= safe_atoi(p
, &s
->priority
);
325 if (r
< 0 || s
->priority
< 0 || s
->priority
> 999) {
326 log_warning("Failed to parse log priority line.");
330 s
->state
= STDOUT_STREAM_LEVEL_PREFIX
;
333 case STDOUT_STREAM_LEVEL_PREFIX
:
334 r
= parse_boolean(p
);
336 log_warning("Failed to parse level prefix line.");
340 s
->level_prefix
= !!r
;
341 s
->state
= STDOUT_STREAM_FORWARD_TO_SYSLOG
;
344 case STDOUT_STREAM_FORWARD_TO_SYSLOG
:
345 r
= parse_boolean(p
);
347 log_warning("Failed to parse forward to syslog line.");
351 s
->forward_to_syslog
= !!r
;
352 s
->state
= STDOUT_STREAM_FORWARD_TO_KMSG
;
355 case STDOUT_STREAM_FORWARD_TO_KMSG
:
356 r
= parse_boolean(p
);
358 log_warning("Failed to parse copy to kmsg line.");
362 s
->forward_to_kmsg
= !!r
;
363 s
->state
= STDOUT_STREAM_FORWARD_TO_CONSOLE
;
366 case STDOUT_STREAM_FORWARD_TO_CONSOLE
:
367 r
= parse_boolean(p
);
369 log_warning("Failed to parse copy to console line.");
373 s
->forward_to_console
= !!r
;
374 s
->state
= STDOUT_STREAM_RUNNING
;
376 /* Try to save the stream, so that journald can be restarted and we can recover */
377 (void) stdout_stream_save(s
);
380 case STDOUT_STREAM_RUNNING
:
381 return stdout_stream_log(s
, p
);
384 assert_not_reached("Unknown stream state");
387 static int stdout_stream_scan(StdoutStream
*s
, bool force_flush
) {
395 remaining
= s
->length
;
400 end
= memchr(p
, '\n', remaining
);
403 else if (remaining
>= sizeof(s
->buffer
) - 1) {
404 end
= p
+ sizeof(s
->buffer
) - 1;
411 r
= stdout_stream_line(s
, p
);
419 if (force_flush
&& remaining
> 0) {
421 r
= stdout_stream_line(s
, p
);
430 memmove(s
->buffer
, p
, remaining
);
431 s
->length
= remaining
;
437 static int stdout_stream_process(sd_event_source
*es
, int fd
, uint32_t revents
, void *userdata
) {
438 StdoutStream
*s
= userdata
;
444 if ((revents
|EPOLLIN
|EPOLLHUP
) != (EPOLLIN
|EPOLLHUP
)) {
445 log_error("Got invalid event from epoll for stdout stream: %"PRIx32
, revents
);
449 l
= read(s
->fd
, s
->buffer
+s
->length
, sizeof(s
->buffer
)-1-s
->length
);
455 log_warning_errno(errno
, "Failed to read from stream: %m");
460 stdout_stream_scan(s
, true);
465 r
= stdout_stream_scan(s
, false);
472 stdout_stream_destroy(s
);
476 static int stdout_stream_install(Server
*s
, int fd
, StdoutStream
**ret
) {
477 _cleanup_(stdout_stream_freep
) StdoutStream
*stream
= NULL
;
483 stream
= new0(StdoutStream
, 1);
488 stream
->priority
= LOG_INFO
;
490 r
= getpeercred(fd
, &stream
->ucred
);
492 return log_error_errno(r
, "Failed to determine peer credentials: %m");
494 if (mac_selinux_use()) {
495 r
= getpeersec(fd
, &stream
->label
);
496 if (r
< 0 && r
!= -EOPNOTSUPP
)
497 (void) log_warning_errno(r
, "Failed to determine peer security context: %m");
500 (void) shutdown(fd
, SHUT_WR
);
502 r
= sd_event_add_io(s
->event
, &stream
->event_source
, fd
, EPOLLIN
, stdout_stream_process
, stream
);
504 return log_error_errno(r
, "Failed to add stream to event loop: %m");
506 r
= sd_event_source_set_priority(stream
->event_source
, SD_EVENT_PRIORITY_NORMAL
+5);
508 return log_error_errno(r
, "Failed to adjust stdout event source priority: %m");
513 LIST_PREPEND(stdout_stream
, s
->stdout_streams
, stream
);
514 s
->n_stdout_streams
++;
524 static int stdout_stream_new(sd_event_source
*es
, int listen_fd
, uint32_t revents
, void *userdata
) {
525 _cleanup_close_
int fd
= -1;
526 Server
*s
= userdata
;
531 if (revents
!= EPOLLIN
) {
532 log_error("Got invalid event from epoll for stdout server fd: %"PRIx32
, revents
);
536 fd
= accept4(s
->stdout_fd
, NULL
, NULL
, SOCK_NONBLOCK
|SOCK_CLOEXEC
);
541 log_error_errno(errno
, "Failed to accept stdout connection: %m");
545 if (s
->n_stdout_streams
>= STDOUT_STREAMS_MAX
) {
546 log_warning("Too many stdout streams, refusing connection.");
550 r
= stdout_stream_install(s
, fd
, NULL
);
558 static int stdout_stream_load(StdoutStream
*stream
, const char *fname
) {
561 *level_prefix
= NULL
,
562 *forward_to_syslog
= NULL
,
563 *forward_to_kmsg
= NULL
,
564 *forward_to_console
= NULL
;
570 if (!stream
->state_file
) {
571 stream
->state_file
= strappend("/run/systemd/journal/streams/", fname
);
572 if (!stream
->state_file
)
576 r
= parse_env_file(stream
->state_file
, NEWLINE
,
577 "PRIORITY", &priority
,
578 "LEVEL_PREFIX", &level_prefix
,
579 "FORWARD_TO_SYSLOG", &forward_to_syslog
,
580 "FORWARD_TO_KMSG", &forward_to_kmsg
,
581 "FORWARD_TO_CONSOLE", &forward_to_console
,
582 "IDENTIFIER", &stream
->identifier
,
583 "UNIT", &stream
->unit_id
,
586 return log_error_errno(r
, "Failed to read: %s", stream
->state_file
);
591 p
= log_level_from_string(priority
);
593 stream
->priority
= p
;
597 r
= parse_boolean(level_prefix
);
599 stream
->level_prefix
= r
;
602 if (forward_to_syslog
) {
603 r
= parse_boolean(forward_to_syslog
);
605 stream
->forward_to_syslog
= r
;
608 if (forward_to_kmsg
) {
609 r
= parse_boolean(forward_to_kmsg
);
611 stream
->forward_to_kmsg
= r
;
614 if (forward_to_console
) {
615 r
= parse_boolean(forward_to_console
);
617 stream
->forward_to_console
= r
;
623 static int stdout_stream_restore(Server
*s
, const char *fname
, int fd
) {
624 StdoutStream
*stream
;
631 if (s
->n_stdout_streams
>= STDOUT_STREAMS_MAX
) {
632 log_warning("Too many stdout streams, refusing restoring of stream.");
636 r
= stdout_stream_install(s
, fd
, &stream
);
640 stream
->state
= STDOUT_STREAM_RUNNING
;
641 stream
->fdstore
= true;
643 /* Ignore all parsing errors */
644 (void) stdout_stream_load(stream
, fname
);
649 int server_restore_streams(Server
*s
, FDSet
*fds
) {
650 _cleanup_closedir_
DIR *d
= NULL
;
654 d
= opendir("/run/systemd/journal/streams");
659 return log_warning_errno(errno
, "Failed to enumerate /run/systemd/journal/streams: %m");
662 FOREACH_DIRENT(de
, d
, goto fail
) {
663 unsigned long st_dev
, st_ino
;
668 if (sscanf(de
->d_name
, "%lu:%lu", &st_dev
, &st_ino
) != 2)
671 FDSET_FOREACH(fd
, fds
, i
) {
674 if (fstat(fd
, &st
) < 0)
675 return log_error_errno(errno
, "Failed to stat %s: %m", de
->d_name
);
677 if (S_ISSOCK(st
.st_mode
) && st
.st_dev
== st_dev
&& st
.st_ino
== st_ino
) {
684 /* No file descriptor? Then let's delete the state file */
685 log_debug("Cannot restore stream file %s", de
->d_name
);
686 unlinkat(dirfd(d
), de
->d_name
, 0);
690 fdset_remove(fds
, fd
);
692 r
= stdout_stream_restore(s
, de
->d_name
, fd
);
700 return log_error_errno(errno
, "Failed to read streams directory: %m");
703 int server_open_stdout_socket(Server
*s
) {
708 if (s
->stdout_fd
< 0) {
709 union sockaddr_union sa
= {
710 .un
.sun_family
= AF_UNIX
,
711 .un
.sun_path
= "/run/systemd/journal/stdout",
714 s
->stdout_fd
= socket(AF_UNIX
, SOCK_STREAM
|SOCK_CLOEXEC
|SOCK_NONBLOCK
, 0);
715 if (s
->stdout_fd
< 0)
716 return log_error_errno(errno
, "socket() failed: %m");
718 unlink(sa
.un
.sun_path
);
720 r
= bind(s
->stdout_fd
, &sa
.sa
, offsetof(union sockaddr_union
, un
.sun_path
) + strlen(sa
.un
.sun_path
));
722 return log_error_errno(errno
, "bind(%s) failed: %m", sa
.un
.sun_path
);
724 (void) chmod(sa
.un
.sun_path
, 0666);
726 if (listen(s
->stdout_fd
, SOMAXCONN
) < 0)
727 return log_error_errno(errno
, "listen(%s) failed: %m", sa
.un
.sun_path
);
729 fd_nonblock(s
->stdout_fd
, 1);
731 r
= sd_event_add_io(s
->event
, &s
->stdout_event_source
, s
->stdout_fd
, EPOLLIN
, stdout_stream_new
, s
);
733 return log_error_errno(r
, "Failed to add stdout server fd to event source: %m");
735 r
= sd_event_source_set_priority(s
->stdout_event_source
, SD_EVENT_PRIORITY_NORMAL
+10);
737 return log_error_errno(r
, "Failed to adjust priority of stdout server event source: %m");
742 void stdout_stream_send_notify(StdoutStream
*s
) {
743 struct iovec iovec
= {
744 .iov_base
= (char*) "FDSTORE=1",
745 .iov_len
= strlen("FDSTORE=1"),
747 struct msghdr msghdr
= {
751 struct cmsghdr
*cmsg
;
756 assert(s
->in_notify_queue
);
758 assert(s
->server
->notify_fd
>= 0);
760 /* Store the connection fd in PID 1, so that we get it passed
761 * in again on next start */
763 msghdr
.msg_controllen
= CMSG_SPACE(sizeof(int));
764 msghdr
.msg_control
= alloca0(msghdr
.msg_controllen
);
766 cmsg
= CMSG_FIRSTHDR(&msghdr
);
767 cmsg
->cmsg_level
= SOL_SOCKET
;
768 cmsg
->cmsg_type
= SCM_RIGHTS
;
769 cmsg
->cmsg_len
= CMSG_LEN(sizeof(int));
771 memcpy(CMSG_DATA(cmsg
), &s
->fd
, sizeof(int));
773 l
= sendmsg(s
->server
->notify_fd
, &msghdr
, MSG_DONTWAIT
|MSG_NOSIGNAL
);
778 log_error_errno(errno
, "Failed to send stream file descriptor to service manager: %m");
780 log_debug("Successfully sent stream file descriptor to service manager.");
784 LIST_REMOVE(stdout_stream_notify_queue
, s
->server
->stdout_streams_notify_queue
, s
);
785 s
->in_notify_queue
= false;