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