]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/journal/journalctl.c
Merge pull request #4061 from dm0-/coreos-1545
[thirdparty/systemd.git] / src / journal / journalctl.c
1 /***
2 This file is part of systemd.
3
4 Copyright 2011 Lennart Poettering
5
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
10
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
18 ***/
19
20 #include <errno.h>
21 #include <fcntl.h>
22 #include <fnmatch.h>
23 #include <getopt.h>
24 #include <linux/fs.h>
25 #include <locale.h>
26 #include <poll.h>
27 #include <signal.h>
28 #include <stddef.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <sys/inotify.h>
33 #include <sys/stat.h>
34 #include <unistd.h>
35
36 #include "sd-bus.h"
37 #include "sd-journal.h"
38
39 #include "acl-util.h"
40 #include "alloc-util.h"
41 #include "bus-error.h"
42 #include "bus-util.h"
43 #include "catalog.h"
44 #include "chattr-util.h"
45 #include "fd-util.h"
46 #include "fileio.h"
47 #include "fs-util.h"
48 #include "fsprg.h"
49 #include "glob-util.h"
50 #include "hostname-util.h"
51 #include "io-util.h"
52 #include "journal-def.h"
53 #include "journal-internal.h"
54 #include "journal-qrcode.h"
55 #include "journal-vacuum.h"
56 #include "journal-verify.h"
57 #include "locale-util.h"
58 #include "log.h"
59 #include "logs-show.h"
60 #include "mkdir.h"
61 #include "pager.h"
62 #include "parse-util.h"
63 #include "path-util.h"
64 #include "rlimit-util.h"
65 #include "set.h"
66 #include "sigbus.h"
67 #include "strv.h"
68 #include "syslog-util.h"
69 #include "terminal-util.h"
70 #include "udev.h"
71 #include "udev-util.h"
72 #include "unit-name.h"
73 #include "user-util.h"
74
75 #define DEFAULT_FSS_INTERVAL_USEC (15*USEC_PER_MINUTE)
76
77 enum {
78 /* Special values for arg_lines */
79 ARG_LINES_DEFAULT = -2,
80 ARG_LINES_ALL = -1,
81 };
82
83 static OutputMode arg_output = OUTPUT_SHORT;
84 static bool arg_utc = false;
85 static bool arg_pager_end = false;
86 static bool arg_follow = false;
87 static bool arg_full = true;
88 static bool arg_all = false;
89 static bool arg_no_pager = false;
90 static int arg_lines = ARG_LINES_DEFAULT;
91 static bool arg_no_tail = false;
92 static bool arg_quiet = false;
93 static bool arg_merge = false;
94 static bool arg_boot = false;
95 static sd_id128_t arg_boot_id = {};
96 static int arg_boot_offset = 0;
97 static bool arg_dmesg = false;
98 static bool arg_no_hostname = false;
99 static const char *arg_cursor = NULL;
100 static const char *arg_after_cursor = NULL;
101 static bool arg_show_cursor = false;
102 static const char *arg_directory = NULL;
103 static char **arg_file = NULL;
104 static bool arg_file_stdin = false;
105 static int arg_priorities = 0xFF;
106 static const char *arg_verify_key = NULL;
107 #ifdef HAVE_GCRYPT
108 static usec_t arg_interval = DEFAULT_FSS_INTERVAL_USEC;
109 static bool arg_force = false;
110 #endif
111 static usec_t arg_since, arg_until;
112 static bool arg_since_set = false, arg_until_set = false;
113 static char **arg_syslog_identifier = NULL;
114 static char **arg_system_units = NULL;
115 static char **arg_user_units = NULL;
116 static const char *arg_field = NULL;
117 static bool arg_catalog = false;
118 static bool arg_reverse = false;
119 static int arg_journal_type = 0;
120 static char *arg_root = NULL;
121 static const char *arg_machine = NULL;
122 static uint64_t arg_vacuum_size = 0;
123 static uint64_t arg_vacuum_n_files = 0;
124 static usec_t arg_vacuum_time = 0;
125
126 static enum {
127 ACTION_SHOW,
128 ACTION_NEW_ID128,
129 ACTION_PRINT_HEADER,
130 ACTION_SETUP_KEYS,
131 ACTION_VERIFY,
132 ACTION_DISK_USAGE,
133 ACTION_LIST_CATALOG,
134 ACTION_DUMP_CATALOG,
135 ACTION_UPDATE_CATALOG,
136 ACTION_LIST_BOOTS,
137 ACTION_FLUSH,
138 ACTION_SYNC,
139 ACTION_ROTATE,
140 ACTION_VACUUM,
141 ACTION_LIST_FIELDS,
142 ACTION_LIST_FIELD_NAMES,
143 } arg_action = ACTION_SHOW;
144
145 typedef struct BootId {
146 sd_id128_t id;
147 uint64_t first;
148 uint64_t last;
149 LIST_FIELDS(struct BootId, boot_list);
150 } BootId;
151
152 static int add_matches_for_device(sd_journal *j, const char *devpath) {
153 int r;
154 _cleanup_udev_unref_ struct udev *udev = NULL;
155 _cleanup_udev_device_unref_ struct udev_device *device = NULL;
156 struct udev_device *d = NULL;
157 struct stat st;
158
159 assert(j);
160 assert(devpath);
161
162 if (!path_startswith(devpath, "/dev/")) {
163 log_error("Devpath does not start with /dev/");
164 return -EINVAL;
165 }
166
167 udev = udev_new();
168 if (!udev)
169 return log_oom();
170
171 r = stat(devpath, &st);
172 if (r < 0)
173 log_error_errno(errno, "Couldn't stat file: %m");
174
175 d = device = udev_device_new_from_devnum(udev, S_ISBLK(st.st_mode) ? 'b' : 'c', st.st_rdev);
176 if (!device)
177 return log_error_errno(errno, "Failed to get udev device from devnum %u:%u: %m", major(st.st_rdev), minor(st.st_rdev));
178
179 while (d) {
180 _cleanup_free_ char *match = NULL;
181 const char *subsys, *sysname, *devnode;
182
183 subsys = udev_device_get_subsystem(d);
184 if (!subsys) {
185 d = udev_device_get_parent(d);
186 continue;
187 }
188
189 sysname = udev_device_get_sysname(d);
190 if (!sysname) {
191 d = udev_device_get_parent(d);
192 continue;
193 }
194
195 match = strjoin("_KERNEL_DEVICE=+", subsys, ":", sysname, NULL);
196 if (!match)
197 return log_oom();
198
199 r = sd_journal_add_match(j, match, 0);
200 if (r < 0)
201 return log_error_errno(r, "Failed to add match: %m");
202
203 devnode = udev_device_get_devnode(d);
204 if (devnode) {
205 _cleanup_free_ char *match1 = NULL;
206
207 r = stat(devnode, &st);
208 if (r < 0)
209 return log_error_errno(r, "Failed to stat() device node \"%s\": %m", devnode);
210
211 r = asprintf(&match1, "_KERNEL_DEVICE=%c%u:%u", S_ISBLK(st.st_mode) ? 'b' : 'c', major(st.st_rdev), minor(st.st_rdev));
212 if (r < 0)
213 return log_oom();
214
215 r = sd_journal_add_match(j, match1, 0);
216 if (r < 0)
217 return log_error_errno(r, "Failed to add match: %m");
218 }
219
220 d = udev_device_get_parent(d);
221 }
222
223 r = add_match_this_boot(j, arg_machine);
224 if (r < 0)
225 return log_error_errno(r, "Failed to add match for the current boot: %m");
226
227 return 0;
228 }
229
230 static char *format_timestamp_maybe_utc(char *buf, size_t l, usec_t t) {
231
232 if (arg_utc)
233 return format_timestamp_utc(buf, l, t);
234
235 return format_timestamp(buf, l, t);
236 }
237
238 static int parse_boot_descriptor(const char *x, sd_id128_t *boot_id, int *offset) {
239 sd_id128_t id = SD_ID128_NULL;
240 int off = 0, r;
241
242 if (strlen(x) >= 32) {
243 char *t;
244
245 t = strndupa(x, 32);
246 r = sd_id128_from_string(t, &id);
247 if (r >= 0)
248 x += 32;
249
250 if (*x != '-' && *x != '+' && *x != 0)
251 return -EINVAL;
252
253 if (*x != 0) {
254 r = safe_atoi(x, &off);
255 if (r < 0)
256 return r;
257 }
258 } else {
259 r = safe_atoi(x, &off);
260 if (r < 0)
261 return r;
262 }
263
264 if (boot_id)
265 *boot_id = id;
266
267 if (offset)
268 *offset = off;
269
270 return 0;
271 }
272
273 static void help(void) {
274
275 pager_open(arg_no_pager, arg_pager_end);
276
277 printf("%s [OPTIONS...] [MATCHES...]\n\n"
278 "Query the journal.\n\n"
279 "Options:\n"
280 " --system Show the system journal\n"
281 " --user Show the user journal for the current user\n"
282 " -M --machine=CONTAINER Operate on local container\n"
283 " -S --since=DATE Show entries not older than the specified date\n"
284 " -U --until=DATE Show entries not newer than the specified date\n"
285 " -c --cursor=CURSOR Show entries starting at the specified cursor\n"
286 " --after-cursor=CURSOR Show entries after the specified cursor\n"
287 " --show-cursor Print the cursor after all the entries\n"
288 " -b --boot[=ID] Show current boot or the specified boot\n"
289 " --list-boots Show terse information about recorded boots\n"
290 " -k --dmesg Show kernel message log from the current boot\n"
291 " -u --unit=UNIT Show logs from the specified unit\n"
292 " --user-unit=UNIT Show logs from the specified user unit\n"
293 " -t --identifier=STRING Show entries with the specified syslog identifier\n"
294 " -p --priority=RANGE Show entries with the specified priority\n"
295 " -e --pager-end Immediately jump to the end in the pager\n"
296 " -f --follow Follow the journal\n"
297 " -n --lines[=INTEGER] Number of journal entries to show\n"
298 " --no-tail Show all lines, even in follow mode\n"
299 " -r --reverse Show the newest entries first\n"
300 " -o --output=STRING Change journal output mode (short, short-precise,\n"
301 " short-iso, short-full, short-monotonic, short-unix,\n"
302 " verbose, export, json, json-pretty, json-sse, cat)\n"
303 " --utc Express time in Coordinated Universal Time (UTC)\n"
304 " -x --catalog Add message explanations where available\n"
305 " --no-full Ellipsize fields\n"
306 " -a --all Show all fields, including long and unprintable\n"
307 " -q --quiet Do not show info messages and privilege warning\n"
308 " --no-pager Do not pipe output into a pager\n"
309 " --no-hostname Suppress output of hostname field\n"
310 " -m --merge Show entries from all available journals\n"
311 " -D --directory=PATH Show journal files from directory\n"
312 " --file=PATH Show journal file\n"
313 " --root=ROOT Operate on files below a root directory\n"
314 #ifdef HAVE_GCRYPT
315 " --interval=TIME Time interval for changing the FSS sealing key\n"
316 " --verify-key=KEY Specify FSS verification key\n"
317 " --force Override of the FSS key pair with --setup-keys\n"
318 #endif
319 "\nCommands:\n"
320 " -h --help Show this help text\n"
321 " --version Show package version\n"
322 " -N --fields List all field names currently used\n"
323 " -F --field=FIELD List all values that a specified field takes\n"
324 " --disk-usage Show total disk usage of all journal files\n"
325 " --vacuum-size=BYTES Reduce disk usage below specified size\n"
326 " --vacuum-files=INT Leave only the specified number of journal files\n"
327 " --vacuum-time=TIME Remove journal files older than specified time\n"
328 " --verify Verify journal file consistency\n"
329 " --sync Synchronize unwritten journal messages to disk\n"
330 " --flush Flush all journal data from /run into /var\n"
331 " --rotate Request immediate rotation of the journal files\n"
332 " --header Show journal header information\n"
333 " --list-catalog Show all message IDs in the catalog\n"
334 " --dump-catalog Show entries in the message catalog\n"
335 " --update-catalog Update the message catalog database\n"
336 " --new-id128 Generate a new 128-bit ID\n"
337 #ifdef HAVE_GCRYPT
338 " --setup-keys Generate a new FSS key pair\n"
339 #endif
340 , program_invocation_short_name);
341 }
342
343 static int parse_argv(int argc, char *argv[]) {
344
345 enum {
346 ARG_VERSION = 0x100,
347 ARG_NO_PAGER,
348 ARG_NO_FULL,
349 ARG_NO_TAIL,
350 ARG_NEW_ID128,
351 ARG_THIS_BOOT,
352 ARG_LIST_BOOTS,
353 ARG_USER,
354 ARG_SYSTEM,
355 ARG_ROOT,
356 ARG_HEADER,
357 ARG_SETUP_KEYS,
358 ARG_FILE,
359 ARG_INTERVAL,
360 ARG_VERIFY,
361 ARG_VERIFY_KEY,
362 ARG_DISK_USAGE,
363 ARG_AFTER_CURSOR,
364 ARG_SHOW_CURSOR,
365 ARG_USER_UNIT,
366 ARG_LIST_CATALOG,
367 ARG_DUMP_CATALOG,
368 ARG_UPDATE_CATALOG,
369 ARG_FORCE,
370 ARG_UTC,
371 ARG_SYNC,
372 ARG_FLUSH,
373 ARG_ROTATE,
374 ARG_VACUUM_SIZE,
375 ARG_VACUUM_FILES,
376 ARG_VACUUM_TIME,
377 ARG_NO_HOSTNAME,
378 };
379
380 static const struct option options[] = {
381 { "help", no_argument, NULL, 'h' },
382 { "version" , no_argument, NULL, ARG_VERSION },
383 { "no-pager", no_argument, NULL, ARG_NO_PAGER },
384 { "pager-end", no_argument, NULL, 'e' },
385 { "follow", no_argument, NULL, 'f' },
386 { "force", no_argument, NULL, ARG_FORCE },
387 { "output", required_argument, NULL, 'o' },
388 { "all", no_argument, NULL, 'a' },
389 { "full", no_argument, NULL, 'l' },
390 { "no-full", no_argument, NULL, ARG_NO_FULL },
391 { "lines", optional_argument, NULL, 'n' },
392 { "no-tail", no_argument, NULL, ARG_NO_TAIL },
393 { "new-id128", no_argument, NULL, ARG_NEW_ID128 },
394 { "quiet", no_argument, NULL, 'q' },
395 { "merge", no_argument, NULL, 'm' },
396 { "this-boot", no_argument, NULL, ARG_THIS_BOOT }, /* deprecated */
397 { "boot", optional_argument, NULL, 'b' },
398 { "list-boots", no_argument, NULL, ARG_LIST_BOOTS },
399 { "dmesg", no_argument, NULL, 'k' },
400 { "system", no_argument, NULL, ARG_SYSTEM },
401 { "user", no_argument, NULL, ARG_USER },
402 { "directory", required_argument, NULL, 'D' },
403 { "file", required_argument, NULL, ARG_FILE },
404 { "root", required_argument, NULL, ARG_ROOT },
405 { "header", no_argument, NULL, ARG_HEADER },
406 { "identifier", required_argument, NULL, 't' },
407 { "priority", required_argument, NULL, 'p' },
408 { "setup-keys", no_argument, NULL, ARG_SETUP_KEYS },
409 { "interval", required_argument, NULL, ARG_INTERVAL },
410 { "verify", no_argument, NULL, ARG_VERIFY },
411 { "verify-key", required_argument, NULL, ARG_VERIFY_KEY },
412 { "disk-usage", no_argument, NULL, ARG_DISK_USAGE },
413 { "cursor", required_argument, NULL, 'c' },
414 { "after-cursor", required_argument, NULL, ARG_AFTER_CURSOR },
415 { "show-cursor", no_argument, NULL, ARG_SHOW_CURSOR },
416 { "since", required_argument, NULL, 'S' },
417 { "until", required_argument, NULL, 'U' },
418 { "unit", required_argument, NULL, 'u' },
419 { "user-unit", required_argument, NULL, ARG_USER_UNIT },
420 { "field", required_argument, NULL, 'F' },
421 { "fields", no_argument, NULL, 'N' },
422 { "catalog", no_argument, NULL, 'x' },
423 { "list-catalog", no_argument, NULL, ARG_LIST_CATALOG },
424 { "dump-catalog", no_argument, NULL, ARG_DUMP_CATALOG },
425 { "update-catalog", no_argument, NULL, ARG_UPDATE_CATALOG },
426 { "reverse", no_argument, NULL, 'r' },
427 { "machine", required_argument, NULL, 'M' },
428 { "utc", no_argument, NULL, ARG_UTC },
429 { "flush", no_argument, NULL, ARG_FLUSH },
430 { "sync", no_argument, NULL, ARG_SYNC },
431 { "rotate", no_argument, NULL, ARG_ROTATE },
432 { "vacuum-size", required_argument, NULL, ARG_VACUUM_SIZE },
433 { "vacuum-files", required_argument, NULL, ARG_VACUUM_FILES },
434 { "vacuum-time", required_argument, NULL, ARG_VACUUM_TIME },
435 { "no-hostname", no_argument, NULL, ARG_NO_HOSTNAME },
436 {}
437 };
438
439 int c, r;
440
441 assert(argc >= 0);
442 assert(argv);
443
444 while ((c = getopt_long(argc, argv, "hefo:aln::qmb::kD:p:c:S:U:t:u:NF:xrM:", options, NULL)) >= 0)
445
446 switch (c) {
447
448 case 'h':
449 help();
450 return 0;
451
452 case ARG_VERSION:
453 return version();
454
455 case ARG_NO_PAGER:
456 arg_no_pager = true;
457 break;
458
459 case 'e':
460 arg_pager_end = true;
461
462 if (arg_lines == ARG_LINES_DEFAULT)
463 arg_lines = 1000;
464
465 break;
466
467 case 'f':
468 arg_follow = true;
469 break;
470
471 case 'o':
472 arg_output = output_mode_from_string(optarg);
473 if (arg_output < 0) {
474 log_error("Unknown output format '%s'.", optarg);
475 return -EINVAL;
476 }
477
478 if (arg_output == OUTPUT_EXPORT ||
479 arg_output == OUTPUT_JSON ||
480 arg_output == OUTPUT_JSON_PRETTY ||
481 arg_output == OUTPUT_JSON_SSE ||
482 arg_output == OUTPUT_CAT)
483 arg_quiet = true;
484
485 break;
486
487 case 'l':
488 arg_full = true;
489 break;
490
491 case ARG_NO_FULL:
492 arg_full = false;
493 break;
494
495 case 'a':
496 arg_all = true;
497 break;
498
499 case 'n':
500 if (optarg) {
501 if (streq(optarg, "all"))
502 arg_lines = ARG_LINES_ALL;
503 else {
504 r = safe_atoi(optarg, &arg_lines);
505 if (r < 0 || arg_lines < 0) {
506 log_error("Failed to parse lines '%s'", optarg);
507 return -EINVAL;
508 }
509 }
510 } else {
511 arg_lines = 10;
512
513 /* Hmm, no argument? Maybe the next
514 * word on the command line is
515 * supposed to be the argument? Let's
516 * see if there is one, and is
517 * parsable. */
518 if (optind < argc) {
519 int n;
520 if (streq(argv[optind], "all")) {
521 arg_lines = ARG_LINES_ALL;
522 optind++;
523 } else if (safe_atoi(argv[optind], &n) >= 0 && n >= 0) {
524 arg_lines = n;
525 optind++;
526 }
527 }
528 }
529
530 break;
531
532 case ARG_NO_TAIL:
533 arg_no_tail = true;
534 break;
535
536 case ARG_NEW_ID128:
537 arg_action = ACTION_NEW_ID128;
538 break;
539
540 case 'q':
541 arg_quiet = true;
542 break;
543
544 case 'm':
545 arg_merge = true;
546 break;
547
548 case ARG_THIS_BOOT:
549 arg_boot = true;
550 break;
551
552 case 'b':
553 arg_boot = true;
554
555 if (optarg) {
556 r = parse_boot_descriptor(optarg, &arg_boot_id, &arg_boot_offset);
557 if (r < 0) {
558 log_error("Failed to parse boot descriptor '%s'", optarg);
559 return -EINVAL;
560 }
561 } else {
562
563 /* Hmm, no argument? Maybe the next
564 * word on the command line is
565 * supposed to be the argument? Let's
566 * see if there is one and is parsable
567 * as a boot descriptor... */
568
569 if (optind < argc &&
570 parse_boot_descriptor(argv[optind], &arg_boot_id, &arg_boot_offset) >= 0)
571 optind++;
572 }
573
574 break;
575
576 case ARG_LIST_BOOTS:
577 arg_action = ACTION_LIST_BOOTS;
578 break;
579
580 case 'k':
581 arg_boot = arg_dmesg = true;
582 break;
583
584 case ARG_SYSTEM:
585 arg_journal_type |= SD_JOURNAL_SYSTEM;
586 break;
587
588 case ARG_USER:
589 arg_journal_type |= SD_JOURNAL_CURRENT_USER;
590 break;
591
592 case 'M':
593 arg_machine = optarg;
594 break;
595
596 case 'D':
597 arg_directory = optarg;
598 break;
599
600 case ARG_FILE:
601 if (streq(optarg, "-"))
602 /* An undocumented feature: we can read journal files from STDIN. We don't document
603 * this though, since after all we only support this for mmap-able, seekable files, and
604 * not for example pipes which are probably the primary usecase for reading things from
605 * STDIN. To avoid confusion we hence don't document this feature. */
606 arg_file_stdin = true;
607 else {
608 r = glob_extend(&arg_file, optarg);
609 if (r < 0)
610 return log_error_errno(r, "Failed to add paths: %m");
611 }
612 break;
613
614 case ARG_ROOT:
615 r = parse_path_argument_and_warn(optarg, true, &arg_root);
616 if (r < 0)
617 return r;
618 break;
619
620 case 'c':
621 arg_cursor = optarg;
622 break;
623
624 case ARG_AFTER_CURSOR:
625 arg_after_cursor = optarg;
626 break;
627
628 case ARG_SHOW_CURSOR:
629 arg_show_cursor = true;
630 break;
631
632 case ARG_HEADER:
633 arg_action = ACTION_PRINT_HEADER;
634 break;
635
636 case ARG_VERIFY:
637 arg_action = ACTION_VERIFY;
638 break;
639
640 case ARG_DISK_USAGE:
641 arg_action = ACTION_DISK_USAGE;
642 break;
643
644 case ARG_VACUUM_SIZE:
645 r = parse_size(optarg, 1024, &arg_vacuum_size);
646 if (r < 0) {
647 log_error("Failed to parse vacuum size: %s", optarg);
648 return r;
649 }
650
651 arg_action = ACTION_VACUUM;
652 break;
653
654 case ARG_VACUUM_FILES:
655 r = safe_atou64(optarg, &arg_vacuum_n_files);
656 if (r < 0) {
657 log_error("Failed to parse vacuum files: %s", optarg);
658 return r;
659 }
660
661 arg_action = ACTION_VACUUM;
662 break;
663
664 case ARG_VACUUM_TIME:
665 r = parse_sec(optarg, &arg_vacuum_time);
666 if (r < 0) {
667 log_error("Failed to parse vacuum time: %s", optarg);
668 return r;
669 }
670
671 arg_action = ACTION_VACUUM;
672 break;
673
674 #ifdef HAVE_GCRYPT
675 case ARG_FORCE:
676 arg_force = true;
677 break;
678
679 case ARG_SETUP_KEYS:
680 arg_action = ACTION_SETUP_KEYS;
681 break;
682
683
684 case ARG_VERIFY_KEY:
685 arg_action = ACTION_VERIFY;
686 arg_verify_key = optarg;
687 arg_merge = false;
688 break;
689
690 case ARG_INTERVAL:
691 r = parse_sec(optarg, &arg_interval);
692 if (r < 0 || arg_interval <= 0) {
693 log_error("Failed to parse sealing key change interval: %s", optarg);
694 return -EINVAL;
695 }
696 break;
697 #else
698 case ARG_SETUP_KEYS:
699 case ARG_VERIFY_KEY:
700 case ARG_INTERVAL:
701 case ARG_FORCE:
702 log_error("Forward-secure sealing not available.");
703 return -EOPNOTSUPP;
704 #endif
705
706 case 'p': {
707 const char *dots;
708
709 dots = strstr(optarg, "..");
710 if (dots) {
711 char *a;
712 int from, to, i;
713
714 /* a range */
715 a = strndup(optarg, dots - optarg);
716 if (!a)
717 return log_oom();
718
719 from = log_level_from_string(a);
720 to = log_level_from_string(dots + 2);
721 free(a);
722
723 if (from < 0 || to < 0) {
724 log_error("Failed to parse log level range %s", optarg);
725 return -EINVAL;
726 }
727
728 arg_priorities = 0;
729
730 if (from < to) {
731 for (i = from; i <= to; i++)
732 arg_priorities |= 1 << i;
733 } else {
734 for (i = to; i <= from; i++)
735 arg_priorities |= 1 << i;
736 }
737
738 } else {
739 int p, i;
740
741 p = log_level_from_string(optarg);
742 if (p < 0) {
743 log_error("Unknown log level %s", optarg);
744 return -EINVAL;
745 }
746
747 arg_priorities = 0;
748
749 for (i = 0; i <= p; i++)
750 arg_priorities |= 1 << i;
751 }
752
753 break;
754 }
755
756 case 'S':
757 r = parse_timestamp(optarg, &arg_since);
758 if (r < 0) {
759 log_error("Failed to parse timestamp: %s", optarg);
760 return -EINVAL;
761 }
762 arg_since_set = true;
763 break;
764
765 case 'U':
766 r = parse_timestamp(optarg, &arg_until);
767 if (r < 0) {
768 log_error("Failed to parse timestamp: %s", optarg);
769 return -EINVAL;
770 }
771 arg_until_set = true;
772 break;
773
774 case 't':
775 r = strv_extend(&arg_syslog_identifier, optarg);
776 if (r < 0)
777 return log_oom();
778 break;
779
780 case 'u':
781 r = strv_extend(&arg_system_units, optarg);
782 if (r < 0)
783 return log_oom();
784 break;
785
786 case ARG_USER_UNIT:
787 r = strv_extend(&arg_user_units, optarg);
788 if (r < 0)
789 return log_oom();
790 break;
791
792 case 'F':
793 arg_action = ACTION_LIST_FIELDS;
794 arg_field = optarg;
795 break;
796
797 case 'N':
798 arg_action = ACTION_LIST_FIELD_NAMES;
799 break;
800
801 case ARG_NO_HOSTNAME:
802 arg_no_hostname = true;
803 break;
804
805 case 'x':
806 arg_catalog = true;
807 break;
808
809 case ARG_LIST_CATALOG:
810 arg_action = ACTION_LIST_CATALOG;
811 break;
812
813 case ARG_DUMP_CATALOG:
814 arg_action = ACTION_DUMP_CATALOG;
815 break;
816
817 case ARG_UPDATE_CATALOG:
818 arg_action = ACTION_UPDATE_CATALOG;
819 break;
820
821 case 'r':
822 arg_reverse = true;
823 break;
824
825 case ARG_UTC:
826 arg_utc = true;
827 break;
828
829 case ARG_FLUSH:
830 arg_action = ACTION_FLUSH;
831 break;
832
833 case ARG_ROTATE:
834 arg_action = ACTION_ROTATE;
835 break;
836
837 case ARG_SYNC:
838 arg_action = ACTION_SYNC;
839 break;
840
841 case '?':
842 return -EINVAL;
843
844 default:
845 assert_not_reached("Unhandled option");
846 }
847
848 if (arg_follow && !arg_no_tail && !arg_since && arg_lines == ARG_LINES_DEFAULT)
849 arg_lines = 10;
850
851 if (!!arg_directory + !!arg_file + !!arg_machine + !!arg_root > 1) {
852 log_error("Please specify at most one of -D/--directory=, --file=, -M/--machine=, --root.");
853 return -EINVAL;
854 }
855
856 if (arg_since_set && arg_until_set && arg_since > arg_until) {
857 log_error("--since= must be before --until=.");
858 return -EINVAL;
859 }
860
861 if (!!arg_cursor + !!arg_after_cursor + !!arg_since_set > 1) {
862 log_error("Please specify only one of --since=, --cursor=, and --after-cursor.");
863 return -EINVAL;
864 }
865
866 if (arg_follow && arg_reverse) {
867 log_error("Please specify either --reverse= or --follow=, not both.");
868 return -EINVAL;
869 }
870
871 if (!IN_SET(arg_action, ACTION_SHOW, ACTION_DUMP_CATALOG, ACTION_LIST_CATALOG) && optind < argc) {
872 log_error("Extraneous arguments starting with '%s'", argv[optind]);
873 return -EINVAL;
874 }
875
876 if ((arg_boot || arg_action == ACTION_LIST_BOOTS) && arg_merge) {
877 log_error("Using --boot or --list-boots with --merge is not supported.");
878 return -EINVAL;
879 }
880
881 if (!strv_isempty(arg_system_units) && (arg_journal_type == SD_JOURNAL_CURRENT_USER)) {
882
883 /* Specifying --user and --unit= at the same time makes no sense (as the former excludes the user
884 * journal, but the latter excludes the system journal, thus resulting in empty output). Let's be nice
885 * to users, and automatically turn --unit= into --user-unit= if combined with --user. */
886 r = strv_extend_strv(&arg_user_units, arg_system_units, true);
887 if (r < 0)
888 return -ENOMEM;
889
890 arg_system_units = strv_free(arg_system_units);
891 }
892
893 return 1;
894 }
895
896 static int generate_new_id128(void) {
897 sd_id128_t id;
898 int r;
899 unsigned i;
900
901 r = sd_id128_randomize(&id);
902 if (r < 0)
903 return log_error_errno(r, "Failed to generate ID: %m");
904
905 printf("As string:\n"
906 SD_ID128_FORMAT_STR "\n\n"
907 "As UUID:\n"
908 "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n\n"
909 "As macro:\n"
910 "#define MESSAGE_XYZ SD_ID128_MAKE(",
911 SD_ID128_FORMAT_VAL(id),
912 SD_ID128_FORMAT_VAL(id));
913 for (i = 0; i < 16; i++)
914 printf("%02x%s", id.bytes[i], i != 15 ? "," : "");
915 fputs(")\n\n", stdout);
916
917 printf("As Python constant:\n"
918 ">>> import uuid\n"
919 ">>> MESSAGE_XYZ = uuid.UUID('" SD_ID128_FORMAT_STR "')\n",
920 SD_ID128_FORMAT_VAL(id));
921
922 return 0;
923 }
924
925 static int add_matches(sd_journal *j, char **args) {
926 char **i;
927 bool have_term = false;
928
929 assert(j);
930
931 STRV_FOREACH(i, args) {
932 int r;
933
934 if (streq(*i, "+")) {
935 if (!have_term)
936 break;
937 r = sd_journal_add_disjunction(j);
938 have_term = false;
939
940 } else if (path_is_absolute(*i)) {
941 _cleanup_free_ char *p, *t = NULL, *t2 = NULL, *interpreter = NULL;
942 const char *path;
943 struct stat st;
944
945 p = canonicalize_file_name(*i);
946 path = p ?: *i;
947
948 if (lstat(path, &st) < 0)
949 return log_error_errno(errno, "Couldn't stat file: %m");
950
951 if (S_ISREG(st.st_mode) && (0111 & st.st_mode)) {
952 if (executable_is_script(path, &interpreter) > 0) {
953 _cleanup_free_ char *comm;
954
955 comm = strndup(basename(path), 15);
956 if (!comm)
957 return log_oom();
958
959 t = strappend("_COMM=", comm);
960 if (!t)
961 return log_oom();
962
963 /* Append _EXE only if the interpreter is not a link.
964 Otherwise, it might be outdated often. */
965 if (lstat(interpreter, &st) == 0 && !S_ISLNK(st.st_mode)) {
966 t2 = strappend("_EXE=", interpreter);
967 if (!t2)
968 return log_oom();
969 }
970 } else {
971 t = strappend("_EXE=", path);
972 if (!t)
973 return log_oom();
974 }
975
976 r = sd_journal_add_match(j, t, 0);
977
978 if (r >=0 && t2)
979 r = sd_journal_add_match(j, t2, 0);
980
981 } else if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) {
982 r = add_matches_for_device(j, path);
983 if (r < 0)
984 return r;
985 } else {
986 log_error("File is neither a device node, nor regular file, nor executable: %s", *i);
987 return -EINVAL;
988 }
989
990 have_term = true;
991 } else {
992 r = sd_journal_add_match(j, *i, 0);
993 have_term = true;
994 }
995
996 if (r < 0)
997 return log_error_errno(r, "Failed to add match '%s': %m", *i);
998 }
999
1000 if (!strv_isempty(args) && !have_term) {
1001 log_error("\"+\" can only be used between terms");
1002 return -EINVAL;
1003 }
1004
1005 return 0;
1006 }
1007
1008 static void boot_id_free_all(BootId *l) {
1009
1010 while (l) {
1011 BootId *i = l;
1012 LIST_REMOVE(boot_list, l, i);
1013 free(i);
1014 }
1015 }
1016
1017 static int discover_next_boot(sd_journal *j,
1018 sd_id128_t previous_boot_id,
1019 bool advance_older,
1020 BootId **ret) {
1021
1022 _cleanup_free_ BootId *next_boot = NULL;
1023 char match[9+32+1] = "_BOOT_ID=";
1024 sd_id128_t boot_id;
1025 int r;
1026
1027 assert(j);
1028 assert(ret);
1029
1030 /* We expect the journal to be on the last position of a boot
1031 * (in relation to the direction we are going), so that the next
1032 * invocation of sd_journal_next/previous will be from a different
1033 * boot. We then collect any information we desire and then jump
1034 * to the last location of the new boot by using a _BOOT_ID match
1035 * coming from the other journal direction. */
1036
1037 /* Make sure we aren't restricted by any _BOOT_ID matches, so that
1038 * we can actually advance to a *different* boot. */
1039 sd_journal_flush_matches(j);
1040
1041 do {
1042 if (advance_older)
1043 r = sd_journal_previous(j);
1044 else
1045 r = sd_journal_next(j);
1046 if (r < 0)
1047 return r;
1048 else if (r == 0)
1049 return 0; /* End of journal, yay. */
1050
1051 r = sd_journal_get_monotonic_usec(j, NULL, &boot_id);
1052 if (r < 0)
1053 return r;
1054
1055 /* We iterate through this in a loop, until the boot ID differs from the previous one. Note that
1056 * normally, this will only require a single iteration, as we seeked to the last entry of the previous
1057 * boot entry already. However, it might happen that the per-journal-field entry arrays are less
1058 * complete than the main entry array, and hence might reference an entry that's not actually the last
1059 * one of the boot ID as last one. Let's hence use the per-field array is initial seek position to
1060 * speed things up, but let's not trust that it is complete, and hence, manually advance as
1061 * necessary. */
1062
1063 } while (sd_id128_equal(boot_id, previous_boot_id));
1064
1065 next_boot = new0(BootId, 1);
1066 if (!next_boot)
1067 return -ENOMEM;
1068
1069 next_boot->id = boot_id;
1070
1071 r = sd_journal_get_realtime_usec(j, &next_boot->first);
1072 if (r < 0)
1073 return r;
1074
1075 /* Now seek to the last occurrence of this boot ID. */
1076 sd_id128_to_string(next_boot->id, match + 9);
1077 r = sd_journal_add_match(j, match, sizeof(match) - 1);
1078 if (r < 0)
1079 return r;
1080
1081 if (advance_older)
1082 r = sd_journal_seek_head(j);
1083 else
1084 r = sd_journal_seek_tail(j);
1085 if (r < 0)
1086 return r;
1087
1088 if (advance_older)
1089 r = sd_journal_next(j);
1090 else
1091 r = sd_journal_previous(j);
1092 if (r < 0)
1093 return r;
1094 else if (r == 0)
1095 return -ENODATA; /* This shouldn't happen. We just came from this very boot ID. */
1096
1097 r = sd_journal_get_realtime_usec(j, &next_boot->last);
1098 if (r < 0)
1099 return r;
1100
1101 *ret = next_boot;
1102 next_boot = NULL;
1103
1104 return 0;
1105 }
1106
1107 static int get_boots(
1108 sd_journal *j,
1109 BootId **boots,
1110 sd_id128_t *boot_id,
1111 int offset) {
1112
1113 bool skip_once;
1114 int r, count = 0;
1115 BootId *head = NULL, *tail = NULL;
1116 const bool advance_older = boot_id && offset <= 0;
1117 sd_id128_t previous_boot_id;
1118
1119 assert(j);
1120
1121 /* Adjust for the asymmetry that offset 0 is
1122 * the last (and current) boot, while 1 is considered the
1123 * (chronological) first boot in the journal. */
1124 skip_once = boot_id && sd_id128_is_null(*boot_id) && offset <= 0;
1125
1126 /* Advance to the earliest/latest occurrence of our reference
1127 * boot ID (taking our lookup direction into account), so that
1128 * discover_next_boot() can do its job.
1129 * If no reference is given, the journal head/tail will do,
1130 * they're "virtual" boots after all. */
1131 if (boot_id && !sd_id128_is_null(*boot_id)) {
1132 char match[9+32+1] = "_BOOT_ID=";
1133
1134 sd_journal_flush_matches(j);
1135
1136 sd_id128_to_string(*boot_id, match + 9);
1137 r = sd_journal_add_match(j, match, sizeof(match) - 1);
1138 if (r < 0)
1139 return r;
1140
1141 if (advance_older)
1142 r = sd_journal_seek_head(j); /* seek to oldest */
1143 else
1144 r = sd_journal_seek_tail(j); /* seek to newest */
1145 if (r < 0)
1146 return r;
1147
1148 if (advance_older)
1149 r = sd_journal_next(j); /* read the oldest entry */
1150 else
1151 r = sd_journal_previous(j); /* read the most recently added entry */
1152 if (r < 0)
1153 return r;
1154 else if (r == 0)
1155 goto finish;
1156 else if (offset == 0) {
1157 count = 1;
1158 goto finish;
1159 }
1160
1161 /* At this point the read pointer is positioned at the oldest/newest occurence of the reference boot
1162 * ID. After flushing the matches, one more invocation of _previous()/_next() will hence place us at
1163 * the following entry, which must then have an older/newer boot ID */
1164 } else {
1165
1166 if (advance_older)
1167 r = sd_journal_seek_tail(j); /* seek to newest */
1168 else
1169 r = sd_journal_seek_head(j); /* seek to oldest */
1170 if (r < 0)
1171 return r;
1172
1173 /* No sd_journal_next()/_previous() here.
1174 *
1175 * At this point the read pointer is positioned after the newest/before the oldest entry in the whole
1176 * journal. The next invocation of _previous()/_next() will hence position us at the newest/oldest
1177 * entry we have. */
1178 }
1179
1180 previous_boot_id = SD_ID128_NULL;
1181 for (;;) {
1182 _cleanup_free_ BootId *current = NULL;
1183
1184 r = discover_next_boot(j, previous_boot_id, advance_older, &current);
1185 if (r < 0) {
1186 boot_id_free_all(head);
1187 return r;
1188 }
1189
1190 if (!current)
1191 break;
1192
1193 previous_boot_id = current->id;
1194
1195 if (boot_id) {
1196 if (!skip_once)
1197 offset += advance_older ? 1 : -1;
1198 skip_once = false;
1199
1200 if (offset == 0) {
1201 count = 1;
1202 *boot_id = current->id;
1203 break;
1204 }
1205 } else {
1206 LIST_INSERT_AFTER(boot_list, head, tail, current);
1207 tail = current;
1208 current = NULL;
1209 count++;
1210 }
1211 }
1212
1213 finish:
1214 if (boots)
1215 *boots = head;
1216
1217 sd_journal_flush_matches(j);
1218
1219 return count;
1220 }
1221
1222 static int list_boots(sd_journal *j) {
1223 int w, i, count;
1224 BootId *id, *all_ids;
1225
1226 assert(j);
1227
1228 count = get_boots(j, &all_ids, NULL, 0);
1229 if (count < 0)
1230 return log_error_errno(count, "Failed to determine boots: %m");
1231 if (count == 0)
1232 return count;
1233
1234 pager_open(arg_no_pager, arg_pager_end);
1235
1236 /* numbers are one less, but we need an extra char for the sign */
1237 w = DECIMAL_STR_WIDTH(count - 1) + 1;
1238
1239 i = 0;
1240 LIST_FOREACH(boot_list, id, all_ids) {
1241 char a[FORMAT_TIMESTAMP_MAX], b[FORMAT_TIMESTAMP_MAX];
1242
1243 printf("% *i " SD_ID128_FORMAT_STR " %s—%s\n",
1244 w, i - count + 1,
1245 SD_ID128_FORMAT_VAL(id->id),
1246 format_timestamp_maybe_utc(a, sizeof(a), id->first),
1247 format_timestamp_maybe_utc(b, sizeof(b), id->last));
1248 i++;
1249 }
1250
1251 boot_id_free_all(all_ids);
1252
1253 return 0;
1254 }
1255
1256 static int add_boot(sd_journal *j) {
1257 char match[9+32+1] = "_BOOT_ID=";
1258 sd_id128_t boot_id;
1259 int r;
1260
1261 assert(j);
1262
1263 if (!arg_boot)
1264 return 0;
1265
1266 /* Take a shortcut and use the current boot_id, which we can do very quickly.
1267 * We can do this only when we logs are coming from the current machine,
1268 * so take the slow path if log location is specified. */
1269 if (arg_boot_offset == 0 && sd_id128_is_null(arg_boot_id) &&
1270 !arg_directory && !arg_file && !arg_root)
1271
1272 return add_match_this_boot(j, arg_machine);
1273
1274 boot_id = arg_boot_id;
1275 r = get_boots(j, NULL, &boot_id, arg_boot_offset);
1276 assert(r <= 1);
1277 if (r <= 0) {
1278 const char *reason = (r == 0) ? "No such boot ID in journal" : strerror(-r);
1279
1280 if (sd_id128_is_null(arg_boot_id))
1281 log_error("Data from the specified boot (%+i) is not available: %s",
1282 arg_boot_offset, reason);
1283 else
1284 log_error("Data from the specified boot ("SD_ID128_FORMAT_STR") is not available: %s",
1285 SD_ID128_FORMAT_VAL(arg_boot_id), reason);
1286
1287 return r == 0 ? -ENODATA : r;
1288 }
1289
1290 sd_id128_to_string(boot_id, match + 9);
1291
1292 r = sd_journal_add_match(j, match, sizeof(match) - 1);
1293 if (r < 0)
1294 return log_error_errno(r, "Failed to add match: %m");
1295
1296 r = sd_journal_add_conjunction(j);
1297 if (r < 0)
1298 return log_error_errno(r, "Failed to add conjunction: %m");
1299
1300 return 0;
1301 }
1302
1303 static int add_dmesg(sd_journal *j) {
1304 int r;
1305 assert(j);
1306
1307 if (!arg_dmesg)
1308 return 0;
1309
1310 r = sd_journal_add_match(j, "_TRANSPORT=kernel", strlen("_TRANSPORT=kernel"));
1311 if (r < 0)
1312 return log_error_errno(r, "Failed to add match: %m");
1313
1314 r = sd_journal_add_conjunction(j);
1315 if (r < 0)
1316 return log_error_errno(r, "Failed to add conjunction: %m");
1317
1318 return 0;
1319 }
1320
1321 static int get_possible_units(
1322 sd_journal *j,
1323 const char *fields,
1324 char **patterns,
1325 Set **units) {
1326
1327 _cleanup_set_free_free_ Set *found;
1328 const char *field;
1329 int r;
1330
1331 found = set_new(&string_hash_ops);
1332 if (!found)
1333 return -ENOMEM;
1334
1335 NULSTR_FOREACH(field, fields) {
1336 const void *data;
1337 size_t size;
1338
1339 r = sd_journal_query_unique(j, field);
1340 if (r < 0)
1341 return r;
1342
1343 SD_JOURNAL_FOREACH_UNIQUE(j, data, size) {
1344 char **pattern, *eq;
1345 size_t prefix;
1346 _cleanup_free_ char *u = NULL;
1347
1348 eq = memchr(data, '=', size);
1349 if (eq)
1350 prefix = eq - (char*) data + 1;
1351 else
1352 prefix = 0;
1353
1354 u = strndup((char*) data + prefix, size - prefix);
1355 if (!u)
1356 return -ENOMEM;
1357
1358 STRV_FOREACH(pattern, patterns)
1359 if (fnmatch(*pattern, u, FNM_NOESCAPE) == 0) {
1360 log_debug("Matched %s with pattern %s=%s", u, field, *pattern);
1361
1362 r = set_consume(found, u);
1363 u = NULL;
1364 if (r < 0 && r != -EEXIST)
1365 return r;
1366
1367 break;
1368 }
1369 }
1370 }
1371
1372 *units = found;
1373 found = NULL;
1374 return 0;
1375 }
1376
1377 /* This list is supposed to return the superset of unit names
1378 * possibly matched by rules added with add_matches_for_unit... */
1379 #define SYSTEM_UNITS \
1380 "_SYSTEMD_UNIT\0" \
1381 "COREDUMP_UNIT\0" \
1382 "UNIT\0" \
1383 "OBJECT_SYSTEMD_UNIT\0" \
1384 "_SYSTEMD_SLICE\0"
1385
1386 /* ... and add_matches_for_user_unit */
1387 #define USER_UNITS \
1388 "_SYSTEMD_USER_UNIT\0" \
1389 "USER_UNIT\0" \
1390 "COREDUMP_USER_UNIT\0" \
1391 "OBJECT_SYSTEMD_USER_UNIT\0"
1392
1393 static int add_units(sd_journal *j) {
1394 _cleanup_strv_free_ char **patterns = NULL;
1395 int r, count = 0;
1396 char **i;
1397
1398 assert(j);
1399
1400 STRV_FOREACH(i, arg_system_units) {
1401 _cleanup_free_ char *u = NULL;
1402
1403 r = unit_name_mangle(*i, UNIT_NAME_GLOB, &u);
1404 if (r < 0)
1405 return r;
1406
1407 if (string_is_glob(u)) {
1408 r = strv_push(&patterns, u);
1409 if (r < 0)
1410 return r;
1411 u = NULL;
1412 } else {
1413 r = add_matches_for_unit(j, u);
1414 if (r < 0)
1415 return r;
1416 r = sd_journal_add_disjunction(j);
1417 if (r < 0)
1418 return r;
1419 count++;
1420 }
1421 }
1422
1423 if (!strv_isempty(patterns)) {
1424 _cleanup_set_free_free_ Set *units = NULL;
1425 Iterator it;
1426 char *u;
1427
1428 r = get_possible_units(j, SYSTEM_UNITS, patterns, &units);
1429 if (r < 0)
1430 return r;
1431
1432 SET_FOREACH(u, units, it) {
1433 r = add_matches_for_unit(j, u);
1434 if (r < 0)
1435 return r;
1436 r = sd_journal_add_disjunction(j);
1437 if (r < 0)
1438 return r;
1439 count++;
1440 }
1441 }
1442
1443 patterns = strv_free(patterns);
1444
1445 STRV_FOREACH(i, arg_user_units) {
1446 _cleanup_free_ char *u = NULL;
1447
1448 r = unit_name_mangle(*i, UNIT_NAME_GLOB, &u);
1449 if (r < 0)
1450 return r;
1451
1452 if (string_is_glob(u)) {
1453 r = strv_push(&patterns, u);
1454 if (r < 0)
1455 return r;
1456 u = NULL;
1457 } else {
1458 r = add_matches_for_user_unit(j, u, getuid());
1459 if (r < 0)
1460 return r;
1461 r = sd_journal_add_disjunction(j);
1462 if (r < 0)
1463 return r;
1464 count++;
1465 }
1466 }
1467
1468 if (!strv_isempty(patterns)) {
1469 _cleanup_set_free_free_ Set *units = NULL;
1470 Iterator it;
1471 char *u;
1472
1473 r = get_possible_units(j, USER_UNITS, patterns, &units);
1474 if (r < 0)
1475 return r;
1476
1477 SET_FOREACH(u, units, it) {
1478 r = add_matches_for_user_unit(j, u, getuid());
1479 if (r < 0)
1480 return r;
1481 r = sd_journal_add_disjunction(j);
1482 if (r < 0)
1483 return r;
1484 count++;
1485 }
1486 }
1487
1488 /* Complain if the user request matches but nothing whatsoever was
1489 * found, since otherwise everything would be matched. */
1490 if (!(strv_isempty(arg_system_units) && strv_isempty(arg_user_units)) && count == 0)
1491 return -ENODATA;
1492
1493 r = sd_journal_add_conjunction(j);
1494 if (r < 0)
1495 return r;
1496
1497 return 0;
1498 }
1499
1500 static int add_priorities(sd_journal *j) {
1501 char match[] = "PRIORITY=0";
1502 int i, r;
1503 assert(j);
1504
1505 if (arg_priorities == 0xFF)
1506 return 0;
1507
1508 for (i = LOG_EMERG; i <= LOG_DEBUG; i++)
1509 if (arg_priorities & (1 << i)) {
1510 match[sizeof(match)-2] = '0' + i;
1511
1512 r = sd_journal_add_match(j, match, strlen(match));
1513 if (r < 0)
1514 return log_error_errno(r, "Failed to add match: %m");
1515 }
1516
1517 r = sd_journal_add_conjunction(j);
1518 if (r < 0)
1519 return log_error_errno(r, "Failed to add conjunction: %m");
1520
1521 return 0;
1522 }
1523
1524
1525 static int add_syslog_identifier(sd_journal *j) {
1526 int r;
1527 char **i;
1528
1529 assert(j);
1530
1531 STRV_FOREACH(i, arg_syslog_identifier) {
1532 char *u;
1533
1534 u = strjoina("SYSLOG_IDENTIFIER=", *i);
1535 r = sd_journal_add_match(j, u, 0);
1536 if (r < 0)
1537 return r;
1538 r = sd_journal_add_disjunction(j);
1539 if (r < 0)
1540 return r;
1541 }
1542
1543 r = sd_journal_add_conjunction(j);
1544 if (r < 0)
1545 return r;
1546
1547 return 0;
1548 }
1549
1550 static int setup_keys(void) {
1551 #ifdef HAVE_GCRYPT
1552 size_t mpk_size, seed_size, state_size, i;
1553 uint8_t *mpk, *seed, *state;
1554 int fd = -1, r;
1555 sd_id128_t machine, boot;
1556 char *p = NULL, *k = NULL;
1557 struct FSSHeader h;
1558 uint64_t n;
1559 struct stat st;
1560
1561 r = stat("/var/log/journal", &st);
1562 if (r < 0 && errno != ENOENT && errno != ENOTDIR)
1563 return log_error_errno(errno, "stat(\"%s\") failed: %m", "/var/log/journal");
1564
1565 if (r < 0 || !S_ISDIR(st.st_mode)) {
1566 log_error("%s is not a directory, must be using persistent logging for FSS.",
1567 "/var/log/journal");
1568 return r < 0 ? -errno : -ENOTDIR;
1569 }
1570
1571 r = sd_id128_get_machine(&machine);
1572 if (r < 0)
1573 return log_error_errno(r, "Failed to get machine ID: %m");
1574
1575 r = sd_id128_get_boot(&boot);
1576 if (r < 0)
1577 return log_error_errno(r, "Failed to get boot ID: %m");
1578
1579 if (asprintf(&p, "/var/log/journal/" SD_ID128_FORMAT_STR "/fss",
1580 SD_ID128_FORMAT_VAL(machine)) < 0)
1581 return log_oom();
1582
1583 if (arg_force) {
1584 r = unlink(p);
1585 if (r < 0 && errno != ENOENT) {
1586 r = log_error_errno(errno, "unlink(\"%s\") failed: %m", p);
1587 goto finish;
1588 }
1589 } else if (access(p, F_OK) >= 0) {
1590 log_error("Sealing key file %s exists already. Use --force to recreate.", p);
1591 r = -EEXIST;
1592 goto finish;
1593 }
1594
1595 if (asprintf(&k, "/var/log/journal/" SD_ID128_FORMAT_STR "/fss.tmp.XXXXXX",
1596 SD_ID128_FORMAT_VAL(machine)) < 0) {
1597 r = log_oom();
1598 goto finish;
1599 }
1600
1601 mpk_size = FSPRG_mskinbytes(FSPRG_RECOMMENDED_SECPAR);
1602 mpk = alloca(mpk_size);
1603
1604 seed_size = FSPRG_RECOMMENDED_SEEDLEN;
1605 seed = alloca(seed_size);
1606
1607 state_size = FSPRG_stateinbytes(FSPRG_RECOMMENDED_SECPAR);
1608 state = alloca(state_size);
1609
1610 fd = open("/dev/random", O_RDONLY|O_CLOEXEC|O_NOCTTY);
1611 if (fd < 0) {
1612 r = log_error_errno(errno, "Failed to open /dev/random: %m");
1613 goto finish;
1614 }
1615
1616 log_info("Generating seed...");
1617 r = loop_read_exact(fd, seed, seed_size, true);
1618 if (r < 0) {
1619 log_error_errno(r, "Failed to read random seed: %m");
1620 goto finish;
1621 }
1622
1623 log_info("Generating key pair...");
1624 FSPRG_GenMK(NULL, mpk, seed, seed_size, FSPRG_RECOMMENDED_SECPAR);
1625
1626 log_info("Generating sealing key...");
1627 FSPRG_GenState0(state, mpk, seed, seed_size);
1628
1629 assert(arg_interval > 0);
1630
1631 n = now(CLOCK_REALTIME);
1632 n /= arg_interval;
1633
1634 safe_close(fd);
1635 fd = mkostemp_safe(k);
1636 if (fd < 0) {
1637 r = log_error_errno(fd, "Failed to open %s: %m", k);
1638 goto finish;
1639 }
1640
1641 /* Enable secure remove, exclusion from dump, synchronous
1642 * writing and in-place updating */
1643 r = chattr_fd(fd, FS_SECRM_FL|FS_NODUMP_FL|FS_SYNC_FL|FS_NOCOW_FL, FS_SECRM_FL|FS_NODUMP_FL|FS_SYNC_FL|FS_NOCOW_FL);
1644 if (r < 0)
1645 log_warning_errno(r, "Failed to set file attributes: %m");
1646
1647 zero(h);
1648 memcpy(h.signature, "KSHHRHLP", 8);
1649 h.machine_id = machine;
1650 h.boot_id = boot;
1651 h.header_size = htole64(sizeof(h));
1652 h.start_usec = htole64(n * arg_interval);
1653 h.interval_usec = htole64(arg_interval);
1654 h.fsprg_secpar = htole16(FSPRG_RECOMMENDED_SECPAR);
1655 h.fsprg_state_size = htole64(state_size);
1656
1657 r = loop_write(fd, &h, sizeof(h), false);
1658 if (r < 0) {
1659 log_error_errno(r, "Failed to write header: %m");
1660 goto finish;
1661 }
1662
1663 r = loop_write(fd, state, state_size, false);
1664 if (r < 0) {
1665 log_error_errno(r, "Failed to write state: %m");
1666 goto finish;
1667 }
1668
1669 if (link(k, p) < 0) {
1670 r = log_error_errno(errno, "Failed to link file: %m");
1671 goto finish;
1672 }
1673
1674 if (on_tty()) {
1675 fprintf(stderr,
1676 "\n"
1677 "The new key pair has been generated. The %ssecret sealing key%s has been written to\n"
1678 "the following local file. This key file is automatically updated when the\n"
1679 "sealing key is advanced. It should not be used on multiple hosts.\n"
1680 "\n"
1681 "\t%s\n"
1682 "\n"
1683 "Please write down the following %ssecret verification key%s. It should be stored\n"
1684 "at a safe location and should not be saved locally on disk.\n"
1685 "\n\t%s",
1686 ansi_highlight(), ansi_normal(),
1687 p,
1688 ansi_highlight(), ansi_normal(),
1689 ansi_highlight_red());
1690 fflush(stderr);
1691 }
1692 for (i = 0; i < seed_size; i++) {
1693 if (i > 0 && i % 3 == 0)
1694 putchar('-');
1695 printf("%02x", ((uint8_t*) seed)[i]);
1696 }
1697
1698 printf("/%llx-%llx\n", (unsigned long long) n, (unsigned long long) arg_interval);
1699
1700 if (on_tty()) {
1701 char tsb[FORMAT_TIMESPAN_MAX], *hn;
1702
1703 fprintf(stderr,
1704 "%s\n"
1705 "The sealing key is automatically changed every %s.\n",
1706 ansi_normal(),
1707 format_timespan(tsb, sizeof(tsb), arg_interval, 0));
1708
1709 hn = gethostname_malloc();
1710
1711 if (hn) {
1712 hostname_cleanup(hn);
1713 fprintf(stderr, "\nThe keys have been generated for host %s/" SD_ID128_FORMAT_STR ".\n", hn, SD_ID128_FORMAT_VAL(machine));
1714 } else
1715 fprintf(stderr, "\nThe keys have been generated for host " SD_ID128_FORMAT_STR ".\n", SD_ID128_FORMAT_VAL(machine));
1716
1717 #ifdef HAVE_QRENCODE
1718 /* If this is not an UTF-8 system don't print any QR codes */
1719 if (is_locale_utf8()) {
1720 fputs("\nTo transfer the verification key to your phone please scan the QR code below:\n\n", stderr);
1721 print_qr_code(stderr, seed, seed_size, n, arg_interval, hn, machine);
1722 }
1723 #endif
1724 free(hn);
1725 }
1726
1727 r = 0;
1728
1729 finish:
1730 safe_close(fd);
1731
1732 if (k) {
1733 unlink(k);
1734 free(k);
1735 }
1736
1737 free(p);
1738
1739 return r;
1740 #else
1741 log_error("Forward-secure sealing not available.");
1742 return -EOPNOTSUPP;
1743 #endif
1744 }
1745
1746 static int verify(sd_journal *j) {
1747 int r = 0;
1748 Iterator i;
1749 JournalFile *f;
1750
1751 assert(j);
1752
1753 log_show_color(true);
1754
1755 ORDERED_HASHMAP_FOREACH(f, j->files, i) {
1756 int k;
1757 usec_t first = 0, validated = 0, last = 0;
1758
1759 #ifdef HAVE_GCRYPT
1760 if (!arg_verify_key && JOURNAL_HEADER_SEALED(f->header))
1761 log_notice("Journal file %s has sealing enabled but verification key has not been passed using --verify-key=.", f->path);
1762 #endif
1763
1764 k = journal_file_verify(f, arg_verify_key, &first, &validated, &last, true);
1765 if (k == -EINVAL) {
1766 /* If the key was invalid give up right-away. */
1767 return k;
1768 } else if (k < 0) {
1769 log_warning_errno(k, "FAIL: %s (%m)", f->path);
1770 r = k;
1771 } else {
1772 char a[FORMAT_TIMESTAMP_MAX], b[FORMAT_TIMESTAMP_MAX], c[FORMAT_TIMESPAN_MAX];
1773 log_info("PASS: %s", f->path);
1774
1775 if (arg_verify_key && JOURNAL_HEADER_SEALED(f->header)) {
1776 if (validated > 0) {
1777 log_info("=> Validated from %s to %s, final %s entries not sealed.",
1778 format_timestamp_maybe_utc(a, sizeof(a), first),
1779 format_timestamp_maybe_utc(b, sizeof(b), validated),
1780 format_timespan(c, sizeof(c), last > validated ? last - validated : 0, 0));
1781 } else if (last > 0)
1782 log_info("=> No sealing yet, %s of entries not sealed.",
1783 format_timespan(c, sizeof(c), last - first, 0));
1784 else
1785 log_info("=> No sealing yet, no entries in file.");
1786 }
1787 }
1788 }
1789
1790 return r;
1791 }
1792
1793 static int access_check_var_log_journal(sd_journal *j) {
1794 #ifdef HAVE_ACL
1795 _cleanup_strv_free_ char **g = NULL;
1796 const char* dir;
1797 #endif
1798 int r;
1799
1800 assert(j);
1801
1802 if (arg_quiet)
1803 return 0;
1804
1805 /* If we are root, we should have access, don't warn. */
1806 if (getuid() == 0)
1807 return 0;
1808
1809 /* If we are in the 'systemd-journal' group, we should have
1810 * access too. */
1811 r = in_group("systemd-journal");
1812 if (r < 0)
1813 return log_error_errno(r, "Failed to check if we are in the 'systemd-journal' group: %m");
1814 if (r > 0)
1815 return 0;
1816
1817 #ifdef HAVE_ACL
1818 if (laccess("/run/log/journal", F_OK) >= 0)
1819 dir = "/run/log/journal";
1820 else
1821 dir = "/var/log/journal";
1822
1823 /* If we are in any of the groups listed in the journal ACLs,
1824 * then all is good, too. Let's enumerate all groups from the
1825 * default ACL of the directory, which generally should allow
1826 * access to most journal files too. */
1827 r = acl_search_groups(dir, &g);
1828 if (r < 0)
1829 return log_error_errno(r, "Failed to search journal ACL: %m");
1830 if (r > 0)
1831 return 0;
1832
1833 /* Print a pretty list, if there were ACLs set. */
1834 if (!strv_isempty(g)) {
1835 _cleanup_free_ char *s = NULL;
1836
1837 /* Thre are groups in the ACL, let's list them */
1838 r = strv_extend(&g, "systemd-journal");
1839 if (r < 0)
1840 return log_oom();
1841
1842 strv_sort(g);
1843 strv_uniq(g);
1844
1845 s = strv_join(g, "', '");
1846 if (!s)
1847 return log_oom();
1848
1849 log_notice("Hint: You are currently not seeing messages from other users and the system.\n"
1850 " Users in groups '%s' can see all messages.\n"
1851 " Pass -q to turn off this notice.", s);
1852 return 1;
1853 }
1854 #endif
1855
1856 /* If no ACLs were found, print a short version of the message. */
1857 log_notice("Hint: You are currently not seeing messages from other users and the system.\n"
1858 " Users in the 'systemd-journal' group can see all messages. Pass -q to\n"
1859 " turn off this notice.");
1860
1861 return 1;
1862 }
1863
1864 static int access_check(sd_journal *j) {
1865 Iterator it;
1866 void *code;
1867 char *path;
1868 int r = 0;
1869
1870 assert(j);
1871
1872 if (hashmap_isempty(j->errors)) {
1873 if (ordered_hashmap_isempty(j->files))
1874 log_notice("No journal files were found.");
1875
1876 return 0;
1877 }
1878
1879 if (hashmap_contains(j->errors, INT_TO_PTR(-EACCES))) {
1880 (void) access_check_var_log_journal(j);
1881
1882 if (ordered_hashmap_isempty(j->files))
1883 r = log_error_errno(EACCES, "No journal files were opened due to insufficient permissions.");
1884 }
1885
1886 HASHMAP_FOREACH_KEY(path, code, j->errors, it) {
1887 int err;
1888
1889 err = abs(PTR_TO_INT(code));
1890
1891 switch (err) {
1892 case EACCES:
1893 continue;
1894
1895 case ENODATA:
1896 log_warning_errno(err, "Journal file %s is truncated, ignoring file.", path);
1897 break;
1898
1899 case EPROTONOSUPPORT:
1900 log_warning_errno(err, "Journal file %s uses an unsupported feature, ignoring file.", path);
1901 break;
1902
1903 case EBADMSG:
1904 log_warning_errno(err, "Journal file %s corrupted, ignoring file.", path);
1905 break;
1906
1907 default:
1908 log_warning_errno(err, "An error was encountered while opening journal file or directory %s, ignoring file: %m", path);
1909 break;
1910 }
1911 }
1912
1913 return r;
1914 }
1915
1916 static int flush_to_var(void) {
1917 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
1918 _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
1919 _cleanup_close_ int watch_fd = -1;
1920 int r;
1921
1922 if (arg_machine) {
1923 log_error("--flush is not supported in conjunction with --machine=.");
1924 return -EOPNOTSUPP;
1925 }
1926
1927 /* Quick exit */
1928 if (access("/run/systemd/journal/flushed", F_OK) >= 0)
1929 return 0;
1930
1931 /* OK, let's actually do the full logic, send SIGUSR1 to the
1932 * daemon and set up inotify to wait for the flushed file to appear */
1933 r = bus_connect_system_systemd(&bus);
1934 if (r < 0)
1935 return log_error_errno(r, "Failed to get D-Bus connection: %m");
1936
1937 r = sd_bus_call_method(
1938 bus,
1939 "org.freedesktop.systemd1",
1940 "/org/freedesktop/systemd1",
1941 "org.freedesktop.systemd1.Manager",
1942 "KillUnit",
1943 &error,
1944 NULL,
1945 "ssi", "systemd-journald.service", "main", SIGUSR1);
1946 if (r < 0)
1947 return log_error_errno(r, "Failed to kill journal service: %s", bus_error_message(&error, r));
1948
1949 mkdir_p("/run/systemd/journal", 0755);
1950
1951 watch_fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC);
1952 if (watch_fd < 0)
1953 return log_error_errno(errno, "Failed to create inotify watch: %m");
1954
1955 r = inotify_add_watch(watch_fd, "/run/systemd/journal", IN_CREATE|IN_DONT_FOLLOW|IN_ONLYDIR);
1956 if (r < 0)
1957 return log_error_errno(errno, "Failed to watch journal directory: %m");
1958
1959 for (;;) {
1960 if (access("/run/systemd/journal/flushed", F_OK) >= 0)
1961 break;
1962
1963 if (errno != ENOENT)
1964 return log_error_errno(errno, "Failed to check for existence of /run/systemd/journal/flushed: %m");
1965
1966 r = fd_wait_for_event(watch_fd, POLLIN, USEC_INFINITY);
1967 if (r < 0)
1968 return log_error_errno(r, "Failed to wait for event: %m");
1969
1970 r = flush_fd(watch_fd);
1971 if (r < 0)
1972 return log_error_errno(r, "Failed to flush inotify events: %m");
1973 }
1974
1975 return 0;
1976 }
1977
1978 static int send_signal_and_wait(int sig, const char *watch_path) {
1979 _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
1980 _cleanup_close_ int watch_fd = -1;
1981 usec_t start;
1982 int r;
1983
1984 if (arg_machine) {
1985 log_error("--sync and --rotate are not supported in conjunction with --machine=.");
1986 return -EOPNOTSUPP;
1987 }
1988
1989 start = now(CLOCK_MONOTONIC);
1990
1991 /* This call sends the specified signal to journald, and waits
1992 * for acknowledgment by watching the mtime of the specified
1993 * flag file. This is used to trigger syncing or rotation and
1994 * then wait for the operation to complete. */
1995
1996 for (;;) {
1997 usec_t tstamp;
1998
1999 /* See if a sync happened by now. */
2000 r = read_timestamp_file(watch_path, &tstamp);
2001 if (r < 0 && r != -ENOENT)
2002 return log_error_errno(errno, "Failed to read %s: %m", watch_path);
2003 if (r >= 0 && tstamp >= start)
2004 return 0;
2005
2006 /* Let's ask for a sync, but only once. */
2007 if (!bus) {
2008 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
2009
2010 r = bus_connect_system_systemd(&bus);
2011 if (r < 0)
2012 return log_error_errno(r, "Failed to get D-Bus connection: %m");
2013
2014 r = sd_bus_call_method(
2015 bus,
2016 "org.freedesktop.systemd1",
2017 "/org/freedesktop/systemd1",
2018 "org.freedesktop.systemd1.Manager",
2019 "KillUnit",
2020 &error,
2021 NULL,
2022 "ssi", "systemd-journald.service", "main", sig);
2023 if (r < 0)
2024 return log_error_errno(r, "Failed to kill journal service: %s", bus_error_message(&error, r));
2025
2026 continue;
2027 }
2028
2029 /* Let's install the inotify watch, if we didn't do that yet. */
2030 if (watch_fd < 0) {
2031
2032 mkdir_p("/run/systemd/journal", 0755);
2033
2034 watch_fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC);
2035 if (watch_fd < 0)
2036 return log_error_errno(errno, "Failed to create inotify watch: %m");
2037
2038 r = inotify_add_watch(watch_fd, "/run/systemd/journal", IN_MOVED_TO|IN_DONT_FOLLOW|IN_ONLYDIR);
2039 if (r < 0)
2040 return log_error_errno(errno, "Failed to watch journal directory: %m");
2041
2042 /* Recheck the flag file immediately, so that we don't miss any event since the last check. */
2043 continue;
2044 }
2045
2046 /* OK, all preparatory steps done, let's wait until
2047 * inotify reports an event. */
2048
2049 r = fd_wait_for_event(watch_fd, POLLIN, USEC_INFINITY);
2050 if (r < 0)
2051 return log_error_errno(r, "Failed to wait for event: %m");
2052
2053 r = flush_fd(watch_fd);
2054 if (r < 0)
2055 return log_error_errno(r, "Failed to flush inotify events: %m");
2056 }
2057
2058 return 0;
2059 }
2060
2061 static int rotate(void) {
2062 return send_signal_and_wait(SIGUSR2, "/run/systemd/journal/rotated");
2063 }
2064
2065 static int sync_journal(void) {
2066 return send_signal_and_wait(SIGRTMIN+1, "/run/systemd/journal/synced");
2067 }
2068
2069 int main(int argc, char *argv[]) {
2070 int r;
2071 _cleanup_(sd_journal_closep) sd_journal *j = NULL;
2072 bool need_seek = false;
2073 sd_id128_t previous_boot_id;
2074 bool previous_boot_id_valid = false, first_line = true;
2075 int n_shown = 0;
2076 bool ellipsized = false;
2077
2078 setlocale(LC_ALL, "");
2079 log_parse_environment();
2080 log_open();
2081
2082 r = parse_argv(argc, argv);
2083 if (r <= 0)
2084 goto finish;
2085
2086 signal(SIGWINCH, columns_lines_cache_reset);
2087 sigbus_install();
2088
2089 /* Increase max number of open files to 16K if we can, we
2090 * might needs this when browsing journal files, which might
2091 * be split up into many files. */
2092 setrlimit_closest(RLIMIT_NOFILE, &RLIMIT_MAKE_CONST(16384));
2093
2094 switch (arg_action) {
2095
2096 case ACTION_NEW_ID128:
2097 r = generate_new_id128();
2098 goto finish;
2099
2100 case ACTION_SETUP_KEYS:
2101 r = setup_keys();
2102 goto finish;
2103
2104 case ACTION_LIST_CATALOG:
2105 case ACTION_DUMP_CATALOG:
2106 case ACTION_UPDATE_CATALOG: {
2107 _cleanup_free_ char *database;
2108
2109 database = path_join(arg_root, CATALOG_DATABASE, NULL);
2110 if (!database) {
2111 r = log_oom();
2112 goto finish;
2113 }
2114
2115 if (arg_action == ACTION_UPDATE_CATALOG) {
2116 r = catalog_update(database, arg_root, catalog_file_dirs);
2117 if (r < 0)
2118 log_error_errno(r, "Failed to list catalog: %m");
2119 } else {
2120 bool oneline = arg_action == ACTION_LIST_CATALOG;
2121
2122 pager_open(arg_no_pager, arg_pager_end);
2123
2124 if (optind < argc)
2125 r = catalog_list_items(stdout, database, oneline, argv + optind);
2126 else
2127 r = catalog_list(stdout, database, oneline);
2128 if (r < 0)
2129 log_error_errno(r, "Failed to list catalog: %m");
2130 }
2131
2132 goto finish;
2133 }
2134
2135 case ACTION_FLUSH:
2136 r = flush_to_var();
2137 goto finish;
2138
2139 case ACTION_SYNC:
2140 r = sync_journal();
2141 goto finish;
2142
2143 case ACTION_ROTATE:
2144 r = rotate();
2145 goto finish;
2146
2147 case ACTION_SHOW:
2148 case ACTION_PRINT_HEADER:
2149 case ACTION_VERIFY:
2150 case ACTION_DISK_USAGE:
2151 case ACTION_LIST_BOOTS:
2152 case ACTION_VACUUM:
2153 case ACTION_LIST_FIELDS:
2154 case ACTION_LIST_FIELD_NAMES:
2155 /* These ones require access to the journal files, continue below. */
2156 break;
2157
2158 default:
2159 assert_not_reached("Unknown action");
2160 }
2161
2162 if (arg_directory)
2163 r = sd_journal_open_directory(&j, arg_directory, arg_journal_type);
2164 else if (arg_root)
2165 r = sd_journal_open_directory(&j, arg_root, arg_journal_type | SD_JOURNAL_OS_ROOT);
2166 else if (arg_file_stdin) {
2167 int ifd = STDIN_FILENO;
2168 r = sd_journal_open_files_fd(&j, &ifd, 1, 0);
2169 } else if (arg_file)
2170 r = sd_journal_open_files(&j, (const char**) arg_file, 0);
2171 else if (arg_machine) {
2172 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
2173 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
2174 _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
2175 int fd;
2176
2177 if (geteuid() != 0) {
2178 /* The file descriptor returned by OpenMachineRootDirectory() will be owned by users/groups of
2179 * the container, thus we need root privileges to override them. */
2180 log_error("Using the --machine= switch requires root privileges.");
2181 r = -EPERM;
2182 goto finish;
2183 }
2184
2185 r = sd_bus_open_system(&bus);
2186 if (r < 0) {
2187 log_error_errno(r, "Failed to open system bus: %m");
2188 goto finish;
2189 }
2190
2191 r = sd_bus_call_method(
2192 bus,
2193 "org.freedesktop.machine1",
2194 "/org/freedesktop/machine1",
2195 "org.freedesktop.machine1.Manager",
2196 "OpenMachineRootDirectory",
2197 &error,
2198 &reply,
2199 "s", arg_machine);
2200 if (r < 0) {
2201 log_error_errno(r, "Failed to open root directory: %s", bus_error_message(&error, r));
2202 goto finish;
2203 }
2204
2205 r = sd_bus_message_read(reply, "h", &fd);
2206 if (r < 0) {
2207 bus_log_parse_error(r);
2208 goto finish;
2209 }
2210
2211 fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
2212 if (fd < 0) {
2213 r = log_error_errno(errno, "Failed to duplicate file descriptor: %m");
2214 goto finish;
2215 }
2216
2217 r = sd_journal_open_directory_fd(&j, fd, SD_JOURNAL_OS_ROOT);
2218 if (r < 0)
2219 safe_close(fd);
2220 } else
2221 r = sd_journal_open(&j, !arg_merge*SD_JOURNAL_LOCAL_ONLY + arg_journal_type);
2222 if (r < 0) {
2223 log_error_errno(r, "Failed to open %s: %m", arg_directory ?: arg_file ? "files" : "journal");
2224 goto finish;
2225 }
2226
2227 r = access_check(j);
2228 if (r < 0)
2229 goto finish;
2230
2231 switch (arg_action) {
2232
2233 case ACTION_NEW_ID128:
2234 case ACTION_SETUP_KEYS:
2235 case ACTION_LIST_CATALOG:
2236 case ACTION_DUMP_CATALOG:
2237 case ACTION_UPDATE_CATALOG:
2238 case ACTION_FLUSH:
2239 case ACTION_SYNC:
2240 case ACTION_ROTATE:
2241 assert_not_reached("Unexpected action.");
2242
2243 case ACTION_PRINT_HEADER:
2244 journal_print_header(j);
2245 r = 0;
2246 goto finish;
2247
2248 case ACTION_VERIFY:
2249 r = verify(j);
2250 goto finish;
2251
2252 case ACTION_DISK_USAGE: {
2253 uint64_t bytes = 0;
2254 char sbytes[FORMAT_BYTES_MAX];
2255
2256 r = sd_journal_get_usage(j, &bytes);
2257 if (r < 0)
2258 goto finish;
2259
2260 printf("Archived and active journals take up %s on disk.\n",
2261 format_bytes(sbytes, sizeof(sbytes), bytes));
2262 goto finish;
2263 }
2264
2265 case ACTION_LIST_BOOTS:
2266 r = list_boots(j);
2267 goto finish;
2268
2269 case ACTION_VACUUM: {
2270 Directory *d;
2271 Iterator i;
2272
2273 HASHMAP_FOREACH(d, j->directories_by_path, i) {
2274 int q;
2275
2276 if (d->is_root)
2277 continue;
2278
2279 q = journal_directory_vacuum(d->path, arg_vacuum_size, arg_vacuum_n_files, arg_vacuum_time, NULL, true);
2280 if (q < 0) {
2281 log_error_errno(q, "Failed to vacuum %s: %m", d->path);
2282 r = q;
2283 }
2284 }
2285
2286 goto finish;
2287 }
2288
2289 case ACTION_LIST_FIELD_NAMES: {
2290 const char *field;
2291
2292 SD_JOURNAL_FOREACH_FIELD(j, field) {
2293 printf("%s\n", field);
2294 n_shown++;
2295 }
2296
2297 r = 0;
2298 goto finish;
2299 }
2300
2301 case ACTION_SHOW:
2302 case ACTION_LIST_FIELDS:
2303 break;
2304
2305 default:
2306 assert_not_reached("Unknown action");
2307 }
2308
2309 if (arg_boot_offset != 0 &&
2310 sd_journal_has_runtime_files(j) > 0 &&
2311 sd_journal_has_persistent_files(j) == 0) {
2312 log_info("Specifying boot ID has no effect, no persistent journal was found");
2313 r = 0;
2314 goto finish;
2315 }
2316 /* add_boot() must be called first!
2317 * It may need to seek the journal to find parent boot IDs. */
2318 r = add_boot(j);
2319 if (r < 0)
2320 goto finish;
2321
2322 r = add_dmesg(j);
2323 if (r < 0)
2324 goto finish;
2325
2326 r = add_units(j);
2327 if (r < 0) {
2328 log_error_errno(r, "Failed to add filter for units: %m");
2329 goto finish;
2330 }
2331
2332 r = add_syslog_identifier(j);
2333 if (r < 0) {
2334 log_error_errno(r, "Failed to add filter for syslog identifiers: %m");
2335 goto finish;
2336 }
2337
2338 r = add_priorities(j);
2339 if (r < 0)
2340 goto finish;
2341
2342 r = add_matches(j, argv + optind);
2343 if (r < 0)
2344 goto finish;
2345
2346 if (_unlikely_(log_get_max_level() >= LOG_DEBUG)) {
2347 _cleanup_free_ char *filter;
2348
2349 filter = journal_make_match_string(j);
2350 if (!filter)
2351 return log_oom();
2352
2353 log_debug("Journal filter: %s", filter);
2354 }
2355
2356 if (arg_action == ACTION_LIST_FIELDS) {
2357 const void *data;
2358 size_t size;
2359
2360 assert(arg_field);
2361
2362 r = sd_journal_set_data_threshold(j, 0);
2363 if (r < 0) {
2364 log_error_errno(r, "Failed to unset data size threshold: %m");
2365 goto finish;
2366 }
2367
2368 r = sd_journal_query_unique(j, arg_field);
2369 if (r < 0) {
2370 log_error_errno(r, "Failed to query unique data objects: %m");
2371 goto finish;
2372 }
2373
2374 SD_JOURNAL_FOREACH_UNIQUE(j, data, size) {
2375 const void *eq;
2376
2377 if (arg_lines >= 0 && n_shown >= arg_lines)
2378 break;
2379
2380 eq = memchr(data, '=', size);
2381 if (eq)
2382 printf("%.*s\n", (int) (size - ((const uint8_t*) eq - (const uint8_t*) data + 1)), (const char*) eq + 1);
2383 else
2384 printf("%.*s\n", (int) size, (const char*) data);
2385
2386 n_shown++;
2387 }
2388
2389 r = 0;
2390 goto finish;
2391 }
2392
2393 /* Opening the fd now means the first sd_journal_wait() will actually wait */
2394 if (arg_follow) {
2395 r = sd_journal_get_fd(j);
2396 if (r == -EMEDIUMTYPE) {
2397 log_error_errno(r, "The --follow switch is not supported in conjunction with reading from STDIN.");
2398 goto finish;
2399 }
2400 if (r < 0) {
2401 log_error_errno(r, "Failed to get journal fd: %m");
2402 goto finish;
2403 }
2404 }
2405
2406 if (arg_cursor || arg_after_cursor) {
2407 r = sd_journal_seek_cursor(j, arg_cursor ?: arg_after_cursor);
2408 if (r < 0) {
2409 log_error_errno(r, "Failed to seek to cursor: %m");
2410 goto finish;
2411 }
2412
2413 if (!arg_reverse)
2414 r = sd_journal_next_skip(j, 1 + !!arg_after_cursor);
2415 else
2416 r = sd_journal_previous_skip(j, 1 + !!arg_after_cursor);
2417
2418 if (arg_after_cursor && r < 2) {
2419 /* We couldn't find the next entry after the cursor. */
2420 if (arg_follow)
2421 need_seek = true;
2422 else
2423 arg_lines = 0;
2424 }
2425
2426 } else if (arg_since_set && !arg_reverse) {
2427 r = sd_journal_seek_realtime_usec(j, arg_since);
2428 if (r < 0) {
2429 log_error_errno(r, "Failed to seek to date: %m");
2430 goto finish;
2431 }
2432 r = sd_journal_next(j);
2433
2434 } else if (arg_until_set && arg_reverse) {
2435 r = sd_journal_seek_realtime_usec(j, arg_until);
2436 if (r < 0) {
2437 log_error_errno(r, "Failed to seek to date: %m");
2438 goto finish;
2439 }
2440 r = sd_journal_previous(j);
2441
2442 } else if (arg_lines >= 0) {
2443 r = sd_journal_seek_tail(j);
2444 if (r < 0) {
2445 log_error_errno(r, "Failed to seek to tail: %m");
2446 goto finish;
2447 }
2448
2449 r = sd_journal_previous_skip(j, arg_lines);
2450
2451 } else if (arg_reverse) {
2452 r = sd_journal_seek_tail(j);
2453 if (r < 0) {
2454 log_error_errno(r, "Failed to seek to tail: %m");
2455 goto finish;
2456 }
2457
2458 r = sd_journal_previous(j);
2459
2460 } else {
2461 r = sd_journal_seek_head(j);
2462 if (r < 0) {
2463 log_error_errno(r, "Failed to seek to head: %m");
2464 goto finish;
2465 }
2466
2467 r = sd_journal_next(j);
2468 }
2469
2470 if (r < 0) {
2471 log_error_errno(r, "Failed to iterate through journal: %m");
2472 goto finish;
2473 }
2474 if (r == 0) {
2475 if (arg_follow)
2476 need_seek = true;
2477 else {
2478 if (!arg_quiet)
2479 printf("-- No entries --\n");
2480 goto finish;
2481 }
2482 }
2483
2484 if (!arg_follow)
2485 pager_open(arg_no_pager, arg_pager_end);
2486
2487 if (!arg_quiet) {
2488 usec_t start, end;
2489 char start_buf[FORMAT_TIMESTAMP_MAX], end_buf[FORMAT_TIMESTAMP_MAX];
2490
2491 r = sd_journal_get_cutoff_realtime_usec(j, &start, &end);
2492 if (r < 0) {
2493 log_error_errno(r, "Failed to get cutoff: %m");
2494 goto finish;
2495 }
2496
2497 if (r > 0) {
2498 if (arg_follow)
2499 printf("-- Logs begin at %s. --\n",
2500 format_timestamp_maybe_utc(start_buf, sizeof(start_buf), start));
2501 else
2502 printf("-- Logs begin at %s, end at %s. --\n",
2503 format_timestamp_maybe_utc(start_buf, sizeof(start_buf), start),
2504 format_timestamp_maybe_utc(end_buf, sizeof(end_buf), end));
2505 }
2506 }
2507
2508 for (;;) {
2509 while (arg_lines < 0 || n_shown < arg_lines || (arg_follow && !first_line)) {
2510 int flags;
2511
2512 if (need_seek) {
2513 if (!arg_reverse)
2514 r = sd_journal_next(j);
2515 else
2516 r = sd_journal_previous(j);
2517 if (r < 0) {
2518 log_error_errno(r, "Failed to iterate through journal: %m");
2519 goto finish;
2520 }
2521 if (r == 0)
2522 break;
2523 }
2524
2525 if (arg_until_set && !arg_reverse) {
2526 usec_t usec;
2527
2528 r = sd_journal_get_realtime_usec(j, &usec);
2529 if (r < 0) {
2530 log_error_errno(r, "Failed to determine timestamp: %m");
2531 goto finish;
2532 }
2533 if (usec > arg_until)
2534 goto finish;
2535 }
2536
2537 if (arg_since_set && arg_reverse) {
2538 usec_t usec;
2539
2540 r = sd_journal_get_realtime_usec(j, &usec);
2541 if (r < 0) {
2542 log_error_errno(r, "Failed to determine timestamp: %m");
2543 goto finish;
2544 }
2545 if (usec < arg_since)
2546 goto finish;
2547 }
2548
2549 if (!arg_merge && !arg_quiet) {
2550 sd_id128_t boot_id;
2551
2552 r = sd_journal_get_monotonic_usec(j, NULL, &boot_id);
2553 if (r >= 0) {
2554 if (previous_boot_id_valid &&
2555 !sd_id128_equal(boot_id, previous_boot_id))
2556 printf("%s-- Reboot --%s\n",
2557 ansi_highlight(), ansi_normal());
2558
2559 previous_boot_id = boot_id;
2560 previous_boot_id_valid = true;
2561 }
2562 }
2563
2564 flags =
2565 arg_all * OUTPUT_SHOW_ALL |
2566 arg_full * OUTPUT_FULL_WIDTH |
2567 colors_enabled() * OUTPUT_COLOR |
2568 arg_catalog * OUTPUT_CATALOG |
2569 arg_utc * OUTPUT_UTC |
2570 arg_no_hostname * OUTPUT_NO_HOSTNAME;
2571
2572 r = output_journal(stdout, j, arg_output, 0, flags, &ellipsized);
2573 need_seek = true;
2574 if (r == -EADDRNOTAVAIL)
2575 break;
2576 else if (r < 0 || ferror(stdout))
2577 goto finish;
2578
2579 n_shown++;
2580 }
2581
2582 if (!arg_follow) {
2583 if (arg_show_cursor) {
2584 _cleanup_free_ char *cursor = NULL;
2585
2586 r = sd_journal_get_cursor(j, &cursor);
2587 if (r < 0 && r != -EADDRNOTAVAIL)
2588 log_error_errno(r, "Failed to get cursor: %m");
2589 else if (r >= 0)
2590 printf("-- cursor: %s\n", cursor);
2591 }
2592
2593 break;
2594 }
2595
2596 r = sd_journal_wait(j, (uint64_t) -1);
2597 if (r < 0) {
2598 log_error_errno(r, "Couldn't wait for journal event: %m");
2599 goto finish;
2600 }
2601
2602 first_line = false;
2603 }
2604
2605 finish:
2606 pager_close();
2607
2608 strv_free(arg_file);
2609
2610 strv_free(arg_syslog_identifier);
2611 strv_free(arg_system_units);
2612 strv_free(arg_user_units);
2613
2614 free(arg_root);
2615
2616 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
2617 }