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