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