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