]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/journal/journald-stream.c
Merge pull request #1790 from endocode/kayrus/fix_man_kernel_cl
[thirdparty/systemd.git] / src / journal / journald-stream.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4 This file is part of systemd.
5
6 Copyright 2011 Lennart Poettering
7
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.
12
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.
17
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/>.
20 ***/
21
22 #include <stddef.h>
23 #include <unistd.h>
24
25 #ifdef HAVE_SELINUX
26 #include <selinux/selinux.h>
27 #endif
28
29 #include "sd-daemon.h"
30 #include "sd-event.h"
31
32 #include "alloc-util.h"
33 #include "dirent-util.h"
34 #include "escape.h"
35 #include "fd-util.h"
36 #include "fileio.h"
37 #include "io-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"
44 #include "mkdir.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"
51
52 #define STDOUT_STREAMS_MAX 4096
53
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,
62 STDOUT_STREAM_RUNNING
63 } StdoutStreamState;
64
65 struct StdoutStream {
66 Server *server;
67 StdoutStreamState state;
68
69 int fd;
70
71 struct ucred ucred;
72 char *label;
73 char *identifier;
74 char *unit_id;
75 int priority;
76 bool level_prefix:1;
77 bool forward_to_syslog:1;
78 bool forward_to_kmsg:1;
79 bool forward_to_console:1;
80
81 bool fdstore:1;
82 bool in_notify_queue:1;
83
84 char buffer[LINE_MAX+1];
85 size_t length;
86
87 sd_event_source *event_source;
88
89 char *state_file;
90
91 LIST_FIELDS(StdoutStream, stdout_stream);
92 LIST_FIELDS(StdoutStream, stdout_stream_notify_queue);
93 };
94
95 void stdout_stream_free(StdoutStream *s) {
96 if (!s)
97 return;
98
99 if (s->server) {
100 assert(s->server->n_stdout_streams > 0);
101 s->server->n_stdout_streams --;
102 LIST_REMOVE(stdout_stream, s->server->stdout_streams, s);
103
104 if (s->in_notify_queue)
105 LIST_REMOVE(stdout_stream_notify_queue, s->server->stdout_streams_notify_queue, s);
106 }
107
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);
111 }
112
113 safe_close(s->fd);
114 free(s->label);
115 free(s->identifier);
116 free(s->unit_id);
117 free(s->state_file);
118
119 free(s);
120 }
121
122 DEFINE_TRIVIAL_CLEANUP_FUNC(StdoutStream*, stdout_stream_free);
123
124 static void stdout_stream_destroy(StdoutStream *s) {
125 if (!s)
126 return;
127
128 if (s->state_file)
129 (void) unlink(s->state_file);
130
131 stdout_stream_free(s);
132 }
133
134 static int stdout_stream_save(StdoutStream *s) {
135 _cleanup_free_ char *temp_path = NULL;
136 _cleanup_fclose_ FILE *f = NULL;
137 int r;
138
139 assert(s);
140
141 if (s->state != STDOUT_STREAM_RUNNING)
142 return 0;
143
144 if (!s->state_file) {
145 struct stat st;
146
147 r = fstat(s->fd, &st);
148 if (r < 0)
149 return log_warning_errno(errno, "Failed to stat connected stream: %m");
150
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)
153 return log_oom();
154 }
155
156 mkdir_p("/run/systemd/journal/streams", 0755);
157
158 r = fopen_temporary(s->state_file, &f, &temp_path);
159 if (r < 0)
160 goto fail;
161
162 fprintf(f,
163 "# This is private data. Do not parse\n"
164 "PRIORITY=%i\n"
165 "LEVEL_PREFIX=%i\n"
166 "FORWARD_TO_SYSLOG=%i\n"
167 "FORWARD_TO_KMSG=%i\n"
168 "FORWARD_TO_CONSOLE=%i\n",
169 s->priority,
170 s->level_prefix,
171 s->forward_to_syslog,
172 s->forward_to_kmsg,
173 s->forward_to_console);
174
175 if (!isempty(s->identifier)) {
176 _cleanup_free_ char *escaped;
177
178 escaped = cescape(s->identifier);
179 if (!escaped) {
180 r = -ENOMEM;
181 goto fail;
182 }
183
184 fprintf(f, "IDENTIFIER=%s\n", escaped);
185 }
186
187 if (!isempty(s->unit_id)) {
188 _cleanup_free_ char *escaped;
189
190 escaped = cescape(s->unit_id);
191 if (!escaped) {
192 r = -ENOMEM;
193 goto fail;
194 }
195
196 fprintf(f, "UNIT=%s\n", escaped);
197 }
198
199 r = fflush_and_check(f);
200 if (r < 0)
201 goto fail;
202
203 if (rename(temp_path, s->state_file) < 0) {
204 r = -errno;
205 goto fail;
206 }
207
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;
211
212 if (s->server->notify_event_source) {
213 r = sd_event_source_set_enabled(s->server->notify_event_source, SD_EVENT_ON);
214 if (r < 0)
215 log_warning_errno(r, "Failed to enable notify event source: %m");
216 }
217 }
218
219 return 0;
220
221 fail:
222 (void) unlink(s->state_file);
223
224 if (temp_path)
225 (void) unlink(temp_path);
226
227 return log_error_errno(r, "Failed to save stream data %s: %m", s->state_file);
228 }
229
230 static int stdout_stream_log(StdoutStream *s, const char *p) {
231 struct iovec iovec[N_IOVEC_META_FIELDS + 5];
232 int priority;
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;
236 unsigned n = 0;
237 size_t label_len;
238
239 assert(s);
240 assert(p);
241
242 if (isempty(p))
243 return 0;
244
245 priority = s->priority;
246
247 if (s->level_prefix)
248 syslog_parse_priority(&p, &priority, false);
249
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);
252
253 if (s->forward_to_kmsg || s->server->forward_to_kmsg)
254 server_forward_kmsg(s->server, priority, s->identifier, p, &s->ucred);
255
256 if (s->forward_to_console || s->server->forward_to_console)
257 server_forward_console(s->server, priority, s->identifier, p, &s->ucred);
258
259 if (s->server->forward_to_wall)
260 server_forward_wall(s->server, priority, s->identifier, p, &s->ucred);
261
262 IOVEC_SET_STRING(iovec[n++], "_TRANSPORT=stdout");
263
264 syslog_priority[strlen("PRIORITY=")] = '0' + LOG_PRI(priority);
265 IOVEC_SET_STRING(iovec[n++], syslog_priority);
266
267 if (priority & LOG_FACMASK) {
268 xsprintf(syslog_facility, "SYSLOG_FACILITY=%i", LOG_FAC(priority));
269 IOVEC_SET_STRING(iovec[n++], syslog_facility);
270 }
271
272 if (s->identifier) {
273 syslog_identifier = strappend("SYSLOG_IDENTIFIER=", s->identifier);
274 if (syslog_identifier)
275 IOVEC_SET_STRING(iovec[n++], syslog_identifier);
276 }
277
278 message = strappend("MESSAGE=", p);
279 if (message)
280 IOVEC_SET_STRING(iovec[n++], message);
281
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);
284 return 0;
285 }
286
287 static int stdout_stream_line(StdoutStream *s, char *p) {
288 int r;
289
290 assert(s);
291 assert(p);
292
293 p = strstrip(p);
294
295 switch (s->state) {
296
297 case STDOUT_STREAM_IDENTIFIER:
298 if (isempty(p))
299 s->identifier = NULL;
300 else {
301 s->identifier = strdup(p);
302 if (!s->identifier)
303 return log_oom();
304 }
305
306 s->state = STDOUT_STREAM_UNIT_ID;
307 return 0;
308
309 case STDOUT_STREAM_UNIT_ID:
310 if (s->ucred.uid == 0) {
311 if (isempty(p))
312 s->unit_id = NULL;
313 else {
314 s->unit_id = strdup(p);
315 if (!s->unit_id)
316 return log_oom();
317 }
318 }
319
320 s->state = STDOUT_STREAM_PRIORITY;
321 return 0;
322
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.");
327 return -EINVAL;
328 }
329
330 s->state = STDOUT_STREAM_LEVEL_PREFIX;
331 return 0;
332
333 case STDOUT_STREAM_LEVEL_PREFIX:
334 r = parse_boolean(p);
335 if (r < 0) {
336 log_warning("Failed to parse level prefix line.");
337 return -EINVAL;
338 }
339
340 s->level_prefix = !!r;
341 s->state = STDOUT_STREAM_FORWARD_TO_SYSLOG;
342 return 0;
343
344 case STDOUT_STREAM_FORWARD_TO_SYSLOG:
345 r = parse_boolean(p);
346 if (r < 0) {
347 log_warning("Failed to parse forward to syslog line.");
348 return -EINVAL;
349 }
350
351 s->forward_to_syslog = !!r;
352 s->state = STDOUT_STREAM_FORWARD_TO_KMSG;
353 return 0;
354
355 case STDOUT_STREAM_FORWARD_TO_KMSG:
356 r = parse_boolean(p);
357 if (r < 0) {
358 log_warning("Failed to parse copy to kmsg line.");
359 return -EINVAL;
360 }
361
362 s->forward_to_kmsg = !!r;
363 s->state = STDOUT_STREAM_FORWARD_TO_CONSOLE;
364 return 0;
365
366 case STDOUT_STREAM_FORWARD_TO_CONSOLE:
367 r = parse_boolean(p);
368 if (r < 0) {
369 log_warning("Failed to parse copy to console line.");
370 return -EINVAL;
371 }
372
373 s->forward_to_console = !!r;
374 s->state = STDOUT_STREAM_RUNNING;
375
376 /* Try to save the stream, so that journald can be restarted and we can recover */
377 (void) stdout_stream_save(s);
378 return 0;
379
380 case STDOUT_STREAM_RUNNING:
381 return stdout_stream_log(s, p);
382 }
383
384 assert_not_reached("Unknown stream state");
385 }
386
387 static int stdout_stream_scan(StdoutStream *s, bool force_flush) {
388 char *p;
389 size_t remaining;
390 int r;
391
392 assert(s);
393
394 p = s->buffer;
395 remaining = s->length;
396 for (;;) {
397 char *end;
398 size_t skip;
399
400 end = memchr(p, '\n', remaining);
401 if (end)
402 skip = end - p + 1;
403 else if (remaining >= sizeof(s->buffer) - 1) {
404 end = p + sizeof(s->buffer) - 1;
405 skip = remaining;
406 } else
407 break;
408
409 *end = 0;
410
411 r = stdout_stream_line(s, p);
412 if (r < 0)
413 return r;
414
415 remaining -= skip;
416 p += skip;
417 }
418
419 if (force_flush && remaining > 0) {
420 p[remaining] = 0;
421 r = stdout_stream_line(s, p);
422 if (r < 0)
423 return r;
424
425 p += remaining;
426 remaining = 0;
427 }
428
429 if (p > s->buffer) {
430 memmove(s->buffer, p, remaining);
431 s->length = remaining;
432 }
433
434 return 0;
435 }
436
437 static int stdout_stream_process(sd_event_source *es, int fd, uint32_t revents, void *userdata) {
438 StdoutStream *s = userdata;
439 ssize_t l;
440 int r;
441
442 assert(s);
443
444 if ((revents|EPOLLIN|EPOLLHUP) != (EPOLLIN|EPOLLHUP)) {
445 log_error("Got invalid event from epoll for stdout stream: %"PRIx32, revents);
446 goto terminate;
447 }
448
449 l = read(s->fd, s->buffer+s->length, sizeof(s->buffer)-1-s->length);
450 if (l < 0) {
451
452 if (errno == EAGAIN)
453 return 0;
454
455 log_warning_errno(errno, "Failed to read from stream: %m");
456 goto terminate;
457 }
458
459 if (l == 0) {
460 stdout_stream_scan(s, true);
461 goto terminate;
462 }
463
464 s->length += l;
465 r = stdout_stream_scan(s, false);
466 if (r < 0)
467 goto terminate;
468
469 return 1;
470
471 terminate:
472 stdout_stream_destroy(s);
473 return 0;
474 }
475
476 static int stdout_stream_install(Server *s, int fd, StdoutStream **ret) {
477 _cleanup_(stdout_stream_freep) StdoutStream *stream = NULL;
478 int r;
479
480 assert(s);
481 assert(fd >= 0);
482
483 stream = new0(StdoutStream, 1);
484 if (!stream)
485 return log_oom();
486
487 stream->fd = -1;
488 stream->priority = LOG_INFO;
489
490 r = getpeercred(fd, &stream->ucred);
491 if (r < 0)
492 return log_error_errno(r, "Failed to determine peer credentials: %m");
493
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");
498 }
499
500 (void) shutdown(fd, SHUT_WR);
501
502 r = sd_event_add_io(s->event, &stream->event_source, fd, EPOLLIN, stdout_stream_process, stream);
503 if (r < 0)
504 return log_error_errno(r, "Failed to add stream to event loop: %m");
505
506 r = sd_event_source_set_priority(stream->event_source, SD_EVENT_PRIORITY_NORMAL+5);
507 if (r < 0)
508 return log_error_errno(r, "Failed to adjust stdout event source priority: %m");
509
510 stream->fd = fd;
511
512 stream->server = s;
513 LIST_PREPEND(stdout_stream, s->stdout_streams, stream);
514 s->n_stdout_streams ++;
515
516 if (ret)
517 *ret = stream;
518
519 stream = NULL;
520
521 return 0;
522 }
523
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;
527 int r;
528
529 assert(s);
530
531 if (revents != EPOLLIN) {
532 log_error("Got invalid event from epoll for stdout server fd: %"PRIx32, revents);
533 return -EIO;
534 }
535
536 fd = accept4(s->stdout_fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC);
537 if (fd < 0) {
538 if (errno == EAGAIN)
539 return 0;
540
541 return log_error_errno(errno, "Failed to accept stdout connection: %m");
542 }
543
544 if (s->n_stdout_streams >= STDOUT_STREAMS_MAX) {
545 log_warning("Too many stdout streams, refusing connection.");
546 return 0;
547 }
548
549 r = stdout_stream_install(s, fd, NULL);
550 if (r < 0)
551 return r;
552
553 fd = -1;
554 return 0;
555 }
556
557 static int stdout_stream_load(StdoutStream *stream, const char *fname) {
558 _cleanup_free_ char
559 *priority = NULL,
560 *level_prefix = NULL,
561 *forward_to_syslog = NULL,
562 *forward_to_kmsg = NULL,
563 *forward_to_console = NULL;
564 int r;
565
566 assert(stream);
567 assert(fname);
568
569 if (!stream->state_file) {
570 stream->state_file = strappend("/run/systemd/journal/streams/", fname);
571 if (!stream->state_file)
572 return log_oom();
573 }
574
575 r = parse_env_file(stream->state_file, NEWLINE,
576 "PRIORITY", &priority,
577 "LEVEL_PREFIX", &level_prefix,
578 "FORWARD_TO_SYSLOG", &forward_to_syslog,
579 "FORWARD_TO_KMSG", &forward_to_kmsg,
580 "FORWARD_TO_CONSOLE", &forward_to_console,
581 "IDENTIFIER", &stream->identifier,
582 "UNIT", &stream->unit_id,
583 NULL);
584 if (r < 0)
585 return log_error_errno(r, "Failed to read: %s", stream->state_file);
586
587 if (priority) {
588 int p;
589
590 p = log_level_from_string(priority);
591 if (p >= 0)
592 stream->priority = p;
593 }
594
595 if (level_prefix) {
596 r = parse_boolean(level_prefix);
597 if (r >= 0)
598 stream->level_prefix = r;
599 }
600
601 if (forward_to_syslog) {
602 r = parse_boolean(forward_to_syslog);
603 if (r >= 0)
604 stream->forward_to_syslog = r;
605 }
606
607 if (forward_to_kmsg) {
608 r = parse_boolean(forward_to_kmsg);
609 if (r >= 0)
610 stream->forward_to_kmsg = r;
611 }
612
613 if (forward_to_console) {
614 r = parse_boolean(forward_to_console);
615 if (r >= 0)
616 stream->forward_to_console = r;
617 }
618
619 return 0;
620 }
621
622 static int stdout_stream_restore(Server *s, const char *fname, int fd) {
623 StdoutStream *stream;
624 int r;
625
626 assert(s);
627 assert(fname);
628 assert(fd >= 0);
629
630 if (s->n_stdout_streams >= STDOUT_STREAMS_MAX) {
631 log_warning("Too many stdout streams, refusing restoring of stream.");
632 return -ENOBUFS;
633 }
634
635 r = stdout_stream_install(s, fd, &stream);
636 if (r < 0)
637 return r;
638
639 stream->state = STDOUT_STREAM_RUNNING;
640 stream->fdstore = true;
641
642 /* Ignore all parsing errors */
643 (void) stdout_stream_load(stream, fname);
644
645 return 0;
646 }
647
648 int server_restore_streams(Server *s, FDSet *fds) {
649 _cleanup_closedir_ DIR *d = NULL;
650 struct dirent *de;
651 int r;
652
653 d = opendir("/run/systemd/journal/streams");
654 if (!d) {
655 if (errno == ENOENT)
656 return 0;
657
658 return log_warning_errno(errno, "Failed to enumerate /run/systemd/journal/streams: %m");
659 }
660
661 FOREACH_DIRENT(de, d, goto fail) {
662 unsigned long st_dev, st_ino;
663 bool found = false;
664 Iterator i;
665 int fd;
666
667 if (sscanf(de->d_name, "%lu:%lu", &st_dev, &st_ino) != 2)
668 continue;
669
670 FDSET_FOREACH(fd, fds, i) {
671 struct stat st;
672
673 if (fstat(fd, &st) < 0)
674 return log_error_errno(errno, "Failed to stat %s: %m", de->d_name);
675
676 if (S_ISSOCK(st.st_mode) && st.st_dev == st_dev && st.st_ino == st_ino) {
677 found = true;
678 break;
679 }
680 }
681
682 if (!found) {
683 /* No file descriptor? Then let's delete the state file */
684 log_debug("Cannot restore stream file %s", de->d_name);
685 unlinkat(dirfd(d), de->d_name, 0);
686 continue;
687 }
688
689 fdset_remove(fds, fd);
690
691 r = stdout_stream_restore(s, de->d_name, fd);
692 if (r < 0)
693 safe_close(fd);
694 }
695
696 return 0;
697
698 fail:
699 return log_error_errno(errno, "Failed to read streams directory: %m");
700 }
701
702 int server_open_stdout_socket(Server *s) {
703 int r;
704
705 assert(s);
706
707 if (s->stdout_fd < 0) {
708 union sockaddr_union sa = {
709 .un.sun_family = AF_UNIX,
710 .un.sun_path = "/run/systemd/journal/stdout",
711 };
712
713 s->stdout_fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
714 if (s->stdout_fd < 0)
715 return log_error_errno(errno, "socket() failed: %m");
716
717 unlink(sa.un.sun_path);
718
719 r = bind(s->stdout_fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path));
720 if (r < 0)
721 return log_error_errno(errno, "bind(%s) failed: %m", sa.un.sun_path);
722
723 (void) chmod(sa.un.sun_path, 0666);
724
725 if (listen(s->stdout_fd, SOMAXCONN) < 0)
726 return log_error_errno(errno, "listen(%s) failed: %m", sa.un.sun_path);
727 } else
728 fd_nonblock(s->stdout_fd, 1);
729
730 r = sd_event_add_io(s->event, &s->stdout_event_source, s->stdout_fd, EPOLLIN, stdout_stream_new, s);
731 if (r < 0)
732 return log_error_errno(r, "Failed to add stdout server fd to event source: %m");
733
734 r = sd_event_source_set_priority(s->stdout_event_source, SD_EVENT_PRIORITY_NORMAL+10);
735 if (r < 0)
736 return log_error_errno(r, "Failed to adjust priority of stdout server event source: %m");
737
738 return 0;
739 }
740
741 void stdout_stream_send_notify(StdoutStream *s) {
742 struct iovec iovec = {
743 .iov_base = (char*) "FDSTORE=1",
744 .iov_len = strlen("FDSTORE=1"),
745 };
746 struct msghdr msghdr = {
747 .msg_iov = &iovec,
748 .msg_iovlen = 1,
749 };
750 struct cmsghdr *cmsg;
751 ssize_t l;
752
753 assert(s);
754 assert(!s->fdstore);
755 assert(s->in_notify_queue);
756 assert(s->server);
757 assert(s->server->notify_fd >= 0);
758
759 /* Store the connection fd in PID 1, so that we get it passed
760 * in again on next start */
761
762 msghdr.msg_controllen = CMSG_SPACE(sizeof(int));
763 msghdr.msg_control = alloca0(msghdr.msg_controllen);
764
765 cmsg = CMSG_FIRSTHDR(&msghdr);
766 cmsg->cmsg_level = SOL_SOCKET;
767 cmsg->cmsg_type = SCM_RIGHTS;
768 cmsg->cmsg_len = CMSG_LEN(sizeof(int));
769
770 memcpy(CMSG_DATA(cmsg), &s->fd, sizeof(int));
771
772 l = sendmsg(s->server->notify_fd, &msghdr, MSG_DONTWAIT|MSG_NOSIGNAL);
773 if (l < 0) {
774 if (errno == EAGAIN)
775 return;
776
777 log_error_errno(errno, "Failed to send stream file descriptor to service manager: %m");
778 } else {
779 log_debug("Successfully sent stream file descriptor to service manager.");
780 s->fdstore = 1;
781 }
782
783 LIST_REMOVE(stdout_stream_notify_queue, s->server->stdout_streams_notify_queue, s);
784 s->in_notify_queue = false;
785
786 }