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