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