]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/journal/journalctl.c
tree-wide: stop using canonicalize_file_name(), use chase_symlinks() instead
[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);
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 = NULL, *t = NULL, *t2 = NULL, *interpreter = NULL;
942 struct stat st;
943
944 r = chase_symlinks(*i, NULL, &p);
945 if (r < 0)
946 return log_error_errno(r, "Couldn't canonicalize path: %m");
947
948 if (lstat(p, &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(p, &interpreter) > 0) {
953 _cleanup_free_ char *comm;
954
955 comm = strndup(basename(p), 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=", p);
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, p);
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 log_debug("Whoopsie! We found a boot ID but can't read its last entry.");
1096 return -ENODATA; /* This shouldn't happen. We just came from this very boot ID. */
1097 }
1098
1099 r = sd_journal_get_realtime_usec(j, &next_boot->last);
1100 if (r < 0)
1101 return r;
1102
1103 *ret = next_boot;
1104 next_boot = NULL;
1105
1106 return 0;
1107 }
1108
1109 static int get_boots(
1110 sd_journal *j,
1111 BootId **boots,
1112 sd_id128_t *boot_id,
1113 int offset) {
1114
1115 bool skip_once;
1116 int r, count = 0;
1117 BootId *head = NULL, *tail = NULL, *id;
1118 const bool advance_older = boot_id && offset <= 0;
1119 sd_id128_t previous_boot_id;
1120
1121 assert(j);
1122
1123 /* Adjust for the asymmetry that offset 0 is
1124 * the last (and current) boot, while 1 is considered the
1125 * (chronological) first boot in the journal. */
1126 skip_once = boot_id && sd_id128_is_null(*boot_id) && offset <= 0;
1127
1128 /* Advance to the earliest/latest occurrence of our reference
1129 * boot ID (taking our lookup direction into account), so that
1130 * discover_next_boot() can do its job.
1131 * If no reference is given, the journal head/tail will do,
1132 * they're "virtual" boots after all. */
1133 if (boot_id && !sd_id128_is_null(*boot_id)) {
1134 char match[9+32+1] = "_BOOT_ID=";
1135
1136 sd_journal_flush_matches(j);
1137
1138 sd_id128_to_string(*boot_id, match + 9);
1139 r = sd_journal_add_match(j, match, sizeof(match) - 1);
1140 if (r < 0)
1141 return r;
1142
1143 if (advance_older)
1144 r = sd_journal_seek_head(j); /* seek to oldest */
1145 else
1146 r = sd_journal_seek_tail(j); /* seek to newest */
1147 if (r < 0)
1148 return r;
1149
1150 if (advance_older)
1151 r = sd_journal_next(j); /* read the oldest entry */
1152 else
1153 r = sd_journal_previous(j); /* read the most recently added entry */
1154 if (r < 0)
1155 return r;
1156 else if (r == 0)
1157 goto finish;
1158 else if (offset == 0) {
1159 count = 1;
1160 goto finish;
1161 }
1162
1163 /* At this point the read pointer is positioned at the oldest/newest occurence of the reference boot
1164 * ID. After flushing the matches, one more invocation of _previous()/_next() will hence place us at
1165 * the following entry, which must then have an older/newer boot ID */
1166 } else {
1167
1168 if (advance_older)
1169 r = sd_journal_seek_tail(j); /* seek to newest */
1170 else
1171 r = sd_journal_seek_head(j); /* seek to oldest */
1172 if (r < 0)
1173 return r;
1174
1175 /* No sd_journal_next()/_previous() here.
1176 *
1177 * At this point the read pointer is positioned after the newest/before the oldest entry in the whole
1178 * journal. The next invocation of _previous()/_next() will hence position us at the newest/oldest
1179 * entry we have. */
1180 }
1181
1182 previous_boot_id = SD_ID128_NULL;
1183 for (;;) {
1184 _cleanup_free_ BootId *current = NULL;
1185
1186 r = discover_next_boot(j, previous_boot_id, advance_older, &current);
1187 if (r < 0) {
1188 boot_id_free_all(head);
1189 return r;
1190 }
1191
1192 if (!current)
1193 break;
1194
1195 previous_boot_id = current->id;
1196
1197 if (boot_id) {
1198 if (!skip_once)
1199 offset += advance_older ? 1 : -1;
1200 skip_once = false;
1201
1202 if (offset == 0) {
1203 count = 1;
1204 *boot_id = current->id;
1205 break;
1206 }
1207 } else {
1208 LIST_FOREACH(boot_list, id, head) {
1209 if (sd_id128_equal(id->id, current->id)) {
1210 /* boot id already stored, something wrong with the journal files */
1211 /* exiting as otherwise this problem would cause forever loop */
1212 goto finish;
1213 }
1214 }
1215 LIST_INSERT_AFTER(boot_list, head, tail, current);
1216 tail = current;
1217 current = NULL;
1218 count++;
1219 }
1220 }
1221
1222 finish:
1223 if (boots)
1224 *boots = head;
1225
1226 sd_journal_flush_matches(j);
1227
1228 return count;
1229 }
1230
1231 static int list_boots(sd_journal *j) {
1232 int w, i, count;
1233 BootId *id, *all_ids;
1234
1235 assert(j);
1236
1237 count = get_boots(j, &all_ids, NULL, 0);
1238 if (count < 0)
1239 return log_error_errno(count, "Failed to determine boots: %m");
1240 if (count == 0)
1241 return count;
1242
1243 pager_open(arg_no_pager, arg_pager_end);
1244
1245 /* numbers are one less, but we need an extra char for the sign */
1246 w = DECIMAL_STR_WIDTH(count - 1) + 1;
1247
1248 i = 0;
1249 LIST_FOREACH(boot_list, id, all_ids) {
1250 char a[FORMAT_TIMESTAMP_MAX], b[FORMAT_TIMESTAMP_MAX];
1251
1252 printf("% *i " SD_ID128_FORMAT_STR " %s—%s\n",
1253 w, i - count + 1,
1254 SD_ID128_FORMAT_VAL(id->id),
1255 format_timestamp_maybe_utc(a, sizeof(a), id->first),
1256 format_timestamp_maybe_utc(b, sizeof(b), id->last));
1257 i++;
1258 }
1259
1260 boot_id_free_all(all_ids);
1261
1262 return 0;
1263 }
1264
1265 static int add_boot(sd_journal *j) {
1266 char match[9+32+1] = "_BOOT_ID=";
1267 sd_id128_t boot_id;
1268 int r;
1269
1270 assert(j);
1271
1272 if (!arg_boot)
1273 return 0;
1274
1275 /* Take a shortcut and use the current boot_id, which we can do very quickly.
1276 * We can do this only when we logs are coming from the current machine,
1277 * so take the slow path if log location is specified. */
1278 if (arg_boot_offset == 0 && sd_id128_is_null(arg_boot_id) &&
1279 !arg_directory && !arg_file && !arg_root)
1280
1281 return add_match_this_boot(j, arg_machine);
1282
1283 boot_id = arg_boot_id;
1284 r = get_boots(j, NULL, &boot_id, arg_boot_offset);
1285 assert(r <= 1);
1286 if (r <= 0) {
1287 const char *reason = (r == 0) ? "No such boot ID in journal" : strerror(-r);
1288
1289 if (sd_id128_is_null(arg_boot_id))
1290 log_error("Data from the specified boot (%+i) is not available: %s",
1291 arg_boot_offset, reason);
1292 else
1293 log_error("Data from the specified boot ("SD_ID128_FORMAT_STR") is not available: %s",
1294 SD_ID128_FORMAT_VAL(arg_boot_id), reason);
1295
1296 return r == 0 ? -ENODATA : r;
1297 }
1298
1299 sd_id128_to_string(boot_id, match + 9);
1300
1301 r = sd_journal_add_match(j, match, sizeof(match) - 1);
1302 if (r < 0)
1303 return log_error_errno(r, "Failed to add match: %m");
1304
1305 r = sd_journal_add_conjunction(j);
1306 if (r < 0)
1307 return log_error_errno(r, "Failed to add conjunction: %m");
1308
1309 return 0;
1310 }
1311
1312 static int add_dmesg(sd_journal *j) {
1313 int r;
1314 assert(j);
1315
1316 if (!arg_dmesg)
1317 return 0;
1318
1319 r = sd_journal_add_match(j, "_TRANSPORT=kernel", strlen("_TRANSPORT=kernel"));
1320 if (r < 0)
1321 return log_error_errno(r, "Failed to add match: %m");
1322
1323 r = sd_journal_add_conjunction(j);
1324 if (r < 0)
1325 return log_error_errno(r, "Failed to add conjunction: %m");
1326
1327 return 0;
1328 }
1329
1330 static int get_possible_units(
1331 sd_journal *j,
1332 const char *fields,
1333 char **patterns,
1334 Set **units) {
1335
1336 _cleanup_set_free_free_ Set *found;
1337 const char *field;
1338 int r;
1339
1340 found = set_new(&string_hash_ops);
1341 if (!found)
1342 return -ENOMEM;
1343
1344 NULSTR_FOREACH(field, fields) {
1345 const void *data;
1346 size_t size;
1347
1348 r = sd_journal_query_unique(j, field);
1349 if (r < 0)
1350 return r;
1351
1352 SD_JOURNAL_FOREACH_UNIQUE(j, data, size) {
1353 char **pattern, *eq;
1354 size_t prefix;
1355 _cleanup_free_ char *u = NULL;
1356
1357 eq = memchr(data, '=', size);
1358 if (eq)
1359 prefix = eq - (char*) data + 1;
1360 else
1361 prefix = 0;
1362
1363 u = strndup((char*) data + prefix, size - prefix);
1364 if (!u)
1365 return -ENOMEM;
1366
1367 STRV_FOREACH(pattern, patterns)
1368 if (fnmatch(*pattern, u, FNM_NOESCAPE) == 0) {
1369 log_debug("Matched %s with pattern %s=%s", u, field, *pattern);
1370
1371 r = set_consume(found, u);
1372 u = NULL;
1373 if (r < 0 && r != -EEXIST)
1374 return r;
1375
1376 break;
1377 }
1378 }
1379 }
1380
1381 *units = found;
1382 found = NULL;
1383 return 0;
1384 }
1385
1386 /* This list is supposed to return the superset of unit names
1387 * possibly matched by rules added with add_matches_for_unit... */
1388 #define SYSTEM_UNITS \
1389 "_SYSTEMD_UNIT\0" \
1390 "COREDUMP_UNIT\0" \
1391 "UNIT\0" \
1392 "OBJECT_SYSTEMD_UNIT\0" \
1393 "_SYSTEMD_SLICE\0"
1394
1395 /* ... and add_matches_for_user_unit */
1396 #define USER_UNITS \
1397 "_SYSTEMD_USER_UNIT\0" \
1398 "USER_UNIT\0" \
1399 "COREDUMP_USER_UNIT\0" \
1400 "OBJECT_SYSTEMD_USER_UNIT\0"
1401
1402 static int add_units(sd_journal *j) {
1403 _cleanup_strv_free_ char **patterns = NULL;
1404 int r, count = 0;
1405 char **i;
1406
1407 assert(j);
1408
1409 STRV_FOREACH(i, arg_system_units) {
1410 _cleanup_free_ char *u = NULL;
1411
1412 r = unit_name_mangle(*i, UNIT_NAME_GLOB, &u);
1413 if (r < 0)
1414 return r;
1415
1416 if (string_is_glob(u)) {
1417 r = strv_push(&patterns, u);
1418 if (r < 0)
1419 return r;
1420 u = NULL;
1421 } else {
1422 r = add_matches_for_unit(j, u);
1423 if (r < 0)
1424 return r;
1425 r = sd_journal_add_disjunction(j);
1426 if (r < 0)
1427 return r;
1428 count++;
1429 }
1430 }
1431
1432 if (!strv_isempty(patterns)) {
1433 _cleanup_set_free_free_ Set *units = NULL;
1434 Iterator it;
1435 char *u;
1436
1437 r = get_possible_units(j, SYSTEM_UNITS, patterns, &units);
1438 if (r < 0)
1439 return r;
1440
1441 SET_FOREACH(u, units, it) {
1442 r = add_matches_for_unit(j, u);
1443 if (r < 0)
1444 return r;
1445 r = sd_journal_add_disjunction(j);
1446 if (r < 0)
1447 return r;
1448 count++;
1449 }
1450 }
1451
1452 patterns = strv_free(patterns);
1453
1454 STRV_FOREACH(i, arg_user_units) {
1455 _cleanup_free_ char *u = NULL;
1456
1457 r = unit_name_mangle(*i, UNIT_NAME_GLOB, &u);
1458 if (r < 0)
1459 return r;
1460
1461 if (string_is_glob(u)) {
1462 r = strv_push(&patterns, u);
1463 if (r < 0)
1464 return r;
1465 u = NULL;
1466 } else {
1467 r = add_matches_for_user_unit(j, u, getuid());
1468 if (r < 0)
1469 return r;
1470 r = sd_journal_add_disjunction(j);
1471 if (r < 0)
1472 return r;
1473 count++;
1474 }
1475 }
1476
1477 if (!strv_isempty(patterns)) {
1478 _cleanup_set_free_free_ Set *units = NULL;
1479 Iterator it;
1480 char *u;
1481
1482 r = get_possible_units(j, USER_UNITS, patterns, &units);
1483 if (r < 0)
1484 return r;
1485
1486 SET_FOREACH(u, units, it) {
1487 r = add_matches_for_user_unit(j, u, getuid());
1488 if (r < 0)
1489 return r;
1490 r = sd_journal_add_disjunction(j);
1491 if (r < 0)
1492 return r;
1493 count++;
1494 }
1495 }
1496
1497 /* Complain if the user request matches but nothing whatsoever was
1498 * found, since otherwise everything would be matched. */
1499 if (!(strv_isempty(arg_system_units) && strv_isempty(arg_user_units)) && count == 0)
1500 return -ENODATA;
1501
1502 r = sd_journal_add_conjunction(j);
1503 if (r < 0)
1504 return r;
1505
1506 return 0;
1507 }
1508
1509 static int add_priorities(sd_journal *j) {
1510 char match[] = "PRIORITY=0";
1511 int i, r;
1512 assert(j);
1513
1514 if (arg_priorities == 0xFF)
1515 return 0;
1516
1517 for (i = LOG_EMERG; i <= LOG_DEBUG; i++)
1518 if (arg_priorities & (1 << i)) {
1519 match[sizeof(match)-2] = '0' + i;
1520
1521 r = sd_journal_add_match(j, match, strlen(match));
1522 if (r < 0)
1523 return log_error_errno(r, "Failed to add match: %m");
1524 }
1525
1526 r = sd_journal_add_conjunction(j);
1527 if (r < 0)
1528 return log_error_errno(r, "Failed to add conjunction: %m");
1529
1530 return 0;
1531 }
1532
1533
1534 static int add_syslog_identifier(sd_journal *j) {
1535 int r;
1536 char **i;
1537
1538 assert(j);
1539
1540 STRV_FOREACH(i, arg_syslog_identifier) {
1541 char *u;
1542
1543 u = strjoina("SYSLOG_IDENTIFIER=", *i);
1544 r = sd_journal_add_match(j, u, 0);
1545 if (r < 0)
1546 return r;
1547 r = sd_journal_add_disjunction(j);
1548 if (r < 0)
1549 return r;
1550 }
1551
1552 r = sd_journal_add_conjunction(j);
1553 if (r < 0)
1554 return r;
1555
1556 return 0;
1557 }
1558
1559 static int setup_keys(void) {
1560 #ifdef HAVE_GCRYPT
1561 size_t mpk_size, seed_size, state_size, i;
1562 uint8_t *mpk, *seed, *state;
1563 int fd = -1, r;
1564 sd_id128_t machine, boot;
1565 char *p = NULL, *k = NULL;
1566 struct FSSHeader h;
1567 uint64_t n;
1568 struct stat st;
1569
1570 r = stat("/var/log/journal", &st);
1571 if (r < 0 && errno != ENOENT && errno != ENOTDIR)
1572 return log_error_errno(errno, "stat(\"%s\") failed: %m", "/var/log/journal");
1573
1574 if (r < 0 || !S_ISDIR(st.st_mode)) {
1575 log_error("%s is not a directory, must be using persistent logging for FSS.",
1576 "/var/log/journal");
1577 return r < 0 ? -errno : -ENOTDIR;
1578 }
1579
1580 r = sd_id128_get_machine(&machine);
1581 if (r < 0)
1582 return log_error_errno(r, "Failed to get machine ID: %m");
1583
1584 r = sd_id128_get_boot(&boot);
1585 if (r < 0)
1586 return log_error_errno(r, "Failed to get boot ID: %m");
1587
1588 if (asprintf(&p, "/var/log/journal/" SD_ID128_FORMAT_STR "/fss",
1589 SD_ID128_FORMAT_VAL(machine)) < 0)
1590 return log_oom();
1591
1592 if (arg_force) {
1593 r = unlink(p);
1594 if (r < 0 && errno != ENOENT) {
1595 r = log_error_errno(errno, "unlink(\"%s\") failed: %m", p);
1596 goto finish;
1597 }
1598 } else if (access(p, F_OK) >= 0) {
1599 log_error("Sealing key file %s exists already. Use --force to recreate.", p);
1600 r = -EEXIST;
1601 goto finish;
1602 }
1603
1604 if (asprintf(&k, "/var/log/journal/" SD_ID128_FORMAT_STR "/fss.tmp.XXXXXX",
1605 SD_ID128_FORMAT_VAL(machine)) < 0) {
1606 r = log_oom();
1607 goto finish;
1608 }
1609
1610 mpk_size = FSPRG_mskinbytes(FSPRG_RECOMMENDED_SECPAR);
1611 mpk = alloca(mpk_size);
1612
1613 seed_size = FSPRG_RECOMMENDED_SEEDLEN;
1614 seed = alloca(seed_size);
1615
1616 state_size = FSPRG_stateinbytes(FSPRG_RECOMMENDED_SECPAR);
1617 state = alloca(state_size);
1618
1619 fd = open("/dev/random", O_RDONLY|O_CLOEXEC|O_NOCTTY);
1620 if (fd < 0) {
1621 r = log_error_errno(errno, "Failed to open /dev/random: %m");
1622 goto finish;
1623 }
1624
1625 log_info("Generating seed...");
1626 r = loop_read_exact(fd, seed, seed_size, true);
1627 if (r < 0) {
1628 log_error_errno(r, "Failed to read random seed: %m");
1629 goto finish;
1630 }
1631
1632 log_info("Generating key pair...");
1633 FSPRG_GenMK(NULL, mpk, seed, seed_size, FSPRG_RECOMMENDED_SECPAR);
1634
1635 log_info("Generating sealing key...");
1636 FSPRG_GenState0(state, mpk, seed, seed_size);
1637
1638 assert(arg_interval > 0);
1639
1640 n = now(CLOCK_REALTIME);
1641 n /= arg_interval;
1642
1643 safe_close(fd);
1644 fd = mkostemp_safe(k);
1645 if (fd < 0) {
1646 r = log_error_errno(fd, "Failed to open %s: %m", k);
1647 goto finish;
1648 }
1649
1650 /* Enable secure remove, exclusion from dump, synchronous
1651 * writing and in-place updating */
1652 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);
1653 if (r < 0)
1654 log_warning_errno(r, "Failed to set file attributes: %m");
1655
1656 zero(h);
1657 memcpy(h.signature, "KSHHRHLP", 8);
1658 h.machine_id = machine;
1659 h.boot_id = boot;
1660 h.header_size = htole64(sizeof(h));
1661 h.start_usec = htole64(n * arg_interval);
1662 h.interval_usec = htole64(arg_interval);
1663 h.fsprg_secpar = htole16(FSPRG_RECOMMENDED_SECPAR);
1664 h.fsprg_state_size = htole64(state_size);
1665
1666 r = loop_write(fd, &h, sizeof(h), false);
1667 if (r < 0) {
1668 log_error_errno(r, "Failed to write header: %m");
1669 goto finish;
1670 }
1671
1672 r = loop_write(fd, state, state_size, false);
1673 if (r < 0) {
1674 log_error_errno(r, "Failed to write state: %m");
1675 goto finish;
1676 }
1677
1678 if (link(k, p) < 0) {
1679 r = log_error_errno(errno, "Failed to link file: %m");
1680 goto finish;
1681 }
1682
1683 if (on_tty()) {
1684 fprintf(stderr,
1685 "\n"
1686 "The new key pair has been generated. The %ssecret sealing key%s has been written to\n"
1687 "the following local file. This key file is automatically updated when the\n"
1688 "sealing key is advanced. It should not be used on multiple hosts.\n"
1689 "\n"
1690 "\t%s\n"
1691 "\n"
1692 "Please write down the following %ssecret verification key%s. It should be stored\n"
1693 "at a safe location and should not be saved locally on disk.\n"
1694 "\n\t%s",
1695 ansi_highlight(), ansi_normal(),
1696 p,
1697 ansi_highlight(), ansi_normal(),
1698 ansi_highlight_red());
1699 fflush(stderr);
1700 }
1701 for (i = 0; i < seed_size; i++) {
1702 if (i > 0 && i % 3 == 0)
1703 putchar('-');
1704 printf("%02x", ((uint8_t*) seed)[i]);
1705 }
1706
1707 printf("/%llx-%llx\n", (unsigned long long) n, (unsigned long long) arg_interval);
1708
1709 if (on_tty()) {
1710 char tsb[FORMAT_TIMESPAN_MAX], *hn;
1711
1712 fprintf(stderr,
1713 "%s\n"
1714 "The sealing key is automatically changed every %s.\n",
1715 ansi_normal(),
1716 format_timespan(tsb, sizeof(tsb), arg_interval, 0));
1717
1718 hn = gethostname_malloc();
1719
1720 if (hn) {
1721 hostname_cleanup(hn);
1722 fprintf(stderr, "\nThe keys have been generated for host %s/" SD_ID128_FORMAT_STR ".\n", hn, SD_ID128_FORMAT_VAL(machine));
1723 } else
1724 fprintf(stderr, "\nThe keys have been generated for host " SD_ID128_FORMAT_STR ".\n", SD_ID128_FORMAT_VAL(machine));
1725
1726 #ifdef HAVE_QRENCODE
1727 /* If this is not an UTF-8 system don't print any QR codes */
1728 if (is_locale_utf8()) {
1729 fputs("\nTo transfer the verification key to your phone please scan the QR code below:\n\n", stderr);
1730 print_qr_code(stderr, seed, seed_size, n, arg_interval, hn, machine);
1731 }
1732 #endif
1733 free(hn);
1734 }
1735
1736 r = 0;
1737
1738 finish:
1739 safe_close(fd);
1740
1741 if (k) {
1742 unlink(k);
1743 free(k);
1744 }
1745
1746 free(p);
1747
1748 return r;
1749 #else
1750 log_error("Forward-secure sealing not available.");
1751 return -EOPNOTSUPP;
1752 #endif
1753 }
1754
1755 static int verify(sd_journal *j) {
1756 int r = 0;
1757 Iterator i;
1758 JournalFile *f;
1759
1760 assert(j);
1761
1762 log_show_color(true);
1763
1764 ORDERED_HASHMAP_FOREACH(f, j->files, i) {
1765 int k;
1766 usec_t first = 0, validated = 0, last = 0;
1767
1768 #ifdef HAVE_GCRYPT
1769 if (!arg_verify_key && JOURNAL_HEADER_SEALED(f->header))
1770 log_notice("Journal file %s has sealing enabled but verification key has not been passed using --verify-key=.", f->path);
1771 #endif
1772
1773 k = journal_file_verify(f, arg_verify_key, &first, &validated, &last, true);
1774 if (k == -EINVAL) {
1775 /* If the key was invalid give up right-away. */
1776 return k;
1777 } else if (k < 0) {
1778 log_warning_errno(k, "FAIL: %s (%m)", f->path);
1779 r = k;
1780 } else {
1781 char a[FORMAT_TIMESTAMP_MAX], b[FORMAT_TIMESTAMP_MAX], c[FORMAT_TIMESPAN_MAX];
1782 log_info("PASS: %s", f->path);
1783
1784 if (arg_verify_key && JOURNAL_HEADER_SEALED(f->header)) {
1785 if (validated > 0) {
1786 log_info("=> Validated from %s to %s, final %s entries not sealed.",
1787 format_timestamp_maybe_utc(a, sizeof(a), first),
1788 format_timestamp_maybe_utc(b, sizeof(b), validated),
1789 format_timespan(c, sizeof(c), last > validated ? last - validated : 0, 0));
1790 } else if (last > 0)
1791 log_info("=> No sealing yet, %s of entries not sealed.",
1792 format_timespan(c, sizeof(c), last - first, 0));
1793 else
1794 log_info("=> No sealing yet, no entries in file.");
1795 }
1796 }
1797 }
1798
1799 return r;
1800 }
1801
1802 static int access_check_var_log_journal(sd_journal *j) {
1803 #ifdef HAVE_ACL
1804 _cleanup_strv_free_ char **g = NULL;
1805 const char* dir;
1806 #endif
1807 int r;
1808
1809 assert(j);
1810
1811 if (arg_quiet)
1812 return 0;
1813
1814 /* If we are root, we should have access, don't warn. */
1815 if (getuid() == 0)
1816 return 0;
1817
1818 /* If we are in the 'systemd-journal' group, we should have
1819 * access too. */
1820 r = in_group("systemd-journal");
1821 if (r < 0)
1822 return log_error_errno(r, "Failed to check if we are in the 'systemd-journal' group: %m");
1823 if (r > 0)
1824 return 0;
1825
1826 #ifdef HAVE_ACL
1827 if (laccess("/run/log/journal", F_OK) >= 0)
1828 dir = "/run/log/journal";
1829 else
1830 dir = "/var/log/journal";
1831
1832 /* If we are in any of the groups listed in the journal ACLs,
1833 * then all is good, too. Let's enumerate all groups from the
1834 * default ACL of the directory, which generally should allow
1835 * access to most journal files too. */
1836 r = acl_search_groups(dir, &g);
1837 if (r < 0)
1838 return log_error_errno(r, "Failed to search journal ACL: %m");
1839 if (r > 0)
1840 return 0;
1841
1842 /* Print a pretty list, if there were ACLs set. */
1843 if (!strv_isempty(g)) {
1844 _cleanup_free_ char *s = NULL;
1845
1846 /* Thre are groups in the ACL, let's list them */
1847 r = strv_extend(&g, "systemd-journal");
1848 if (r < 0)
1849 return log_oom();
1850
1851 strv_sort(g);
1852 strv_uniq(g);
1853
1854 s = strv_join(g, "', '");
1855 if (!s)
1856 return log_oom();
1857
1858 log_notice("Hint: You are currently not seeing messages from other users and the system.\n"
1859 " Users in groups '%s' can see all messages.\n"
1860 " Pass -q to turn off this notice.", s);
1861 return 1;
1862 }
1863 #endif
1864
1865 /* If no ACLs were found, print a short version of the message. */
1866 log_notice("Hint: You are currently not seeing messages from other users and the system.\n"
1867 " Users in the 'systemd-journal' group can see all messages. Pass -q to\n"
1868 " turn off this notice.");
1869
1870 return 1;
1871 }
1872
1873 static int access_check(sd_journal *j) {
1874 Iterator it;
1875 void *code;
1876 char *path;
1877 int r = 0;
1878
1879 assert(j);
1880
1881 if (hashmap_isempty(j->errors)) {
1882 if (ordered_hashmap_isempty(j->files))
1883 log_notice("No journal files were found.");
1884
1885 return 0;
1886 }
1887
1888 if (hashmap_contains(j->errors, INT_TO_PTR(-EACCES))) {
1889 (void) access_check_var_log_journal(j);
1890
1891 if (ordered_hashmap_isempty(j->files))
1892 r = log_error_errno(EACCES, "No journal files were opened due to insufficient permissions.");
1893 }
1894
1895 HASHMAP_FOREACH_KEY(path, code, j->errors, it) {
1896 int err;
1897
1898 err = abs(PTR_TO_INT(code));
1899
1900 switch (err) {
1901 case EACCES:
1902 continue;
1903
1904 case ENODATA:
1905 log_warning_errno(err, "Journal file %s is truncated, ignoring file.", path);
1906 break;
1907
1908 case EPROTONOSUPPORT:
1909 log_warning_errno(err, "Journal file %s uses an unsupported feature, ignoring file.", path);
1910 break;
1911
1912 case EBADMSG:
1913 log_warning_errno(err, "Journal file %s corrupted, ignoring file.", path);
1914 break;
1915
1916 default:
1917 log_warning_errno(err, "An error was encountered while opening journal file or directory %s, ignoring file: %m", path);
1918 break;
1919 }
1920 }
1921
1922 return r;
1923 }
1924
1925 static int flush_to_var(void) {
1926 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
1927 _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
1928 _cleanup_close_ int watch_fd = -1;
1929 int r;
1930
1931 if (arg_machine) {
1932 log_error("--flush is not supported in conjunction with --machine=.");
1933 return -EOPNOTSUPP;
1934 }
1935
1936 /* Quick exit */
1937 if (access("/run/systemd/journal/flushed", F_OK) >= 0)
1938 return 0;
1939
1940 /* OK, let's actually do the full logic, send SIGUSR1 to the
1941 * daemon and set up inotify to wait for the flushed file to appear */
1942 r = bus_connect_system_systemd(&bus);
1943 if (r < 0)
1944 return log_error_errno(r, "Failed to get D-Bus connection: %m");
1945
1946 r = sd_bus_call_method(
1947 bus,
1948 "org.freedesktop.systemd1",
1949 "/org/freedesktop/systemd1",
1950 "org.freedesktop.systemd1.Manager",
1951 "KillUnit",
1952 &error,
1953 NULL,
1954 "ssi", "systemd-journald.service", "main", SIGUSR1);
1955 if (r < 0)
1956 return log_error_errno(r, "Failed to kill journal service: %s", bus_error_message(&error, r));
1957
1958 mkdir_p("/run/systemd/journal", 0755);
1959
1960 watch_fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC);
1961 if (watch_fd < 0)
1962 return log_error_errno(errno, "Failed to create inotify watch: %m");
1963
1964 r = inotify_add_watch(watch_fd, "/run/systemd/journal", IN_CREATE|IN_DONT_FOLLOW|IN_ONLYDIR);
1965 if (r < 0)
1966 return log_error_errno(errno, "Failed to watch journal directory: %m");
1967
1968 for (;;) {
1969 if (access("/run/systemd/journal/flushed", F_OK) >= 0)
1970 break;
1971
1972 if (errno != ENOENT)
1973 return log_error_errno(errno, "Failed to check for existence of /run/systemd/journal/flushed: %m");
1974
1975 r = fd_wait_for_event(watch_fd, POLLIN, USEC_INFINITY);
1976 if (r < 0)
1977 return log_error_errno(r, "Failed to wait for event: %m");
1978
1979 r = flush_fd(watch_fd);
1980 if (r < 0)
1981 return log_error_errno(r, "Failed to flush inotify events: %m");
1982 }
1983
1984 return 0;
1985 }
1986
1987 static int send_signal_and_wait(int sig, const char *watch_path) {
1988 _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
1989 _cleanup_close_ int watch_fd = -1;
1990 usec_t start;
1991 int r;
1992
1993 if (arg_machine) {
1994 log_error("--sync and --rotate are not supported in conjunction with --machine=.");
1995 return -EOPNOTSUPP;
1996 }
1997
1998 start = now(CLOCK_MONOTONIC);
1999
2000 /* This call sends the specified signal to journald, and waits
2001 * for acknowledgment by watching the mtime of the specified
2002 * flag file. This is used to trigger syncing or rotation and
2003 * then wait for the operation to complete. */
2004
2005 for (;;) {
2006 usec_t tstamp;
2007
2008 /* See if a sync happened by now. */
2009 r = read_timestamp_file(watch_path, &tstamp);
2010 if (r < 0 && r != -ENOENT)
2011 return log_error_errno(errno, "Failed to read %s: %m", watch_path);
2012 if (r >= 0 && tstamp >= start)
2013 return 0;
2014
2015 /* Let's ask for a sync, but only once. */
2016 if (!bus) {
2017 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
2018
2019 r = bus_connect_system_systemd(&bus);
2020 if (r < 0)
2021 return log_error_errno(r, "Failed to get D-Bus connection: %m");
2022
2023 r = sd_bus_call_method(
2024 bus,
2025 "org.freedesktop.systemd1",
2026 "/org/freedesktop/systemd1",
2027 "org.freedesktop.systemd1.Manager",
2028 "KillUnit",
2029 &error,
2030 NULL,
2031 "ssi", "systemd-journald.service", "main", sig);
2032 if (r < 0)
2033 return log_error_errno(r, "Failed to kill journal service: %s", bus_error_message(&error, r));
2034
2035 continue;
2036 }
2037
2038 /* Let's install the inotify watch, if we didn't do that yet. */
2039 if (watch_fd < 0) {
2040
2041 mkdir_p("/run/systemd/journal", 0755);
2042
2043 watch_fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC);
2044 if (watch_fd < 0)
2045 return log_error_errno(errno, "Failed to create inotify watch: %m");
2046
2047 r = inotify_add_watch(watch_fd, "/run/systemd/journal", IN_MOVED_TO|IN_DONT_FOLLOW|IN_ONLYDIR);
2048 if (r < 0)
2049 return log_error_errno(errno, "Failed to watch journal directory: %m");
2050
2051 /* Recheck the flag file immediately, so that we don't miss any event since the last check. */
2052 continue;
2053 }
2054
2055 /* OK, all preparatory steps done, let's wait until
2056 * inotify reports an event. */
2057
2058 r = fd_wait_for_event(watch_fd, POLLIN, USEC_INFINITY);
2059 if (r < 0)
2060 return log_error_errno(r, "Failed to wait for event: %m");
2061
2062 r = flush_fd(watch_fd);
2063 if (r < 0)
2064 return log_error_errno(r, "Failed to flush inotify events: %m");
2065 }
2066
2067 return 0;
2068 }
2069
2070 static int rotate(void) {
2071 return send_signal_and_wait(SIGUSR2, "/run/systemd/journal/rotated");
2072 }
2073
2074 static int sync_journal(void) {
2075 return send_signal_and_wait(SIGRTMIN+1, "/run/systemd/journal/synced");
2076 }
2077
2078 int main(int argc, char *argv[]) {
2079 int r;
2080 _cleanup_(sd_journal_closep) sd_journal *j = NULL;
2081 bool need_seek = false;
2082 sd_id128_t previous_boot_id;
2083 bool previous_boot_id_valid = false, first_line = true;
2084 int n_shown = 0;
2085 bool ellipsized = false;
2086
2087 setlocale(LC_ALL, "");
2088 log_parse_environment();
2089 log_open();
2090
2091 r = parse_argv(argc, argv);
2092 if (r <= 0)
2093 goto finish;
2094
2095 signal(SIGWINCH, columns_lines_cache_reset);
2096 sigbus_install();
2097
2098 /* Increase max number of open files to 16K if we can, we
2099 * might needs this when browsing journal files, which might
2100 * be split up into many files. */
2101 setrlimit_closest(RLIMIT_NOFILE, &RLIMIT_MAKE_CONST(16384));
2102
2103 switch (arg_action) {
2104
2105 case ACTION_NEW_ID128:
2106 r = generate_new_id128();
2107 goto finish;
2108
2109 case ACTION_SETUP_KEYS:
2110 r = setup_keys();
2111 goto finish;
2112
2113 case ACTION_LIST_CATALOG:
2114 case ACTION_DUMP_CATALOG:
2115 case ACTION_UPDATE_CATALOG: {
2116 _cleanup_free_ char *database;
2117
2118 database = path_join(arg_root, CATALOG_DATABASE, NULL);
2119 if (!database) {
2120 r = log_oom();
2121 goto finish;
2122 }
2123
2124 if (arg_action == ACTION_UPDATE_CATALOG) {
2125 r = catalog_update(database, arg_root, catalog_file_dirs);
2126 if (r < 0)
2127 log_error_errno(r, "Failed to list catalog: %m");
2128 } else {
2129 bool oneline = arg_action == ACTION_LIST_CATALOG;
2130
2131 pager_open(arg_no_pager, arg_pager_end);
2132
2133 if (optind < argc)
2134 r = catalog_list_items(stdout, database, oneline, argv + optind);
2135 else
2136 r = catalog_list(stdout, database, oneline);
2137 if (r < 0)
2138 log_error_errno(r, "Failed to list catalog: %m");
2139 }
2140
2141 goto finish;
2142 }
2143
2144 case ACTION_FLUSH:
2145 r = flush_to_var();
2146 goto finish;
2147
2148 case ACTION_SYNC:
2149 r = sync_journal();
2150 goto finish;
2151
2152 case ACTION_ROTATE:
2153 r = rotate();
2154 goto finish;
2155
2156 case ACTION_SHOW:
2157 case ACTION_PRINT_HEADER:
2158 case ACTION_VERIFY:
2159 case ACTION_DISK_USAGE:
2160 case ACTION_LIST_BOOTS:
2161 case ACTION_VACUUM:
2162 case ACTION_LIST_FIELDS:
2163 case ACTION_LIST_FIELD_NAMES:
2164 /* These ones require access to the journal files, continue below. */
2165 break;
2166
2167 default:
2168 assert_not_reached("Unknown action");
2169 }
2170
2171 if (arg_directory)
2172 r = sd_journal_open_directory(&j, arg_directory, arg_journal_type);
2173 else if (arg_root)
2174 r = sd_journal_open_directory(&j, arg_root, arg_journal_type | SD_JOURNAL_OS_ROOT);
2175 else if (arg_file_stdin) {
2176 int ifd = STDIN_FILENO;
2177 r = sd_journal_open_files_fd(&j, &ifd, 1, 0);
2178 } else if (arg_file)
2179 r = sd_journal_open_files(&j, (const char**) arg_file, 0);
2180 else if (arg_machine) {
2181 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
2182 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
2183 _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
2184 int fd;
2185
2186 if (geteuid() != 0) {
2187 /* The file descriptor returned by OpenMachineRootDirectory() will be owned by users/groups of
2188 * the container, thus we need root privileges to override them. */
2189 log_error("Using the --machine= switch requires root privileges.");
2190 r = -EPERM;
2191 goto finish;
2192 }
2193
2194 r = sd_bus_open_system(&bus);
2195 if (r < 0) {
2196 log_error_errno(r, "Failed to open system bus: %m");
2197 goto finish;
2198 }
2199
2200 r = sd_bus_call_method(
2201 bus,
2202 "org.freedesktop.machine1",
2203 "/org/freedesktop/machine1",
2204 "org.freedesktop.machine1.Manager",
2205 "OpenMachineRootDirectory",
2206 &error,
2207 &reply,
2208 "s", arg_machine);
2209 if (r < 0) {
2210 log_error_errno(r, "Failed to open root directory: %s", bus_error_message(&error, r));
2211 goto finish;
2212 }
2213
2214 r = sd_bus_message_read(reply, "h", &fd);
2215 if (r < 0) {
2216 bus_log_parse_error(r);
2217 goto finish;
2218 }
2219
2220 fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
2221 if (fd < 0) {
2222 r = log_error_errno(errno, "Failed to duplicate file descriptor: %m");
2223 goto finish;
2224 }
2225
2226 r = sd_journal_open_directory_fd(&j, fd, SD_JOURNAL_OS_ROOT);
2227 if (r < 0)
2228 safe_close(fd);
2229 } else
2230 r = sd_journal_open(&j, !arg_merge*SD_JOURNAL_LOCAL_ONLY + arg_journal_type);
2231 if (r < 0) {
2232 log_error_errno(r, "Failed to open %s: %m", arg_directory ?: arg_file ? "files" : "journal");
2233 goto finish;
2234 }
2235
2236 r = access_check(j);
2237 if (r < 0)
2238 goto finish;
2239
2240 switch (arg_action) {
2241
2242 case ACTION_NEW_ID128:
2243 case ACTION_SETUP_KEYS:
2244 case ACTION_LIST_CATALOG:
2245 case ACTION_DUMP_CATALOG:
2246 case ACTION_UPDATE_CATALOG:
2247 case ACTION_FLUSH:
2248 case ACTION_SYNC:
2249 case ACTION_ROTATE:
2250 assert_not_reached("Unexpected action.");
2251
2252 case ACTION_PRINT_HEADER:
2253 journal_print_header(j);
2254 r = 0;
2255 goto finish;
2256
2257 case ACTION_VERIFY:
2258 r = verify(j);
2259 goto finish;
2260
2261 case ACTION_DISK_USAGE: {
2262 uint64_t bytes = 0;
2263 char sbytes[FORMAT_BYTES_MAX];
2264
2265 r = sd_journal_get_usage(j, &bytes);
2266 if (r < 0)
2267 goto finish;
2268
2269 printf("Archived and active journals take up %s in the file system.\n",
2270 format_bytes(sbytes, sizeof(sbytes), bytes));
2271 goto finish;
2272 }
2273
2274 case ACTION_LIST_BOOTS:
2275 r = list_boots(j);
2276 goto finish;
2277
2278 case ACTION_VACUUM: {
2279 Directory *d;
2280 Iterator i;
2281
2282 HASHMAP_FOREACH(d, j->directories_by_path, i) {
2283 int q;
2284
2285 if (d->is_root)
2286 continue;
2287
2288 q = journal_directory_vacuum(d->path, arg_vacuum_size, arg_vacuum_n_files, arg_vacuum_time, NULL, true);
2289 if (q < 0) {
2290 log_error_errno(q, "Failed to vacuum %s: %m", d->path);
2291 r = q;
2292 }
2293 }
2294
2295 goto finish;
2296 }
2297
2298 case ACTION_LIST_FIELD_NAMES: {
2299 const char *field;
2300
2301 SD_JOURNAL_FOREACH_FIELD(j, field) {
2302 printf("%s\n", field);
2303 n_shown++;
2304 }
2305
2306 r = 0;
2307 goto finish;
2308 }
2309
2310 case ACTION_SHOW:
2311 case ACTION_LIST_FIELDS:
2312 break;
2313
2314 default:
2315 assert_not_reached("Unknown action");
2316 }
2317
2318 if (arg_boot_offset != 0 &&
2319 sd_journal_has_runtime_files(j) > 0 &&
2320 sd_journal_has_persistent_files(j) == 0) {
2321 log_info("Specifying boot ID has no effect, no persistent journal was found");
2322 r = 0;
2323 goto finish;
2324 }
2325 /* add_boot() must be called first!
2326 * It may need to seek the journal to find parent boot IDs. */
2327 r = add_boot(j);
2328 if (r < 0)
2329 goto finish;
2330
2331 r = add_dmesg(j);
2332 if (r < 0)
2333 goto finish;
2334
2335 r = add_units(j);
2336 if (r < 0) {
2337 log_error_errno(r, "Failed to add filter for units: %m");
2338 goto finish;
2339 }
2340
2341 r = add_syslog_identifier(j);
2342 if (r < 0) {
2343 log_error_errno(r, "Failed to add filter for syslog identifiers: %m");
2344 goto finish;
2345 }
2346
2347 r = add_priorities(j);
2348 if (r < 0)
2349 goto finish;
2350
2351 r = add_matches(j, argv + optind);
2352 if (r < 0)
2353 goto finish;
2354
2355 if (_unlikely_(log_get_max_level() >= LOG_DEBUG)) {
2356 _cleanup_free_ char *filter;
2357
2358 filter = journal_make_match_string(j);
2359 if (!filter)
2360 return log_oom();
2361
2362 log_debug("Journal filter: %s", filter);
2363 }
2364
2365 if (arg_action == ACTION_LIST_FIELDS) {
2366 const void *data;
2367 size_t size;
2368
2369 assert(arg_field);
2370
2371 r = sd_journal_set_data_threshold(j, 0);
2372 if (r < 0) {
2373 log_error_errno(r, "Failed to unset data size threshold: %m");
2374 goto finish;
2375 }
2376
2377 r = sd_journal_query_unique(j, arg_field);
2378 if (r < 0) {
2379 log_error_errno(r, "Failed to query unique data objects: %m");
2380 goto finish;
2381 }
2382
2383 SD_JOURNAL_FOREACH_UNIQUE(j, data, size) {
2384 const void *eq;
2385
2386 if (arg_lines >= 0 && n_shown >= arg_lines)
2387 break;
2388
2389 eq = memchr(data, '=', size);
2390 if (eq)
2391 printf("%.*s\n", (int) (size - ((const uint8_t*) eq - (const uint8_t*) data + 1)), (const char*) eq + 1);
2392 else
2393 printf("%.*s\n", (int) size, (const char*) data);
2394
2395 n_shown++;
2396 }
2397
2398 r = 0;
2399 goto finish;
2400 }
2401
2402 /* Opening the fd now means the first sd_journal_wait() will actually wait */
2403 if (arg_follow) {
2404 r = sd_journal_get_fd(j);
2405 if (r == -EMEDIUMTYPE) {
2406 log_error_errno(r, "The --follow switch is not supported in conjunction with reading from STDIN.");
2407 goto finish;
2408 }
2409 if (r < 0) {
2410 log_error_errno(r, "Failed to get journal fd: %m");
2411 goto finish;
2412 }
2413 }
2414
2415 if (arg_cursor || arg_after_cursor) {
2416 r = sd_journal_seek_cursor(j, arg_cursor ?: arg_after_cursor);
2417 if (r < 0) {
2418 log_error_errno(r, "Failed to seek to cursor: %m");
2419 goto finish;
2420 }
2421
2422 if (!arg_reverse)
2423 r = sd_journal_next_skip(j, 1 + !!arg_after_cursor);
2424 else
2425 r = sd_journal_previous_skip(j, 1 + !!arg_after_cursor);
2426
2427 if (arg_after_cursor && r < 2) {
2428 /* We couldn't find the next entry after the cursor. */
2429 if (arg_follow)
2430 need_seek = true;
2431 else
2432 arg_lines = 0;
2433 }
2434
2435 } else if (arg_since_set && !arg_reverse) {
2436 r = sd_journal_seek_realtime_usec(j, arg_since);
2437 if (r < 0) {
2438 log_error_errno(r, "Failed to seek to date: %m");
2439 goto finish;
2440 }
2441 r = sd_journal_next(j);
2442
2443 } else if (arg_until_set && arg_reverse) {
2444 r = sd_journal_seek_realtime_usec(j, arg_until);
2445 if (r < 0) {
2446 log_error_errno(r, "Failed to seek to date: %m");
2447 goto finish;
2448 }
2449 r = sd_journal_previous(j);
2450
2451 } else if (arg_lines >= 0) {
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_skip(j, arg_lines);
2459
2460 } else if (arg_reverse) {
2461 r = sd_journal_seek_tail(j);
2462 if (r < 0) {
2463 log_error_errno(r, "Failed to seek to tail: %m");
2464 goto finish;
2465 }
2466
2467 r = sd_journal_previous(j);
2468
2469 } else {
2470 r = sd_journal_seek_head(j);
2471 if (r < 0) {
2472 log_error_errno(r, "Failed to seek to head: %m");
2473 goto finish;
2474 }
2475
2476 r = sd_journal_next(j);
2477 }
2478
2479 if (r < 0) {
2480 log_error_errno(r, "Failed to iterate through journal: %m");
2481 goto finish;
2482 }
2483 if (r == 0) {
2484 if (arg_follow)
2485 need_seek = true;
2486 else {
2487 if (!arg_quiet)
2488 printf("-- No entries --\n");
2489 goto finish;
2490 }
2491 }
2492
2493 if (!arg_follow)
2494 pager_open(arg_no_pager, arg_pager_end);
2495
2496 if (!arg_quiet) {
2497 usec_t start, end;
2498 char start_buf[FORMAT_TIMESTAMP_MAX], end_buf[FORMAT_TIMESTAMP_MAX];
2499
2500 r = sd_journal_get_cutoff_realtime_usec(j, &start, &end);
2501 if (r < 0) {
2502 log_error_errno(r, "Failed to get cutoff: %m");
2503 goto finish;
2504 }
2505
2506 if (r > 0) {
2507 if (arg_follow)
2508 printf("-- Logs begin at %s. --\n",
2509 format_timestamp_maybe_utc(start_buf, sizeof(start_buf), start));
2510 else
2511 printf("-- Logs begin at %s, end at %s. --\n",
2512 format_timestamp_maybe_utc(start_buf, sizeof(start_buf), start),
2513 format_timestamp_maybe_utc(end_buf, sizeof(end_buf), end));
2514 }
2515 }
2516
2517 for (;;) {
2518 while (arg_lines < 0 || n_shown < arg_lines || (arg_follow && !first_line)) {
2519 int flags;
2520
2521 if (need_seek) {
2522 if (!arg_reverse)
2523 r = sd_journal_next(j);
2524 else
2525 r = sd_journal_previous(j);
2526 if (r < 0) {
2527 log_error_errno(r, "Failed to iterate through journal: %m");
2528 goto finish;
2529 }
2530 if (r == 0)
2531 break;
2532 }
2533
2534 if (arg_until_set && !arg_reverse) {
2535 usec_t usec;
2536
2537 r = sd_journal_get_realtime_usec(j, &usec);
2538 if (r < 0) {
2539 log_error_errno(r, "Failed to determine timestamp: %m");
2540 goto finish;
2541 }
2542 if (usec > arg_until)
2543 goto finish;
2544 }
2545
2546 if (arg_since_set && arg_reverse) {
2547 usec_t usec;
2548
2549 r = sd_journal_get_realtime_usec(j, &usec);
2550 if (r < 0) {
2551 log_error_errno(r, "Failed to determine timestamp: %m");
2552 goto finish;
2553 }
2554 if (usec < arg_since)
2555 goto finish;
2556 }
2557
2558 if (!arg_merge && !arg_quiet) {
2559 sd_id128_t boot_id;
2560
2561 r = sd_journal_get_monotonic_usec(j, NULL, &boot_id);
2562 if (r >= 0) {
2563 if (previous_boot_id_valid &&
2564 !sd_id128_equal(boot_id, previous_boot_id))
2565 printf("%s-- Reboot --%s\n",
2566 ansi_highlight(), ansi_normal());
2567
2568 previous_boot_id = boot_id;
2569 previous_boot_id_valid = true;
2570 }
2571 }
2572
2573 flags =
2574 arg_all * OUTPUT_SHOW_ALL |
2575 arg_full * OUTPUT_FULL_WIDTH |
2576 colors_enabled() * OUTPUT_COLOR |
2577 arg_catalog * OUTPUT_CATALOG |
2578 arg_utc * OUTPUT_UTC |
2579 arg_no_hostname * OUTPUT_NO_HOSTNAME;
2580
2581 r = output_journal(stdout, j, arg_output, 0, flags, &ellipsized);
2582 need_seek = true;
2583 if (r == -EADDRNOTAVAIL)
2584 break;
2585 else if (r < 0 || ferror(stdout))
2586 goto finish;
2587
2588 n_shown++;
2589 }
2590
2591 if (!arg_follow) {
2592 if (arg_show_cursor) {
2593 _cleanup_free_ char *cursor = NULL;
2594
2595 r = sd_journal_get_cursor(j, &cursor);
2596 if (r < 0 && r != -EADDRNOTAVAIL)
2597 log_error_errno(r, "Failed to get cursor: %m");
2598 else if (r >= 0)
2599 printf("-- cursor: %s\n", cursor);
2600 }
2601
2602 break;
2603 }
2604
2605 r = sd_journal_wait(j, (uint64_t) -1);
2606 if (r < 0) {
2607 log_error_errno(r, "Couldn't wait for journal event: %m");
2608 goto finish;
2609 }
2610
2611 first_line = false;
2612 }
2613
2614 finish:
2615 pager_close();
2616
2617 strv_free(arg_file);
2618
2619 strv_free(arg_syslog_identifier);
2620 strv_free(arg_system_units);
2621 strv_free(arg_user_units);
2622
2623 free(arg_root);
2624
2625 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
2626 }