File: | build-scan/../src/journal/journald-stream.c |
Warning: | line 621, column 9 Value stored to 'fd' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* SPDX-License-Identifier: LGPL-2.1+ */ |
2 | |
3 | #include <stddef.h> |
4 | #include <unistd.h> |
5 | |
6 | #if HAVE_SELINUX1 |
7 | #include <selinux/selinux.h> |
8 | #endif |
9 | |
10 | #include "sd-daemon.h" |
11 | #include "sd-event.h" |
12 | |
13 | #include "alloc-util.h" |
14 | #include "dirent-util.h" |
15 | #include "escape.h" |
16 | #include "fd-util.h" |
17 | #include "fileio.h" |
18 | #include "io-util.h" |
19 | #include "journald-console.h" |
20 | #include "journald-context.h" |
21 | #include "journald-kmsg.h" |
22 | #include "journald-server.h" |
23 | #include "journald-stream.h" |
24 | #include "journald-syslog.h" |
25 | #include "journald-wall.h" |
26 | #include "mkdir.h" |
27 | #include "parse-util.h" |
28 | #include "process-util.h" |
29 | #include "selinux-util.h" |
30 | #include "socket-util.h" |
31 | #include "stdio-util.h" |
32 | #include "string-util.h" |
33 | #include "syslog-util.h" |
34 | #include "unit-name.h" |
35 | |
36 | #define STDOUT_STREAMS_MAX4096 4096 |
37 | |
38 | typedef enum StdoutStreamState { |
39 | STDOUT_STREAM_IDENTIFIER, |
40 | STDOUT_STREAM_UNIT_ID, |
41 | STDOUT_STREAM_PRIORITY, |
42 | STDOUT_STREAM_LEVEL_PREFIX, |
43 | STDOUT_STREAM_FORWARD_TO_SYSLOG, |
44 | STDOUT_STREAM_FORWARD_TO_KMSG, |
45 | STDOUT_STREAM_FORWARD_TO_CONSOLE, |
46 | STDOUT_STREAM_RUNNING |
47 | } StdoutStreamState; |
48 | |
49 | /* The different types of log record terminators: a real \n was read, a NUL character was read, the maximum line length |
50 | * was reached, or the end of the stream was reached */ |
51 | |
52 | typedef enum LineBreak { |
53 | LINE_BREAK_NEWLINE, |
54 | LINE_BREAK_NUL, |
55 | LINE_BREAK_LINE_MAX, |
56 | LINE_BREAK_EOF, |
57 | } LineBreak; |
58 | |
59 | struct StdoutStream { |
60 | Server *server; |
61 | StdoutStreamState state; |
62 | |
63 | int fd; |
64 | |
65 | struct ucred ucred; |
66 | char *label; |
67 | char *identifier; |
68 | char *unit_id; |
69 | int priority; |
70 | bool_Bool level_prefix:1; |
71 | bool_Bool forward_to_syslog:1; |
72 | bool_Bool forward_to_kmsg:1; |
73 | bool_Bool forward_to_console:1; |
74 | |
75 | bool_Bool fdstore:1; |
76 | bool_Bool in_notify_queue:1; |
77 | |
78 | char *buffer; |
79 | size_t length; |
80 | size_t allocated; |
81 | |
82 | sd_event_source *event_source; |
83 | |
84 | char *state_file; |
85 | |
86 | ClientContext *context; |
87 | |
88 | LIST_FIELDS(StdoutStream, stdout_stream)StdoutStream *stdout_stream_next, *stdout_stream_prev; |
89 | LIST_FIELDS(StdoutStream, stdout_stream_notify_queue)StdoutStream *stdout_stream_notify_queue_next, *stdout_stream_notify_queue_prev; |
90 | |
91 | char id_field[STRLEN("_STREAM_ID=")(sizeof("""_STREAM_ID=""") - 1) + SD_ID128_STRING_MAX33]; |
92 | }; |
93 | |
94 | void stdout_stream_free(StdoutStream *s) { |
95 | if (!s) |
96 | return; |
97 | |
98 | if (s->server) { |
99 | |
100 | if (s->context) |
101 | client_context_release(s->server, s->context); |
102 | |
103 | assert(s->server->n_stdout_streams > 0)do { if ((__builtin_expect(!!(!(s->server->n_stdout_streams > 0)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("s->server->n_stdout_streams > 0" ), "../src/journal/journald-stream.c", 103, __PRETTY_FUNCTION__ ); } while (0); |
104 | s->server->n_stdout_streams--; |
105 | LIST_REMOVE(stdout_stream, s->server->stdout_streams, s)do { typeof(*(s->server->stdout_streams)) **_head = & (s->server->stdout_streams), *_item = (s); do { if ((__builtin_expect (!!(!(_item)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("_item"), "../src/journal/journald-stream.c", 105, __PRETTY_FUNCTION__ ); } while (0); if (_item->stdout_stream_next) _item->stdout_stream_next ->stdout_stream_prev = _item->stdout_stream_prev; if (_item ->stdout_stream_prev) _item->stdout_stream_prev->stdout_stream_next = _item->stdout_stream_next; else { do { if ((__builtin_expect (!!(!(*_head == _item)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD , ("*_head == _item"), "../src/journal/journald-stream.c", 105 , __PRETTY_FUNCTION__); } while (0); *_head = _item->stdout_stream_next ; } _item->stdout_stream_next = _item->stdout_stream_prev = ((void*)0); } while (0); |
106 | |
107 | if (s->in_notify_queue) |
108 | LIST_REMOVE(stdout_stream_notify_queue, s->server->stdout_streams_notify_queue, s)do { typeof(*(s->server->stdout_streams_notify_queue)) * *_head = &(s->server->stdout_streams_notify_queue), *_item = (s); do { if ((__builtin_expect(!!(!(_item)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("_item"), "../src/journal/journald-stream.c" , 108, __PRETTY_FUNCTION__); } while (0); if (_item->stdout_stream_notify_queue_next ) _item->stdout_stream_notify_queue_next->stdout_stream_notify_queue_prev = _item->stdout_stream_notify_queue_prev; if (_item->stdout_stream_notify_queue_prev ) _item->stdout_stream_notify_queue_prev->stdout_stream_notify_queue_next = _item->stdout_stream_notify_queue_next; else { do { if ( (__builtin_expect(!!(!(*_head == _item)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("*_head == _item"), "../src/journal/journald-stream.c" , 108, __PRETTY_FUNCTION__); } while (0); *_head = _item-> stdout_stream_notify_queue_next; } _item->stdout_stream_notify_queue_next = _item->stdout_stream_notify_queue_prev = ((void*)0); } while (0); |
109 | } |
110 | |
111 | if (s->event_source) { |
112 | sd_event_source_set_enabled(s->event_source, SD_EVENT_OFF); |
113 | s->event_source = sd_event_source_unref(s->event_source); |
114 | } |
115 | |
116 | safe_close(s->fd); |
117 | free(s->label); |
118 | free(s->identifier); |
119 | free(s->unit_id); |
120 | free(s->state_file); |
121 | free(s->buffer); |
122 | |
123 | free(s); |
124 | } |
125 | |
126 | DEFINE_TRIVIAL_CLEANUP_FUNC(StdoutStream*, stdout_stream_free)static inline void stdout_stream_freep(StdoutStream* *p) { if (*p) stdout_stream_free(*p); }; |
127 | |
128 | void stdout_stream_destroy(StdoutStream *s) { |
129 | if (!s) |
130 | return; |
131 | |
132 | if (s->state_file) |
133 | (void) unlink(s->state_file); |
134 | |
135 | stdout_stream_free(s); |
136 | } |
137 | |
138 | static int stdout_stream_save(StdoutStream *s) { |
139 | _cleanup_free___attribute__((cleanup(freep))) char *temp_path = NULL((void*)0); |
140 | _cleanup_fclose___attribute__((cleanup(fclosep))) FILE *f = NULL((void*)0); |
141 | int r; |
142 | |
143 | assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("s"), "../src/journal/journald-stream.c" , 143, __PRETTY_FUNCTION__); } while (0); |
144 | |
145 | if (s->state != STDOUT_STREAM_RUNNING) |
146 | return 0; |
147 | |
148 | if (!s->state_file) { |
149 | struct stat st; |
150 | |
151 | r = fstat(s->fd, &st); |
152 | if (r < 0) |
153 | return log_warning_errno(errno, "Failed to stat connected stream: %m")({ int _level = ((4)), _e = (((*__errno_location ()))), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >= ((_level) & 0x07)) ? log_internal_realm(((_realm) << 10 | (_level)), _e, "../src/journal/journald-stream.c", 153, __func__, "Failed to stat connected stream: %m") : -abs(_e); }); |
154 | |
155 | /* We use device and inode numbers as identifier for the stream */ |
156 | if (asprintf(&s->state_file, "/run/systemd/journal/streams/%lu:%lu", (unsigned long) st.st_dev, (unsigned long) st.st_ino) < 0) |
157 | return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/journal/journald-stream.c" , 157, __func__); |
158 | } |
159 | |
160 | mkdir_p("/run/systemd/journal/streams", 0755); |
161 | |
162 | r = fopen_temporary(s->state_file, &f, &temp_path); |
163 | if (r < 0) |
164 | goto fail; |
165 | |
166 | fprintf(f, |
167 | "# This is private data. Do not parse\n" |
168 | "PRIORITY=%i\n" |
169 | "LEVEL_PREFIX=%i\n" |
170 | "FORWARD_TO_SYSLOG=%i\n" |
171 | "FORWARD_TO_KMSG=%i\n" |
172 | "FORWARD_TO_CONSOLE=%i\n" |
173 | "STREAM_ID=%s\n", |
174 | s->priority, |
175 | s->level_prefix, |
176 | s->forward_to_syslog, |
177 | s->forward_to_kmsg, |
178 | s->forward_to_console, |
179 | s->id_field + STRLEN("_STREAM_ID=")(sizeof("""_STREAM_ID=""") - 1)); |
180 | |
181 | if (!isempty(s->identifier)) { |
182 | _cleanup_free___attribute__((cleanup(freep))) char *escaped; |
183 | |
184 | escaped = cescape(s->identifier); |
185 | if (!escaped) { |
186 | r = -ENOMEM12; |
187 | goto fail; |
188 | } |
189 | |
190 | fprintf(f, "IDENTIFIER=%s\n", escaped); |
191 | } |
192 | |
193 | if (!isempty(s->unit_id)) { |
194 | _cleanup_free___attribute__((cleanup(freep))) char *escaped; |
195 | |
196 | escaped = cescape(s->unit_id); |
197 | if (!escaped) { |
198 | r = -ENOMEM12; |
199 | goto fail; |
200 | } |
201 | |
202 | fprintf(f, "UNIT=%s\n", escaped); |
203 | } |
204 | |
205 | r = fflush_and_check(f); |
206 | if (r < 0) |
207 | goto fail; |
208 | |
209 | if (rename(temp_path, s->state_file) < 0) { |
210 | r = -errno(*__errno_location ()); |
211 | goto fail; |
212 | } |
213 | |
214 | if (!s->fdstore && !s->in_notify_queue) { |
215 | LIST_PREPEND(stdout_stream_notify_queue, s->server->stdout_streams_notify_queue, s)do { typeof(*(s->server->stdout_streams_notify_queue)) * *_head = &(s->server->stdout_streams_notify_queue), *_item = (s); do { if ((__builtin_expect(!!(!(_item)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("_item"), "../src/journal/journald-stream.c" , 215, __PRETTY_FUNCTION__); } while (0); if ((_item->stdout_stream_notify_queue_next = *_head)) _item->stdout_stream_notify_queue_next->stdout_stream_notify_queue_prev = _item; _item->stdout_stream_notify_queue_prev = ((void* )0); *_head = _item; } while (0); |
216 | s->in_notify_queue = true1; |
217 | |
218 | if (s->server->notify_event_source) { |
219 | r = sd_event_source_set_enabled(s->server->notify_event_source, SD_EVENT_ON); |
220 | if (r < 0) |
221 | log_warning_errno(r, "Failed to enable notify event source: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal/journald-stream.c", 221, __func__, "Failed to enable notify event source: %m" ) : -abs(_e); }); |
222 | } |
223 | } |
224 | |
225 | return 0; |
226 | |
227 | fail: |
228 | (void) unlink(s->state_file); |
229 | |
230 | if (temp_path) |
231 | (void) unlink(temp_path); |
232 | |
233 | return log_error_errno(r, "Failed to save stream data %s: %m", s->state_file)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal/journald-stream.c", 233, __func__, "Failed to save stream data %s: %m" , s->state_file) : -abs(_e); }); |
234 | } |
235 | |
236 | static int stdout_stream_log(StdoutStream *s, const char *p, LineBreak line_break) { |
237 | struct iovec *iovec; |
238 | int priority; |
239 | char syslog_priority[] = "PRIORITY=\0"; |
240 | char syslog_facility[STRLEN("SYSLOG_FACILITY=")(sizeof("""SYSLOG_FACILITY=""") - 1) + DECIMAL_STR_MAX(int)(2+(sizeof(int) <= 1 ? 3 : sizeof(int) <= 2 ? 5 : sizeof (int) <= 4 ? 10 : sizeof(int) <= 8 ? 20 : sizeof(int[-2 *(sizeof(int) > 8)]))) + 1]; |
241 | _cleanup_free___attribute__((cleanup(freep))) char *message = NULL((void*)0), *syslog_identifier = NULL((void*)0); |
242 | size_t n = 0, m; |
243 | int r; |
244 | |
245 | assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("s"), "../src/journal/journald-stream.c" , 245, __PRETTY_FUNCTION__); } while (0); |
246 | assert(p)do { if ((__builtin_expect(!!(!(p)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("p"), "../src/journal/journald-stream.c" , 246, __PRETTY_FUNCTION__); } while (0); |
247 | |
248 | if (s->context) |
249 | (void) client_context_maybe_refresh(s->server, s->context, NULL((void*)0), NULL((void*)0), 0, NULL((void*)0), USEC_INFINITY((usec_t) -1)); |
250 | else if (pid_is_valid(s->ucred.pid)) { |
251 | r = client_context_acquire(s->server, s->ucred.pid, &s->ucred, s->label, strlen_ptr(s->label), s->unit_id, &s->context); |
252 | if (r < 0) |
253 | log_warning_errno(r, "Failed to acquire client context, ignoring: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal/journald-stream.c", 253, __func__, "Failed to acquire client context, ignoring: %m" ) : -abs(_e); }); |
254 | } |
255 | |
256 | priority = s->priority; |
257 | |
258 | if (s->level_prefix) |
259 | syslog_parse_priority(&p, &priority, false0); |
260 | |
261 | if (!client_context_test_priority(s->context, priority)) |
262 | return 0; |
263 | |
264 | if (isempty(p)) |
265 | return 0; |
266 | |
267 | if (s->forward_to_syslog || s->server->forward_to_syslog) |
268 | server_forward_syslog(s->server, syslog_fixup_facility(priority), s->identifier, p, &s->ucred, NULL((void*)0)); |
269 | |
270 | if (s->forward_to_kmsg || s->server->forward_to_kmsg) |
271 | server_forward_kmsg(s->server, priority, s->identifier, p, &s->ucred); |
272 | |
273 | if (s->forward_to_console || s->server->forward_to_console) |
274 | server_forward_console(s->server, priority, s->identifier, p, &s->ucred); |
275 | |
276 | if (s->server->forward_to_wall) |
277 | server_forward_wall(s->server, priority, s->identifier, p, &s->ucred); |
278 | |
279 | m = N_IOVEC_META_FIELDS22 + 7 + client_context_extra_fields_n_iovec(s->context); |
280 | iovec = newa(struct iovec, m)({ do { if ((__builtin_expect(!!(!(!size_multiply_overflow(sizeof (struct iovec), m))),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD , ("!size_multiply_overflow(sizeof(struct iovec), m)"), "../src/journal/journald-stream.c" , 280, __PRETTY_FUNCTION__); } while (0); (struct iovec*) __builtin_alloca (sizeof(struct iovec)*(m)); }); |
281 | |
282 | iovec[n++] = IOVEC_MAKE_STRING("_TRANSPORT=stdout")(struct iovec) { .iov_base = ((char*) "_TRANSPORT=stdout"), . iov_len = (strlen("_TRANSPORT=stdout")) }; |
283 | iovec[n++] = IOVEC_MAKE_STRING(s->id_field)(struct iovec) { .iov_base = ((char*) s->id_field), .iov_len = (strlen(s->id_field)) }; |
284 | |
285 | syslog_priority[STRLEN("PRIORITY=")(sizeof("""PRIORITY=""") - 1)] = '0' + LOG_PRI(priority)((priority) & 0x07); |
286 | iovec[n++] = IOVEC_MAKE_STRING(syslog_priority)(struct iovec) { .iov_base = ((char*) syslog_priority), .iov_len = (strlen(syslog_priority)) }; |
287 | |
288 | if (priority & LOG_FACMASK0x03f8) { |
289 | xsprintf(syslog_facility, "SYSLOG_FACILITY=%i", LOG_FAC(priority))do { if ((__builtin_expect(!!(!(((size_t) snprintf(syslog_facility , __extension__ (__builtin_choose_expr( !__builtin_types_compatible_p (typeof(syslog_facility), typeof(&*(syslog_facility))), sizeof (syslog_facility)/sizeof((syslog_facility)[0]), ((void)0))), "SYSLOG_FACILITY=%i" , (((priority) & 0x03f8) >> 3)) < (__extension__ (__builtin_choose_expr( !__builtin_types_compatible_p(typeof (syslog_facility), typeof(&*(syslog_facility))), sizeof(syslog_facility )/sizeof((syslog_facility)[0]), ((void)0))))))),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("xsprintf: " "syslog_facility" "[] must be big enough" ), "../src/journal/journald-stream.c", 289, __PRETTY_FUNCTION__ ); } while (0); |
290 | iovec[n++] = IOVEC_MAKE_STRING(syslog_facility)(struct iovec) { .iov_base = ((char*) syslog_facility), .iov_len = (strlen(syslog_facility)) }; |
291 | } |
292 | |
293 | if (s->identifier) { |
294 | syslog_identifier = strappend("SYSLOG_IDENTIFIER=", s->identifier); |
295 | if (syslog_identifier) |
296 | iovec[n++] = IOVEC_MAKE_STRING(syslog_identifier)(struct iovec) { .iov_base = ((char*) syslog_identifier), .iov_len = (strlen(syslog_identifier)) }; |
297 | } |
298 | |
299 | if (line_break != LINE_BREAK_NEWLINE) { |
300 | const char *c; |
301 | |
302 | /* If this log message was generated due to an uncommon line break then mention this in the log |
303 | * entry */ |
304 | |
305 | c = line_break == LINE_BREAK_NUL ? "_LINE_BREAK=nul" : |
306 | line_break == LINE_BREAK_LINE_MAX ? "_LINE_BREAK=line-max" : |
307 | "_LINE_BREAK=eof"; |
308 | iovec[n++] = IOVEC_MAKE_STRING(c)(struct iovec) { .iov_base = ((char*) c), .iov_len = (strlen( c)) }; |
309 | } |
310 | |
311 | message = strappend("MESSAGE=", p); |
312 | if (message) |
313 | iovec[n++] = IOVEC_MAKE_STRING(message)(struct iovec) { .iov_base = ((char*) message), .iov_len = (strlen (message)) }; |
314 | |
315 | server_dispatch_message(s->server, iovec, n, m, s->context, NULL((void*)0), priority, 0); |
316 | return 0; |
317 | } |
318 | |
319 | static int stdout_stream_line(StdoutStream *s, char *p, LineBreak line_break) { |
320 | int r; |
321 | char *orig; |
322 | |
323 | assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("s"), "../src/journal/journald-stream.c" , 323, __PRETTY_FUNCTION__); } while (0); |
324 | assert(p)do { if ((__builtin_expect(!!(!(p)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("p"), "../src/journal/journald-stream.c" , 324, __PRETTY_FUNCTION__); } while (0); |
325 | |
326 | orig = p; |
327 | p = strstrip(p); |
328 | |
329 | /* line breaks by NUL, line max length or EOF are not permissible during the negotiation part of the protocol */ |
330 | if (line_break != LINE_BREAK_NEWLINE && s->state != STDOUT_STREAM_RUNNING) { |
331 | log_warning("Control protocol line not properly terminated.")({ int _level = (((4))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal/journald-stream.c", 331, __func__, "Control protocol line not properly terminated." ) : -abs(_e); }); |
332 | return -EINVAL22; |
333 | } |
334 | |
335 | switch (s->state) { |
336 | |
337 | case STDOUT_STREAM_IDENTIFIER: |
338 | if (!isempty(p)) { |
339 | s->identifier = strdup(p); |
340 | if (!s->identifier) |
341 | return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/journal/journald-stream.c" , 341, __func__); |
342 | } |
343 | |
344 | s->state = STDOUT_STREAM_UNIT_ID; |
345 | return 0; |
346 | |
347 | case STDOUT_STREAM_UNIT_ID: |
348 | if (s->ucred.uid == 0 && |
349 | unit_name_is_valid(p, UNIT_NAME_PLAIN|UNIT_NAME_INSTANCE)) { |
350 | |
351 | s->unit_id = strdup(p); |
352 | if (!s->unit_id) |
353 | return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/journal/journald-stream.c" , 353, __func__); |
354 | } |
355 | |
356 | s->state = STDOUT_STREAM_PRIORITY; |
357 | return 0; |
358 | |
359 | case STDOUT_STREAM_PRIORITY: |
360 | r = safe_atoi(p, &s->priority); |
361 | if (r < 0 || s->priority < 0 || s->priority > 999) { |
362 | log_warning("Failed to parse log priority line.")({ int _level = (((4))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal/journald-stream.c", 362, __func__, "Failed to parse log priority line." ) : -abs(_e); }); |
363 | return -EINVAL22; |
364 | } |
365 | |
366 | s->state = STDOUT_STREAM_LEVEL_PREFIX; |
367 | return 0; |
368 | |
369 | case STDOUT_STREAM_LEVEL_PREFIX: |
370 | r = parse_boolean(p); |
371 | if (r < 0) { |
372 | log_warning("Failed to parse level prefix line.")({ int _level = (((4))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal/journald-stream.c", 372, __func__, "Failed to parse level prefix line." ) : -abs(_e); }); |
373 | return -EINVAL22; |
374 | } |
375 | |
376 | s->level_prefix = r; |
377 | s->state = STDOUT_STREAM_FORWARD_TO_SYSLOG; |
378 | return 0; |
379 | |
380 | case STDOUT_STREAM_FORWARD_TO_SYSLOG: |
381 | r = parse_boolean(p); |
382 | if (r < 0) { |
383 | log_warning("Failed to parse forward to syslog line.")({ int _level = (((4))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal/journald-stream.c", 383, __func__, "Failed to parse forward to syslog line." ) : -abs(_e); }); |
384 | return -EINVAL22; |
385 | } |
386 | |
387 | s->forward_to_syslog = r; |
388 | s->state = STDOUT_STREAM_FORWARD_TO_KMSG; |
389 | return 0; |
390 | |
391 | case STDOUT_STREAM_FORWARD_TO_KMSG: |
392 | r = parse_boolean(p); |
393 | if (r < 0) { |
394 | log_warning("Failed to parse copy to kmsg line.")({ int _level = (((4))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal/journald-stream.c", 394, __func__, "Failed to parse copy to kmsg line." ) : -abs(_e); }); |
395 | return -EINVAL22; |
396 | } |
397 | |
398 | s->forward_to_kmsg = r; |
399 | s->state = STDOUT_STREAM_FORWARD_TO_CONSOLE; |
400 | return 0; |
401 | |
402 | case STDOUT_STREAM_FORWARD_TO_CONSOLE: |
403 | r = parse_boolean(p); |
404 | if (r < 0) { |
405 | log_warning("Failed to parse copy to console line.")({ int _level = (((4))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal/journald-stream.c", 405, __func__, "Failed to parse copy to console line." ) : -abs(_e); }); |
406 | return -EINVAL22; |
407 | } |
408 | |
409 | s->forward_to_console = r; |
410 | s->state = STDOUT_STREAM_RUNNING; |
411 | |
412 | /* Try to save the stream, so that journald can be restarted and we can recover */ |
413 | (void) stdout_stream_save(s); |
414 | return 0; |
415 | |
416 | case STDOUT_STREAM_RUNNING: |
417 | return stdout_stream_log(s, orig, line_break); |
418 | } |
419 | |
420 | assert_not_reached("Unknown stream state")do { log_assert_failed_unreachable_realm(LOG_REALM_SYSTEMD, ( "Unknown stream state"), "../src/journal/journald-stream.c", 420 , __PRETTY_FUNCTION__); } while (0); |
421 | } |
422 | |
423 | static int stdout_stream_scan(StdoutStream *s, bool_Bool force_flush) { |
424 | char *p; |
425 | size_t remaining; |
426 | int r; |
427 | |
428 | assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("s"), "../src/journal/journald-stream.c" , 428, __PRETTY_FUNCTION__); } while (0); |
429 | |
430 | p = s->buffer; |
431 | remaining = s->length; |
432 | |
433 | /* XXX: This function does nothing if (s->length == 0) */ |
434 | |
435 | for (;;) { |
436 | LineBreak line_break; |
437 | size_t skip; |
438 | char *end1, *end2; |
439 | |
440 | end1 = memchr(p, '\n', remaining); |
441 | end2 = memchr(p, 0, end1 ? (size_t) (end1 - p) : remaining); |
442 | |
443 | if (end2) { |
444 | /* We found a NUL terminator */ |
445 | skip = end2 - p + 1; |
446 | line_break = LINE_BREAK_NUL; |
447 | } else if (end1) { |
448 | /* We found a \n terminator */ |
449 | *end1 = 0; |
450 | skip = end1 - p + 1; |
451 | line_break = LINE_BREAK_NEWLINE; |
452 | } else if (remaining >= s->server->line_max) { |
453 | /* Force a line break after the maximum line length */ |
454 | *(p + s->server->line_max) = 0; |
455 | skip = remaining; |
456 | line_break = LINE_BREAK_LINE_MAX; |
457 | } else |
458 | break; |
459 | |
460 | r = stdout_stream_line(s, p, line_break); |
461 | if (r < 0) |
462 | return r; |
463 | |
464 | remaining -= skip; |
465 | p += skip; |
466 | } |
467 | |
468 | if (force_flush && remaining > 0) { |
469 | p[remaining] = 0; |
470 | r = stdout_stream_line(s, p, LINE_BREAK_EOF); |
471 | if (r < 0) |
472 | return r; |
473 | |
474 | p += remaining; |
475 | remaining = 0; |
476 | } |
477 | |
478 | if (p > s->buffer) { |
479 | memmove(s->buffer, p, remaining); |
480 | s->length = remaining; |
481 | } |
482 | |
483 | return 0; |
484 | } |
485 | |
486 | static int stdout_stream_process(sd_event_source *es, int fd, uint32_t revents, void *userdata) { |
487 | StdoutStream *s = userdata; |
488 | size_t limit; |
489 | ssize_t l; |
490 | int r; |
491 | |
492 | assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("s"), "../src/journal/journald-stream.c" , 492, __PRETTY_FUNCTION__); } while (0); |
493 | |
494 | if ((revents|EPOLLINEPOLLIN|EPOLLHUPEPOLLHUP) != (EPOLLINEPOLLIN|EPOLLHUPEPOLLHUP)) { |
495 | log_error("Got invalid event from epoll for stdout stream: %"PRIx32, revents)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal/journald-stream.c", 495, __func__, "Got invalid event from epoll for stdout stream: %" "x", revents) : -abs(_e); }); |
496 | goto terminate; |
497 | } |
498 | |
499 | /* If the buffer is full already (discounting the extra NUL we need), add room for another 1K */ |
500 | if (s->length + 1 >= s->allocated) { |
501 | if (!GREEDY_REALLOC(s->buffer, s->allocated, s->length + 1 + 1024)greedy_realloc((void**) &(s->buffer), &(s->allocated ), (s->length + 1 + 1024), sizeof((s->buffer)[0]))) { |
502 | log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/journal/journald-stream.c" , 502, __func__); |
503 | goto terminate; |
504 | } |
505 | } |
506 | |
507 | /* Try to make use of the allocated buffer in full, but never read more than the configured line size. Also, |
508 | * always leave room for a terminating NUL we might need to add. */ |
509 | limit = MIN(s->allocated - 1, s->server->line_max)__extension__ ({ const typeof((s->allocated - 1)) __unique_prefix_A13 = ((s->allocated - 1)); const typeof((s->server->line_max )) __unique_prefix_B14 = ((s->server->line_max)); __unique_prefix_A13 < __unique_prefix_B14 ? __unique_prefix_A13 : __unique_prefix_B14 ; }); |
510 | |
511 | l = read(s->fd, s->buffer + s->length, limit - s->length); |
512 | if (l < 0) { |
513 | if (errno(*__errno_location ()) == EAGAIN11) |
514 | return 0; |
515 | |
516 | log_warning_errno(errno, "Failed to read from stream: %m")({ int _level = ((4)), _e = (((*__errno_location ()))), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >= ((_level) & 0x07)) ? log_internal_realm(((_realm) << 10 | (_level)), _e, "../src/journal/journald-stream.c", 516, __func__, "Failed to read from stream: %m") : -abs(_e); }); |
517 | goto terminate; |
518 | } |
519 | |
520 | if (l == 0) { |
521 | stdout_stream_scan(s, true1); |
522 | goto terminate; |
523 | } |
524 | |
525 | s->length += l; |
526 | r = stdout_stream_scan(s, false0); |
527 | if (r < 0) |
528 | goto terminate; |
529 | |
530 | return 1; |
531 | |
532 | terminate: |
533 | stdout_stream_destroy(s); |
534 | return 0; |
535 | } |
536 | |
537 | int stdout_stream_install(Server *s, int fd, StdoutStream **ret) { |
538 | _cleanup_(stdout_stream_freep)__attribute__((cleanup(stdout_stream_freep))) StdoutStream *stream = NULL((void*)0); |
539 | sd_id128_t id; |
540 | int r; |
541 | |
542 | assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("s"), "../src/journal/journald-stream.c" , 542, __PRETTY_FUNCTION__); } while (0); |
543 | assert(fd >= 0)do { if ((__builtin_expect(!!(!(fd >= 0)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("fd >= 0"), "../src/journal/journald-stream.c" , 543, __PRETTY_FUNCTION__); } while (0); |
544 | |
545 | r = sd_id128_randomize(&id); |
546 | if (r < 0) |
547 | return log_error_errno(r, "Failed to generate stream ID: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal/journald-stream.c", 547, __func__, "Failed to generate stream ID: %m" ) : -abs(_e); }); |
548 | |
549 | stream = new0(StdoutStream, 1)((StdoutStream*) calloc((1), sizeof(StdoutStream))); |
550 | if (!stream) |
551 | return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/journal/journald-stream.c" , 551, __func__); |
552 | |
553 | stream->fd = -1; |
554 | stream->priority = LOG_INFO6; |
555 | |
556 | xsprintf(stream->id_field, "_STREAM_ID=" SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(id))do { if ((__builtin_expect(!!(!(((size_t) snprintf(stream-> id_field, __extension__ (__builtin_choose_expr( !__builtin_types_compatible_p (typeof(stream->id_field), typeof(&*(stream->id_field ))), sizeof(stream->id_field)/sizeof((stream->id_field) [0]), ((void)0))), "_STREAM_ID=" "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" , (id).bytes[0], (id).bytes[1], (id).bytes[2], (id).bytes[3], (id).bytes[4], (id).bytes[5], (id).bytes[6], (id).bytes[7], ( id).bytes[8], (id).bytes[9], (id).bytes[10], (id).bytes[11], ( id).bytes[12], (id).bytes[13], (id).bytes[14], (id).bytes[15] ) < (__extension__ (__builtin_choose_expr( !__builtin_types_compatible_p (typeof(stream->id_field), typeof(&*(stream->id_field ))), sizeof(stream->id_field)/sizeof((stream->id_field) [0]), ((void)0))))))),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD , ("xsprintf: " "stream->id_field" "[] must be big enough" ), "../src/journal/journald-stream.c", 556, __PRETTY_FUNCTION__ ); } while (0); |
557 | |
558 | r = getpeercred(fd, &stream->ucred); |
559 | if (r < 0) |
560 | return log_error_errno(r, "Failed to determine peer credentials: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal/journald-stream.c", 560, __func__, "Failed to determine peer credentials: %m" ) : -abs(_e); }); |
561 | |
562 | if (mac_selinux_use()) { |
563 | r = getpeersec(fd, &stream->label); |
564 | if (r < 0 && r != -EOPNOTSUPP95) |
565 | (void) log_warning_errno(r, "Failed to determine peer security context: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal/journald-stream.c", 565, __func__, "Failed to determine peer security context: %m" ) : -abs(_e); }); |
566 | } |
567 | |
568 | (void) shutdown(fd, SHUT_WRSHUT_WR); |
569 | |
570 | r = sd_event_add_io(s->event, &stream->event_source, fd, EPOLLINEPOLLIN, stdout_stream_process, stream); |
571 | if (r < 0) |
572 | return log_error_errno(r, "Failed to add stream to event loop: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal/journald-stream.c", 572, __func__, "Failed to add stream to event loop: %m" ) : -abs(_e); }); |
573 | |
574 | r = sd_event_source_set_priority(stream->event_source, SD_EVENT_PRIORITY_NORMAL+5); |
575 | if (r < 0) |
576 | return log_error_errno(r, "Failed to adjust stdout event source priority: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal/journald-stream.c", 576, __func__, "Failed to adjust stdout event source priority: %m" ) : -abs(_e); }); |
577 | |
578 | stream->fd = fd; |
579 | |
580 | stream->server = s; |
581 | LIST_PREPEND(stdout_stream, s->stdout_streams, stream)do { typeof(*(s->stdout_streams)) **_head = &(s->stdout_streams ), *_item = (stream); do { if ((__builtin_expect(!!(!(_item)) ,0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("_item"), "../src/journal/journald-stream.c" , 581, __PRETTY_FUNCTION__); } while (0); if ((_item->stdout_stream_next = *_head)) _item->stdout_stream_next->stdout_stream_prev = _item; _item->stdout_stream_prev = ((void*)0); *_head = _item; } while (0); |
582 | s->n_stdout_streams++; |
583 | |
584 | if (ret) |
585 | *ret = stream; |
586 | |
587 | stream = NULL((void*)0); |
588 | |
589 | return 0; |
590 | } |
591 | |
592 | static int stdout_stream_new(sd_event_source *es, int listen_fd, uint32_t revents, void *userdata) { |
593 | _cleanup_close___attribute__((cleanup(closep))) int fd = -1; |
594 | Server *s = userdata; |
595 | int r; |
596 | |
597 | assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("s"), "../src/journal/journald-stream.c" , 597, __PRETTY_FUNCTION__); } while (0); |
598 | |
599 | if (revents != EPOLLINEPOLLIN) { |
600 | log_error("Got invalid event from epoll for stdout server fd: %"PRIx32, revents)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal/journald-stream.c", 600, __func__, "Got invalid event from epoll for stdout server fd: %" "x", revents) : -abs(_e); }); |
601 | return -EIO5; |
602 | } |
603 | |
604 | fd = accept4(s->stdout_fd, NULL((void*)0), NULL((void*)0), SOCK_NONBLOCKSOCK_NONBLOCK|SOCK_CLOEXECSOCK_CLOEXEC); |
605 | if (fd < 0) { |
606 | if (errno(*__errno_location ()) == EAGAIN11) |
607 | return 0; |
608 | |
609 | return log_error_errno(errno, "Failed to accept stdout connection: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >= ((_level) & 0x07)) ? log_internal_realm(((_realm) << 10 | (_level)), _e, "../src/journal/journald-stream.c", 609, __func__, "Failed to accept stdout connection: %m") : -abs(_e ); }); |
610 | } |
611 | |
612 | if (s->n_stdout_streams >= STDOUT_STREAMS_MAX4096) { |
613 | log_warning("Too many stdout streams, refusing connection.")({ int _level = (((4))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal/journald-stream.c", 613, __func__, "Too many stdout streams, refusing connection." ) : -abs(_e); }); |
614 | return 0; |
615 | } |
616 | |
617 | r = stdout_stream_install(s, fd, NULL((void*)0)); |
618 | if (r < 0) |
619 | return r; |
620 | |
621 | fd = -1; |
Value stored to 'fd' is never read | |
622 | return 0; |
623 | } |
624 | |
625 | static int stdout_stream_load(StdoutStream *stream, const char *fname) { |
626 | _cleanup_free___attribute__((cleanup(freep))) char |
627 | *priority = NULL((void*)0), |
628 | *level_prefix = NULL((void*)0), |
629 | *forward_to_syslog = NULL((void*)0), |
630 | *forward_to_kmsg = NULL((void*)0), |
631 | *forward_to_console = NULL((void*)0), |
632 | *stream_id = NULL((void*)0); |
633 | int r; |
634 | |
635 | assert(stream)do { if ((__builtin_expect(!!(!(stream)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("stream"), "../src/journal/journald-stream.c" , 635, __PRETTY_FUNCTION__); } while (0); |
636 | assert(fname)do { if ((__builtin_expect(!!(!(fname)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("fname"), "../src/journal/journald-stream.c" , 636, __PRETTY_FUNCTION__); } while (0); |
637 | |
638 | if (!stream->state_file) { |
639 | stream->state_file = strappend("/run/systemd/journal/streams/", fname); |
640 | if (!stream->state_file) |
641 | return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/journal/journald-stream.c" , 641, __func__); |
642 | } |
643 | |
644 | r = parse_env_file(NULL((void*)0), stream->state_file, NEWLINE"\n\r", |
645 | "PRIORITY", &priority, |
646 | "LEVEL_PREFIX", &level_prefix, |
647 | "FORWARD_TO_SYSLOG", &forward_to_syslog, |
648 | "FORWARD_TO_KMSG", &forward_to_kmsg, |
649 | "FORWARD_TO_CONSOLE", &forward_to_console, |
650 | "IDENTIFIER", &stream->identifier, |
651 | "UNIT", &stream->unit_id, |
652 | "STREAM_ID", &stream_id, |
653 | NULL((void*)0)); |
654 | if (r < 0) |
655 | return log_error_errno(r, "Failed to read: %s", stream->state_file)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal/journald-stream.c", 655, __func__, "Failed to read: %s" , stream->state_file) : -abs(_e); }); |
656 | |
657 | if (priority) { |
658 | int p; |
659 | |
660 | p = log_level_from_string(priority); |
661 | if (p >= 0) |
662 | stream->priority = p; |
663 | } |
664 | |
665 | if (level_prefix) { |
666 | r = parse_boolean(level_prefix); |
667 | if (r >= 0) |
668 | stream->level_prefix = r; |
669 | } |
670 | |
671 | if (forward_to_syslog) { |
672 | r = parse_boolean(forward_to_syslog); |
673 | if (r >= 0) |
674 | stream->forward_to_syslog = r; |
675 | } |
676 | |
677 | if (forward_to_kmsg) { |
678 | r = parse_boolean(forward_to_kmsg); |
679 | if (r >= 0) |
680 | stream->forward_to_kmsg = r; |
681 | } |
682 | |
683 | if (forward_to_console) { |
684 | r = parse_boolean(forward_to_console); |
685 | if (r >= 0) |
686 | stream->forward_to_console = r; |
687 | } |
688 | |
689 | if (stream_id) { |
690 | sd_id128_t id; |
691 | |
692 | r = sd_id128_from_string(stream_id, &id); |
693 | if (r >= 0) |
694 | xsprintf(stream->id_field, "_STREAM_ID=" SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(id))do { if ((__builtin_expect(!!(!(((size_t) snprintf(stream-> id_field, __extension__ (__builtin_choose_expr( !__builtin_types_compatible_p (typeof(stream->id_field), typeof(&*(stream->id_field ))), sizeof(stream->id_field)/sizeof((stream->id_field) [0]), ((void)0))), "_STREAM_ID=" "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" , (id).bytes[0], (id).bytes[1], (id).bytes[2], (id).bytes[3], (id).bytes[4], (id).bytes[5], (id).bytes[6], (id).bytes[7], ( id).bytes[8], (id).bytes[9], (id).bytes[10], (id).bytes[11], ( id).bytes[12], (id).bytes[13], (id).bytes[14], (id).bytes[15] ) < (__extension__ (__builtin_choose_expr( !__builtin_types_compatible_p (typeof(stream->id_field), typeof(&*(stream->id_field ))), sizeof(stream->id_field)/sizeof((stream->id_field) [0]), ((void)0))))))),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD , ("xsprintf: " "stream->id_field" "[] must be big enough" ), "../src/journal/journald-stream.c", 694, __PRETTY_FUNCTION__ ); } while (0); |
695 | } |
696 | |
697 | return 0; |
698 | } |
699 | |
700 | static int stdout_stream_restore(Server *s, const char *fname, int fd) { |
701 | StdoutStream *stream; |
702 | int r; |
703 | |
704 | assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("s"), "../src/journal/journald-stream.c" , 704, __PRETTY_FUNCTION__); } while (0); |
705 | assert(fname)do { if ((__builtin_expect(!!(!(fname)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("fname"), "../src/journal/journald-stream.c" , 705, __PRETTY_FUNCTION__); } while (0); |
706 | assert(fd >= 0)do { if ((__builtin_expect(!!(!(fd >= 0)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("fd >= 0"), "../src/journal/journald-stream.c" , 706, __PRETTY_FUNCTION__); } while (0); |
707 | |
708 | if (s->n_stdout_streams >= STDOUT_STREAMS_MAX4096) { |
709 | log_warning("Too many stdout streams, refusing restoring of stream.")({ int _level = (((4))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal/journald-stream.c", 709, __func__, "Too many stdout streams, refusing restoring of stream." ) : -abs(_e); }); |
710 | return -ENOBUFS105; |
711 | } |
712 | |
713 | r = stdout_stream_install(s, fd, &stream); |
714 | if (r < 0) |
715 | return r; |
716 | |
717 | stream->state = STDOUT_STREAM_RUNNING; |
718 | stream->fdstore = true1; |
719 | |
720 | /* Ignore all parsing errors */ |
721 | (void) stdout_stream_load(stream, fname); |
722 | |
723 | return 0; |
724 | } |
725 | |
726 | int server_restore_streams(Server *s, FDSet *fds) { |
727 | _cleanup_closedir___attribute__((cleanup(closedirp))) DIR *d = NULL((void*)0); |
728 | struct dirent *de; |
729 | int r; |
730 | |
731 | d = opendir("/run/systemd/journal/streams"); |
732 | if (!d) { |
733 | if (errno(*__errno_location ()) == ENOENT2) |
734 | return 0; |
735 | |
736 | return log_warning_errno(errno, "Failed to enumerate /run/systemd/journal/streams: %m")({ int _level = ((4)), _e = (((*__errno_location ()))), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >= ((_level) & 0x07)) ? log_internal_realm(((_realm) << 10 | (_level)), _e, "../src/journal/journald-stream.c", 736, __func__, "Failed to enumerate /run/systemd/journal/streams: %m" ) : -abs(_e); }); |
737 | } |
738 | |
739 | FOREACH_DIRENT(de, d, goto fail)for ((*__errno_location ()) = 0, de = readdir(d);; (*__errno_location ()) = 0, de = readdir(d)) if (!de) { if ((*__errno_location ( )) > 0) { goto fail; } break; } else if (hidden_or_backup_file ((de)->d_name)) continue; else { |
740 | unsigned long st_dev, st_ino; |
741 | bool_Bool found = false0; |
742 | Iterator i; |
743 | int fd; |
744 | |
745 | if (sscanf(de->d_name, "%lu:%lu", &st_dev, &st_ino) != 2) |
746 | continue; |
747 | |
748 | FDSET_FOREACH(fd, fds, i)for ((i) = ((Iterator) { .idx = ((2147483647 *2U +1U) - 1), . next_key = ((void*)0) }), (fd) = fdset_iterate((fds), &(i )); (fd) >= 0; (fd) = fdset_iterate((fds), &(i))) { |
749 | struct stat st; |
750 | |
751 | if (fstat(fd, &st) < 0) |
752 | return log_error_errno(errno, "Failed to stat %s: %m", de->d_name)({ int _level = ((3)), _e = (((*__errno_location ()))), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >= ((_level) & 0x07)) ? log_internal_realm(((_realm) << 10 | (_level)), _e, "../src/journal/journald-stream.c", 752, __func__, "Failed to stat %s: %m", de->d_name) : -abs(_e) ; }); |
753 | |
754 | if (S_ISSOCK(st.st_mode)((((st.st_mode)) & 0170000) == (0140000)) && st.st_dev == st_dev && st.st_ino == st_ino) { |
755 | found = true1; |
756 | break; |
757 | } |
758 | } |
759 | |
760 | if (!found) { |
761 | /* No file descriptor? Then let's delete the state file */ |
762 | log_debug("Cannot restore stream file %s", de->d_name)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal/journald-stream.c", 762, __func__, "Cannot restore stream file %s" , de->d_name) : -abs(_e); }); |
763 | if (unlinkat(dirfd(d), de->d_name, 0) < 0) |
764 | log_warning_errno(errno, "Failed to remove /run/systemd/journal/streams/%s: %m",({ int _level = ((4)), _e = (((*__errno_location ()))), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >= ((_level) & 0x07)) ? log_internal_realm(((_realm) << 10 | (_level)), _e, "../src/journal/journald-stream.c", 765, __func__, "Failed to remove /run/systemd/journal/streams/%s: %m" , de->d_name) : -abs(_e); }) |
765 | de->d_name)({ int _level = ((4)), _e = (((*__errno_location ()))), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >= ((_level) & 0x07)) ? log_internal_realm(((_realm) << 10 | (_level)), _e, "../src/journal/journald-stream.c", 765, __func__, "Failed to remove /run/systemd/journal/streams/%s: %m" , de->d_name) : -abs(_e); }); |
766 | continue; |
767 | } |
768 | |
769 | fdset_remove(fds, fd); |
770 | |
771 | r = stdout_stream_restore(s, de->d_name, fd); |
772 | if (r < 0) |
773 | safe_close(fd); |
774 | } |
775 | |
776 | return 0; |
777 | |
778 | fail: |
779 | return log_error_errno(errno, "Failed to read streams directory: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >= ((_level) & 0x07)) ? log_internal_realm(((_realm) << 10 | (_level)), _e, "../src/journal/journald-stream.c", 779, __func__, "Failed to read streams directory: %m") : -abs(_e) ; }); |
780 | } |
781 | |
782 | int server_open_stdout_socket(Server *s) { |
783 | static const union sockaddr_union sa = { |
784 | .un.sun_family = AF_UNIX1, |
785 | .un.sun_path = "/run/systemd/journal/stdout", |
786 | }; |
787 | int r; |
788 | |
789 | assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("s"), "../src/journal/journald-stream.c" , 789, __PRETTY_FUNCTION__); } while (0); |
790 | |
791 | if (s->stdout_fd < 0) { |
792 | s->stdout_fd = socket(AF_UNIX1, SOCK_STREAMSOCK_STREAM|SOCK_CLOEXECSOCK_CLOEXEC|SOCK_NONBLOCKSOCK_NONBLOCK, 0); |
793 | if (s->stdout_fd < 0) |
794 | return log_error_errno(errno, "socket() failed: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >= ((_level) & 0x07)) ? log_internal_realm(((_realm) << 10 | (_level)), _e, "../src/journal/journald-stream.c", 794, __func__, "socket() failed: %m") : -abs(_e); }); |
795 | |
796 | (void) unlink(sa.un.sun_path); |
797 | |
798 | r = bind(s->stdout_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)({ const struct sockaddr_un *_sa = &(sa.un); do { if ((__builtin_expect (!!(!(_sa->sun_family == 1)),0))) log_assert_failed_realm( LOG_REALM_SYSTEMD, ("_sa->sun_family == AF_UNIX"), "../src/journal/journald-stream.c" , 798, __PRETTY_FUNCTION__); } while (0); __builtin_offsetof( struct sockaddr_un, sun_path) + (_sa->sun_path[0] == 0 ? 1 + strnlen(_sa->sun_path+1, sizeof(_sa->sun_path)-1) : strnlen (_sa->sun_path, sizeof(_sa->sun_path))); })); |
799 | if (r < 0) |
800 | return log_error_errno(errno, "bind(%s) failed: %m", sa.un.sun_path)({ int _level = ((3)), _e = (((*__errno_location ()))), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >= ((_level) & 0x07)) ? log_internal_realm(((_realm) << 10 | (_level)), _e, "../src/journal/journald-stream.c", 800, __func__, "bind(%s) failed: %m", sa.un.sun_path) : -abs(_e); }); |
801 | |
802 | (void) chmod(sa.un.sun_path, 0666); |
803 | |
804 | if (listen(s->stdout_fd, SOMAXCONN4096) < 0) |
805 | return log_error_errno(errno, "listen(%s) failed: %m", sa.un.sun_path)({ int _level = ((3)), _e = (((*__errno_location ()))), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >= ((_level) & 0x07)) ? log_internal_realm(((_realm) << 10 | (_level)), _e, "../src/journal/journald-stream.c", 805, __func__, "listen(%s) failed: %m", sa.un.sun_path) : -abs(_e ); }); |
806 | } else |
807 | fd_nonblock(s->stdout_fd, 1); |
808 | |
809 | r = sd_event_add_io(s->event, &s->stdout_event_source, s->stdout_fd, EPOLLINEPOLLIN, stdout_stream_new, s); |
810 | if (r < 0) |
811 | return log_error_errno(r, "Failed to add stdout server fd to event source: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal/journald-stream.c", 811, __func__, "Failed to add stdout server fd to event source: %m" ) : -abs(_e); }); |
812 | |
813 | r = sd_event_source_set_priority(s->stdout_event_source, SD_EVENT_PRIORITY_NORMAL+5); |
814 | if (r < 0) |
815 | return log_error_errno(r, "Failed to adjust priority of stdout server event source: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal/journald-stream.c", 815, __func__, "Failed to adjust priority of stdout server event source: %m" ) : -abs(_e); }); |
816 | |
817 | return 0; |
818 | } |
819 | |
820 | void stdout_stream_send_notify(StdoutStream *s) { |
821 | struct iovec iovec = { |
822 | .iov_base = (char*) "FDSTORE=1", |
823 | .iov_len = STRLEN("FDSTORE=1")(sizeof("""FDSTORE=1""") - 1), |
824 | }; |
825 | struct msghdr msghdr = { |
826 | .msg_iov = &iovec, |
827 | .msg_iovlen = 1, |
828 | }; |
829 | struct cmsghdr *cmsg; |
830 | ssize_t l; |
831 | |
832 | assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("s"), "../src/journal/journald-stream.c" , 832, __PRETTY_FUNCTION__); } while (0); |
833 | assert(!s->fdstore)do { if ((__builtin_expect(!!(!(!s->fdstore)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("!s->fdstore"), "../src/journal/journald-stream.c" , 833, __PRETTY_FUNCTION__); } while (0); |
834 | assert(s->in_notify_queue)do { if ((__builtin_expect(!!(!(s->in_notify_queue)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("s->in_notify_queue"), "../src/journal/journald-stream.c" , 834, __PRETTY_FUNCTION__); } while (0); |
835 | assert(s->server)do { if ((__builtin_expect(!!(!(s->server)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("s->server"), "../src/journal/journald-stream.c" , 835, __PRETTY_FUNCTION__); } while (0); |
836 | assert(s->server->notify_fd >= 0)do { if ((__builtin_expect(!!(!(s->server->notify_fd >= 0)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("s->server->notify_fd >= 0" ), "../src/journal/journald-stream.c", 836, __PRETTY_FUNCTION__ ); } while (0); |
837 | |
838 | /* Store the connection fd in PID 1, so that we get it passed |
839 | * in again on next start */ |
840 | |
841 | msghdr.msg_controllen = CMSG_SPACE(sizeof(int))((((sizeof(int)) + sizeof (size_t) - 1) & (size_t) ~(sizeof (size_t) - 1)) + (((sizeof (struct cmsghdr)) + sizeof (size_t ) - 1) & (size_t) ~(sizeof (size_t) - 1))); |
842 | msghdr.msg_control = alloca0(msghdr.msg_controllen)({ char *_new_; size_t _len_ = msghdr.msg_controllen; _new_ = __builtin_alloca (_len_); (void *) memset(_new_, 0, _len_); } ); |
843 | |
844 | cmsg = CMSG_FIRSTHDR(&msghdr)((size_t) (&msghdr)->msg_controllen >= sizeof (struct cmsghdr) ? (struct cmsghdr *) (&msghdr)->msg_control : (struct cmsghdr *) 0); |
845 | cmsg->cmsg_level = SOL_SOCKET1; |
846 | cmsg->cmsg_type = SCM_RIGHTSSCM_RIGHTS; |
847 | cmsg->cmsg_len = CMSG_LEN(sizeof(int))((((sizeof (struct cmsghdr)) + sizeof (size_t) - 1) & (size_t ) ~(sizeof (size_t) - 1)) + (sizeof(int))); |
848 | |
849 | memcpy(CMSG_DATA(cmsg)((cmsg)->__cmsg_data), &s->fd, sizeof(int)); |
850 | |
851 | l = sendmsg(s->server->notify_fd, &msghdr, MSG_DONTWAITMSG_DONTWAIT|MSG_NOSIGNALMSG_NOSIGNAL); |
852 | if (l < 0) { |
853 | if (errno(*__errno_location ()) == EAGAIN11) |
854 | return; |
855 | |
856 | log_error_errno(errno, "Failed to send stream file descriptor to service manager: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >= ((_level) & 0x07)) ? log_internal_realm(((_realm) << 10 | (_level)), _e, "../src/journal/journald-stream.c", 856, __func__, "Failed to send stream file descriptor to service manager: %m" ) : -abs(_e); }); |
857 | } else { |
858 | log_debug("Successfully sent stream file descriptor to service manager.")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal/journald-stream.c", 858, __func__, "Successfully sent stream file descriptor to service manager." ) : -abs(_e); }); |
859 | s->fdstore = 1; |
860 | } |
861 | |
862 | LIST_REMOVE(stdout_stream_notify_queue, s->server->stdout_streams_notify_queue, s)do { typeof(*(s->server->stdout_streams_notify_queue)) * *_head = &(s->server->stdout_streams_notify_queue), *_item = (s); do { if ((__builtin_expect(!!(!(_item)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("_item"), "../src/journal/journald-stream.c" , 862, __PRETTY_FUNCTION__); } while (0); if (_item->stdout_stream_notify_queue_next ) _item->stdout_stream_notify_queue_next->stdout_stream_notify_queue_prev = _item->stdout_stream_notify_queue_prev; if (_item->stdout_stream_notify_queue_prev ) _item->stdout_stream_notify_queue_prev->stdout_stream_notify_queue_next = _item->stdout_stream_notify_queue_next; else { do { if ( (__builtin_expect(!!(!(*_head == _item)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("*_head == _item"), "../src/journal/journald-stream.c" , 862, __PRETTY_FUNCTION__); } while (0); *_head = _item-> stdout_stream_notify_queue_next; } _item->stdout_stream_notify_queue_next = _item->stdout_stream_notify_queue_prev = ((void*)0); } while (0); |
863 | s->in_notify_queue = false0; |
864 | |
865 | } |