]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/journal/journald.c
journal: hook up coredumping with journal
[thirdparty/systemd.git] / src / journal / journald.c
CommitLineData
87d2c1ff
LP
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 General Public License as published by
10 the Free Software Foundation; either version 2 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 General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
22#include <sys/epoll.h>
23#include <sys/socket.h>
24#include <errno.h>
25#include <sys/signalfd.h>
26#include <unistd.h>
27#include <fcntl.h>
7f3e6257
LP
28#include <stddef.h>
29#include <sys/ioctl.h>
30#include <linux/sockios.h>
6e409ce1 31#include <sys/statvfs.h>
87d2c1ff 32
81527be1
LP
33#include <systemd/sd-journal.h>
34#include <systemd/sd-login.h>
35#include <systemd/sd-messages.h>
36#include <systemd/sd-daemon.h>
37
87d2c1ff 38#include "hashmap.h"
cec736d2 39#include "journal-file.h"
87d2c1ff 40#include "socket-util.h"
69e5d42d 41#include "cgroup-util.h"
fe652127 42#include "list.h"
6e409ce1 43#include "journal-rate-limit.h"
cf244689 44#include "journal-internal.h"
e6960940
LP
45#include "conf-parser.h"
46#include "journald.h"
effb1102 47#include "virt.h"
87d2c1ff 48
e6520a0f
LP
49#ifdef HAVE_ACL
50#include <sys/acl.h>
51#include <acl/libacl.h>
52#include "acl-util.h"
53#endif
54
8a0f04e6
LP
55#ifdef HAVE_SELINUX
56#include <selinux/selinux.h>
57#endif
58
cab8ac60 59#define USER_JOURNALS_MAX 1024
fe652127
LP
60#define STDOUT_STREAMS_MAX 4096
61
de97b26a
LP
62#define DEFAULT_RATE_LIMIT_INTERVAL (10*USEC_PER_SEC)
63#define DEFAULT_RATE_LIMIT_BURST 200
64
9cfb57c9
LP
65#define RECHECK_AVAILABLE_SPACE_USEC (30*USEC_PER_SEC)
66
54a7b863
LP
67#define RECHECK_VAR_AVAILABLE_USEC (30*USEC_PER_SEC)
68
98736c68 69#define SYSLOG_TIMEOUT_USEC (250*USEC_PER_MSEC)
8b18eb67 70
8a0f04e6 71#define N_IOVEC_META_FIELDS 17
224f2ee2 72
fe652127 73typedef enum StdoutStreamState {
4cd9a9d9 74 STDOUT_STREAM_IDENTIFIER,
fe652127 75 STDOUT_STREAM_PRIORITY,
258cdffc 76 STDOUT_STREAM_LEVEL_PREFIX,
224f2ee2
LP
77 STDOUT_STREAM_FORWARD_TO_SYSLOG,
78 STDOUT_STREAM_FORWARD_TO_KMSG,
79 STDOUT_STREAM_FORWARD_TO_CONSOLE,
fe652127
LP
80 STDOUT_STREAM_RUNNING
81} StdoutStreamState;
82
83struct StdoutStream {
84 Server *server;
85 StdoutStreamState state;
86
87 int fd;
88
89 struct ucred ucred;
90
4cd9a9d9 91 char *identifier;
fe652127 92 int priority;
258cdffc 93 bool level_prefix:1;
224f2ee2
LP
94 bool forward_to_syslog:1;
95 bool forward_to_kmsg:1;
96 bool forward_to_console:1;
fe652127
LP
97
98 char buffer[LINE_MAX+1];
99 size_t length;
100
101 LIST_FIELDS(StdoutStream, stdout_stream);
102};
103
cf244689
LP
104static int server_flush_to_var(Server *s);
105
6e409ce1 106static uint64_t available_space(Server *s) {
babfc091 107 char ids[33], *p;
6e409ce1 108 const char *f;
babfc091 109 sd_id128_t machine;
6e409ce1
LP
110 struct statvfs ss;
111 uint64_t sum = 0, avail = 0, ss_avail = 0;
112 int r;
113 DIR *d;
babfc091
LP
114 usec_t ts;
115 JournalMetrics *m;
116
117 ts = now(CLOCK_MONOTONIC);
9cfb57c9
LP
118
119 if (s->cached_available_space_timestamp + RECHECK_AVAILABLE_SPACE_USEC > ts)
120 return s->cached_available_space;
6e409ce1
LP
121
122 r = sd_id128_get_machine(&machine);
123 if (r < 0)
124 return 0;
125
babfc091 126 if (s->system_journal) {
6e409ce1 127 f = "/var/log/journal/";
babfc091
LP
128 m = &s->system_metrics;
129 } else {
6e409ce1 130 f = "/run/log/journal/";
babfc091
LP
131 m = &s->runtime_metrics;
132 }
133
134 assert(m);
6e409ce1
LP
135
136 p = strappend(f, sd_id128_to_string(machine, ids));
137 if (!p)
138 return 0;
139
140 d = opendir(p);
141 free(p);
142
143 if (!d)
144 return 0;
145
146 if (fstatvfs(dirfd(d), &ss) < 0)
147 goto finish;
148
149 for (;;) {
150 struct stat st;
151 struct dirent buf, *de;
152 int k;
153
154 k = readdir_r(d, &buf, &de);
155 if (k != 0) {
156 r = -k;
157 goto finish;
158 }
159
160 if (!de)
161 break;
162
163 if (!dirent_is_file_with_suffix(de, ".journal"))
164 continue;
165
166 if (fstatat(dirfd(d), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0)
167 continue;
168
169 sum += (uint64_t) st.st_blocks * (uint64_t) st.st_blksize;
170 }
171
babfc091 172 avail = sum >= m->max_use ? 0 : m->max_use - sum;
6e409ce1
LP
173
174 ss_avail = ss.f_bsize * ss.f_bavail;
175
babfc091 176 ss_avail = ss_avail < m->keep_free ? 0 : ss_avail - m->keep_free;
6e409ce1
LP
177
178 if (ss_avail < avail)
179 avail = ss_avail;
180
9cfb57c9
LP
181 s->cached_available_space = avail;
182 s->cached_available_space_timestamp = ts;
183
6e409ce1
LP
184finish:
185 closedir(d);
186
187 return avail;
188}
189
5e41cfec
LP
190static void server_read_file_gid(Server *s) {
191 const char *adm = "adm";
192 int r;
193
194 assert(s);
195
196 if (s->file_gid_valid)
197 return;
198
199 r = get_group_creds(&adm, &s->file_gid);
200 if (r < 0)
201 log_warning("Failed to resolve 'adm' group: %s", strerror(-r));
202
203 /* if we couldn't read the gid, then it will be 0, but that's
204 * fine and we shouldn't try to resolve the group again, so
205 * let's just pretend it worked right-away. */
206 s->file_gid_valid = true;
207}
208
209static void server_fix_perms(Server *s, JournalFile *f, uid_t uid) {
e6520a0f
LP
210 int r;
211#ifdef HAVE_ACL
f4b47811
LP
212 acl_t acl;
213 acl_entry_t entry;
214 acl_permset_t permset;
e6520a0f 215#endif
f4b47811
LP
216
217 assert(f);
218
5e41cfec
LP
219 server_read_file_gid(s);
220
221 r = fchmod_and_fchown(f->fd, 0640, 0, s->file_gid);
f4b47811
LP
222 if (r < 0)
223 log_warning("Failed to fix access mode/rights on %s, ignoring: %s", f->path, strerror(-r));
224
e6520a0f 225#ifdef HAVE_ACL
f4b47811
LP
226 if (uid <= 0)
227 return;
228
229 acl = acl_get_fd(f->fd);
230 if (!acl) {
231 log_warning("Failed to read ACL on %s, ignoring: %m", f->path);
232 return;
233 }
234
235 r = acl_find_uid(acl, uid, &entry);
236 if (r <= 0) {
237
238 if (acl_create_entry(&acl, &entry) < 0 ||
239 acl_set_tag_type(entry, ACL_USER) < 0 ||
240 acl_set_qualifier(entry, &uid) < 0) {
241 log_warning("Failed to patch ACL on %s, ignoring: %m", f->path);
242 goto finish;
243 }
244 }
245
246 if (acl_get_permset(entry, &permset) < 0 ||
247 acl_add_perm(permset, ACL_READ) < 0 ||
248 acl_calc_mask(&acl) < 0) {
249 log_warning("Failed to patch ACL on %s, ignoring: %m", f->path);
250 goto finish;
251 }
252
253 if (acl_set_fd(f->fd, acl) < 0)
254 log_warning("Failed to set ACL on %s, ignoring: %m", f->path);
255
256finish:
257 acl_free(acl);
e6520a0f 258#endif
f4b47811
LP
259}
260
261static JournalFile* find_journal(Server *s, uid_t uid) {
262 char *p;
263 int r;
264 JournalFile *f;
3fbf9cbb
LP
265 char ids[33];
266 sd_id128_t machine;
f4b47811
LP
267
268 assert(s);
269
cf244689
LP
270 /* We split up user logs only on /var, not on /run. If the
271 * runtime file is open, we write to it exclusively, in order
272 * to guarantee proper order as soon as we flush /run to
273 * /var and close the runtime file. */
274
275 if (s->runtime_journal)
f4b47811
LP
276 return s->runtime_journal;
277
278 if (uid <= 0)
279 return s->system_journal;
280
3fbf9cbb
LP
281 r = sd_id128_get_machine(&machine);
282 if (r < 0)
283 return s->system_journal;
284
f4b47811
LP
285 f = hashmap_get(s->user_journals, UINT32_TO_PTR(uid));
286 if (f)
287 return f;
288
3fbf9cbb 289 if (asprintf(&p, "/var/log/journal/%s/user-%lu.journal", sd_id128_to_string(machine, ids), (unsigned long) uid) < 0)
f4b47811
LP
290 return s->system_journal;
291
cab8ac60
LP
292 while (hashmap_size(s->user_journals) >= USER_JOURNALS_MAX) {
293 /* Too many open? Then let's close one */
294 f = hashmap_steal_first(s->user_journals);
295 assert(f);
296 journal_file_close(f);
297 }
298
c2373f84 299 r = journal_file_open(p, O_RDWR|O_CREAT, 0640, s->system_journal, &f);
f4b47811
LP
300 free(p);
301
302 if (r < 0)
303 return s->system_journal;
304
5e41cfec 305 server_fix_perms(s, f, uid);
babfc091 306 f->metrics = s->system_metrics;
807e17f0 307 f->compress = s->compress;
f4b47811
LP
308
309 r = hashmap_put(s->user_journals, UINT32_TO_PTR(uid), f);
310 if (r < 0) {
311 journal_file_close(f);
312 return s->system_journal;
313 }
314
315 return f;
316}
317
b1a0ab71
LP
318static void server_rotate(Server *s) {
319 JournalFile *f;
bc85bfee 320 void *k;
b1a0ab71 321 Iterator i;
bc85bfee 322 int r;
bc85bfee
LP
323
324 log_info("Rotating...");
325
326 if (s->runtime_journal) {
327 r = journal_file_rotate(&s->runtime_journal);
328 if (r < 0)
329 log_error("Failed to rotate %s: %s", s->runtime_journal->path, strerror(-r));
330 }
331
332 if (s->system_journal) {
333 r = journal_file_rotate(&s->system_journal);
334 if (r < 0)
335 log_error("Failed to rotate %s: %s", s->system_journal->path, strerror(-r));
336 }
337
338 HASHMAP_FOREACH_KEY(f, k, s->user_journals, i) {
339 r = journal_file_rotate(&f);
340 if (r < 0)
341 log_error("Failed to rotate %s: %s", f->path, strerror(-r));
342 else
343 hashmap_replace(s->user_journals, k, f);
344 }
b1a0ab71
LP
345}
346
347static void server_vacuum(Server *s) {
348 char *p;
349 char ids[33];
350 sd_id128_t machine;
351 int r;
bc85bfee
LP
352
353 log_info("Vacuuming...");
354
355 r = sd_id128_get_machine(&machine);
356 if (r < 0) {
357 log_error("Failed to get machine ID: %s", strerror(-r));
358 return;
359 }
360
babfc091 361 sd_id128_to_string(machine, ids);
bc85bfee 362
babfc091
LP
363 if (s->system_journal) {
364 if (asprintf(&p, "/var/log/journal/%s", ids) < 0) {
365 log_error("Out of memory.");
366 return;
367 }
bc85bfee 368
babfc091
LP
369 r = journal_directory_vacuum(p, s->system_metrics.max_use, s->system_metrics.keep_free);
370 if (r < 0 && r != -ENOENT)
371 log_error("Failed to vacuum %s: %s", p, strerror(-r));
372 free(p);
bc85bfee
LP
373 }
374
babfc091
LP
375
376 if (s->runtime_journal) {
377 if (asprintf(&p, "/run/log/journal/%s", ids) < 0) {
378 log_error("Out of memory.");
379 return;
380 }
381
382 r = journal_directory_vacuum(p, s->runtime_metrics.max_use, s->runtime_metrics.keep_free);
383 if (r < 0 && r != -ENOENT)
384 log_error("Failed to vacuum %s: %s", p, strerror(-r));
385 free(p);
386 }
9cfb57c9
LP
387
388 s->cached_available_space_timestamp = 0;
bc85bfee
LP
389}
390
6e409ce1
LP
391static char *shortened_cgroup_path(pid_t pid) {
392 int r;
393 char *process_path, *init_path, *path;
394
395 assert(pid > 0);
396
397 r = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, pid, &process_path);
398 if (r < 0)
399 return NULL;
400
401 r = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, 1, &init_path);
402 if (r < 0) {
403 free(process_path);
404 return NULL;
405 }
406
bad75c27
LP
407 if (endswith(init_path, "/system"))
408 init_path[strlen(init_path) - 7] = 0;
409 else if (streq(init_path, "/"))
6e409ce1
LP
410 init_path[0] = 0;
411
783d2675
LP
412 if (startswith(process_path, init_path)) {
413 char *p;
414
415 p = strdup(process_path + strlen(init_path));
416 if (!p) {
417 free(process_path);
418 free(init_path);
419 return NULL;
420 }
421 path = p;
422 } else {
6e409ce1 423 path = process_path;
783d2675
LP
424 process_path = NULL;
425 }
6e409ce1 426
783d2675 427 free(process_path);
6e409ce1
LP
428 free(init_path);
429
430 return path;
431}
432
433static void dispatch_message_real(Server *s,
434 struct iovec *iovec, unsigned n, unsigned m,
435 struct ucred *ucred,
436 struct timeval *tv) {
437
7f3e6257 438 char *pid = NULL, *uid = NULL, *gid = NULL,
87d2c1ff
LP
439 *source_time = NULL, *boot_id = NULL, *machine_id = NULL,
440 *comm = NULL, *cmdline = NULL, *hostname = NULL,
441 *audit_session = NULL, *audit_loginuid = NULL,
85d83bf4 442 *exe = NULL, *cgroup = NULL, *session = NULL,
8a0f04e6 443 *owner_uid = NULL, *unit = NULL, *selinux_context = NULL;
7f3e6257 444
87d2c1ff
LP
445 char idbuf[33];
446 sd_id128_t id;
447 int r;
448 char *t;
de190aef 449 uid_t loginuid = 0, realuid = 0;
f4b47811 450 JournalFile *f;
bc85bfee 451 bool vacuumed = false;
87d2c1ff 452
7f3e6257 453 assert(s);
6e409ce1
LP
454 assert(iovec);
455 assert(n > 0);
224f2ee2 456 assert(n + N_IOVEC_META_FIELDS <= m);
87d2c1ff
LP
457
458 if (ucred) {
85d83bf4
LP
459 uint32_t audit;
460 uid_t owner;
8a0f04e6
LP
461#ifdef HAVE_SELINUX
462 security_context_t con;
463#endif
87d2c1ff 464
de190aef
LP
465 realuid = ucred->uid;
466
467 if (asprintf(&pid, "_PID=%lu", (unsigned long) ucred->pid) >= 0)
87d2c1ff
LP
468 IOVEC_SET_STRING(iovec[n++], pid);
469
de190aef 470 if (asprintf(&uid, "_UID=%lu", (unsigned long) ucred->uid) >= 0)
87d2c1ff
LP
471 IOVEC_SET_STRING(iovec[n++], uid);
472
de190aef 473 if (asprintf(&gid, "_GID=%lu", (unsigned long) ucred->gid) >= 0)
87d2c1ff
LP
474 IOVEC_SET_STRING(iovec[n++], gid);
475
476 r = get_process_comm(ucred->pid, &t);
477 if (r >= 0) {
de190aef 478 comm = strappend("_COMM=", t);
85d83bf4
LP
479 free(t);
480
87d2c1ff
LP
481 if (comm)
482 IOVEC_SET_STRING(iovec[n++], comm);
87d2c1ff
LP
483 }
484
485 r = get_process_exe(ucred->pid, &t);
486 if (r >= 0) {
de190aef 487 exe = strappend("_EXE=", t);
85d83bf4
LP
488 free(t);
489
87d2c1ff
LP
490 if (comm)
491 IOVEC_SET_STRING(iovec[n++], exe);
87d2c1ff
LP
492 }
493
494 r = get_process_cmdline(ucred->pid, LINE_MAX, false, &t);
495 if (r >= 0) {
de190aef 496 cmdline = strappend("_CMDLINE=", t);
85d83bf4
LP
497 free(t);
498
87d2c1ff
LP
499 if (cmdline)
500 IOVEC_SET_STRING(iovec[n++], cmdline);
87d2c1ff
LP
501 }
502
85d83bf4 503 r = audit_session_from_pid(ucred->pid, &audit);
87d2c1ff 504 if (r >= 0)
85d83bf4 505 if (asprintf(&audit_session, "_AUDIT_SESSION=%lu", (unsigned long) audit) >= 0)
87d2c1ff
LP
506 IOVEC_SET_STRING(iovec[n++], audit_session);
507
508 r = audit_loginuid_from_pid(ucred->pid, &loginuid);
509 if (r >= 0)
de190aef 510 if (asprintf(&audit_loginuid, "_AUDIT_LOGINUID=%lu", (unsigned long) loginuid) >= 0)
87d2c1ff 511 IOVEC_SET_STRING(iovec[n++], audit_loginuid);
69e5d42d 512
85d83bf4
LP
513 t = shortened_cgroup_path(ucred->pid);
514 if (t) {
515 cgroup = strappend("_SYSTEMD_CGROUP=", t);
516 free(t);
517
69e5d42d
LP
518 if (cgroup)
519 IOVEC_SET_STRING(iovec[n++], cgroup);
85d83bf4
LP
520 }
521
522 if (sd_pid_get_session(ucred->pid, &t) >= 0) {
523 session = strappend("_SYSTEMD_SESSION=", t);
524 free(t);
525
526 if (session)
527 IOVEC_SET_STRING(iovec[n++], session);
528 }
6e409ce1 529
94fb446e
LP
530 if (sd_pid_get_unit(ucred->pid, &t) >= 0) {
531 unit = strappend("_SYSTEMD_UNIT=", t);
85d83bf4
LP
532 free(t);
533
94fb446e
LP
534 if (unit)
535 IOVEC_SET_STRING(iovec[n++], unit);
69e5d42d 536 }
85d83bf4
LP
537
538 if (sd_pid_get_owner_uid(ucred->uid, &owner) >= 0)
539 if (asprintf(&owner_uid, "_SYSTEMD_OWNER_UID=%lu", (unsigned long) owner) >= 0)
540 IOVEC_SET_STRING(iovec[n++], owner_uid);
8a0f04e6
LP
541
542#ifdef HAVE_SELINUX
543 if (getpidcon(ucred->pid, &con) >= 0) {
544 selinux_context = strappend("_SELINUX_CONTEXT=", con);
545 if (selinux_context)
546 IOVEC_SET_STRING(iovec[n++], selinux_context);
547
548 freecon(con);
549 }
550#endif
87d2c1ff
LP
551 }
552
553 if (tv) {
de190aef 554 if (asprintf(&source_time, "_SOURCE_REALTIME_TIMESTAMP=%llu",
87d2c1ff
LP
555 (unsigned long long) timeval_load(tv)) >= 0)
556 IOVEC_SET_STRING(iovec[n++], source_time);
557 }
558
ed49ef3f
LP
559 /* Note that strictly speaking storing the boot id here is
560 * redundant since the entry includes this in-line
561 * anyway. However, we need this indexed, too. */
87d2c1ff
LP
562 r = sd_id128_get_boot(&id);
563 if (r >= 0)
de190aef 564 if (asprintf(&boot_id, "_BOOT_ID=%s", sd_id128_to_string(id, idbuf)) >= 0)
87d2c1ff
LP
565 IOVEC_SET_STRING(iovec[n++], boot_id);
566
567 r = sd_id128_get_machine(&id);
568 if (r >= 0)
de190aef 569 if (asprintf(&machine_id, "_MACHINE_ID=%s", sd_id128_to_string(id, idbuf)) >= 0)
87d2c1ff
LP
570 IOVEC_SET_STRING(iovec[n++], machine_id);
571
572 t = gethostname_malloc();
573 if (t) {
de190aef 574 hostname = strappend("_HOSTNAME=", t);
85d83bf4 575 free(t);
87d2c1ff
LP
576 if (hostname)
577 IOVEC_SET_STRING(iovec[n++], hostname);
87d2c1ff
LP
578 }
579
7f3e6257
LP
580 assert(n <= m);
581
cf244689
LP
582 server_flush_to_var(s);
583
bc85bfee 584retry:
de190aef 585 f = find_journal(s, realuid == 0 ? 0 : loginuid);
f4b47811
LP
586 if (!f)
587 log_warning("Dropping message, as we can't find a place to store the data.");
588 else {
c2373f84 589 r = journal_file_append_entry(f, NULL, iovec, n, &s->seqnum, NULL, NULL);
87d2c1ff 590
bc85bfee
LP
591 if (r == -E2BIG && !vacuumed) {
592 log_info("Allocation limit reached.");
593
b1a0ab71 594 server_rotate(s);
bc85bfee
LP
595 server_vacuum(s);
596 vacuumed = true;
597
598 log_info("Retrying write.");
599 goto retry;
600 }
601
f4b47811
LP
602 if (r < 0)
603 log_error("Failed to write entry, ignoring: %s", strerror(-r));
604 }
87d2c1ff 605
87d2c1ff
LP
606 free(pid);
607 free(uid);
608 free(gid);
609 free(comm);
69e5d42d 610 free(exe);
87d2c1ff
LP
611 free(cmdline);
612 free(source_time);
613 free(boot_id);
614 free(machine_id);
615 free(hostname);
616 free(audit_session);
617 free(audit_loginuid);
7f3e6257 618 free(cgroup);
85d83bf4
LP
619 free(session);
620 free(owner_uid);
94fb446e 621 free(unit);
8a0f04e6 622 free(selinux_context);
7f3e6257
LP
623}
624
224f2ee2
LP
625static void driver_message(Server *s, sd_id128_t message_id, const char *format, ...) {
626 char mid[11 + 32 + 1];
627 char buffer[16 + LINE_MAX + 1];
33eb8abf 628 struct iovec iovec[N_IOVEC_META_FIELDS + 4];
224f2ee2
LP
629 int n = 0;
630 va_list ap;
631 struct ucred ucred;
632
633 assert(s);
634 assert(format);
635
636 IOVEC_SET_STRING(iovec[n++], "PRIORITY=5");
33eb8abf 637 IOVEC_SET_STRING(iovec[n++], "_TRANSPORT=driver");
224f2ee2
LP
638
639 memcpy(buffer, "MESSAGE=", 8);
640 va_start(ap, format);
641 vsnprintf(buffer + 8, sizeof(buffer) - 8, format, ap);
642 va_end(ap);
643 char_array_0(buffer);
644 IOVEC_SET_STRING(iovec[n++], buffer);
645
646 snprintf(mid, sizeof(mid), "MESSAGE_ID=" SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(message_id));
647 char_array_0(mid);
648 IOVEC_SET_STRING(iovec[n++], mid);
649
650 zero(ucred);
651 ucred.pid = getpid();
652 ucred.uid = getuid();
653 ucred.gid = getgid();
654
655 dispatch_message_real(s, iovec, n, ELEMENTSOF(iovec), &ucred, NULL);
656}
657
6e409ce1
LP
658static void dispatch_message(Server *s,
659 struct iovec *iovec, unsigned n, unsigned m,
660 struct ucred *ucred,
661 struct timeval *tv,
662 int priority) {
663 int rl;
783d2675 664 char *path = NULL, *c;
6e409ce1
LP
665
666 assert(s);
667 assert(iovec || n == 0);
668
669 if (n == 0)
670 return;
671
672 if (!ucred)
673 goto finish;
674
675 path = shortened_cgroup_path(ucred->pid);
676 if (!path)
677 goto finish;
678
679 /* example: /user/lennart/3/foobar
680 * /system/dbus.service/foobar
681 *
682 * So let's cut of everything past the third /, since that is
683 * wher user directories start */
684
685 c = strchr(path, '/');
686 if (c) {
687 c = strchr(c+1, '/');
688 if (c) {
689 c = strchr(c+1, '/');
690 if (c)
691 *c = 0;
692 }
693 }
694
224f2ee2 695 rl = journal_rate_limit_test(s->rate_limit, path, priority & LOG_PRIMASK, available_space(s));
6e409ce1
LP
696
697 if (rl == 0) {
698 free(path);
699 return;
700 }
701
224f2ee2
LP
702 /* Write a suppression message if we suppressed something */
703 if (rl > 1)
704 driver_message(s, SD_MESSAGE_JOURNAL_DROPPED, "Suppressed %u messages from %s", rl - 1, path);
705
706 free(path);
707
708finish:
709 dispatch_message_real(s, iovec, n, m, ucred, tv);
710}
711
712static void forward_syslog_iovec(Server *s, const struct iovec *iovec, unsigned n_iovec, struct ucred *ucred, struct timeval *tv) {
713 struct msghdr msghdr;
714 struct cmsghdr *cmsg;
715 union {
716 struct cmsghdr cmsghdr;
717 uint8_t buf[CMSG_SPACE(sizeof(struct ucred))];
718 } control;
719 union sockaddr_union sa;
720
721 assert(s);
722 assert(iovec);
723 assert(n_iovec > 0);
724
725 zero(msghdr);
726 msghdr.msg_iov = (struct iovec*) iovec;
727 msghdr.msg_iovlen = n_iovec;
728
729 zero(sa);
730 sa.un.sun_family = AF_UNIX;
259d2e76 731 strncpy(sa.un.sun_path, "/run/systemd/journal/syslog", sizeof(sa.un.sun_path));
224f2ee2
LP
732 msghdr.msg_name = &sa;
733 msghdr.msg_namelen = offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path);
734
735 if (ucred) {
736 zero(control);
737 msghdr.msg_control = &control;
738 msghdr.msg_controllen = sizeof(control);
739
740 cmsg = CMSG_FIRSTHDR(&msghdr);
741 cmsg->cmsg_level = SOL_SOCKET;
742 cmsg->cmsg_type = SCM_CREDENTIALS;
743 cmsg->cmsg_len = CMSG_LEN(sizeof(struct ucred));
744 memcpy(CMSG_DATA(cmsg), ucred, sizeof(struct ucred));
745 msghdr.msg_controllen = cmsg->cmsg_len;
746 }
747
748 /* Forward the syslog message we received via /dev/log to
749 * /run/systemd/syslog. Unfortunately we currently can't set
750 * the SO_TIMESTAMP auxiliary data, and hence we don't. */
6e409ce1 751
224f2ee2
LP
752 if (sendmsg(s->syslog_fd, &msghdr, MSG_NOSIGNAL) >= 0)
753 return;
6e409ce1 754
7c8bbccd
LP
755 /* The socket is full? I guess the syslog implementation is
756 * too slow, and we shouldn't wait for that... */
757 if (errno == EAGAIN)
758 return;
759
224f2ee2
LP
760 if (ucred && errno == ESRCH) {
761 struct ucred u;
6e409ce1 762
224f2ee2
LP
763 /* Hmm, presumably the sender process vanished
764 * by now, so let's fix it as good as we
765 * can, and retry */
6e409ce1 766
224f2ee2
LP
767 u = *ucred;
768 u.pid = getpid();
769 memcpy(CMSG_DATA(cmsg), &u, sizeof(struct ucred));
770
771 if (sendmsg(s->syslog_fd, &msghdr, MSG_NOSIGNAL) >= 0)
772 return;
7c8bbccd
LP
773
774 if (errno == EAGAIN)
775 return;
6e409ce1
LP
776 }
777
224f2ee2
LP
778 log_debug("Failed to forward syslog message: %m");
779}
780
781static void forward_syslog_raw(Server *s, const char *buffer, struct ucred *ucred, struct timeval *tv) {
782 struct iovec iovec;
783
784 assert(s);
785 assert(buffer);
786
787 IOVEC_SET_STRING(iovec, buffer);
788 forward_syslog_iovec(s, &iovec, 1, ucred, tv);
789}
790
4cd9a9d9 791static void forward_syslog(Server *s, int priority, const char *identifier, const char *message, struct ucred *ucred, struct timeval *tv) {
224f2ee2
LP
792 struct iovec iovec[5];
793 char header_priority[6], header_time[64], header_pid[16];
794 int n = 0;
795 time_t t;
796 struct tm *tm;
4cd9a9d9 797 char *ident_buf = NULL;
224f2ee2
LP
798
799 assert(s);
800 assert(priority >= 0);
801 assert(priority <= 999);
802 assert(message);
803
804 /* First: priority field */
805 snprintf(header_priority, sizeof(header_priority), "<%i>", priority);
806 char_array_0(header_priority);
807 IOVEC_SET_STRING(iovec[n++], header_priority);
808
809 /* Second: timestamp */
810 t = tv ? tv->tv_sec : ((time_t) (now(CLOCK_REALTIME) / USEC_PER_SEC));
811 tm = localtime(&t);
812 if (!tm)
813 return;
814 if (strftime(header_time, sizeof(header_time), "%h %e %T ", tm) <= 0)
815 return;
816 IOVEC_SET_STRING(iovec[n++], header_time);
817
4cd9a9d9 818 /* Third: identifier and PID */
224f2ee2 819 if (ucred) {
4cd9a9d9
LP
820 if (!identifier) {
821 get_process_comm(ucred->pid, &ident_buf);
822 identifier = ident_buf;
224f2ee2
LP
823 }
824
825 snprintf(header_pid, sizeof(header_pid), "[%lu]: ", (unsigned long) ucred->pid);
826 char_array_0(header_pid);
827
4cd9a9d9
LP
828 if (identifier)
829 IOVEC_SET_STRING(iovec[n++], identifier);
224f2ee2
LP
830
831 IOVEC_SET_STRING(iovec[n++], header_pid);
4cd9a9d9
LP
832 } else if (identifier) {
833 IOVEC_SET_STRING(iovec[n++], identifier);
224f2ee2
LP
834 IOVEC_SET_STRING(iovec[n++], ": ");
835 }
836
837 /* Fourth: message */
838 IOVEC_SET_STRING(iovec[n++], message);
839
840 forward_syslog_iovec(s, iovec, n, ucred, tv);
841
4cd9a9d9 842 free(ident_buf);
224f2ee2
LP
843}
844
845static int fixup_priority(int priority) {
846
847 if ((priority & LOG_FACMASK) == 0)
848 return (priority & LOG_PRIMASK) | LOG_USER;
849
850 return priority;
851}
852
4cd9a9d9 853static void forward_kmsg(Server *s, int priority, const char *identifier, const char *message, struct ucred *ucred) {
224f2ee2
LP
854 struct iovec iovec[5];
855 char header_priority[6], header_pid[16];
856 int n = 0;
4cd9a9d9 857 char *ident_buf = NULL;
224f2ee2
LP
858 int fd;
859
860 assert(s);
861 assert(priority >= 0);
862 assert(priority <= 999);
863 assert(message);
864
865 /* Never allow messages with kernel facility to be written to
866 * kmsg, regardless where the data comes from. */
867 priority = fixup_priority(priority);
868
869 /* First: priority field */
870 snprintf(header_priority, sizeof(header_priority), "<%i>", priority);
871 char_array_0(header_priority);
872 IOVEC_SET_STRING(iovec[n++], header_priority);
873
4cd9a9d9 874 /* Second: identifier and PID */
224f2ee2 875 if (ucred) {
4cd9a9d9
LP
876 if (!identifier) {
877 get_process_comm(ucred->pid, &ident_buf);
878 identifier = ident_buf;
224f2ee2
LP
879 }
880
881 snprintf(header_pid, sizeof(header_pid), "[%lu]: ", (unsigned long) ucred->pid);
882 char_array_0(header_pid);
883
4cd9a9d9
LP
884 if (identifier)
885 IOVEC_SET_STRING(iovec[n++], identifier);
224f2ee2
LP
886
887 IOVEC_SET_STRING(iovec[n++], header_pid);
4cd9a9d9
LP
888 } else if (identifier) {
889 IOVEC_SET_STRING(iovec[n++], identifier);
224f2ee2
LP
890 IOVEC_SET_STRING(iovec[n++], ": ");
891 }
892
893 /* Fourth: message */
894 IOVEC_SET_STRING(iovec[n++], message);
895 IOVEC_SET_STRING(iovec[n++], "\n");
896
897 fd = open("/dev/kmsg", O_WRONLY|O_NOCTTY|O_CLOEXEC);
898 if (fd < 0) {
899 log_debug("Failed to open /dev/kmsg for logging: %s", strerror(errno));
900 goto finish;
901 }
902
903 if (writev(fd, iovec, n) < 0)
904 log_debug("Failed to write to /dev/kmsg for logging: %s", strerror(errno));
905
906 close_nointr_nofail(fd);
6e409ce1
LP
907
908finish:
4cd9a9d9 909 free(ident_buf);
224f2ee2
LP
910}
911
4cd9a9d9 912static void forward_console(Server *s, const char *identifier, const char *message, struct ucred *ucred) {
224f2ee2
LP
913 struct iovec iovec[4];
914 char header_pid[16];
915 int n = 0, fd;
4cd9a9d9 916 char *ident_buf = NULL;
224f2ee2
LP
917
918 assert(s);
919 assert(message);
920
4cd9a9d9 921 /* First: identifier and PID */
224f2ee2 922 if (ucred) {
4cd9a9d9
LP
923 if (!identifier) {
924 get_process_comm(ucred->pid, &ident_buf);
925 identifier = ident_buf;
224f2ee2
LP
926 }
927
928 snprintf(header_pid, sizeof(header_pid), "[%lu]: ", (unsigned long) ucred->pid);
929 char_array_0(header_pid);
930
4cd9a9d9
LP
931 if (identifier)
932 IOVEC_SET_STRING(iovec[n++], identifier);
224f2ee2
LP
933
934 IOVEC_SET_STRING(iovec[n++], header_pid);
4cd9a9d9
LP
935 } else if (identifier) {
936 IOVEC_SET_STRING(iovec[n++], identifier);
224f2ee2
LP
937 IOVEC_SET_STRING(iovec[n++], ": ");
938 }
939
940 /* Third: message */
941 IOVEC_SET_STRING(iovec[n++], message);
942 IOVEC_SET_STRING(iovec[n++], "\n");
943
944 fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
945 if (fd < 0) {
946 log_debug("Failed to open /dev/console for logging: %s", strerror(errno));
947 goto finish;
948 }
949
950 if (writev(fd, iovec, n) < 0)
951 log_debug("Failed to write to /dev/console for logging: %s", strerror(errno));
952
953 close_nointr_nofail(fd);
954
955finish:
4cd9a9d9 956 free(ident_buf);
224f2ee2
LP
957}
958
6c1e6b98 959static void read_identifier(const char **buf, char **identifier, char **pid) {
224f2ee2
LP
960 const char *p;
961 char *t;
962 size_t l, e;
963
964 assert(buf);
4cd9a9d9 965 assert(identifier);
6c1e6b98 966 assert(pid);
224f2ee2
LP
967
968 p = *buf;
969
970 p += strspn(p, WHITESPACE);
971 l = strcspn(p, WHITESPACE);
972
973 if (l <= 0 ||
974 p[l-1] != ':')
975 return;
976
977 e = l;
978 l--;
979
980 if (p[l-1] == ']') {
981 size_t k = l-1;
982
983 for (;;) {
984
985 if (p[k] == '[') {
6c1e6b98
LP
986 t = strndup(p+k+1, l-k-2);
987 if (t)
988 *pid = t;
989
224f2ee2
LP
990 l = k;
991 break;
992 }
993
994 if (k == 0)
995 break;
996
997 k--;
998 }
999 }
1000
1001 t = strndup(p, l);
1002 if (t)
4cd9a9d9 1003 *identifier = t;
224f2ee2
LP
1004
1005 *buf = p + e;
1006 *buf += strspn(*buf, WHITESPACE);
6e409ce1
LP
1007}
1008
7f3e6257 1009static void process_syslog_message(Server *s, const char *buf, struct ucred *ucred, struct timeval *tv) {
6c1e6b98
LP
1010 char *message = NULL, *syslog_priority = NULL, *syslog_facility = NULL, *syslog_identifier = NULL, *syslog_pid = NULL;
1011 struct iovec iovec[N_IOVEC_META_FIELDS + 6];
7f3e6257
LP
1012 unsigned n = 0;
1013 int priority = LOG_USER | LOG_INFO;
6c1e6b98 1014 char *identifier = NULL, *pid = NULL;
7f3e6257
LP
1015
1016 assert(s);
1017 assert(buf);
1018
224f2ee2
LP
1019 if (s->forward_to_syslog)
1020 forward_syslog_raw(s, buf, ucred, tv);
1021
7f3e6257
LP
1022 parse_syslog_priority((char**) &buf, &priority);
1023 skip_syslog_date((char**) &buf);
6c1e6b98 1024 read_identifier(&buf, &identifier, &pid);
224f2ee2
LP
1025
1026 if (s->forward_to_kmsg)
4cd9a9d9 1027 forward_kmsg(s, priority, identifier, buf, ucred);
224f2ee2
LP
1028
1029 if (s->forward_to_console)
4cd9a9d9 1030 forward_console(s, identifier, buf, ucred);
7f3e6257 1031
33eb8abf
LP
1032 IOVEC_SET_STRING(iovec[n++], "_TRANSPORT=syslog");
1033
7f3e6257
LP
1034 if (asprintf(&syslog_priority, "PRIORITY=%i", priority & LOG_PRIMASK) >= 0)
1035 IOVEC_SET_STRING(iovec[n++], syslog_priority);
1036
224f2ee2
LP
1037 if (priority & LOG_FACMASK)
1038 if (asprintf(&syslog_facility, "SYSLOG_FACILITY=%i", LOG_FAC(priority)) >= 0)
1039 IOVEC_SET_STRING(iovec[n++], syslog_facility);
1040
4cd9a9d9
LP
1041 if (identifier) {
1042 syslog_identifier = strappend("SYSLOG_IDENTIFIER=", identifier);
1043 if (syslog_identifier)
1044 IOVEC_SET_STRING(iovec[n++], syslog_identifier);
224f2ee2 1045 }
7f3e6257 1046
6c1e6b98
LP
1047 if (pid) {
1048 syslog_pid = strappend("SYSLOG_PID=", pid);
1049 if (syslog_pid)
1050 IOVEC_SET_STRING(iovec[n++], syslog_pid);
1051 }
1052
7f3e6257
LP
1053 message = strappend("MESSAGE=", buf);
1054 if (message)
1055 IOVEC_SET_STRING(iovec[n++], message);
1056
224f2ee2 1057 dispatch_message(s, iovec, n, ELEMENTSOF(iovec), ucred, tv, priority);
7f3e6257
LP
1058
1059 free(message);
4cd9a9d9 1060 free(identifier);
6c1e6b98 1061 free(pid);
87d2c1ff 1062 free(syslog_priority);
224f2ee2 1063 free(syslog_facility);
4cd9a9d9 1064 free(syslog_identifier);
7f3e6257
LP
1065}
1066
6ad1d1c3
LP
1067static bool valid_user_field(const char *p, size_t l) {
1068 const char *a;
1069
1070 /* We kinda enforce POSIX syntax recommendations for
1071 environment variables here, but make a couple of additional
1072 requirements.
1073
1074 http://pubs.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap08.html */
1075
1076 /* No empty field names */
1077 if (l <= 0)
1078 return false;
1079
1080 /* Don't allow names longer than 64 chars */
1081 if (l > 64)
1082 return false;
1083
1084 /* Variables starting with an underscore are protected */
1085 if (p[0] == '_')
1086 return false;
1087
1088 /* Don't allow digits as first character */
1089 if (p[0] >= '0' && p[0] <= '9')
1090 return false;
1091
1092 /* Only allow A-Z0-9 and '_' */
1093 for (a = p; a < p + l; a++)
1094 if (!((*a >= 'A' && *a <= 'Z') ||
1095 (*a >= '0' && *a <= '9') ||
1096 *a == '_'))
1097 return false;
1098
1099 return true;
1100}
1101
7f3e6257
LP
1102static void process_native_message(Server *s, const void *buffer, size_t buffer_size, struct ucred *ucred, struct timeval *tv) {
1103 struct iovec *iovec = NULL;
33eb8abf 1104 unsigned n = 0, m = 0, j, tn = (unsigned) -1;
7f3e6257
LP
1105 const char *p;
1106 size_t remaining;
6e409ce1 1107 int priority = LOG_INFO;
4cd9a9d9 1108 char *identifier = NULL, *message = NULL;
7f3e6257
LP
1109
1110 assert(s);
1111 assert(buffer || n == 0);
1112
1113 p = buffer;
1114 remaining = buffer_size;
1115
1116 while (remaining > 0) {
1117 const char *e, *q;
1118
1119 e = memchr(p, '\n', remaining);
1120
1121 if (!e) {
1122 /* Trailing noise, let's ignore it, and flush what we collected */
1123 log_debug("Received message with trailing noise, ignoring.");
1124 break;
1125 }
1126
1127 if (e == p) {
1128 /* Entry separator */
6e409ce1 1129 dispatch_message(s, iovec, n, m, ucred, tv, priority);
7f3e6257 1130 n = 0;
6e409ce1 1131 priority = LOG_INFO;
7f3e6257
LP
1132
1133 p++;
1134 remaining--;
1135 continue;
1136 }
1137
6ad1d1c3
LP
1138 if (*p == '.' || *p == '#') {
1139 /* Ignore control commands for now, and
1140 * comments too. */
7f3e6257
LP
1141 remaining -= (e - p) + 1;
1142 p = e + 1;
1143 continue;
1144 }
1145
1146 /* A property follows */
1147
224f2ee2 1148 if (n+N_IOVEC_META_FIELDS >= m) {
7f3e6257
LP
1149 struct iovec *c;
1150 unsigned u;
1151
33eb8abf 1152 u = MAX((n+N_IOVEC_META_FIELDS+1) * 2U, 4U);
7f3e6257
LP
1153 c = realloc(iovec, u * sizeof(struct iovec));
1154 if (!c) {
1155 log_error("Out of memory");
1156 break;
1157 }
1158
1159 iovec = c;
1160 m = u;
1161 }
1162
1163 q = memchr(p, '=', e - p);
1164 if (q) {
6ad1d1c3 1165 if (valid_user_field(p, q - p)) {
224f2ee2
LP
1166 size_t l;
1167
1168 l = e - p;
1169
2b0ba69b
LP
1170 /* If the field name starts with an
1171 * underscore, skip the variable,
1172 * since that indidates a trusted
1173 * field */
1174 iovec[n].iov_base = (char*) p;
224f2ee2 1175 iovec[n].iov_len = l;
2b0ba69b 1176 n++;
6e409ce1
LP
1177
1178 /* We need to determine the priority
1179 * of this entry for the rate limiting
1180 * logic */
224f2ee2
LP
1181 if (l == 10 &&
1182 memcmp(p, "PRIORITY=", 9) == 0 &&
1183 p[9] >= '0' && p[9] <= '9')
1184 priority = (priority & LOG_FACMASK) | (p[9] - '0');
1185
1186 else if (l == 17 &&
1187 memcmp(p, "SYSLOG_FACILITY=", 16) == 0 &&
1188 p[16] >= '0' && p[16] <= '9')
1189 priority = (priority & LOG_PRIMASK) | ((p[16] - '0') << 3);
1190
1191 else if (l == 18 &&
1192 memcmp(p, "SYSLOG_FACILITY=", 16) == 0 &&
1193 p[16] >= '0' && p[16] <= '9' &&
1194 p[17] >= '0' && p[17] <= '9')
1195 priority = (priority & LOG_PRIMASK) | (((p[16] - '0')*10 + (p[17] - '0')) << 3);
1196
1197 else if (l >= 12 &&
4cd9a9d9 1198 memcmp(p, "SYSLOG_IDENTIFIER=", 11) == 0) {
224f2ee2
LP
1199 char *t;
1200
1201 t = strndup(p + 11, l - 11);
1202 if (t) {
4cd9a9d9
LP
1203 free(identifier);
1204 identifier = t;
224f2ee2
LP
1205 }
1206 } else if (l >= 8 &&
1207 memcmp(p, "MESSAGE=", 8) == 0) {
1208 char *t;
1209
1210 t = strndup(p + 8, l - 8);
1211 if (t) {
1212 free(message);
1213 message = t;
1214 }
1215 }
2b0ba69b 1216 }
7f3e6257
LP
1217
1218 remaining -= (e - p) + 1;
1219 p = e + 1;
1220 continue;
1221 } else {
1222 uint64_t l;
1223 char *k;
1224
1225 if (remaining < e - p + 1 + sizeof(uint64_t) + 1) {
1226 log_debug("Failed to parse message, ignoring.");
1227 break;
1228 }
1229
1230 memcpy(&l, e + 1, sizeof(uint64_t));
1231 l = le64toh(l);
1232
1233 if (remaining < e - p + 1 + sizeof(uint64_t) + l + 1 ||
1234 e[1+sizeof(uint64_t)+l] != '\n') {
1235 log_debug("Failed to parse message, ignoring.");
1236 break;
1237 }
1238
1239 k = malloc((e - p) + 1 + l);
1240 if (!k) {
1241 log_error("Out of memory");
1242 break;
1243 }
1244
1245 memcpy(k, p, e - p);
1246 k[e - p] = '=';
1247 memcpy(k + (e - p) + 1, e + 1 + sizeof(uint64_t), l);
1248
6ad1d1c3 1249 if (valid_user_field(p, e - p)) {
2b0ba69b
LP
1250 iovec[n].iov_base = k;
1251 iovec[n].iov_len = (e - p) + 1 + l;
1252 n++;
1253 } else
1254 free(k);
7f3e6257
LP
1255
1256 remaining -= (e - p) + 1 + sizeof(uint64_t) + l + 1;
1257 p = e + 1 + sizeof(uint64_t) + l + 1;
1258 }
1259 }
1260
33eb8abf
LP
1261 if (n <= 0)
1262 goto finish;
1263
1264 tn = n++;
1265 IOVEC_SET_STRING(iovec[tn], "_TRANSPORT=journal");
1266
224f2ee2
LP
1267 if (message) {
1268 if (s->forward_to_syslog)
4cd9a9d9 1269 forward_syslog(s, priority, identifier, message, ucred, tv);
224f2ee2
LP
1270
1271 if (s->forward_to_kmsg)
4cd9a9d9 1272 forward_kmsg(s, priority, identifier, message, ucred);
224f2ee2
LP
1273
1274 if (s->forward_to_console)
4cd9a9d9 1275 forward_console(s, identifier, message, ucred);
224f2ee2
LP
1276 }
1277
6e409ce1 1278 dispatch_message(s, iovec, n, m, ucred, tv, priority);
7f3e6257 1279
33eb8abf
LP
1280finish:
1281 for (j = 0; j < n; j++) {
1282 if (j == tn)
1283 continue;
1284
7f3e6257
LP
1285 if (iovec[j].iov_base < buffer ||
1286 (const uint8_t*) iovec[j].iov_base >= (const uint8_t*) buffer + buffer_size)
1287 free(iovec[j].iov_base);
33eb8abf 1288 }
224f2ee2 1289
4cd9a9d9 1290 free(identifier);
224f2ee2 1291 free(message);
87d2c1ff
LP
1292}
1293
224f2ee2 1294static int stdout_stream_log(StdoutStream *s, const char *p) {
33eb8abf 1295 struct iovec iovec[N_IOVEC_META_FIELDS + 5];
4cd9a9d9 1296 char *message = NULL, *syslog_priority = NULL, *syslog_facility = NULL, *syslog_identifier = NULL;
fe652127 1297 unsigned n = 0;
fe652127
LP
1298 int priority;
1299
87d2c1ff 1300 assert(s);
fe652127
LP
1301 assert(p);
1302
1303 priority = s->priority;
1304
258cdffc 1305 if (s->level_prefix)
224f2ee2 1306 parse_syslog_priority((char**) &p, &priority);
fe652127 1307
224f2ee2 1308 if (s->forward_to_syslog || s->server->forward_to_syslog)
4cd9a9d9 1309 forward_syslog(s->server, fixup_priority(priority), s->identifier, p, &s->ucred, NULL);
fe652127 1310
224f2ee2 1311 if (s->forward_to_kmsg || s->server->forward_to_kmsg)
4cd9a9d9 1312 forward_kmsg(s->server, priority, s->identifier, p, &s->ucred);
fe652127 1313
224f2ee2 1314 if (s->forward_to_console || s->server->forward_to_console)
4cd9a9d9 1315 forward_console(s->server, s->identifier, p, &s->ucred);
224f2ee2 1316
33eb8abf
LP
1317 IOVEC_SET_STRING(iovec[n++], "_TRANSPORT=stdout");
1318
224f2ee2 1319 if (asprintf(&syslog_priority, "PRIORITY=%i", priority & LOG_PRIMASK) >= 0)
fe652127
LP
1320 IOVEC_SET_STRING(iovec[n++], syslog_priority);
1321
224f2ee2
LP
1322 if (priority & LOG_FACMASK)
1323 if (asprintf(&syslog_facility, "SYSLOG_FACILITY=%i", LOG_FAC(priority)) >= 0)
1324 IOVEC_SET_STRING(iovec[n++], syslog_facility);
fe652127 1325
4cd9a9d9
LP
1326 if (s->identifier) {
1327 syslog_identifier = strappend("SYSLOG_IDENTIFIER=", s->identifier);
1328 if (syslog_identifier)
1329 IOVEC_SET_STRING(iovec[n++], syslog_identifier);
87d2c1ff
LP
1330 }
1331
224f2ee2
LP
1332 message = strappend("MESSAGE=", p);
1333 if (message)
1334 IOVEC_SET_STRING(iovec[n++], message);
fe652127 1335
224f2ee2 1336 dispatch_message(s->server, iovec, n, ELEMENTSOF(iovec), &s->ucred, NULL, priority);
fe652127
LP
1337
1338 free(message);
1339 free(syslog_priority);
224f2ee2 1340 free(syslog_facility);
4cd9a9d9 1341 free(syslog_identifier);
fe652127
LP
1342
1343 return 0;
1344}
1345
224f2ee2
LP
1346static int stdout_stream_line(StdoutStream *s, char *p) {
1347 int r;
1348
fe652127
LP
1349 assert(s);
1350 assert(p);
1351
224f2ee2 1352 p = strstrip(p);
fe652127
LP
1353
1354 switch (s->state) {
1355
4cd9a9d9
LP
1356 case STDOUT_STREAM_IDENTIFIER:
1357 s->identifier = strdup(p);
1358 if (!s->identifier) {
224f2ee2
LP
1359 log_error("Out of memory");
1360 return -ENOMEM;
fe652127
LP
1361 }
1362
1363 s->state = STDOUT_STREAM_PRIORITY;
1364 return 0;
1365
1366 case STDOUT_STREAM_PRIORITY:
224f2ee2
LP
1367 r = safe_atoi(p, &s->priority);
1368 if (r < 0 || s->priority <= 0 || s->priority >= 999) {
fe652127
LP
1369 log_warning("Failed to parse log priority line.");
1370 return -EINVAL;
1371 }
1372
258cdffc 1373 s->state = STDOUT_STREAM_LEVEL_PREFIX;
fe652127
LP
1374 return 0;
1375
258cdffc 1376 case STDOUT_STREAM_LEVEL_PREFIX:
224f2ee2
LP
1377 r = parse_boolean(p);
1378 if (r < 0) {
258cdffc 1379 log_warning("Failed to parse level prefix line.");
fe652127
LP
1380 return -EINVAL;
1381 }
1382
258cdffc 1383 s->level_prefix = !!r;
224f2ee2 1384 s->state = STDOUT_STREAM_FORWARD_TO_SYSLOG;
fe652127
LP
1385 return 0;
1386
224f2ee2
LP
1387 case STDOUT_STREAM_FORWARD_TO_SYSLOG:
1388 r = parse_boolean(p);
1389 if (r < 0) {
1390 log_warning("Failed to parse forward to syslog line.");
fe652127
LP
1391 return -EINVAL;
1392 }
1393
224f2ee2
LP
1394 s->forward_to_syslog = !!r;
1395 s->state = STDOUT_STREAM_FORWARD_TO_KMSG;
1396 return 0;
1397
1398 case STDOUT_STREAM_FORWARD_TO_KMSG:
1399 r = parse_boolean(p);
1400 if (r < 0) {
1401 log_warning("Failed to parse copy to kmsg line.");
1402 return -EINVAL;
1403 }
1404
1405 s->forward_to_kmsg = !!r;
1406 s->state = STDOUT_STREAM_FORWARD_TO_CONSOLE;
1407 return 0;
1408
1409 case STDOUT_STREAM_FORWARD_TO_CONSOLE:
1410 r = parse_boolean(p);
1411 if (r < 0) {
1412 log_warning("Failed to parse copy to console line.");
1413 return -EINVAL;
1414 }
1415
1416 s->forward_to_console = !!r;
fe652127
LP
1417 s->state = STDOUT_STREAM_RUNNING;
1418 return 0;
1419
1420 case STDOUT_STREAM_RUNNING:
224f2ee2 1421 return stdout_stream_log(s, p);
fe652127
LP
1422 }
1423
1424 assert_not_reached("Unknown stream state");
1425}
1426
1427static int stdout_stream_scan(StdoutStream *s, bool force_flush) {
1428 char *p;
1429 size_t remaining;
1430 int r;
1431
1432 assert(s);
1433
1434 p = s->buffer;
1435 remaining = s->length;
1436 for (;;) {
1437 char *end;
1438 size_t skip;
1439
1440 end = memchr(p, '\n', remaining);
224f2ee2 1441 if (end)
fe652127 1442 skip = end - p + 1;
224f2ee2
LP
1443 else if (remaining >= sizeof(s->buffer) - 1) {
1444 end = p + sizeof(s->buffer) - 1;
6c1e6b98 1445 skip = remaining;
224f2ee2
LP
1446 } else
1447 break;
1448
1449 *end = 0;
fe652127 1450
224f2ee2 1451 r = stdout_stream_line(s, p);
fe652127
LP
1452 if (r < 0)
1453 return r;
1454
1455 remaining -= skip;
1456 p += skip;
1457 }
1458
1459 if (force_flush && remaining > 0) {
224f2ee2
LP
1460 p[remaining] = 0;
1461 r = stdout_stream_line(s, p);
fe652127
LP
1462 if (r < 0)
1463 return r;
1464
1465 p += remaining;
1466 remaining = 0;
1467 }
1468
1469 if (p > s->buffer) {
1470 memmove(s->buffer, p, remaining);
1471 s->length = remaining;
1472 }
1473
1474 return 0;
1475}
1476
1477static int stdout_stream_process(StdoutStream *s) {
1478 ssize_t l;
1479 int r;
1480
1481 assert(s);
1482
1483 l = read(s->fd, s->buffer+s->length, sizeof(s->buffer)-1-s->length);
1484 if (l < 0) {
1485
1486 if (errno == EAGAIN)
1487 return 0;
1488
1489 log_warning("Failed to read from stream: %m");
1490 return -errno;
1491 }
1492
1493 if (l == 0) {
1494 r = stdout_stream_scan(s, true);
1495 if (r < 0)
1496 return r;
1497
1498 return 0;
1499 }
1500
1501 s->length += l;
1502 r = stdout_stream_scan(s, false);
1503 if (r < 0)
1504 return r;
1505
1506 return 1;
1507
1508}
1509
1510static void stdout_stream_free(StdoutStream *s) {
1511 assert(s);
1512
1513 if (s->server) {
1514 assert(s->server->n_stdout_streams > 0);
1515 s->server->n_stdout_streams --;
1516 LIST_REMOVE(StdoutStream, stdout_stream, s->server->stdout_streams, s);
1517 }
1518
1519 if (s->fd >= 0) {
1520 if (s->server)
1521 epoll_ctl(s->server->epoll_fd, EPOLL_CTL_DEL, s->fd, NULL);
1522
1523 close_nointr_nofail(s->fd);
1524 }
1525
4cd9a9d9 1526 free(s->identifier);
fe652127
LP
1527 free(s);
1528}
1529
1530static int stdout_stream_new(Server *s) {
1531 StdoutStream *stream;
1532 int fd, r;
1533 socklen_t len;
1534 struct epoll_event ev;
1535
1536 assert(s);
1537
1538 fd = accept4(s->stdout_fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC);
1539 if (fd < 0) {
1540 if (errno == EAGAIN)
1541 return 0;
1542
1543 log_error("Failed to accept stdout connection: %m");
1544 return -errno;
1545 }
1546
1547 if (s->n_stdout_streams >= STDOUT_STREAMS_MAX) {
1548 log_warning("Too many stdout streams, refusing connection.");
1549 close_nointr_nofail(fd);
1550 return 0;
1551 }
1552
1553 stream = new0(StdoutStream, 1);
1554 if (!stream) {
1555 log_error("Out of memory.");
1556 close_nointr_nofail(fd);
1557 return -ENOMEM;
1558 }
1559
1560 stream->fd = fd;
1561
1562 len = sizeof(stream->ucred);
1563 if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &stream->ucred, &len) < 0) {
1564 log_error("Failed to determine peer credentials: %m");
1565 r = -errno;
1566 goto fail;
1567 }
1568
1569 if (shutdown(fd, SHUT_WR) < 0) {
1570 log_error("Failed to shutdown writing side of socket: %m");
1571 r = -errno;
1572 goto fail;
1573 }
1574
1575 zero(ev);
1576 ev.data.ptr = stream;
1577 ev.events = EPOLLIN;
1578 if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0) {
1579 log_error("Failed to add stream to event loop: %m");
1580 r = -errno;
1581 goto fail;
1582 }
1583
1584 stream->server = s;
1585 LIST_PREPEND(StdoutStream, stdout_stream, s->stdout_streams, stream);
1586 s->n_stdout_streams ++;
1587
1588 return 0;
1589
1590fail:
1591 stdout_stream_free(stream);
1592 return r;
1593}
1594
6c1e6b98
LP
1595static int parse_kernel_timestamp(char **_p, usec_t *t) {
1596 usec_t r;
1597 int k, i;
1598 char *p;
1599
1600 assert(_p);
1601 assert(*_p);
1602 assert(t);
1603
1604 p = *_p;
1605
1606 if (strlen(p) < 14 || p[0] != '[' || p[13] != ']' || p[6] != '.')
1607 return 0;
1608
1609 r = 0;
1610
1611 for (i = 1; i <= 5; i++) {
1612 r *= 10;
1613
1614 if (p[i] == ' ')
1615 continue;
1616
1617 k = undecchar(p[i]);
1618 if (k < 0)
1619 return 0;
1620
1621 r += k;
1622 }
1623
1624 for (i = 7; i <= 12; i++) {
1625 r *= 10;
1626
1627 k = undecchar(p[i]);
1628 if (k < 0)
1629 return 0;
1630
1631 r += k;
1632 }
1633
1634 *t = r;
1635 *_p += 14;
1636 *_p += strspn(*_p, WHITESPACE);
1637
1638 return 1;
1639}
1640
1641static void proc_kmsg_line(Server *s, const char *p) {
1642 struct iovec iovec[N_IOVEC_META_FIELDS + 7];
1643 char *message = NULL, *syslog_priority = NULL, *syslog_pid = NULL, *syslog_facility = NULL, *syslog_identifier = NULL, *source_time = NULL;
1644 int priority = LOG_KERN | LOG_INFO;
1645 unsigned n = 0;
1646 usec_t usec;
1647 char *identifier = NULL, *pid = NULL;
1648
1649 assert(s);
1650 assert(p);
1651
1652 parse_syslog_priority((char **) &p, &priority);
1653
1654 if (s->forward_to_kmsg && (priority & LOG_FACMASK) != LOG_KERN)
1655 return;
1656
1657 if (parse_kernel_timestamp((char **) &p, &usec) > 0) {
1658 if (asprintf(&source_time, "_SOURCE_MONOTONIC_TIMESTAMP=%llu",
1659 (unsigned long long) usec) >= 0)
1660 IOVEC_SET_STRING(iovec[n++], source_time);
1661 }
1662
1663 IOVEC_SET_STRING(iovec[n++], "_TRANSPORT=kernel");
1664
1665 if (asprintf(&syslog_priority, "PRIORITY=%i", priority & LOG_PRIMASK) >= 0)
1666 IOVEC_SET_STRING(iovec[n++], syslog_priority);
1667
1668 if ((priority & LOG_FACMASK) == LOG_KERN) {
1669
1670 if (s->forward_to_syslog)
1671 forward_syslog(s, priority, "kernel", p, NULL, NULL);
1672
1673 IOVEC_SET_STRING(iovec[n++], "SYSLOG_IDENTIFIER=kernel");
1674 } else {
1675 read_identifier(&p, &identifier, &pid);
1676
1677 if (s->forward_to_syslog)
1678 forward_syslog(s, priority, identifier, p, NULL, NULL);
1679
1680 if (identifier) {
1681 syslog_identifier = strappend("SYSLOG_IDENTIFIER=", identifier);
1682 if (syslog_identifier)
1683 IOVEC_SET_STRING(iovec[n++], syslog_identifier);
1684 }
1685
1686 if (pid) {
1687 syslog_pid = strappend("SYSLOG_PID=", pid);
1688 if (syslog_pid)
1689 IOVEC_SET_STRING(iovec[n++], syslog_pid);
1690 }
1691
1692 if (asprintf(&syslog_facility, "SYSLOG_FACILITY=%i", LOG_FAC(priority)) >= 0)
1693 IOVEC_SET_STRING(iovec[n++], syslog_facility);
1694 }
1695
1696 message = strappend("MESSAGE=", p);
1697 if (message)
1698 IOVEC_SET_STRING(iovec[n++], message);
1699
1700
1701 dispatch_message(s, iovec, n, ELEMENTSOF(iovec), NULL, NULL, priority);
1702
1703 free(message);
1704 free(syslog_priority);
1705 free(syslog_identifier);
1706 free(syslog_pid);
1707 free(syslog_facility);
1708 free(source_time);
1709 free(identifier);
1710 free(pid);
1711}
1712
1713static void proc_kmsg_scan(Server *s) {
1714 char *p;
1715 size_t remaining;
1716
1717 assert(s);
1718
1719 p = s->proc_kmsg_buffer;
1720 remaining = s->proc_kmsg_length;
1721 for (;;) {
1722 char *end;
1723 size_t skip;
1724
1725 end = memchr(p, '\n', remaining);
1726 if (end)
1727 skip = end - p + 1;
1728 else if (remaining >= sizeof(s->proc_kmsg_buffer) - 1) {
1729 end = p + sizeof(s->proc_kmsg_buffer) - 1;
1730 skip = remaining;
1731 } else
1732 break;
1733
1734 *end = 0;
1735
1736 proc_kmsg_line(s, p);
1737
1738 remaining -= skip;
1739 p += skip;
1740 }
1741
1742 if (p > s->proc_kmsg_buffer) {
1743 memmove(s->proc_kmsg_buffer, p, remaining);
1744 s->proc_kmsg_length = remaining;
1745 }
1746}
1747
cf244689
LP
1748static int system_journal_open(Server *s) {
1749 int r;
1750 char *fn;
1751 sd_id128_t machine;
1752 char ids[33];
1753
1754 r = sd_id128_get_machine(&machine);
1755 if (r < 0)
1756 return r;
1757
1758 sd_id128_to_string(machine, ids);
1759
1760 if (!s->system_journal) {
1761
1762 /* First try to create the machine path, but not the prefix */
1763 fn = strappend("/var/log/journal/", ids);
1764 if (!fn)
1765 return -ENOMEM;
1766 (void) mkdir(fn, 0755);
1767 free(fn);
1768
1769 /* The create the system journal file */
1770 fn = join("/var/log/journal/", ids, "/system.journal", NULL);
1771 if (!fn)
1772 return -ENOMEM;
1773
1774 r = journal_file_open(fn, O_RDWR|O_CREAT, 0640, NULL, &s->system_journal);
1775 free(fn);
1776
1777 if (r >= 0) {
babfc091
LP
1778 journal_default_metrics(&s->system_metrics, s->system_journal->fd);
1779
1780 s->system_journal->metrics = s->system_metrics;
cf244689
LP
1781 s->system_journal->compress = s->compress;
1782
5e41cfec 1783 server_fix_perms(s, s->system_journal, 0);
cf244689
LP
1784 } else if (r < 0) {
1785
adf7d506
LP
1786 if (r != -ENOENT && r != -EROFS)
1787 log_warning("Failed to open system journal: %s", strerror(-r));
1788
1789 r = 0;
cf244689
LP
1790 }
1791 }
1792
1793 if (!s->runtime_journal) {
1794
1795 fn = join("/run/log/journal/", ids, "/system.journal", NULL);
1796 if (!fn)
1797 return -ENOMEM;
1798
1799 if (s->system_journal) {
1800
1801 /* Try to open the runtime journal, but only
1802 * if it already exists, so that we can flush
1803 * it into the system journal */
1804
1805 r = journal_file_open(fn, O_RDWR, 0640, NULL, &s->runtime_journal);
1806 free(fn);
1807
1808 if (r < 0) {
adf7d506
LP
1809 if (r != -ENOENT)
1810 log_warning("Failed to open runtime journal: %s", strerror(-r));
cf244689 1811
adf7d506 1812 r = 0;
cf244689
LP
1813 }
1814
1815 } else {
1816
1817 /* OK, we really need the runtime journal, so create
1818 * it if necessary. */
1819
1820 (void) mkdir_parents(fn, 0755);
1821 r = journal_file_open(fn, O_RDWR|O_CREAT, 0640, NULL, &s->runtime_journal);
1822 free(fn);
1823
1824 if (r < 0) {
1825 log_error("Failed to open runtime journal: %s", strerror(-r));
1826 return r;
1827 }
1828 }
1829
1830 if (s->runtime_journal) {
babfc091
LP
1831 journal_default_metrics(&s->runtime_metrics, s->runtime_journal->fd);
1832
1833 s->runtime_journal->metrics = s->runtime_metrics;
cf244689
LP
1834 s->runtime_journal->compress = s->compress;
1835
5e41cfec 1836 server_fix_perms(s, s->runtime_journal, 0);
cf244689
LP
1837 }
1838 }
1839
1840 return r;
1841}
1842
1843static int server_flush_to_var(Server *s) {
1844 char path[] = "/run/log/journal/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
1845 Object *o = NULL;
1846 int r;
1847 sd_id128_t machine;
1848 sd_journal *j;
54a7b863 1849 usec_t ts;
cf244689
LP
1850
1851 assert(s);
1852
54a7b863
LP
1853 if (!s->runtime_journal)
1854 return 0;
1855
1856 ts = now(CLOCK_MONOTONIC);
1857 if (s->var_available_timestamp + RECHECK_VAR_AVAILABLE_USEC > ts)
1858 return 0;
1859
1860 s->var_available_timestamp = ts;
1861
cf244689
LP
1862 system_journal_open(s);
1863
54a7b863 1864 if (!s->system_journal)
cf244689
LP
1865 return 0;
1866
6c1e6b98
LP
1867 log_info("Flushing to /var...");
1868
cf244689
LP
1869 r = sd_id128_get_machine(&machine);
1870 if (r < 0) {
1871 log_error("Failed to get machine id: %s", strerror(-r));
1872 return r;
1873 }
1874
1875 r = sd_journal_open(&j, SD_JOURNAL_RUNTIME_ONLY);
1876 if (r < 0) {
1877 log_error("Failed to read runtime journal: %s", strerror(-r));
1878 return r;
1879 }
1880
1881 SD_JOURNAL_FOREACH(j) {
1882 JournalFile *f;
1883
1884 f = j->current_file;
1885 assert(f && f->current_offset > 0);
1886
1887 r = journal_file_move_to_object(f, OBJECT_ENTRY, f->current_offset, &o);
1888 if (r < 0) {
1889 log_error("Can't read entry: %s", strerror(-r));
1890 goto finish;
1891 }
1892
1893 r = journal_file_copy_entry(f, s->system_journal, o, f->current_offset, NULL, NULL, NULL);
1894 if (r == -E2BIG) {
1895 log_info("Allocation limit reached.");
1896
1897 journal_file_post_change(s->system_journal);
b1a0ab71 1898 server_rotate(s);
cf244689
LP
1899 server_vacuum(s);
1900
1901 r = journal_file_copy_entry(f, s->system_journal, o, f->current_offset, NULL, NULL, NULL);
1902 }
1903
1904 if (r < 0) {
1905 log_error("Can't write entry: %s", strerror(-r));
1906 goto finish;
1907 }
1908 }
1909
1910finish:
1911 journal_file_post_change(s->system_journal);
1912
1913 journal_file_close(s->runtime_journal);
1914 s->runtime_journal = NULL;
1915
1916 if (r >= 0) {
1917 sd_id128_to_string(machine, path + 17);
1918 rm_rf(path, false, true, false);
1919 }
1920
1921 return r;
1922}
1923
6c1e6b98
LP
1924static int server_read_proc_kmsg(Server *s) {
1925 ssize_t l;
1926 assert(s);
1927 assert(s->proc_kmsg_fd >= 0);
1928
1929 l = read(s->proc_kmsg_fd, s->proc_kmsg_buffer + s->proc_kmsg_length, sizeof(s->proc_kmsg_buffer) - 1 - s->proc_kmsg_length);
1930 if (l < 0) {
1931
1932 if (errno == EAGAIN || errno == EINTR)
1933 return 0;
1934
1935 log_error("Failed to read from kernel: %m");
1936 return -errno;
1937 }
1938
1939 s->proc_kmsg_length += l;
1940
1941 proc_kmsg_scan(s);
1942 return 1;
1943}
1944
1945static int server_flush_proc_kmsg(Server *s) {
1946 int r;
1947
1948 assert(s);
1949
1950 if (s->proc_kmsg_fd < 0)
1951 return 0;
1952
1953 log_info("Flushing /proc/kmsg...");
1954
1955 for (;;) {
1956 r = server_read_proc_kmsg(s);
1957 if (r < 0)
1958 return r;
1959
1960 if (r == 0)
1961 break;
1962 }
1963
1964 return 0;
1965}
1966
fe652127
LP
1967static int process_event(Server *s, struct epoll_event *ev) {
1968 assert(s);
1969
87d2c1ff
LP
1970 if (ev->data.fd == s->signal_fd) {
1971 struct signalfd_siginfo sfsi;
1972 ssize_t n;
1973
fe652127
LP
1974 if (ev->events != EPOLLIN) {
1975 log_info("Got invalid event from epoll.");
1976 return -EIO;
1977 }
1978
87d2c1ff
LP
1979 n = read(s->signal_fd, &sfsi, sizeof(sfsi));
1980 if (n != sizeof(sfsi)) {
1981
1982 if (n >= 0)
1983 return -EIO;
1984
1985 if (errno == EINTR || errno == EAGAIN)
6c1e6b98 1986 return 1;
87d2c1ff
LP
1987
1988 return -errno;
1989 }
1990
cf244689
LP
1991 if (sfsi.ssi_signo == SIGUSR1) {
1992 server_flush_to_var(s);
1993 return 0;
1994 }
1995
87d2c1ff
LP
1996 log_debug("Received SIG%s", signal_to_string(sfsi.ssi_signo));
1997 return 0;
1998
6c1e6b98
LP
1999 } else if (ev->data.fd == s->proc_kmsg_fd) {
2000 int r;
2001
2002 if (ev->events != EPOLLIN) {
2003 log_info("Got invalid event from epoll.");
2004 return -EIO;
2005 }
2006
2007 r = server_read_proc_kmsg(s);
2008 if (r < 0)
2009 return r;
2010
2011 return 1;
2012
fe652127
LP
2013 } else if (ev->data.fd == s->native_fd ||
2014 ev->data.fd == s->syslog_fd) {
2015
2016 if (ev->events != EPOLLIN) {
2017 log_info("Got invalid event from epoll.");
2018 return -EIO;
2019 }
cec736d2 2020
87d2c1ff 2021 for (;;) {
87d2c1ff
LP
2022 struct msghdr msghdr;
2023 struct iovec iovec;
2024 struct ucred *ucred = NULL;
2025 struct timeval *tv = NULL;
2026 struct cmsghdr *cmsg;
2027 union {
2028 struct cmsghdr cmsghdr;
2029 uint8_t buf[CMSG_SPACE(sizeof(struct ucred)) +
2030 CMSG_SPACE(sizeof(struct timeval))];
2031 } control;
2032 ssize_t n;
7f3e6257
LP
2033 int v;
2034
2035 if (ioctl(ev->data.fd, SIOCINQ, &v) < 0) {
2036 log_error("SIOCINQ failed: %m");
2037 return -errno;
2038 }
2039
2040 if (v <= 0)
2041 return 1;
2042
2043 if (s->buffer_size < (size_t) v) {
2044 void *b;
2045 size_t l;
2046
2047 l = MAX(LINE_MAX + (size_t) v, s->buffer_size * 2);
2048 b = realloc(s->buffer, l+1);
2049
2050 if (!b) {
2051 log_error("Couldn't increase buffer.");
2052 return -ENOMEM;
2053 }
2054
2055 s->buffer_size = l;
2056 s->buffer = b;
2057 }
87d2c1ff
LP
2058
2059 zero(iovec);
7f3e6257
LP
2060 iovec.iov_base = s->buffer;
2061 iovec.iov_len = s->buffer_size;
87d2c1ff
LP
2062
2063 zero(control);
2064 zero(msghdr);
2065 msghdr.msg_iov = &iovec;
2066 msghdr.msg_iovlen = 1;
2067 msghdr.msg_control = &control;
2068 msghdr.msg_controllen = sizeof(control);
2069
2070 n = recvmsg(ev->data.fd, &msghdr, MSG_DONTWAIT);
2071 if (n < 0) {
2072
2073 if (errno == EINTR || errno == EAGAIN)
2074 return 1;
2075
2076 log_error("recvmsg() failed: %m");
2077 return -errno;
2078 }
2079
2080 for (cmsg = CMSG_FIRSTHDR(&msghdr); cmsg; cmsg = CMSG_NXTHDR(&msghdr, cmsg)) {
2081
2082 if (cmsg->cmsg_level == SOL_SOCKET &&
2083 cmsg->cmsg_type == SCM_CREDENTIALS &&
2084 cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred)))
2085 ucred = (struct ucred*) CMSG_DATA(cmsg);
2086 else if (cmsg->cmsg_level == SOL_SOCKET &&
2087 cmsg->cmsg_type == SO_TIMESTAMP &&
2088 cmsg->cmsg_len == CMSG_LEN(sizeof(struct timeval)))
2089 tv = (struct timeval*) CMSG_DATA(cmsg);
2090 }
2091
7f3e6257
LP
2092 if (ev->data.fd == s->syslog_fd) {
2093 char *e;
2094
2095 e = memchr(s->buffer, '\n', n);
2096 if (e)
2097 *e = 0;
2098 else
2099 s->buffer[n] = 0;
87d2c1ff 2100
7f3e6257
LP
2101 process_syslog_message(s, strstrip(s->buffer), ucred, tv);
2102 } else
2103 process_native_message(s, s->buffer, n, ucred, tv);
87d2c1ff 2104 }
cec736d2
LP
2105
2106 return 1;
fe652127
LP
2107
2108 } else if (ev->data.fd == s->stdout_fd) {
2109
2110 if (ev->events != EPOLLIN) {
2111 log_info("Got invalid event from epoll.");
2112 return -EIO;
2113 }
2114
2115 stdout_stream_new(s);
2116 return 1;
2117
2118 } else {
2119 StdoutStream *stream;
2120
2121 if ((ev->events|EPOLLIN|EPOLLHUP) != (EPOLLIN|EPOLLHUP)) {
2122 log_info("Got invalid event from epoll.");
2123 return -EIO;
2124 }
2125
2126 /* If it is none of the well-known fds, it must be an
2127 * stdout stream fd. Note that this is a bit ugly here
2128 * (since we rely that none of the well-known fds
2129 * could be interpreted as pointer), but nonetheless
2130 * safe, since the well-known fds would never get an
2131 * fd > 4096, i.e. beyond the first memory page */
2132
2133 stream = ev->data.ptr;
2134
2135 if (stdout_stream_process(stream) <= 0)
2136 stdout_stream_free(stream);
2137
2138 return 1;
87d2c1ff
LP
2139 }
2140
cec736d2
LP
2141 log_error("Unknown event.");
2142 return 0;
87d2c1ff
LP
2143}
2144
7f3e6257
LP
2145static int open_syslog_socket(Server *s) {
2146 union sockaddr_union sa;
2147 int one, r;
fe652127 2148 struct epoll_event ev;
8b18eb67 2149 struct timeval tv;
87d2c1ff
LP
2150
2151 assert(s);
2152
7f3e6257 2153 if (s->syslog_fd < 0) {
87d2c1ff 2154
6c1e6b98 2155 s->syslog_fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
7f3e6257
LP
2156 if (s->syslog_fd < 0) {
2157 log_error("socket() failed: %m");
2158 return -errno;
2159 }
2160
2161 zero(sa);
2162 sa.un.sun_family = AF_UNIX;
8b18eb67 2163 strncpy(sa.un.sun_path, "/dev/log", sizeof(sa.un.sun_path));
7f3e6257
LP
2164
2165 unlink(sa.un.sun_path);
2166
2167 r = bind(s->syslog_fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path));
2168 if (r < 0) {
2169 log_error("bind() failed: %m");
2170 return -errno;
2171 }
2172
2173 chmod(sa.un.sun_path, 0666);
87d2c1ff
LP
2174 }
2175
7f3e6257
LP
2176 one = 1;
2177 r = setsockopt(s->syslog_fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one));
2178 if (r < 0) {
2179 log_error("SO_PASSCRED failed: %m");
2180 return -errno;
87d2c1ff
LP
2181 }
2182
7f3e6257
LP
2183 one = 1;
2184 r = setsockopt(s->syslog_fd, SOL_SOCKET, SO_TIMESTAMP, &one, sizeof(one));
2185 if (r < 0) {
2186 log_error("SO_TIMESTAMP failed: %m");
2187 return -errno;
87d2c1ff
LP
2188 }
2189
8b18eb67
LP
2190 /* Since we use the same socket for forwarding this to some
2191 * other syslog implementation, make sure we don't hang
2192 * forever */
2193 timeval_store(&tv, SYSLOG_TIMEOUT_USEC);
2194 if (setsockopt(s->syslog_fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) < 0) {
2195 log_error("SO_SNDTIMEO failed: %m");
2196 return -errno;
2197 }
2198
fe652127
LP
2199 zero(ev);
2200 ev.events = EPOLLIN;
2201 ev.data.fd = s->syslog_fd;
2202 if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, s->syslog_fd, &ev) < 0) {
2203 log_error("Failed to add syslog server fd to epoll object: %m");
2204 return -errno;
2205 }
2206
7f3e6257
LP
2207 return 0;
2208}
87d2c1ff 2209
7f3e6257
LP
2210static int open_native_socket(Server*s) {
2211 union sockaddr_union sa;
2212 int one, r;
fe652127 2213 struct epoll_event ev;
7f3e6257
LP
2214
2215 assert(s);
2216
2217 if (s->native_fd < 0) {
2218
6c1e6b98 2219 s->native_fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
7f3e6257 2220 if (s->native_fd < 0) {
87d2c1ff
LP
2221 log_error("socket() failed: %m");
2222 return -errno;
2223 }
2224
2225 zero(sa);
2226 sa.un.sun_family = AF_UNIX;
259d2e76 2227 strncpy(sa.un.sun_path, "/run/systemd/journal/socket", sizeof(sa.un.sun_path));
87d2c1ff
LP
2228
2229 unlink(sa.un.sun_path);
2230
7f3e6257 2231 r = bind(s->native_fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path));
87d2c1ff
LP
2232 if (r < 0) {
2233 log_error("bind() failed: %m");
2234 return -errno;
2235 }
2236
2237 chmod(sa.un.sun_path, 0666);
2238 }
2239
2240 one = 1;
7f3e6257 2241 r = setsockopt(s->native_fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one));
87d2c1ff
LP
2242 if (r < 0) {
2243 log_error("SO_PASSCRED failed: %m");
2244 return -errno;
2245 }
2246
2247 one = 1;
7f3e6257 2248 r = setsockopt(s->native_fd, SOL_SOCKET, SO_TIMESTAMP, &one, sizeof(one));
87d2c1ff
LP
2249 if (r < 0) {
2250 log_error("SO_TIMESTAMP failed: %m");
2251 return -errno;
2252 }
2253
fe652127
LP
2254 zero(ev);
2255 ev.events = EPOLLIN;
2256 ev.data.fd = s->native_fd;
2257 if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, s->native_fd, &ev) < 0) {
2258 log_error("Failed to add native server fd to epoll object: %m");
2259 return -errno;
2260 }
2261
7f3e6257
LP
2262 return 0;
2263}
2264
fe652127
LP
2265static int open_stdout_socket(Server *s) {
2266 union sockaddr_union sa;
2267 int r;
7f3e6257 2268 struct epoll_event ev;
fe652127
LP
2269
2270 assert(s);
2271
2272 if (s->stdout_fd < 0) {
2273
6c1e6b98 2274 s->stdout_fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
fe652127
LP
2275 if (s->stdout_fd < 0) {
2276 log_error("socket() failed: %m");
2277 return -errno;
2278 }
2279
2280 zero(sa);
2281 sa.un.sun_family = AF_UNIX;
259d2e76 2282 strncpy(sa.un.sun_path, "/run/systemd/journal/stdout", sizeof(sa.un.sun_path));
fe652127
LP
2283
2284 unlink(sa.un.sun_path);
2285
2286 r = bind(s->stdout_fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path));
2287 if (r < 0) {
2288 log_error("bind() failed: %m");
2289 return -errno;
2290 }
2291
2292 chmod(sa.un.sun_path, 0666);
2293
2294 if (listen(s->stdout_fd, SOMAXCONN) < 0) {
2295 log_error("liste() failed: %m");
2296 return -errno;
2297 }
2298 }
2299
2300 zero(ev);
2301 ev.events = EPOLLIN;
2302 ev.data.fd = s->stdout_fd;
2303 if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, s->stdout_fd, &ev) < 0) {
2304 log_error("Failed to add stdout server fd to epoll object: %m");
2305 return -errno;
2306 }
2307
2308 return 0;
2309}
2310
6c1e6b98
LP
2311static int open_proc_kmsg(Server *s) {
2312 struct epoll_event ev;
2313
2314 assert(s);
2315
2316 if (!s->import_proc_kmsg)
2317 return 0;
2318
2319
2320 s->proc_kmsg_fd = open("/proc/kmsg", O_CLOEXEC|O_NONBLOCK|O_NOCTTY);
2321 if (s->proc_kmsg_fd < 0) {
2322 log_warning("Failed to open /proc/kmsg, ignoring: %m");
2323 return 0;
2324 }
2325
2326 zero(ev);
2327 ev.events = EPOLLIN;
2328 ev.data.fd = s->proc_kmsg_fd;
2329 if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, s->proc_kmsg_fd, &ev) < 0) {
2330 log_error("Failed to add /proc/kmsg fd to epoll object: %m");
2331 return -errno;
2332 }
2333
2334 return 0;
2335}
2336
fe652127 2337static int open_signalfd(Server *s) {
7f3e6257 2338 sigset_t mask;
fe652127
LP
2339 struct epoll_event ev;
2340
2341 assert(s);
2342
2343 assert_se(sigemptyset(&mask) == 0);
cf244689 2344 sigset_add_many(&mask, SIGINT, SIGTERM, SIGUSR1, -1);
fe652127
LP
2345 assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
2346
2347 s->signal_fd = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC);
2348 if (s->signal_fd < 0) {
2349 log_error("signalfd(): %m");
2350 return -errno;
2351 }
2352
2353 zero(ev);
2354 ev.events = EPOLLIN;
2355 ev.data.fd = s->signal_fd;
2356
2357 if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, s->signal_fd, &ev) < 0) {
2358 log_error("epoll_ctl(): %m");
2359 return -errno;
2360 }
2361
2362 return 0;
2363}
2364
effb1102
LP
2365static int server_parse_proc_cmdline(Server *s) {
2366 char *line, *w, *state;
2367 int r;
2368 size_t l;
2369
2370 if (detect_container(NULL) > 0)
2371 return 0;
2372
2373 r = read_one_line_file("/proc/cmdline", &line);
2374 if (r < 0) {
2375 log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r));
2376 return 0;
2377 }
2378
2379 FOREACH_WORD_QUOTED(w, l, line, state) {
2380 char *word;
2381
2382 word = strndup(w, l);
2383 if (!word) {
2384 r = -ENOMEM;
2385 goto finish;
2386 }
2387
2388 if (startswith(word, "systemd_journald.forward_to_syslog=")) {
2389 r = parse_boolean(word + 35);
2390 if (r < 0)
2391 log_warning("Failed to parse forward to syslog switch %s. Ignoring.", word + 35);
2392 else
2393 s->forward_to_syslog = r;
2394 } else if (startswith(word, "systemd_journald.forward_to_kmsg=")) {
2395 r = parse_boolean(word + 33);
2396 if (r < 0)
2397 log_warning("Failed to parse forward to kmsg switch %s. Ignoring.", word + 33);
2398 else
2399 s->forward_to_kmsg = r;
2400 } else if (startswith(word, "systemd_journald.forward_to_console=")) {
2401 r = parse_boolean(word + 36);
2402 if (r < 0)
2403 log_warning("Failed to parse forward to console switch %s. Ignoring.", word + 36);
2404 else
2405 s->forward_to_console = r;
2406 }
2407
2408 free(word);
2409 }
2410
2411 r = 0;
2412
2413finish:
2414 free(line);
2415 return r;
2416}
2417
e6960940
LP
2418static int server_parse_config_file(Server *s) {
2419 FILE *f;
2420 const char *fn;
2421 int r;
2422
2423 assert(s);
2424
2425 fn = "/etc/systemd/systemd-journald.conf";
2426 f = fopen(fn, "re");
2427 if (!f) {
2428 if (errno == ENOENT)
2429 return 0;
2430
2431 log_warning("Failed to open configuration file %s: %m", fn);
2432 return -errno;
2433 }
2434
2435 r = config_parse(fn, f, "Journal\0", config_item_perf_lookup, (void*) journald_gperf_lookup, false, s);
2436 if (r < 0)
2437 log_warning("Failed to parse configuration file: %s", strerror(-r));
2438
2439 fclose(f);
2440
2441 return r;
2442}
2443
fe652127
LP
2444static int server_init(Server *s) {
2445 int n, r, fd;
7f3e6257
LP
2446
2447 assert(s);
2448
2449 zero(*s);
6c1e6b98 2450 s->syslog_fd = s->native_fd = s->stdout_fd = s->signal_fd = s->epoll_fd = s->proc_kmsg_fd = -1;
807e17f0 2451 s->compress = true;
7f3e6257 2452
e6960940
LP
2453 s->rate_limit_interval = DEFAULT_RATE_LIMIT_INTERVAL;
2454 s->rate_limit_burst = DEFAULT_RATE_LIMIT_BURST;
2455
224f2ee2 2456 s->forward_to_syslog = true;
6c1e6b98 2457 s->import_proc_kmsg = true;
224f2ee2 2458
babfc091
LP
2459 memset(&s->system_metrics, 0xFF, sizeof(s->system_metrics));
2460 memset(&s->runtime_metrics, 0xFF, sizeof(s->runtime_metrics));
2461
e6960940 2462 server_parse_config_file(s);
effb1102 2463 server_parse_proc_cmdline(s);
e6960940 2464
fe652127
LP
2465 s->user_journals = hashmap_new(trivial_hash_func, trivial_compare_func);
2466 if (!s->user_journals) {
2467 log_error("Out of memory.");
2468 return -ENOMEM;
2469 }
2470
7f3e6257
LP
2471 s->epoll_fd = epoll_create1(EPOLL_CLOEXEC);
2472 if (s->epoll_fd < 0) {
2473 log_error("Failed to create epoll object: %m");
2474 return -errno;
2475 }
2476
2477 n = sd_listen_fds(true);
2478 if (n < 0) {
2479 log_error("Failed to read listening file descriptors from environment: %s", strerror(-n));
2480 return n;
2481 }
2482
2483 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd++) {
2484
259d2e76 2485 if (sd_is_socket_unix(fd, SOCK_DGRAM, -1, "/run/systemd/journal/socket", 0) > 0) {
7f3e6257 2486
fe652127
LP
2487 if (s->native_fd >= 0) {
2488 log_error("Too many native sockets passed.");
7f3e6257
LP
2489 return -EINVAL;
2490 }
2491
fe652127 2492 s->native_fd = fd;
7f3e6257 2493
259d2e76 2494 } else if (sd_is_socket_unix(fd, SOCK_STREAM, 1, "/run/systemd/journal/stdout", 0) > 0) {
7f3e6257 2495
fe652127
LP
2496 if (s->stdout_fd >= 0) {
2497 log_error("Too many stdout sockets passed.");
7f3e6257
LP
2498 return -EINVAL;
2499 }
2500
fe652127
LP
2501 s->stdout_fd = fd;
2502
2503 } else if (sd_is_socket_unix(fd, SOCK_DGRAM, -1, "/dev/log", 0) > 0) {
2504
2505 if (s->syslog_fd >= 0) {
2506 log_error("Too many /dev/log sockets passed.");
2507 return -EINVAL;
2508 }
2509
2510 s->syslog_fd = fd;
2511
7f3e6257
LP
2512 } else {
2513 log_error("Unknown socket passed.");
2514 return -EINVAL;
2515 }
2516 }
2517
2518 r = open_syslog_socket(s);
2519 if (r < 0)
2520 return r;
2521
7f3e6257
LP
2522 r = open_native_socket(s);
2523 if (r < 0)
2524 return r;
2525
fe652127
LP
2526 r = open_stdout_socket(s);
2527 if (r < 0)
2528 return r;
87d2c1ff 2529
6c1e6b98
LP
2530 r = open_proc_kmsg(s);
2531 if (r < 0)
2532 return r;
2533
ed49ef3f
LP
2534 r = system_journal_open(s);
2535 if (r < 0)
87d2c1ff 2536 return r;
87d2c1ff 2537
fe652127
LP
2538 r = open_signalfd(s);
2539 if (r < 0)
2540 return r;
87d2c1ff 2541
e6960940 2542 s->rate_limit = journal_rate_limit_new(s->rate_limit_interval, s->rate_limit_burst);
6e409ce1
LP
2543 if (!s->rate_limit)
2544 return -ENOMEM;
2545
87d2c1ff
LP
2546 return 0;
2547}
2548
2549static void server_done(Server *s) {
2550 JournalFile *f;
2551 assert(s);
2552
fe652127
LP
2553 while (s->stdout_streams)
2554 stdout_stream_free(s->stdout_streams);
2555
87d2c1ff
LP
2556 if (s->system_journal)
2557 journal_file_close(s->system_journal);
2558
f4b47811
LP
2559 if (s->runtime_journal)
2560 journal_file_close(s->runtime_journal);
2561
87d2c1ff
LP
2562 while ((f = hashmap_steal_first(s->user_journals)))
2563 journal_file_close(f);
2564
2565 hashmap_free(s->user_journals);
2566
2567 if (s->epoll_fd >= 0)
2568 close_nointr_nofail(s->epoll_fd);
2569
2570 if (s->signal_fd >= 0)
2571 close_nointr_nofail(s->signal_fd);
2572
2573 if (s->syslog_fd >= 0)
2574 close_nointr_nofail(s->syslog_fd);
7f3e6257
LP
2575
2576 if (s->native_fd >= 0)
2577 close_nointr_nofail(s->native_fd);
fe652127
LP
2578
2579 if (s->stdout_fd >= 0)
2580 close_nointr_nofail(s->stdout_fd);
6e409ce1 2581
6c1e6b98
LP
2582 if (s->proc_kmsg_fd >= 0)
2583 close_nointr_nofail(s->proc_kmsg_fd);
2584
6e409ce1
LP
2585 if (s->rate_limit)
2586 journal_rate_limit_free(s->rate_limit);
783d2675
LP
2587
2588 free(s->buffer);
87d2c1ff
LP
2589}
2590
2591int main(int argc, char *argv[]) {
2592 Server server;
2593 int r;
2594
2595 /* if (getppid() != 1) { */
2596 /* log_error("This program should be invoked by init only."); */
2597 /* return EXIT_FAILURE; */
2598 /* } */
2599
2600 if (argc > 1) {
2601 log_error("This program does not take arguments.");
2602 return EXIT_FAILURE;
2603 }
2604
f4b47811 2605 log_set_target(LOG_TARGET_CONSOLE);
87d2c1ff
LP
2606 log_parse_environment();
2607 log_open();
2608
2609 umask(0022);
2610
2611 r = server_init(&server);
2612 if (r < 0)
2613 goto finish;
2614
e6960940
LP
2615 server_vacuum(&server);
2616 server_flush_to_var(&server);
6c1e6b98 2617 server_flush_proc_kmsg(&server);
e6960940 2618
87d2c1ff 2619 log_debug("systemd-journald running as pid %lu", (unsigned long) getpid());
224f2ee2 2620 driver_message(&server, SD_MESSAGE_JOURNAL_START, "Journal started");
87d2c1ff
LP
2621
2622 sd_notify(false,
2623 "READY=1\n"
fe652127 2624 "STATUS=Processing requests...");
50f20cfd 2625
87d2c1ff
LP
2626 for (;;) {
2627 struct epoll_event event;
2628
2629 r = epoll_wait(server.epoll_fd, &event, 1, -1);
2630 if (r < 0) {
2631
2632 if (errno == EINTR)
2633 continue;
2634
2635 log_error("epoll_wait() failed: %m");
2636 r = -errno;
2637 goto finish;
2638 } else if (r == 0)
2639 break;
2640
2641 r = process_event(&server, &event);
2642 if (r < 0)
2643 goto finish;
2644 else if (r == 0)
2645 break;
2646 }
2647
fe652127 2648 log_debug("systemd-journald stopped as pid %lu", (unsigned long) getpid());
224f2ee2 2649 driver_message(&server, SD_MESSAGE_JOURNAL_STOP, "Journal stopped");
fe652127 2650
87d2c1ff
LP
2651finish:
2652 sd_notify(false,
2653 "STATUS=Shutting down...");
2654
2655 server_done(&server);
2656
2657 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
2658}