1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd.
5 Copyright 2011 Lennart Poettering
12 #include <selinux/selinux.h>
15 #include "sd-daemon.h"
18 #include "alloc-util.h"
19 #include "dirent-util.h"
24 #include "journald-console.h"
25 #include "journald-context.h"
26 #include "journald-kmsg.h"
27 #include "journald-server.h"
28 #include "journald-stream.h"
29 #include "journald-syslog.h"
30 #include "journald-wall.h"
32 #include "parse-util.h"
33 #include "process-util.h"
34 #include "selinux-util.h"
35 #include "socket-util.h"
36 #include "stdio-util.h"
37 #include "string-util.h"
38 #include "syslog-util.h"
39 #include "unit-name.h"
41 #define STDOUT_STREAMS_MAX 4096
43 typedef enum StdoutStreamState
{
44 STDOUT_STREAM_IDENTIFIER
,
45 STDOUT_STREAM_UNIT_ID
,
46 STDOUT_STREAM_PRIORITY
,
47 STDOUT_STREAM_LEVEL_PREFIX
,
48 STDOUT_STREAM_FORWARD_TO_SYSLOG
,
49 STDOUT_STREAM_FORWARD_TO_KMSG
,
50 STDOUT_STREAM_FORWARD_TO_CONSOLE
,
54 /* The different types of log record terminators: a real \n was read, a NUL character was read, the maximum line length
55 * was reached, or the end of the stream was reached */
57 typedef enum LineBreak
{
66 StdoutStreamState state
;
76 bool forward_to_syslog
:1;
77 bool forward_to_kmsg
:1;
78 bool forward_to_console
:1;
81 bool in_notify_queue
:1;
87 sd_event_source
*event_source
;
91 ClientContext
*context
;
93 LIST_FIELDS(StdoutStream
, stdout_stream
);
94 LIST_FIELDS(StdoutStream
, stdout_stream_notify_queue
);
96 char id_field
[STRLEN("_STREAM_ID=") + SD_ID128_STRING_MAX
];
99 void stdout_stream_free(StdoutStream
*s
) {
106 client_context_release(s
->server
, s
->context
);
108 assert(s
->server
->n_stdout_streams
> 0);
109 s
->server
->n_stdout_streams
--;
110 LIST_REMOVE(stdout_stream
, s
->server
->stdout_streams
, s
);
112 if (s
->in_notify_queue
)
113 LIST_REMOVE(stdout_stream_notify_queue
, s
->server
->stdout_streams_notify_queue
, s
);
116 if (s
->event_source
) {
117 sd_event_source_set_enabled(s
->event_source
, SD_EVENT_OFF
);
118 s
->event_source
= sd_event_source_unref(s
->event_source
);
131 DEFINE_TRIVIAL_CLEANUP_FUNC(StdoutStream
*, stdout_stream_free
);
133 static void stdout_stream_destroy(StdoutStream
*s
) {
138 (void) unlink(s
->state_file
);
140 stdout_stream_free(s
);
143 static int stdout_stream_save(StdoutStream
*s
) {
144 _cleanup_free_
char *temp_path
= NULL
;
145 _cleanup_fclose_
FILE *f
= NULL
;
150 if (s
->state
!= STDOUT_STREAM_RUNNING
)
153 if (!s
->state_file
) {
156 r
= fstat(s
->fd
, &st
);
158 return log_warning_errno(errno
, "Failed to stat connected stream: %m");
160 /* We use device and inode numbers as identifier for the stream */
161 if (asprintf(&s
->state_file
, "/run/systemd/journal/streams/%lu:%lu", (unsigned long) st
.st_dev
, (unsigned long) st
.st_ino
) < 0)
165 mkdir_p("/run/systemd/journal/streams", 0755);
167 r
= fopen_temporary(s
->state_file
, &f
, &temp_path
);
172 "# This is private data. Do not parse\n"
175 "FORWARD_TO_SYSLOG=%i\n"
176 "FORWARD_TO_KMSG=%i\n"
177 "FORWARD_TO_CONSOLE=%i\n"
181 s
->forward_to_syslog
,
183 s
->forward_to_console
,
184 s
->id_field
+ STRLEN("_STREAM_ID="));
186 if (!isempty(s
->identifier
)) {
187 _cleanup_free_
char *escaped
;
189 escaped
= cescape(s
->identifier
);
195 fprintf(f
, "IDENTIFIER=%s\n", escaped
);
198 if (!isempty(s
->unit_id
)) {
199 _cleanup_free_
char *escaped
;
201 escaped
= cescape(s
->unit_id
);
207 fprintf(f
, "UNIT=%s\n", escaped
);
210 r
= fflush_and_check(f
);
214 if (rename(temp_path
, s
->state_file
) < 0) {
219 if (!s
->fdstore
&& !s
->in_notify_queue
) {
220 LIST_PREPEND(stdout_stream_notify_queue
, s
->server
->stdout_streams_notify_queue
, s
);
221 s
->in_notify_queue
= true;
223 if (s
->server
->notify_event_source
) {
224 r
= sd_event_source_set_enabled(s
->server
->notify_event_source
, SD_EVENT_ON
);
226 log_warning_errno(r
, "Failed to enable notify event source: %m");
233 (void) unlink(s
->state_file
);
236 (void) unlink(temp_path
);
238 return log_error_errno(r
, "Failed to save stream data %s: %m", s
->state_file
);
241 static int stdout_stream_log(StdoutStream
*s
, const char *p
, LineBreak line_break
) {
244 char syslog_priority
[] = "PRIORITY=\0";
245 char syslog_facility
[STRLEN("SYSLOG_FACILITY=") + DECIMAL_STR_MAX(int) + 1];
246 _cleanup_free_
char *message
= NULL
, *syslog_identifier
= NULL
;
254 (void) client_context_maybe_refresh(s
->server
, s
->context
, NULL
, NULL
, 0, NULL
, USEC_INFINITY
);
255 else if (pid_is_valid(s
->ucred
.pid
)) {
256 r
= client_context_acquire(s
->server
, s
->ucred
.pid
, &s
->ucred
, s
->label
, strlen_ptr(s
->label
), s
->unit_id
, &s
->context
);
258 log_warning_errno(r
, "Failed to acquire client context, ignoring: %m");
261 priority
= s
->priority
;
264 syslog_parse_priority(&p
, &priority
, false);
266 if (!client_context_test_priority(s
->context
, priority
))
272 if (s
->forward_to_syslog
|| s
->server
->forward_to_syslog
)
273 server_forward_syslog(s
->server
, syslog_fixup_facility(priority
), s
->identifier
, p
, &s
->ucred
, NULL
);
275 if (s
->forward_to_kmsg
|| s
->server
->forward_to_kmsg
)
276 server_forward_kmsg(s
->server
, priority
, s
->identifier
, p
, &s
->ucred
);
278 if (s
->forward_to_console
|| s
->server
->forward_to_console
)
279 server_forward_console(s
->server
, priority
, s
->identifier
, p
, &s
->ucred
);
281 if (s
->server
->forward_to_wall
)
282 server_forward_wall(s
->server
, priority
, s
->identifier
, p
, &s
->ucred
);
284 m
= N_IOVEC_META_FIELDS
+ 7 + client_context_extra_fields_n_iovec(s
->context
);
285 iovec
= newa(struct iovec
, m
);
287 iovec
[n
++] = IOVEC_MAKE_STRING("_TRANSPORT=stdout");
288 iovec
[n
++] = IOVEC_MAKE_STRING(s
->id_field
);
290 syslog_priority
[STRLEN("PRIORITY=")] = '0' + LOG_PRI(priority
);
291 iovec
[n
++] = IOVEC_MAKE_STRING(syslog_priority
);
293 if (priority
& LOG_FACMASK
) {
294 xsprintf(syslog_facility
, "SYSLOG_FACILITY=%i", LOG_FAC(priority
));
295 iovec
[n
++] = IOVEC_MAKE_STRING(syslog_facility
);
299 syslog_identifier
= strappend("SYSLOG_IDENTIFIER=", s
->identifier
);
300 if (syslog_identifier
)
301 iovec
[n
++] = IOVEC_MAKE_STRING(syslog_identifier
);
304 if (line_break
!= LINE_BREAK_NEWLINE
) {
307 /* If this log message was generated due to an uncommon line break then mention this in the log
310 c
= line_break
== LINE_BREAK_NUL
? "_LINE_BREAK=nul" :
311 line_break
== LINE_BREAK_LINE_MAX
? "_LINE_BREAK=line-max" :
313 iovec
[n
++] = IOVEC_MAKE_STRING(c
);
316 message
= strappend("MESSAGE=", p
);
318 iovec
[n
++] = IOVEC_MAKE_STRING(message
);
320 server_dispatch_message(s
->server
, iovec
, n
, m
, s
->context
, NULL
, priority
, 0);
324 static int stdout_stream_line(StdoutStream
*s
, char *p
, LineBreak line_break
) {
334 /* line breaks by NUL, line max length or EOF are not permissible during the negotiation part of the protocol */
335 if (line_break
!= LINE_BREAK_NEWLINE
&& s
->state
!= STDOUT_STREAM_RUNNING
) {
336 log_warning("Control protocol line not properly terminated.");
342 case STDOUT_STREAM_IDENTIFIER
:
344 s
->identifier
= strdup(p
);
349 s
->state
= STDOUT_STREAM_UNIT_ID
;
352 case STDOUT_STREAM_UNIT_ID
:
353 if (s
->ucred
.uid
== 0 &&
354 unit_name_is_valid(p
, UNIT_NAME_PLAIN
|UNIT_NAME_INSTANCE
)) {
356 s
->unit_id
= strdup(p
);
361 s
->state
= STDOUT_STREAM_PRIORITY
;
364 case STDOUT_STREAM_PRIORITY
:
365 r
= safe_atoi(p
, &s
->priority
);
366 if (r
< 0 || s
->priority
< 0 || s
->priority
> 999) {
367 log_warning("Failed to parse log priority line.");
371 s
->state
= STDOUT_STREAM_LEVEL_PREFIX
;
374 case STDOUT_STREAM_LEVEL_PREFIX
:
375 r
= parse_boolean(p
);
377 log_warning("Failed to parse level prefix line.");
382 s
->state
= STDOUT_STREAM_FORWARD_TO_SYSLOG
;
385 case STDOUT_STREAM_FORWARD_TO_SYSLOG
:
386 r
= parse_boolean(p
);
388 log_warning("Failed to parse forward to syslog line.");
392 s
->forward_to_syslog
= r
;
393 s
->state
= STDOUT_STREAM_FORWARD_TO_KMSG
;
396 case STDOUT_STREAM_FORWARD_TO_KMSG
:
397 r
= parse_boolean(p
);
399 log_warning("Failed to parse copy to kmsg line.");
403 s
->forward_to_kmsg
= r
;
404 s
->state
= STDOUT_STREAM_FORWARD_TO_CONSOLE
;
407 case STDOUT_STREAM_FORWARD_TO_CONSOLE
:
408 r
= parse_boolean(p
);
410 log_warning("Failed to parse copy to console line.");
414 s
->forward_to_console
= r
;
415 s
->state
= STDOUT_STREAM_RUNNING
;
417 /* Try to save the stream, so that journald can be restarted and we can recover */
418 (void) stdout_stream_save(s
);
421 case STDOUT_STREAM_RUNNING
:
422 return stdout_stream_log(s
, orig
, line_break
);
425 assert_not_reached("Unknown stream state");
428 static int stdout_stream_scan(StdoutStream
*s
, bool force_flush
) {
436 remaining
= s
->length
;
438 /* XXX: This function does nothing if (s->length == 0) */
441 LineBreak line_break
;
445 end1
= memchr(p
, '\n', remaining
);
446 end2
= memchr(p
, 0, end1
? (size_t) (end1
- p
) : remaining
);
449 /* We found a NUL terminator */
451 line_break
= LINE_BREAK_NUL
;
453 /* We found a \n terminator */
456 line_break
= LINE_BREAK_NEWLINE
;
457 } else if (remaining
>= s
->server
->line_max
) {
458 /* Force a line break after the maximum line length */
459 *(p
+ s
->server
->line_max
) = 0;
461 line_break
= LINE_BREAK_LINE_MAX
;
465 r
= stdout_stream_line(s
, p
, line_break
);
473 if (force_flush
&& remaining
> 0) {
475 r
= stdout_stream_line(s
, p
, LINE_BREAK_EOF
);
484 memmove(s
->buffer
, p
, remaining
);
485 s
->length
= remaining
;
491 static int stdout_stream_process(sd_event_source
*es
, int fd
, uint32_t revents
, void *userdata
) {
492 StdoutStream
*s
= userdata
;
499 if ((revents
|EPOLLIN
|EPOLLHUP
) != (EPOLLIN
|EPOLLHUP
)) {
500 log_error("Got invalid event from epoll for stdout stream: %"PRIx32
, revents
);
504 /* If the buffer is full already (discounting the extra NUL we need), add room for another 1K */
505 if (s
->length
+ 1 >= s
->allocated
) {
506 if (!GREEDY_REALLOC(s
->buffer
, s
->allocated
, s
->length
+ 1 + 1024)) {
512 /* Try to make use of the allocated buffer in full, but never read more than the configured line size. Also,
513 * always leave room for a terminating NUL we might need to add. */
514 limit
= MIN(s
->allocated
- 1, s
->server
->line_max
);
516 l
= read(s
->fd
, s
->buffer
+ s
->length
, limit
- s
->length
);
521 log_warning_errno(errno
, "Failed to read from stream: %m");
526 stdout_stream_scan(s
, true);
531 r
= stdout_stream_scan(s
, false);
538 stdout_stream_destroy(s
);
542 static int stdout_stream_install(Server
*s
, int fd
, StdoutStream
**ret
) {
543 _cleanup_(stdout_stream_freep
) StdoutStream
*stream
= NULL
;
550 r
= sd_id128_randomize(&id
);
552 return log_error_errno(r
, "Failed to generate stream ID: %m");
554 stream
= new0(StdoutStream
, 1);
559 stream
->priority
= LOG_INFO
;
561 xsprintf(stream
->id_field
, "_STREAM_ID=" SD_ID128_FORMAT_STR
, SD_ID128_FORMAT_VAL(id
));
563 r
= getpeercred(fd
, &stream
->ucred
);
565 return log_error_errno(r
, "Failed to determine peer credentials: %m");
567 if (mac_selinux_use()) {
568 r
= getpeersec(fd
, &stream
->label
);
569 if (r
< 0 && r
!= -EOPNOTSUPP
)
570 (void) log_warning_errno(r
, "Failed to determine peer security context: %m");
573 (void) shutdown(fd
, SHUT_WR
);
575 r
= sd_event_add_io(s
->event
, &stream
->event_source
, fd
, EPOLLIN
, stdout_stream_process
, stream
);
577 return log_error_errno(r
, "Failed to add stream to event loop: %m");
579 r
= sd_event_source_set_priority(stream
->event_source
, SD_EVENT_PRIORITY_NORMAL
+5);
581 return log_error_errno(r
, "Failed to adjust stdout event source priority: %m");
586 LIST_PREPEND(stdout_stream
, s
->stdout_streams
, stream
);
587 s
->n_stdout_streams
++;
597 static int stdout_stream_new(sd_event_source
*es
, int listen_fd
, uint32_t revents
, void *userdata
) {
598 _cleanup_close_
int fd
= -1;
599 Server
*s
= userdata
;
604 if (revents
!= EPOLLIN
) {
605 log_error("Got invalid event from epoll for stdout server fd: %"PRIx32
, revents
);
609 fd
= accept4(s
->stdout_fd
, NULL
, NULL
, SOCK_NONBLOCK
|SOCK_CLOEXEC
);
614 return log_error_errno(errno
, "Failed to accept stdout connection: %m");
617 if (s
->n_stdout_streams
>= STDOUT_STREAMS_MAX
) {
618 log_warning("Too many stdout streams, refusing connection.");
622 r
= stdout_stream_install(s
, fd
, NULL
);
630 static int stdout_stream_load(StdoutStream
*stream
, const char *fname
) {
633 *level_prefix
= NULL
,
634 *forward_to_syslog
= NULL
,
635 *forward_to_kmsg
= NULL
,
636 *forward_to_console
= NULL
,
643 if (!stream
->state_file
) {
644 stream
->state_file
= strappend("/run/systemd/journal/streams/", fname
);
645 if (!stream
->state_file
)
649 r
= parse_env_file(NULL
, stream
->state_file
, NEWLINE
,
650 "PRIORITY", &priority
,
651 "LEVEL_PREFIX", &level_prefix
,
652 "FORWARD_TO_SYSLOG", &forward_to_syslog
,
653 "FORWARD_TO_KMSG", &forward_to_kmsg
,
654 "FORWARD_TO_CONSOLE", &forward_to_console
,
655 "IDENTIFIER", &stream
->identifier
,
656 "UNIT", &stream
->unit_id
,
657 "STREAM_ID", &stream_id
,
660 return log_error_errno(r
, "Failed to read: %s", stream
->state_file
);
665 p
= log_level_from_string(priority
);
667 stream
->priority
= p
;
671 r
= parse_boolean(level_prefix
);
673 stream
->level_prefix
= r
;
676 if (forward_to_syslog
) {
677 r
= parse_boolean(forward_to_syslog
);
679 stream
->forward_to_syslog
= r
;
682 if (forward_to_kmsg
) {
683 r
= parse_boolean(forward_to_kmsg
);
685 stream
->forward_to_kmsg
= r
;
688 if (forward_to_console
) {
689 r
= parse_boolean(forward_to_console
);
691 stream
->forward_to_console
= r
;
697 r
= sd_id128_from_string(stream_id
, &id
);
699 xsprintf(stream
->id_field
, "_STREAM_ID=" SD_ID128_FORMAT_STR
, SD_ID128_FORMAT_VAL(id
));
705 static int stdout_stream_restore(Server
*s
, const char *fname
, int fd
) {
706 StdoutStream
*stream
;
713 if (s
->n_stdout_streams
>= STDOUT_STREAMS_MAX
) {
714 log_warning("Too many stdout streams, refusing restoring of stream.");
718 r
= stdout_stream_install(s
, fd
, &stream
);
722 stream
->state
= STDOUT_STREAM_RUNNING
;
723 stream
->fdstore
= true;
725 /* Ignore all parsing errors */
726 (void) stdout_stream_load(stream
, fname
);
731 int server_restore_streams(Server
*s
, FDSet
*fds
) {
732 _cleanup_closedir_
DIR *d
= NULL
;
736 d
= opendir("/run/systemd/journal/streams");
741 return log_warning_errno(errno
, "Failed to enumerate /run/systemd/journal/streams: %m");
744 FOREACH_DIRENT(de
, d
, goto fail
) {
745 unsigned long st_dev
, st_ino
;
750 if (sscanf(de
->d_name
, "%lu:%lu", &st_dev
, &st_ino
) != 2)
753 FDSET_FOREACH(fd
, fds
, i
) {
756 if (fstat(fd
, &st
) < 0)
757 return log_error_errno(errno
, "Failed to stat %s: %m", de
->d_name
);
759 if (S_ISSOCK(st
.st_mode
) && st
.st_dev
== st_dev
&& st
.st_ino
== st_ino
) {
766 /* No file descriptor? Then let's delete the state file */
767 log_debug("Cannot restore stream file %s", de
->d_name
);
768 if (unlinkat(dirfd(d
), de
->d_name
, 0) < 0)
769 log_warning_errno(errno
, "Failed to remove /run/systemd/journal/streams/%s: %m",
774 fdset_remove(fds
, fd
);
776 r
= stdout_stream_restore(s
, de
->d_name
, fd
);
784 return log_error_errno(errno
, "Failed to read streams directory: %m");
787 int server_open_stdout_socket(Server
*s
) {
788 static const union sockaddr_union sa
= {
789 .un
.sun_family
= AF_UNIX
,
790 .un
.sun_path
= "/run/systemd/journal/stdout",
796 if (s
->stdout_fd
< 0) {
797 s
->stdout_fd
= socket(AF_UNIX
, SOCK_STREAM
|SOCK_CLOEXEC
|SOCK_NONBLOCK
, 0);
798 if (s
->stdout_fd
< 0)
799 return log_error_errno(errno
, "socket() failed: %m");
801 (void) unlink(sa
.un
.sun_path
);
803 r
= bind(s
->stdout_fd
, &sa
.sa
, SOCKADDR_UN_LEN(sa
.un
));
805 return log_error_errno(errno
, "bind(%s) failed: %m", sa
.un
.sun_path
);
807 (void) chmod(sa
.un
.sun_path
, 0666);
809 if (listen(s
->stdout_fd
, SOMAXCONN
) < 0)
810 return log_error_errno(errno
, "listen(%s) failed: %m", sa
.un
.sun_path
);
812 fd_nonblock(s
->stdout_fd
, 1);
814 r
= sd_event_add_io(s
->event
, &s
->stdout_event_source
, s
->stdout_fd
, EPOLLIN
, stdout_stream_new
, s
);
816 return log_error_errno(r
, "Failed to add stdout server fd to event source: %m");
818 r
= sd_event_source_set_priority(s
->stdout_event_source
, SD_EVENT_PRIORITY_NORMAL
+5);
820 return log_error_errno(r
, "Failed to adjust priority of stdout server event source: %m");
825 void stdout_stream_send_notify(StdoutStream
*s
) {
826 struct iovec iovec
= {
827 .iov_base
= (char*) "FDSTORE=1",
828 .iov_len
= STRLEN("FDSTORE=1"),
830 struct msghdr msghdr
= {
834 struct cmsghdr
*cmsg
;
839 assert(s
->in_notify_queue
);
841 assert(s
->server
->notify_fd
>= 0);
843 /* Store the connection fd in PID 1, so that we get it passed
844 * in again on next start */
846 msghdr
.msg_controllen
= CMSG_SPACE(sizeof(int));
847 msghdr
.msg_control
= alloca0(msghdr
.msg_controllen
);
849 cmsg
= CMSG_FIRSTHDR(&msghdr
);
850 cmsg
->cmsg_level
= SOL_SOCKET
;
851 cmsg
->cmsg_type
= SCM_RIGHTS
;
852 cmsg
->cmsg_len
= CMSG_LEN(sizeof(int));
854 memcpy(CMSG_DATA(cmsg
), &s
->fd
, sizeof(int));
856 l
= sendmsg(s
->server
->notify_fd
, &msghdr
, MSG_DONTWAIT
|MSG_NOSIGNAL
);
861 log_error_errno(errno
, "Failed to send stream file descriptor to service manager: %m");
863 log_debug("Successfully sent stream file descriptor to service manager.");
867 LIST_REMOVE(stdout_stream_notify_queue
, s
->server
->stdout_streams_notify_queue
, s
);
868 s
->in_notify_queue
= false;