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