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